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_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1183 }; 1184 1185 /* 1186 * MMI instructions with opcode field = MMI: 1187 * 1188 * 31 26 5 0 1189 * +--------+-------------------------------+--------+ 1190 * | MMI | |function| 1191 * +--------+-------------------------------+--------+ 1192 * 1193 * function bits 2..0 1194 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1195 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1196 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1197 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1198 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1199 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1200 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1201 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1202 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1203 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1204 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1205 */ 1206 1207 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1208 enum { 1209 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1210 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1211 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1212 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1213 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1214 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1215 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1216 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1217 }; 1218 1219 /* global register indices */ 1220 TCGv cpu_gpr[32], cpu_PC; 1221 /* 1222 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1223 * and the upper halves in cpu_gpr_hi[]. 1224 */ 1225 TCGv_i64 cpu_gpr_hi[32]; 1226 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1227 static TCGv cpu_dspctrl, btarget; 1228 TCGv bcond; 1229 static TCGv cpu_lladdr, cpu_llval; 1230 static TCGv_i32 hflags; 1231 TCGv_i32 fpu_fcr0, fpu_fcr31; 1232 TCGv_i64 fpu_f64[32]; 1233 1234 #include "exec/gen-icount.h" 1235 1236 #define gen_helper_0e0i(name, arg) do { \ 1237 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 1238 gen_helper_##name(cpu_env, helper_tmp); \ 1239 tcg_temp_free_i32(helper_tmp); \ 1240 } while (0) 1241 1242 #define gen_helper_0e1i(name, arg1, arg2) do { \ 1243 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1244 gen_helper_##name(cpu_env, arg1, helper_tmp); \ 1245 tcg_temp_free_i32(helper_tmp); \ 1246 } while (0) 1247 1248 #define gen_helper_1e0i(name, ret, arg1) do { \ 1249 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ 1250 gen_helper_##name(ret, cpu_env, helper_tmp); \ 1251 tcg_temp_free_i32(helper_tmp); \ 1252 } while (0) 1253 1254 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \ 1255 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1256 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ 1257 tcg_temp_free_i32(helper_tmp); \ 1258 } while (0) 1259 1260 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ 1261 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1262 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ 1263 tcg_temp_free_i32(helper_tmp); \ 1264 } while (0) 1265 1266 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ 1267 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1268 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ 1269 tcg_temp_free_i32(helper_tmp); \ 1270 } while (0) 1271 1272 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ 1273 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 1274 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ 1275 tcg_temp_free_i32(helper_tmp); \ 1276 } while (0) 1277 1278 #define DISAS_STOP DISAS_TARGET_0 1279 #define DISAS_EXIT DISAS_TARGET_1 1280 1281 static const char regnames_HI[][4] = { 1282 "HI0", "HI1", "HI2", "HI3", 1283 }; 1284 1285 static const char regnames_LO[][4] = { 1286 "LO0", "LO1", "LO2", "LO3", 1287 }; 1288 1289 /* General purpose registers moves. */ 1290 void gen_load_gpr(TCGv t, int reg) 1291 { 1292 if (reg == 0) { 1293 tcg_gen_movi_tl(t, 0); 1294 } else { 1295 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1296 } 1297 } 1298 1299 void gen_store_gpr(TCGv t, int reg) 1300 { 1301 if (reg != 0) { 1302 tcg_gen_mov_tl(cpu_gpr[reg], t); 1303 } 1304 } 1305 1306 #if defined(TARGET_MIPS64) 1307 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1308 { 1309 if (reg == 0) { 1310 tcg_gen_movi_i64(t, 0); 1311 } else { 1312 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1313 } 1314 } 1315 1316 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1317 { 1318 if (reg != 0) { 1319 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1320 } 1321 } 1322 #endif /* TARGET_MIPS64 */ 1323 1324 /* Moves to/from shadow registers. */ 1325 static inline void gen_load_srsgpr(int from, int to) 1326 { 1327 TCGv t0 = tcg_temp_new(); 1328 1329 if (from == 0) { 1330 tcg_gen_movi_tl(t0, 0); 1331 } else { 1332 TCGv_i32 t2 = tcg_temp_new_i32(); 1333 TCGv_ptr addr = tcg_temp_new_ptr(); 1334 1335 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1336 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1337 tcg_gen_andi_i32(t2, t2, 0xf); 1338 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1339 tcg_gen_ext_i32_ptr(addr, t2); 1340 tcg_gen_add_ptr(addr, cpu_env, addr); 1341 1342 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1343 tcg_temp_free_ptr(addr); 1344 tcg_temp_free_i32(t2); 1345 } 1346 gen_store_gpr(t0, to); 1347 tcg_temp_free(t0); 1348 } 1349 1350 static inline void gen_store_srsgpr(int from, int to) 1351 { 1352 if (to != 0) { 1353 TCGv t0 = tcg_temp_new(); 1354 TCGv_i32 t2 = tcg_temp_new_i32(); 1355 TCGv_ptr addr = tcg_temp_new_ptr(); 1356 1357 gen_load_gpr(t0, from); 1358 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1359 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1360 tcg_gen_andi_i32(t2, t2, 0xf); 1361 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1362 tcg_gen_ext_i32_ptr(addr, t2); 1363 tcg_gen_add_ptr(addr, cpu_env, addr); 1364 1365 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1366 tcg_temp_free_ptr(addr); 1367 tcg_temp_free_i32(t2); 1368 tcg_temp_free(t0); 1369 } 1370 } 1371 1372 /* Tests */ 1373 static inline void gen_save_pc(target_ulong pc) 1374 { 1375 tcg_gen_movi_tl(cpu_PC, pc); 1376 } 1377 1378 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1379 { 1380 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1381 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1382 gen_save_pc(ctx->base.pc_next); 1383 ctx->saved_pc = ctx->base.pc_next; 1384 } 1385 if (ctx->hflags != ctx->saved_hflags) { 1386 tcg_gen_movi_i32(hflags, ctx->hflags); 1387 ctx->saved_hflags = ctx->hflags; 1388 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1389 case MIPS_HFLAG_BR: 1390 break; 1391 case MIPS_HFLAG_BC: 1392 case MIPS_HFLAG_BL: 1393 case MIPS_HFLAG_B: 1394 tcg_gen_movi_tl(btarget, ctx->btarget); 1395 break; 1396 } 1397 } 1398 } 1399 1400 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1401 { 1402 ctx->saved_hflags = ctx->hflags; 1403 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1404 case MIPS_HFLAG_BR: 1405 break; 1406 case MIPS_HFLAG_BC: 1407 case MIPS_HFLAG_BL: 1408 case MIPS_HFLAG_B: 1409 ctx->btarget = env->btarget; 1410 break; 1411 } 1412 } 1413 1414 void generate_exception_err(DisasContext *ctx, int excp, int err) 1415 { 1416 TCGv_i32 texcp = tcg_const_i32(excp); 1417 TCGv_i32 terr = tcg_const_i32(err); 1418 save_cpu_state(ctx, 1); 1419 gen_helper_raise_exception_err(cpu_env, texcp, terr); 1420 tcg_temp_free_i32(terr); 1421 tcg_temp_free_i32(texcp); 1422 ctx->base.is_jmp = DISAS_NORETURN; 1423 } 1424 1425 void generate_exception(DisasContext *ctx, int excp) 1426 { 1427 gen_helper_0e0i(raise_exception, excp); 1428 } 1429 1430 void generate_exception_end(DisasContext *ctx, int excp) 1431 { 1432 generate_exception_err(ctx, excp, 0); 1433 } 1434 1435 void gen_reserved_instruction(DisasContext *ctx) 1436 { 1437 generate_exception_end(ctx, EXCP_RI); 1438 } 1439 1440 /* Floating point register moves. */ 1441 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1442 { 1443 if (ctx->hflags & MIPS_HFLAG_FRE) { 1444 generate_exception(ctx, EXCP_RI); 1445 } 1446 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1447 } 1448 1449 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1450 { 1451 TCGv_i64 t64; 1452 if (ctx->hflags & MIPS_HFLAG_FRE) { 1453 generate_exception(ctx, EXCP_RI); 1454 } 1455 t64 = tcg_temp_new_i64(); 1456 tcg_gen_extu_i32_i64(t64, t); 1457 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1458 tcg_temp_free_i64(t64); 1459 } 1460 1461 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1462 { 1463 if (ctx->hflags & MIPS_HFLAG_F64) { 1464 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1465 } else { 1466 gen_load_fpr32(ctx, t, reg | 1); 1467 } 1468 } 1469 1470 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1471 { 1472 if (ctx->hflags & MIPS_HFLAG_F64) { 1473 TCGv_i64 t64 = tcg_temp_new_i64(); 1474 tcg_gen_extu_i32_i64(t64, t); 1475 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1476 tcg_temp_free_i64(t64); 1477 } else { 1478 gen_store_fpr32(ctx, t, reg | 1); 1479 } 1480 } 1481 1482 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1483 { 1484 if (ctx->hflags & MIPS_HFLAG_F64) { 1485 tcg_gen_mov_i64(t, fpu_f64[reg]); 1486 } else { 1487 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1488 } 1489 } 1490 1491 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1492 { 1493 if (ctx->hflags & MIPS_HFLAG_F64) { 1494 tcg_gen_mov_i64(fpu_f64[reg], t); 1495 } else { 1496 TCGv_i64 t0; 1497 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1498 t0 = tcg_temp_new_i64(); 1499 tcg_gen_shri_i64(t0, t, 32); 1500 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1501 tcg_temp_free_i64(t0); 1502 } 1503 } 1504 1505 int get_fp_bit(int cc) 1506 { 1507 if (cc) { 1508 return 24 + cc; 1509 } else { 1510 return 23; 1511 } 1512 } 1513 1514 /* Addresses computation */ 1515 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1516 { 1517 tcg_gen_add_tl(ret, arg0, arg1); 1518 1519 #if defined(TARGET_MIPS64) 1520 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1521 tcg_gen_ext32s_i64(ret, ret); 1522 } 1523 #endif 1524 } 1525 1526 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1527 target_long ofs) 1528 { 1529 tcg_gen_addi_tl(ret, base, ofs); 1530 1531 #if defined(TARGET_MIPS64) 1532 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1533 tcg_gen_ext32s_i64(ret, ret); 1534 } 1535 #endif 1536 } 1537 1538 /* Addresses computation (translation time) */ 1539 static target_long addr_add(DisasContext *ctx, target_long base, 1540 target_long offset) 1541 { 1542 target_long sum = base + offset; 1543 1544 #if defined(TARGET_MIPS64) 1545 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1546 sum = (int32_t)sum; 1547 } 1548 #endif 1549 return sum; 1550 } 1551 1552 /* Sign-extract the low 32-bits to a target_long. */ 1553 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1554 { 1555 #if defined(TARGET_MIPS64) 1556 tcg_gen_ext32s_i64(ret, arg); 1557 #else 1558 tcg_gen_extrl_i64_i32(ret, arg); 1559 #endif 1560 } 1561 1562 /* Sign-extract the high 32-bits to a target_long. */ 1563 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1564 { 1565 #if defined(TARGET_MIPS64) 1566 tcg_gen_sari_i64(ret, arg, 32); 1567 #else 1568 tcg_gen_extrh_i64_i32(ret, arg); 1569 #endif 1570 } 1571 1572 bool check_cp0_enabled(DisasContext *ctx) 1573 { 1574 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1575 generate_exception_end(ctx, EXCP_CpU); 1576 return false; 1577 } 1578 return true; 1579 } 1580 1581 void check_cp1_enabled(DisasContext *ctx) 1582 { 1583 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1584 generate_exception_err(ctx, EXCP_CpU, 1); 1585 } 1586 } 1587 1588 /* 1589 * Verify that the processor is running with COP1X instructions enabled. 1590 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1591 * opcode tables. 1592 */ 1593 void check_cop1x(DisasContext *ctx) 1594 { 1595 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1596 gen_reserved_instruction(ctx); 1597 } 1598 } 1599 1600 /* 1601 * Verify that the processor is running with 64-bit floating-point 1602 * operations enabled. 1603 */ 1604 void check_cp1_64bitmode(DisasContext *ctx) 1605 { 1606 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { 1607 gen_reserved_instruction(ctx); 1608 } 1609 } 1610 1611 /* 1612 * Verify if floating point register is valid; an operation is not defined 1613 * if bit 0 of any register specification is set and the FR bit in the 1614 * Status register equals zero, since the register numbers specify an 1615 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1616 * in the Status register equals one, both even and odd register numbers 1617 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1618 * 1619 * Multiple 64 bit wide registers can be checked by calling 1620 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1621 */ 1622 void check_cp1_registers(DisasContext *ctx, int regs) 1623 { 1624 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1625 gen_reserved_instruction(ctx); 1626 } 1627 } 1628 1629 /* 1630 * Verify that the processor is running with DSP instructions enabled. 1631 * This is enabled by CP0 Status register MX(24) bit. 1632 */ 1633 static inline void check_dsp(DisasContext *ctx) 1634 { 1635 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1636 if (ctx->insn_flags & ASE_DSP) { 1637 generate_exception_end(ctx, EXCP_DSPDIS); 1638 } else { 1639 gen_reserved_instruction(ctx); 1640 } 1641 } 1642 } 1643 1644 static inline void check_dsp_r2(DisasContext *ctx) 1645 { 1646 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1647 if (ctx->insn_flags & ASE_DSP) { 1648 generate_exception_end(ctx, EXCP_DSPDIS); 1649 } else { 1650 gen_reserved_instruction(ctx); 1651 } 1652 } 1653 } 1654 1655 static inline void check_dsp_r3(DisasContext *ctx) 1656 { 1657 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1658 if (ctx->insn_flags & ASE_DSP) { 1659 generate_exception_end(ctx, EXCP_DSPDIS); 1660 } else { 1661 gen_reserved_instruction(ctx); 1662 } 1663 } 1664 } 1665 1666 /* 1667 * This code generates a "reserved instruction" exception if the 1668 * CPU does not support the instruction set corresponding to flags. 1669 */ 1670 void check_insn(DisasContext *ctx, uint64_t flags) 1671 { 1672 if (unlikely(!(ctx->insn_flags & flags))) { 1673 gen_reserved_instruction(ctx); 1674 } 1675 } 1676 1677 /* 1678 * This code generates a "reserved instruction" exception if the 1679 * CPU has corresponding flag set which indicates that the instruction 1680 * has been removed. 1681 */ 1682 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1683 { 1684 if (unlikely(ctx->insn_flags & flags)) { 1685 gen_reserved_instruction(ctx); 1686 } 1687 } 1688 1689 /* 1690 * The Linux kernel traps certain reserved instruction exceptions to 1691 * emulate the corresponding instructions. QEMU is the kernel in user 1692 * mode, so those traps are emulated by accepting the instructions. 1693 * 1694 * A reserved instruction exception is generated for flagged CPUs if 1695 * QEMU runs in system mode. 1696 */ 1697 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1698 { 1699 #ifndef CONFIG_USER_ONLY 1700 check_insn_opc_removed(ctx, flags); 1701 #endif 1702 } 1703 1704 /* 1705 * This code generates a "reserved instruction" exception if the 1706 * CPU does not support 64-bit paired-single (PS) floating point data type. 1707 */ 1708 static inline void check_ps(DisasContext *ctx) 1709 { 1710 if (unlikely(!ctx->ps)) { 1711 generate_exception(ctx, EXCP_RI); 1712 } 1713 check_cp1_64bitmode(ctx); 1714 } 1715 1716 /* 1717 * This code generates a "reserved instruction" exception if cpu is not 1718 * 64-bit or 64-bit instructions are not enabled. 1719 */ 1720 void check_mips_64(DisasContext *ctx) 1721 { 1722 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1723 gen_reserved_instruction(ctx); 1724 } 1725 } 1726 1727 #ifndef CONFIG_USER_ONLY 1728 static inline void check_mvh(DisasContext *ctx) 1729 { 1730 if (unlikely(!ctx->mvh)) { 1731 generate_exception(ctx, EXCP_RI); 1732 } 1733 } 1734 #endif 1735 1736 /* 1737 * This code generates a "reserved instruction" exception if the 1738 * Config5 XNP bit is set. 1739 */ 1740 static inline void check_xnp(DisasContext *ctx) 1741 { 1742 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1743 gen_reserved_instruction(ctx); 1744 } 1745 } 1746 1747 #ifndef CONFIG_USER_ONLY 1748 /* 1749 * This code generates a "reserved instruction" exception if the 1750 * Config3 PW bit is NOT set. 1751 */ 1752 static inline void check_pw(DisasContext *ctx) 1753 { 1754 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1755 gen_reserved_instruction(ctx); 1756 } 1757 } 1758 #endif 1759 1760 /* 1761 * This code generates a "reserved instruction" exception if the 1762 * Config3 MT bit is NOT set. 1763 */ 1764 static inline void check_mt(DisasContext *ctx) 1765 { 1766 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1767 gen_reserved_instruction(ctx); 1768 } 1769 } 1770 1771 #ifndef CONFIG_USER_ONLY 1772 /* 1773 * This code generates a "coprocessor unusable" exception if CP0 is not 1774 * available, and, if that is not the case, generates a "reserved instruction" 1775 * exception if the Config5 MT bit is NOT set. This is needed for availability 1776 * control of some of MT ASE instructions. 1777 */ 1778 static inline void check_cp0_mt(DisasContext *ctx) 1779 { 1780 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1781 generate_exception_end(ctx, EXCP_CpU); 1782 } else { 1783 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1784 gen_reserved_instruction(ctx); 1785 } 1786 } 1787 } 1788 #endif 1789 1790 /* 1791 * This code generates a "reserved instruction" exception if the 1792 * Config5 NMS bit is set. 1793 */ 1794 static inline void check_nms(DisasContext *ctx) 1795 { 1796 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1797 gen_reserved_instruction(ctx); 1798 } 1799 } 1800 1801 /* 1802 * This code generates a "reserved instruction" exception if the 1803 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1804 * Config2 TL, and Config5 L2C are unset. 1805 */ 1806 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1807 { 1808 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1809 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1810 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1811 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1812 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1813 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1814 gen_reserved_instruction(ctx); 1815 } 1816 } 1817 1818 /* 1819 * This code generates a "reserved instruction" exception if the 1820 * Config5 EVA bit is NOT set. 1821 */ 1822 static inline void check_eva(DisasContext *ctx) 1823 { 1824 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1825 gen_reserved_instruction(ctx); 1826 } 1827 } 1828 1829 1830 /* 1831 * Define small wrappers for gen_load_fpr* so that we have a uniform 1832 * calling interface for 32 and 64-bit FPRs. No sense in changing 1833 * all callers for gen_load_fpr32 when we need the CTX parameter for 1834 * this one use. 1835 */ 1836 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1837 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1838 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1839 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1840 int ft, int fs, int cc) \ 1841 { \ 1842 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1843 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1844 switch (ifmt) { \ 1845 case FMT_PS: \ 1846 check_ps(ctx); \ 1847 break; \ 1848 case FMT_D: \ 1849 if (abs) { \ 1850 check_cop1x(ctx); \ 1851 } \ 1852 check_cp1_registers(ctx, fs | ft); \ 1853 break; \ 1854 case FMT_S: \ 1855 if (abs) { \ 1856 check_cop1x(ctx); \ 1857 } \ 1858 break; \ 1859 } \ 1860 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1861 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1862 switch (n) { \ 1863 case 0: \ 1864 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1865 break; \ 1866 case 1: \ 1867 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1868 break; \ 1869 case 2: \ 1870 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1871 break; \ 1872 case 3: \ 1873 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1874 break; \ 1875 case 4: \ 1876 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1877 break; \ 1878 case 5: \ 1879 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1880 break; \ 1881 case 6: \ 1882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1883 break; \ 1884 case 7: \ 1885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1886 break; \ 1887 case 8: \ 1888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1889 break; \ 1890 case 9: \ 1891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1892 break; \ 1893 case 10: \ 1894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1895 break; \ 1896 case 11: \ 1897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1898 break; \ 1899 case 12: \ 1900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1901 break; \ 1902 case 13: \ 1903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1904 break; \ 1905 case 14: \ 1906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1907 break; \ 1908 case 15: \ 1909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1910 break; \ 1911 default: \ 1912 abort(); \ 1913 } \ 1914 tcg_temp_free_i##bits(fp0); \ 1915 tcg_temp_free_i##bits(fp1); \ 1916 } 1917 1918 FOP_CONDS(, 0, d, FMT_D, 64) 1919 FOP_CONDS(abs, 1, d, FMT_D, 64) 1920 FOP_CONDS(, 0, s, FMT_S, 32) 1921 FOP_CONDS(abs, 1, s, FMT_S, 32) 1922 FOP_CONDS(, 0, ps, FMT_PS, 64) 1923 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1924 #undef FOP_CONDS 1925 1926 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1927 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1928 int ft, int fs, int fd) \ 1929 { \ 1930 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1931 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1932 if (ifmt == FMT_D) { \ 1933 check_cp1_registers(ctx, fs | ft | fd); \ 1934 } \ 1935 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1936 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1937 switch (n) { \ 1938 case 0: \ 1939 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1940 break; \ 1941 case 1: \ 1942 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1943 break; \ 1944 case 2: \ 1945 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1946 break; \ 1947 case 3: \ 1948 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1949 break; \ 1950 case 4: \ 1951 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1952 break; \ 1953 case 5: \ 1954 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1955 break; \ 1956 case 6: \ 1957 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1958 break; \ 1959 case 7: \ 1960 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1961 break; \ 1962 case 8: \ 1963 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1964 break; \ 1965 case 9: \ 1966 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1967 break; \ 1968 case 10: \ 1969 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1970 break; \ 1971 case 11: \ 1972 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1973 break; \ 1974 case 12: \ 1975 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1976 break; \ 1977 case 13: \ 1978 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1979 break; \ 1980 case 14: \ 1981 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1982 break; \ 1983 case 15: \ 1984 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1985 break; \ 1986 case 17: \ 1987 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1988 break; \ 1989 case 18: \ 1990 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1991 break; \ 1992 case 19: \ 1993 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1994 break; \ 1995 case 25: \ 1996 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1997 break; \ 1998 case 26: \ 1999 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 2000 break; \ 2001 case 27: \ 2002 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 2003 break; \ 2004 default: \ 2005 abort(); \ 2006 } \ 2007 STORE; \ 2008 tcg_temp_free_i ## bits(fp0); \ 2009 tcg_temp_free_i ## bits(fp1); \ 2010 } 2011 2012 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 2013 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 2014 #undef FOP_CONDNS 2015 #undef gen_ldcmp_fpr32 2016 #undef gen_ldcmp_fpr64 2017 2018 /* load/store instructions. */ 2019 #ifdef CONFIG_USER_ONLY 2020 #define OP_LD_ATOMIC(insn, fname) \ 2021 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2022 DisasContext *ctx) \ 2023 { \ 2024 TCGv t0 = tcg_temp_new(); \ 2025 tcg_gen_mov_tl(t0, arg1); \ 2026 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 2027 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 2028 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 2029 tcg_temp_free(t0); \ 2030 } 2031 #else 2032 #define OP_LD_ATOMIC(insn, fname) \ 2033 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2034 DisasContext *ctx) \ 2035 { \ 2036 gen_helper_1e1i(insn, ret, arg1, mem_idx); \ 2037 } 2038 #endif 2039 OP_LD_ATOMIC(ll, ld32s); 2040 #if defined(TARGET_MIPS64) 2041 OP_LD_ATOMIC(lld, ld64); 2042 #endif 2043 #undef OP_LD_ATOMIC 2044 2045 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 2046 { 2047 if (base == 0) { 2048 tcg_gen_movi_tl(addr, offset); 2049 } else if (offset == 0) { 2050 gen_load_gpr(addr, base); 2051 } else { 2052 tcg_gen_movi_tl(addr, offset); 2053 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 2054 } 2055 } 2056 2057 static target_ulong pc_relative_pc(DisasContext *ctx) 2058 { 2059 target_ulong pc = ctx->base.pc_next; 2060 2061 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2062 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2063 2064 pc -= branch_bytes; 2065 } 2066 2067 pc &= ~(target_ulong)3; 2068 return pc; 2069 } 2070 2071 /* Load */ 2072 static void gen_ld(DisasContext *ctx, uint32_t opc, 2073 int rt, int base, int offset) 2074 { 2075 TCGv t0, t1, t2; 2076 int mem_idx = ctx->mem_idx; 2077 2078 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2079 INSN_LOONGSON3A)) { 2080 /* 2081 * Loongson CPU uses a load to zero register for prefetch. 2082 * We emulate it as a NOP. On other CPU we must perform the 2083 * actual memory access. 2084 */ 2085 return; 2086 } 2087 2088 t0 = tcg_temp_new(); 2089 gen_base_offset_addr(ctx, t0, base, offset); 2090 2091 switch (opc) { 2092 #if defined(TARGET_MIPS64) 2093 case OPC_LWU: 2094 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2095 ctx->default_tcg_memop_mask); 2096 gen_store_gpr(t0, rt); 2097 break; 2098 case OPC_LD: 2099 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | 2100 ctx->default_tcg_memop_mask); 2101 gen_store_gpr(t0, rt); 2102 break; 2103 case OPC_LLD: 2104 case R6_OPC_LLD: 2105 op_ld_lld(t0, t0, mem_idx, ctx); 2106 gen_store_gpr(t0, rt); 2107 break; 2108 case OPC_LDL: 2109 t1 = tcg_temp_new(); 2110 /* 2111 * Do a byte access to possibly trigger a page 2112 * fault with the unaligned address. 2113 */ 2114 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2115 tcg_gen_andi_tl(t1, t0, 7); 2116 #ifndef TARGET_WORDS_BIGENDIAN 2117 tcg_gen_xori_tl(t1, t1, 7); 2118 #endif 2119 tcg_gen_shli_tl(t1, t1, 3); 2120 tcg_gen_andi_tl(t0, t0, ~7); 2121 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2122 tcg_gen_shl_tl(t0, t0, t1); 2123 t2 = tcg_const_tl(-1); 2124 tcg_gen_shl_tl(t2, t2, t1); 2125 gen_load_gpr(t1, rt); 2126 tcg_gen_andc_tl(t1, t1, t2); 2127 tcg_temp_free(t2); 2128 tcg_gen_or_tl(t0, t0, t1); 2129 tcg_temp_free(t1); 2130 gen_store_gpr(t0, rt); 2131 break; 2132 case OPC_LDR: 2133 t1 = tcg_temp_new(); 2134 /* 2135 * Do a byte access to possibly trigger a page 2136 * fault with the unaligned address. 2137 */ 2138 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2139 tcg_gen_andi_tl(t1, t0, 7); 2140 #ifdef TARGET_WORDS_BIGENDIAN 2141 tcg_gen_xori_tl(t1, t1, 7); 2142 #endif 2143 tcg_gen_shli_tl(t1, t1, 3); 2144 tcg_gen_andi_tl(t0, t0, ~7); 2145 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2146 tcg_gen_shr_tl(t0, t0, t1); 2147 tcg_gen_xori_tl(t1, t1, 63); 2148 t2 = tcg_const_tl(0xfffffffffffffffeull); 2149 tcg_gen_shl_tl(t2, t2, t1); 2150 gen_load_gpr(t1, rt); 2151 tcg_gen_and_tl(t1, t1, t2); 2152 tcg_temp_free(t2); 2153 tcg_gen_or_tl(t0, t0, t1); 2154 tcg_temp_free(t1); 2155 gen_store_gpr(t0, rt); 2156 break; 2157 case OPC_LDPC: 2158 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2159 gen_op_addr_add(ctx, t0, t0, t1); 2160 tcg_temp_free(t1); 2161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2162 gen_store_gpr(t0, rt); 2163 break; 2164 #endif 2165 case OPC_LWPC: 2166 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2167 gen_op_addr_add(ctx, t0, t0, t1); 2168 tcg_temp_free(t1); 2169 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2170 gen_store_gpr(t0, rt); 2171 break; 2172 case OPC_LWE: 2173 mem_idx = MIPS_HFLAG_UM; 2174 /* fall through */ 2175 case OPC_LW: 2176 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2177 ctx->default_tcg_memop_mask); 2178 gen_store_gpr(t0, rt); 2179 break; 2180 case OPC_LHE: 2181 mem_idx = MIPS_HFLAG_UM; 2182 /* fall through */ 2183 case OPC_LH: 2184 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2185 ctx->default_tcg_memop_mask); 2186 gen_store_gpr(t0, rt); 2187 break; 2188 case OPC_LHUE: 2189 mem_idx = MIPS_HFLAG_UM; 2190 /* fall through */ 2191 case OPC_LHU: 2192 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2193 ctx->default_tcg_memop_mask); 2194 gen_store_gpr(t0, rt); 2195 break; 2196 case OPC_LBE: 2197 mem_idx = MIPS_HFLAG_UM; 2198 /* fall through */ 2199 case OPC_LB: 2200 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2201 gen_store_gpr(t0, rt); 2202 break; 2203 case OPC_LBUE: 2204 mem_idx = MIPS_HFLAG_UM; 2205 /* fall through */ 2206 case OPC_LBU: 2207 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2208 gen_store_gpr(t0, rt); 2209 break; 2210 case OPC_LWLE: 2211 mem_idx = MIPS_HFLAG_UM; 2212 /* fall through */ 2213 case OPC_LWL: 2214 t1 = tcg_temp_new(); 2215 /* 2216 * Do a byte access to possibly trigger a page 2217 * fault with the unaligned address. 2218 */ 2219 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2220 tcg_gen_andi_tl(t1, t0, 3); 2221 #ifndef TARGET_WORDS_BIGENDIAN 2222 tcg_gen_xori_tl(t1, t1, 3); 2223 #endif 2224 tcg_gen_shli_tl(t1, t1, 3); 2225 tcg_gen_andi_tl(t0, t0, ~3); 2226 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2227 tcg_gen_shl_tl(t0, t0, t1); 2228 t2 = tcg_const_tl(-1); 2229 tcg_gen_shl_tl(t2, t2, t1); 2230 gen_load_gpr(t1, rt); 2231 tcg_gen_andc_tl(t1, t1, t2); 2232 tcg_temp_free(t2); 2233 tcg_gen_or_tl(t0, t0, t1); 2234 tcg_temp_free(t1); 2235 tcg_gen_ext32s_tl(t0, t0); 2236 gen_store_gpr(t0, rt); 2237 break; 2238 case OPC_LWRE: 2239 mem_idx = MIPS_HFLAG_UM; 2240 /* fall through */ 2241 case OPC_LWR: 2242 t1 = tcg_temp_new(); 2243 /* 2244 * Do a byte access to possibly trigger a page 2245 * fault with the unaligned address. 2246 */ 2247 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2248 tcg_gen_andi_tl(t1, t0, 3); 2249 #ifdef TARGET_WORDS_BIGENDIAN 2250 tcg_gen_xori_tl(t1, t1, 3); 2251 #endif 2252 tcg_gen_shli_tl(t1, t1, 3); 2253 tcg_gen_andi_tl(t0, t0, ~3); 2254 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2255 tcg_gen_shr_tl(t0, t0, t1); 2256 tcg_gen_xori_tl(t1, t1, 31); 2257 t2 = tcg_const_tl(0xfffffffeull); 2258 tcg_gen_shl_tl(t2, t2, t1); 2259 gen_load_gpr(t1, rt); 2260 tcg_gen_and_tl(t1, t1, t2); 2261 tcg_temp_free(t2); 2262 tcg_gen_or_tl(t0, t0, t1); 2263 tcg_temp_free(t1); 2264 tcg_gen_ext32s_tl(t0, t0); 2265 gen_store_gpr(t0, rt); 2266 break; 2267 case OPC_LLE: 2268 mem_idx = MIPS_HFLAG_UM; 2269 /* fall through */ 2270 case OPC_LL: 2271 case R6_OPC_LL: 2272 op_ld_ll(t0, t0, mem_idx, ctx); 2273 gen_store_gpr(t0, rt); 2274 break; 2275 } 2276 tcg_temp_free(t0); 2277 } 2278 2279 /* Store */ 2280 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2281 int base, int offset) 2282 { 2283 TCGv t0 = tcg_temp_new(); 2284 TCGv t1 = tcg_temp_new(); 2285 int mem_idx = ctx->mem_idx; 2286 2287 gen_base_offset_addr(ctx, t0, base, offset); 2288 gen_load_gpr(t1, rt); 2289 switch (opc) { 2290 #if defined(TARGET_MIPS64) 2291 case OPC_SD: 2292 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | 2293 ctx->default_tcg_memop_mask); 2294 break; 2295 case OPC_SDL: 2296 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2297 break; 2298 case OPC_SDR: 2299 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2300 break; 2301 #endif 2302 case OPC_SWE: 2303 mem_idx = MIPS_HFLAG_UM; 2304 /* fall through */ 2305 case OPC_SW: 2306 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2307 ctx->default_tcg_memop_mask); 2308 break; 2309 case OPC_SHE: 2310 mem_idx = MIPS_HFLAG_UM; 2311 /* fall through */ 2312 case OPC_SH: 2313 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2314 ctx->default_tcg_memop_mask); 2315 break; 2316 case OPC_SBE: 2317 mem_idx = MIPS_HFLAG_UM; 2318 /* fall through */ 2319 case OPC_SB: 2320 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2321 break; 2322 case OPC_SWLE: 2323 mem_idx = MIPS_HFLAG_UM; 2324 /* fall through */ 2325 case OPC_SWL: 2326 gen_helper_0e2i(swl, t1, t0, mem_idx); 2327 break; 2328 case OPC_SWRE: 2329 mem_idx = MIPS_HFLAG_UM; 2330 /* fall through */ 2331 case OPC_SWR: 2332 gen_helper_0e2i(swr, t1, t0, mem_idx); 2333 break; 2334 } 2335 tcg_temp_free(t0); 2336 tcg_temp_free(t1); 2337 } 2338 2339 2340 /* Store conditional */ 2341 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2342 MemOp tcg_mo, bool eva) 2343 { 2344 TCGv addr, t0, val; 2345 TCGLabel *l1 = gen_new_label(); 2346 TCGLabel *done = gen_new_label(); 2347 2348 t0 = tcg_temp_new(); 2349 addr = tcg_temp_new(); 2350 /* compare the address against that of the preceding LL */ 2351 gen_base_offset_addr(ctx, addr, base, offset); 2352 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2353 tcg_temp_free(addr); 2354 tcg_gen_movi_tl(t0, 0); 2355 gen_store_gpr(t0, rt); 2356 tcg_gen_br(done); 2357 2358 gen_set_label(l1); 2359 /* generate cmpxchg */ 2360 val = tcg_temp_new(); 2361 gen_load_gpr(val, rt); 2362 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2363 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2364 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2365 gen_store_gpr(t0, rt); 2366 tcg_temp_free(val); 2367 2368 gen_set_label(done); 2369 tcg_temp_free(t0); 2370 } 2371 2372 /* Load and store */ 2373 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2374 TCGv t0) 2375 { 2376 /* 2377 * Don't do NOP if destination is zero: we must perform the actual 2378 * memory access. 2379 */ 2380 switch (opc) { 2381 case OPC_LWC1: 2382 { 2383 TCGv_i32 fp0 = tcg_temp_new_i32(); 2384 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2385 ctx->default_tcg_memop_mask); 2386 gen_store_fpr32(ctx, fp0, ft); 2387 tcg_temp_free_i32(fp0); 2388 } 2389 break; 2390 case OPC_SWC1: 2391 { 2392 TCGv_i32 fp0 = tcg_temp_new_i32(); 2393 gen_load_fpr32(ctx, fp0, ft); 2394 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2395 ctx->default_tcg_memop_mask); 2396 tcg_temp_free_i32(fp0); 2397 } 2398 break; 2399 case OPC_LDC1: 2400 { 2401 TCGv_i64 fp0 = tcg_temp_new_i64(); 2402 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2403 ctx->default_tcg_memop_mask); 2404 gen_store_fpr64(ctx, fp0, ft); 2405 tcg_temp_free_i64(fp0); 2406 } 2407 break; 2408 case OPC_SDC1: 2409 { 2410 TCGv_i64 fp0 = tcg_temp_new_i64(); 2411 gen_load_fpr64(ctx, fp0, ft); 2412 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2413 ctx->default_tcg_memop_mask); 2414 tcg_temp_free_i64(fp0); 2415 } 2416 break; 2417 default: 2418 MIPS_INVAL("flt_ldst"); 2419 gen_reserved_instruction(ctx); 2420 break; 2421 } 2422 } 2423 2424 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2425 int rs, int16_t imm) 2426 { 2427 TCGv t0 = tcg_temp_new(); 2428 2429 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2430 check_cp1_enabled(ctx); 2431 switch (op) { 2432 case OPC_LDC1: 2433 case OPC_SDC1: 2434 check_insn(ctx, ISA_MIPS2); 2435 /* Fallthrough */ 2436 default: 2437 gen_base_offset_addr(ctx, t0, rs, imm); 2438 gen_flt_ldst(ctx, op, rt, t0); 2439 } 2440 } else { 2441 generate_exception_err(ctx, EXCP_CpU, 1); 2442 } 2443 tcg_temp_free(t0); 2444 } 2445 2446 /* Arithmetic with immediate operand */ 2447 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2448 int rt, int rs, int imm) 2449 { 2450 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2451 2452 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2453 /* 2454 * If no destination, treat it as a NOP. 2455 * For addi, we must generate the overflow exception when needed. 2456 */ 2457 return; 2458 } 2459 switch (opc) { 2460 case OPC_ADDI: 2461 { 2462 TCGv t0 = tcg_temp_local_new(); 2463 TCGv t1 = tcg_temp_new(); 2464 TCGv t2 = tcg_temp_new(); 2465 TCGLabel *l1 = gen_new_label(); 2466 2467 gen_load_gpr(t1, rs); 2468 tcg_gen_addi_tl(t0, t1, uimm); 2469 tcg_gen_ext32s_tl(t0, t0); 2470 2471 tcg_gen_xori_tl(t1, t1, ~uimm); 2472 tcg_gen_xori_tl(t2, t0, uimm); 2473 tcg_gen_and_tl(t1, t1, t2); 2474 tcg_temp_free(t2); 2475 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2476 tcg_temp_free(t1); 2477 /* operands of same sign, result different sign */ 2478 generate_exception(ctx, EXCP_OVERFLOW); 2479 gen_set_label(l1); 2480 tcg_gen_ext32s_tl(t0, t0); 2481 gen_store_gpr(t0, rt); 2482 tcg_temp_free(t0); 2483 } 2484 break; 2485 case OPC_ADDIU: 2486 if (rs != 0) { 2487 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2488 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2489 } else { 2490 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2491 } 2492 break; 2493 #if defined(TARGET_MIPS64) 2494 case OPC_DADDI: 2495 { 2496 TCGv t0 = tcg_temp_local_new(); 2497 TCGv t1 = tcg_temp_new(); 2498 TCGv t2 = tcg_temp_new(); 2499 TCGLabel *l1 = gen_new_label(); 2500 2501 gen_load_gpr(t1, rs); 2502 tcg_gen_addi_tl(t0, t1, uimm); 2503 2504 tcg_gen_xori_tl(t1, t1, ~uimm); 2505 tcg_gen_xori_tl(t2, t0, uimm); 2506 tcg_gen_and_tl(t1, t1, t2); 2507 tcg_temp_free(t2); 2508 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2509 tcg_temp_free(t1); 2510 /* operands of same sign, result different sign */ 2511 generate_exception(ctx, EXCP_OVERFLOW); 2512 gen_set_label(l1); 2513 gen_store_gpr(t0, rt); 2514 tcg_temp_free(t0); 2515 } 2516 break; 2517 case OPC_DADDIU: 2518 if (rs != 0) { 2519 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2520 } else { 2521 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2522 } 2523 break; 2524 #endif 2525 } 2526 } 2527 2528 /* Logic with immediate operand */ 2529 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2530 int rt, int rs, int16_t imm) 2531 { 2532 target_ulong uimm; 2533 2534 if (rt == 0) { 2535 /* If no destination, treat it as a NOP. */ 2536 return; 2537 } 2538 uimm = (uint16_t)imm; 2539 switch (opc) { 2540 case OPC_ANDI: 2541 if (likely(rs != 0)) { 2542 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2543 } else { 2544 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2545 } 2546 break; 2547 case OPC_ORI: 2548 if (rs != 0) { 2549 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2550 } else { 2551 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2552 } 2553 break; 2554 case OPC_XORI: 2555 if (likely(rs != 0)) { 2556 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2557 } else { 2558 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2559 } 2560 break; 2561 case OPC_LUI: 2562 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2563 /* OPC_AUI */ 2564 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2565 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2566 } else { 2567 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2568 } 2569 break; 2570 2571 default: 2572 break; 2573 } 2574 } 2575 2576 /* Set on less than with immediate operand */ 2577 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2578 int rt, int rs, int16_t imm) 2579 { 2580 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2581 TCGv t0; 2582 2583 if (rt == 0) { 2584 /* If no destination, treat it as a NOP. */ 2585 return; 2586 } 2587 t0 = tcg_temp_new(); 2588 gen_load_gpr(t0, rs); 2589 switch (opc) { 2590 case OPC_SLTI: 2591 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2592 break; 2593 case OPC_SLTIU: 2594 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2595 break; 2596 } 2597 tcg_temp_free(t0); 2598 } 2599 2600 /* Shifts with immediate operand */ 2601 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2602 int rt, int rs, int16_t imm) 2603 { 2604 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2605 TCGv t0; 2606 2607 if (rt == 0) { 2608 /* If no destination, treat it as a NOP. */ 2609 return; 2610 } 2611 2612 t0 = tcg_temp_new(); 2613 gen_load_gpr(t0, rs); 2614 switch (opc) { 2615 case OPC_SLL: 2616 tcg_gen_shli_tl(t0, t0, uimm); 2617 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2618 break; 2619 case OPC_SRA: 2620 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2621 break; 2622 case OPC_SRL: 2623 if (uimm != 0) { 2624 tcg_gen_ext32u_tl(t0, t0); 2625 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2626 } else { 2627 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2628 } 2629 break; 2630 case OPC_ROTR: 2631 if (uimm != 0) { 2632 TCGv_i32 t1 = tcg_temp_new_i32(); 2633 2634 tcg_gen_trunc_tl_i32(t1, t0); 2635 tcg_gen_rotri_i32(t1, t1, uimm); 2636 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2637 tcg_temp_free_i32(t1); 2638 } else { 2639 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2640 } 2641 break; 2642 #if defined(TARGET_MIPS64) 2643 case OPC_DSLL: 2644 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2645 break; 2646 case OPC_DSRA: 2647 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2648 break; 2649 case OPC_DSRL: 2650 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2651 break; 2652 case OPC_DROTR: 2653 if (uimm != 0) { 2654 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2655 } else { 2656 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2657 } 2658 break; 2659 case OPC_DSLL32: 2660 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2661 break; 2662 case OPC_DSRA32: 2663 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2664 break; 2665 case OPC_DSRL32: 2666 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2667 break; 2668 case OPC_DROTR32: 2669 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2670 break; 2671 #endif 2672 } 2673 tcg_temp_free(t0); 2674 } 2675 2676 /* Arithmetic */ 2677 static void gen_arith(DisasContext *ctx, uint32_t opc, 2678 int rd, int rs, int rt) 2679 { 2680 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2681 && opc != OPC_DADD && opc != OPC_DSUB) { 2682 /* 2683 * If no destination, treat it as a NOP. 2684 * For add & sub, we must generate the overflow exception when needed. 2685 */ 2686 return; 2687 } 2688 2689 switch (opc) { 2690 case OPC_ADD: 2691 { 2692 TCGv t0 = tcg_temp_local_new(); 2693 TCGv t1 = tcg_temp_new(); 2694 TCGv t2 = tcg_temp_new(); 2695 TCGLabel *l1 = gen_new_label(); 2696 2697 gen_load_gpr(t1, rs); 2698 gen_load_gpr(t2, rt); 2699 tcg_gen_add_tl(t0, t1, t2); 2700 tcg_gen_ext32s_tl(t0, t0); 2701 tcg_gen_xor_tl(t1, t1, t2); 2702 tcg_gen_xor_tl(t2, t0, t2); 2703 tcg_gen_andc_tl(t1, t2, t1); 2704 tcg_temp_free(t2); 2705 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2706 tcg_temp_free(t1); 2707 /* operands of same sign, result different sign */ 2708 generate_exception(ctx, EXCP_OVERFLOW); 2709 gen_set_label(l1); 2710 gen_store_gpr(t0, rd); 2711 tcg_temp_free(t0); 2712 } 2713 break; 2714 case OPC_ADDU: 2715 if (rs != 0 && rt != 0) { 2716 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2717 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2718 } else if (rs == 0 && rt != 0) { 2719 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2720 } else if (rs != 0 && rt == 0) { 2721 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2722 } else { 2723 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2724 } 2725 break; 2726 case OPC_SUB: 2727 { 2728 TCGv t0 = tcg_temp_local_new(); 2729 TCGv t1 = tcg_temp_new(); 2730 TCGv t2 = tcg_temp_new(); 2731 TCGLabel *l1 = gen_new_label(); 2732 2733 gen_load_gpr(t1, rs); 2734 gen_load_gpr(t2, rt); 2735 tcg_gen_sub_tl(t0, t1, t2); 2736 tcg_gen_ext32s_tl(t0, t0); 2737 tcg_gen_xor_tl(t2, t1, t2); 2738 tcg_gen_xor_tl(t1, t0, t1); 2739 tcg_gen_and_tl(t1, t1, t2); 2740 tcg_temp_free(t2); 2741 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2742 tcg_temp_free(t1); 2743 /* 2744 * operands of different sign, first operand and the result 2745 * of different sign 2746 */ 2747 generate_exception(ctx, EXCP_OVERFLOW); 2748 gen_set_label(l1); 2749 gen_store_gpr(t0, rd); 2750 tcg_temp_free(t0); 2751 } 2752 break; 2753 case OPC_SUBU: 2754 if (rs != 0 && rt != 0) { 2755 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2756 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2757 } else if (rs == 0 && rt != 0) { 2758 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2759 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2760 } else if (rs != 0 && rt == 0) { 2761 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2762 } else { 2763 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2764 } 2765 break; 2766 #if defined(TARGET_MIPS64) 2767 case OPC_DADD: 2768 { 2769 TCGv t0 = tcg_temp_local_new(); 2770 TCGv t1 = tcg_temp_new(); 2771 TCGv t2 = tcg_temp_new(); 2772 TCGLabel *l1 = gen_new_label(); 2773 2774 gen_load_gpr(t1, rs); 2775 gen_load_gpr(t2, rt); 2776 tcg_gen_add_tl(t0, t1, t2); 2777 tcg_gen_xor_tl(t1, t1, t2); 2778 tcg_gen_xor_tl(t2, t0, t2); 2779 tcg_gen_andc_tl(t1, t2, t1); 2780 tcg_temp_free(t2); 2781 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2782 tcg_temp_free(t1); 2783 /* operands of same sign, result different sign */ 2784 generate_exception(ctx, EXCP_OVERFLOW); 2785 gen_set_label(l1); 2786 gen_store_gpr(t0, rd); 2787 tcg_temp_free(t0); 2788 } 2789 break; 2790 case OPC_DADDU: 2791 if (rs != 0 && rt != 0) { 2792 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2793 } else if (rs == 0 && rt != 0) { 2794 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2795 } else if (rs != 0 && rt == 0) { 2796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2797 } else { 2798 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2799 } 2800 break; 2801 case OPC_DSUB: 2802 { 2803 TCGv t0 = tcg_temp_local_new(); 2804 TCGv t1 = tcg_temp_new(); 2805 TCGv t2 = tcg_temp_new(); 2806 TCGLabel *l1 = gen_new_label(); 2807 2808 gen_load_gpr(t1, rs); 2809 gen_load_gpr(t2, rt); 2810 tcg_gen_sub_tl(t0, t1, t2); 2811 tcg_gen_xor_tl(t2, t1, t2); 2812 tcg_gen_xor_tl(t1, t0, t1); 2813 tcg_gen_and_tl(t1, t1, t2); 2814 tcg_temp_free(t2); 2815 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2816 tcg_temp_free(t1); 2817 /* 2818 * Operands of different sign, first operand and result different 2819 * sign. 2820 */ 2821 generate_exception(ctx, EXCP_OVERFLOW); 2822 gen_set_label(l1); 2823 gen_store_gpr(t0, rd); 2824 tcg_temp_free(t0); 2825 } 2826 break; 2827 case OPC_DSUBU: 2828 if (rs != 0 && rt != 0) { 2829 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2830 } else if (rs == 0 && rt != 0) { 2831 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2832 } else if (rs != 0 && rt == 0) { 2833 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2834 } else { 2835 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2836 } 2837 break; 2838 #endif 2839 case OPC_MUL: 2840 if (likely(rs != 0 && rt != 0)) { 2841 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2842 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2843 } else { 2844 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2845 } 2846 break; 2847 } 2848 } 2849 2850 /* Conditional move */ 2851 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2852 int rd, int rs, int rt) 2853 { 2854 TCGv t0, t1, t2; 2855 2856 if (rd == 0) { 2857 /* If no destination, treat it as a NOP. */ 2858 return; 2859 } 2860 2861 t0 = tcg_temp_new(); 2862 gen_load_gpr(t0, rt); 2863 t1 = tcg_const_tl(0); 2864 t2 = tcg_temp_new(); 2865 gen_load_gpr(t2, rs); 2866 switch (opc) { 2867 case OPC_MOVN: 2868 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2869 break; 2870 case OPC_MOVZ: 2871 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2872 break; 2873 case OPC_SELNEZ: 2874 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2875 break; 2876 case OPC_SELEQZ: 2877 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2878 break; 2879 } 2880 tcg_temp_free(t2); 2881 tcg_temp_free(t1); 2882 tcg_temp_free(t0); 2883 } 2884 2885 /* Logic */ 2886 static void gen_logic(DisasContext *ctx, uint32_t opc, 2887 int rd, int rs, int rt) 2888 { 2889 if (rd == 0) { 2890 /* If no destination, treat it as a NOP. */ 2891 return; 2892 } 2893 2894 switch (opc) { 2895 case OPC_AND: 2896 if (likely(rs != 0 && rt != 0)) { 2897 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2898 } else { 2899 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2900 } 2901 break; 2902 case OPC_NOR: 2903 if (rs != 0 && rt != 0) { 2904 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2905 } else if (rs == 0 && rt != 0) { 2906 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2907 } else if (rs != 0 && rt == 0) { 2908 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2909 } else { 2910 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2911 } 2912 break; 2913 case OPC_OR: 2914 if (likely(rs != 0 && rt != 0)) { 2915 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2916 } else if (rs == 0 && rt != 0) { 2917 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2918 } else if (rs != 0 && rt == 0) { 2919 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2920 } else { 2921 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2922 } 2923 break; 2924 case OPC_XOR: 2925 if (likely(rs != 0 && rt != 0)) { 2926 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2927 } else if (rs == 0 && rt != 0) { 2928 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2929 } else if (rs != 0 && rt == 0) { 2930 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2931 } else { 2932 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2933 } 2934 break; 2935 } 2936 } 2937 2938 /* Set on lower than */ 2939 static void gen_slt(DisasContext *ctx, uint32_t opc, 2940 int rd, int rs, int rt) 2941 { 2942 TCGv t0, t1; 2943 2944 if (rd == 0) { 2945 /* If no destination, treat it as a NOP. */ 2946 return; 2947 } 2948 2949 t0 = tcg_temp_new(); 2950 t1 = tcg_temp_new(); 2951 gen_load_gpr(t0, rs); 2952 gen_load_gpr(t1, rt); 2953 switch (opc) { 2954 case OPC_SLT: 2955 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2956 break; 2957 case OPC_SLTU: 2958 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2959 break; 2960 } 2961 tcg_temp_free(t0); 2962 tcg_temp_free(t1); 2963 } 2964 2965 /* Shifts */ 2966 static void gen_shift(DisasContext *ctx, uint32_t opc, 2967 int rd, int rs, int rt) 2968 { 2969 TCGv t0, t1; 2970 2971 if (rd == 0) { 2972 /* 2973 * If no destination, treat it as a NOP. 2974 * For add & sub, we must generate the overflow exception when needed. 2975 */ 2976 return; 2977 } 2978 2979 t0 = tcg_temp_new(); 2980 t1 = tcg_temp_new(); 2981 gen_load_gpr(t0, rs); 2982 gen_load_gpr(t1, rt); 2983 switch (opc) { 2984 case OPC_SLLV: 2985 tcg_gen_andi_tl(t0, t0, 0x1f); 2986 tcg_gen_shl_tl(t0, t1, t0); 2987 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2988 break; 2989 case OPC_SRAV: 2990 tcg_gen_andi_tl(t0, t0, 0x1f); 2991 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2992 break; 2993 case OPC_SRLV: 2994 tcg_gen_ext32u_tl(t1, t1); 2995 tcg_gen_andi_tl(t0, t0, 0x1f); 2996 tcg_gen_shr_tl(t0, t1, t0); 2997 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2998 break; 2999 case OPC_ROTRV: 3000 { 3001 TCGv_i32 t2 = tcg_temp_new_i32(); 3002 TCGv_i32 t3 = tcg_temp_new_i32(); 3003 3004 tcg_gen_trunc_tl_i32(t2, t0); 3005 tcg_gen_trunc_tl_i32(t3, t1); 3006 tcg_gen_andi_i32(t2, t2, 0x1f); 3007 tcg_gen_rotr_i32(t2, t3, t2); 3008 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3009 tcg_temp_free_i32(t2); 3010 tcg_temp_free_i32(t3); 3011 } 3012 break; 3013 #if defined(TARGET_MIPS64) 3014 case OPC_DSLLV: 3015 tcg_gen_andi_tl(t0, t0, 0x3f); 3016 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 3017 break; 3018 case OPC_DSRAV: 3019 tcg_gen_andi_tl(t0, t0, 0x3f); 3020 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 3021 break; 3022 case OPC_DSRLV: 3023 tcg_gen_andi_tl(t0, t0, 0x3f); 3024 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 3025 break; 3026 case OPC_DROTRV: 3027 tcg_gen_andi_tl(t0, t0, 0x3f); 3028 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 3029 break; 3030 #endif 3031 } 3032 tcg_temp_free(t0); 3033 tcg_temp_free(t1); 3034 } 3035 3036 /* Arithmetic on HI/LO registers */ 3037 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 3038 { 3039 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 3040 /* Treat as NOP. */ 3041 return; 3042 } 3043 3044 if (acc != 0) { 3045 check_dsp(ctx); 3046 } 3047 3048 switch (opc) { 3049 case OPC_MFHI: 3050 #if defined(TARGET_MIPS64) 3051 if (acc != 0) { 3052 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 3053 } else 3054 #endif 3055 { 3056 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 3057 } 3058 break; 3059 case OPC_MFLO: 3060 #if defined(TARGET_MIPS64) 3061 if (acc != 0) { 3062 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3063 } else 3064 #endif 3065 { 3066 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3067 } 3068 break; 3069 case OPC_MTHI: 3070 if (reg != 0) { 3071 #if defined(TARGET_MIPS64) 3072 if (acc != 0) { 3073 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3074 } else 3075 #endif 3076 { 3077 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3078 } 3079 } else { 3080 tcg_gen_movi_tl(cpu_HI[acc], 0); 3081 } 3082 break; 3083 case OPC_MTLO: 3084 if (reg != 0) { 3085 #if defined(TARGET_MIPS64) 3086 if (acc != 0) { 3087 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3088 } else 3089 #endif 3090 { 3091 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3092 } 3093 } else { 3094 tcg_gen_movi_tl(cpu_LO[acc], 0); 3095 } 3096 break; 3097 } 3098 } 3099 3100 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3101 MemOp memop) 3102 { 3103 TCGv t0 = tcg_const_tl(addr); 3104 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3105 gen_store_gpr(t0, reg); 3106 tcg_temp_free(t0); 3107 } 3108 3109 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3110 int rs) 3111 { 3112 target_long offset; 3113 target_long addr; 3114 3115 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3116 case OPC_ADDIUPC: 3117 if (rs != 0) { 3118 offset = sextract32(ctx->opcode << 2, 0, 21); 3119 addr = addr_add(ctx, pc, offset); 3120 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3121 } 3122 break; 3123 case R6_OPC_LWPC: 3124 offset = sextract32(ctx->opcode << 2, 0, 21); 3125 addr = addr_add(ctx, pc, offset); 3126 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3127 break; 3128 #if defined(TARGET_MIPS64) 3129 case OPC_LWUPC: 3130 check_mips_64(ctx); 3131 offset = sextract32(ctx->opcode << 2, 0, 21); 3132 addr = addr_add(ctx, pc, offset); 3133 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3134 break; 3135 #endif 3136 default: 3137 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3138 case OPC_AUIPC: 3139 if (rs != 0) { 3140 offset = sextract32(ctx->opcode, 0, 16) << 16; 3141 addr = addr_add(ctx, pc, offset); 3142 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3143 } 3144 break; 3145 case OPC_ALUIPC: 3146 if (rs != 0) { 3147 offset = sextract32(ctx->opcode, 0, 16) << 16; 3148 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3149 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3150 } 3151 break; 3152 #if defined(TARGET_MIPS64) 3153 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3154 case R6_OPC_LDPC + (1 << 16): 3155 case R6_OPC_LDPC + (2 << 16): 3156 case R6_OPC_LDPC + (3 << 16): 3157 check_mips_64(ctx); 3158 offset = sextract32(ctx->opcode << 3, 0, 21); 3159 addr = addr_add(ctx, (pc & ~0x7), offset); 3160 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ); 3161 break; 3162 #endif 3163 default: 3164 MIPS_INVAL("OPC_PCREL"); 3165 gen_reserved_instruction(ctx); 3166 break; 3167 } 3168 break; 3169 } 3170 } 3171 3172 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3173 { 3174 TCGv t0, t1; 3175 3176 if (rd == 0) { 3177 /* Treat as NOP. */ 3178 return; 3179 } 3180 3181 t0 = tcg_temp_new(); 3182 t1 = tcg_temp_new(); 3183 3184 gen_load_gpr(t0, rs); 3185 gen_load_gpr(t1, rt); 3186 3187 switch (opc) { 3188 case R6_OPC_DIV: 3189 { 3190 TCGv t2 = tcg_temp_new(); 3191 TCGv t3 = tcg_temp_new(); 3192 tcg_gen_ext32s_tl(t0, t0); 3193 tcg_gen_ext32s_tl(t1, t1); 3194 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3195 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3196 tcg_gen_and_tl(t2, t2, t3); 3197 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3198 tcg_gen_or_tl(t2, t2, t3); 3199 tcg_gen_movi_tl(t3, 0); 3200 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3201 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3202 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3203 tcg_temp_free(t3); 3204 tcg_temp_free(t2); 3205 } 3206 break; 3207 case R6_OPC_MOD: 3208 { 3209 TCGv t2 = tcg_temp_new(); 3210 TCGv t3 = tcg_temp_new(); 3211 tcg_gen_ext32s_tl(t0, t0); 3212 tcg_gen_ext32s_tl(t1, t1); 3213 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3214 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3215 tcg_gen_and_tl(t2, t2, t3); 3216 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3217 tcg_gen_or_tl(t2, t2, t3); 3218 tcg_gen_movi_tl(t3, 0); 3219 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3220 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3221 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3222 tcg_temp_free(t3); 3223 tcg_temp_free(t2); 3224 } 3225 break; 3226 case R6_OPC_DIVU: 3227 { 3228 TCGv t2 = tcg_const_tl(0); 3229 TCGv t3 = tcg_const_tl(1); 3230 tcg_gen_ext32u_tl(t0, t0); 3231 tcg_gen_ext32u_tl(t1, t1); 3232 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3233 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3235 tcg_temp_free(t3); 3236 tcg_temp_free(t2); 3237 } 3238 break; 3239 case R6_OPC_MODU: 3240 { 3241 TCGv t2 = tcg_const_tl(0); 3242 TCGv t3 = tcg_const_tl(1); 3243 tcg_gen_ext32u_tl(t0, t0); 3244 tcg_gen_ext32u_tl(t1, t1); 3245 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3246 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3247 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3248 tcg_temp_free(t3); 3249 tcg_temp_free(t2); 3250 } 3251 break; 3252 case R6_OPC_MUL: 3253 { 3254 TCGv_i32 t2 = tcg_temp_new_i32(); 3255 TCGv_i32 t3 = tcg_temp_new_i32(); 3256 tcg_gen_trunc_tl_i32(t2, t0); 3257 tcg_gen_trunc_tl_i32(t3, t1); 3258 tcg_gen_mul_i32(t2, t2, t3); 3259 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3260 tcg_temp_free_i32(t2); 3261 tcg_temp_free_i32(t3); 3262 } 3263 break; 3264 case R6_OPC_MUH: 3265 { 3266 TCGv_i32 t2 = tcg_temp_new_i32(); 3267 TCGv_i32 t3 = tcg_temp_new_i32(); 3268 tcg_gen_trunc_tl_i32(t2, t0); 3269 tcg_gen_trunc_tl_i32(t3, t1); 3270 tcg_gen_muls2_i32(t2, t3, t2, t3); 3271 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3272 tcg_temp_free_i32(t2); 3273 tcg_temp_free_i32(t3); 3274 } 3275 break; 3276 case R6_OPC_MULU: 3277 { 3278 TCGv_i32 t2 = tcg_temp_new_i32(); 3279 TCGv_i32 t3 = tcg_temp_new_i32(); 3280 tcg_gen_trunc_tl_i32(t2, t0); 3281 tcg_gen_trunc_tl_i32(t3, t1); 3282 tcg_gen_mul_i32(t2, t2, t3); 3283 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3284 tcg_temp_free_i32(t2); 3285 tcg_temp_free_i32(t3); 3286 } 3287 break; 3288 case R6_OPC_MUHU: 3289 { 3290 TCGv_i32 t2 = tcg_temp_new_i32(); 3291 TCGv_i32 t3 = tcg_temp_new_i32(); 3292 tcg_gen_trunc_tl_i32(t2, t0); 3293 tcg_gen_trunc_tl_i32(t3, t1); 3294 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3295 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3296 tcg_temp_free_i32(t2); 3297 tcg_temp_free_i32(t3); 3298 } 3299 break; 3300 #if defined(TARGET_MIPS64) 3301 case R6_OPC_DDIV: 3302 { 3303 TCGv t2 = tcg_temp_new(); 3304 TCGv t3 = tcg_temp_new(); 3305 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3306 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3307 tcg_gen_and_tl(t2, t2, t3); 3308 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3309 tcg_gen_or_tl(t2, t2, t3); 3310 tcg_gen_movi_tl(t3, 0); 3311 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3312 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3313 tcg_temp_free(t3); 3314 tcg_temp_free(t2); 3315 } 3316 break; 3317 case R6_OPC_DMOD: 3318 { 3319 TCGv t2 = tcg_temp_new(); 3320 TCGv t3 = tcg_temp_new(); 3321 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3322 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3323 tcg_gen_and_tl(t2, t2, t3); 3324 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3325 tcg_gen_or_tl(t2, t2, t3); 3326 tcg_gen_movi_tl(t3, 0); 3327 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3328 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3329 tcg_temp_free(t3); 3330 tcg_temp_free(t2); 3331 } 3332 break; 3333 case R6_OPC_DDIVU: 3334 { 3335 TCGv t2 = tcg_const_tl(0); 3336 TCGv t3 = tcg_const_tl(1); 3337 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3338 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3339 tcg_temp_free(t3); 3340 tcg_temp_free(t2); 3341 } 3342 break; 3343 case R6_OPC_DMODU: 3344 { 3345 TCGv t2 = tcg_const_tl(0); 3346 TCGv t3 = tcg_const_tl(1); 3347 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3348 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3349 tcg_temp_free(t3); 3350 tcg_temp_free(t2); 3351 } 3352 break; 3353 case R6_OPC_DMUL: 3354 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3355 break; 3356 case R6_OPC_DMUH: 3357 { 3358 TCGv t2 = tcg_temp_new(); 3359 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3360 tcg_temp_free(t2); 3361 } 3362 break; 3363 case R6_OPC_DMULU: 3364 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3365 break; 3366 case R6_OPC_DMUHU: 3367 { 3368 TCGv t2 = tcg_temp_new(); 3369 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3370 tcg_temp_free(t2); 3371 } 3372 break; 3373 #endif 3374 default: 3375 MIPS_INVAL("r6 mul/div"); 3376 gen_reserved_instruction(ctx); 3377 goto out; 3378 } 3379 out: 3380 tcg_temp_free(t0); 3381 tcg_temp_free(t1); 3382 } 3383 3384 #if defined(TARGET_MIPS64) 3385 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3386 { 3387 TCGv t0, t1; 3388 3389 t0 = tcg_temp_new(); 3390 t1 = tcg_temp_new(); 3391 3392 gen_load_gpr(t0, rs); 3393 gen_load_gpr(t1, rt); 3394 3395 switch (opc) { 3396 case MMI_OPC_DIV1: 3397 { 3398 TCGv t2 = tcg_temp_new(); 3399 TCGv t3 = tcg_temp_new(); 3400 tcg_gen_ext32s_tl(t0, t0); 3401 tcg_gen_ext32s_tl(t1, t1); 3402 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3403 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3404 tcg_gen_and_tl(t2, t2, t3); 3405 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3406 tcg_gen_or_tl(t2, t2, t3); 3407 tcg_gen_movi_tl(t3, 0); 3408 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3409 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3410 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3411 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3412 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3413 tcg_temp_free(t3); 3414 tcg_temp_free(t2); 3415 } 3416 break; 3417 case MMI_OPC_DIVU1: 3418 { 3419 TCGv t2 = tcg_const_tl(0); 3420 TCGv t3 = tcg_const_tl(1); 3421 tcg_gen_ext32u_tl(t0, t0); 3422 tcg_gen_ext32u_tl(t1, t1); 3423 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3424 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3425 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3426 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3427 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3428 tcg_temp_free(t3); 3429 tcg_temp_free(t2); 3430 } 3431 break; 3432 default: 3433 MIPS_INVAL("div1 TX79"); 3434 gen_reserved_instruction(ctx); 3435 goto out; 3436 } 3437 out: 3438 tcg_temp_free(t0); 3439 tcg_temp_free(t1); 3440 } 3441 #endif 3442 3443 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3444 int acc, int rs, int rt) 3445 { 3446 TCGv t0, t1; 3447 3448 t0 = tcg_temp_new(); 3449 t1 = tcg_temp_new(); 3450 3451 gen_load_gpr(t0, rs); 3452 gen_load_gpr(t1, rt); 3453 3454 if (acc != 0) { 3455 check_dsp(ctx); 3456 } 3457 3458 switch (opc) { 3459 case OPC_DIV: 3460 { 3461 TCGv t2 = tcg_temp_new(); 3462 TCGv t3 = tcg_temp_new(); 3463 tcg_gen_ext32s_tl(t0, t0); 3464 tcg_gen_ext32s_tl(t1, t1); 3465 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3466 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3467 tcg_gen_and_tl(t2, t2, t3); 3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3469 tcg_gen_or_tl(t2, t2, t3); 3470 tcg_gen_movi_tl(t3, 0); 3471 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3472 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3473 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3474 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3475 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3476 tcg_temp_free(t3); 3477 tcg_temp_free(t2); 3478 } 3479 break; 3480 case OPC_DIVU: 3481 { 3482 TCGv t2 = tcg_const_tl(0); 3483 TCGv t3 = tcg_const_tl(1); 3484 tcg_gen_ext32u_tl(t0, t0); 3485 tcg_gen_ext32u_tl(t1, t1); 3486 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3487 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3488 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3489 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3490 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3491 tcg_temp_free(t3); 3492 tcg_temp_free(t2); 3493 } 3494 break; 3495 case OPC_MULT: 3496 { 3497 TCGv_i32 t2 = tcg_temp_new_i32(); 3498 TCGv_i32 t3 = tcg_temp_new_i32(); 3499 tcg_gen_trunc_tl_i32(t2, t0); 3500 tcg_gen_trunc_tl_i32(t3, t1); 3501 tcg_gen_muls2_i32(t2, t3, t2, t3); 3502 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3503 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3504 tcg_temp_free_i32(t2); 3505 tcg_temp_free_i32(t3); 3506 } 3507 break; 3508 case OPC_MULTU: 3509 { 3510 TCGv_i32 t2 = tcg_temp_new_i32(); 3511 TCGv_i32 t3 = tcg_temp_new_i32(); 3512 tcg_gen_trunc_tl_i32(t2, t0); 3513 tcg_gen_trunc_tl_i32(t3, t1); 3514 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3515 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3516 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3517 tcg_temp_free_i32(t2); 3518 tcg_temp_free_i32(t3); 3519 } 3520 break; 3521 #if defined(TARGET_MIPS64) 3522 case OPC_DDIV: 3523 { 3524 TCGv t2 = tcg_temp_new(); 3525 TCGv t3 = tcg_temp_new(); 3526 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3527 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3528 tcg_gen_and_tl(t2, t2, t3); 3529 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3530 tcg_gen_or_tl(t2, t2, t3); 3531 tcg_gen_movi_tl(t3, 0); 3532 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3533 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3534 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3535 tcg_temp_free(t3); 3536 tcg_temp_free(t2); 3537 } 3538 break; 3539 case OPC_DDIVU: 3540 { 3541 TCGv t2 = tcg_const_tl(0); 3542 TCGv t3 = tcg_const_tl(1); 3543 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3544 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3545 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3546 tcg_temp_free(t3); 3547 tcg_temp_free(t2); 3548 } 3549 break; 3550 case OPC_DMULT: 3551 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3552 break; 3553 case OPC_DMULTU: 3554 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3555 break; 3556 #endif 3557 case OPC_MADD: 3558 { 3559 TCGv_i64 t2 = tcg_temp_new_i64(); 3560 TCGv_i64 t3 = tcg_temp_new_i64(); 3561 3562 tcg_gen_ext_tl_i64(t2, t0); 3563 tcg_gen_ext_tl_i64(t3, t1); 3564 tcg_gen_mul_i64(t2, t2, t3); 3565 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3566 tcg_gen_add_i64(t2, t2, t3); 3567 tcg_temp_free_i64(t3); 3568 gen_move_low32(cpu_LO[acc], t2); 3569 gen_move_high32(cpu_HI[acc], t2); 3570 tcg_temp_free_i64(t2); 3571 } 3572 break; 3573 case OPC_MADDU: 3574 { 3575 TCGv_i64 t2 = tcg_temp_new_i64(); 3576 TCGv_i64 t3 = tcg_temp_new_i64(); 3577 3578 tcg_gen_ext32u_tl(t0, t0); 3579 tcg_gen_ext32u_tl(t1, t1); 3580 tcg_gen_extu_tl_i64(t2, t0); 3581 tcg_gen_extu_tl_i64(t3, t1); 3582 tcg_gen_mul_i64(t2, t2, t3); 3583 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3584 tcg_gen_add_i64(t2, t2, t3); 3585 tcg_temp_free_i64(t3); 3586 gen_move_low32(cpu_LO[acc], t2); 3587 gen_move_high32(cpu_HI[acc], t2); 3588 tcg_temp_free_i64(t2); 3589 } 3590 break; 3591 case OPC_MSUB: 3592 { 3593 TCGv_i64 t2 = tcg_temp_new_i64(); 3594 TCGv_i64 t3 = tcg_temp_new_i64(); 3595 3596 tcg_gen_ext_tl_i64(t2, t0); 3597 tcg_gen_ext_tl_i64(t3, t1); 3598 tcg_gen_mul_i64(t2, t2, t3); 3599 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3600 tcg_gen_sub_i64(t2, t3, t2); 3601 tcg_temp_free_i64(t3); 3602 gen_move_low32(cpu_LO[acc], t2); 3603 gen_move_high32(cpu_HI[acc], t2); 3604 tcg_temp_free_i64(t2); 3605 } 3606 break; 3607 case OPC_MSUBU: 3608 { 3609 TCGv_i64 t2 = tcg_temp_new_i64(); 3610 TCGv_i64 t3 = tcg_temp_new_i64(); 3611 3612 tcg_gen_ext32u_tl(t0, t0); 3613 tcg_gen_ext32u_tl(t1, t1); 3614 tcg_gen_extu_tl_i64(t2, t0); 3615 tcg_gen_extu_tl_i64(t3, t1); 3616 tcg_gen_mul_i64(t2, t2, t3); 3617 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3618 tcg_gen_sub_i64(t2, t3, t2); 3619 tcg_temp_free_i64(t3); 3620 gen_move_low32(cpu_LO[acc], t2); 3621 gen_move_high32(cpu_HI[acc], t2); 3622 tcg_temp_free_i64(t2); 3623 } 3624 break; 3625 default: 3626 MIPS_INVAL("mul/div"); 3627 gen_reserved_instruction(ctx); 3628 goto out; 3629 } 3630 out: 3631 tcg_temp_free(t0); 3632 tcg_temp_free(t1); 3633 } 3634 3635 /* 3636 * These MULT[U] and MADD[U] instructions implemented in for example 3637 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3638 * architectures are special three-operand variants with the syntax 3639 * 3640 * MULT[U][1] rd, rs, rt 3641 * 3642 * such that 3643 * 3644 * (rd, LO, HI) <- rs * rt 3645 * 3646 * and 3647 * 3648 * MADD[U][1] rd, rs, rt 3649 * 3650 * such that 3651 * 3652 * (rd, LO, HI) <- (LO, HI) + rs * rt 3653 * 3654 * where the low-order 32-bits of the result is placed into both the 3655 * GPR rd and the special register LO. The high-order 32-bits of the 3656 * result is placed into the special register HI. 3657 * 3658 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3659 * which is the zero register that always reads as 0. 3660 */ 3661 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3662 int rd, int rs, int rt) 3663 { 3664 TCGv t0 = tcg_temp_new(); 3665 TCGv t1 = tcg_temp_new(); 3666 int acc = 0; 3667 3668 gen_load_gpr(t0, rs); 3669 gen_load_gpr(t1, rt); 3670 3671 switch (opc) { 3672 case MMI_OPC_MULT1: 3673 acc = 1; 3674 /* Fall through */ 3675 case OPC_MULT: 3676 { 3677 TCGv_i32 t2 = tcg_temp_new_i32(); 3678 TCGv_i32 t3 = tcg_temp_new_i32(); 3679 tcg_gen_trunc_tl_i32(t2, t0); 3680 tcg_gen_trunc_tl_i32(t3, t1); 3681 tcg_gen_muls2_i32(t2, t3, t2, t3); 3682 if (rd) { 3683 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3684 } 3685 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3686 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3687 tcg_temp_free_i32(t2); 3688 tcg_temp_free_i32(t3); 3689 } 3690 break; 3691 case MMI_OPC_MULTU1: 3692 acc = 1; 3693 /* Fall through */ 3694 case OPC_MULTU: 3695 { 3696 TCGv_i32 t2 = tcg_temp_new_i32(); 3697 TCGv_i32 t3 = tcg_temp_new_i32(); 3698 tcg_gen_trunc_tl_i32(t2, t0); 3699 tcg_gen_trunc_tl_i32(t3, t1); 3700 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3701 if (rd) { 3702 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3703 } 3704 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3705 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3706 tcg_temp_free_i32(t2); 3707 tcg_temp_free_i32(t3); 3708 } 3709 break; 3710 case MMI_OPC_MADD1: 3711 acc = 1; 3712 /* Fall through */ 3713 case MMI_OPC_MADD: 3714 { 3715 TCGv_i64 t2 = tcg_temp_new_i64(); 3716 TCGv_i64 t3 = tcg_temp_new_i64(); 3717 3718 tcg_gen_ext_tl_i64(t2, t0); 3719 tcg_gen_ext_tl_i64(t3, t1); 3720 tcg_gen_mul_i64(t2, t2, t3); 3721 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3722 tcg_gen_add_i64(t2, t2, t3); 3723 tcg_temp_free_i64(t3); 3724 gen_move_low32(cpu_LO[acc], t2); 3725 gen_move_high32(cpu_HI[acc], t2); 3726 if (rd) { 3727 gen_move_low32(cpu_gpr[rd], t2); 3728 } 3729 tcg_temp_free_i64(t2); 3730 } 3731 break; 3732 case MMI_OPC_MADDU1: 3733 acc = 1; 3734 /* Fall through */ 3735 case MMI_OPC_MADDU: 3736 { 3737 TCGv_i64 t2 = tcg_temp_new_i64(); 3738 TCGv_i64 t3 = tcg_temp_new_i64(); 3739 3740 tcg_gen_ext32u_tl(t0, t0); 3741 tcg_gen_ext32u_tl(t1, t1); 3742 tcg_gen_extu_tl_i64(t2, t0); 3743 tcg_gen_extu_tl_i64(t3, t1); 3744 tcg_gen_mul_i64(t2, t2, t3); 3745 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3746 tcg_gen_add_i64(t2, t2, t3); 3747 tcg_temp_free_i64(t3); 3748 gen_move_low32(cpu_LO[acc], t2); 3749 gen_move_high32(cpu_HI[acc], t2); 3750 if (rd) { 3751 gen_move_low32(cpu_gpr[rd], t2); 3752 } 3753 tcg_temp_free_i64(t2); 3754 } 3755 break; 3756 default: 3757 MIPS_INVAL("mul/madd TXx9"); 3758 gen_reserved_instruction(ctx); 3759 goto out; 3760 } 3761 3762 out: 3763 tcg_temp_free(t0); 3764 tcg_temp_free(t1); 3765 } 3766 3767 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, 3768 int rd, int rs, int rt) 3769 { 3770 TCGv t0 = tcg_temp_new(); 3771 TCGv t1 = tcg_temp_new(); 3772 3773 gen_load_gpr(t0, rs); 3774 gen_load_gpr(t1, rt); 3775 3776 switch (opc) { 3777 case OPC_VR54XX_MULS: 3778 gen_helper_muls(t0, cpu_env, t0, t1); 3779 break; 3780 case OPC_VR54XX_MULSU: 3781 gen_helper_mulsu(t0, cpu_env, t0, t1); 3782 break; 3783 case OPC_VR54XX_MACC: 3784 gen_helper_macc(t0, cpu_env, t0, t1); 3785 break; 3786 case OPC_VR54XX_MACCU: 3787 gen_helper_maccu(t0, cpu_env, t0, t1); 3788 break; 3789 case OPC_VR54XX_MSAC: 3790 gen_helper_msac(t0, cpu_env, t0, t1); 3791 break; 3792 case OPC_VR54XX_MSACU: 3793 gen_helper_msacu(t0, cpu_env, t0, t1); 3794 break; 3795 case OPC_VR54XX_MULHI: 3796 gen_helper_mulhi(t0, cpu_env, t0, t1); 3797 break; 3798 case OPC_VR54XX_MULHIU: 3799 gen_helper_mulhiu(t0, cpu_env, t0, t1); 3800 break; 3801 case OPC_VR54XX_MULSHI: 3802 gen_helper_mulshi(t0, cpu_env, t0, t1); 3803 break; 3804 case OPC_VR54XX_MULSHIU: 3805 gen_helper_mulshiu(t0, cpu_env, t0, t1); 3806 break; 3807 case OPC_VR54XX_MACCHI: 3808 gen_helper_macchi(t0, cpu_env, t0, t1); 3809 break; 3810 case OPC_VR54XX_MACCHIU: 3811 gen_helper_macchiu(t0, cpu_env, t0, t1); 3812 break; 3813 case OPC_VR54XX_MSACHI: 3814 gen_helper_msachi(t0, cpu_env, t0, t1); 3815 break; 3816 case OPC_VR54XX_MSACHIU: 3817 gen_helper_msachiu(t0, cpu_env, t0, t1); 3818 break; 3819 default: 3820 MIPS_INVAL("mul vr54xx"); 3821 gen_reserved_instruction(ctx); 3822 goto out; 3823 } 3824 gen_store_gpr(t0, rd); 3825 3826 out: 3827 tcg_temp_free(t0); 3828 tcg_temp_free(t1); 3829 } 3830 3831 static void gen_cl(DisasContext *ctx, uint32_t opc, 3832 int rd, int rs) 3833 { 3834 TCGv t0; 3835 3836 if (rd == 0) { 3837 /* Treat as NOP. */ 3838 return; 3839 } 3840 t0 = cpu_gpr[rd]; 3841 gen_load_gpr(t0, rs); 3842 3843 switch (opc) { 3844 case OPC_CLO: 3845 case R6_OPC_CLO: 3846 #if defined(TARGET_MIPS64) 3847 case OPC_DCLO: 3848 case R6_OPC_DCLO: 3849 #endif 3850 tcg_gen_not_tl(t0, t0); 3851 break; 3852 } 3853 3854 switch (opc) { 3855 case OPC_CLO: 3856 case R6_OPC_CLO: 3857 case OPC_CLZ: 3858 case R6_OPC_CLZ: 3859 tcg_gen_ext32u_tl(t0, t0); 3860 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3861 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3862 break; 3863 #if defined(TARGET_MIPS64) 3864 case OPC_DCLO: 3865 case R6_OPC_DCLO: 3866 case OPC_DCLZ: 3867 case R6_OPC_DCLZ: 3868 tcg_gen_clzi_i64(t0, t0, 64); 3869 break; 3870 #endif 3871 } 3872 } 3873 3874 /* Godson integer instructions */ 3875 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3876 int rd, int rs, int rt) 3877 { 3878 TCGv t0, t1; 3879 3880 if (rd == 0) { 3881 /* Treat as NOP. */ 3882 return; 3883 } 3884 3885 switch (opc) { 3886 case OPC_MULT_G_2E: 3887 case OPC_MULT_G_2F: 3888 case OPC_MULTU_G_2E: 3889 case OPC_MULTU_G_2F: 3890 #if defined(TARGET_MIPS64) 3891 case OPC_DMULT_G_2E: 3892 case OPC_DMULT_G_2F: 3893 case OPC_DMULTU_G_2E: 3894 case OPC_DMULTU_G_2F: 3895 #endif 3896 t0 = tcg_temp_new(); 3897 t1 = tcg_temp_new(); 3898 break; 3899 default: 3900 t0 = tcg_temp_local_new(); 3901 t1 = tcg_temp_local_new(); 3902 break; 3903 } 3904 3905 gen_load_gpr(t0, rs); 3906 gen_load_gpr(t1, rt); 3907 3908 switch (opc) { 3909 case OPC_MULT_G_2E: 3910 case OPC_MULT_G_2F: 3911 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3912 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3913 break; 3914 case OPC_MULTU_G_2E: 3915 case OPC_MULTU_G_2F: 3916 tcg_gen_ext32u_tl(t0, t0); 3917 tcg_gen_ext32u_tl(t1, t1); 3918 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3919 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3920 break; 3921 case OPC_DIV_G_2E: 3922 case OPC_DIV_G_2F: 3923 { 3924 TCGLabel *l1 = gen_new_label(); 3925 TCGLabel *l2 = gen_new_label(); 3926 TCGLabel *l3 = gen_new_label(); 3927 tcg_gen_ext32s_tl(t0, t0); 3928 tcg_gen_ext32s_tl(t1, t1); 3929 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3930 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3931 tcg_gen_br(l3); 3932 gen_set_label(l1); 3933 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3934 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3935 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3936 tcg_gen_br(l3); 3937 gen_set_label(l2); 3938 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3939 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3940 gen_set_label(l3); 3941 } 3942 break; 3943 case OPC_DIVU_G_2E: 3944 case OPC_DIVU_G_2F: 3945 { 3946 TCGLabel *l1 = gen_new_label(); 3947 TCGLabel *l2 = gen_new_label(); 3948 tcg_gen_ext32u_tl(t0, t0); 3949 tcg_gen_ext32u_tl(t1, t1); 3950 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3951 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3952 tcg_gen_br(l2); 3953 gen_set_label(l1); 3954 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3955 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3956 gen_set_label(l2); 3957 } 3958 break; 3959 case OPC_MOD_G_2E: 3960 case OPC_MOD_G_2F: 3961 { 3962 TCGLabel *l1 = gen_new_label(); 3963 TCGLabel *l2 = gen_new_label(); 3964 TCGLabel *l3 = gen_new_label(); 3965 tcg_gen_ext32u_tl(t0, t0); 3966 tcg_gen_ext32u_tl(t1, t1); 3967 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3968 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3969 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3970 gen_set_label(l1); 3971 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3972 tcg_gen_br(l3); 3973 gen_set_label(l2); 3974 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3975 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3976 gen_set_label(l3); 3977 } 3978 break; 3979 case OPC_MODU_G_2E: 3980 case OPC_MODU_G_2F: 3981 { 3982 TCGLabel *l1 = gen_new_label(); 3983 TCGLabel *l2 = gen_new_label(); 3984 tcg_gen_ext32u_tl(t0, t0); 3985 tcg_gen_ext32u_tl(t1, t1); 3986 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3987 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3988 tcg_gen_br(l2); 3989 gen_set_label(l1); 3990 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3991 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3992 gen_set_label(l2); 3993 } 3994 break; 3995 #if defined(TARGET_MIPS64) 3996 case OPC_DMULT_G_2E: 3997 case OPC_DMULT_G_2F: 3998 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3999 break; 4000 case OPC_DMULTU_G_2E: 4001 case OPC_DMULTU_G_2F: 4002 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4003 break; 4004 case OPC_DDIV_G_2E: 4005 case OPC_DDIV_G_2F: 4006 { 4007 TCGLabel *l1 = gen_new_label(); 4008 TCGLabel *l2 = gen_new_label(); 4009 TCGLabel *l3 = gen_new_label(); 4010 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4011 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4012 tcg_gen_br(l3); 4013 gen_set_label(l1); 4014 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4015 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4016 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4017 tcg_gen_br(l3); 4018 gen_set_label(l2); 4019 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 4020 gen_set_label(l3); 4021 } 4022 break; 4023 case OPC_DDIVU_G_2E: 4024 case OPC_DDIVU_G_2F: 4025 { 4026 TCGLabel *l1 = gen_new_label(); 4027 TCGLabel *l2 = gen_new_label(); 4028 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4029 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4030 tcg_gen_br(l2); 4031 gen_set_label(l1); 4032 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 4033 gen_set_label(l2); 4034 } 4035 break; 4036 case OPC_DMOD_G_2E: 4037 case OPC_DMOD_G_2F: 4038 { 4039 TCGLabel *l1 = gen_new_label(); 4040 TCGLabel *l2 = gen_new_label(); 4041 TCGLabel *l3 = gen_new_label(); 4042 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 4043 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4044 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4045 gen_set_label(l1); 4046 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4047 tcg_gen_br(l3); 4048 gen_set_label(l2); 4049 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 4050 gen_set_label(l3); 4051 } 4052 break; 4053 case OPC_DMODU_G_2E: 4054 case OPC_DMODU_G_2F: 4055 { 4056 TCGLabel *l1 = gen_new_label(); 4057 TCGLabel *l2 = gen_new_label(); 4058 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4059 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4060 tcg_gen_br(l2); 4061 gen_set_label(l1); 4062 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 4063 gen_set_label(l2); 4064 } 4065 break; 4066 #endif 4067 } 4068 4069 tcg_temp_free(t0); 4070 tcg_temp_free(t1); 4071 } 4072 4073 /* Loongson multimedia instructions */ 4074 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 4075 { 4076 uint32_t opc, shift_max; 4077 TCGv_i64 t0, t1; 4078 TCGCond cond; 4079 4080 opc = MASK_LMMI(ctx->opcode); 4081 switch (opc) { 4082 case OPC_ADD_CP2: 4083 case OPC_SUB_CP2: 4084 case OPC_DADD_CP2: 4085 case OPC_DSUB_CP2: 4086 t0 = tcg_temp_local_new_i64(); 4087 t1 = tcg_temp_local_new_i64(); 4088 break; 4089 default: 4090 t0 = tcg_temp_new_i64(); 4091 t1 = tcg_temp_new_i64(); 4092 break; 4093 } 4094 4095 check_cp1_enabled(ctx); 4096 gen_load_fpr64(ctx, t0, rs); 4097 gen_load_fpr64(ctx, t1, rt); 4098 4099 switch (opc) { 4100 case OPC_PADDSH: 4101 gen_helper_paddsh(t0, t0, t1); 4102 break; 4103 case OPC_PADDUSH: 4104 gen_helper_paddush(t0, t0, t1); 4105 break; 4106 case OPC_PADDH: 4107 gen_helper_paddh(t0, t0, t1); 4108 break; 4109 case OPC_PADDW: 4110 gen_helper_paddw(t0, t0, t1); 4111 break; 4112 case OPC_PADDSB: 4113 gen_helper_paddsb(t0, t0, t1); 4114 break; 4115 case OPC_PADDUSB: 4116 gen_helper_paddusb(t0, t0, t1); 4117 break; 4118 case OPC_PADDB: 4119 gen_helper_paddb(t0, t0, t1); 4120 break; 4121 4122 case OPC_PSUBSH: 4123 gen_helper_psubsh(t0, t0, t1); 4124 break; 4125 case OPC_PSUBUSH: 4126 gen_helper_psubush(t0, t0, t1); 4127 break; 4128 case OPC_PSUBH: 4129 gen_helper_psubh(t0, t0, t1); 4130 break; 4131 case OPC_PSUBW: 4132 gen_helper_psubw(t0, t0, t1); 4133 break; 4134 case OPC_PSUBSB: 4135 gen_helper_psubsb(t0, t0, t1); 4136 break; 4137 case OPC_PSUBUSB: 4138 gen_helper_psubusb(t0, t0, t1); 4139 break; 4140 case OPC_PSUBB: 4141 gen_helper_psubb(t0, t0, t1); 4142 break; 4143 4144 case OPC_PSHUFH: 4145 gen_helper_pshufh(t0, t0, t1); 4146 break; 4147 case OPC_PACKSSWH: 4148 gen_helper_packsswh(t0, t0, t1); 4149 break; 4150 case OPC_PACKSSHB: 4151 gen_helper_packsshb(t0, t0, t1); 4152 break; 4153 case OPC_PACKUSHB: 4154 gen_helper_packushb(t0, t0, t1); 4155 break; 4156 4157 case OPC_PUNPCKLHW: 4158 gen_helper_punpcklhw(t0, t0, t1); 4159 break; 4160 case OPC_PUNPCKHHW: 4161 gen_helper_punpckhhw(t0, t0, t1); 4162 break; 4163 case OPC_PUNPCKLBH: 4164 gen_helper_punpcklbh(t0, t0, t1); 4165 break; 4166 case OPC_PUNPCKHBH: 4167 gen_helper_punpckhbh(t0, t0, t1); 4168 break; 4169 case OPC_PUNPCKLWD: 4170 gen_helper_punpcklwd(t0, t0, t1); 4171 break; 4172 case OPC_PUNPCKHWD: 4173 gen_helper_punpckhwd(t0, t0, t1); 4174 break; 4175 4176 case OPC_PAVGH: 4177 gen_helper_pavgh(t0, t0, t1); 4178 break; 4179 case OPC_PAVGB: 4180 gen_helper_pavgb(t0, t0, t1); 4181 break; 4182 case OPC_PMAXSH: 4183 gen_helper_pmaxsh(t0, t0, t1); 4184 break; 4185 case OPC_PMINSH: 4186 gen_helper_pminsh(t0, t0, t1); 4187 break; 4188 case OPC_PMAXUB: 4189 gen_helper_pmaxub(t0, t0, t1); 4190 break; 4191 case OPC_PMINUB: 4192 gen_helper_pminub(t0, t0, t1); 4193 break; 4194 4195 case OPC_PCMPEQW: 4196 gen_helper_pcmpeqw(t0, t0, t1); 4197 break; 4198 case OPC_PCMPGTW: 4199 gen_helper_pcmpgtw(t0, t0, t1); 4200 break; 4201 case OPC_PCMPEQH: 4202 gen_helper_pcmpeqh(t0, t0, t1); 4203 break; 4204 case OPC_PCMPGTH: 4205 gen_helper_pcmpgth(t0, t0, t1); 4206 break; 4207 case OPC_PCMPEQB: 4208 gen_helper_pcmpeqb(t0, t0, t1); 4209 break; 4210 case OPC_PCMPGTB: 4211 gen_helper_pcmpgtb(t0, t0, t1); 4212 break; 4213 4214 case OPC_PSLLW: 4215 gen_helper_psllw(t0, t0, t1); 4216 break; 4217 case OPC_PSLLH: 4218 gen_helper_psllh(t0, t0, t1); 4219 break; 4220 case OPC_PSRLW: 4221 gen_helper_psrlw(t0, t0, t1); 4222 break; 4223 case OPC_PSRLH: 4224 gen_helper_psrlh(t0, t0, t1); 4225 break; 4226 case OPC_PSRAW: 4227 gen_helper_psraw(t0, t0, t1); 4228 break; 4229 case OPC_PSRAH: 4230 gen_helper_psrah(t0, t0, t1); 4231 break; 4232 4233 case OPC_PMULLH: 4234 gen_helper_pmullh(t0, t0, t1); 4235 break; 4236 case OPC_PMULHH: 4237 gen_helper_pmulhh(t0, t0, t1); 4238 break; 4239 case OPC_PMULHUH: 4240 gen_helper_pmulhuh(t0, t0, t1); 4241 break; 4242 case OPC_PMADDHW: 4243 gen_helper_pmaddhw(t0, t0, t1); 4244 break; 4245 4246 case OPC_PASUBUB: 4247 gen_helper_pasubub(t0, t0, t1); 4248 break; 4249 case OPC_BIADD: 4250 gen_helper_biadd(t0, t0); 4251 break; 4252 case OPC_PMOVMSKB: 4253 gen_helper_pmovmskb(t0, t0); 4254 break; 4255 4256 case OPC_PADDD: 4257 tcg_gen_add_i64(t0, t0, t1); 4258 break; 4259 case OPC_PSUBD: 4260 tcg_gen_sub_i64(t0, t0, t1); 4261 break; 4262 case OPC_XOR_CP2: 4263 tcg_gen_xor_i64(t0, t0, t1); 4264 break; 4265 case OPC_NOR_CP2: 4266 tcg_gen_nor_i64(t0, t0, t1); 4267 break; 4268 case OPC_AND_CP2: 4269 tcg_gen_and_i64(t0, t0, t1); 4270 break; 4271 case OPC_OR_CP2: 4272 tcg_gen_or_i64(t0, t0, t1); 4273 break; 4274 4275 case OPC_PANDN: 4276 tcg_gen_andc_i64(t0, t1, t0); 4277 break; 4278 4279 case OPC_PINSRH_0: 4280 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4281 break; 4282 case OPC_PINSRH_1: 4283 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4284 break; 4285 case OPC_PINSRH_2: 4286 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4287 break; 4288 case OPC_PINSRH_3: 4289 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4290 break; 4291 4292 case OPC_PEXTRH: 4293 tcg_gen_andi_i64(t1, t1, 3); 4294 tcg_gen_shli_i64(t1, t1, 4); 4295 tcg_gen_shr_i64(t0, t0, t1); 4296 tcg_gen_ext16u_i64(t0, t0); 4297 break; 4298 4299 case OPC_ADDU_CP2: 4300 tcg_gen_add_i64(t0, t0, t1); 4301 tcg_gen_ext32s_i64(t0, t0); 4302 break; 4303 case OPC_SUBU_CP2: 4304 tcg_gen_sub_i64(t0, t0, t1); 4305 tcg_gen_ext32s_i64(t0, t0); 4306 break; 4307 4308 case OPC_SLL_CP2: 4309 shift_max = 32; 4310 goto do_shift; 4311 case OPC_SRL_CP2: 4312 shift_max = 32; 4313 goto do_shift; 4314 case OPC_SRA_CP2: 4315 shift_max = 32; 4316 goto do_shift; 4317 case OPC_DSLL_CP2: 4318 shift_max = 64; 4319 goto do_shift; 4320 case OPC_DSRL_CP2: 4321 shift_max = 64; 4322 goto do_shift; 4323 case OPC_DSRA_CP2: 4324 shift_max = 64; 4325 goto do_shift; 4326 do_shift: 4327 /* Make sure shift count isn't TCG undefined behaviour. */ 4328 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4329 4330 switch (opc) { 4331 case OPC_SLL_CP2: 4332 case OPC_DSLL_CP2: 4333 tcg_gen_shl_i64(t0, t0, t1); 4334 break; 4335 case OPC_SRA_CP2: 4336 case OPC_DSRA_CP2: 4337 /* 4338 * Since SRA is UndefinedResult without sign-extended inputs, 4339 * we can treat SRA and DSRA the same. 4340 */ 4341 tcg_gen_sar_i64(t0, t0, t1); 4342 break; 4343 case OPC_SRL_CP2: 4344 /* We want to shift in zeros for SRL; zero-extend first. */ 4345 tcg_gen_ext32u_i64(t0, t0); 4346 /* FALLTHRU */ 4347 case OPC_DSRL_CP2: 4348 tcg_gen_shr_i64(t0, t0, t1); 4349 break; 4350 } 4351 4352 if (shift_max == 32) { 4353 tcg_gen_ext32s_i64(t0, t0); 4354 } 4355 4356 /* Shifts larger than MAX produce zero. */ 4357 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4358 tcg_gen_neg_i64(t1, t1); 4359 tcg_gen_and_i64(t0, t0, t1); 4360 break; 4361 4362 case OPC_ADD_CP2: 4363 case OPC_DADD_CP2: 4364 { 4365 TCGv_i64 t2 = tcg_temp_new_i64(); 4366 TCGLabel *lab = gen_new_label(); 4367 4368 tcg_gen_mov_i64(t2, t0); 4369 tcg_gen_add_i64(t0, t1, t2); 4370 if (opc == OPC_ADD_CP2) { 4371 tcg_gen_ext32s_i64(t0, t0); 4372 } 4373 tcg_gen_xor_i64(t1, t1, t2); 4374 tcg_gen_xor_i64(t2, t2, t0); 4375 tcg_gen_andc_i64(t1, t2, t1); 4376 tcg_temp_free_i64(t2); 4377 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4378 generate_exception(ctx, EXCP_OVERFLOW); 4379 gen_set_label(lab); 4380 break; 4381 } 4382 4383 case OPC_SUB_CP2: 4384 case OPC_DSUB_CP2: 4385 { 4386 TCGv_i64 t2 = tcg_temp_new_i64(); 4387 TCGLabel *lab = gen_new_label(); 4388 4389 tcg_gen_mov_i64(t2, t0); 4390 tcg_gen_sub_i64(t0, t1, t2); 4391 if (opc == OPC_SUB_CP2) { 4392 tcg_gen_ext32s_i64(t0, t0); 4393 } 4394 tcg_gen_xor_i64(t1, t1, t2); 4395 tcg_gen_xor_i64(t2, t2, t0); 4396 tcg_gen_and_i64(t1, t1, t2); 4397 tcg_temp_free_i64(t2); 4398 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4399 generate_exception(ctx, EXCP_OVERFLOW); 4400 gen_set_label(lab); 4401 break; 4402 } 4403 4404 case OPC_PMULUW: 4405 tcg_gen_ext32u_i64(t0, t0); 4406 tcg_gen_ext32u_i64(t1, t1); 4407 tcg_gen_mul_i64(t0, t0, t1); 4408 break; 4409 4410 case OPC_SEQU_CP2: 4411 case OPC_SEQ_CP2: 4412 cond = TCG_COND_EQ; 4413 goto do_cc_cond; 4414 break; 4415 case OPC_SLTU_CP2: 4416 cond = TCG_COND_LTU; 4417 goto do_cc_cond; 4418 break; 4419 case OPC_SLT_CP2: 4420 cond = TCG_COND_LT; 4421 goto do_cc_cond; 4422 break; 4423 case OPC_SLEU_CP2: 4424 cond = TCG_COND_LEU; 4425 goto do_cc_cond; 4426 break; 4427 case OPC_SLE_CP2: 4428 cond = TCG_COND_LE; 4429 do_cc_cond: 4430 { 4431 int cc = (ctx->opcode >> 8) & 0x7; 4432 TCGv_i64 t64 = tcg_temp_new_i64(); 4433 TCGv_i32 t32 = tcg_temp_new_i32(); 4434 4435 tcg_gen_setcond_i64(cond, t64, t0, t1); 4436 tcg_gen_extrl_i64_i32(t32, t64); 4437 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4438 get_fp_bit(cc), 1); 4439 4440 tcg_temp_free_i32(t32); 4441 tcg_temp_free_i64(t64); 4442 } 4443 goto no_rd; 4444 break; 4445 default: 4446 MIPS_INVAL("loongson_cp2"); 4447 gen_reserved_instruction(ctx); 4448 return; 4449 } 4450 4451 gen_store_fpr64(ctx, t0, rd); 4452 4453 no_rd: 4454 tcg_temp_free_i64(t0); 4455 tcg_temp_free_i64(t1); 4456 } 4457 4458 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4459 int rs, int rd) 4460 { 4461 TCGv t0, t1, t2; 4462 TCGv_i32 fp0; 4463 #if defined(TARGET_MIPS64) 4464 int lsq_rt1 = ctx->opcode & 0x1f; 4465 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4466 #endif 4467 int shf_offset = sextract32(ctx->opcode, 6, 8); 4468 4469 t0 = tcg_temp_new(); 4470 4471 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4472 #if defined(TARGET_MIPS64) 4473 case OPC_GSLQ: 4474 t1 = tcg_temp_new(); 4475 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4476 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4477 ctx->default_tcg_memop_mask); 4478 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4479 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4480 ctx->default_tcg_memop_mask); 4481 gen_store_gpr(t1, rt); 4482 gen_store_gpr(t0, lsq_rt1); 4483 tcg_temp_free(t1); 4484 break; 4485 case OPC_GSLQC1: 4486 check_cp1_enabled(ctx); 4487 t1 = tcg_temp_new(); 4488 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4489 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4490 ctx->default_tcg_memop_mask); 4491 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4492 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4493 ctx->default_tcg_memop_mask); 4494 gen_store_fpr64(ctx, t1, rt); 4495 gen_store_fpr64(ctx, t0, lsq_rt1); 4496 tcg_temp_free(t1); 4497 break; 4498 case OPC_GSSQ: 4499 t1 = tcg_temp_new(); 4500 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4501 gen_load_gpr(t1, rt); 4502 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4503 ctx->default_tcg_memop_mask); 4504 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4505 gen_load_gpr(t1, lsq_rt1); 4506 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4507 ctx->default_tcg_memop_mask); 4508 tcg_temp_free(t1); 4509 break; 4510 case OPC_GSSQC1: 4511 check_cp1_enabled(ctx); 4512 t1 = tcg_temp_new(); 4513 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4514 gen_load_fpr64(ctx, t1, rt); 4515 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4516 ctx->default_tcg_memop_mask); 4517 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4518 gen_load_fpr64(ctx, t1, lsq_rt1); 4519 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4520 ctx->default_tcg_memop_mask); 4521 tcg_temp_free(t1); 4522 break; 4523 #endif 4524 case OPC_GSSHFL: 4525 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4526 case OPC_GSLWLC1: 4527 check_cp1_enabled(ctx); 4528 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4529 t1 = tcg_temp_new(); 4530 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4531 tcg_gen_andi_tl(t1, t0, 3); 4532 #ifndef TARGET_WORDS_BIGENDIAN 4533 tcg_gen_xori_tl(t1, t1, 3); 4534 #endif 4535 tcg_gen_shli_tl(t1, t1, 3); 4536 tcg_gen_andi_tl(t0, t0, ~3); 4537 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4538 tcg_gen_shl_tl(t0, t0, t1); 4539 t2 = tcg_const_tl(-1); 4540 tcg_gen_shl_tl(t2, t2, t1); 4541 fp0 = tcg_temp_new_i32(); 4542 gen_load_fpr32(ctx, fp0, rt); 4543 tcg_gen_ext_i32_tl(t1, fp0); 4544 tcg_gen_andc_tl(t1, t1, t2); 4545 tcg_temp_free(t2); 4546 tcg_gen_or_tl(t0, t0, t1); 4547 tcg_temp_free(t1); 4548 #if defined(TARGET_MIPS64) 4549 tcg_gen_extrl_i64_i32(fp0, t0); 4550 #else 4551 tcg_gen_ext32s_tl(fp0, t0); 4552 #endif 4553 gen_store_fpr32(ctx, fp0, rt); 4554 tcg_temp_free_i32(fp0); 4555 break; 4556 case OPC_GSLWRC1: 4557 check_cp1_enabled(ctx); 4558 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4559 t1 = tcg_temp_new(); 4560 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4561 tcg_gen_andi_tl(t1, t0, 3); 4562 #ifdef TARGET_WORDS_BIGENDIAN 4563 tcg_gen_xori_tl(t1, t1, 3); 4564 #endif 4565 tcg_gen_shli_tl(t1, t1, 3); 4566 tcg_gen_andi_tl(t0, t0, ~3); 4567 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4568 tcg_gen_shr_tl(t0, t0, t1); 4569 tcg_gen_xori_tl(t1, t1, 31); 4570 t2 = tcg_const_tl(0xfffffffeull); 4571 tcg_gen_shl_tl(t2, t2, t1); 4572 fp0 = tcg_temp_new_i32(); 4573 gen_load_fpr32(ctx, fp0, rt); 4574 tcg_gen_ext_i32_tl(t1, fp0); 4575 tcg_gen_and_tl(t1, t1, t2); 4576 tcg_temp_free(t2); 4577 tcg_gen_or_tl(t0, t0, t1); 4578 tcg_temp_free(t1); 4579 #if defined(TARGET_MIPS64) 4580 tcg_gen_extrl_i64_i32(fp0, t0); 4581 #else 4582 tcg_gen_ext32s_tl(fp0, t0); 4583 #endif 4584 gen_store_fpr32(ctx, fp0, rt); 4585 tcg_temp_free_i32(fp0); 4586 break; 4587 #if defined(TARGET_MIPS64) 4588 case OPC_GSLDLC1: 4589 check_cp1_enabled(ctx); 4590 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4591 t1 = tcg_temp_new(); 4592 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4593 tcg_gen_andi_tl(t1, t0, 7); 4594 #ifndef TARGET_WORDS_BIGENDIAN 4595 tcg_gen_xori_tl(t1, t1, 7); 4596 #endif 4597 tcg_gen_shli_tl(t1, t1, 3); 4598 tcg_gen_andi_tl(t0, t0, ~7); 4599 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4600 tcg_gen_shl_tl(t0, t0, t1); 4601 t2 = tcg_const_tl(-1); 4602 tcg_gen_shl_tl(t2, t2, t1); 4603 gen_load_fpr64(ctx, t1, rt); 4604 tcg_gen_andc_tl(t1, t1, t2); 4605 tcg_temp_free(t2); 4606 tcg_gen_or_tl(t0, t0, t1); 4607 tcg_temp_free(t1); 4608 gen_store_fpr64(ctx, t0, rt); 4609 break; 4610 case OPC_GSLDRC1: 4611 check_cp1_enabled(ctx); 4612 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4613 t1 = tcg_temp_new(); 4614 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4615 tcg_gen_andi_tl(t1, t0, 7); 4616 #ifdef TARGET_WORDS_BIGENDIAN 4617 tcg_gen_xori_tl(t1, t1, 7); 4618 #endif 4619 tcg_gen_shli_tl(t1, t1, 3); 4620 tcg_gen_andi_tl(t0, t0, ~7); 4621 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4622 tcg_gen_shr_tl(t0, t0, t1); 4623 tcg_gen_xori_tl(t1, t1, 63); 4624 t2 = tcg_const_tl(0xfffffffffffffffeull); 4625 tcg_gen_shl_tl(t2, t2, t1); 4626 gen_load_fpr64(ctx, t1, rt); 4627 tcg_gen_and_tl(t1, t1, t2); 4628 tcg_temp_free(t2); 4629 tcg_gen_or_tl(t0, t0, t1); 4630 tcg_temp_free(t1); 4631 gen_store_fpr64(ctx, t0, rt); 4632 break; 4633 #endif 4634 default: 4635 MIPS_INVAL("loongson_gsshfl"); 4636 gen_reserved_instruction(ctx); 4637 break; 4638 } 4639 break; 4640 case OPC_GSSHFS: 4641 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4642 case OPC_GSSWLC1: 4643 check_cp1_enabled(ctx); 4644 t1 = tcg_temp_new(); 4645 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4646 fp0 = tcg_temp_new_i32(); 4647 gen_load_fpr32(ctx, fp0, rt); 4648 tcg_gen_ext_i32_tl(t1, fp0); 4649 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4650 tcg_temp_free_i32(fp0); 4651 tcg_temp_free(t1); 4652 break; 4653 case OPC_GSSWRC1: 4654 check_cp1_enabled(ctx); 4655 t1 = tcg_temp_new(); 4656 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4657 fp0 = tcg_temp_new_i32(); 4658 gen_load_fpr32(ctx, fp0, rt); 4659 tcg_gen_ext_i32_tl(t1, fp0); 4660 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4661 tcg_temp_free_i32(fp0); 4662 tcg_temp_free(t1); 4663 break; 4664 #if defined(TARGET_MIPS64) 4665 case OPC_GSSDLC1: 4666 check_cp1_enabled(ctx); 4667 t1 = tcg_temp_new(); 4668 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4669 gen_load_fpr64(ctx, t1, rt); 4670 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4671 tcg_temp_free(t1); 4672 break; 4673 case OPC_GSSDRC1: 4674 check_cp1_enabled(ctx); 4675 t1 = tcg_temp_new(); 4676 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4677 gen_load_fpr64(ctx, t1, rt); 4678 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4679 tcg_temp_free(t1); 4680 break; 4681 #endif 4682 default: 4683 MIPS_INVAL("loongson_gsshfs"); 4684 gen_reserved_instruction(ctx); 4685 break; 4686 } 4687 break; 4688 default: 4689 MIPS_INVAL("loongson_gslsq"); 4690 gen_reserved_instruction(ctx); 4691 break; 4692 } 4693 tcg_temp_free(t0); 4694 } 4695 4696 /* Loongson EXT LDC2/SDC2 */ 4697 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4698 int rs, int rd) 4699 { 4700 int offset = sextract32(ctx->opcode, 3, 8); 4701 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4702 TCGv t0, t1; 4703 TCGv_i32 fp0; 4704 4705 /* Pre-conditions */ 4706 switch (opc) { 4707 case OPC_GSLBX: 4708 case OPC_GSLHX: 4709 case OPC_GSLWX: 4710 case OPC_GSLDX: 4711 /* prefetch, implement as NOP */ 4712 if (rt == 0) { 4713 return; 4714 } 4715 break; 4716 case OPC_GSSBX: 4717 case OPC_GSSHX: 4718 case OPC_GSSWX: 4719 case OPC_GSSDX: 4720 break; 4721 case OPC_GSLWXC1: 4722 #if defined(TARGET_MIPS64) 4723 case OPC_GSLDXC1: 4724 #endif 4725 check_cp1_enabled(ctx); 4726 /* prefetch, implement as NOP */ 4727 if (rt == 0) { 4728 return; 4729 } 4730 break; 4731 case OPC_GSSWXC1: 4732 #if defined(TARGET_MIPS64) 4733 case OPC_GSSDXC1: 4734 #endif 4735 check_cp1_enabled(ctx); 4736 break; 4737 default: 4738 MIPS_INVAL("loongson_lsdc2"); 4739 gen_reserved_instruction(ctx); 4740 return; 4741 break; 4742 } 4743 4744 t0 = tcg_temp_new(); 4745 4746 gen_base_offset_addr(ctx, t0, rs, offset); 4747 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4748 4749 switch (opc) { 4750 case OPC_GSLBX: 4751 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4752 gen_store_gpr(t0, rt); 4753 break; 4754 case OPC_GSLHX: 4755 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4756 ctx->default_tcg_memop_mask); 4757 gen_store_gpr(t0, rt); 4758 break; 4759 case OPC_GSLWX: 4760 gen_base_offset_addr(ctx, t0, rs, offset); 4761 if (rd) { 4762 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4763 } 4764 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4765 ctx->default_tcg_memop_mask); 4766 gen_store_gpr(t0, rt); 4767 break; 4768 #if defined(TARGET_MIPS64) 4769 case OPC_GSLDX: 4770 gen_base_offset_addr(ctx, t0, rs, offset); 4771 if (rd) { 4772 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4773 } 4774 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4775 ctx->default_tcg_memop_mask); 4776 gen_store_gpr(t0, rt); 4777 break; 4778 #endif 4779 case OPC_GSLWXC1: 4780 check_cp1_enabled(ctx); 4781 gen_base_offset_addr(ctx, t0, rs, offset); 4782 if (rd) { 4783 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4784 } 4785 fp0 = tcg_temp_new_i32(); 4786 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4787 ctx->default_tcg_memop_mask); 4788 gen_store_fpr32(ctx, fp0, rt); 4789 tcg_temp_free_i32(fp0); 4790 break; 4791 #if defined(TARGET_MIPS64) 4792 case OPC_GSLDXC1: 4793 check_cp1_enabled(ctx); 4794 gen_base_offset_addr(ctx, t0, rs, offset); 4795 if (rd) { 4796 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4797 } 4798 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4799 ctx->default_tcg_memop_mask); 4800 gen_store_fpr64(ctx, t0, rt); 4801 break; 4802 #endif 4803 case OPC_GSSBX: 4804 t1 = tcg_temp_new(); 4805 gen_load_gpr(t1, rt); 4806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4807 tcg_temp_free(t1); 4808 break; 4809 case OPC_GSSHX: 4810 t1 = tcg_temp_new(); 4811 gen_load_gpr(t1, rt); 4812 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4813 ctx->default_tcg_memop_mask); 4814 tcg_temp_free(t1); 4815 break; 4816 case OPC_GSSWX: 4817 t1 = tcg_temp_new(); 4818 gen_load_gpr(t1, rt); 4819 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4820 ctx->default_tcg_memop_mask); 4821 tcg_temp_free(t1); 4822 break; 4823 #if defined(TARGET_MIPS64) 4824 case OPC_GSSDX: 4825 t1 = tcg_temp_new(); 4826 gen_load_gpr(t1, rt); 4827 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4828 ctx->default_tcg_memop_mask); 4829 tcg_temp_free(t1); 4830 break; 4831 #endif 4832 case OPC_GSSWXC1: 4833 fp0 = tcg_temp_new_i32(); 4834 gen_load_fpr32(ctx, fp0, rt); 4835 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4836 ctx->default_tcg_memop_mask); 4837 tcg_temp_free_i32(fp0); 4838 break; 4839 #if defined(TARGET_MIPS64) 4840 case OPC_GSSDXC1: 4841 t1 = tcg_temp_new(); 4842 gen_load_fpr64(ctx, t1, rt); 4843 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | 4844 ctx->default_tcg_memop_mask); 4845 tcg_temp_free(t1); 4846 break; 4847 #endif 4848 default: 4849 break; 4850 } 4851 4852 tcg_temp_free(t0); 4853 } 4854 4855 /* Traps */ 4856 static void gen_trap(DisasContext *ctx, uint32_t opc, 4857 int rs, int rt, int16_t imm) 4858 { 4859 int cond; 4860 TCGv t0 = tcg_temp_new(); 4861 TCGv t1 = tcg_temp_new(); 4862 4863 cond = 0; 4864 /* Load needed operands */ 4865 switch (opc) { 4866 case OPC_TEQ: 4867 case OPC_TGE: 4868 case OPC_TGEU: 4869 case OPC_TLT: 4870 case OPC_TLTU: 4871 case OPC_TNE: 4872 /* Compare two registers */ 4873 if (rs != rt) { 4874 gen_load_gpr(t0, rs); 4875 gen_load_gpr(t1, rt); 4876 cond = 1; 4877 } 4878 break; 4879 case OPC_TEQI: 4880 case OPC_TGEI: 4881 case OPC_TGEIU: 4882 case OPC_TLTI: 4883 case OPC_TLTIU: 4884 case OPC_TNEI: 4885 /* Compare register to immediate */ 4886 if (rs != 0 || imm != 0) { 4887 gen_load_gpr(t0, rs); 4888 tcg_gen_movi_tl(t1, (int32_t)imm); 4889 cond = 1; 4890 } 4891 break; 4892 } 4893 if (cond == 0) { 4894 switch (opc) { 4895 case OPC_TEQ: /* rs == rs */ 4896 case OPC_TEQI: /* r0 == 0 */ 4897 case OPC_TGE: /* rs >= rs */ 4898 case OPC_TGEI: /* r0 >= 0 */ 4899 case OPC_TGEU: /* rs >= rs unsigned */ 4900 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4901 /* Always trap */ 4902 generate_exception_end(ctx, EXCP_TRAP); 4903 break; 4904 case OPC_TLT: /* rs < rs */ 4905 case OPC_TLTI: /* r0 < 0 */ 4906 case OPC_TLTU: /* rs < rs unsigned */ 4907 case OPC_TLTIU: /* r0 < 0 unsigned */ 4908 case OPC_TNE: /* rs != rs */ 4909 case OPC_TNEI: /* r0 != 0 */ 4910 /* Never trap: treat as NOP. */ 4911 break; 4912 } 4913 } else { 4914 TCGLabel *l1 = gen_new_label(); 4915 4916 switch (opc) { 4917 case OPC_TEQ: 4918 case OPC_TEQI: 4919 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4920 break; 4921 case OPC_TGE: 4922 case OPC_TGEI: 4923 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4924 break; 4925 case OPC_TGEU: 4926 case OPC_TGEIU: 4927 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4928 break; 4929 case OPC_TLT: 4930 case OPC_TLTI: 4931 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4932 break; 4933 case OPC_TLTU: 4934 case OPC_TLTIU: 4935 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4936 break; 4937 case OPC_TNE: 4938 case OPC_TNEI: 4939 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4940 break; 4941 } 4942 generate_exception(ctx, EXCP_TRAP); 4943 gen_set_label(l1); 4944 } 4945 tcg_temp_free(t0); 4946 tcg_temp_free(t1); 4947 } 4948 4949 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4950 { 4951 if (translator_use_goto_tb(&ctx->base, dest)) { 4952 tcg_gen_goto_tb(n); 4953 gen_save_pc(dest); 4954 tcg_gen_exit_tb(ctx->base.tb, n); 4955 } else { 4956 gen_save_pc(dest); 4957 if (ctx->base.singlestep_enabled) { 4958 save_cpu_state(ctx, 0); 4959 gen_helper_raise_exception_debug(cpu_env); 4960 } else { 4961 tcg_gen_lookup_and_goto_ptr(); 4962 } 4963 } 4964 } 4965 4966 /* Branches (before delay slot) */ 4967 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4968 int insn_bytes, 4969 int rs, int rt, int32_t offset, 4970 int delayslot_size) 4971 { 4972 target_ulong btgt = -1; 4973 int blink = 0; 4974 int bcond_compute = 0; 4975 TCGv t0 = tcg_temp_new(); 4976 TCGv t1 = tcg_temp_new(); 4977 4978 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4979 #ifdef MIPS_DEBUG_DISAS 4980 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4981 TARGET_FMT_lx "\n", ctx->base.pc_next); 4982 #endif 4983 gen_reserved_instruction(ctx); 4984 goto out; 4985 } 4986 4987 /* Load needed operands */ 4988 switch (opc) { 4989 case OPC_BEQ: 4990 case OPC_BEQL: 4991 case OPC_BNE: 4992 case OPC_BNEL: 4993 /* Compare two registers */ 4994 if (rs != rt) { 4995 gen_load_gpr(t0, rs); 4996 gen_load_gpr(t1, rt); 4997 bcond_compute = 1; 4998 } 4999 btgt = ctx->base.pc_next + insn_bytes + offset; 5000 break; 5001 case OPC_BGEZ: 5002 case OPC_BGEZAL: 5003 case OPC_BGEZALL: 5004 case OPC_BGEZL: 5005 case OPC_BGTZ: 5006 case OPC_BGTZL: 5007 case OPC_BLEZ: 5008 case OPC_BLEZL: 5009 case OPC_BLTZ: 5010 case OPC_BLTZAL: 5011 case OPC_BLTZALL: 5012 case OPC_BLTZL: 5013 /* Compare to zero */ 5014 if (rs != 0) { 5015 gen_load_gpr(t0, rs); 5016 bcond_compute = 1; 5017 } 5018 btgt = ctx->base.pc_next + insn_bytes + offset; 5019 break; 5020 case OPC_BPOSGE32: 5021 #if defined(TARGET_MIPS64) 5022 case OPC_BPOSGE64: 5023 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 5024 #else 5025 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 5026 #endif 5027 bcond_compute = 1; 5028 btgt = ctx->base.pc_next + insn_bytes + offset; 5029 break; 5030 case OPC_J: 5031 case OPC_JAL: 5032 case OPC_JALX: 5033 /* Jump to immediate */ 5034 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 5035 (uint32_t)offset; 5036 break; 5037 case OPC_JR: 5038 case OPC_JALR: 5039 /* Jump to register */ 5040 if (offset != 0 && offset != 16) { 5041 /* 5042 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 5043 * others are reserved. 5044 */ 5045 MIPS_INVAL("jump hint"); 5046 gen_reserved_instruction(ctx); 5047 goto out; 5048 } 5049 gen_load_gpr(btarget, rs); 5050 break; 5051 default: 5052 MIPS_INVAL("branch/jump"); 5053 gen_reserved_instruction(ctx); 5054 goto out; 5055 } 5056 if (bcond_compute == 0) { 5057 /* No condition to be computed */ 5058 switch (opc) { 5059 case OPC_BEQ: /* rx == rx */ 5060 case OPC_BEQL: /* rx == rx likely */ 5061 case OPC_BGEZ: /* 0 >= 0 */ 5062 case OPC_BGEZL: /* 0 >= 0 likely */ 5063 case OPC_BLEZ: /* 0 <= 0 */ 5064 case OPC_BLEZL: /* 0 <= 0 likely */ 5065 /* Always take */ 5066 ctx->hflags |= MIPS_HFLAG_B; 5067 break; 5068 case OPC_BGEZAL: /* 0 >= 0 */ 5069 case OPC_BGEZALL: /* 0 >= 0 likely */ 5070 /* Always take and link */ 5071 blink = 31; 5072 ctx->hflags |= MIPS_HFLAG_B; 5073 break; 5074 case OPC_BNE: /* rx != rx */ 5075 case OPC_BGTZ: /* 0 > 0 */ 5076 case OPC_BLTZ: /* 0 < 0 */ 5077 /* Treat as NOP. */ 5078 goto out; 5079 case OPC_BLTZAL: /* 0 < 0 */ 5080 /* 5081 * Handle as an unconditional branch to get correct delay 5082 * slot checking. 5083 */ 5084 blink = 31; 5085 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 5086 ctx->hflags |= MIPS_HFLAG_B; 5087 break; 5088 case OPC_BLTZALL: /* 0 < 0 likely */ 5089 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 5090 /* Skip the instruction in the delay slot */ 5091 ctx->base.pc_next += 4; 5092 goto out; 5093 case OPC_BNEL: /* rx != rx likely */ 5094 case OPC_BGTZL: /* 0 > 0 likely */ 5095 case OPC_BLTZL: /* 0 < 0 likely */ 5096 /* Skip the instruction in the delay slot */ 5097 ctx->base.pc_next += 4; 5098 goto out; 5099 case OPC_J: 5100 ctx->hflags |= MIPS_HFLAG_B; 5101 break; 5102 case OPC_JALX: 5103 ctx->hflags |= MIPS_HFLAG_BX; 5104 /* Fallthrough */ 5105 case OPC_JAL: 5106 blink = 31; 5107 ctx->hflags |= MIPS_HFLAG_B; 5108 break; 5109 case OPC_JR: 5110 ctx->hflags |= MIPS_HFLAG_BR; 5111 break; 5112 case OPC_JALR: 5113 blink = rt; 5114 ctx->hflags |= MIPS_HFLAG_BR; 5115 break; 5116 default: 5117 MIPS_INVAL("branch/jump"); 5118 gen_reserved_instruction(ctx); 5119 goto out; 5120 } 5121 } else { 5122 switch (opc) { 5123 case OPC_BEQ: 5124 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5125 goto not_likely; 5126 case OPC_BEQL: 5127 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5128 goto likely; 5129 case OPC_BNE: 5130 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5131 goto not_likely; 5132 case OPC_BNEL: 5133 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5134 goto likely; 5135 case OPC_BGEZ: 5136 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5137 goto not_likely; 5138 case OPC_BGEZL: 5139 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5140 goto likely; 5141 case OPC_BGEZAL: 5142 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5143 blink = 31; 5144 goto not_likely; 5145 case OPC_BGEZALL: 5146 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5147 blink = 31; 5148 goto likely; 5149 case OPC_BGTZ: 5150 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5151 goto not_likely; 5152 case OPC_BGTZL: 5153 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5154 goto likely; 5155 case OPC_BLEZ: 5156 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5157 goto not_likely; 5158 case OPC_BLEZL: 5159 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5160 goto likely; 5161 case OPC_BLTZ: 5162 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5163 goto not_likely; 5164 case OPC_BLTZL: 5165 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5166 goto likely; 5167 case OPC_BPOSGE32: 5168 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5169 goto not_likely; 5170 #if defined(TARGET_MIPS64) 5171 case OPC_BPOSGE64: 5172 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5173 goto not_likely; 5174 #endif 5175 case OPC_BLTZAL: 5176 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5177 blink = 31; 5178 not_likely: 5179 ctx->hflags |= MIPS_HFLAG_BC; 5180 break; 5181 case OPC_BLTZALL: 5182 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5183 blink = 31; 5184 likely: 5185 ctx->hflags |= MIPS_HFLAG_BL; 5186 break; 5187 default: 5188 MIPS_INVAL("conditional branch/jump"); 5189 gen_reserved_instruction(ctx); 5190 goto out; 5191 } 5192 } 5193 5194 ctx->btarget = btgt; 5195 5196 switch (delayslot_size) { 5197 case 2: 5198 ctx->hflags |= MIPS_HFLAG_BDS16; 5199 break; 5200 case 4: 5201 ctx->hflags |= MIPS_HFLAG_BDS32; 5202 break; 5203 } 5204 5205 if (blink > 0) { 5206 int post_delay = insn_bytes + delayslot_size; 5207 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5208 5209 tcg_gen_movi_tl(cpu_gpr[blink], 5210 ctx->base.pc_next + post_delay + lowbit); 5211 } 5212 5213 out: 5214 if (insn_bytes == 2) { 5215 ctx->hflags |= MIPS_HFLAG_B16; 5216 } 5217 tcg_temp_free(t0); 5218 tcg_temp_free(t1); 5219 } 5220 5221 5222 /* special3 bitfield operations */ 5223 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5224 int rs, int lsb, int msb) 5225 { 5226 TCGv t0 = tcg_temp_new(); 5227 TCGv t1 = tcg_temp_new(); 5228 5229 gen_load_gpr(t1, rs); 5230 switch (opc) { 5231 case OPC_EXT: 5232 if (lsb + msb > 31) { 5233 goto fail; 5234 } 5235 if (msb != 31) { 5236 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5237 } else { 5238 /* 5239 * The two checks together imply that lsb == 0, 5240 * so this is a simple sign-extension. 5241 */ 5242 tcg_gen_ext32s_tl(t0, t1); 5243 } 5244 break; 5245 #if defined(TARGET_MIPS64) 5246 case OPC_DEXTU: 5247 lsb += 32; 5248 goto do_dext; 5249 case OPC_DEXTM: 5250 msb += 32; 5251 goto do_dext; 5252 case OPC_DEXT: 5253 do_dext: 5254 if (lsb + msb > 63) { 5255 goto fail; 5256 } 5257 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5258 break; 5259 #endif 5260 case OPC_INS: 5261 if (lsb > msb) { 5262 goto fail; 5263 } 5264 gen_load_gpr(t0, rt); 5265 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5266 tcg_gen_ext32s_tl(t0, t0); 5267 break; 5268 #if defined(TARGET_MIPS64) 5269 case OPC_DINSU: 5270 lsb += 32; 5271 /* FALLTHRU */ 5272 case OPC_DINSM: 5273 msb += 32; 5274 /* FALLTHRU */ 5275 case OPC_DINS: 5276 if (lsb > msb) { 5277 goto fail; 5278 } 5279 gen_load_gpr(t0, rt); 5280 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5281 break; 5282 #endif 5283 default: 5284 fail: 5285 MIPS_INVAL("bitops"); 5286 gen_reserved_instruction(ctx); 5287 tcg_temp_free(t0); 5288 tcg_temp_free(t1); 5289 return; 5290 } 5291 gen_store_gpr(t0, rt); 5292 tcg_temp_free(t0); 5293 tcg_temp_free(t1); 5294 } 5295 5296 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5297 { 5298 TCGv t0; 5299 5300 if (rd == 0) { 5301 /* If no destination, treat it as a NOP. */ 5302 return; 5303 } 5304 5305 t0 = tcg_temp_new(); 5306 gen_load_gpr(t0, rt); 5307 switch (op2) { 5308 case OPC_WSBH: 5309 { 5310 TCGv t1 = tcg_temp_new(); 5311 TCGv t2 = tcg_const_tl(0x00FF00FF); 5312 5313 tcg_gen_shri_tl(t1, t0, 8); 5314 tcg_gen_and_tl(t1, t1, t2); 5315 tcg_gen_and_tl(t0, t0, t2); 5316 tcg_gen_shli_tl(t0, t0, 8); 5317 tcg_gen_or_tl(t0, t0, t1); 5318 tcg_temp_free(t2); 5319 tcg_temp_free(t1); 5320 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5321 } 5322 break; 5323 case OPC_SEB: 5324 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5325 break; 5326 case OPC_SEH: 5327 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5328 break; 5329 #if defined(TARGET_MIPS64) 5330 case OPC_DSBH: 5331 { 5332 TCGv t1 = tcg_temp_new(); 5333 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5334 5335 tcg_gen_shri_tl(t1, t0, 8); 5336 tcg_gen_and_tl(t1, t1, t2); 5337 tcg_gen_and_tl(t0, t0, t2); 5338 tcg_gen_shli_tl(t0, t0, 8); 5339 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5340 tcg_temp_free(t2); 5341 tcg_temp_free(t1); 5342 } 5343 break; 5344 case OPC_DSHD: 5345 { 5346 TCGv t1 = tcg_temp_new(); 5347 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5348 5349 tcg_gen_shri_tl(t1, t0, 16); 5350 tcg_gen_and_tl(t1, t1, t2); 5351 tcg_gen_and_tl(t0, t0, t2); 5352 tcg_gen_shli_tl(t0, t0, 16); 5353 tcg_gen_or_tl(t0, t0, t1); 5354 tcg_gen_shri_tl(t1, t0, 32); 5355 tcg_gen_shli_tl(t0, t0, 32); 5356 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5357 tcg_temp_free(t2); 5358 tcg_temp_free(t1); 5359 } 5360 break; 5361 #endif 5362 default: 5363 MIPS_INVAL("bsfhl"); 5364 gen_reserved_instruction(ctx); 5365 tcg_temp_free(t0); 5366 return; 5367 } 5368 tcg_temp_free(t0); 5369 } 5370 5371 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5372 int rt, int bits) 5373 { 5374 TCGv t0; 5375 if (rd == 0) { 5376 /* Treat as NOP. */ 5377 return; 5378 } 5379 t0 = tcg_temp_new(); 5380 if (bits == 0 || bits == wordsz) { 5381 if (bits == 0) { 5382 gen_load_gpr(t0, rt); 5383 } else { 5384 gen_load_gpr(t0, rs); 5385 } 5386 switch (wordsz) { 5387 case 32: 5388 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5389 break; 5390 #if defined(TARGET_MIPS64) 5391 case 64: 5392 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5393 break; 5394 #endif 5395 } 5396 } else { 5397 TCGv t1 = tcg_temp_new(); 5398 gen_load_gpr(t0, rt); 5399 gen_load_gpr(t1, rs); 5400 switch (wordsz) { 5401 case 32: 5402 { 5403 TCGv_i64 t2 = tcg_temp_new_i64(); 5404 tcg_gen_concat_tl_i64(t2, t1, t0); 5405 tcg_gen_shri_i64(t2, t2, 32 - bits); 5406 gen_move_low32(cpu_gpr[rd], t2); 5407 tcg_temp_free_i64(t2); 5408 } 5409 break; 5410 #if defined(TARGET_MIPS64) 5411 case 64: 5412 tcg_gen_shli_tl(t0, t0, bits); 5413 tcg_gen_shri_tl(t1, t1, 64 - bits); 5414 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5415 break; 5416 #endif 5417 } 5418 tcg_temp_free(t1); 5419 } 5420 5421 tcg_temp_free(t0); 5422 } 5423 5424 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5425 { 5426 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5427 } 5428 5429 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5430 { 5431 TCGv t0; 5432 if (rd == 0) { 5433 /* Treat as NOP. */ 5434 return; 5435 } 5436 t0 = tcg_temp_new(); 5437 gen_load_gpr(t0, rt); 5438 switch (opc) { 5439 case OPC_BITSWAP: 5440 gen_helper_bitswap(cpu_gpr[rd], t0); 5441 break; 5442 #if defined(TARGET_MIPS64) 5443 case OPC_DBITSWAP: 5444 gen_helper_dbitswap(cpu_gpr[rd], t0); 5445 break; 5446 #endif 5447 } 5448 tcg_temp_free(t0); 5449 } 5450 5451 #ifndef CONFIG_USER_ONLY 5452 /* CP0 (MMU and control) */ 5453 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5454 { 5455 TCGv_i64 t0 = tcg_temp_new_i64(); 5456 TCGv_i64 t1 = tcg_temp_new_i64(); 5457 5458 tcg_gen_ext_tl_i64(t0, arg); 5459 tcg_gen_ld_i64(t1, cpu_env, off); 5460 #if defined(TARGET_MIPS64) 5461 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5462 #else 5463 tcg_gen_concat32_i64(t1, t1, t0); 5464 #endif 5465 tcg_gen_st_i64(t1, cpu_env, off); 5466 tcg_temp_free_i64(t1); 5467 tcg_temp_free_i64(t0); 5468 } 5469 5470 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5471 { 5472 TCGv_i64 t0 = tcg_temp_new_i64(); 5473 TCGv_i64 t1 = tcg_temp_new_i64(); 5474 5475 tcg_gen_ext_tl_i64(t0, arg); 5476 tcg_gen_ld_i64(t1, cpu_env, off); 5477 tcg_gen_concat32_i64(t1, t1, t0); 5478 tcg_gen_st_i64(t1, cpu_env, off); 5479 tcg_temp_free_i64(t1); 5480 tcg_temp_free_i64(t0); 5481 } 5482 5483 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5484 { 5485 TCGv_i64 t0 = tcg_temp_new_i64(); 5486 5487 tcg_gen_ld_i64(t0, cpu_env, off); 5488 #if defined(TARGET_MIPS64) 5489 tcg_gen_shri_i64(t0, t0, 30); 5490 #else 5491 tcg_gen_shri_i64(t0, t0, 32); 5492 #endif 5493 gen_move_low32(arg, t0); 5494 tcg_temp_free_i64(t0); 5495 } 5496 5497 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5498 { 5499 TCGv_i64 t0 = tcg_temp_new_i64(); 5500 5501 tcg_gen_ld_i64(t0, cpu_env, off); 5502 tcg_gen_shri_i64(t0, t0, 32 + shift); 5503 gen_move_low32(arg, t0); 5504 tcg_temp_free_i64(t0); 5505 } 5506 5507 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5508 { 5509 TCGv_i32 t0 = tcg_temp_new_i32(); 5510 5511 tcg_gen_ld_i32(t0, cpu_env, off); 5512 tcg_gen_ext_i32_tl(arg, t0); 5513 tcg_temp_free_i32(t0); 5514 } 5515 5516 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5517 { 5518 tcg_gen_ld_tl(arg, cpu_env, off); 5519 tcg_gen_ext32s_tl(arg, arg); 5520 } 5521 5522 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5523 { 5524 TCGv_i32 t0 = tcg_temp_new_i32(); 5525 5526 tcg_gen_trunc_tl_i32(t0, arg); 5527 tcg_gen_st_i32(t0, cpu_env, off); 5528 tcg_temp_free_i32(t0); 5529 } 5530 5531 #define CP0_CHECK(c) \ 5532 do { \ 5533 if (!(c)) { \ 5534 goto cp0_unimplemented; \ 5535 } \ 5536 } while (0) 5537 5538 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5539 { 5540 const char *register_name = "invalid"; 5541 5542 switch (reg) { 5543 case CP0_REGISTER_02: 5544 switch (sel) { 5545 case 0: 5546 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5547 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5548 register_name = "EntryLo0"; 5549 break; 5550 default: 5551 goto cp0_unimplemented; 5552 } 5553 break; 5554 case CP0_REGISTER_03: 5555 switch (sel) { 5556 case CP0_REG03__ENTRYLO1: 5557 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5558 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5559 register_name = "EntryLo1"; 5560 break; 5561 default: 5562 goto cp0_unimplemented; 5563 } 5564 break; 5565 case CP0_REGISTER_09: 5566 switch (sel) { 5567 case CP0_REG09__SAAR: 5568 CP0_CHECK(ctx->saar); 5569 gen_helper_mfhc0_saar(arg, cpu_env); 5570 register_name = "SAAR"; 5571 break; 5572 default: 5573 goto cp0_unimplemented; 5574 } 5575 break; 5576 case CP0_REGISTER_17: 5577 switch (sel) { 5578 case CP0_REG17__LLADDR: 5579 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5580 ctx->CP0_LLAddr_shift); 5581 register_name = "LLAddr"; 5582 break; 5583 case CP0_REG17__MAAR: 5584 CP0_CHECK(ctx->mrp); 5585 gen_helper_mfhc0_maar(arg, cpu_env); 5586 register_name = "MAAR"; 5587 break; 5588 default: 5589 goto cp0_unimplemented; 5590 } 5591 break; 5592 case CP0_REGISTER_19: 5593 switch (sel) { 5594 case CP0_REG19__WATCHHI0: 5595 case CP0_REG19__WATCHHI1: 5596 case CP0_REG19__WATCHHI2: 5597 case CP0_REG19__WATCHHI3: 5598 case CP0_REG19__WATCHHI4: 5599 case CP0_REG19__WATCHHI5: 5600 case CP0_REG19__WATCHHI6: 5601 case CP0_REG19__WATCHHI7: 5602 /* upper 32 bits are only available when Config5MI != 0 */ 5603 CP0_CHECK(ctx->mi); 5604 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5605 register_name = "WatchHi"; 5606 break; 5607 default: 5608 goto cp0_unimplemented; 5609 } 5610 break; 5611 case CP0_REGISTER_28: 5612 switch (sel) { 5613 case 0: 5614 case 2: 5615 case 4: 5616 case 6: 5617 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5618 register_name = "TagLo"; 5619 break; 5620 default: 5621 goto cp0_unimplemented; 5622 } 5623 break; 5624 default: 5625 goto cp0_unimplemented; 5626 } 5627 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5628 return; 5629 5630 cp0_unimplemented: 5631 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5632 register_name, reg, sel); 5633 tcg_gen_movi_tl(arg, 0); 5634 } 5635 5636 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5637 { 5638 const char *register_name = "invalid"; 5639 uint64_t mask = ctx->PAMask >> 36; 5640 5641 switch (reg) { 5642 case CP0_REGISTER_02: 5643 switch (sel) { 5644 case 0: 5645 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5646 tcg_gen_andi_tl(arg, arg, mask); 5647 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5648 register_name = "EntryLo0"; 5649 break; 5650 default: 5651 goto cp0_unimplemented; 5652 } 5653 break; 5654 case CP0_REGISTER_03: 5655 switch (sel) { 5656 case CP0_REG03__ENTRYLO1: 5657 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5658 tcg_gen_andi_tl(arg, arg, mask); 5659 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5660 register_name = "EntryLo1"; 5661 break; 5662 default: 5663 goto cp0_unimplemented; 5664 } 5665 break; 5666 case CP0_REGISTER_09: 5667 switch (sel) { 5668 case CP0_REG09__SAAR: 5669 CP0_CHECK(ctx->saar); 5670 gen_helper_mthc0_saar(cpu_env, arg); 5671 register_name = "SAAR"; 5672 break; 5673 default: 5674 goto cp0_unimplemented; 5675 } 5676 break; 5677 case CP0_REGISTER_17: 5678 switch (sel) { 5679 case CP0_REG17__LLADDR: 5680 /* 5681 * LLAddr is read-only (the only exception is bit 0 if LLB is 5682 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5683 * relevant for modern MIPS cores supporting MTHC0, therefore 5684 * treating MTHC0 to LLAddr as NOP. 5685 */ 5686 register_name = "LLAddr"; 5687 break; 5688 case CP0_REG17__MAAR: 5689 CP0_CHECK(ctx->mrp); 5690 gen_helper_mthc0_maar(cpu_env, arg); 5691 register_name = "MAAR"; 5692 break; 5693 default: 5694 goto cp0_unimplemented; 5695 } 5696 break; 5697 case CP0_REGISTER_19: 5698 switch (sel) { 5699 case CP0_REG19__WATCHHI0: 5700 case CP0_REG19__WATCHHI1: 5701 case CP0_REG19__WATCHHI2: 5702 case CP0_REG19__WATCHHI3: 5703 case CP0_REG19__WATCHHI4: 5704 case CP0_REG19__WATCHHI5: 5705 case CP0_REG19__WATCHHI6: 5706 case CP0_REG19__WATCHHI7: 5707 /* upper 32 bits are only available when Config5MI != 0 */ 5708 CP0_CHECK(ctx->mi); 5709 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5710 register_name = "WatchHi"; 5711 break; 5712 default: 5713 goto cp0_unimplemented; 5714 } 5715 break; 5716 case CP0_REGISTER_28: 5717 switch (sel) { 5718 case 0: 5719 case 2: 5720 case 4: 5721 case 6: 5722 tcg_gen_andi_tl(arg, arg, mask); 5723 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5724 register_name = "TagLo"; 5725 break; 5726 default: 5727 goto cp0_unimplemented; 5728 } 5729 break; 5730 default: 5731 goto cp0_unimplemented; 5732 } 5733 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5734 return; 5735 5736 cp0_unimplemented: 5737 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5738 register_name, reg, sel); 5739 } 5740 5741 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5742 { 5743 if (ctx->insn_flags & ISA_MIPS_R6) { 5744 tcg_gen_movi_tl(arg, 0); 5745 } else { 5746 tcg_gen_movi_tl(arg, ~0); 5747 } 5748 } 5749 5750 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5751 { 5752 const char *register_name = "invalid"; 5753 5754 if (sel != 0) { 5755 check_insn(ctx, ISA_MIPS_R1); 5756 } 5757 5758 switch (reg) { 5759 case CP0_REGISTER_00: 5760 switch (sel) { 5761 case CP0_REG00__INDEX: 5762 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5763 register_name = "Index"; 5764 break; 5765 case CP0_REG00__MVPCONTROL: 5766 CP0_CHECK(ctx->insn_flags & ASE_MT); 5767 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5768 register_name = "MVPControl"; 5769 break; 5770 case CP0_REG00__MVPCONF0: 5771 CP0_CHECK(ctx->insn_flags & ASE_MT); 5772 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5773 register_name = "MVPConf0"; 5774 break; 5775 case CP0_REG00__MVPCONF1: 5776 CP0_CHECK(ctx->insn_flags & ASE_MT); 5777 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5778 register_name = "MVPConf1"; 5779 break; 5780 case CP0_REG00__VPCONTROL: 5781 CP0_CHECK(ctx->vp); 5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5783 register_name = "VPControl"; 5784 break; 5785 default: 5786 goto cp0_unimplemented; 5787 } 5788 break; 5789 case CP0_REGISTER_01: 5790 switch (sel) { 5791 case CP0_REG01__RANDOM: 5792 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5793 gen_helper_mfc0_random(arg, cpu_env); 5794 register_name = "Random"; 5795 break; 5796 case CP0_REG01__VPECONTROL: 5797 CP0_CHECK(ctx->insn_flags & ASE_MT); 5798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5799 register_name = "VPEControl"; 5800 break; 5801 case CP0_REG01__VPECONF0: 5802 CP0_CHECK(ctx->insn_flags & ASE_MT); 5803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5804 register_name = "VPEConf0"; 5805 break; 5806 case CP0_REG01__VPECONF1: 5807 CP0_CHECK(ctx->insn_flags & ASE_MT); 5808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5809 register_name = "VPEConf1"; 5810 break; 5811 case CP0_REG01__YQMASK: 5812 CP0_CHECK(ctx->insn_flags & ASE_MT); 5813 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5814 register_name = "YQMask"; 5815 break; 5816 case CP0_REG01__VPESCHEDULE: 5817 CP0_CHECK(ctx->insn_flags & ASE_MT); 5818 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5819 register_name = "VPESchedule"; 5820 break; 5821 case CP0_REG01__VPESCHEFBACK: 5822 CP0_CHECK(ctx->insn_flags & ASE_MT); 5823 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5824 register_name = "VPEScheFBack"; 5825 break; 5826 case CP0_REG01__VPEOPT: 5827 CP0_CHECK(ctx->insn_flags & ASE_MT); 5828 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5829 register_name = "VPEOpt"; 5830 break; 5831 default: 5832 goto cp0_unimplemented; 5833 } 5834 break; 5835 case CP0_REGISTER_02: 5836 switch (sel) { 5837 case CP0_REG02__ENTRYLO0: 5838 { 5839 TCGv_i64 tmp = tcg_temp_new_i64(); 5840 tcg_gen_ld_i64(tmp, cpu_env, 5841 offsetof(CPUMIPSState, CP0_EntryLo0)); 5842 #if defined(TARGET_MIPS64) 5843 if (ctx->rxi) { 5844 /* Move RI/XI fields to bits 31:30 */ 5845 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5846 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5847 } 5848 #endif 5849 gen_move_low32(arg, tmp); 5850 tcg_temp_free_i64(tmp); 5851 } 5852 register_name = "EntryLo0"; 5853 break; 5854 case CP0_REG02__TCSTATUS: 5855 CP0_CHECK(ctx->insn_flags & ASE_MT); 5856 gen_helper_mfc0_tcstatus(arg, cpu_env); 5857 register_name = "TCStatus"; 5858 break; 5859 case CP0_REG02__TCBIND: 5860 CP0_CHECK(ctx->insn_flags & ASE_MT); 5861 gen_helper_mfc0_tcbind(arg, cpu_env); 5862 register_name = "TCBind"; 5863 break; 5864 case CP0_REG02__TCRESTART: 5865 CP0_CHECK(ctx->insn_flags & ASE_MT); 5866 gen_helper_mfc0_tcrestart(arg, cpu_env); 5867 register_name = "TCRestart"; 5868 break; 5869 case CP0_REG02__TCHALT: 5870 CP0_CHECK(ctx->insn_flags & ASE_MT); 5871 gen_helper_mfc0_tchalt(arg, cpu_env); 5872 register_name = "TCHalt"; 5873 break; 5874 case CP0_REG02__TCCONTEXT: 5875 CP0_CHECK(ctx->insn_flags & ASE_MT); 5876 gen_helper_mfc0_tccontext(arg, cpu_env); 5877 register_name = "TCContext"; 5878 break; 5879 case CP0_REG02__TCSCHEDULE: 5880 CP0_CHECK(ctx->insn_flags & ASE_MT); 5881 gen_helper_mfc0_tcschedule(arg, cpu_env); 5882 register_name = "TCSchedule"; 5883 break; 5884 case CP0_REG02__TCSCHEFBACK: 5885 CP0_CHECK(ctx->insn_flags & ASE_MT); 5886 gen_helper_mfc0_tcschefback(arg, cpu_env); 5887 register_name = "TCScheFBack"; 5888 break; 5889 default: 5890 goto cp0_unimplemented; 5891 } 5892 break; 5893 case CP0_REGISTER_03: 5894 switch (sel) { 5895 case CP0_REG03__ENTRYLO1: 5896 { 5897 TCGv_i64 tmp = tcg_temp_new_i64(); 5898 tcg_gen_ld_i64(tmp, cpu_env, 5899 offsetof(CPUMIPSState, CP0_EntryLo1)); 5900 #if defined(TARGET_MIPS64) 5901 if (ctx->rxi) { 5902 /* Move RI/XI fields to bits 31:30 */ 5903 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5904 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5905 } 5906 #endif 5907 gen_move_low32(arg, tmp); 5908 tcg_temp_free_i64(tmp); 5909 } 5910 register_name = "EntryLo1"; 5911 break; 5912 case CP0_REG03__GLOBALNUM: 5913 CP0_CHECK(ctx->vp); 5914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5915 register_name = "GlobalNumber"; 5916 break; 5917 default: 5918 goto cp0_unimplemented; 5919 } 5920 break; 5921 case CP0_REGISTER_04: 5922 switch (sel) { 5923 case CP0_REG04__CONTEXT: 5924 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5925 tcg_gen_ext32s_tl(arg, arg); 5926 register_name = "Context"; 5927 break; 5928 case CP0_REG04__CONTEXTCONFIG: 5929 /* SmartMIPS ASE */ 5930 /* gen_helper_mfc0_contextconfig(arg); */ 5931 register_name = "ContextConfig"; 5932 goto cp0_unimplemented; 5933 case CP0_REG04__USERLOCAL: 5934 CP0_CHECK(ctx->ulri); 5935 tcg_gen_ld_tl(arg, cpu_env, 5936 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5937 tcg_gen_ext32s_tl(arg, arg); 5938 register_name = "UserLocal"; 5939 break; 5940 case CP0_REG04__MMID: 5941 CP0_CHECK(ctx->mi); 5942 gen_helper_mtc0_memorymapid(cpu_env, arg); 5943 register_name = "MMID"; 5944 break; 5945 default: 5946 goto cp0_unimplemented; 5947 } 5948 break; 5949 case CP0_REGISTER_05: 5950 switch (sel) { 5951 case CP0_REG05__PAGEMASK: 5952 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5953 register_name = "PageMask"; 5954 break; 5955 case CP0_REG05__PAGEGRAIN: 5956 check_insn(ctx, ISA_MIPS_R2); 5957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5958 register_name = "PageGrain"; 5959 break; 5960 case CP0_REG05__SEGCTL0: 5961 CP0_CHECK(ctx->sc); 5962 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5963 tcg_gen_ext32s_tl(arg, arg); 5964 register_name = "SegCtl0"; 5965 break; 5966 case CP0_REG05__SEGCTL1: 5967 CP0_CHECK(ctx->sc); 5968 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5969 tcg_gen_ext32s_tl(arg, arg); 5970 register_name = "SegCtl1"; 5971 break; 5972 case CP0_REG05__SEGCTL2: 5973 CP0_CHECK(ctx->sc); 5974 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5975 tcg_gen_ext32s_tl(arg, arg); 5976 register_name = "SegCtl2"; 5977 break; 5978 case CP0_REG05__PWBASE: 5979 check_pw(ctx); 5980 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5981 register_name = "PWBase"; 5982 break; 5983 case CP0_REG05__PWFIELD: 5984 check_pw(ctx); 5985 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5986 register_name = "PWField"; 5987 break; 5988 case CP0_REG05__PWSIZE: 5989 check_pw(ctx); 5990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5991 register_name = "PWSize"; 5992 break; 5993 default: 5994 goto cp0_unimplemented; 5995 } 5996 break; 5997 case CP0_REGISTER_06: 5998 switch (sel) { 5999 case CP0_REG06__WIRED: 6000 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6001 register_name = "Wired"; 6002 break; 6003 case CP0_REG06__SRSCONF0: 6004 check_insn(ctx, ISA_MIPS_R2); 6005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6006 register_name = "SRSConf0"; 6007 break; 6008 case CP0_REG06__SRSCONF1: 6009 check_insn(ctx, ISA_MIPS_R2); 6010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6011 register_name = "SRSConf1"; 6012 break; 6013 case CP0_REG06__SRSCONF2: 6014 check_insn(ctx, ISA_MIPS_R2); 6015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6016 register_name = "SRSConf2"; 6017 break; 6018 case CP0_REG06__SRSCONF3: 6019 check_insn(ctx, ISA_MIPS_R2); 6020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6021 register_name = "SRSConf3"; 6022 break; 6023 case CP0_REG06__SRSCONF4: 6024 check_insn(ctx, ISA_MIPS_R2); 6025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6026 register_name = "SRSConf4"; 6027 break; 6028 case CP0_REG06__PWCTL: 6029 check_pw(ctx); 6030 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6031 register_name = "PWCtl"; 6032 break; 6033 default: 6034 goto cp0_unimplemented; 6035 } 6036 break; 6037 case CP0_REGISTER_07: 6038 switch (sel) { 6039 case CP0_REG07__HWRENA: 6040 check_insn(ctx, ISA_MIPS_R2); 6041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6042 register_name = "HWREna"; 6043 break; 6044 default: 6045 goto cp0_unimplemented; 6046 } 6047 break; 6048 case CP0_REGISTER_08: 6049 switch (sel) { 6050 case CP0_REG08__BADVADDR: 6051 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6052 tcg_gen_ext32s_tl(arg, arg); 6053 register_name = "BadVAddr"; 6054 break; 6055 case CP0_REG08__BADINSTR: 6056 CP0_CHECK(ctx->bi); 6057 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6058 register_name = "BadInstr"; 6059 break; 6060 case CP0_REG08__BADINSTRP: 6061 CP0_CHECK(ctx->bp); 6062 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6063 register_name = "BadInstrP"; 6064 break; 6065 case CP0_REG08__BADINSTRX: 6066 CP0_CHECK(ctx->bi); 6067 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6068 tcg_gen_andi_tl(arg, arg, ~0xffff); 6069 register_name = "BadInstrX"; 6070 break; 6071 default: 6072 goto cp0_unimplemented; 6073 } 6074 break; 6075 case CP0_REGISTER_09: 6076 switch (sel) { 6077 case CP0_REG09__COUNT: 6078 /* Mark as an IO operation because we read the time. */ 6079 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6080 gen_io_start(); 6081 } 6082 gen_helper_mfc0_count(arg, cpu_env); 6083 /* 6084 * Break the TB to be able to take timer interrupts immediately 6085 * after reading count. DISAS_STOP isn't sufficient, we need to 6086 * ensure we break completely out of translated code. 6087 */ 6088 gen_save_pc(ctx->base.pc_next + 4); 6089 ctx->base.is_jmp = DISAS_EXIT; 6090 register_name = "Count"; 6091 break; 6092 case CP0_REG09__SAARI: 6093 CP0_CHECK(ctx->saar); 6094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 6095 register_name = "SAARI"; 6096 break; 6097 case CP0_REG09__SAAR: 6098 CP0_CHECK(ctx->saar); 6099 gen_helper_mfc0_saar(arg, cpu_env); 6100 register_name = "SAAR"; 6101 break; 6102 default: 6103 goto cp0_unimplemented; 6104 } 6105 break; 6106 case CP0_REGISTER_10: 6107 switch (sel) { 6108 case CP0_REG10__ENTRYHI: 6109 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6110 tcg_gen_ext32s_tl(arg, arg); 6111 register_name = "EntryHi"; 6112 break; 6113 default: 6114 goto cp0_unimplemented; 6115 } 6116 break; 6117 case CP0_REGISTER_11: 6118 switch (sel) { 6119 case CP0_REG11__COMPARE: 6120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6121 register_name = "Compare"; 6122 break; 6123 /* 6,7 are implementation dependent */ 6124 default: 6125 goto cp0_unimplemented; 6126 } 6127 break; 6128 case CP0_REGISTER_12: 6129 switch (sel) { 6130 case CP0_REG12__STATUS: 6131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6132 register_name = "Status"; 6133 break; 6134 case CP0_REG12__INTCTL: 6135 check_insn(ctx, ISA_MIPS_R2); 6136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6137 register_name = "IntCtl"; 6138 break; 6139 case CP0_REG12__SRSCTL: 6140 check_insn(ctx, ISA_MIPS_R2); 6141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6142 register_name = "SRSCtl"; 6143 break; 6144 case CP0_REG12__SRSMAP: 6145 check_insn(ctx, ISA_MIPS_R2); 6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6147 register_name = "SRSMap"; 6148 break; 6149 default: 6150 goto cp0_unimplemented; 6151 } 6152 break; 6153 case CP0_REGISTER_13: 6154 switch (sel) { 6155 case CP0_REG13__CAUSE: 6156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6157 register_name = "Cause"; 6158 break; 6159 default: 6160 goto cp0_unimplemented; 6161 } 6162 break; 6163 case CP0_REGISTER_14: 6164 switch (sel) { 6165 case CP0_REG14__EPC: 6166 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6167 tcg_gen_ext32s_tl(arg, arg); 6168 register_name = "EPC"; 6169 break; 6170 default: 6171 goto cp0_unimplemented; 6172 } 6173 break; 6174 case CP0_REGISTER_15: 6175 switch (sel) { 6176 case CP0_REG15__PRID: 6177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6178 register_name = "PRid"; 6179 break; 6180 case CP0_REG15__EBASE: 6181 check_insn(ctx, ISA_MIPS_R2); 6182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6183 tcg_gen_ext32s_tl(arg, arg); 6184 register_name = "EBase"; 6185 break; 6186 case CP0_REG15__CMGCRBASE: 6187 check_insn(ctx, ISA_MIPS_R2); 6188 CP0_CHECK(ctx->cmgcr); 6189 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6190 tcg_gen_ext32s_tl(arg, arg); 6191 register_name = "CMGCRBase"; 6192 break; 6193 default: 6194 goto cp0_unimplemented; 6195 } 6196 break; 6197 case CP0_REGISTER_16: 6198 switch (sel) { 6199 case CP0_REG16__CONFIG: 6200 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6201 register_name = "Config"; 6202 break; 6203 case CP0_REG16__CONFIG1: 6204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6205 register_name = "Config1"; 6206 break; 6207 case CP0_REG16__CONFIG2: 6208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6209 register_name = "Config2"; 6210 break; 6211 case CP0_REG16__CONFIG3: 6212 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6213 register_name = "Config3"; 6214 break; 6215 case CP0_REG16__CONFIG4: 6216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6217 register_name = "Config4"; 6218 break; 6219 case CP0_REG16__CONFIG5: 6220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6221 register_name = "Config5"; 6222 break; 6223 /* 6,7 are implementation dependent */ 6224 case CP0_REG16__CONFIG6: 6225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6226 register_name = "Config6"; 6227 break; 6228 case CP0_REG16__CONFIG7: 6229 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6230 register_name = "Config7"; 6231 break; 6232 default: 6233 goto cp0_unimplemented; 6234 } 6235 break; 6236 case CP0_REGISTER_17: 6237 switch (sel) { 6238 case CP0_REG17__LLADDR: 6239 gen_helper_mfc0_lladdr(arg, cpu_env); 6240 register_name = "LLAddr"; 6241 break; 6242 case CP0_REG17__MAAR: 6243 CP0_CHECK(ctx->mrp); 6244 gen_helper_mfc0_maar(arg, cpu_env); 6245 register_name = "MAAR"; 6246 break; 6247 case CP0_REG17__MAARI: 6248 CP0_CHECK(ctx->mrp); 6249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6250 register_name = "MAARI"; 6251 break; 6252 default: 6253 goto cp0_unimplemented; 6254 } 6255 break; 6256 case CP0_REGISTER_18: 6257 switch (sel) { 6258 case CP0_REG18__WATCHLO0: 6259 case CP0_REG18__WATCHLO1: 6260 case CP0_REG18__WATCHLO2: 6261 case CP0_REG18__WATCHLO3: 6262 case CP0_REG18__WATCHLO4: 6263 case CP0_REG18__WATCHLO5: 6264 case CP0_REG18__WATCHLO6: 6265 case CP0_REG18__WATCHLO7: 6266 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6267 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6268 register_name = "WatchLo"; 6269 break; 6270 default: 6271 goto cp0_unimplemented; 6272 } 6273 break; 6274 case CP0_REGISTER_19: 6275 switch (sel) { 6276 case CP0_REG19__WATCHHI0: 6277 case CP0_REG19__WATCHHI1: 6278 case CP0_REG19__WATCHHI2: 6279 case CP0_REG19__WATCHHI3: 6280 case CP0_REG19__WATCHHI4: 6281 case CP0_REG19__WATCHHI5: 6282 case CP0_REG19__WATCHHI6: 6283 case CP0_REG19__WATCHHI7: 6284 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6285 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6286 register_name = "WatchHi"; 6287 break; 6288 default: 6289 goto cp0_unimplemented; 6290 } 6291 break; 6292 case CP0_REGISTER_20: 6293 switch (sel) { 6294 case CP0_REG20__XCONTEXT: 6295 #if defined(TARGET_MIPS64) 6296 check_insn(ctx, ISA_MIPS3); 6297 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6298 tcg_gen_ext32s_tl(arg, arg); 6299 register_name = "XContext"; 6300 break; 6301 #endif 6302 default: 6303 goto cp0_unimplemented; 6304 } 6305 break; 6306 case CP0_REGISTER_21: 6307 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6308 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6309 switch (sel) { 6310 case 0: 6311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6312 register_name = "Framemask"; 6313 break; 6314 default: 6315 goto cp0_unimplemented; 6316 } 6317 break; 6318 case CP0_REGISTER_22: 6319 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6320 register_name = "'Diagnostic"; /* implementation dependent */ 6321 break; 6322 case CP0_REGISTER_23: 6323 switch (sel) { 6324 case CP0_REG23__DEBUG: 6325 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6326 register_name = "Debug"; 6327 break; 6328 case CP0_REG23__TRACECONTROL: 6329 /* PDtrace support */ 6330 /* gen_helper_mfc0_tracecontrol(arg); */ 6331 register_name = "TraceControl"; 6332 goto cp0_unimplemented; 6333 case CP0_REG23__TRACECONTROL2: 6334 /* PDtrace support */ 6335 /* gen_helper_mfc0_tracecontrol2(arg); */ 6336 register_name = "TraceControl2"; 6337 goto cp0_unimplemented; 6338 case CP0_REG23__USERTRACEDATA1: 6339 /* PDtrace support */ 6340 /* gen_helper_mfc0_usertracedata1(arg);*/ 6341 register_name = "UserTraceData1"; 6342 goto cp0_unimplemented; 6343 case CP0_REG23__TRACEIBPC: 6344 /* PDtrace support */ 6345 /* gen_helper_mfc0_traceibpc(arg); */ 6346 register_name = "TraceIBPC"; 6347 goto cp0_unimplemented; 6348 case CP0_REG23__TRACEDBPC: 6349 /* PDtrace support */ 6350 /* gen_helper_mfc0_tracedbpc(arg); */ 6351 register_name = "TraceDBPC"; 6352 goto cp0_unimplemented; 6353 default: 6354 goto cp0_unimplemented; 6355 } 6356 break; 6357 case CP0_REGISTER_24: 6358 switch (sel) { 6359 case CP0_REG24__DEPC: 6360 /* EJTAG support */ 6361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6362 tcg_gen_ext32s_tl(arg, arg); 6363 register_name = "DEPC"; 6364 break; 6365 default: 6366 goto cp0_unimplemented; 6367 } 6368 break; 6369 case CP0_REGISTER_25: 6370 switch (sel) { 6371 case CP0_REG25__PERFCTL0: 6372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6373 register_name = "Performance0"; 6374 break; 6375 case CP0_REG25__PERFCNT0: 6376 /* gen_helper_mfc0_performance1(arg); */ 6377 register_name = "Performance1"; 6378 goto cp0_unimplemented; 6379 case CP0_REG25__PERFCTL1: 6380 /* gen_helper_mfc0_performance2(arg); */ 6381 register_name = "Performance2"; 6382 goto cp0_unimplemented; 6383 case CP0_REG25__PERFCNT1: 6384 /* gen_helper_mfc0_performance3(arg); */ 6385 register_name = "Performance3"; 6386 goto cp0_unimplemented; 6387 case CP0_REG25__PERFCTL2: 6388 /* gen_helper_mfc0_performance4(arg); */ 6389 register_name = "Performance4"; 6390 goto cp0_unimplemented; 6391 case CP0_REG25__PERFCNT2: 6392 /* gen_helper_mfc0_performance5(arg); */ 6393 register_name = "Performance5"; 6394 goto cp0_unimplemented; 6395 case CP0_REG25__PERFCTL3: 6396 /* gen_helper_mfc0_performance6(arg); */ 6397 register_name = "Performance6"; 6398 goto cp0_unimplemented; 6399 case CP0_REG25__PERFCNT3: 6400 /* gen_helper_mfc0_performance7(arg); */ 6401 register_name = "Performance7"; 6402 goto cp0_unimplemented; 6403 default: 6404 goto cp0_unimplemented; 6405 } 6406 break; 6407 case CP0_REGISTER_26: 6408 switch (sel) { 6409 case CP0_REG26__ERRCTL: 6410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6411 register_name = "ErrCtl"; 6412 break; 6413 default: 6414 goto cp0_unimplemented; 6415 } 6416 break; 6417 case CP0_REGISTER_27: 6418 switch (sel) { 6419 case CP0_REG27__CACHERR: 6420 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6421 register_name = "CacheErr"; 6422 break; 6423 default: 6424 goto cp0_unimplemented; 6425 } 6426 break; 6427 case CP0_REGISTER_28: 6428 switch (sel) { 6429 case CP0_REG28__TAGLO: 6430 case CP0_REG28__TAGLO1: 6431 case CP0_REG28__TAGLO2: 6432 case CP0_REG28__TAGLO3: 6433 { 6434 TCGv_i64 tmp = tcg_temp_new_i64(); 6435 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6436 gen_move_low32(arg, tmp); 6437 tcg_temp_free_i64(tmp); 6438 } 6439 register_name = "TagLo"; 6440 break; 6441 case CP0_REG28__DATALO: 6442 case CP0_REG28__DATALO1: 6443 case CP0_REG28__DATALO2: 6444 case CP0_REG28__DATALO3: 6445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6446 register_name = "DataLo"; 6447 break; 6448 default: 6449 goto cp0_unimplemented; 6450 } 6451 break; 6452 case CP0_REGISTER_29: 6453 switch (sel) { 6454 case CP0_REG29__TAGHI: 6455 case CP0_REG29__TAGHI1: 6456 case CP0_REG29__TAGHI2: 6457 case CP0_REG29__TAGHI3: 6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6459 register_name = "TagHi"; 6460 break; 6461 case CP0_REG29__DATAHI: 6462 case CP0_REG29__DATAHI1: 6463 case CP0_REG29__DATAHI2: 6464 case CP0_REG29__DATAHI3: 6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6466 register_name = "DataHi"; 6467 break; 6468 default: 6469 goto cp0_unimplemented; 6470 } 6471 break; 6472 case CP0_REGISTER_30: 6473 switch (sel) { 6474 case CP0_REG30__ERROREPC: 6475 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6476 tcg_gen_ext32s_tl(arg, arg); 6477 register_name = "ErrorEPC"; 6478 break; 6479 default: 6480 goto cp0_unimplemented; 6481 } 6482 break; 6483 case CP0_REGISTER_31: 6484 switch (sel) { 6485 case CP0_REG31__DESAVE: 6486 /* EJTAG support */ 6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6488 register_name = "DESAVE"; 6489 break; 6490 case CP0_REG31__KSCRATCH1: 6491 case CP0_REG31__KSCRATCH2: 6492 case CP0_REG31__KSCRATCH3: 6493 case CP0_REG31__KSCRATCH4: 6494 case CP0_REG31__KSCRATCH5: 6495 case CP0_REG31__KSCRATCH6: 6496 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6497 tcg_gen_ld_tl(arg, cpu_env, 6498 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6499 tcg_gen_ext32s_tl(arg, arg); 6500 register_name = "KScratch"; 6501 break; 6502 default: 6503 goto cp0_unimplemented; 6504 } 6505 break; 6506 default: 6507 goto cp0_unimplemented; 6508 } 6509 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6510 return; 6511 6512 cp0_unimplemented: 6513 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6514 register_name, reg, sel); 6515 gen_mfc0_unimplemented(ctx, arg); 6516 } 6517 6518 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6519 { 6520 const char *register_name = "invalid"; 6521 6522 if (sel != 0) { 6523 check_insn(ctx, ISA_MIPS_R1); 6524 } 6525 6526 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6527 gen_io_start(); 6528 } 6529 6530 switch (reg) { 6531 case CP0_REGISTER_00: 6532 switch (sel) { 6533 case CP0_REG00__INDEX: 6534 gen_helper_mtc0_index(cpu_env, arg); 6535 register_name = "Index"; 6536 break; 6537 case CP0_REG00__MVPCONTROL: 6538 CP0_CHECK(ctx->insn_flags & ASE_MT); 6539 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6540 register_name = "MVPControl"; 6541 break; 6542 case CP0_REG00__MVPCONF0: 6543 CP0_CHECK(ctx->insn_flags & ASE_MT); 6544 /* ignored */ 6545 register_name = "MVPConf0"; 6546 break; 6547 case CP0_REG00__MVPCONF1: 6548 CP0_CHECK(ctx->insn_flags & ASE_MT); 6549 /* ignored */ 6550 register_name = "MVPConf1"; 6551 break; 6552 case CP0_REG00__VPCONTROL: 6553 CP0_CHECK(ctx->vp); 6554 /* ignored */ 6555 register_name = "VPControl"; 6556 break; 6557 default: 6558 goto cp0_unimplemented; 6559 } 6560 break; 6561 case CP0_REGISTER_01: 6562 switch (sel) { 6563 case CP0_REG01__RANDOM: 6564 /* ignored */ 6565 register_name = "Random"; 6566 break; 6567 case CP0_REG01__VPECONTROL: 6568 CP0_CHECK(ctx->insn_flags & ASE_MT); 6569 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6570 register_name = "VPEControl"; 6571 break; 6572 case CP0_REG01__VPECONF0: 6573 CP0_CHECK(ctx->insn_flags & ASE_MT); 6574 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6575 register_name = "VPEConf0"; 6576 break; 6577 case CP0_REG01__VPECONF1: 6578 CP0_CHECK(ctx->insn_flags & ASE_MT); 6579 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6580 register_name = "VPEConf1"; 6581 break; 6582 case CP0_REG01__YQMASK: 6583 CP0_CHECK(ctx->insn_flags & ASE_MT); 6584 gen_helper_mtc0_yqmask(cpu_env, arg); 6585 register_name = "YQMask"; 6586 break; 6587 case CP0_REG01__VPESCHEDULE: 6588 CP0_CHECK(ctx->insn_flags & ASE_MT); 6589 tcg_gen_st_tl(arg, cpu_env, 6590 offsetof(CPUMIPSState, CP0_VPESchedule)); 6591 register_name = "VPESchedule"; 6592 break; 6593 case CP0_REG01__VPESCHEFBACK: 6594 CP0_CHECK(ctx->insn_flags & ASE_MT); 6595 tcg_gen_st_tl(arg, cpu_env, 6596 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6597 register_name = "VPEScheFBack"; 6598 break; 6599 case CP0_REG01__VPEOPT: 6600 CP0_CHECK(ctx->insn_flags & ASE_MT); 6601 gen_helper_mtc0_vpeopt(cpu_env, arg); 6602 register_name = "VPEOpt"; 6603 break; 6604 default: 6605 goto cp0_unimplemented; 6606 } 6607 break; 6608 case CP0_REGISTER_02: 6609 switch (sel) { 6610 case CP0_REG02__ENTRYLO0: 6611 gen_helper_mtc0_entrylo0(cpu_env, arg); 6612 register_name = "EntryLo0"; 6613 break; 6614 case CP0_REG02__TCSTATUS: 6615 CP0_CHECK(ctx->insn_flags & ASE_MT); 6616 gen_helper_mtc0_tcstatus(cpu_env, arg); 6617 register_name = "TCStatus"; 6618 break; 6619 case CP0_REG02__TCBIND: 6620 CP0_CHECK(ctx->insn_flags & ASE_MT); 6621 gen_helper_mtc0_tcbind(cpu_env, arg); 6622 register_name = "TCBind"; 6623 break; 6624 case CP0_REG02__TCRESTART: 6625 CP0_CHECK(ctx->insn_flags & ASE_MT); 6626 gen_helper_mtc0_tcrestart(cpu_env, arg); 6627 register_name = "TCRestart"; 6628 break; 6629 case CP0_REG02__TCHALT: 6630 CP0_CHECK(ctx->insn_flags & ASE_MT); 6631 gen_helper_mtc0_tchalt(cpu_env, arg); 6632 register_name = "TCHalt"; 6633 break; 6634 case CP0_REG02__TCCONTEXT: 6635 CP0_CHECK(ctx->insn_flags & ASE_MT); 6636 gen_helper_mtc0_tccontext(cpu_env, arg); 6637 register_name = "TCContext"; 6638 break; 6639 case CP0_REG02__TCSCHEDULE: 6640 CP0_CHECK(ctx->insn_flags & ASE_MT); 6641 gen_helper_mtc0_tcschedule(cpu_env, arg); 6642 register_name = "TCSchedule"; 6643 break; 6644 case CP0_REG02__TCSCHEFBACK: 6645 CP0_CHECK(ctx->insn_flags & ASE_MT); 6646 gen_helper_mtc0_tcschefback(cpu_env, arg); 6647 register_name = "TCScheFBack"; 6648 break; 6649 default: 6650 goto cp0_unimplemented; 6651 } 6652 break; 6653 case CP0_REGISTER_03: 6654 switch (sel) { 6655 case CP0_REG03__ENTRYLO1: 6656 gen_helper_mtc0_entrylo1(cpu_env, arg); 6657 register_name = "EntryLo1"; 6658 break; 6659 case CP0_REG03__GLOBALNUM: 6660 CP0_CHECK(ctx->vp); 6661 /* ignored */ 6662 register_name = "GlobalNumber"; 6663 break; 6664 default: 6665 goto cp0_unimplemented; 6666 } 6667 break; 6668 case CP0_REGISTER_04: 6669 switch (sel) { 6670 case CP0_REG04__CONTEXT: 6671 gen_helper_mtc0_context(cpu_env, arg); 6672 register_name = "Context"; 6673 break; 6674 case CP0_REG04__CONTEXTCONFIG: 6675 /* SmartMIPS ASE */ 6676 /* gen_helper_mtc0_contextconfig(arg); */ 6677 register_name = "ContextConfig"; 6678 goto cp0_unimplemented; 6679 case CP0_REG04__USERLOCAL: 6680 CP0_CHECK(ctx->ulri); 6681 tcg_gen_st_tl(arg, cpu_env, 6682 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6683 register_name = "UserLocal"; 6684 break; 6685 case CP0_REG04__MMID: 6686 CP0_CHECK(ctx->mi); 6687 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6688 register_name = "MMID"; 6689 break; 6690 default: 6691 goto cp0_unimplemented; 6692 } 6693 break; 6694 case CP0_REGISTER_05: 6695 switch (sel) { 6696 case CP0_REG05__PAGEMASK: 6697 gen_helper_mtc0_pagemask(cpu_env, arg); 6698 register_name = "PageMask"; 6699 break; 6700 case CP0_REG05__PAGEGRAIN: 6701 check_insn(ctx, ISA_MIPS_R2); 6702 gen_helper_mtc0_pagegrain(cpu_env, arg); 6703 register_name = "PageGrain"; 6704 ctx->base.is_jmp = DISAS_STOP; 6705 break; 6706 case CP0_REG05__SEGCTL0: 6707 CP0_CHECK(ctx->sc); 6708 gen_helper_mtc0_segctl0(cpu_env, arg); 6709 register_name = "SegCtl0"; 6710 break; 6711 case CP0_REG05__SEGCTL1: 6712 CP0_CHECK(ctx->sc); 6713 gen_helper_mtc0_segctl1(cpu_env, arg); 6714 register_name = "SegCtl1"; 6715 break; 6716 case CP0_REG05__SEGCTL2: 6717 CP0_CHECK(ctx->sc); 6718 gen_helper_mtc0_segctl2(cpu_env, arg); 6719 register_name = "SegCtl2"; 6720 break; 6721 case CP0_REG05__PWBASE: 6722 check_pw(ctx); 6723 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6724 register_name = "PWBase"; 6725 break; 6726 case CP0_REG05__PWFIELD: 6727 check_pw(ctx); 6728 gen_helper_mtc0_pwfield(cpu_env, arg); 6729 register_name = "PWField"; 6730 break; 6731 case CP0_REG05__PWSIZE: 6732 check_pw(ctx); 6733 gen_helper_mtc0_pwsize(cpu_env, arg); 6734 register_name = "PWSize"; 6735 break; 6736 default: 6737 goto cp0_unimplemented; 6738 } 6739 break; 6740 case CP0_REGISTER_06: 6741 switch (sel) { 6742 case CP0_REG06__WIRED: 6743 gen_helper_mtc0_wired(cpu_env, arg); 6744 register_name = "Wired"; 6745 break; 6746 case CP0_REG06__SRSCONF0: 6747 check_insn(ctx, ISA_MIPS_R2); 6748 gen_helper_mtc0_srsconf0(cpu_env, arg); 6749 register_name = "SRSConf0"; 6750 break; 6751 case CP0_REG06__SRSCONF1: 6752 check_insn(ctx, ISA_MIPS_R2); 6753 gen_helper_mtc0_srsconf1(cpu_env, arg); 6754 register_name = "SRSConf1"; 6755 break; 6756 case CP0_REG06__SRSCONF2: 6757 check_insn(ctx, ISA_MIPS_R2); 6758 gen_helper_mtc0_srsconf2(cpu_env, arg); 6759 register_name = "SRSConf2"; 6760 break; 6761 case CP0_REG06__SRSCONF3: 6762 check_insn(ctx, ISA_MIPS_R2); 6763 gen_helper_mtc0_srsconf3(cpu_env, arg); 6764 register_name = "SRSConf3"; 6765 break; 6766 case CP0_REG06__SRSCONF4: 6767 check_insn(ctx, ISA_MIPS_R2); 6768 gen_helper_mtc0_srsconf4(cpu_env, arg); 6769 register_name = "SRSConf4"; 6770 break; 6771 case CP0_REG06__PWCTL: 6772 check_pw(ctx); 6773 gen_helper_mtc0_pwctl(cpu_env, arg); 6774 register_name = "PWCtl"; 6775 break; 6776 default: 6777 goto cp0_unimplemented; 6778 } 6779 break; 6780 case CP0_REGISTER_07: 6781 switch (sel) { 6782 case CP0_REG07__HWRENA: 6783 check_insn(ctx, ISA_MIPS_R2); 6784 gen_helper_mtc0_hwrena(cpu_env, arg); 6785 ctx->base.is_jmp = DISAS_STOP; 6786 register_name = "HWREna"; 6787 break; 6788 default: 6789 goto cp0_unimplemented; 6790 } 6791 break; 6792 case CP0_REGISTER_08: 6793 switch (sel) { 6794 case CP0_REG08__BADVADDR: 6795 /* ignored */ 6796 register_name = "BadVAddr"; 6797 break; 6798 case CP0_REG08__BADINSTR: 6799 /* ignored */ 6800 register_name = "BadInstr"; 6801 break; 6802 case CP0_REG08__BADINSTRP: 6803 /* ignored */ 6804 register_name = "BadInstrP"; 6805 break; 6806 case CP0_REG08__BADINSTRX: 6807 /* ignored */ 6808 register_name = "BadInstrX"; 6809 break; 6810 default: 6811 goto cp0_unimplemented; 6812 } 6813 break; 6814 case CP0_REGISTER_09: 6815 switch (sel) { 6816 case CP0_REG09__COUNT: 6817 gen_helper_mtc0_count(cpu_env, arg); 6818 register_name = "Count"; 6819 break; 6820 case CP0_REG09__SAARI: 6821 CP0_CHECK(ctx->saar); 6822 gen_helper_mtc0_saari(cpu_env, arg); 6823 register_name = "SAARI"; 6824 break; 6825 case CP0_REG09__SAAR: 6826 CP0_CHECK(ctx->saar); 6827 gen_helper_mtc0_saar(cpu_env, arg); 6828 register_name = "SAAR"; 6829 break; 6830 default: 6831 goto cp0_unimplemented; 6832 } 6833 break; 6834 case CP0_REGISTER_10: 6835 switch (sel) { 6836 case CP0_REG10__ENTRYHI: 6837 gen_helper_mtc0_entryhi(cpu_env, arg); 6838 register_name = "EntryHi"; 6839 break; 6840 default: 6841 goto cp0_unimplemented; 6842 } 6843 break; 6844 case CP0_REGISTER_11: 6845 switch (sel) { 6846 case CP0_REG11__COMPARE: 6847 gen_helper_mtc0_compare(cpu_env, arg); 6848 register_name = "Compare"; 6849 break; 6850 /* 6,7 are implementation dependent */ 6851 default: 6852 goto cp0_unimplemented; 6853 } 6854 break; 6855 case CP0_REGISTER_12: 6856 switch (sel) { 6857 case CP0_REG12__STATUS: 6858 save_cpu_state(ctx, 1); 6859 gen_helper_mtc0_status(cpu_env, arg); 6860 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6861 gen_save_pc(ctx->base.pc_next + 4); 6862 ctx->base.is_jmp = DISAS_EXIT; 6863 register_name = "Status"; 6864 break; 6865 case CP0_REG12__INTCTL: 6866 check_insn(ctx, ISA_MIPS_R2); 6867 gen_helper_mtc0_intctl(cpu_env, arg); 6868 /* Stop translation as we may have switched the execution mode */ 6869 ctx->base.is_jmp = DISAS_STOP; 6870 register_name = "IntCtl"; 6871 break; 6872 case CP0_REG12__SRSCTL: 6873 check_insn(ctx, ISA_MIPS_R2); 6874 gen_helper_mtc0_srsctl(cpu_env, arg); 6875 /* Stop translation as we may have switched the execution mode */ 6876 ctx->base.is_jmp = DISAS_STOP; 6877 register_name = "SRSCtl"; 6878 break; 6879 case CP0_REG12__SRSMAP: 6880 check_insn(ctx, ISA_MIPS_R2); 6881 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6882 /* Stop translation as we may have switched the execution mode */ 6883 ctx->base.is_jmp = DISAS_STOP; 6884 register_name = "SRSMap"; 6885 break; 6886 default: 6887 goto cp0_unimplemented; 6888 } 6889 break; 6890 case CP0_REGISTER_13: 6891 switch (sel) { 6892 case CP0_REG13__CAUSE: 6893 save_cpu_state(ctx, 1); 6894 gen_helper_mtc0_cause(cpu_env, arg); 6895 /* 6896 * Stop translation as we may have triggered an interrupt. 6897 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6898 * translated code to check for pending interrupts. 6899 */ 6900 gen_save_pc(ctx->base.pc_next + 4); 6901 ctx->base.is_jmp = DISAS_EXIT; 6902 register_name = "Cause"; 6903 break; 6904 default: 6905 goto cp0_unimplemented; 6906 } 6907 break; 6908 case CP0_REGISTER_14: 6909 switch (sel) { 6910 case CP0_REG14__EPC: 6911 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6912 register_name = "EPC"; 6913 break; 6914 default: 6915 goto cp0_unimplemented; 6916 } 6917 break; 6918 case CP0_REGISTER_15: 6919 switch (sel) { 6920 case CP0_REG15__PRID: 6921 /* ignored */ 6922 register_name = "PRid"; 6923 break; 6924 case CP0_REG15__EBASE: 6925 check_insn(ctx, ISA_MIPS_R2); 6926 gen_helper_mtc0_ebase(cpu_env, arg); 6927 register_name = "EBase"; 6928 break; 6929 default: 6930 goto cp0_unimplemented; 6931 } 6932 break; 6933 case CP0_REGISTER_16: 6934 switch (sel) { 6935 case CP0_REG16__CONFIG: 6936 gen_helper_mtc0_config0(cpu_env, arg); 6937 register_name = "Config"; 6938 /* Stop translation as we may have switched the execution mode */ 6939 ctx->base.is_jmp = DISAS_STOP; 6940 break; 6941 case CP0_REG16__CONFIG1: 6942 /* ignored, read only */ 6943 register_name = "Config1"; 6944 break; 6945 case CP0_REG16__CONFIG2: 6946 gen_helper_mtc0_config2(cpu_env, arg); 6947 register_name = "Config2"; 6948 /* Stop translation as we may have switched the execution mode */ 6949 ctx->base.is_jmp = DISAS_STOP; 6950 break; 6951 case CP0_REG16__CONFIG3: 6952 gen_helper_mtc0_config3(cpu_env, arg); 6953 register_name = "Config3"; 6954 /* Stop translation as we may have switched the execution mode */ 6955 ctx->base.is_jmp = DISAS_STOP; 6956 break; 6957 case CP0_REG16__CONFIG4: 6958 gen_helper_mtc0_config4(cpu_env, arg); 6959 register_name = "Config4"; 6960 ctx->base.is_jmp = DISAS_STOP; 6961 break; 6962 case CP0_REG16__CONFIG5: 6963 gen_helper_mtc0_config5(cpu_env, arg); 6964 register_name = "Config5"; 6965 /* Stop translation as we may have switched the execution mode */ 6966 ctx->base.is_jmp = DISAS_STOP; 6967 break; 6968 /* 6,7 are implementation dependent */ 6969 case CP0_REG16__CONFIG6: 6970 /* ignored */ 6971 register_name = "Config6"; 6972 break; 6973 case CP0_REG16__CONFIG7: 6974 /* ignored */ 6975 register_name = "Config7"; 6976 break; 6977 default: 6978 register_name = "Invalid config selector"; 6979 goto cp0_unimplemented; 6980 } 6981 break; 6982 case CP0_REGISTER_17: 6983 switch (sel) { 6984 case CP0_REG17__LLADDR: 6985 gen_helper_mtc0_lladdr(cpu_env, arg); 6986 register_name = "LLAddr"; 6987 break; 6988 case CP0_REG17__MAAR: 6989 CP0_CHECK(ctx->mrp); 6990 gen_helper_mtc0_maar(cpu_env, arg); 6991 register_name = "MAAR"; 6992 break; 6993 case CP0_REG17__MAARI: 6994 CP0_CHECK(ctx->mrp); 6995 gen_helper_mtc0_maari(cpu_env, arg); 6996 register_name = "MAARI"; 6997 break; 6998 default: 6999 goto cp0_unimplemented; 7000 } 7001 break; 7002 case CP0_REGISTER_18: 7003 switch (sel) { 7004 case CP0_REG18__WATCHLO0: 7005 case CP0_REG18__WATCHLO1: 7006 case CP0_REG18__WATCHLO2: 7007 case CP0_REG18__WATCHLO3: 7008 case CP0_REG18__WATCHLO4: 7009 case CP0_REG18__WATCHLO5: 7010 case CP0_REG18__WATCHLO6: 7011 case CP0_REG18__WATCHLO7: 7012 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7013 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7014 register_name = "WatchLo"; 7015 break; 7016 default: 7017 goto cp0_unimplemented; 7018 } 7019 break; 7020 case CP0_REGISTER_19: 7021 switch (sel) { 7022 case CP0_REG19__WATCHHI0: 7023 case CP0_REG19__WATCHHI1: 7024 case CP0_REG19__WATCHHI2: 7025 case CP0_REG19__WATCHHI3: 7026 case CP0_REG19__WATCHHI4: 7027 case CP0_REG19__WATCHHI5: 7028 case CP0_REG19__WATCHHI6: 7029 case CP0_REG19__WATCHHI7: 7030 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7031 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7032 register_name = "WatchHi"; 7033 break; 7034 default: 7035 goto cp0_unimplemented; 7036 } 7037 break; 7038 case CP0_REGISTER_20: 7039 switch (sel) { 7040 case CP0_REG20__XCONTEXT: 7041 #if defined(TARGET_MIPS64) 7042 check_insn(ctx, ISA_MIPS3); 7043 gen_helper_mtc0_xcontext(cpu_env, arg); 7044 register_name = "XContext"; 7045 break; 7046 #endif 7047 default: 7048 goto cp0_unimplemented; 7049 } 7050 break; 7051 case CP0_REGISTER_21: 7052 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7053 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7054 switch (sel) { 7055 case 0: 7056 gen_helper_mtc0_framemask(cpu_env, arg); 7057 register_name = "Framemask"; 7058 break; 7059 default: 7060 goto cp0_unimplemented; 7061 } 7062 break; 7063 case CP0_REGISTER_22: 7064 /* ignored */ 7065 register_name = "Diagnostic"; /* implementation dependent */ 7066 break; 7067 case CP0_REGISTER_23: 7068 switch (sel) { 7069 case CP0_REG23__DEBUG: 7070 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 7071 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7072 gen_save_pc(ctx->base.pc_next + 4); 7073 ctx->base.is_jmp = DISAS_EXIT; 7074 register_name = "Debug"; 7075 break; 7076 case CP0_REG23__TRACECONTROL: 7077 /* PDtrace support */ 7078 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 7079 register_name = "TraceControl"; 7080 /* Stop translation as we may have switched the execution mode */ 7081 ctx->base.is_jmp = DISAS_STOP; 7082 goto cp0_unimplemented; 7083 case CP0_REG23__TRACECONTROL2: 7084 /* PDtrace support */ 7085 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 7086 register_name = "TraceControl2"; 7087 /* Stop translation as we may have switched the execution mode */ 7088 ctx->base.is_jmp = DISAS_STOP; 7089 goto cp0_unimplemented; 7090 case CP0_REG23__USERTRACEDATA1: 7091 /* Stop translation as we may have switched the execution mode */ 7092 ctx->base.is_jmp = DISAS_STOP; 7093 /* PDtrace support */ 7094 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 7095 register_name = "UserTraceData"; 7096 /* Stop translation as we may have switched the execution mode */ 7097 ctx->base.is_jmp = DISAS_STOP; 7098 goto cp0_unimplemented; 7099 case CP0_REG23__TRACEIBPC: 7100 /* PDtrace support */ 7101 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 7102 /* Stop translation as we may have switched the execution mode */ 7103 ctx->base.is_jmp = DISAS_STOP; 7104 register_name = "TraceIBPC"; 7105 goto cp0_unimplemented; 7106 case CP0_REG23__TRACEDBPC: 7107 /* PDtrace support */ 7108 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 7109 /* Stop translation as we may have switched the execution mode */ 7110 ctx->base.is_jmp = DISAS_STOP; 7111 register_name = "TraceDBPC"; 7112 goto cp0_unimplemented; 7113 default: 7114 goto cp0_unimplemented; 7115 } 7116 break; 7117 case CP0_REGISTER_24: 7118 switch (sel) { 7119 case CP0_REG24__DEPC: 7120 /* EJTAG support */ 7121 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7122 register_name = "DEPC"; 7123 break; 7124 default: 7125 goto cp0_unimplemented; 7126 } 7127 break; 7128 case CP0_REGISTER_25: 7129 switch (sel) { 7130 case CP0_REG25__PERFCTL0: 7131 gen_helper_mtc0_performance0(cpu_env, arg); 7132 register_name = "Performance0"; 7133 break; 7134 case CP0_REG25__PERFCNT0: 7135 /* gen_helper_mtc0_performance1(arg); */ 7136 register_name = "Performance1"; 7137 goto cp0_unimplemented; 7138 case CP0_REG25__PERFCTL1: 7139 /* gen_helper_mtc0_performance2(arg); */ 7140 register_name = "Performance2"; 7141 goto cp0_unimplemented; 7142 case CP0_REG25__PERFCNT1: 7143 /* gen_helper_mtc0_performance3(arg); */ 7144 register_name = "Performance3"; 7145 goto cp0_unimplemented; 7146 case CP0_REG25__PERFCTL2: 7147 /* gen_helper_mtc0_performance4(arg); */ 7148 register_name = "Performance4"; 7149 goto cp0_unimplemented; 7150 case CP0_REG25__PERFCNT2: 7151 /* gen_helper_mtc0_performance5(arg); */ 7152 register_name = "Performance5"; 7153 goto cp0_unimplemented; 7154 case CP0_REG25__PERFCTL3: 7155 /* gen_helper_mtc0_performance6(arg); */ 7156 register_name = "Performance6"; 7157 goto cp0_unimplemented; 7158 case CP0_REG25__PERFCNT3: 7159 /* gen_helper_mtc0_performance7(arg); */ 7160 register_name = "Performance7"; 7161 goto cp0_unimplemented; 7162 default: 7163 goto cp0_unimplemented; 7164 } 7165 break; 7166 case CP0_REGISTER_26: 7167 switch (sel) { 7168 case CP0_REG26__ERRCTL: 7169 gen_helper_mtc0_errctl(cpu_env, arg); 7170 ctx->base.is_jmp = DISAS_STOP; 7171 register_name = "ErrCtl"; 7172 break; 7173 default: 7174 goto cp0_unimplemented; 7175 } 7176 break; 7177 case CP0_REGISTER_27: 7178 switch (sel) { 7179 case CP0_REG27__CACHERR: 7180 /* ignored */ 7181 register_name = "CacheErr"; 7182 break; 7183 default: 7184 goto cp0_unimplemented; 7185 } 7186 break; 7187 case CP0_REGISTER_28: 7188 switch (sel) { 7189 case CP0_REG28__TAGLO: 7190 case CP0_REG28__TAGLO1: 7191 case CP0_REG28__TAGLO2: 7192 case CP0_REG28__TAGLO3: 7193 gen_helper_mtc0_taglo(cpu_env, arg); 7194 register_name = "TagLo"; 7195 break; 7196 case CP0_REG28__DATALO: 7197 case CP0_REG28__DATALO1: 7198 case CP0_REG28__DATALO2: 7199 case CP0_REG28__DATALO3: 7200 gen_helper_mtc0_datalo(cpu_env, arg); 7201 register_name = "DataLo"; 7202 break; 7203 default: 7204 goto cp0_unimplemented; 7205 } 7206 break; 7207 case CP0_REGISTER_29: 7208 switch (sel) { 7209 case CP0_REG29__TAGHI: 7210 case CP0_REG29__TAGHI1: 7211 case CP0_REG29__TAGHI2: 7212 case CP0_REG29__TAGHI3: 7213 gen_helper_mtc0_taghi(cpu_env, arg); 7214 register_name = "TagHi"; 7215 break; 7216 case CP0_REG29__DATAHI: 7217 case CP0_REG29__DATAHI1: 7218 case CP0_REG29__DATAHI2: 7219 case CP0_REG29__DATAHI3: 7220 gen_helper_mtc0_datahi(cpu_env, arg); 7221 register_name = "DataHi"; 7222 break; 7223 default: 7224 register_name = "invalid sel"; 7225 goto cp0_unimplemented; 7226 } 7227 break; 7228 case CP0_REGISTER_30: 7229 switch (sel) { 7230 case CP0_REG30__ERROREPC: 7231 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7232 register_name = "ErrorEPC"; 7233 break; 7234 default: 7235 goto cp0_unimplemented; 7236 } 7237 break; 7238 case CP0_REGISTER_31: 7239 switch (sel) { 7240 case CP0_REG31__DESAVE: 7241 /* EJTAG support */ 7242 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7243 register_name = "DESAVE"; 7244 break; 7245 case CP0_REG31__KSCRATCH1: 7246 case CP0_REG31__KSCRATCH2: 7247 case CP0_REG31__KSCRATCH3: 7248 case CP0_REG31__KSCRATCH4: 7249 case CP0_REG31__KSCRATCH5: 7250 case CP0_REG31__KSCRATCH6: 7251 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7252 tcg_gen_st_tl(arg, cpu_env, 7253 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7254 register_name = "KScratch"; 7255 break; 7256 default: 7257 goto cp0_unimplemented; 7258 } 7259 break; 7260 default: 7261 goto cp0_unimplemented; 7262 } 7263 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7264 7265 /* For simplicity assume that all writes can cause interrupts. */ 7266 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7267 /* 7268 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7269 * translated code to check for pending interrupts. 7270 */ 7271 gen_save_pc(ctx->base.pc_next + 4); 7272 ctx->base.is_jmp = DISAS_EXIT; 7273 } 7274 return; 7275 7276 cp0_unimplemented: 7277 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7278 register_name, reg, sel); 7279 } 7280 7281 #if defined(TARGET_MIPS64) 7282 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7283 { 7284 const char *register_name = "invalid"; 7285 7286 if (sel != 0) { 7287 check_insn(ctx, ISA_MIPS_R1); 7288 } 7289 7290 switch (reg) { 7291 case CP0_REGISTER_00: 7292 switch (sel) { 7293 case CP0_REG00__INDEX: 7294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7295 register_name = "Index"; 7296 break; 7297 case CP0_REG00__MVPCONTROL: 7298 CP0_CHECK(ctx->insn_flags & ASE_MT); 7299 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7300 register_name = "MVPControl"; 7301 break; 7302 case CP0_REG00__MVPCONF0: 7303 CP0_CHECK(ctx->insn_flags & ASE_MT); 7304 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7305 register_name = "MVPConf0"; 7306 break; 7307 case CP0_REG00__MVPCONF1: 7308 CP0_CHECK(ctx->insn_flags & ASE_MT); 7309 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7310 register_name = "MVPConf1"; 7311 break; 7312 case CP0_REG00__VPCONTROL: 7313 CP0_CHECK(ctx->vp); 7314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7315 register_name = "VPControl"; 7316 break; 7317 default: 7318 goto cp0_unimplemented; 7319 } 7320 break; 7321 case CP0_REGISTER_01: 7322 switch (sel) { 7323 case CP0_REG01__RANDOM: 7324 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7325 gen_helper_mfc0_random(arg, cpu_env); 7326 register_name = "Random"; 7327 break; 7328 case CP0_REG01__VPECONTROL: 7329 CP0_CHECK(ctx->insn_flags & ASE_MT); 7330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7331 register_name = "VPEControl"; 7332 break; 7333 case CP0_REG01__VPECONF0: 7334 CP0_CHECK(ctx->insn_flags & ASE_MT); 7335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7336 register_name = "VPEConf0"; 7337 break; 7338 case CP0_REG01__VPECONF1: 7339 CP0_CHECK(ctx->insn_flags & ASE_MT); 7340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7341 register_name = "VPEConf1"; 7342 break; 7343 case CP0_REG01__YQMASK: 7344 CP0_CHECK(ctx->insn_flags & ASE_MT); 7345 tcg_gen_ld_tl(arg, cpu_env, 7346 offsetof(CPUMIPSState, CP0_YQMask)); 7347 register_name = "YQMask"; 7348 break; 7349 case CP0_REG01__VPESCHEDULE: 7350 CP0_CHECK(ctx->insn_flags & ASE_MT); 7351 tcg_gen_ld_tl(arg, cpu_env, 7352 offsetof(CPUMIPSState, CP0_VPESchedule)); 7353 register_name = "VPESchedule"; 7354 break; 7355 case CP0_REG01__VPESCHEFBACK: 7356 CP0_CHECK(ctx->insn_flags & ASE_MT); 7357 tcg_gen_ld_tl(arg, cpu_env, 7358 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7359 register_name = "VPEScheFBack"; 7360 break; 7361 case CP0_REG01__VPEOPT: 7362 CP0_CHECK(ctx->insn_flags & ASE_MT); 7363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7364 register_name = "VPEOpt"; 7365 break; 7366 default: 7367 goto cp0_unimplemented; 7368 } 7369 break; 7370 case CP0_REGISTER_02: 7371 switch (sel) { 7372 case CP0_REG02__ENTRYLO0: 7373 tcg_gen_ld_tl(arg, cpu_env, 7374 offsetof(CPUMIPSState, CP0_EntryLo0)); 7375 register_name = "EntryLo0"; 7376 break; 7377 case CP0_REG02__TCSTATUS: 7378 CP0_CHECK(ctx->insn_flags & ASE_MT); 7379 gen_helper_mfc0_tcstatus(arg, cpu_env); 7380 register_name = "TCStatus"; 7381 break; 7382 case CP0_REG02__TCBIND: 7383 CP0_CHECK(ctx->insn_flags & ASE_MT); 7384 gen_helper_mfc0_tcbind(arg, cpu_env); 7385 register_name = "TCBind"; 7386 break; 7387 case CP0_REG02__TCRESTART: 7388 CP0_CHECK(ctx->insn_flags & ASE_MT); 7389 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7390 register_name = "TCRestart"; 7391 break; 7392 case CP0_REG02__TCHALT: 7393 CP0_CHECK(ctx->insn_flags & ASE_MT); 7394 gen_helper_dmfc0_tchalt(arg, cpu_env); 7395 register_name = "TCHalt"; 7396 break; 7397 case CP0_REG02__TCCONTEXT: 7398 CP0_CHECK(ctx->insn_flags & ASE_MT); 7399 gen_helper_dmfc0_tccontext(arg, cpu_env); 7400 register_name = "TCContext"; 7401 break; 7402 case CP0_REG02__TCSCHEDULE: 7403 CP0_CHECK(ctx->insn_flags & ASE_MT); 7404 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7405 register_name = "TCSchedule"; 7406 break; 7407 case CP0_REG02__TCSCHEFBACK: 7408 CP0_CHECK(ctx->insn_flags & ASE_MT); 7409 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7410 register_name = "TCScheFBack"; 7411 break; 7412 default: 7413 goto cp0_unimplemented; 7414 } 7415 break; 7416 case CP0_REGISTER_03: 7417 switch (sel) { 7418 case CP0_REG03__ENTRYLO1: 7419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7420 register_name = "EntryLo1"; 7421 break; 7422 case CP0_REG03__GLOBALNUM: 7423 CP0_CHECK(ctx->vp); 7424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7425 register_name = "GlobalNumber"; 7426 break; 7427 default: 7428 goto cp0_unimplemented; 7429 } 7430 break; 7431 case CP0_REGISTER_04: 7432 switch (sel) { 7433 case CP0_REG04__CONTEXT: 7434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7435 register_name = "Context"; 7436 break; 7437 case CP0_REG04__CONTEXTCONFIG: 7438 /* SmartMIPS ASE */ 7439 /* gen_helper_dmfc0_contextconfig(arg); */ 7440 register_name = "ContextConfig"; 7441 goto cp0_unimplemented; 7442 case CP0_REG04__USERLOCAL: 7443 CP0_CHECK(ctx->ulri); 7444 tcg_gen_ld_tl(arg, cpu_env, 7445 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7446 register_name = "UserLocal"; 7447 break; 7448 case CP0_REG04__MMID: 7449 CP0_CHECK(ctx->mi); 7450 gen_helper_mtc0_memorymapid(cpu_env, arg); 7451 register_name = "MMID"; 7452 break; 7453 default: 7454 goto cp0_unimplemented; 7455 } 7456 break; 7457 case CP0_REGISTER_05: 7458 switch (sel) { 7459 case CP0_REG05__PAGEMASK: 7460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7461 register_name = "PageMask"; 7462 break; 7463 case CP0_REG05__PAGEGRAIN: 7464 check_insn(ctx, ISA_MIPS_R2); 7465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7466 register_name = "PageGrain"; 7467 break; 7468 case CP0_REG05__SEGCTL0: 7469 CP0_CHECK(ctx->sc); 7470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7471 register_name = "SegCtl0"; 7472 break; 7473 case CP0_REG05__SEGCTL1: 7474 CP0_CHECK(ctx->sc); 7475 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7476 register_name = "SegCtl1"; 7477 break; 7478 case CP0_REG05__SEGCTL2: 7479 CP0_CHECK(ctx->sc); 7480 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7481 register_name = "SegCtl2"; 7482 break; 7483 case CP0_REG05__PWBASE: 7484 check_pw(ctx); 7485 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7486 register_name = "PWBase"; 7487 break; 7488 case CP0_REG05__PWFIELD: 7489 check_pw(ctx); 7490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7491 register_name = "PWField"; 7492 break; 7493 case CP0_REG05__PWSIZE: 7494 check_pw(ctx); 7495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7496 register_name = "PWSize"; 7497 break; 7498 default: 7499 goto cp0_unimplemented; 7500 } 7501 break; 7502 case CP0_REGISTER_06: 7503 switch (sel) { 7504 case CP0_REG06__WIRED: 7505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7506 register_name = "Wired"; 7507 break; 7508 case CP0_REG06__SRSCONF0: 7509 check_insn(ctx, ISA_MIPS_R2); 7510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7511 register_name = "SRSConf0"; 7512 break; 7513 case CP0_REG06__SRSCONF1: 7514 check_insn(ctx, ISA_MIPS_R2); 7515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7516 register_name = "SRSConf1"; 7517 break; 7518 case CP0_REG06__SRSCONF2: 7519 check_insn(ctx, ISA_MIPS_R2); 7520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7521 register_name = "SRSConf2"; 7522 break; 7523 case CP0_REG06__SRSCONF3: 7524 check_insn(ctx, ISA_MIPS_R2); 7525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7526 register_name = "SRSConf3"; 7527 break; 7528 case CP0_REG06__SRSCONF4: 7529 check_insn(ctx, ISA_MIPS_R2); 7530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7531 register_name = "SRSConf4"; 7532 break; 7533 case CP0_REG06__PWCTL: 7534 check_pw(ctx); 7535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7536 register_name = "PWCtl"; 7537 break; 7538 default: 7539 goto cp0_unimplemented; 7540 } 7541 break; 7542 case CP0_REGISTER_07: 7543 switch (sel) { 7544 case CP0_REG07__HWRENA: 7545 check_insn(ctx, ISA_MIPS_R2); 7546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7547 register_name = "HWREna"; 7548 break; 7549 default: 7550 goto cp0_unimplemented; 7551 } 7552 break; 7553 case CP0_REGISTER_08: 7554 switch (sel) { 7555 case CP0_REG08__BADVADDR: 7556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7557 register_name = "BadVAddr"; 7558 break; 7559 case CP0_REG08__BADINSTR: 7560 CP0_CHECK(ctx->bi); 7561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7562 register_name = "BadInstr"; 7563 break; 7564 case CP0_REG08__BADINSTRP: 7565 CP0_CHECK(ctx->bp); 7566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7567 register_name = "BadInstrP"; 7568 break; 7569 case CP0_REG08__BADINSTRX: 7570 CP0_CHECK(ctx->bi); 7571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7572 tcg_gen_andi_tl(arg, arg, ~0xffff); 7573 register_name = "BadInstrX"; 7574 break; 7575 default: 7576 goto cp0_unimplemented; 7577 } 7578 break; 7579 case CP0_REGISTER_09: 7580 switch (sel) { 7581 case CP0_REG09__COUNT: 7582 /* Mark as an IO operation because we read the time. */ 7583 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7584 gen_io_start(); 7585 } 7586 gen_helper_mfc0_count(arg, cpu_env); 7587 /* 7588 * Break the TB to be able to take timer interrupts immediately 7589 * after reading count. DISAS_STOP isn't sufficient, we need to 7590 * ensure we break completely out of translated code. 7591 */ 7592 gen_save_pc(ctx->base.pc_next + 4); 7593 ctx->base.is_jmp = DISAS_EXIT; 7594 register_name = "Count"; 7595 break; 7596 case CP0_REG09__SAARI: 7597 CP0_CHECK(ctx->saar); 7598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7599 register_name = "SAARI"; 7600 break; 7601 case CP0_REG09__SAAR: 7602 CP0_CHECK(ctx->saar); 7603 gen_helper_dmfc0_saar(arg, cpu_env); 7604 register_name = "SAAR"; 7605 break; 7606 default: 7607 goto cp0_unimplemented; 7608 } 7609 break; 7610 case CP0_REGISTER_10: 7611 switch (sel) { 7612 case CP0_REG10__ENTRYHI: 7613 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7614 register_name = "EntryHi"; 7615 break; 7616 default: 7617 goto cp0_unimplemented; 7618 } 7619 break; 7620 case CP0_REGISTER_11: 7621 switch (sel) { 7622 case CP0_REG11__COMPARE: 7623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7624 register_name = "Compare"; 7625 break; 7626 /* 6,7 are implementation dependent */ 7627 default: 7628 goto cp0_unimplemented; 7629 } 7630 break; 7631 case CP0_REGISTER_12: 7632 switch (sel) { 7633 case CP0_REG12__STATUS: 7634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7635 register_name = "Status"; 7636 break; 7637 case CP0_REG12__INTCTL: 7638 check_insn(ctx, ISA_MIPS_R2); 7639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7640 register_name = "IntCtl"; 7641 break; 7642 case CP0_REG12__SRSCTL: 7643 check_insn(ctx, ISA_MIPS_R2); 7644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7645 register_name = "SRSCtl"; 7646 break; 7647 case CP0_REG12__SRSMAP: 7648 check_insn(ctx, ISA_MIPS_R2); 7649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7650 register_name = "SRSMap"; 7651 break; 7652 default: 7653 goto cp0_unimplemented; 7654 } 7655 break; 7656 case CP0_REGISTER_13: 7657 switch (sel) { 7658 case CP0_REG13__CAUSE: 7659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7660 register_name = "Cause"; 7661 break; 7662 default: 7663 goto cp0_unimplemented; 7664 } 7665 break; 7666 case CP0_REGISTER_14: 7667 switch (sel) { 7668 case CP0_REG14__EPC: 7669 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7670 register_name = "EPC"; 7671 break; 7672 default: 7673 goto cp0_unimplemented; 7674 } 7675 break; 7676 case CP0_REGISTER_15: 7677 switch (sel) { 7678 case CP0_REG15__PRID: 7679 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7680 register_name = "PRid"; 7681 break; 7682 case CP0_REG15__EBASE: 7683 check_insn(ctx, ISA_MIPS_R2); 7684 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7685 register_name = "EBase"; 7686 break; 7687 case CP0_REG15__CMGCRBASE: 7688 check_insn(ctx, ISA_MIPS_R2); 7689 CP0_CHECK(ctx->cmgcr); 7690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7691 register_name = "CMGCRBase"; 7692 break; 7693 default: 7694 goto cp0_unimplemented; 7695 } 7696 break; 7697 case CP0_REGISTER_16: 7698 switch (sel) { 7699 case CP0_REG16__CONFIG: 7700 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7701 register_name = "Config"; 7702 break; 7703 case CP0_REG16__CONFIG1: 7704 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7705 register_name = "Config1"; 7706 break; 7707 case CP0_REG16__CONFIG2: 7708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7709 register_name = "Config2"; 7710 break; 7711 case CP0_REG16__CONFIG3: 7712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7713 register_name = "Config3"; 7714 break; 7715 case CP0_REG16__CONFIG4: 7716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7717 register_name = "Config4"; 7718 break; 7719 case CP0_REG16__CONFIG5: 7720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7721 register_name = "Config5"; 7722 break; 7723 /* 6,7 are implementation dependent */ 7724 case CP0_REG16__CONFIG6: 7725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7726 register_name = "Config6"; 7727 break; 7728 case CP0_REG16__CONFIG7: 7729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7730 register_name = "Config7"; 7731 break; 7732 default: 7733 goto cp0_unimplemented; 7734 } 7735 break; 7736 case CP0_REGISTER_17: 7737 switch (sel) { 7738 case CP0_REG17__LLADDR: 7739 gen_helper_dmfc0_lladdr(arg, cpu_env); 7740 register_name = "LLAddr"; 7741 break; 7742 case CP0_REG17__MAAR: 7743 CP0_CHECK(ctx->mrp); 7744 gen_helper_dmfc0_maar(arg, cpu_env); 7745 register_name = "MAAR"; 7746 break; 7747 case CP0_REG17__MAARI: 7748 CP0_CHECK(ctx->mrp); 7749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7750 register_name = "MAARI"; 7751 break; 7752 default: 7753 goto cp0_unimplemented; 7754 } 7755 break; 7756 case CP0_REGISTER_18: 7757 switch (sel) { 7758 case CP0_REG18__WATCHLO0: 7759 case CP0_REG18__WATCHLO1: 7760 case CP0_REG18__WATCHLO2: 7761 case CP0_REG18__WATCHLO3: 7762 case CP0_REG18__WATCHLO4: 7763 case CP0_REG18__WATCHLO5: 7764 case CP0_REG18__WATCHLO6: 7765 case CP0_REG18__WATCHLO7: 7766 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7767 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7768 register_name = "WatchLo"; 7769 break; 7770 default: 7771 goto cp0_unimplemented; 7772 } 7773 break; 7774 case CP0_REGISTER_19: 7775 switch (sel) { 7776 case CP0_REG19__WATCHHI0: 7777 case CP0_REG19__WATCHHI1: 7778 case CP0_REG19__WATCHHI2: 7779 case CP0_REG19__WATCHHI3: 7780 case CP0_REG19__WATCHHI4: 7781 case CP0_REG19__WATCHHI5: 7782 case CP0_REG19__WATCHHI6: 7783 case CP0_REG19__WATCHHI7: 7784 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7785 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7786 register_name = "WatchHi"; 7787 break; 7788 default: 7789 goto cp0_unimplemented; 7790 } 7791 break; 7792 case CP0_REGISTER_20: 7793 switch (sel) { 7794 case CP0_REG20__XCONTEXT: 7795 check_insn(ctx, ISA_MIPS3); 7796 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7797 register_name = "XContext"; 7798 break; 7799 default: 7800 goto cp0_unimplemented; 7801 } 7802 break; 7803 case CP0_REGISTER_21: 7804 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7805 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7806 switch (sel) { 7807 case 0: 7808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7809 register_name = "Framemask"; 7810 break; 7811 default: 7812 goto cp0_unimplemented; 7813 } 7814 break; 7815 case CP0_REGISTER_22: 7816 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7817 register_name = "'Diagnostic"; /* implementation dependent */ 7818 break; 7819 case CP0_REGISTER_23: 7820 switch (sel) { 7821 case CP0_REG23__DEBUG: 7822 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7823 register_name = "Debug"; 7824 break; 7825 case CP0_REG23__TRACECONTROL: 7826 /* PDtrace support */ 7827 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7828 register_name = "TraceControl"; 7829 goto cp0_unimplemented; 7830 case CP0_REG23__TRACECONTROL2: 7831 /* PDtrace support */ 7832 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7833 register_name = "TraceControl2"; 7834 goto cp0_unimplemented; 7835 case CP0_REG23__USERTRACEDATA1: 7836 /* PDtrace support */ 7837 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7838 register_name = "UserTraceData1"; 7839 goto cp0_unimplemented; 7840 case CP0_REG23__TRACEIBPC: 7841 /* PDtrace support */ 7842 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7843 register_name = "TraceIBPC"; 7844 goto cp0_unimplemented; 7845 case CP0_REG23__TRACEDBPC: 7846 /* PDtrace support */ 7847 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7848 register_name = "TraceDBPC"; 7849 goto cp0_unimplemented; 7850 default: 7851 goto cp0_unimplemented; 7852 } 7853 break; 7854 case CP0_REGISTER_24: 7855 switch (sel) { 7856 case CP0_REG24__DEPC: 7857 /* EJTAG support */ 7858 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7859 register_name = "DEPC"; 7860 break; 7861 default: 7862 goto cp0_unimplemented; 7863 } 7864 break; 7865 case CP0_REGISTER_25: 7866 switch (sel) { 7867 case CP0_REG25__PERFCTL0: 7868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7869 register_name = "Performance0"; 7870 break; 7871 case CP0_REG25__PERFCNT0: 7872 /* gen_helper_dmfc0_performance1(arg); */ 7873 register_name = "Performance1"; 7874 goto cp0_unimplemented; 7875 case CP0_REG25__PERFCTL1: 7876 /* gen_helper_dmfc0_performance2(arg); */ 7877 register_name = "Performance2"; 7878 goto cp0_unimplemented; 7879 case CP0_REG25__PERFCNT1: 7880 /* gen_helper_dmfc0_performance3(arg); */ 7881 register_name = "Performance3"; 7882 goto cp0_unimplemented; 7883 case CP0_REG25__PERFCTL2: 7884 /* gen_helper_dmfc0_performance4(arg); */ 7885 register_name = "Performance4"; 7886 goto cp0_unimplemented; 7887 case CP0_REG25__PERFCNT2: 7888 /* gen_helper_dmfc0_performance5(arg); */ 7889 register_name = "Performance5"; 7890 goto cp0_unimplemented; 7891 case CP0_REG25__PERFCTL3: 7892 /* gen_helper_dmfc0_performance6(arg); */ 7893 register_name = "Performance6"; 7894 goto cp0_unimplemented; 7895 case CP0_REG25__PERFCNT3: 7896 /* gen_helper_dmfc0_performance7(arg); */ 7897 register_name = "Performance7"; 7898 goto cp0_unimplemented; 7899 default: 7900 goto cp0_unimplemented; 7901 } 7902 break; 7903 case CP0_REGISTER_26: 7904 switch (sel) { 7905 case CP0_REG26__ERRCTL: 7906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7907 register_name = "ErrCtl"; 7908 break; 7909 default: 7910 goto cp0_unimplemented; 7911 } 7912 break; 7913 case CP0_REGISTER_27: 7914 switch (sel) { 7915 /* ignored */ 7916 case CP0_REG27__CACHERR: 7917 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7918 register_name = "CacheErr"; 7919 break; 7920 default: 7921 goto cp0_unimplemented; 7922 } 7923 break; 7924 case CP0_REGISTER_28: 7925 switch (sel) { 7926 case CP0_REG28__TAGLO: 7927 case CP0_REG28__TAGLO1: 7928 case CP0_REG28__TAGLO2: 7929 case CP0_REG28__TAGLO3: 7930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7931 register_name = "TagLo"; 7932 break; 7933 case CP0_REG28__DATALO: 7934 case CP0_REG28__DATALO1: 7935 case CP0_REG28__DATALO2: 7936 case CP0_REG28__DATALO3: 7937 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7938 register_name = "DataLo"; 7939 break; 7940 default: 7941 goto cp0_unimplemented; 7942 } 7943 break; 7944 case CP0_REGISTER_29: 7945 switch (sel) { 7946 case CP0_REG29__TAGHI: 7947 case CP0_REG29__TAGHI1: 7948 case CP0_REG29__TAGHI2: 7949 case CP0_REG29__TAGHI3: 7950 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7951 register_name = "TagHi"; 7952 break; 7953 case CP0_REG29__DATAHI: 7954 case CP0_REG29__DATAHI1: 7955 case CP0_REG29__DATAHI2: 7956 case CP0_REG29__DATAHI3: 7957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7958 register_name = "DataHi"; 7959 break; 7960 default: 7961 goto cp0_unimplemented; 7962 } 7963 break; 7964 case CP0_REGISTER_30: 7965 switch (sel) { 7966 case CP0_REG30__ERROREPC: 7967 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7968 register_name = "ErrorEPC"; 7969 break; 7970 default: 7971 goto cp0_unimplemented; 7972 } 7973 break; 7974 case CP0_REGISTER_31: 7975 switch (sel) { 7976 case CP0_REG31__DESAVE: 7977 /* EJTAG support */ 7978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7979 register_name = "DESAVE"; 7980 break; 7981 case CP0_REG31__KSCRATCH1: 7982 case CP0_REG31__KSCRATCH2: 7983 case CP0_REG31__KSCRATCH3: 7984 case CP0_REG31__KSCRATCH4: 7985 case CP0_REG31__KSCRATCH5: 7986 case CP0_REG31__KSCRATCH6: 7987 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7988 tcg_gen_ld_tl(arg, cpu_env, 7989 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7990 register_name = "KScratch"; 7991 break; 7992 default: 7993 goto cp0_unimplemented; 7994 } 7995 break; 7996 default: 7997 goto cp0_unimplemented; 7998 } 7999 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 8000 return; 8001 8002 cp0_unimplemented: 8003 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 8004 register_name, reg, sel); 8005 gen_mfc0_unimplemented(ctx, arg); 8006 } 8007 8008 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 8009 { 8010 const char *register_name = "invalid"; 8011 8012 if (sel != 0) { 8013 check_insn(ctx, ISA_MIPS_R1); 8014 } 8015 8016 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8017 gen_io_start(); 8018 } 8019 8020 switch (reg) { 8021 case CP0_REGISTER_00: 8022 switch (sel) { 8023 case CP0_REG00__INDEX: 8024 gen_helper_mtc0_index(cpu_env, arg); 8025 register_name = "Index"; 8026 break; 8027 case CP0_REG00__MVPCONTROL: 8028 CP0_CHECK(ctx->insn_flags & ASE_MT); 8029 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 8030 register_name = "MVPControl"; 8031 break; 8032 case CP0_REG00__MVPCONF0: 8033 CP0_CHECK(ctx->insn_flags & ASE_MT); 8034 /* ignored */ 8035 register_name = "MVPConf0"; 8036 break; 8037 case CP0_REG00__MVPCONF1: 8038 CP0_CHECK(ctx->insn_flags & ASE_MT); 8039 /* ignored */ 8040 register_name = "MVPConf1"; 8041 break; 8042 case CP0_REG00__VPCONTROL: 8043 CP0_CHECK(ctx->vp); 8044 /* ignored */ 8045 register_name = "VPControl"; 8046 break; 8047 default: 8048 goto cp0_unimplemented; 8049 } 8050 break; 8051 case CP0_REGISTER_01: 8052 switch (sel) { 8053 case CP0_REG01__RANDOM: 8054 /* ignored */ 8055 register_name = "Random"; 8056 break; 8057 case CP0_REG01__VPECONTROL: 8058 CP0_CHECK(ctx->insn_flags & ASE_MT); 8059 gen_helper_mtc0_vpecontrol(cpu_env, arg); 8060 register_name = "VPEControl"; 8061 break; 8062 case CP0_REG01__VPECONF0: 8063 CP0_CHECK(ctx->insn_flags & ASE_MT); 8064 gen_helper_mtc0_vpeconf0(cpu_env, arg); 8065 register_name = "VPEConf0"; 8066 break; 8067 case CP0_REG01__VPECONF1: 8068 CP0_CHECK(ctx->insn_flags & ASE_MT); 8069 gen_helper_mtc0_vpeconf1(cpu_env, arg); 8070 register_name = "VPEConf1"; 8071 break; 8072 case CP0_REG01__YQMASK: 8073 CP0_CHECK(ctx->insn_flags & ASE_MT); 8074 gen_helper_mtc0_yqmask(cpu_env, arg); 8075 register_name = "YQMask"; 8076 break; 8077 case CP0_REG01__VPESCHEDULE: 8078 CP0_CHECK(ctx->insn_flags & ASE_MT); 8079 tcg_gen_st_tl(arg, cpu_env, 8080 offsetof(CPUMIPSState, CP0_VPESchedule)); 8081 register_name = "VPESchedule"; 8082 break; 8083 case CP0_REG01__VPESCHEFBACK: 8084 CP0_CHECK(ctx->insn_flags & ASE_MT); 8085 tcg_gen_st_tl(arg, cpu_env, 8086 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 8087 register_name = "VPEScheFBack"; 8088 break; 8089 case CP0_REG01__VPEOPT: 8090 CP0_CHECK(ctx->insn_flags & ASE_MT); 8091 gen_helper_mtc0_vpeopt(cpu_env, arg); 8092 register_name = "VPEOpt"; 8093 break; 8094 default: 8095 goto cp0_unimplemented; 8096 } 8097 break; 8098 case CP0_REGISTER_02: 8099 switch (sel) { 8100 case CP0_REG02__ENTRYLO0: 8101 gen_helper_dmtc0_entrylo0(cpu_env, arg); 8102 register_name = "EntryLo0"; 8103 break; 8104 case CP0_REG02__TCSTATUS: 8105 CP0_CHECK(ctx->insn_flags & ASE_MT); 8106 gen_helper_mtc0_tcstatus(cpu_env, arg); 8107 register_name = "TCStatus"; 8108 break; 8109 case CP0_REG02__TCBIND: 8110 CP0_CHECK(ctx->insn_flags & ASE_MT); 8111 gen_helper_mtc0_tcbind(cpu_env, arg); 8112 register_name = "TCBind"; 8113 break; 8114 case CP0_REG02__TCRESTART: 8115 CP0_CHECK(ctx->insn_flags & ASE_MT); 8116 gen_helper_mtc0_tcrestart(cpu_env, arg); 8117 register_name = "TCRestart"; 8118 break; 8119 case CP0_REG02__TCHALT: 8120 CP0_CHECK(ctx->insn_flags & ASE_MT); 8121 gen_helper_mtc0_tchalt(cpu_env, arg); 8122 register_name = "TCHalt"; 8123 break; 8124 case CP0_REG02__TCCONTEXT: 8125 CP0_CHECK(ctx->insn_flags & ASE_MT); 8126 gen_helper_mtc0_tccontext(cpu_env, arg); 8127 register_name = "TCContext"; 8128 break; 8129 case CP0_REG02__TCSCHEDULE: 8130 CP0_CHECK(ctx->insn_flags & ASE_MT); 8131 gen_helper_mtc0_tcschedule(cpu_env, arg); 8132 register_name = "TCSchedule"; 8133 break; 8134 case CP0_REG02__TCSCHEFBACK: 8135 CP0_CHECK(ctx->insn_flags & ASE_MT); 8136 gen_helper_mtc0_tcschefback(cpu_env, arg); 8137 register_name = "TCScheFBack"; 8138 break; 8139 default: 8140 goto cp0_unimplemented; 8141 } 8142 break; 8143 case CP0_REGISTER_03: 8144 switch (sel) { 8145 case CP0_REG03__ENTRYLO1: 8146 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8147 register_name = "EntryLo1"; 8148 break; 8149 case CP0_REG03__GLOBALNUM: 8150 CP0_CHECK(ctx->vp); 8151 /* ignored */ 8152 register_name = "GlobalNumber"; 8153 break; 8154 default: 8155 goto cp0_unimplemented; 8156 } 8157 break; 8158 case CP0_REGISTER_04: 8159 switch (sel) { 8160 case CP0_REG04__CONTEXT: 8161 gen_helper_mtc0_context(cpu_env, arg); 8162 register_name = "Context"; 8163 break; 8164 case CP0_REG04__CONTEXTCONFIG: 8165 /* SmartMIPS ASE */ 8166 /* gen_helper_dmtc0_contextconfig(arg); */ 8167 register_name = "ContextConfig"; 8168 goto cp0_unimplemented; 8169 case CP0_REG04__USERLOCAL: 8170 CP0_CHECK(ctx->ulri); 8171 tcg_gen_st_tl(arg, cpu_env, 8172 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8173 register_name = "UserLocal"; 8174 break; 8175 case CP0_REG04__MMID: 8176 CP0_CHECK(ctx->mi); 8177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8178 register_name = "MMID"; 8179 break; 8180 default: 8181 goto cp0_unimplemented; 8182 } 8183 break; 8184 case CP0_REGISTER_05: 8185 switch (sel) { 8186 case CP0_REG05__PAGEMASK: 8187 gen_helper_mtc0_pagemask(cpu_env, arg); 8188 register_name = "PageMask"; 8189 break; 8190 case CP0_REG05__PAGEGRAIN: 8191 check_insn(ctx, ISA_MIPS_R2); 8192 gen_helper_mtc0_pagegrain(cpu_env, arg); 8193 register_name = "PageGrain"; 8194 break; 8195 case CP0_REG05__SEGCTL0: 8196 CP0_CHECK(ctx->sc); 8197 gen_helper_mtc0_segctl0(cpu_env, arg); 8198 register_name = "SegCtl0"; 8199 break; 8200 case CP0_REG05__SEGCTL1: 8201 CP0_CHECK(ctx->sc); 8202 gen_helper_mtc0_segctl1(cpu_env, arg); 8203 register_name = "SegCtl1"; 8204 break; 8205 case CP0_REG05__SEGCTL2: 8206 CP0_CHECK(ctx->sc); 8207 gen_helper_mtc0_segctl2(cpu_env, arg); 8208 register_name = "SegCtl2"; 8209 break; 8210 case CP0_REG05__PWBASE: 8211 check_pw(ctx); 8212 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8213 register_name = "PWBase"; 8214 break; 8215 case CP0_REG05__PWFIELD: 8216 check_pw(ctx); 8217 gen_helper_mtc0_pwfield(cpu_env, arg); 8218 register_name = "PWField"; 8219 break; 8220 case CP0_REG05__PWSIZE: 8221 check_pw(ctx); 8222 gen_helper_mtc0_pwsize(cpu_env, arg); 8223 register_name = "PWSize"; 8224 break; 8225 default: 8226 goto cp0_unimplemented; 8227 } 8228 break; 8229 case CP0_REGISTER_06: 8230 switch (sel) { 8231 case CP0_REG06__WIRED: 8232 gen_helper_mtc0_wired(cpu_env, arg); 8233 register_name = "Wired"; 8234 break; 8235 case CP0_REG06__SRSCONF0: 8236 check_insn(ctx, ISA_MIPS_R2); 8237 gen_helper_mtc0_srsconf0(cpu_env, arg); 8238 register_name = "SRSConf0"; 8239 break; 8240 case CP0_REG06__SRSCONF1: 8241 check_insn(ctx, ISA_MIPS_R2); 8242 gen_helper_mtc0_srsconf1(cpu_env, arg); 8243 register_name = "SRSConf1"; 8244 break; 8245 case CP0_REG06__SRSCONF2: 8246 check_insn(ctx, ISA_MIPS_R2); 8247 gen_helper_mtc0_srsconf2(cpu_env, arg); 8248 register_name = "SRSConf2"; 8249 break; 8250 case CP0_REG06__SRSCONF3: 8251 check_insn(ctx, ISA_MIPS_R2); 8252 gen_helper_mtc0_srsconf3(cpu_env, arg); 8253 register_name = "SRSConf3"; 8254 break; 8255 case CP0_REG06__SRSCONF4: 8256 check_insn(ctx, ISA_MIPS_R2); 8257 gen_helper_mtc0_srsconf4(cpu_env, arg); 8258 register_name = "SRSConf4"; 8259 break; 8260 case CP0_REG06__PWCTL: 8261 check_pw(ctx); 8262 gen_helper_mtc0_pwctl(cpu_env, arg); 8263 register_name = "PWCtl"; 8264 break; 8265 default: 8266 goto cp0_unimplemented; 8267 } 8268 break; 8269 case CP0_REGISTER_07: 8270 switch (sel) { 8271 case CP0_REG07__HWRENA: 8272 check_insn(ctx, ISA_MIPS_R2); 8273 gen_helper_mtc0_hwrena(cpu_env, arg); 8274 ctx->base.is_jmp = DISAS_STOP; 8275 register_name = "HWREna"; 8276 break; 8277 default: 8278 goto cp0_unimplemented; 8279 } 8280 break; 8281 case CP0_REGISTER_08: 8282 switch (sel) { 8283 case CP0_REG08__BADVADDR: 8284 /* ignored */ 8285 register_name = "BadVAddr"; 8286 break; 8287 case CP0_REG08__BADINSTR: 8288 /* ignored */ 8289 register_name = "BadInstr"; 8290 break; 8291 case CP0_REG08__BADINSTRP: 8292 /* ignored */ 8293 register_name = "BadInstrP"; 8294 break; 8295 case CP0_REG08__BADINSTRX: 8296 /* ignored */ 8297 register_name = "BadInstrX"; 8298 break; 8299 default: 8300 goto cp0_unimplemented; 8301 } 8302 break; 8303 case CP0_REGISTER_09: 8304 switch (sel) { 8305 case CP0_REG09__COUNT: 8306 gen_helper_mtc0_count(cpu_env, arg); 8307 register_name = "Count"; 8308 break; 8309 case CP0_REG09__SAARI: 8310 CP0_CHECK(ctx->saar); 8311 gen_helper_mtc0_saari(cpu_env, arg); 8312 register_name = "SAARI"; 8313 break; 8314 case CP0_REG09__SAAR: 8315 CP0_CHECK(ctx->saar); 8316 gen_helper_mtc0_saar(cpu_env, arg); 8317 register_name = "SAAR"; 8318 break; 8319 default: 8320 goto cp0_unimplemented; 8321 } 8322 /* Stop translation as we may have switched the execution mode */ 8323 ctx->base.is_jmp = DISAS_STOP; 8324 break; 8325 case CP0_REGISTER_10: 8326 switch (sel) { 8327 case CP0_REG10__ENTRYHI: 8328 gen_helper_mtc0_entryhi(cpu_env, arg); 8329 register_name = "EntryHi"; 8330 break; 8331 default: 8332 goto cp0_unimplemented; 8333 } 8334 break; 8335 case CP0_REGISTER_11: 8336 switch (sel) { 8337 case CP0_REG11__COMPARE: 8338 gen_helper_mtc0_compare(cpu_env, arg); 8339 register_name = "Compare"; 8340 break; 8341 /* 6,7 are implementation dependent */ 8342 default: 8343 goto cp0_unimplemented; 8344 } 8345 /* Stop translation as we may have switched the execution mode */ 8346 ctx->base.is_jmp = DISAS_STOP; 8347 break; 8348 case CP0_REGISTER_12: 8349 switch (sel) { 8350 case CP0_REG12__STATUS: 8351 save_cpu_state(ctx, 1); 8352 gen_helper_mtc0_status(cpu_env, arg); 8353 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8354 gen_save_pc(ctx->base.pc_next + 4); 8355 ctx->base.is_jmp = DISAS_EXIT; 8356 register_name = "Status"; 8357 break; 8358 case CP0_REG12__INTCTL: 8359 check_insn(ctx, ISA_MIPS_R2); 8360 gen_helper_mtc0_intctl(cpu_env, arg); 8361 /* Stop translation as we may have switched the execution mode */ 8362 ctx->base.is_jmp = DISAS_STOP; 8363 register_name = "IntCtl"; 8364 break; 8365 case CP0_REG12__SRSCTL: 8366 check_insn(ctx, ISA_MIPS_R2); 8367 gen_helper_mtc0_srsctl(cpu_env, arg); 8368 /* Stop translation as we may have switched the execution mode */ 8369 ctx->base.is_jmp = DISAS_STOP; 8370 register_name = "SRSCtl"; 8371 break; 8372 case CP0_REG12__SRSMAP: 8373 check_insn(ctx, ISA_MIPS_R2); 8374 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8375 /* Stop translation as we may have switched the execution mode */ 8376 ctx->base.is_jmp = DISAS_STOP; 8377 register_name = "SRSMap"; 8378 break; 8379 default: 8380 goto cp0_unimplemented; 8381 } 8382 break; 8383 case CP0_REGISTER_13: 8384 switch (sel) { 8385 case CP0_REG13__CAUSE: 8386 save_cpu_state(ctx, 1); 8387 gen_helper_mtc0_cause(cpu_env, arg); 8388 /* 8389 * Stop translation as we may have triggered an interrupt. 8390 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8391 * translated code to check for pending interrupts. 8392 */ 8393 gen_save_pc(ctx->base.pc_next + 4); 8394 ctx->base.is_jmp = DISAS_EXIT; 8395 register_name = "Cause"; 8396 break; 8397 default: 8398 goto cp0_unimplemented; 8399 } 8400 break; 8401 case CP0_REGISTER_14: 8402 switch (sel) { 8403 case CP0_REG14__EPC: 8404 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8405 register_name = "EPC"; 8406 break; 8407 default: 8408 goto cp0_unimplemented; 8409 } 8410 break; 8411 case CP0_REGISTER_15: 8412 switch (sel) { 8413 case CP0_REG15__PRID: 8414 /* ignored */ 8415 register_name = "PRid"; 8416 break; 8417 case CP0_REG15__EBASE: 8418 check_insn(ctx, ISA_MIPS_R2); 8419 gen_helper_mtc0_ebase(cpu_env, arg); 8420 register_name = "EBase"; 8421 break; 8422 default: 8423 goto cp0_unimplemented; 8424 } 8425 break; 8426 case CP0_REGISTER_16: 8427 switch (sel) { 8428 case CP0_REG16__CONFIG: 8429 gen_helper_mtc0_config0(cpu_env, arg); 8430 register_name = "Config"; 8431 /* Stop translation as we may have switched the execution mode */ 8432 ctx->base.is_jmp = DISAS_STOP; 8433 break; 8434 case CP0_REG16__CONFIG1: 8435 /* ignored, read only */ 8436 register_name = "Config1"; 8437 break; 8438 case CP0_REG16__CONFIG2: 8439 gen_helper_mtc0_config2(cpu_env, arg); 8440 register_name = "Config2"; 8441 /* Stop translation as we may have switched the execution mode */ 8442 ctx->base.is_jmp = DISAS_STOP; 8443 break; 8444 case CP0_REG16__CONFIG3: 8445 gen_helper_mtc0_config3(cpu_env, arg); 8446 register_name = "Config3"; 8447 /* Stop translation as we may have switched the execution mode */ 8448 ctx->base.is_jmp = DISAS_STOP; 8449 break; 8450 case CP0_REG16__CONFIG4: 8451 /* currently ignored */ 8452 register_name = "Config4"; 8453 break; 8454 case CP0_REG16__CONFIG5: 8455 gen_helper_mtc0_config5(cpu_env, arg); 8456 register_name = "Config5"; 8457 /* Stop translation as we may have switched the execution mode */ 8458 ctx->base.is_jmp = DISAS_STOP; 8459 break; 8460 /* 6,7 are implementation dependent */ 8461 default: 8462 register_name = "Invalid config selector"; 8463 goto cp0_unimplemented; 8464 } 8465 break; 8466 case CP0_REGISTER_17: 8467 switch (sel) { 8468 case CP0_REG17__LLADDR: 8469 gen_helper_mtc0_lladdr(cpu_env, arg); 8470 register_name = "LLAddr"; 8471 break; 8472 case CP0_REG17__MAAR: 8473 CP0_CHECK(ctx->mrp); 8474 gen_helper_mtc0_maar(cpu_env, arg); 8475 register_name = "MAAR"; 8476 break; 8477 case CP0_REG17__MAARI: 8478 CP0_CHECK(ctx->mrp); 8479 gen_helper_mtc0_maari(cpu_env, arg); 8480 register_name = "MAARI"; 8481 break; 8482 default: 8483 goto cp0_unimplemented; 8484 } 8485 break; 8486 case CP0_REGISTER_18: 8487 switch (sel) { 8488 case CP0_REG18__WATCHLO0: 8489 case CP0_REG18__WATCHLO1: 8490 case CP0_REG18__WATCHLO2: 8491 case CP0_REG18__WATCHLO3: 8492 case CP0_REG18__WATCHLO4: 8493 case CP0_REG18__WATCHLO5: 8494 case CP0_REG18__WATCHLO6: 8495 case CP0_REG18__WATCHLO7: 8496 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8497 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8498 register_name = "WatchLo"; 8499 break; 8500 default: 8501 goto cp0_unimplemented; 8502 } 8503 break; 8504 case CP0_REGISTER_19: 8505 switch (sel) { 8506 case CP0_REG19__WATCHHI0: 8507 case CP0_REG19__WATCHHI1: 8508 case CP0_REG19__WATCHHI2: 8509 case CP0_REG19__WATCHHI3: 8510 case CP0_REG19__WATCHHI4: 8511 case CP0_REG19__WATCHHI5: 8512 case CP0_REG19__WATCHHI6: 8513 case CP0_REG19__WATCHHI7: 8514 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8515 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8516 register_name = "WatchHi"; 8517 break; 8518 default: 8519 goto cp0_unimplemented; 8520 } 8521 break; 8522 case CP0_REGISTER_20: 8523 switch (sel) { 8524 case CP0_REG20__XCONTEXT: 8525 check_insn(ctx, ISA_MIPS3); 8526 gen_helper_mtc0_xcontext(cpu_env, arg); 8527 register_name = "XContext"; 8528 break; 8529 default: 8530 goto cp0_unimplemented; 8531 } 8532 break; 8533 case CP0_REGISTER_21: 8534 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8535 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8536 switch (sel) { 8537 case 0: 8538 gen_helper_mtc0_framemask(cpu_env, arg); 8539 register_name = "Framemask"; 8540 break; 8541 default: 8542 goto cp0_unimplemented; 8543 } 8544 break; 8545 case CP0_REGISTER_22: 8546 /* ignored */ 8547 register_name = "Diagnostic"; /* implementation dependent */ 8548 break; 8549 case CP0_REGISTER_23: 8550 switch (sel) { 8551 case CP0_REG23__DEBUG: 8552 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8553 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8554 gen_save_pc(ctx->base.pc_next + 4); 8555 ctx->base.is_jmp = DISAS_EXIT; 8556 register_name = "Debug"; 8557 break; 8558 case CP0_REG23__TRACECONTROL: 8559 /* PDtrace support */ 8560 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8561 /* Stop translation as we may have switched the execution mode */ 8562 ctx->base.is_jmp = DISAS_STOP; 8563 register_name = "TraceControl"; 8564 goto cp0_unimplemented; 8565 case CP0_REG23__TRACECONTROL2: 8566 /* PDtrace support */ 8567 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8568 /* Stop translation as we may have switched the execution mode */ 8569 ctx->base.is_jmp = DISAS_STOP; 8570 register_name = "TraceControl2"; 8571 goto cp0_unimplemented; 8572 case CP0_REG23__USERTRACEDATA1: 8573 /* PDtrace support */ 8574 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8575 /* Stop translation as we may have switched the execution mode */ 8576 ctx->base.is_jmp = DISAS_STOP; 8577 register_name = "UserTraceData1"; 8578 goto cp0_unimplemented; 8579 case CP0_REG23__TRACEIBPC: 8580 /* PDtrace support */ 8581 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8582 /* Stop translation as we may have switched the execution mode */ 8583 ctx->base.is_jmp = DISAS_STOP; 8584 register_name = "TraceIBPC"; 8585 goto cp0_unimplemented; 8586 case CP0_REG23__TRACEDBPC: 8587 /* PDtrace support */ 8588 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8589 /* Stop translation as we may have switched the execution mode */ 8590 ctx->base.is_jmp = DISAS_STOP; 8591 register_name = "TraceDBPC"; 8592 goto cp0_unimplemented; 8593 default: 8594 goto cp0_unimplemented; 8595 } 8596 break; 8597 case CP0_REGISTER_24: 8598 switch (sel) { 8599 case CP0_REG24__DEPC: 8600 /* EJTAG support */ 8601 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8602 register_name = "DEPC"; 8603 break; 8604 default: 8605 goto cp0_unimplemented; 8606 } 8607 break; 8608 case CP0_REGISTER_25: 8609 switch (sel) { 8610 case CP0_REG25__PERFCTL0: 8611 gen_helper_mtc0_performance0(cpu_env, arg); 8612 register_name = "Performance0"; 8613 break; 8614 case CP0_REG25__PERFCNT0: 8615 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8616 register_name = "Performance1"; 8617 goto cp0_unimplemented; 8618 case CP0_REG25__PERFCTL1: 8619 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8620 register_name = "Performance2"; 8621 goto cp0_unimplemented; 8622 case CP0_REG25__PERFCNT1: 8623 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8624 register_name = "Performance3"; 8625 goto cp0_unimplemented; 8626 case CP0_REG25__PERFCTL2: 8627 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8628 register_name = "Performance4"; 8629 goto cp0_unimplemented; 8630 case CP0_REG25__PERFCNT2: 8631 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8632 register_name = "Performance5"; 8633 goto cp0_unimplemented; 8634 case CP0_REG25__PERFCTL3: 8635 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8636 register_name = "Performance6"; 8637 goto cp0_unimplemented; 8638 case CP0_REG25__PERFCNT3: 8639 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8640 register_name = "Performance7"; 8641 goto cp0_unimplemented; 8642 default: 8643 goto cp0_unimplemented; 8644 } 8645 break; 8646 case CP0_REGISTER_26: 8647 switch (sel) { 8648 case CP0_REG26__ERRCTL: 8649 gen_helper_mtc0_errctl(cpu_env, arg); 8650 ctx->base.is_jmp = DISAS_STOP; 8651 register_name = "ErrCtl"; 8652 break; 8653 default: 8654 goto cp0_unimplemented; 8655 } 8656 break; 8657 case CP0_REGISTER_27: 8658 switch (sel) { 8659 case CP0_REG27__CACHERR: 8660 /* ignored */ 8661 register_name = "CacheErr"; 8662 break; 8663 default: 8664 goto cp0_unimplemented; 8665 } 8666 break; 8667 case CP0_REGISTER_28: 8668 switch (sel) { 8669 case CP0_REG28__TAGLO: 8670 case CP0_REG28__TAGLO1: 8671 case CP0_REG28__TAGLO2: 8672 case CP0_REG28__TAGLO3: 8673 gen_helper_mtc0_taglo(cpu_env, arg); 8674 register_name = "TagLo"; 8675 break; 8676 case CP0_REG28__DATALO: 8677 case CP0_REG28__DATALO1: 8678 case CP0_REG28__DATALO2: 8679 case CP0_REG28__DATALO3: 8680 gen_helper_mtc0_datalo(cpu_env, arg); 8681 register_name = "DataLo"; 8682 break; 8683 default: 8684 goto cp0_unimplemented; 8685 } 8686 break; 8687 case CP0_REGISTER_29: 8688 switch (sel) { 8689 case CP0_REG29__TAGHI: 8690 case CP0_REG29__TAGHI1: 8691 case CP0_REG29__TAGHI2: 8692 case CP0_REG29__TAGHI3: 8693 gen_helper_mtc0_taghi(cpu_env, arg); 8694 register_name = "TagHi"; 8695 break; 8696 case CP0_REG29__DATAHI: 8697 case CP0_REG29__DATAHI1: 8698 case CP0_REG29__DATAHI2: 8699 case CP0_REG29__DATAHI3: 8700 gen_helper_mtc0_datahi(cpu_env, arg); 8701 register_name = "DataHi"; 8702 break; 8703 default: 8704 register_name = "invalid sel"; 8705 goto cp0_unimplemented; 8706 } 8707 break; 8708 case CP0_REGISTER_30: 8709 switch (sel) { 8710 case CP0_REG30__ERROREPC: 8711 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8712 register_name = "ErrorEPC"; 8713 break; 8714 default: 8715 goto cp0_unimplemented; 8716 } 8717 break; 8718 case CP0_REGISTER_31: 8719 switch (sel) { 8720 case CP0_REG31__DESAVE: 8721 /* EJTAG support */ 8722 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8723 register_name = "DESAVE"; 8724 break; 8725 case CP0_REG31__KSCRATCH1: 8726 case CP0_REG31__KSCRATCH2: 8727 case CP0_REG31__KSCRATCH3: 8728 case CP0_REG31__KSCRATCH4: 8729 case CP0_REG31__KSCRATCH5: 8730 case CP0_REG31__KSCRATCH6: 8731 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8732 tcg_gen_st_tl(arg, cpu_env, 8733 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8734 register_name = "KScratch"; 8735 break; 8736 default: 8737 goto cp0_unimplemented; 8738 } 8739 break; 8740 default: 8741 goto cp0_unimplemented; 8742 } 8743 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8744 8745 /* For simplicity assume that all writes can cause interrupts. */ 8746 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8747 /* 8748 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8749 * translated code to check for pending interrupts. 8750 */ 8751 gen_save_pc(ctx->base.pc_next + 4); 8752 ctx->base.is_jmp = DISAS_EXIT; 8753 } 8754 return; 8755 8756 cp0_unimplemented: 8757 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8758 register_name, reg, sel); 8759 } 8760 #endif /* TARGET_MIPS64 */ 8761 8762 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8763 int u, int sel, int h) 8764 { 8765 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8766 TCGv t0 = tcg_temp_local_new(); 8767 8768 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8769 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8770 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8771 tcg_gen_movi_tl(t0, -1); 8772 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8773 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8774 tcg_gen_movi_tl(t0, -1); 8775 } else if (u == 0) { 8776 switch (rt) { 8777 case 1: 8778 switch (sel) { 8779 case 1: 8780 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8781 break; 8782 case 2: 8783 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8784 break; 8785 default: 8786 goto die; 8787 break; 8788 } 8789 break; 8790 case 2: 8791 switch (sel) { 8792 case 1: 8793 gen_helper_mftc0_tcstatus(t0, cpu_env); 8794 break; 8795 case 2: 8796 gen_helper_mftc0_tcbind(t0, cpu_env); 8797 break; 8798 case 3: 8799 gen_helper_mftc0_tcrestart(t0, cpu_env); 8800 break; 8801 case 4: 8802 gen_helper_mftc0_tchalt(t0, cpu_env); 8803 break; 8804 case 5: 8805 gen_helper_mftc0_tccontext(t0, cpu_env); 8806 break; 8807 case 6: 8808 gen_helper_mftc0_tcschedule(t0, cpu_env); 8809 break; 8810 case 7: 8811 gen_helper_mftc0_tcschefback(t0, cpu_env); 8812 break; 8813 default: 8814 gen_mfc0(ctx, t0, rt, sel); 8815 break; 8816 } 8817 break; 8818 case 10: 8819 switch (sel) { 8820 case 0: 8821 gen_helper_mftc0_entryhi(t0, cpu_env); 8822 break; 8823 default: 8824 gen_mfc0(ctx, t0, rt, sel); 8825 break; 8826 } 8827 break; 8828 case 12: 8829 switch (sel) { 8830 case 0: 8831 gen_helper_mftc0_status(t0, cpu_env); 8832 break; 8833 default: 8834 gen_mfc0(ctx, t0, rt, sel); 8835 break; 8836 } 8837 break; 8838 case 13: 8839 switch (sel) { 8840 case 0: 8841 gen_helper_mftc0_cause(t0, cpu_env); 8842 break; 8843 default: 8844 goto die; 8845 break; 8846 } 8847 break; 8848 case 14: 8849 switch (sel) { 8850 case 0: 8851 gen_helper_mftc0_epc(t0, cpu_env); 8852 break; 8853 default: 8854 goto die; 8855 break; 8856 } 8857 break; 8858 case 15: 8859 switch (sel) { 8860 case 1: 8861 gen_helper_mftc0_ebase(t0, cpu_env); 8862 break; 8863 default: 8864 goto die; 8865 break; 8866 } 8867 break; 8868 case 16: 8869 switch (sel) { 8870 case 0: 8871 case 1: 8872 case 2: 8873 case 3: 8874 case 4: 8875 case 5: 8876 case 6: 8877 case 7: 8878 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 8879 break; 8880 default: 8881 goto die; 8882 break; 8883 } 8884 break; 8885 case 23: 8886 switch (sel) { 8887 case 0: 8888 gen_helper_mftc0_debug(t0, cpu_env); 8889 break; 8890 default: 8891 gen_mfc0(ctx, t0, rt, sel); 8892 break; 8893 } 8894 break; 8895 default: 8896 gen_mfc0(ctx, t0, rt, sel); 8897 } 8898 } else { 8899 switch (sel) { 8900 /* GPR registers. */ 8901 case 0: 8902 gen_helper_1e0i(mftgpr, t0, rt); 8903 break; 8904 /* Auxiliary CPU registers */ 8905 case 1: 8906 switch (rt) { 8907 case 0: 8908 gen_helper_1e0i(mftlo, t0, 0); 8909 break; 8910 case 1: 8911 gen_helper_1e0i(mfthi, t0, 0); 8912 break; 8913 case 2: 8914 gen_helper_1e0i(mftacx, t0, 0); 8915 break; 8916 case 4: 8917 gen_helper_1e0i(mftlo, t0, 1); 8918 break; 8919 case 5: 8920 gen_helper_1e0i(mfthi, t0, 1); 8921 break; 8922 case 6: 8923 gen_helper_1e0i(mftacx, t0, 1); 8924 break; 8925 case 8: 8926 gen_helper_1e0i(mftlo, t0, 2); 8927 break; 8928 case 9: 8929 gen_helper_1e0i(mfthi, t0, 2); 8930 break; 8931 case 10: 8932 gen_helper_1e0i(mftacx, t0, 2); 8933 break; 8934 case 12: 8935 gen_helper_1e0i(mftlo, t0, 3); 8936 break; 8937 case 13: 8938 gen_helper_1e0i(mfthi, t0, 3); 8939 break; 8940 case 14: 8941 gen_helper_1e0i(mftacx, t0, 3); 8942 break; 8943 case 16: 8944 gen_helper_mftdsp(t0, cpu_env); 8945 break; 8946 default: 8947 goto die; 8948 } 8949 break; 8950 /* Floating point (COP1). */ 8951 case 2: 8952 /* XXX: For now we support only a single FPU context. */ 8953 if (h == 0) { 8954 TCGv_i32 fp0 = tcg_temp_new_i32(); 8955 8956 gen_load_fpr32(ctx, fp0, rt); 8957 tcg_gen_ext_i32_tl(t0, fp0); 8958 tcg_temp_free_i32(fp0); 8959 } else { 8960 TCGv_i32 fp0 = tcg_temp_new_i32(); 8961 8962 gen_load_fpr32h(ctx, fp0, rt); 8963 tcg_gen_ext_i32_tl(t0, fp0); 8964 tcg_temp_free_i32(fp0); 8965 } 8966 break; 8967 case 3: 8968 /* XXX: For now we support only a single FPU context. */ 8969 gen_helper_1e0i(cfc1, t0, rt); 8970 break; 8971 /* COP2: Not implemented. */ 8972 case 4: 8973 case 5: 8974 /* fall through */ 8975 default: 8976 goto die; 8977 } 8978 } 8979 trace_mips_translate_tr("mftr", rt, u, sel, h); 8980 gen_store_gpr(t0, rd); 8981 tcg_temp_free(t0); 8982 return; 8983 8984 die: 8985 tcg_temp_free(t0); 8986 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8987 gen_reserved_instruction(ctx); 8988 } 8989 8990 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8991 int u, int sel, int h) 8992 { 8993 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8994 TCGv t0 = tcg_temp_local_new(); 8995 8996 gen_load_gpr(t0, rt); 8997 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8998 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8999 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 9000 /* NOP */ 9001 ; 9002 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 9003 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 9004 /* NOP */ 9005 ; 9006 } else if (u == 0) { 9007 switch (rd) { 9008 case 1: 9009 switch (sel) { 9010 case 1: 9011 gen_helper_mttc0_vpecontrol(cpu_env, t0); 9012 break; 9013 case 2: 9014 gen_helper_mttc0_vpeconf0(cpu_env, t0); 9015 break; 9016 default: 9017 goto die; 9018 break; 9019 } 9020 break; 9021 case 2: 9022 switch (sel) { 9023 case 1: 9024 gen_helper_mttc0_tcstatus(cpu_env, t0); 9025 break; 9026 case 2: 9027 gen_helper_mttc0_tcbind(cpu_env, t0); 9028 break; 9029 case 3: 9030 gen_helper_mttc0_tcrestart(cpu_env, t0); 9031 break; 9032 case 4: 9033 gen_helper_mttc0_tchalt(cpu_env, t0); 9034 break; 9035 case 5: 9036 gen_helper_mttc0_tccontext(cpu_env, t0); 9037 break; 9038 case 6: 9039 gen_helper_mttc0_tcschedule(cpu_env, t0); 9040 break; 9041 case 7: 9042 gen_helper_mttc0_tcschefback(cpu_env, t0); 9043 break; 9044 default: 9045 gen_mtc0(ctx, t0, rd, sel); 9046 break; 9047 } 9048 break; 9049 case 10: 9050 switch (sel) { 9051 case 0: 9052 gen_helper_mttc0_entryhi(cpu_env, t0); 9053 break; 9054 default: 9055 gen_mtc0(ctx, t0, rd, sel); 9056 break; 9057 } 9058 break; 9059 case 12: 9060 switch (sel) { 9061 case 0: 9062 gen_helper_mttc0_status(cpu_env, t0); 9063 break; 9064 default: 9065 gen_mtc0(ctx, t0, rd, sel); 9066 break; 9067 } 9068 break; 9069 case 13: 9070 switch (sel) { 9071 case 0: 9072 gen_helper_mttc0_cause(cpu_env, t0); 9073 break; 9074 default: 9075 goto die; 9076 break; 9077 } 9078 break; 9079 case 15: 9080 switch (sel) { 9081 case 1: 9082 gen_helper_mttc0_ebase(cpu_env, t0); 9083 break; 9084 default: 9085 goto die; 9086 break; 9087 } 9088 break; 9089 case 23: 9090 switch (sel) { 9091 case 0: 9092 gen_helper_mttc0_debug(cpu_env, t0); 9093 break; 9094 default: 9095 gen_mtc0(ctx, t0, rd, sel); 9096 break; 9097 } 9098 break; 9099 default: 9100 gen_mtc0(ctx, t0, rd, sel); 9101 } 9102 } else { 9103 switch (sel) { 9104 /* GPR registers. */ 9105 case 0: 9106 gen_helper_0e1i(mttgpr, t0, rd); 9107 break; 9108 /* Auxiliary CPU registers */ 9109 case 1: 9110 switch (rd) { 9111 case 0: 9112 gen_helper_0e1i(mttlo, t0, 0); 9113 break; 9114 case 1: 9115 gen_helper_0e1i(mtthi, t0, 0); 9116 break; 9117 case 2: 9118 gen_helper_0e1i(mttacx, t0, 0); 9119 break; 9120 case 4: 9121 gen_helper_0e1i(mttlo, t0, 1); 9122 break; 9123 case 5: 9124 gen_helper_0e1i(mtthi, t0, 1); 9125 break; 9126 case 6: 9127 gen_helper_0e1i(mttacx, t0, 1); 9128 break; 9129 case 8: 9130 gen_helper_0e1i(mttlo, t0, 2); 9131 break; 9132 case 9: 9133 gen_helper_0e1i(mtthi, t0, 2); 9134 break; 9135 case 10: 9136 gen_helper_0e1i(mttacx, t0, 2); 9137 break; 9138 case 12: 9139 gen_helper_0e1i(mttlo, t0, 3); 9140 break; 9141 case 13: 9142 gen_helper_0e1i(mtthi, t0, 3); 9143 break; 9144 case 14: 9145 gen_helper_0e1i(mttacx, t0, 3); 9146 break; 9147 case 16: 9148 gen_helper_mttdsp(cpu_env, t0); 9149 break; 9150 default: 9151 goto die; 9152 } 9153 break; 9154 /* Floating point (COP1). */ 9155 case 2: 9156 /* XXX: For now we support only a single FPU context. */ 9157 if (h == 0) { 9158 TCGv_i32 fp0 = tcg_temp_new_i32(); 9159 9160 tcg_gen_trunc_tl_i32(fp0, t0); 9161 gen_store_fpr32(ctx, fp0, rd); 9162 tcg_temp_free_i32(fp0); 9163 } else { 9164 TCGv_i32 fp0 = tcg_temp_new_i32(); 9165 9166 tcg_gen_trunc_tl_i32(fp0, t0); 9167 gen_store_fpr32h(ctx, fp0, rd); 9168 tcg_temp_free_i32(fp0); 9169 } 9170 break; 9171 case 3: 9172 /* XXX: For now we support only a single FPU context. */ 9173 { 9174 TCGv_i32 fs_tmp = tcg_const_i32(rd); 9175 9176 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9177 tcg_temp_free_i32(fs_tmp); 9178 } 9179 /* Stop translation as we may have changed hflags */ 9180 ctx->base.is_jmp = DISAS_STOP; 9181 break; 9182 /* COP2: Not implemented. */ 9183 case 4: 9184 case 5: 9185 /* fall through */ 9186 default: 9187 goto die; 9188 } 9189 } 9190 trace_mips_translate_tr("mttr", rd, u, sel, h); 9191 tcg_temp_free(t0); 9192 return; 9193 9194 die: 9195 tcg_temp_free(t0); 9196 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9197 gen_reserved_instruction(ctx); 9198 } 9199 9200 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9201 int rt, int rd) 9202 { 9203 const char *opn = "ldst"; 9204 9205 check_cp0_enabled(ctx); 9206 switch (opc) { 9207 case OPC_MFC0: 9208 if (rt == 0) { 9209 /* Treat as NOP. */ 9210 return; 9211 } 9212 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9213 opn = "mfc0"; 9214 break; 9215 case OPC_MTC0: 9216 { 9217 TCGv t0 = tcg_temp_new(); 9218 9219 gen_load_gpr(t0, rt); 9220 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9221 tcg_temp_free(t0); 9222 } 9223 opn = "mtc0"; 9224 break; 9225 #if defined(TARGET_MIPS64) 9226 case OPC_DMFC0: 9227 check_insn(ctx, ISA_MIPS3); 9228 if (rt == 0) { 9229 /* Treat as NOP. */ 9230 return; 9231 } 9232 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9233 opn = "dmfc0"; 9234 break; 9235 case OPC_DMTC0: 9236 check_insn(ctx, ISA_MIPS3); 9237 { 9238 TCGv t0 = tcg_temp_new(); 9239 9240 gen_load_gpr(t0, rt); 9241 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9242 tcg_temp_free(t0); 9243 } 9244 opn = "dmtc0"; 9245 break; 9246 #endif 9247 case OPC_MFHC0: 9248 check_mvh(ctx); 9249 if (rt == 0) { 9250 /* Treat as NOP. */ 9251 return; 9252 } 9253 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9254 opn = "mfhc0"; 9255 break; 9256 case OPC_MTHC0: 9257 check_mvh(ctx); 9258 { 9259 TCGv t0 = tcg_temp_new(); 9260 gen_load_gpr(t0, rt); 9261 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9262 tcg_temp_free(t0); 9263 } 9264 opn = "mthc0"; 9265 break; 9266 case OPC_MFTR: 9267 check_cp0_enabled(ctx); 9268 if (rd == 0) { 9269 /* Treat as NOP. */ 9270 return; 9271 } 9272 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9273 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9274 opn = "mftr"; 9275 break; 9276 case OPC_MTTR: 9277 check_cp0_enabled(ctx); 9278 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9279 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9280 opn = "mttr"; 9281 break; 9282 case OPC_TLBWI: 9283 opn = "tlbwi"; 9284 if (!env->tlb->helper_tlbwi) { 9285 goto die; 9286 } 9287 gen_helper_tlbwi(cpu_env); 9288 break; 9289 case OPC_TLBINV: 9290 opn = "tlbinv"; 9291 if (ctx->ie >= 2) { 9292 if (!env->tlb->helper_tlbinv) { 9293 goto die; 9294 } 9295 gen_helper_tlbinv(cpu_env); 9296 } /* treat as nop if TLBINV not supported */ 9297 break; 9298 case OPC_TLBINVF: 9299 opn = "tlbinvf"; 9300 if (ctx->ie >= 2) { 9301 if (!env->tlb->helper_tlbinvf) { 9302 goto die; 9303 } 9304 gen_helper_tlbinvf(cpu_env); 9305 } /* treat as nop if TLBINV not supported */ 9306 break; 9307 case OPC_TLBWR: 9308 opn = "tlbwr"; 9309 if (!env->tlb->helper_tlbwr) { 9310 goto die; 9311 } 9312 gen_helper_tlbwr(cpu_env); 9313 break; 9314 case OPC_TLBP: 9315 opn = "tlbp"; 9316 if (!env->tlb->helper_tlbp) { 9317 goto die; 9318 } 9319 gen_helper_tlbp(cpu_env); 9320 break; 9321 case OPC_TLBR: 9322 opn = "tlbr"; 9323 if (!env->tlb->helper_tlbr) { 9324 goto die; 9325 } 9326 gen_helper_tlbr(cpu_env); 9327 break; 9328 case OPC_ERET: /* OPC_ERETNC */ 9329 if ((ctx->insn_flags & ISA_MIPS_R6) && 9330 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9331 goto die; 9332 } else { 9333 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9334 if (ctx->opcode & (1 << bit_shift)) { 9335 /* OPC_ERETNC */ 9336 opn = "eretnc"; 9337 check_insn(ctx, ISA_MIPS_R5); 9338 gen_helper_eretnc(cpu_env); 9339 } else { 9340 /* OPC_ERET */ 9341 opn = "eret"; 9342 check_insn(ctx, ISA_MIPS2); 9343 gen_helper_eret(cpu_env); 9344 } 9345 ctx->base.is_jmp = DISAS_EXIT; 9346 } 9347 break; 9348 case OPC_DERET: 9349 opn = "deret"; 9350 check_insn(ctx, ISA_MIPS_R1); 9351 if ((ctx->insn_flags & ISA_MIPS_R6) && 9352 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9353 goto die; 9354 } 9355 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9356 MIPS_INVAL(opn); 9357 gen_reserved_instruction(ctx); 9358 } else { 9359 gen_helper_deret(cpu_env); 9360 ctx->base.is_jmp = DISAS_EXIT; 9361 } 9362 break; 9363 case OPC_WAIT: 9364 opn = "wait"; 9365 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9366 if ((ctx->insn_flags & ISA_MIPS_R6) && 9367 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9368 goto die; 9369 } 9370 /* If we get an exception, we want to restart at next instruction */ 9371 ctx->base.pc_next += 4; 9372 save_cpu_state(ctx, 1); 9373 ctx->base.pc_next -= 4; 9374 gen_helper_wait(cpu_env); 9375 ctx->base.is_jmp = DISAS_NORETURN; 9376 break; 9377 default: 9378 die: 9379 MIPS_INVAL(opn); 9380 gen_reserved_instruction(ctx); 9381 return; 9382 } 9383 (void)opn; /* avoid a compiler warning */ 9384 } 9385 #endif /* !CONFIG_USER_ONLY */ 9386 9387 /* CP1 Branches (before delay slot) */ 9388 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9389 int32_t cc, int32_t offset) 9390 { 9391 target_ulong btarget; 9392 TCGv_i32 t0 = tcg_temp_new_i32(); 9393 9394 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9395 gen_reserved_instruction(ctx); 9396 goto out; 9397 } 9398 9399 if (cc != 0) { 9400 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9401 } 9402 9403 btarget = ctx->base.pc_next + 4 + offset; 9404 9405 switch (op) { 9406 case OPC_BC1F: 9407 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9408 tcg_gen_not_i32(t0, t0); 9409 tcg_gen_andi_i32(t0, t0, 1); 9410 tcg_gen_extu_i32_tl(bcond, t0); 9411 goto not_likely; 9412 case OPC_BC1FL: 9413 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9414 tcg_gen_not_i32(t0, t0); 9415 tcg_gen_andi_i32(t0, t0, 1); 9416 tcg_gen_extu_i32_tl(bcond, t0); 9417 goto likely; 9418 case OPC_BC1T: 9419 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9420 tcg_gen_andi_i32(t0, t0, 1); 9421 tcg_gen_extu_i32_tl(bcond, t0); 9422 goto not_likely; 9423 case OPC_BC1TL: 9424 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9425 tcg_gen_andi_i32(t0, t0, 1); 9426 tcg_gen_extu_i32_tl(bcond, t0); 9427 likely: 9428 ctx->hflags |= MIPS_HFLAG_BL; 9429 break; 9430 case OPC_BC1FANY2: 9431 { 9432 TCGv_i32 t1 = tcg_temp_new_i32(); 9433 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9434 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9435 tcg_gen_nand_i32(t0, t0, t1); 9436 tcg_temp_free_i32(t1); 9437 tcg_gen_andi_i32(t0, t0, 1); 9438 tcg_gen_extu_i32_tl(bcond, t0); 9439 } 9440 goto not_likely; 9441 case OPC_BC1TANY2: 9442 { 9443 TCGv_i32 t1 = tcg_temp_new_i32(); 9444 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9445 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9446 tcg_gen_or_i32(t0, t0, t1); 9447 tcg_temp_free_i32(t1); 9448 tcg_gen_andi_i32(t0, t0, 1); 9449 tcg_gen_extu_i32_tl(bcond, t0); 9450 } 9451 goto not_likely; 9452 case OPC_BC1FANY4: 9453 { 9454 TCGv_i32 t1 = tcg_temp_new_i32(); 9455 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9456 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9457 tcg_gen_and_i32(t0, t0, t1); 9458 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9459 tcg_gen_and_i32(t0, t0, t1); 9460 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9461 tcg_gen_nand_i32(t0, t0, t1); 9462 tcg_temp_free_i32(t1); 9463 tcg_gen_andi_i32(t0, t0, 1); 9464 tcg_gen_extu_i32_tl(bcond, t0); 9465 } 9466 goto not_likely; 9467 case OPC_BC1TANY4: 9468 { 9469 TCGv_i32 t1 = tcg_temp_new_i32(); 9470 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9471 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9472 tcg_gen_or_i32(t0, t0, t1); 9473 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9474 tcg_gen_or_i32(t0, t0, t1); 9475 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9476 tcg_gen_or_i32(t0, t0, t1); 9477 tcg_temp_free_i32(t1); 9478 tcg_gen_andi_i32(t0, t0, 1); 9479 tcg_gen_extu_i32_tl(bcond, t0); 9480 } 9481 not_likely: 9482 ctx->hflags |= MIPS_HFLAG_BC; 9483 break; 9484 default: 9485 MIPS_INVAL("cp1 cond branch"); 9486 gen_reserved_instruction(ctx); 9487 goto out; 9488 } 9489 ctx->btarget = btarget; 9490 ctx->hflags |= MIPS_HFLAG_BDS32; 9491 out: 9492 tcg_temp_free_i32(t0); 9493 } 9494 9495 /* R6 CP1 Branches */ 9496 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9497 int32_t ft, int32_t offset, 9498 int delayslot_size) 9499 { 9500 target_ulong btarget; 9501 TCGv_i64 t0 = tcg_temp_new_i64(); 9502 9503 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9504 #ifdef MIPS_DEBUG_DISAS 9505 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9506 "\n", ctx->base.pc_next); 9507 #endif 9508 gen_reserved_instruction(ctx); 9509 goto out; 9510 } 9511 9512 gen_load_fpr64(ctx, t0, ft); 9513 tcg_gen_andi_i64(t0, t0, 1); 9514 9515 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9516 9517 switch (op) { 9518 case OPC_BC1EQZ: 9519 tcg_gen_xori_i64(t0, t0, 1); 9520 ctx->hflags |= MIPS_HFLAG_BC; 9521 break; 9522 case OPC_BC1NEZ: 9523 /* t0 already set */ 9524 ctx->hflags |= MIPS_HFLAG_BC; 9525 break; 9526 default: 9527 MIPS_INVAL("cp1 cond branch"); 9528 gen_reserved_instruction(ctx); 9529 goto out; 9530 } 9531 9532 tcg_gen_trunc_i64_tl(bcond, t0); 9533 9534 ctx->btarget = btarget; 9535 9536 switch (delayslot_size) { 9537 case 2: 9538 ctx->hflags |= MIPS_HFLAG_BDS16; 9539 break; 9540 case 4: 9541 ctx->hflags |= MIPS_HFLAG_BDS32; 9542 break; 9543 } 9544 9545 out: 9546 tcg_temp_free_i64(t0); 9547 } 9548 9549 /* Coprocessor 1 (FPU) */ 9550 9551 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9552 9553 enum fopcode { 9554 OPC_ADD_S = FOP(0, FMT_S), 9555 OPC_SUB_S = FOP(1, FMT_S), 9556 OPC_MUL_S = FOP(2, FMT_S), 9557 OPC_DIV_S = FOP(3, FMT_S), 9558 OPC_SQRT_S = FOP(4, FMT_S), 9559 OPC_ABS_S = FOP(5, FMT_S), 9560 OPC_MOV_S = FOP(6, FMT_S), 9561 OPC_NEG_S = FOP(7, FMT_S), 9562 OPC_ROUND_L_S = FOP(8, FMT_S), 9563 OPC_TRUNC_L_S = FOP(9, FMT_S), 9564 OPC_CEIL_L_S = FOP(10, FMT_S), 9565 OPC_FLOOR_L_S = FOP(11, FMT_S), 9566 OPC_ROUND_W_S = FOP(12, FMT_S), 9567 OPC_TRUNC_W_S = FOP(13, FMT_S), 9568 OPC_CEIL_W_S = FOP(14, FMT_S), 9569 OPC_FLOOR_W_S = FOP(15, FMT_S), 9570 OPC_SEL_S = FOP(16, FMT_S), 9571 OPC_MOVCF_S = FOP(17, FMT_S), 9572 OPC_MOVZ_S = FOP(18, FMT_S), 9573 OPC_MOVN_S = FOP(19, FMT_S), 9574 OPC_SELEQZ_S = FOP(20, FMT_S), 9575 OPC_RECIP_S = FOP(21, FMT_S), 9576 OPC_RSQRT_S = FOP(22, FMT_S), 9577 OPC_SELNEZ_S = FOP(23, FMT_S), 9578 OPC_MADDF_S = FOP(24, FMT_S), 9579 OPC_MSUBF_S = FOP(25, FMT_S), 9580 OPC_RINT_S = FOP(26, FMT_S), 9581 OPC_CLASS_S = FOP(27, FMT_S), 9582 OPC_MIN_S = FOP(28, FMT_S), 9583 OPC_RECIP2_S = FOP(28, FMT_S), 9584 OPC_MINA_S = FOP(29, FMT_S), 9585 OPC_RECIP1_S = FOP(29, FMT_S), 9586 OPC_MAX_S = FOP(30, FMT_S), 9587 OPC_RSQRT1_S = FOP(30, FMT_S), 9588 OPC_MAXA_S = FOP(31, FMT_S), 9589 OPC_RSQRT2_S = FOP(31, FMT_S), 9590 OPC_CVT_D_S = FOP(33, FMT_S), 9591 OPC_CVT_W_S = FOP(36, FMT_S), 9592 OPC_CVT_L_S = FOP(37, FMT_S), 9593 OPC_CVT_PS_S = FOP(38, FMT_S), 9594 OPC_CMP_F_S = FOP(48, FMT_S), 9595 OPC_CMP_UN_S = FOP(49, FMT_S), 9596 OPC_CMP_EQ_S = FOP(50, FMT_S), 9597 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9598 OPC_CMP_OLT_S = FOP(52, FMT_S), 9599 OPC_CMP_ULT_S = FOP(53, FMT_S), 9600 OPC_CMP_OLE_S = FOP(54, FMT_S), 9601 OPC_CMP_ULE_S = FOP(55, FMT_S), 9602 OPC_CMP_SF_S = FOP(56, FMT_S), 9603 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9604 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9605 OPC_CMP_NGL_S = FOP(59, FMT_S), 9606 OPC_CMP_LT_S = FOP(60, FMT_S), 9607 OPC_CMP_NGE_S = FOP(61, FMT_S), 9608 OPC_CMP_LE_S = FOP(62, FMT_S), 9609 OPC_CMP_NGT_S = FOP(63, FMT_S), 9610 9611 OPC_ADD_D = FOP(0, FMT_D), 9612 OPC_SUB_D = FOP(1, FMT_D), 9613 OPC_MUL_D = FOP(2, FMT_D), 9614 OPC_DIV_D = FOP(3, FMT_D), 9615 OPC_SQRT_D = FOP(4, FMT_D), 9616 OPC_ABS_D = FOP(5, FMT_D), 9617 OPC_MOV_D = FOP(6, FMT_D), 9618 OPC_NEG_D = FOP(7, FMT_D), 9619 OPC_ROUND_L_D = FOP(8, FMT_D), 9620 OPC_TRUNC_L_D = FOP(9, FMT_D), 9621 OPC_CEIL_L_D = FOP(10, FMT_D), 9622 OPC_FLOOR_L_D = FOP(11, FMT_D), 9623 OPC_ROUND_W_D = FOP(12, FMT_D), 9624 OPC_TRUNC_W_D = FOP(13, FMT_D), 9625 OPC_CEIL_W_D = FOP(14, FMT_D), 9626 OPC_FLOOR_W_D = FOP(15, FMT_D), 9627 OPC_SEL_D = FOP(16, FMT_D), 9628 OPC_MOVCF_D = FOP(17, FMT_D), 9629 OPC_MOVZ_D = FOP(18, FMT_D), 9630 OPC_MOVN_D = FOP(19, FMT_D), 9631 OPC_SELEQZ_D = FOP(20, FMT_D), 9632 OPC_RECIP_D = FOP(21, FMT_D), 9633 OPC_RSQRT_D = FOP(22, FMT_D), 9634 OPC_SELNEZ_D = FOP(23, FMT_D), 9635 OPC_MADDF_D = FOP(24, FMT_D), 9636 OPC_MSUBF_D = FOP(25, FMT_D), 9637 OPC_RINT_D = FOP(26, FMT_D), 9638 OPC_CLASS_D = FOP(27, FMT_D), 9639 OPC_MIN_D = FOP(28, FMT_D), 9640 OPC_RECIP2_D = FOP(28, FMT_D), 9641 OPC_MINA_D = FOP(29, FMT_D), 9642 OPC_RECIP1_D = FOP(29, FMT_D), 9643 OPC_MAX_D = FOP(30, FMT_D), 9644 OPC_RSQRT1_D = FOP(30, FMT_D), 9645 OPC_MAXA_D = FOP(31, FMT_D), 9646 OPC_RSQRT2_D = FOP(31, FMT_D), 9647 OPC_CVT_S_D = FOP(32, FMT_D), 9648 OPC_CVT_W_D = FOP(36, FMT_D), 9649 OPC_CVT_L_D = FOP(37, FMT_D), 9650 OPC_CMP_F_D = FOP(48, FMT_D), 9651 OPC_CMP_UN_D = FOP(49, FMT_D), 9652 OPC_CMP_EQ_D = FOP(50, FMT_D), 9653 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9654 OPC_CMP_OLT_D = FOP(52, FMT_D), 9655 OPC_CMP_ULT_D = FOP(53, FMT_D), 9656 OPC_CMP_OLE_D = FOP(54, FMT_D), 9657 OPC_CMP_ULE_D = FOP(55, FMT_D), 9658 OPC_CMP_SF_D = FOP(56, FMT_D), 9659 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9660 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9661 OPC_CMP_NGL_D = FOP(59, FMT_D), 9662 OPC_CMP_LT_D = FOP(60, FMT_D), 9663 OPC_CMP_NGE_D = FOP(61, FMT_D), 9664 OPC_CMP_LE_D = FOP(62, FMT_D), 9665 OPC_CMP_NGT_D = FOP(63, FMT_D), 9666 9667 OPC_CVT_S_W = FOP(32, FMT_W), 9668 OPC_CVT_D_W = FOP(33, FMT_W), 9669 OPC_CVT_S_L = FOP(32, FMT_L), 9670 OPC_CVT_D_L = FOP(33, FMT_L), 9671 OPC_CVT_PS_PW = FOP(38, FMT_W), 9672 9673 OPC_ADD_PS = FOP(0, FMT_PS), 9674 OPC_SUB_PS = FOP(1, FMT_PS), 9675 OPC_MUL_PS = FOP(2, FMT_PS), 9676 OPC_DIV_PS = FOP(3, FMT_PS), 9677 OPC_ABS_PS = FOP(5, FMT_PS), 9678 OPC_MOV_PS = FOP(6, FMT_PS), 9679 OPC_NEG_PS = FOP(7, FMT_PS), 9680 OPC_MOVCF_PS = FOP(17, FMT_PS), 9681 OPC_MOVZ_PS = FOP(18, FMT_PS), 9682 OPC_MOVN_PS = FOP(19, FMT_PS), 9683 OPC_ADDR_PS = FOP(24, FMT_PS), 9684 OPC_MULR_PS = FOP(26, FMT_PS), 9685 OPC_RECIP2_PS = FOP(28, FMT_PS), 9686 OPC_RECIP1_PS = FOP(29, FMT_PS), 9687 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9688 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9689 9690 OPC_CVT_S_PU = FOP(32, FMT_PS), 9691 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9692 OPC_CVT_S_PL = FOP(40, FMT_PS), 9693 OPC_PLL_PS = FOP(44, FMT_PS), 9694 OPC_PLU_PS = FOP(45, FMT_PS), 9695 OPC_PUL_PS = FOP(46, FMT_PS), 9696 OPC_PUU_PS = FOP(47, FMT_PS), 9697 OPC_CMP_F_PS = FOP(48, FMT_PS), 9698 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9699 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9700 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9701 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9702 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9703 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9704 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9705 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9706 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9707 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9708 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9709 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9710 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9711 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9712 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9713 }; 9714 9715 enum r6_f_cmp_op { 9716 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9717 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9718 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9719 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9720 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9721 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9722 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9723 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9724 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9725 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9726 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9727 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9728 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9729 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9730 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9731 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9732 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9733 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9734 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9735 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9736 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9737 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9738 9739 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9740 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9741 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9742 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9743 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9744 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9745 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9746 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9747 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9748 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9749 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9750 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9751 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9752 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9753 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9754 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9755 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9756 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9757 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9758 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9759 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9760 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9761 }; 9762 9763 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9764 { 9765 TCGv t0 = tcg_temp_new(); 9766 9767 switch (opc) { 9768 case OPC_MFC1: 9769 { 9770 TCGv_i32 fp0 = tcg_temp_new_i32(); 9771 9772 gen_load_fpr32(ctx, fp0, fs); 9773 tcg_gen_ext_i32_tl(t0, fp0); 9774 tcg_temp_free_i32(fp0); 9775 } 9776 gen_store_gpr(t0, rt); 9777 break; 9778 case OPC_MTC1: 9779 gen_load_gpr(t0, rt); 9780 { 9781 TCGv_i32 fp0 = tcg_temp_new_i32(); 9782 9783 tcg_gen_trunc_tl_i32(fp0, t0); 9784 gen_store_fpr32(ctx, fp0, fs); 9785 tcg_temp_free_i32(fp0); 9786 } 9787 break; 9788 case OPC_CFC1: 9789 gen_helper_1e0i(cfc1, t0, fs); 9790 gen_store_gpr(t0, rt); 9791 break; 9792 case OPC_CTC1: 9793 gen_load_gpr(t0, rt); 9794 save_cpu_state(ctx, 0); 9795 { 9796 TCGv_i32 fs_tmp = tcg_const_i32(fs); 9797 9798 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9799 tcg_temp_free_i32(fs_tmp); 9800 } 9801 /* Stop translation as we may have changed hflags */ 9802 ctx->base.is_jmp = DISAS_STOP; 9803 break; 9804 #if defined(TARGET_MIPS64) 9805 case OPC_DMFC1: 9806 gen_load_fpr64(ctx, t0, fs); 9807 gen_store_gpr(t0, rt); 9808 break; 9809 case OPC_DMTC1: 9810 gen_load_gpr(t0, rt); 9811 gen_store_fpr64(ctx, t0, fs); 9812 break; 9813 #endif 9814 case OPC_MFHC1: 9815 { 9816 TCGv_i32 fp0 = tcg_temp_new_i32(); 9817 9818 gen_load_fpr32h(ctx, fp0, fs); 9819 tcg_gen_ext_i32_tl(t0, fp0); 9820 tcg_temp_free_i32(fp0); 9821 } 9822 gen_store_gpr(t0, rt); 9823 break; 9824 case OPC_MTHC1: 9825 gen_load_gpr(t0, rt); 9826 { 9827 TCGv_i32 fp0 = tcg_temp_new_i32(); 9828 9829 tcg_gen_trunc_tl_i32(fp0, t0); 9830 gen_store_fpr32h(ctx, fp0, fs); 9831 tcg_temp_free_i32(fp0); 9832 } 9833 break; 9834 default: 9835 MIPS_INVAL("cp1 move"); 9836 gen_reserved_instruction(ctx); 9837 goto out; 9838 } 9839 9840 out: 9841 tcg_temp_free(t0); 9842 } 9843 9844 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9845 { 9846 TCGLabel *l1; 9847 TCGCond cond; 9848 TCGv_i32 t0; 9849 9850 if (rd == 0) { 9851 /* Treat as NOP. */ 9852 return; 9853 } 9854 9855 if (tf) { 9856 cond = TCG_COND_EQ; 9857 } else { 9858 cond = TCG_COND_NE; 9859 } 9860 9861 l1 = gen_new_label(); 9862 t0 = tcg_temp_new_i32(); 9863 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9864 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9865 tcg_temp_free_i32(t0); 9866 gen_load_gpr(cpu_gpr[rd], rs); 9867 gen_set_label(l1); 9868 } 9869 9870 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9871 int tf) 9872 { 9873 int cond; 9874 TCGv_i32 t0 = tcg_temp_new_i32(); 9875 TCGLabel *l1 = gen_new_label(); 9876 9877 if (tf) { 9878 cond = TCG_COND_EQ; 9879 } else { 9880 cond = TCG_COND_NE; 9881 } 9882 9883 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9884 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9885 gen_load_fpr32(ctx, t0, fs); 9886 gen_store_fpr32(ctx, t0, fd); 9887 gen_set_label(l1); 9888 tcg_temp_free_i32(t0); 9889 } 9890 9891 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9892 int tf) 9893 { 9894 int cond; 9895 TCGv_i32 t0 = tcg_temp_new_i32(); 9896 TCGv_i64 fp0; 9897 TCGLabel *l1 = gen_new_label(); 9898 9899 if (tf) { 9900 cond = TCG_COND_EQ; 9901 } else { 9902 cond = TCG_COND_NE; 9903 } 9904 9905 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9906 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9907 tcg_temp_free_i32(t0); 9908 fp0 = tcg_temp_new_i64(); 9909 gen_load_fpr64(ctx, fp0, fs); 9910 gen_store_fpr64(ctx, fp0, fd); 9911 tcg_temp_free_i64(fp0); 9912 gen_set_label(l1); 9913 } 9914 9915 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9916 int cc, int tf) 9917 { 9918 int cond; 9919 TCGv_i32 t0 = tcg_temp_new_i32(); 9920 TCGLabel *l1 = gen_new_label(); 9921 TCGLabel *l2 = gen_new_label(); 9922 9923 if (tf) { 9924 cond = TCG_COND_EQ; 9925 } else { 9926 cond = TCG_COND_NE; 9927 } 9928 9929 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9930 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9931 gen_load_fpr32(ctx, t0, fs); 9932 gen_store_fpr32(ctx, t0, fd); 9933 gen_set_label(l1); 9934 9935 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9936 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9937 gen_load_fpr32h(ctx, t0, fs); 9938 gen_store_fpr32h(ctx, t0, fd); 9939 tcg_temp_free_i32(t0); 9940 gen_set_label(l2); 9941 } 9942 9943 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9944 int fs) 9945 { 9946 TCGv_i32 t1 = tcg_const_i32(0); 9947 TCGv_i32 fp0 = tcg_temp_new_i32(); 9948 TCGv_i32 fp1 = tcg_temp_new_i32(); 9949 TCGv_i32 fp2 = tcg_temp_new_i32(); 9950 gen_load_fpr32(ctx, fp0, fd); 9951 gen_load_fpr32(ctx, fp1, ft); 9952 gen_load_fpr32(ctx, fp2, fs); 9953 9954 switch (op1) { 9955 case OPC_SEL_S: 9956 tcg_gen_andi_i32(fp0, fp0, 1); 9957 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9958 break; 9959 case OPC_SELEQZ_S: 9960 tcg_gen_andi_i32(fp1, fp1, 1); 9961 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9962 break; 9963 case OPC_SELNEZ_S: 9964 tcg_gen_andi_i32(fp1, fp1, 1); 9965 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9966 break; 9967 default: 9968 MIPS_INVAL("gen_sel_s"); 9969 gen_reserved_instruction(ctx); 9970 break; 9971 } 9972 9973 gen_store_fpr32(ctx, fp0, fd); 9974 tcg_temp_free_i32(fp2); 9975 tcg_temp_free_i32(fp1); 9976 tcg_temp_free_i32(fp0); 9977 tcg_temp_free_i32(t1); 9978 } 9979 9980 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9981 int fs) 9982 { 9983 TCGv_i64 t1 = tcg_const_i64(0); 9984 TCGv_i64 fp0 = tcg_temp_new_i64(); 9985 TCGv_i64 fp1 = tcg_temp_new_i64(); 9986 TCGv_i64 fp2 = tcg_temp_new_i64(); 9987 gen_load_fpr64(ctx, fp0, fd); 9988 gen_load_fpr64(ctx, fp1, ft); 9989 gen_load_fpr64(ctx, fp2, fs); 9990 9991 switch (op1) { 9992 case OPC_SEL_D: 9993 tcg_gen_andi_i64(fp0, fp0, 1); 9994 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9995 break; 9996 case OPC_SELEQZ_D: 9997 tcg_gen_andi_i64(fp1, fp1, 1); 9998 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9999 break; 10000 case OPC_SELNEZ_D: 10001 tcg_gen_andi_i64(fp1, fp1, 1); 10002 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 10003 break; 10004 default: 10005 MIPS_INVAL("gen_sel_d"); 10006 gen_reserved_instruction(ctx); 10007 break; 10008 } 10009 10010 gen_store_fpr64(ctx, fp0, fd); 10011 tcg_temp_free_i64(fp2); 10012 tcg_temp_free_i64(fp1); 10013 tcg_temp_free_i64(fp0); 10014 tcg_temp_free_i64(t1); 10015 } 10016 10017 static void gen_farith(DisasContext *ctx, enum fopcode op1, 10018 int ft, int fs, int fd, int cc) 10019 { 10020 uint32_t func = ctx->opcode & 0x3f; 10021 switch (op1) { 10022 case OPC_ADD_S: 10023 { 10024 TCGv_i32 fp0 = tcg_temp_new_i32(); 10025 TCGv_i32 fp1 = tcg_temp_new_i32(); 10026 10027 gen_load_fpr32(ctx, fp0, fs); 10028 gen_load_fpr32(ctx, fp1, ft); 10029 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 10030 tcg_temp_free_i32(fp1); 10031 gen_store_fpr32(ctx, fp0, fd); 10032 tcg_temp_free_i32(fp0); 10033 } 10034 break; 10035 case OPC_SUB_S: 10036 { 10037 TCGv_i32 fp0 = tcg_temp_new_i32(); 10038 TCGv_i32 fp1 = tcg_temp_new_i32(); 10039 10040 gen_load_fpr32(ctx, fp0, fs); 10041 gen_load_fpr32(ctx, fp1, ft); 10042 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 10043 tcg_temp_free_i32(fp1); 10044 gen_store_fpr32(ctx, fp0, fd); 10045 tcg_temp_free_i32(fp0); 10046 } 10047 break; 10048 case OPC_MUL_S: 10049 { 10050 TCGv_i32 fp0 = tcg_temp_new_i32(); 10051 TCGv_i32 fp1 = tcg_temp_new_i32(); 10052 10053 gen_load_fpr32(ctx, fp0, fs); 10054 gen_load_fpr32(ctx, fp1, ft); 10055 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 10056 tcg_temp_free_i32(fp1); 10057 gen_store_fpr32(ctx, fp0, fd); 10058 tcg_temp_free_i32(fp0); 10059 } 10060 break; 10061 case OPC_DIV_S: 10062 { 10063 TCGv_i32 fp0 = tcg_temp_new_i32(); 10064 TCGv_i32 fp1 = tcg_temp_new_i32(); 10065 10066 gen_load_fpr32(ctx, fp0, fs); 10067 gen_load_fpr32(ctx, fp1, ft); 10068 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 10069 tcg_temp_free_i32(fp1); 10070 gen_store_fpr32(ctx, fp0, fd); 10071 tcg_temp_free_i32(fp0); 10072 } 10073 break; 10074 case OPC_SQRT_S: 10075 { 10076 TCGv_i32 fp0 = tcg_temp_new_i32(); 10077 10078 gen_load_fpr32(ctx, fp0, fs); 10079 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 10080 gen_store_fpr32(ctx, fp0, fd); 10081 tcg_temp_free_i32(fp0); 10082 } 10083 break; 10084 case OPC_ABS_S: 10085 { 10086 TCGv_i32 fp0 = tcg_temp_new_i32(); 10087 10088 gen_load_fpr32(ctx, fp0, fs); 10089 if (ctx->abs2008) { 10090 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 10091 } else { 10092 gen_helper_float_abs_s(fp0, fp0); 10093 } 10094 gen_store_fpr32(ctx, fp0, fd); 10095 tcg_temp_free_i32(fp0); 10096 } 10097 break; 10098 case OPC_MOV_S: 10099 { 10100 TCGv_i32 fp0 = tcg_temp_new_i32(); 10101 10102 gen_load_fpr32(ctx, fp0, fs); 10103 gen_store_fpr32(ctx, fp0, fd); 10104 tcg_temp_free_i32(fp0); 10105 } 10106 break; 10107 case OPC_NEG_S: 10108 { 10109 TCGv_i32 fp0 = tcg_temp_new_i32(); 10110 10111 gen_load_fpr32(ctx, fp0, fs); 10112 if (ctx->abs2008) { 10113 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 10114 } else { 10115 gen_helper_float_chs_s(fp0, fp0); 10116 } 10117 gen_store_fpr32(ctx, fp0, fd); 10118 tcg_temp_free_i32(fp0); 10119 } 10120 break; 10121 case OPC_ROUND_L_S: 10122 check_cp1_64bitmode(ctx); 10123 { 10124 TCGv_i32 fp32 = tcg_temp_new_i32(); 10125 TCGv_i64 fp64 = tcg_temp_new_i64(); 10126 10127 gen_load_fpr32(ctx, fp32, fs); 10128 if (ctx->nan2008) { 10129 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10130 } else { 10131 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10132 } 10133 tcg_temp_free_i32(fp32); 10134 gen_store_fpr64(ctx, fp64, fd); 10135 tcg_temp_free_i64(fp64); 10136 } 10137 break; 10138 case OPC_TRUNC_L_S: 10139 check_cp1_64bitmode(ctx); 10140 { 10141 TCGv_i32 fp32 = tcg_temp_new_i32(); 10142 TCGv_i64 fp64 = tcg_temp_new_i64(); 10143 10144 gen_load_fpr32(ctx, fp32, fs); 10145 if (ctx->nan2008) { 10146 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10147 } else { 10148 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10149 } 10150 tcg_temp_free_i32(fp32); 10151 gen_store_fpr64(ctx, fp64, fd); 10152 tcg_temp_free_i64(fp64); 10153 } 10154 break; 10155 case OPC_CEIL_L_S: 10156 check_cp1_64bitmode(ctx); 10157 { 10158 TCGv_i32 fp32 = tcg_temp_new_i32(); 10159 TCGv_i64 fp64 = tcg_temp_new_i64(); 10160 10161 gen_load_fpr32(ctx, fp32, fs); 10162 if (ctx->nan2008) { 10163 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10164 } else { 10165 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10166 } 10167 tcg_temp_free_i32(fp32); 10168 gen_store_fpr64(ctx, fp64, fd); 10169 tcg_temp_free_i64(fp64); 10170 } 10171 break; 10172 case OPC_FLOOR_L_S: 10173 check_cp1_64bitmode(ctx); 10174 { 10175 TCGv_i32 fp32 = tcg_temp_new_i32(); 10176 TCGv_i64 fp64 = tcg_temp_new_i64(); 10177 10178 gen_load_fpr32(ctx, fp32, fs); 10179 if (ctx->nan2008) { 10180 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10181 } else { 10182 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10183 } 10184 tcg_temp_free_i32(fp32); 10185 gen_store_fpr64(ctx, fp64, fd); 10186 tcg_temp_free_i64(fp64); 10187 } 10188 break; 10189 case OPC_ROUND_W_S: 10190 { 10191 TCGv_i32 fp0 = tcg_temp_new_i32(); 10192 10193 gen_load_fpr32(ctx, fp0, fs); 10194 if (ctx->nan2008) { 10195 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10196 } else { 10197 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10198 } 10199 gen_store_fpr32(ctx, fp0, fd); 10200 tcg_temp_free_i32(fp0); 10201 } 10202 break; 10203 case OPC_TRUNC_W_S: 10204 { 10205 TCGv_i32 fp0 = tcg_temp_new_i32(); 10206 10207 gen_load_fpr32(ctx, fp0, fs); 10208 if (ctx->nan2008) { 10209 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10210 } else { 10211 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10212 } 10213 gen_store_fpr32(ctx, fp0, fd); 10214 tcg_temp_free_i32(fp0); 10215 } 10216 break; 10217 case OPC_CEIL_W_S: 10218 { 10219 TCGv_i32 fp0 = tcg_temp_new_i32(); 10220 10221 gen_load_fpr32(ctx, fp0, fs); 10222 if (ctx->nan2008) { 10223 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10224 } else { 10225 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10226 } 10227 gen_store_fpr32(ctx, fp0, fd); 10228 tcg_temp_free_i32(fp0); 10229 } 10230 break; 10231 case OPC_FLOOR_W_S: 10232 { 10233 TCGv_i32 fp0 = tcg_temp_new_i32(); 10234 10235 gen_load_fpr32(ctx, fp0, fs); 10236 if (ctx->nan2008) { 10237 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10238 } else { 10239 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10240 } 10241 gen_store_fpr32(ctx, fp0, fd); 10242 tcg_temp_free_i32(fp0); 10243 } 10244 break; 10245 case OPC_SEL_S: 10246 check_insn(ctx, ISA_MIPS_R6); 10247 gen_sel_s(ctx, op1, fd, ft, fs); 10248 break; 10249 case OPC_SELEQZ_S: 10250 check_insn(ctx, ISA_MIPS_R6); 10251 gen_sel_s(ctx, op1, fd, ft, fs); 10252 break; 10253 case OPC_SELNEZ_S: 10254 check_insn(ctx, ISA_MIPS_R6); 10255 gen_sel_s(ctx, op1, fd, ft, fs); 10256 break; 10257 case OPC_MOVCF_S: 10258 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10259 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10260 break; 10261 case OPC_MOVZ_S: 10262 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10263 { 10264 TCGLabel *l1 = gen_new_label(); 10265 TCGv_i32 fp0; 10266 10267 if (ft != 0) { 10268 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10269 } 10270 fp0 = tcg_temp_new_i32(); 10271 gen_load_fpr32(ctx, fp0, fs); 10272 gen_store_fpr32(ctx, fp0, fd); 10273 tcg_temp_free_i32(fp0); 10274 gen_set_label(l1); 10275 } 10276 break; 10277 case OPC_MOVN_S: 10278 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10279 { 10280 TCGLabel *l1 = gen_new_label(); 10281 TCGv_i32 fp0; 10282 10283 if (ft != 0) { 10284 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10285 fp0 = tcg_temp_new_i32(); 10286 gen_load_fpr32(ctx, fp0, fs); 10287 gen_store_fpr32(ctx, fp0, fd); 10288 tcg_temp_free_i32(fp0); 10289 gen_set_label(l1); 10290 } 10291 } 10292 break; 10293 case OPC_RECIP_S: 10294 { 10295 TCGv_i32 fp0 = tcg_temp_new_i32(); 10296 10297 gen_load_fpr32(ctx, fp0, fs); 10298 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10299 gen_store_fpr32(ctx, fp0, fd); 10300 tcg_temp_free_i32(fp0); 10301 } 10302 break; 10303 case OPC_RSQRT_S: 10304 { 10305 TCGv_i32 fp0 = tcg_temp_new_i32(); 10306 10307 gen_load_fpr32(ctx, fp0, fs); 10308 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10309 gen_store_fpr32(ctx, fp0, fd); 10310 tcg_temp_free_i32(fp0); 10311 } 10312 break; 10313 case OPC_MADDF_S: 10314 check_insn(ctx, ISA_MIPS_R6); 10315 { 10316 TCGv_i32 fp0 = tcg_temp_new_i32(); 10317 TCGv_i32 fp1 = tcg_temp_new_i32(); 10318 TCGv_i32 fp2 = tcg_temp_new_i32(); 10319 gen_load_fpr32(ctx, fp0, fs); 10320 gen_load_fpr32(ctx, fp1, ft); 10321 gen_load_fpr32(ctx, fp2, fd); 10322 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10323 gen_store_fpr32(ctx, fp2, fd); 10324 tcg_temp_free_i32(fp2); 10325 tcg_temp_free_i32(fp1); 10326 tcg_temp_free_i32(fp0); 10327 } 10328 break; 10329 case OPC_MSUBF_S: 10330 check_insn(ctx, ISA_MIPS_R6); 10331 { 10332 TCGv_i32 fp0 = tcg_temp_new_i32(); 10333 TCGv_i32 fp1 = tcg_temp_new_i32(); 10334 TCGv_i32 fp2 = tcg_temp_new_i32(); 10335 gen_load_fpr32(ctx, fp0, fs); 10336 gen_load_fpr32(ctx, fp1, ft); 10337 gen_load_fpr32(ctx, fp2, fd); 10338 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10339 gen_store_fpr32(ctx, fp2, fd); 10340 tcg_temp_free_i32(fp2); 10341 tcg_temp_free_i32(fp1); 10342 tcg_temp_free_i32(fp0); 10343 } 10344 break; 10345 case OPC_RINT_S: 10346 check_insn(ctx, ISA_MIPS_R6); 10347 { 10348 TCGv_i32 fp0 = tcg_temp_new_i32(); 10349 gen_load_fpr32(ctx, fp0, fs); 10350 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10351 gen_store_fpr32(ctx, fp0, fd); 10352 tcg_temp_free_i32(fp0); 10353 } 10354 break; 10355 case OPC_CLASS_S: 10356 check_insn(ctx, ISA_MIPS_R6); 10357 { 10358 TCGv_i32 fp0 = tcg_temp_new_i32(); 10359 gen_load_fpr32(ctx, fp0, fs); 10360 gen_helper_float_class_s(fp0, cpu_env, fp0); 10361 gen_store_fpr32(ctx, fp0, fd); 10362 tcg_temp_free_i32(fp0); 10363 } 10364 break; 10365 case OPC_MIN_S: /* OPC_RECIP2_S */ 10366 if (ctx->insn_flags & ISA_MIPS_R6) { 10367 /* OPC_MIN_S */ 10368 TCGv_i32 fp0 = tcg_temp_new_i32(); 10369 TCGv_i32 fp1 = tcg_temp_new_i32(); 10370 TCGv_i32 fp2 = tcg_temp_new_i32(); 10371 gen_load_fpr32(ctx, fp0, fs); 10372 gen_load_fpr32(ctx, fp1, ft); 10373 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10374 gen_store_fpr32(ctx, fp2, fd); 10375 tcg_temp_free_i32(fp2); 10376 tcg_temp_free_i32(fp1); 10377 tcg_temp_free_i32(fp0); 10378 } else { 10379 /* OPC_RECIP2_S */ 10380 check_cp1_64bitmode(ctx); 10381 { 10382 TCGv_i32 fp0 = tcg_temp_new_i32(); 10383 TCGv_i32 fp1 = tcg_temp_new_i32(); 10384 10385 gen_load_fpr32(ctx, fp0, fs); 10386 gen_load_fpr32(ctx, fp1, ft); 10387 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10388 tcg_temp_free_i32(fp1); 10389 gen_store_fpr32(ctx, fp0, fd); 10390 tcg_temp_free_i32(fp0); 10391 } 10392 } 10393 break; 10394 case OPC_MINA_S: /* OPC_RECIP1_S */ 10395 if (ctx->insn_flags & ISA_MIPS_R6) { 10396 /* OPC_MINA_S */ 10397 TCGv_i32 fp0 = tcg_temp_new_i32(); 10398 TCGv_i32 fp1 = tcg_temp_new_i32(); 10399 TCGv_i32 fp2 = tcg_temp_new_i32(); 10400 gen_load_fpr32(ctx, fp0, fs); 10401 gen_load_fpr32(ctx, fp1, ft); 10402 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10403 gen_store_fpr32(ctx, fp2, fd); 10404 tcg_temp_free_i32(fp2); 10405 tcg_temp_free_i32(fp1); 10406 tcg_temp_free_i32(fp0); 10407 } else { 10408 /* OPC_RECIP1_S */ 10409 check_cp1_64bitmode(ctx); 10410 { 10411 TCGv_i32 fp0 = tcg_temp_new_i32(); 10412 10413 gen_load_fpr32(ctx, fp0, fs); 10414 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10415 gen_store_fpr32(ctx, fp0, fd); 10416 tcg_temp_free_i32(fp0); 10417 } 10418 } 10419 break; 10420 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10421 if (ctx->insn_flags & ISA_MIPS_R6) { 10422 /* OPC_MAX_S */ 10423 TCGv_i32 fp0 = tcg_temp_new_i32(); 10424 TCGv_i32 fp1 = tcg_temp_new_i32(); 10425 gen_load_fpr32(ctx, fp0, fs); 10426 gen_load_fpr32(ctx, fp1, ft); 10427 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10428 gen_store_fpr32(ctx, fp1, fd); 10429 tcg_temp_free_i32(fp1); 10430 tcg_temp_free_i32(fp0); 10431 } else { 10432 /* OPC_RSQRT1_S */ 10433 check_cp1_64bitmode(ctx); 10434 { 10435 TCGv_i32 fp0 = tcg_temp_new_i32(); 10436 10437 gen_load_fpr32(ctx, fp0, fs); 10438 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10439 gen_store_fpr32(ctx, fp0, fd); 10440 tcg_temp_free_i32(fp0); 10441 } 10442 } 10443 break; 10444 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10445 if (ctx->insn_flags & ISA_MIPS_R6) { 10446 /* OPC_MAXA_S */ 10447 TCGv_i32 fp0 = tcg_temp_new_i32(); 10448 TCGv_i32 fp1 = tcg_temp_new_i32(); 10449 gen_load_fpr32(ctx, fp0, fs); 10450 gen_load_fpr32(ctx, fp1, ft); 10451 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10452 gen_store_fpr32(ctx, fp1, fd); 10453 tcg_temp_free_i32(fp1); 10454 tcg_temp_free_i32(fp0); 10455 } else { 10456 /* OPC_RSQRT2_S */ 10457 check_cp1_64bitmode(ctx); 10458 { 10459 TCGv_i32 fp0 = tcg_temp_new_i32(); 10460 TCGv_i32 fp1 = tcg_temp_new_i32(); 10461 10462 gen_load_fpr32(ctx, fp0, fs); 10463 gen_load_fpr32(ctx, fp1, ft); 10464 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10465 tcg_temp_free_i32(fp1); 10466 gen_store_fpr32(ctx, fp0, fd); 10467 tcg_temp_free_i32(fp0); 10468 } 10469 } 10470 break; 10471 case OPC_CVT_D_S: 10472 check_cp1_registers(ctx, fd); 10473 { 10474 TCGv_i32 fp32 = tcg_temp_new_i32(); 10475 TCGv_i64 fp64 = tcg_temp_new_i64(); 10476 10477 gen_load_fpr32(ctx, fp32, fs); 10478 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10479 tcg_temp_free_i32(fp32); 10480 gen_store_fpr64(ctx, fp64, fd); 10481 tcg_temp_free_i64(fp64); 10482 } 10483 break; 10484 case OPC_CVT_W_S: 10485 { 10486 TCGv_i32 fp0 = tcg_temp_new_i32(); 10487 10488 gen_load_fpr32(ctx, fp0, fs); 10489 if (ctx->nan2008) { 10490 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10491 } else { 10492 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10493 } 10494 gen_store_fpr32(ctx, fp0, fd); 10495 tcg_temp_free_i32(fp0); 10496 } 10497 break; 10498 case OPC_CVT_L_S: 10499 check_cp1_64bitmode(ctx); 10500 { 10501 TCGv_i32 fp32 = tcg_temp_new_i32(); 10502 TCGv_i64 fp64 = tcg_temp_new_i64(); 10503 10504 gen_load_fpr32(ctx, fp32, fs); 10505 if (ctx->nan2008) { 10506 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10507 } else { 10508 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10509 } 10510 tcg_temp_free_i32(fp32); 10511 gen_store_fpr64(ctx, fp64, fd); 10512 tcg_temp_free_i64(fp64); 10513 } 10514 break; 10515 case OPC_CVT_PS_S: 10516 check_ps(ctx); 10517 { 10518 TCGv_i64 fp64 = tcg_temp_new_i64(); 10519 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10520 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10521 10522 gen_load_fpr32(ctx, fp32_0, fs); 10523 gen_load_fpr32(ctx, fp32_1, ft); 10524 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10525 tcg_temp_free_i32(fp32_1); 10526 tcg_temp_free_i32(fp32_0); 10527 gen_store_fpr64(ctx, fp64, fd); 10528 tcg_temp_free_i64(fp64); 10529 } 10530 break; 10531 case OPC_CMP_F_S: 10532 case OPC_CMP_UN_S: 10533 case OPC_CMP_EQ_S: 10534 case OPC_CMP_UEQ_S: 10535 case OPC_CMP_OLT_S: 10536 case OPC_CMP_ULT_S: 10537 case OPC_CMP_OLE_S: 10538 case OPC_CMP_ULE_S: 10539 case OPC_CMP_SF_S: 10540 case OPC_CMP_NGLE_S: 10541 case OPC_CMP_SEQ_S: 10542 case OPC_CMP_NGL_S: 10543 case OPC_CMP_LT_S: 10544 case OPC_CMP_NGE_S: 10545 case OPC_CMP_LE_S: 10546 case OPC_CMP_NGT_S: 10547 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10548 if (ctx->opcode & (1 << 6)) { 10549 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10550 } else { 10551 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10552 } 10553 break; 10554 case OPC_ADD_D: 10555 check_cp1_registers(ctx, fs | ft | fd); 10556 { 10557 TCGv_i64 fp0 = tcg_temp_new_i64(); 10558 TCGv_i64 fp1 = tcg_temp_new_i64(); 10559 10560 gen_load_fpr64(ctx, fp0, fs); 10561 gen_load_fpr64(ctx, fp1, ft); 10562 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10563 tcg_temp_free_i64(fp1); 10564 gen_store_fpr64(ctx, fp0, fd); 10565 tcg_temp_free_i64(fp0); 10566 } 10567 break; 10568 case OPC_SUB_D: 10569 check_cp1_registers(ctx, fs | ft | fd); 10570 { 10571 TCGv_i64 fp0 = tcg_temp_new_i64(); 10572 TCGv_i64 fp1 = tcg_temp_new_i64(); 10573 10574 gen_load_fpr64(ctx, fp0, fs); 10575 gen_load_fpr64(ctx, fp1, ft); 10576 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10577 tcg_temp_free_i64(fp1); 10578 gen_store_fpr64(ctx, fp0, fd); 10579 tcg_temp_free_i64(fp0); 10580 } 10581 break; 10582 case OPC_MUL_D: 10583 check_cp1_registers(ctx, fs | ft | fd); 10584 { 10585 TCGv_i64 fp0 = tcg_temp_new_i64(); 10586 TCGv_i64 fp1 = tcg_temp_new_i64(); 10587 10588 gen_load_fpr64(ctx, fp0, fs); 10589 gen_load_fpr64(ctx, fp1, ft); 10590 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10591 tcg_temp_free_i64(fp1); 10592 gen_store_fpr64(ctx, fp0, fd); 10593 tcg_temp_free_i64(fp0); 10594 } 10595 break; 10596 case OPC_DIV_D: 10597 check_cp1_registers(ctx, fs | ft | fd); 10598 { 10599 TCGv_i64 fp0 = tcg_temp_new_i64(); 10600 TCGv_i64 fp1 = tcg_temp_new_i64(); 10601 10602 gen_load_fpr64(ctx, fp0, fs); 10603 gen_load_fpr64(ctx, fp1, ft); 10604 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10605 tcg_temp_free_i64(fp1); 10606 gen_store_fpr64(ctx, fp0, fd); 10607 tcg_temp_free_i64(fp0); 10608 } 10609 break; 10610 case OPC_SQRT_D: 10611 check_cp1_registers(ctx, fs | fd); 10612 { 10613 TCGv_i64 fp0 = tcg_temp_new_i64(); 10614 10615 gen_load_fpr64(ctx, fp0, fs); 10616 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10617 gen_store_fpr64(ctx, fp0, fd); 10618 tcg_temp_free_i64(fp0); 10619 } 10620 break; 10621 case OPC_ABS_D: 10622 check_cp1_registers(ctx, fs | fd); 10623 { 10624 TCGv_i64 fp0 = tcg_temp_new_i64(); 10625 10626 gen_load_fpr64(ctx, fp0, fs); 10627 if (ctx->abs2008) { 10628 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10629 } else { 10630 gen_helper_float_abs_d(fp0, fp0); 10631 } 10632 gen_store_fpr64(ctx, fp0, fd); 10633 tcg_temp_free_i64(fp0); 10634 } 10635 break; 10636 case OPC_MOV_D: 10637 check_cp1_registers(ctx, fs | fd); 10638 { 10639 TCGv_i64 fp0 = tcg_temp_new_i64(); 10640 10641 gen_load_fpr64(ctx, fp0, fs); 10642 gen_store_fpr64(ctx, fp0, fd); 10643 tcg_temp_free_i64(fp0); 10644 } 10645 break; 10646 case OPC_NEG_D: 10647 check_cp1_registers(ctx, fs | fd); 10648 { 10649 TCGv_i64 fp0 = tcg_temp_new_i64(); 10650 10651 gen_load_fpr64(ctx, fp0, fs); 10652 if (ctx->abs2008) { 10653 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10654 } else { 10655 gen_helper_float_chs_d(fp0, fp0); 10656 } 10657 gen_store_fpr64(ctx, fp0, fd); 10658 tcg_temp_free_i64(fp0); 10659 } 10660 break; 10661 case OPC_ROUND_L_D: 10662 check_cp1_64bitmode(ctx); 10663 { 10664 TCGv_i64 fp0 = tcg_temp_new_i64(); 10665 10666 gen_load_fpr64(ctx, fp0, fs); 10667 if (ctx->nan2008) { 10668 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10669 } else { 10670 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10671 } 10672 gen_store_fpr64(ctx, fp0, fd); 10673 tcg_temp_free_i64(fp0); 10674 } 10675 break; 10676 case OPC_TRUNC_L_D: 10677 check_cp1_64bitmode(ctx); 10678 { 10679 TCGv_i64 fp0 = tcg_temp_new_i64(); 10680 10681 gen_load_fpr64(ctx, fp0, fs); 10682 if (ctx->nan2008) { 10683 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10684 } else { 10685 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10686 } 10687 gen_store_fpr64(ctx, fp0, fd); 10688 tcg_temp_free_i64(fp0); 10689 } 10690 break; 10691 case OPC_CEIL_L_D: 10692 check_cp1_64bitmode(ctx); 10693 { 10694 TCGv_i64 fp0 = tcg_temp_new_i64(); 10695 10696 gen_load_fpr64(ctx, fp0, fs); 10697 if (ctx->nan2008) { 10698 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10699 } else { 10700 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10701 } 10702 gen_store_fpr64(ctx, fp0, fd); 10703 tcg_temp_free_i64(fp0); 10704 } 10705 break; 10706 case OPC_FLOOR_L_D: 10707 check_cp1_64bitmode(ctx); 10708 { 10709 TCGv_i64 fp0 = tcg_temp_new_i64(); 10710 10711 gen_load_fpr64(ctx, fp0, fs); 10712 if (ctx->nan2008) { 10713 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10714 } else { 10715 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10716 } 10717 gen_store_fpr64(ctx, fp0, fd); 10718 tcg_temp_free_i64(fp0); 10719 } 10720 break; 10721 case OPC_ROUND_W_D: 10722 check_cp1_registers(ctx, fs); 10723 { 10724 TCGv_i32 fp32 = tcg_temp_new_i32(); 10725 TCGv_i64 fp64 = tcg_temp_new_i64(); 10726 10727 gen_load_fpr64(ctx, fp64, fs); 10728 if (ctx->nan2008) { 10729 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10730 } else { 10731 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10732 } 10733 tcg_temp_free_i64(fp64); 10734 gen_store_fpr32(ctx, fp32, fd); 10735 tcg_temp_free_i32(fp32); 10736 } 10737 break; 10738 case OPC_TRUNC_W_D: 10739 check_cp1_registers(ctx, fs); 10740 { 10741 TCGv_i32 fp32 = tcg_temp_new_i32(); 10742 TCGv_i64 fp64 = tcg_temp_new_i64(); 10743 10744 gen_load_fpr64(ctx, fp64, fs); 10745 if (ctx->nan2008) { 10746 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10747 } else { 10748 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10749 } 10750 tcg_temp_free_i64(fp64); 10751 gen_store_fpr32(ctx, fp32, fd); 10752 tcg_temp_free_i32(fp32); 10753 } 10754 break; 10755 case OPC_CEIL_W_D: 10756 check_cp1_registers(ctx, fs); 10757 { 10758 TCGv_i32 fp32 = tcg_temp_new_i32(); 10759 TCGv_i64 fp64 = tcg_temp_new_i64(); 10760 10761 gen_load_fpr64(ctx, fp64, fs); 10762 if (ctx->nan2008) { 10763 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10764 } else { 10765 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10766 } 10767 tcg_temp_free_i64(fp64); 10768 gen_store_fpr32(ctx, fp32, fd); 10769 tcg_temp_free_i32(fp32); 10770 } 10771 break; 10772 case OPC_FLOOR_W_D: 10773 check_cp1_registers(ctx, fs); 10774 { 10775 TCGv_i32 fp32 = tcg_temp_new_i32(); 10776 TCGv_i64 fp64 = tcg_temp_new_i64(); 10777 10778 gen_load_fpr64(ctx, fp64, fs); 10779 if (ctx->nan2008) { 10780 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10781 } else { 10782 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10783 } 10784 tcg_temp_free_i64(fp64); 10785 gen_store_fpr32(ctx, fp32, fd); 10786 tcg_temp_free_i32(fp32); 10787 } 10788 break; 10789 case OPC_SEL_D: 10790 check_insn(ctx, ISA_MIPS_R6); 10791 gen_sel_d(ctx, op1, fd, ft, fs); 10792 break; 10793 case OPC_SELEQZ_D: 10794 check_insn(ctx, ISA_MIPS_R6); 10795 gen_sel_d(ctx, op1, fd, ft, fs); 10796 break; 10797 case OPC_SELNEZ_D: 10798 check_insn(ctx, ISA_MIPS_R6); 10799 gen_sel_d(ctx, op1, fd, ft, fs); 10800 break; 10801 case OPC_MOVCF_D: 10802 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10803 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10804 break; 10805 case OPC_MOVZ_D: 10806 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10807 { 10808 TCGLabel *l1 = gen_new_label(); 10809 TCGv_i64 fp0; 10810 10811 if (ft != 0) { 10812 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10813 } 10814 fp0 = tcg_temp_new_i64(); 10815 gen_load_fpr64(ctx, fp0, fs); 10816 gen_store_fpr64(ctx, fp0, fd); 10817 tcg_temp_free_i64(fp0); 10818 gen_set_label(l1); 10819 } 10820 break; 10821 case OPC_MOVN_D: 10822 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10823 { 10824 TCGLabel *l1 = gen_new_label(); 10825 TCGv_i64 fp0; 10826 10827 if (ft != 0) { 10828 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10829 fp0 = tcg_temp_new_i64(); 10830 gen_load_fpr64(ctx, fp0, fs); 10831 gen_store_fpr64(ctx, fp0, fd); 10832 tcg_temp_free_i64(fp0); 10833 gen_set_label(l1); 10834 } 10835 } 10836 break; 10837 case OPC_RECIP_D: 10838 check_cp1_registers(ctx, fs | fd); 10839 { 10840 TCGv_i64 fp0 = tcg_temp_new_i64(); 10841 10842 gen_load_fpr64(ctx, fp0, fs); 10843 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10844 gen_store_fpr64(ctx, fp0, fd); 10845 tcg_temp_free_i64(fp0); 10846 } 10847 break; 10848 case OPC_RSQRT_D: 10849 check_cp1_registers(ctx, fs | fd); 10850 { 10851 TCGv_i64 fp0 = tcg_temp_new_i64(); 10852 10853 gen_load_fpr64(ctx, fp0, fs); 10854 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10855 gen_store_fpr64(ctx, fp0, fd); 10856 tcg_temp_free_i64(fp0); 10857 } 10858 break; 10859 case OPC_MADDF_D: 10860 check_insn(ctx, ISA_MIPS_R6); 10861 { 10862 TCGv_i64 fp0 = tcg_temp_new_i64(); 10863 TCGv_i64 fp1 = tcg_temp_new_i64(); 10864 TCGv_i64 fp2 = tcg_temp_new_i64(); 10865 gen_load_fpr64(ctx, fp0, fs); 10866 gen_load_fpr64(ctx, fp1, ft); 10867 gen_load_fpr64(ctx, fp2, fd); 10868 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10869 gen_store_fpr64(ctx, fp2, fd); 10870 tcg_temp_free_i64(fp2); 10871 tcg_temp_free_i64(fp1); 10872 tcg_temp_free_i64(fp0); 10873 } 10874 break; 10875 case OPC_MSUBF_D: 10876 check_insn(ctx, ISA_MIPS_R6); 10877 { 10878 TCGv_i64 fp0 = tcg_temp_new_i64(); 10879 TCGv_i64 fp1 = tcg_temp_new_i64(); 10880 TCGv_i64 fp2 = tcg_temp_new_i64(); 10881 gen_load_fpr64(ctx, fp0, fs); 10882 gen_load_fpr64(ctx, fp1, ft); 10883 gen_load_fpr64(ctx, fp2, fd); 10884 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10885 gen_store_fpr64(ctx, fp2, fd); 10886 tcg_temp_free_i64(fp2); 10887 tcg_temp_free_i64(fp1); 10888 tcg_temp_free_i64(fp0); 10889 } 10890 break; 10891 case OPC_RINT_D: 10892 check_insn(ctx, ISA_MIPS_R6); 10893 { 10894 TCGv_i64 fp0 = tcg_temp_new_i64(); 10895 gen_load_fpr64(ctx, fp0, fs); 10896 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10897 gen_store_fpr64(ctx, fp0, fd); 10898 tcg_temp_free_i64(fp0); 10899 } 10900 break; 10901 case OPC_CLASS_D: 10902 check_insn(ctx, ISA_MIPS_R6); 10903 { 10904 TCGv_i64 fp0 = tcg_temp_new_i64(); 10905 gen_load_fpr64(ctx, fp0, fs); 10906 gen_helper_float_class_d(fp0, cpu_env, fp0); 10907 gen_store_fpr64(ctx, fp0, fd); 10908 tcg_temp_free_i64(fp0); 10909 } 10910 break; 10911 case OPC_MIN_D: /* OPC_RECIP2_D */ 10912 if (ctx->insn_flags & ISA_MIPS_R6) { 10913 /* OPC_MIN_D */ 10914 TCGv_i64 fp0 = tcg_temp_new_i64(); 10915 TCGv_i64 fp1 = tcg_temp_new_i64(); 10916 gen_load_fpr64(ctx, fp0, fs); 10917 gen_load_fpr64(ctx, fp1, ft); 10918 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10919 gen_store_fpr64(ctx, fp1, fd); 10920 tcg_temp_free_i64(fp1); 10921 tcg_temp_free_i64(fp0); 10922 } else { 10923 /* OPC_RECIP2_D */ 10924 check_cp1_64bitmode(ctx); 10925 { 10926 TCGv_i64 fp0 = tcg_temp_new_i64(); 10927 TCGv_i64 fp1 = tcg_temp_new_i64(); 10928 10929 gen_load_fpr64(ctx, fp0, fs); 10930 gen_load_fpr64(ctx, fp1, ft); 10931 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10932 tcg_temp_free_i64(fp1); 10933 gen_store_fpr64(ctx, fp0, fd); 10934 tcg_temp_free_i64(fp0); 10935 } 10936 } 10937 break; 10938 case OPC_MINA_D: /* OPC_RECIP1_D */ 10939 if (ctx->insn_flags & ISA_MIPS_R6) { 10940 /* OPC_MINA_D */ 10941 TCGv_i64 fp0 = tcg_temp_new_i64(); 10942 TCGv_i64 fp1 = tcg_temp_new_i64(); 10943 gen_load_fpr64(ctx, fp0, fs); 10944 gen_load_fpr64(ctx, fp1, ft); 10945 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10946 gen_store_fpr64(ctx, fp1, fd); 10947 tcg_temp_free_i64(fp1); 10948 tcg_temp_free_i64(fp0); 10949 } else { 10950 /* OPC_RECIP1_D */ 10951 check_cp1_64bitmode(ctx); 10952 { 10953 TCGv_i64 fp0 = tcg_temp_new_i64(); 10954 10955 gen_load_fpr64(ctx, fp0, fs); 10956 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10957 gen_store_fpr64(ctx, fp0, fd); 10958 tcg_temp_free_i64(fp0); 10959 } 10960 } 10961 break; 10962 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10963 if (ctx->insn_flags & ISA_MIPS_R6) { 10964 /* OPC_MAX_D */ 10965 TCGv_i64 fp0 = tcg_temp_new_i64(); 10966 TCGv_i64 fp1 = tcg_temp_new_i64(); 10967 gen_load_fpr64(ctx, fp0, fs); 10968 gen_load_fpr64(ctx, fp1, ft); 10969 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10970 gen_store_fpr64(ctx, fp1, fd); 10971 tcg_temp_free_i64(fp1); 10972 tcg_temp_free_i64(fp0); 10973 } else { 10974 /* OPC_RSQRT1_D */ 10975 check_cp1_64bitmode(ctx); 10976 { 10977 TCGv_i64 fp0 = tcg_temp_new_i64(); 10978 10979 gen_load_fpr64(ctx, fp0, fs); 10980 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10981 gen_store_fpr64(ctx, fp0, fd); 10982 tcg_temp_free_i64(fp0); 10983 } 10984 } 10985 break; 10986 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10987 if (ctx->insn_flags & ISA_MIPS_R6) { 10988 /* OPC_MAXA_D */ 10989 TCGv_i64 fp0 = tcg_temp_new_i64(); 10990 TCGv_i64 fp1 = tcg_temp_new_i64(); 10991 gen_load_fpr64(ctx, fp0, fs); 10992 gen_load_fpr64(ctx, fp1, ft); 10993 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 10994 gen_store_fpr64(ctx, fp1, fd); 10995 tcg_temp_free_i64(fp1); 10996 tcg_temp_free_i64(fp0); 10997 } else { 10998 /* OPC_RSQRT2_D */ 10999 check_cp1_64bitmode(ctx); 11000 { 11001 TCGv_i64 fp0 = tcg_temp_new_i64(); 11002 TCGv_i64 fp1 = tcg_temp_new_i64(); 11003 11004 gen_load_fpr64(ctx, fp0, fs); 11005 gen_load_fpr64(ctx, fp1, ft); 11006 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 11007 tcg_temp_free_i64(fp1); 11008 gen_store_fpr64(ctx, fp0, fd); 11009 tcg_temp_free_i64(fp0); 11010 } 11011 } 11012 break; 11013 case OPC_CMP_F_D: 11014 case OPC_CMP_UN_D: 11015 case OPC_CMP_EQ_D: 11016 case OPC_CMP_UEQ_D: 11017 case OPC_CMP_OLT_D: 11018 case OPC_CMP_ULT_D: 11019 case OPC_CMP_OLE_D: 11020 case OPC_CMP_ULE_D: 11021 case OPC_CMP_SF_D: 11022 case OPC_CMP_NGLE_D: 11023 case OPC_CMP_SEQ_D: 11024 case OPC_CMP_NGL_D: 11025 case OPC_CMP_LT_D: 11026 case OPC_CMP_NGE_D: 11027 case OPC_CMP_LE_D: 11028 case OPC_CMP_NGT_D: 11029 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11030 if (ctx->opcode & (1 << 6)) { 11031 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 11032 } else { 11033 gen_cmp_d(ctx, func - 48, ft, fs, cc); 11034 } 11035 break; 11036 case OPC_CVT_S_D: 11037 check_cp1_registers(ctx, fs); 11038 { 11039 TCGv_i32 fp32 = tcg_temp_new_i32(); 11040 TCGv_i64 fp64 = tcg_temp_new_i64(); 11041 11042 gen_load_fpr64(ctx, fp64, fs); 11043 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 11044 tcg_temp_free_i64(fp64); 11045 gen_store_fpr32(ctx, fp32, fd); 11046 tcg_temp_free_i32(fp32); 11047 } 11048 break; 11049 case OPC_CVT_W_D: 11050 check_cp1_registers(ctx, fs); 11051 { 11052 TCGv_i32 fp32 = tcg_temp_new_i32(); 11053 TCGv_i64 fp64 = tcg_temp_new_i64(); 11054 11055 gen_load_fpr64(ctx, fp64, fs); 11056 if (ctx->nan2008) { 11057 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 11058 } else { 11059 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 11060 } 11061 tcg_temp_free_i64(fp64); 11062 gen_store_fpr32(ctx, fp32, fd); 11063 tcg_temp_free_i32(fp32); 11064 } 11065 break; 11066 case OPC_CVT_L_D: 11067 check_cp1_64bitmode(ctx); 11068 { 11069 TCGv_i64 fp0 = tcg_temp_new_i64(); 11070 11071 gen_load_fpr64(ctx, fp0, fs); 11072 if (ctx->nan2008) { 11073 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 11074 } else { 11075 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 11076 } 11077 gen_store_fpr64(ctx, fp0, fd); 11078 tcg_temp_free_i64(fp0); 11079 } 11080 break; 11081 case OPC_CVT_S_W: 11082 { 11083 TCGv_i32 fp0 = tcg_temp_new_i32(); 11084 11085 gen_load_fpr32(ctx, fp0, fs); 11086 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 11087 gen_store_fpr32(ctx, fp0, fd); 11088 tcg_temp_free_i32(fp0); 11089 } 11090 break; 11091 case OPC_CVT_D_W: 11092 check_cp1_registers(ctx, fd); 11093 { 11094 TCGv_i32 fp32 = tcg_temp_new_i32(); 11095 TCGv_i64 fp64 = tcg_temp_new_i64(); 11096 11097 gen_load_fpr32(ctx, fp32, fs); 11098 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 11099 tcg_temp_free_i32(fp32); 11100 gen_store_fpr64(ctx, fp64, fd); 11101 tcg_temp_free_i64(fp64); 11102 } 11103 break; 11104 case OPC_CVT_S_L: 11105 check_cp1_64bitmode(ctx); 11106 { 11107 TCGv_i32 fp32 = tcg_temp_new_i32(); 11108 TCGv_i64 fp64 = tcg_temp_new_i64(); 11109 11110 gen_load_fpr64(ctx, fp64, fs); 11111 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 11112 tcg_temp_free_i64(fp64); 11113 gen_store_fpr32(ctx, fp32, fd); 11114 tcg_temp_free_i32(fp32); 11115 } 11116 break; 11117 case OPC_CVT_D_L: 11118 check_cp1_64bitmode(ctx); 11119 { 11120 TCGv_i64 fp0 = tcg_temp_new_i64(); 11121 11122 gen_load_fpr64(ctx, fp0, fs); 11123 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11124 gen_store_fpr64(ctx, fp0, fd); 11125 tcg_temp_free_i64(fp0); 11126 } 11127 break; 11128 case OPC_CVT_PS_PW: 11129 check_ps(ctx); 11130 { 11131 TCGv_i64 fp0 = tcg_temp_new_i64(); 11132 11133 gen_load_fpr64(ctx, fp0, fs); 11134 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11135 gen_store_fpr64(ctx, fp0, fd); 11136 tcg_temp_free_i64(fp0); 11137 } 11138 break; 11139 case OPC_ADD_PS: 11140 check_ps(ctx); 11141 { 11142 TCGv_i64 fp0 = tcg_temp_new_i64(); 11143 TCGv_i64 fp1 = tcg_temp_new_i64(); 11144 11145 gen_load_fpr64(ctx, fp0, fs); 11146 gen_load_fpr64(ctx, fp1, ft); 11147 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11148 tcg_temp_free_i64(fp1); 11149 gen_store_fpr64(ctx, fp0, fd); 11150 tcg_temp_free_i64(fp0); 11151 } 11152 break; 11153 case OPC_SUB_PS: 11154 check_ps(ctx); 11155 { 11156 TCGv_i64 fp0 = tcg_temp_new_i64(); 11157 TCGv_i64 fp1 = tcg_temp_new_i64(); 11158 11159 gen_load_fpr64(ctx, fp0, fs); 11160 gen_load_fpr64(ctx, fp1, ft); 11161 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11162 tcg_temp_free_i64(fp1); 11163 gen_store_fpr64(ctx, fp0, fd); 11164 tcg_temp_free_i64(fp0); 11165 } 11166 break; 11167 case OPC_MUL_PS: 11168 check_ps(ctx); 11169 { 11170 TCGv_i64 fp0 = tcg_temp_new_i64(); 11171 TCGv_i64 fp1 = tcg_temp_new_i64(); 11172 11173 gen_load_fpr64(ctx, fp0, fs); 11174 gen_load_fpr64(ctx, fp1, ft); 11175 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11176 tcg_temp_free_i64(fp1); 11177 gen_store_fpr64(ctx, fp0, fd); 11178 tcg_temp_free_i64(fp0); 11179 } 11180 break; 11181 case OPC_ABS_PS: 11182 check_ps(ctx); 11183 { 11184 TCGv_i64 fp0 = tcg_temp_new_i64(); 11185 11186 gen_load_fpr64(ctx, fp0, fs); 11187 gen_helper_float_abs_ps(fp0, fp0); 11188 gen_store_fpr64(ctx, fp0, fd); 11189 tcg_temp_free_i64(fp0); 11190 } 11191 break; 11192 case OPC_MOV_PS: 11193 check_ps(ctx); 11194 { 11195 TCGv_i64 fp0 = tcg_temp_new_i64(); 11196 11197 gen_load_fpr64(ctx, fp0, fs); 11198 gen_store_fpr64(ctx, fp0, fd); 11199 tcg_temp_free_i64(fp0); 11200 } 11201 break; 11202 case OPC_NEG_PS: 11203 check_ps(ctx); 11204 { 11205 TCGv_i64 fp0 = tcg_temp_new_i64(); 11206 11207 gen_load_fpr64(ctx, fp0, fs); 11208 gen_helper_float_chs_ps(fp0, fp0); 11209 gen_store_fpr64(ctx, fp0, fd); 11210 tcg_temp_free_i64(fp0); 11211 } 11212 break; 11213 case OPC_MOVCF_PS: 11214 check_ps(ctx); 11215 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11216 break; 11217 case OPC_MOVZ_PS: 11218 check_ps(ctx); 11219 { 11220 TCGLabel *l1 = gen_new_label(); 11221 TCGv_i64 fp0; 11222 11223 if (ft != 0) { 11224 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11225 } 11226 fp0 = tcg_temp_new_i64(); 11227 gen_load_fpr64(ctx, fp0, fs); 11228 gen_store_fpr64(ctx, fp0, fd); 11229 tcg_temp_free_i64(fp0); 11230 gen_set_label(l1); 11231 } 11232 break; 11233 case OPC_MOVN_PS: 11234 check_ps(ctx); 11235 { 11236 TCGLabel *l1 = gen_new_label(); 11237 TCGv_i64 fp0; 11238 11239 if (ft != 0) { 11240 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11241 fp0 = tcg_temp_new_i64(); 11242 gen_load_fpr64(ctx, fp0, fs); 11243 gen_store_fpr64(ctx, fp0, fd); 11244 tcg_temp_free_i64(fp0); 11245 gen_set_label(l1); 11246 } 11247 } 11248 break; 11249 case OPC_ADDR_PS: 11250 check_ps(ctx); 11251 { 11252 TCGv_i64 fp0 = tcg_temp_new_i64(); 11253 TCGv_i64 fp1 = tcg_temp_new_i64(); 11254 11255 gen_load_fpr64(ctx, fp0, ft); 11256 gen_load_fpr64(ctx, fp1, fs); 11257 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11258 tcg_temp_free_i64(fp1); 11259 gen_store_fpr64(ctx, fp0, fd); 11260 tcg_temp_free_i64(fp0); 11261 } 11262 break; 11263 case OPC_MULR_PS: 11264 check_ps(ctx); 11265 { 11266 TCGv_i64 fp0 = tcg_temp_new_i64(); 11267 TCGv_i64 fp1 = tcg_temp_new_i64(); 11268 11269 gen_load_fpr64(ctx, fp0, ft); 11270 gen_load_fpr64(ctx, fp1, fs); 11271 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11272 tcg_temp_free_i64(fp1); 11273 gen_store_fpr64(ctx, fp0, fd); 11274 tcg_temp_free_i64(fp0); 11275 } 11276 break; 11277 case OPC_RECIP2_PS: 11278 check_ps(ctx); 11279 { 11280 TCGv_i64 fp0 = tcg_temp_new_i64(); 11281 TCGv_i64 fp1 = tcg_temp_new_i64(); 11282 11283 gen_load_fpr64(ctx, fp0, fs); 11284 gen_load_fpr64(ctx, fp1, ft); 11285 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11286 tcg_temp_free_i64(fp1); 11287 gen_store_fpr64(ctx, fp0, fd); 11288 tcg_temp_free_i64(fp0); 11289 } 11290 break; 11291 case OPC_RECIP1_PS: 11292 check_ps(ctx); 11293 { 11294 TCGv_i64 fp0 = tcg_temp_new_i64(); 11295 11296 gen_load_fpr64(ctx, fp0, fs); 11297 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11298 gen_store_fpr64(ctx, fp0, fd); 11299 tcg_temp_free_i64(fp0); 11300 } 11301 break; 11302 case OPC_RSQRT1_PS: 11303 check_ps(ctx); 11304 { 11305 TCGv_i64 fp0 = tcg_temp_new_i64(); 11306 11307 gen_load_fpr64(ctx, fp0, fs); 11308 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11309 gen_store_fpr64(ctx, fp0, fd); 11310 tcg_temp_free_i64(fp0); 11311 } 11312 break; 11313 case OPC_RSQRT2_PS: 11314 check_ps(ctx); 11315 { 11316 TCGv_i64 fp0 = tcg_temp_new_i64(); 11317 TCGv_i64 fp1 = tcg_temp_new_i64(); 11318 11319 gen_load_fpr64(ctx, fp0, fs); 11320 gen_load_fpr64(ctx, fp1, ft); 11321 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11322 tcg_temp_free_i64(fp1); 11323 gen_store_fpr64(ctx, fp0, fd); 11324 tcg_temp_free_i64(fp0); 11325 } 11326 break; 11327 case OPC_CVT_S_PU: 11328 check_cp1_64bitmode(ctx); 11329 { 11330 TCGv_i32 fp0 = tcg_temp_new_i32(); 11331 11332 gen_load_fpr32h(ctx, fp0, fs); 11333 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11334 gen_store_fpr32(ctx, fp0, fd); 11335 tcg_temp_free_i32(fp0); 11336 } 11337 break; 11338 case OPC_CVT_PW_PS: 11339 check_ps(ctx); 11340 { 11341 TCGv_i64 fp0 = tcg_temp_new_i64(); 11342 11343 gen_load_fpr64(ctx, fp0, fs); 11344 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11345 gen_store_fpr64(ctx, fp0, fd); 11346 tcg_temp_free_i64(fp0); 11347 } 11348 break; 11349 case OPC_CVT_S_PL: 11350 check_cp1_64bitmode(ctx); 11351 { 11352 TCGv_i32 fp0 = tcg_temp_new_i32(); 11353 11354 gen_load_fpr32(ctx, fp0, fs); 11355 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11356 gen_store_fpr32(ctx, fp0, fd); 11357 tcg_temp_free_i32(fp0); 11358 } 11359 break; 11360 case OPC_PLL_PS: 11361 check_ps(ctx); 11362 { 11363 TCGv_i32 fp0 = tcg_temp_new_i32(); 11364 TCGv_i32 fp1 = tcg_temp_new_i32(); 11365 11366 gen_load_fpr32(ctx, fp0, fs); 11367 gen_load_fpr32(ctx, fp1, ft); 11368 gen_store_fpr32h(ctx, fp0, fd); 11369 gen_store_fpr32(ctx, fp1, fd); 11370 tcg_temp_free_i32(fp0); 11371 tcg_temp_free_i32(fp1); 11372 } 11373 break; 11374 case OPC_PLU_PS: 11375 check_ps(ctx); 11376 { 11377 TCGv_i32 fp0 = tcg_temp_new_i32(); 11378 TCGv_i32 fp1 = tcg_temp_new_i32(); 11379 11380 gen_load_fpr32(ctx, fp0, fs); 11381 gen_load_fpr32h(ctx, fp1, ft); 11382 gen_store_fpr32(ctx, fp1, fd); 11383 gen_store_fpr32h(ctx, fp0, fd); 11384 tcg_temp_free_i32(fp0); 11385 tcg_temp_free_i32(fp1); 11386 } 11387 break; 11388 case OPC_PUL_PS: 11389 check_ps(ctx); 11390 { 11391 TCGv_i32 fp0 = tcg_temp_new_i32(); 11392 TCGv_i32 fp1 = tcg_temp_new_i32(); 11393 11394 gen_load_fpr32h(ctx, fp0, fs); 11395 gen_load_fpr32(ctx, fp1, ft); 11396 gen_store_fpr32(ctx, fp1, fd); 11397 gen_store_fpr32h(ctx, fp0, fd); 11398 tcg_temp_free_i32(fp0); 11399 tcg_temp_free_i32(fp1); 11400 } 11401 break; 11402 case OPC_PUU_PS: 11403 check_ps(ctx); 11404 { 11405 TCGv_i32 fp0 = tcg_temp_new_i32(); 11406 TCGv_i32 fp1 = tcg_temp_new_i32(); 11407 11408 gen_load_fpr32h(ctx, fp0, fs); 11409 gen_load_fpr32h(ctx, fp1, ft); 11410 gen_store_fpr32(ctx, fp1, fd); 11411 gen_store_fpr32h(ctx, fp0, fd); 11412 tcg_temp_free_i32(fp0); 11413 tcg_temp_free_i32(fp1); 11414 } 11415 break; 11416 case OPC_CMP_F_PS: 11417 case OPC_CMP_UN_PS: 11418 case OPC_CMP_EQ_PS: 11419 case OPC_CMP_UEQ_PS: 11420 case OPC_CMP_OLT_PS: 11421 case OPC_CMP_ULT_PS: 11422 case OPC_CMP_OLE_PS: 11423 case OPC_CMP_ULE_PS: 11424 case OPC_CMP_SF_PS: 11425 case OPC_CMP_NGLE_PS: 11426 case OPC_CMP_SEQ_PS: 11427 case OPC_CMP_NGL_PS: 11428 case OPC_CMP_LT_PS: 11429 case OPC_CMP_NGE_PS: 11430 case OPC_CMP_LE_PS: 11431 case OPC_CMP_NGT_PS: 11432 if (ctx->opcode & (1 << 6)) { 11433 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11434 } else { 11435 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11436 } 11437 break; 11438 default: 11439 MIPS_INVAL("farith"); 11440 gen_reserved_instruction(ctx); 11441 return; 11442 } 11443 } 11444 11445 /* Coprocessor 3 (FPU) */ 11446 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11447 int fd, int fs, int base, int index) 11448 { 11449 TCGv t0 = tcg_temp_new(); 11450 11451 if (base == 0) { 11452 gen_load_gpr(t0, index); 11453 } else if (index == 0) { 11454 gen_load_gpr(t0, base); 11455 } else { 11456 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11457 } 11458 /* 11459 * Don't do NOP if destination is zero: we must perform the actual 11460 * memory access. 11461 */ 11462 switch (opc) { 11463 case OPC_LWXC1: 11464 check_cop1x(ctx); 11465 { 11466 TCGv_i32 fp0 = tcg_temp_new_i32(); 11467 11468 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11469 tcg_gen_trunc_tl_i32(fp0, t0); 11470 gen_store_fpr32(ctx, fp0, fd); 11471 tcg_temp_free_i32(fp0); 11472 } 11473 break; 11474 case OPC_LDXC1: 11475 check_cop1x(ctx); 11476 check_cp1_registers(ctx, fd); 11477 { 11478 TCGv_i64 fp0 = tcg_temp_new_i64(); 11479 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11480 gen_store_fpr64(ctx, fp0, fd); 11481 tcg_temp_free_i64(fp0); 11482 } 11483 break; 11484 case OPC_LUXC1: 11485 check_cp1_64bitmode(ctx); 11486 tcg_gen_andi_tl(t0, t0, ~0x7); 11487 { 11488 TCGv_i64 fp0 = tcg_temp_new_i64(); 11489 11490 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11491 gen_store_fpr64(ctx, fp0, fd); 11492 tcg_temp_free_i64(fp0); 11493 } 11494 break; 11495 case OPC_SWXC1: 11496 check_cop1x(ctx); 11497 { 11498 TCGv_i32 fp0 = tcg_temp_new_i32(); 11499 gen_load_fpr32(ctx, fp0, fs); 11500 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11501 tcg_temp_free_i32(fp0); 11502 } 11503 break; 11504 case OPC_SDXC1: 11505 check_cop1x(ctx); 11506 check_cp1_registers(ctx, fs); 11507 { 11508 TCGv_i64 fp0 = tcg_temp_new_i64(); 11509 gen_load_fpr64(ctx, fp0, fs); 11510 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11511 tcg_temp_free_i64(fp0); 11512 } 11513 break; 11514 case OPC_SUXC1: 11515 check_cp1_64bitmode(ctx); 11516 tcg_gen_andi_tl(t0, t0, ~0x7); 11517 { 11518 TCGv_i64 fp0 = tcg_temp_new_i64(); 11519 gen_load_fpr64(ctx, fp0, fs); 11520 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11521 tcg_temp_free_i64(fp0); 11522 } 11523 break; 11524 } 11525 tcg_temp_free(t0); 11526 } 11527 11528 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11529 int fd, int fr, int fs, int ft) 11530 { 11531 switch (opc) { 11532 case OPC_ALNV_PS: 11533 check_ps(ctx); 11534 { 11535 TCGv t0 = tcg_temp_local_new(); 11536 TCGv_i32 fp = tcg_temp_new_i32(); 11537 TCGv_i32 fph = tcg_temp_new_i32(); 11538 TCGLabel *l1 = gen_new_label(); 11539 TCGLabel *l2 = gen_new_label(); 11540 11541 gen_load_gpr(t0, fr); 11542 tcg_gen_andi_tl(t0, t0, 0x7); 11543 11544 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11545 gen_load_fpr32(ctx, fp, fs); 11546 gen_load_fpr32h(ctx, fph, fs); 11547 gen_store_fpr32(ctx, fp, fd); 11548 gen_store_fpr32h(ctx, fph, fd); 11549 tcg_gen_br(l2); 11550 gen_set_label(l1); 11551 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11552 tcg_temp_free(t0); 11553 #ifdef TARGET_WORDS_BIGENDIAN 11554 gen_load_fpr32(ctx, fp, fs); 11555 gen_load_fpr32h(ctx, fph, ft); 11556 gen_store_fpr32h(ctx, fp, fd); 11557 gen_store_fpr32(ctx, fph, fd); 11558 #else 11559 gen_load_fpr32h(ctx, fph, fs); 11560 gen_load_fpr32(ctx, fp, ft); 11561 gen_store_fpr32(ctx, fph, fd); 11562 gen_store_fpr32h(ctx, fp, fd); 11563 #endif 11564 gen_set_label(l2); 11565 tcg_temp_free_i32(fp); 11566 tcg_temp_free_i32(fph); 11567 } 11568 break; 11569 case OPC_MADD_S: 11570 check_cop1x(ctx); 11571 { 11572 TCGv_i32 fp0 = tcg_temp_new_i32(); 11573 TCGv_i32 fp1 = tcg_temp_new_i32(); 11574 TCGv_i32 fp2 = tcg_temp_new_i32(); 11575 11576 gen_load_fpr32(ctx, fp0, fs); 11577 gen_load_fpr32(ctx, fp1, ft); 11578 gen_load_fpr32(ctx, fp2, fr); 11579 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11580 tcg_temp_free_i32(fp0); 11581 tcg_temp_free_i32(fp1); 11582 gen_store_fpr32(ctx, fp2, fd); 11583 tcg_temp_free_i32(fp2); 11584 } 11585 break; 11586 case OPC_MADD_D: 11587 check_cop1x(ctx); 11588 check_cp1_registers(ctx, fd | fs | ft | fr); 11589 { 11590 TCGv_i64 fp0 = tcg_temp_new_i64(); 11591 TCGv_i64 fp1 = tcg_temp_new_i64(); 11592 TCGv_i64 fp2 = tcg_temp_new_i64(); 11593 11594 gen_load_fpr64(ctx, fp0, fs); 11595 gen_load_fpr64(ctx, fp1, ft); 11596 gen_load_fpr64(ctx, fp2, fr); 11597 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11598 tcg_temp_free_i64(fp0); 11599 tcg_temp_free_i64(fp1); 11600 gen_store_fpr64(ctx, fp2, fd); 11601 tcg_temp_free_i64(fp2); 11602 } 11603 break; 11604 case OPC_MADD_PS: 11605 check_ps(ctx); 11606 { 11607 TCGv_i64 fp0 = tcg_temp_new_i64(); 11608 TCGv_i64 fp1 = tcg_temp_new_i64(); 11609 TCGv_i64 fp2 = tcg_temp_new_i64(); 11610 11611 gen_load_fpr64(ctx, fp0, fs); 11612 gen_load_fpr64(ctx, fp1, ft); 11613 gen_load_fpr64(ctx, fp2, fr); 11614 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11615 tcg_temp_free_i64(fp0); 11616 tcg_temp_free_i64(fp1); 11617 gen_store_fpr64(ctx, fp2, fd); 11618 tcg_temp_free_i64(fp2); 11619 } 11620 break; 11621 case OPC_MSUB_S: 11622 check_cop1x(ctx); 11623 { 11624 TCGv_i32 fp0 = tcg_temp_new_i32(); 11625 TCGv_i32 fp1 = tcg_temp_new_i32(); 11626 TCGv_i32 fp2 = tcg_temp_new_i32(); 11627 11628 gen_load_fpr32(ctx, fp0, fs); 11629 gen_load_fpr32(ctx, fp1, ft); 11630 gen_load_fpr32(ctx, fp2, fr); 11631 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11632 tcg_temp_free_i32(fp0); 11633 tcg_temp_free_i32(fp1); 11634 gen_store_fpr32(ctx, fp2, fd); 11635 tcg_temp_free_i32(fp2); 11636 } 11637 break; 11638 case OPC_MSUB_D: 11639 check_cop1x(ctx); 11640 check_cp1_registers(ctx, fd | fs | ft | fr); 11641 { 11642 TCGv_i64 fp0 = tcg_temp_new_i64(); 11643 TCGv_i64 fp1 = tcg_temp_new_i64(); 11644 TCGv_i64 fp2 = tcg_temp_new_i64(); 11645 11646 gen_load_fpr64(ctx, fp0, fs); 11647 gen_load_fpr64(ctx, fp1, ft); 11648 gen_load_fpr64(ctx, fp2, fr); 11649 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11650 tcg_temp_free_i64(fp0); 11651 tcg_temp_free_i64(fp1); 11652 gen_store_fpr64(ctx, fp2, fd); 11653 tcg_temp_free_i64(fp2); 11654 } 11655 break; 11656 case OPC_MSUB_PS: 11657 check_ps(ctx); 11658 { 11659 TCGv_i64 fp0 = tcg_temp_new_i64(); 11660 TCGv_i64 fp1 = tcg_temp_new_i64(); 11661 TCGv_i64 fp2 = tcg_temp_new_i64(); 11662 11663 gen_load_fpr64(ctx, fp0, fs); 11664 gen_load_fpr64(ctx, fp1, ft); 11665 gen_load_fpr64(ctx, fp2, fr); 11666 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11667 tcg_temp_free_i64(fp0); 11668 tcg_temp_free_i64(fp1); 11669 gen_store_fpr64(ctx, fp2, fd); 11670 tcg_temp_free_i64(fp2); 11671 } 11672 break; 11673 case OPC_NMADD_S: 11674 check_cop1x(ctx); 11675 { 11676 TCGv_i32 fp0 = tcg_temp_new_i32(); 11677 TCGv_i32 fp1 = tcg_temp_new_i32(); 11678 TCGv_i32 fp2 = tcg_temp_new_i32(); 11679 11680 gen_load_fpr32(ctx, fp0, fs); 11681 gen_load_fpr32(ctx, fp1, ft); 11682 gen_load_fpr32(ctx, fp2, fr); 11683 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11684 tcg_temp_free_i32(fp0); 11685 tcg_temp_free_i32(fp1); 11686 gen_store_fpr32(ctx, fp2, fd); 11687 tcg_temp_free_i32(fp2); 11688 } 11689 break; 11690 case OPC_NMADD_D: 11691 check_cop1x(ctx); 11692 check_cp1_registers(ctx, fd | fs | ft | fr); 11693 { 11694 TCGv_i64 fp0 = tcg_temp_new_i64(); 11695 TCGv_i64 fp1 = tcg_temp_new_i64(); 11696 TCGv_i64 fp2 = tcg_temp_new_i64(); 11697 11698 gen_load_fpr64(ctx, fp0, fs); 11699 gen_load_fpr64(ctx, fp1, ft); 11700 gen_load_fpr64(ctx, fp2, fr); 11701 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11702 tcg_temp_free_i64(fp0); 11703 tcg_temp_free_i64(fp1); 11704 gen_store_fpr64(ctx, fp2, fd); 11705 tcg_temp_free_i64(fp2); 11706 } 11707 break; 11708 case OPC_NMADD_PS: 11709 check_ps(ctx); 11710 { 11711 TCGv_i64 fp0 = tcg_temp_new_i64(); 11712 TCGv_i64 fp1 = tcg_temp_new_i64(); 11713 TCGv_i64 fp2 = tcg_temp_new_i64(); 11714 11715 gen_load_fpr64(ctx, fp0, fs); 11716 gen_load_fpr64(ctx, fp1, ft); 11717 gen_load_fpr64(ctx, fp2, fr); 11718 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11719 tcg_temp_free_i64(fp0); 11720 tcg_temp_free_i64(fp1); 11721 gen_store_fpr64(ctx, fp2, fd); 11722 tcg_temp_free_i64(fp2); 11723 } 11724 break; 11725 case OPC_NMSUB_S: 11726 check_cop1x(ctx); 11727 { 11728 TCGv_i32 fp0 = tcg_temp_new_i32(); 11729 TCGv_i32 fp1 = tcg_temp_new_i32(); 11730 TCGv_i32 fp2 = tcg_temp_new_i32(); 11731 11732 gen_load_fpr32(ctx, fp0, fs); 11733 gen_load_fpr32(ctx, fp1, ft); 11734 gen_load_fpr32(ctx, fp2, fr); 11735 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11736 tcg_temp_free_i32(fp0); 11737 tcg_temp_free_i32(fp1); 11738 gen_store_fpr32(ctx, fp2, fd); 11739 tcg_temp_free_i32(fp2); 11740 } 11741 break; 11742 case OPC_NMSUB_D: 11743 check_cop1x(ctx); 11744 check_cp1_registers(ctx, fd | fs | ft | fr); 11745 { 11746 TCGv_i64 fp0 = tcg_temp_new_i64(); 11747 TCGv_i64 fp1 = tcg_temp_new_i64(); 11748 TCGv_i64 fp2 = tcg_temp_new_i64(); 11749 11750 gen_load_fpr64(ctx, fp0, fs); 11751 gen_load_fpr64(ctx, fp1, ft); 11752 gen_load_fpr64(ctx, fp2, fr); 11753 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11754 tcg_temp_free_i64(fp0); 11755 tcg_temp_free_i64(fp1); 11756 gen_store_fpr64(ctx, fp2, fd); 11757 tcg_temp_free_i64(fp2); 11758 } 11759 break; 11760 case OPC_NMSUB_PS: 11761 check_ps(ctx); 11762 { 11763 TCGv_i64 fp0 = tcg_temp_new_i64(); 11764 TCGv_i64 fp1 = tcg_temp_new_i64(); 11765 TCGv_i64 fp2 = tcg_temp_new_i64(); 11766 11767 gen_load_fpr64(ctx, fp0, fs); 11768 gen_load_fpr64(ctx, fp1, ft); 11769 gen_load_fpr64(ctx, fp2, fr); 11770 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11771 tcg_temp_free_i64(fp0); 11772 tcg_temp_free_i64(fp1); 11773 gen_store_fpr64(ctx, fp2, fd); 11774 tcg_temp_free_i64(fp2); 11775 } 11776 break; 11777 default: 11778 MIPS_INVAL("flt3_arith"); 11779 gen_reserved_instruction(ctx); 11780 return; 11781 } 11782 } 11783 11784 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11785 { 11786 TCGv t0; 11787 11788 #if !defined(CONFIG_USER_ONLY) 11789 /* 11790 * The Linux kernel will emulate rdhwr if it's not supported natively. 11791 * Therefore only check the ISA in system mode. 11792 */ 11793 check_insn(ctx, ISA_MIPS_R2); 11794 #endif 11795 t0 = tcg_temp_new(); 11796 11797 switch (rd) { 11798 case 0: 11799 gen_helper_rdhwr_cpunum(t0, cpu_env); 11800 gen_store_gpr(t0, rt); 11801 break; 11802 case 1: 11803 gen_helper_rdhwr_synci_step(t0, cpu_env); 11804 gen_store_gpr(t0, rt); 11805 break; 11806 case 2: 11807 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11808 gen_io_start(); 11809 } 11810 gen_helper_rdhwr_cc(t0, cpu_env); 11811 gen_store_gpr(t0, rt); 11812 /* 11813 * Break the TB to be able to take timer interrupts immediately 11814 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11815 * we break completely out of translated code. 11816 */ 11817 gen_save_pc(ctx->base.pc_next + 4); 11818 ctx->base.is_jmp = DISAS_EXIT; 11819 break; 11820 case 3: 11821 gen_helper_rdhwr_ccres(t0, cpu_env); 11822 gen_store_gpr(t0, rt); 11823 break; 11824 case 4: 11825 check_insn(ctx, ISA_MIPS_R6); 11826 if (sel != 0) { 11827 /* 11828 * Performance counter registers are not implemented other than 11829 * control register 0. 11830 */ 11831 generate_exception(ctx, EXCP_RI); 11832 } 11833 gen_helper_rdhwr_performance(t0, cpu_env); 11834 gen_store_gpr(t0, rt); 11835 break; 11836 case 5: 11837 check_insn(ctx, ISA_MIPS_R6); 11838 gen_helper_rdhwr_xnp(t0, cpu_env); 11839 gen_store_gpr(t0, rt); 11840 break; 11841 case 29: 11842 #if defined(CONFIG_USER_ONLY) 11843 tcg_gen_ld_tl(t0, cpu_env, 11844 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11845 gen_store_gpr(t0, rt); 11846 break; 11847 #else 11848 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11849 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11850 tcg_gen_ld_tl(t0, cpu_env, 11851 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11852 gen_store_gpr(t0, rt); 11853 } else { 11854 gen_reserved_instruction(ctx); 11855 } 11856 break; 11857 #endif 11858 default: /* Invalid */ 11859 MIPS_INVAL("rdhwr"); 11860 gen_reserved_instruction(ctx); 11861 break; 11862 } 11863 tcg_temp_free(t0); 11864 } 11865 11866 static inline void clear_branch_hflags(DisasContext *ctx) 11867 { 11868 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11869 if (ctx->base.is_jmp == DISAS_NEXT) { 11870 save_cpu_state(ctx, 0); 11871 } else { 11872 /* 11873 * It is not safe to save ctx->hflags as hflags may be changed 11874 * in execution time by the instruction in delay / forbidden slot. 11875 */ 11876 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11877 } 11878 } 11879 11880 static void gen_branch(DisasContext *ctx, int insn_bytes) 11881 { 11882 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11883 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11884 /* Branches completion */ 11885 clear_branch_hflags(ctx); 11886 ctx->base.is_jmp = DISAS_NORETURN; 11887 /* FIXME: Need to clear can_do_io. */ 11888 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11889 case MIPS_HFLAG_FBNSLOT: 11890 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11891 break; 11892 case MIPS_HFLAG_B: 11893 /* unconditional branch */ 11894 if (proc_hflags & MIPS_HFLAG_BX) { 11895 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11896 } 11897 gen_goto_tb(ctx, 0, ctx->btarget); 11898 break; 11899 case MIPS_HFLAG_BL: 11900 /* blikely taken case */ 11901 gen_goto_tb(ctx, 0, ctx->btarget); 11902 break; 11903 case MIPS_HFLAG_BC: 11904 /* Conditional branch */ 11905 { 11906 TCGLabel *l1 = gen_new_label(); 11907 11908 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11909 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11910 gen_set_label(l1); 11911 gen_goto_tb(ctx, 0, ctx->btarget); 11912 } 11913 break; 11914 case MIPS_HFLAG_BR: 11915 /* unconditional branch to register */ 11916 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11917 TCGv t0 = tcg_temp_new(); 11918 TCGv_i32 t1 = tcg_temp_new_i32(); 11919 11920 tcg_gen_andi_tl(t0, btarget, 0x1); 11921 tcg_gen_trunc_tl_i32(t1, t0); 11922 tcg_temp_free(t0); 11923 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11924 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11925 tcg_gen_or_i32(hflags, hflags, t1); 11926 tcg_temp_free_i32(t1); 11927 11928 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11929 } else { 11930 tcg_gen_mov_tl(cpu_PC, btarget); 11931 } 11932 if (ctx->base.singlestep_enabled) { 11933 save_cpu_state(ctx, 0); 11934 gen_helper_raise_exception_debug(cpu_env); 11935 } 11936 tcg_gen_lookup_and_goto_ptr(); 11937 break; 11938 default: 11939 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11940 gen_reserved_instruction(ctx); 11941 } 11942 } 11943 } 11944 11945 /* Compact Branches */ 11946 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11947 int rs, int rt, int32_t offset) 11948 { 11949 int bcond_compute = 0; 11950 TCGv t0 = tcg_temp_new(); 11951 TCGv t1 = tcg_temp_new(); 11952 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11953 11954 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11955 #ifdef MIPS_DEBUG_DISAS 11956 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11957 "\n", ctx->base.pc_next); 11958 #endif 11959 gen_reserved_instruction(ctx); 11960 goto out; 11961 } 11962 11963 /* Load needed operands and calculate btarget */ 11964 switch (opc) { 11965 /* compact branch */ 11966 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11967 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11968 gen_load_gpr(t0, rs); 11969 gen_load_gpr(t1, rt); 11970 bcond_compute = 1; 11971 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11972 if (rs <= rt && rs == 0) { 11973 /* OPC_BEQZALC, OPC_BNEZALC */ 11974 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11975 } 11976 break; 11977 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11978 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11979 gen_load_gpr(t0, rs); 11980 gen_load_gpr(t1, rt); 11981 bcond_compute = 1; 11982 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11983 break; 11984 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11985 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11986 if (rs == 0 || rs == rt) { 11987 /* OPC_BLEZALC, OPC_BGEZALC */ 11988 /* OPC_BGTZALC, OPC_BLTZALC */ 11989 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11990 } 11991 gen_load_gpr(t0, rs); 11992 gen_load_gpr(t1, rt); 11993 bcond_compute = 1; 11994 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11995 break; 11996 case OPC_BC: 11997 case OPC_BALC: 11998 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11999 break; 12000 case OPC_BEQZC: 12001 case OPC_BNEZC: 12002 if (rs != 0) { 12003 /* OPC_BEQZC, OPC_BNEZC */ 12004 gen_load_gpr(t0, rs); 12005 bcond_compute = 1; 12006 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12007 } else { 12008 /* OPC_JIC, OPC_JIALC */ 12009 TCGv tbase = tcg_temp_new(); 12010 TCGv toffset = tcg_temp_new(); 12011 12012 gen_load_gpr(tbase, rt); 12013 tcg_gen_movi_tl(toffset, offset); 12014 gen_op_addr_add(ctx, btarget, tbase, toffset); 12015 tcg_temp_free(tbase); 12016 tcg_temp_free(toffset); 12017 } 12018 break; 12019 default: 12020 MIPS_INVAL("Compact branch/jump"); 12021 gen_reserved_instruction(ctx); 12022 goto out; 12023 } 12024 12025 if (bcond_compute == 0) { 12026 /* Unconditional compact branch */ 12027 switch (opc) { 12028 case OPC_JIALC: 12029 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12030 /* Fallthrough */ 12031 case OPC_JIC: 12032 ctx->hflags |= MIPS_HFLAG_BR; 12033 break; 12034 case OPC_BALC: 12035 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12036 /* Fallthrough */ 12037 case OPC_BC: 12038 ctx->hflags |= MIPS_HFLAG_B; 12039 break; 12040 default: 12041 MIPS_INVAL("Compact branch/jump"); 12042 gen_reserved_instruction(ctx); 12043 goto out; 12044 } 12045 12046 /* Generating branch here as compact branches don't have delay slot */ 12047 gen_branch(ctx, 4); 12048 } else { 12049 /* Conditional compact branch */ 12050 TCGLabel *fs = gen_new_label(); 12051 save_cpu_state(ctx, 0); 12052 12053 switch (opc) { 12054 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 12055 if (rs == 0 && rt != 0) { 12056 /* OPC_BLEZALC */ 12057 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12058 } else if (rs != 0 && rt != 0 && rs == rt) { 12059 /* OPC_BGEZALC */ 12060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12061 } else { 12062 /* OPC_BGEUC */ 12063 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 12064 } 12065 break; 12066 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12067 if (rs == 0 && rt != 0) { 12068 /* OPC_BGTZALC */ 12069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12070 } else if (rs != 0 && rt != 0 && rs == rt) { 12071 /* OPC_BLTZALC */ 12072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12073 } else { 12074 /* OPC_BLTUC */ 12075 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 12076 } 12077 break; 12078 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 12079 if (rs == 0 && rt != 0) { 12080 /* OPC_BLEZC */ 12081 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12082 } else if (rs != 0 && rt != 0 && rs == rt) { 12083 /* OPC_BGEZC */ 12084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12085 } else { 12086 /* OPC_BGEC */ 12087 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 12088 } 12089 break; 12090 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 12091 if (rs == 0 && rt != 0) { 12092 /* OPC_BGTZC */ 12093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12094 } else if (rs != 0 && rt != 0 && rs == rt) { 12095 /* OPC_BLTZC */ 12096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12097 } else { 12098 /* OPC_BLTC */ 12099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 12100 } 12101 break; 12102 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 12103 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 12104 if (rs >= rt) { 12105 /* OPC_BOVC, OPC_BNVC */ 12106 TCGv t2 = tcg_temp_new(); 12107 TCGv t3 = tcg_temp_new(); 12108 TCGv t4 = tcg_temp_new(); 12109 TCGv input_overflow = tcg_temp_new(); 12110 12111 gen_load_gpr(t0, rs); 12112 gen_load_gpr(t1, rt); 12113 tcg_gen_ext32s_tl(t2, t0); 12114 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 12115 tcg_gen_ext32s_tl(t3, t1); 12116 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 12117 tcg_gen_or_tl(input_overflow, input_overflow, t4); 12118 12119 tcg_gen_add_tl(t4, t2, t3); 12120 tcg_gen_ext32s_tl(t4, t4); 12121 tcg_gen_xor_tl(t2, t2, t3); 12122 tcg_gen_xor_tl(t3, t4, t3); 12123 tcg_gen_andc_tl(t2, t3, t2); 12124 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 12125 tcg_gen_or_tl(t4, t4, input_overflow); 12126 if (opc == OPC_BOVC) { 12127 /* OPC_BOVC */ 12128 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12129 } else { 12130 /* OPC_BNVC */ 12131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12132 } 12133 tcg_temp_free(input_overflow); 12134 tcg_temp_free(t4); 12135 tcg_temp_free(t3); 12136 tcg_temp_free(t2); 12137 } else if (rs < rt && rs == 0) { 12138 /* OPC_BEQZALC, OPC_BNEZALC */ 12139 if (opc == OPC_BEQZALC) { 12140 /* OPC_BEQZALC */ 12141 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12142 } else { 12143 /* OPC_BNEZALC */ 12144 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12145 } 12146 } else { 12147 /* OPC_BEQC, OPC_BNEC */ 12148 if (opc == OPC_BEQC) { 12149 /* OPC_BEQC */ 12150 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12151 } else { 12152 /* OPC_BNEC */ 12153 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12154 } 12155 } 12156 break; 12157 case OPC_BEQZC: 12158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12159 break; 12160 case OPC_BNEZC: 12161 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12162 break; 12163 default: 12164 MIPS_INVAL("Compact conditional branch/jump"); 12165 gen_reserved_instruction(ctx); 12166 goto out; 12167 } 12168 12169 /* Generating branch here as compact branches don't have delay slot */ 12170 gen_goto_tb(ctx, 1, ctx->btarget); 12171 gen_set_label(fs); 12172 12173 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12174 } 12175 12176 out: 12177 tcg_temp_free(t0); 12178 tcg_temp_free(t1); 12179 } 12180 12181 void gen_addiupc(DisasContext *ctx, int rx, int imm, 12182 int is_64_bit, int extended) 12183 { 12184 TCGv t0; 12185 12186 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12187 gen_reserved_instruction(ctx); 12188 return; 12189 } 12190 12191 t0 = tcg_temp_new(); 12192 12193 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12194 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12195 if (!is_64_bit) { 12196 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12197 } 12198 12199 tcg_temp_free(t0); 12200 } 12201 12202 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12203 int16_t offset) 12204 { 12205 TCGv_i32 t0 = tcg_const_i32(op); 12206 TCGv t1 = tcg_temp_new(); 12207 gen_base_offset_addr(ctx, t1, base, offset); 12208 gen_helper_cache(cpu_env, t1, t0); 12209 tcg_temp_free(t1); 12210 tcg_temp_free_i32(t0); 12211 } 12212 12213 static inline bool is_uhi(int sdbbp_code) 12214 { 12215 #ifdef CONFIG_USER_ONLY 12216 return false; 12217 #else 12218 return semihosting_enabled() && sdbbp_code == 1; 12219 #endif 12220 } 12221 12222 #ifdef CONFIG_USER_ONLY 12223 /* The above should dead-code away any calls to this..*/ 12224 static inline void gen_helper_do_semihosting(void *env) 12225 { 12226 g_assert_not_reached(); 12227 } 12228 #endif 12229 12230 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 12231 { 12232 TCGv t0 = tcg_temp_new(); 12233 TCGv t1 = tcg_temp_new(); 12234 12235 gen_load_gpr(t0, base); 12236 12237 if (index != 0) { 12238 gen_load_gpr(t1, index); 12239 tcg_gen_shli_tl(t1, t1, 2); 12240 gen_op_addr_add(ctx, t0, t1, t0); 12241 } 12242 12243 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 12244 gen_store_gpr(t1, rd); 12245 12246 tcg_temp_free(t0); 12247 tcg_temp_free(t1); 12248 } 12249 12250 static void gen_sync(int stype) 12251 { 12252 TCGBar tcg_mo = TCG_BAR_SC; 12253 12254 switch (stype) { 12255 case 0x4: /* SYNC_WMB */ 12256 tcg_mo |= TCG_MO_ST_ST; 12257 break; 12258 case 0x10: /* SYNC_MB */ 12259 tcg_mo |= TCG_MO_ALL; 12260 break; 12261 case 0x11: /* SYNC_ACQUIRE */ 12262 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 12263 break; 12264 case 0x12: /* SYNC_RELEASE */ 12265 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 12266 break; 12267 case 0x13: /* SYNC_RMB */ 12268 tcg_mo |= TCG_MO_LD_LD; 12269 break; 12270 default: 12271 tcg_mo |= TCG_MO_ALL; 12272 break; 12273 } 12274 12275 tcg_gen_mb(tcg_mo); 12276 } 12277 12278 /* ISA extensions (ASEs) */ 12279 12280 /* MIPS16 extension to MIPS32 */ 12281 #include "mips16e_translate.c.inc" 12282 12283 /* microMIPS extension to MIPS32/MIPS64 */ 12284 12285 /* 12286 * Values for microMIPS fmt field. Variable-width, depending on which 12287 * formats the instruction supports. 12288 */ 12289 enum { 12290 FMT_SD_S = 0, 12291 FMT_SD_D = 1, 12292 12293 FMT_SDPS_S = 0, 12294 FMT_SDPS_D = 1, 12295 FMT_SDPS_PS = 2, 12296 12297 FMT_SWL_S = 0, 12298 FMT_SWL_W = 1, 12299 FMT_SWL_L = 2, 12300 12301 FMT_DWL_D = 0, 12302 FMT_DWL_W = 1, 12303 FMT_DWL_L = 2 12304 }; 12305 12306 #include "micromips_translate.c.inc" 12307 12308 #include "nanomips_translate.c.inc" 12309 12310 /* MIPSDSP functions. */ 12311 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, 12312 int rd, int base, int offset) 12313 { 12314 TCGv t0; 12315 12316 check_dsp(ctx); 12317 t0 = tcg_temp_new(); 12318 12319 if (base == 0) { 12320 gen_load_gpr(t0, offset); 12321 } else if (offset == 0) { 12322 gen_load_gpr(t0, base); 12323 } else { 12324 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 12325 } 12326 12327 switch (opc) { 12328 case OPC_LBUX: 12329 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 12330 gen_store_gpr(t0, rd); 12331 break; 12332 case OPC_LHX: 12333 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 12334 gen_store_gpr(t0, rd); 12335 break; 12336 case OPC_LWX: 12337 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 12338 gen_store_gpr(t0, rd); 12339 break; 12340 #if defined(TARGET_MIPS64) 12341 case OPC_LDX: 12342 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 12343 gen_store_gpr(t0, rd); 12344 break; 12345 #endif 12346 } 12347 tcg_temp_free(t0); 12348 } 12349 12350 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 12351 int ret, int v1, int v2) 12352 { 12353 TCGv v1_t; 12354 TCGv v2_t; 12355 12356 if (ret == 0) { 12357 /* Treat as NOP. */ 12358 return; 12359 } 12360 12361 v1_t = tcg_temp_new(); 12362 v2_t = tcg_temp_new(); 12363 12364 gen_load_gpr(v1_t, v1); 12365 gen_load_gpr(v2_t, v2); 12366 12367 switch (op1) { 12368 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 12369 case OPC_MULT_G_2E: 12370 check_dsp_r2(ctx); 12371 switch (op2) { 12372 case OPC_ADDUH_QB: 12373 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 12374 break; 12375 case OPC_ADDUH_R_QB: 12376 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12377 break; 12378 case OPC_ADDQH_PH: 12379 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 12380 break; 12381 case OPC_ADDQH_R_PH: 12382 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12383 break; 12384 case OPC_ADDQH_W: 12385 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 12386 break; 12387 case OPC_ADDQH_R_W: 12388 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12389 break; 12390 case OPC_SUBUH_QB: 12391 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 12392 break; 12393 case OPC_SUBUH_R_QB: 12394 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12395 break; 12396 case OPC_SUBQH_PH: 12397 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 12398 break; 12399 case OPC_SUBQH_R_PH: 12400 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12401 break; 12402 case OPC_SUBQH_W: 12403 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 12404 break; 12405 case OPC_SUBQH_R_W: 12406 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12407 break; 12408 } 12409 break; 12410 case OPC_ABSQ_S_PH_DSP: 12411 switch (op2) { 12412 case OPC_ABSQ_S_QB: 12413 check_dsp_r2(ctx); 12414 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 12415 break; 12416 case OPC_ABSQ_S_PH: 12417 check_dsp(ctx); 12418 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 12419 break; 12420 case OPC_ABSQ_S_W: 12421 check_dsp(ctx); 12422 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 12423 break; 12424 case OPC_PRECEQ_W_PHL: 12425 check_dsp(ctx); 12426 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 12427 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12428 break; 12429 case OPC_PRECEQ_W_PHR: 12430 check_dsp(ctx); 12431 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 12432 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 12433 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12434 break; 12435 case OPC_PRECEQU_PH_QBL: 12436 check_dsp(ctx); 12437 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 12438 break; 12439 case OPC_PRECEQU_PH_QBR: 12440 check_dsp(ctx); 12441 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 12442 break; 12443 case OPC_PRECEQU_PH_QBLA: 12444 check_dsp(ctx); 12445 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 12446 break; 12447 case OPC_PRECEQU_PH_QBRA: 12448 check_dsp(ctx); 12449 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 12450 break; 12451 case OPC_PRECEU_PH_QBL: 12452 check_dsp(ctx); 12453 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 12454 break; 12455 case OPC_PRECEU_PH_QBR: 12456 check_dsp(ctx); 12457 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 12458 break; 12459 case OPC_PRECEU_PH_QBLA: 12460 check_dsp(ctx); 12461 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 12462 break; 12463 case OPC_PRECEU_PH_QBRA: 12464 check_dsp(ctx); 12465 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 12466 break; 12467 } 12468 break; 12469 case OPC_ADDU_QB_DSP: 12470 switch (op2) { 12471 case OPC_ADDQ_PH: 12472 check_dsp(ctx); 12473 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12474 break; 12475 case OPC_ADDQ_S_PH: 12476 check_dsp(ctx); 12477 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12478 break; 12479 case OPC_ADDQ_S_W: 12480 check_dsp(ctx); 12481 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12482 break; 12483 case OPC_ADDU_QB: 12484 check_dsp(ctx); 12485 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12486 break; 12487 case OPC_ADDU_S_QB: 12488 check_dsp(ctx); 12489 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12490 break; 12491 case OPC_ADDU_PH: 12492 check_dsp_r2(ctx); 12493 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12494 break; 12495 case OPC_ADDU_S_PH: 12496 check_dsp_r2(ctx); 12497 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12498 break; 12499 case OPC_SUBQ_PH: 12500 check_dsp(ctx); 12501 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12502 break; 12503 case OPC_SUBQ_S_PH: 12504 check_dsp(ctx); 12505 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12506 break; 12507 case OPC_SUBQ_S_W: 12508 check_dsp(ctx); 12509 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12510 break; 12511 case OPC_SUBU_QB: 12512 check_dsp(ctx); 12513 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12514 break; 12515 case OPC_SUBU_S_QB: 12516 check_dsp(ctx); 12517 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12518 break; 12519 case OPC_SUBU_PH: 12520 check_dsp_r2(ctx); 12521 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12522 break; 12523 case OPC_SUBU_S_PH: 12524 check_dsp_r2(ctx); 12525 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12526 break; 12527 case OPC_ADDSC: 12528 check_dsp(ctx); 12529 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12530 break; 12531 case OPC_ADDWC: 12532 check_dsp(ctx); 12533 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12534 break; 12535 case OPC_MODSUB: 12536 check_dsp(ctx); 12537 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 12538 break; 12539 case OPC_RADDU_W_QB: 12540 check_dsp(ctx); 12541 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 12542 break; 12543 } 12544 break; 12545 case OPC_CMPU_EQ_QB_DSP: 12546 switch (op2) { 12547 case OPC_PRECR_QB_PH: 12548 check_dsp_r2(ctx); 12549 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12550 break; 12551 case OPC_PRECRQ_QB_PH: 12552 check_dsp(ctx); 12553 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12554 break; 12555 case OPC_PRECR_SRA_PH_W: 12556 check_dsp_r2(ctx); 12557 { 12558 TCGv_i32 sa_t = tcg_const_i32(v2); 12559 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 12560 cpu_gpr[ret]); 12561 tcg_temp_free_i32(sa_t); 12562 break; 12563 } 12564 case OPC_PRECR_SRA_R_PH_W: 12565 check_dsp_r2(ctx); 12566 { 12567 TCGv_i32 sa_t = tcg_const_i32(v2); 12568 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 12569 cpu_gpr[ret]); 12570 tcg_temp_free_i32(sa_t); 12571 break; 12572 } 12573 case OPC_PRECRQ_PH_W: 12574 check_dsp(ctx); 12575 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 12576 break; 12577 case OPC_PRECRQ_RS_PH_W: 12578 check_dsp(ctx); 12579 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12580 break; 12581 case OPC_PRECRQU_S_QB_PH: 12582 check_dsp(ctx); 12583 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12584 break; 12585 } 12586 break; 12587 #ifdef TARGET_MIPS64 12588 case OPC_ABSQ_S_QH_DSP: 12589 switch (op2) { 12590 case OPC_PRECEQ_L_PWL: 12591 check_dsp(ctx); 12592 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 12593 break; 12594 case OPC_PRECEQ_L_PWR: 12595 check_dsp(ctx); 12596 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 12597 break; 12598 case OPC_PRECEQ_PW_QHL: 12599 check_dsp(ctx); 12600 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 12601 break; 12602 case OPC_PRECEQ_PW_QHR: 12603 check_dsp(ctx); 12604 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 12605 break; 12606 case OPC_PRECEQ_PW_QHLA: 12607 check_dsp(ctx); 12608 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 12609 break; 12610 case OPC_PRECEQ_PW_QHRA: 12611 check_dsp(ctx); 12612 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 12613 break; 12614 case OPC_PRECEQU_QH_OBL: 12615 check_dsp(ctx); 12616 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 12617 break; 12618 case OPC_PRECEQU_QH_OBR: 12619 check_dsp(ctx); 12620 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 12621 break; 12622 case OPC_PRECEQU_QH_OBLA: 12623 check_dsp(ctx); 12624 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 12625 break; 12626 case OPC_PRECEQU_QH_OBRA: 12627 check_dsp(ctx); 12628 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 12629 break; 12630 case OPC_PRECEU_QH_OBL: 12631 check_dsp(ctx); 12632 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 12633 break; 12634 case OPC_PRECEU_QH_OBR: 12635 check_dsp(ctx); 12636 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 12637 break; 12638 case OPC_PRECEU_QH_OBLA: 12639 check_dsp(ctx); 12640 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 12641 break; 12642 case OPC_PRECEU_QH_OBRA: 12643 check_dsp(ctx); 12644 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 12645 break; 12646 case OPC_ABSQ_S_OB: 12647 check_dsp_r2(ctx); 12648 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 12649 break; 12650 case OPC_ABSQ_S_PW: 12651 check_dsp(ctx); 12652 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 12653 break; 12654 case OPC_ABSQ_S_QH: 12655 check_dsp(ctx); 12656 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 12657 break; 12658 } 12659 break; 12660 case OPC_ADDU_OB_DSP: 12661 switch (op2) { 12662 case OPC_RADDU_L_OB: 12663 check_dsp(ctx); 12664 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 12665 break; 12666 case OPC_SUBQ_PW: 12667 check_dsp(ctx); 12668 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12669 break; 12670 case OPC_SUBQ_S_PW: 12671 check_dsp(ctx); 12672 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12673 break; 12674 case OPC_SUBQ_QH: 12675 check_dsp(ctx); 12676 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12677 break; 12678 case OPC_SUBQ_S_QH: 12679 check_dsp(ctx); 12680 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12681 break; 12682 case OPC_SUBU_OB: 12683 check_dsp(ctx); 12684 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12685 break; 12686 case OPC_SUBU_S_OB: 12687 check_dsp(ctx); 12688 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12689 break; 12690 case OPC_SUBU_QH: 12691 check_dsp_r2(ctx); 12692 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12693 break; 12694 case OPC_SUBU_S_QH: 12695 check_dsp_r2(ctx); 12696 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12697 break; 12698 case OPC_SUBUH_OB: 12699 check_dsp_r2(ctx); 12700 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12701 break; 12702 case OPC_SUBUH_R_OB: 12703 check_dsp_r2(ctx); 12704 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12705 break; 12706 case OPC_ADDQ_PW: 12707 check_dsp(ctx); 12708 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12709 break; 12710 case OPC_ADDQ_S_PW: 12711 check_dsp(ctx); 12712 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12713 break; 12714 case OPC_ADDQ_QH: 12715 check_dsp(ctx); 12716 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12717 break; 12718 case OPC_ADDQ_S_QH: 12719 check_dsp(ctx); 12720 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12721 break; 12722 case OPC_ADDU_OB: 12723 check_dsp(ctx); 12724 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12725 break; 12726 case OPC_ADDU_S_OB: 12727 check_dsp(ctx); 12728 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12729 break; 12730 case OPC_ADDU_QH: 12731 check_dsp_r2(ctx); 12732 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12733 break; 12734 case OPC_ADDU_S_QH: 12735 check_dsp_r2(ctx); 12736 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12737 break; 12738 case OPC_ADDUH_OB: 12739 check_dsp_r2(ctx); 12740 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12741 break; 12742 case OPC_ADDUH_R_OB: 12743 check_dsp_r2(ctx); 12744 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12745 break; 12746 } 12747 break; 12748 case OPC_CMPU_EQ_OB_DSP: 12749 switch (op2) { 12750 case OPC_PRECR_OB_QH: 12751 check_dsp_r2(ctx); 12752 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12753 break; 12754 case OPC_PRECR_SRA_QH_PW: 12755 check_dsp_r2(ctx); 12756 { 12757 TCGv_i32 ret_t = tcg_const_i32(ret); 12758 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12759 tcg_temp_free_i32(ret_t); 12760 break; 12761 } 12762 case OPC_PRECR_SRA_R_QH_PW: 12763 check_dsp_r2(ctx); 12764 { 12765 TCGv_i32 sa_v = tcg_const_i32(ret); 12766 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12767 tcg_temp_free_i32(sa_v); 12768 break; 12769 } 12770 case OPC_PRECRQ_OB_QH: 12771 check_dsp(ctx); 12772 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12773 break; 12774 case OPC_PRECRQ_PW_L: 12775 check_dsp(ctx); 12776 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12777 break; 12778 case OPC_PRECRQ_QH_PW: 12779 check_dsp(ctx); 12780 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12781 break; 12782 case OPC_PRECRQ_RS_QH_PW: 12783 check_dsp(ctx); 12784 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12785 break; 12786 case OPC_PRECRQU_S_OB_QH: 12787 check_dsp(ctx); 12788 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12789 break; 12790 } 12791 break; 12792 #endif 12793 } 12794 12795 tcg_temp_free(v1_t); 12796 tcg_temp_free(v2_t); 12797 } 12798 12799 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12800 int ret, int v1, int v2) 12801 { 12802 uint32_t op2; 12803 TCGv t0; 12804 TCGv v1_t; 12805 TCGv v2_t; 12806 12807 if (ret == 0) { 12808 /* Treat as NOP. */ 12809 return; 12810 } 12811 12812 t0 = tcg_temp_new(); 12813 v1_t = tcg_temp_new(); 12814 v2_t = tcg_temp_new(); 12815 12816 tcg_gen_movi_tl(t0, v1); 12817 gen_load_gpr(v1_t, v1); 12818 gen_load_gpr(v2_t, v2); 12819 12820 switch (opc) { 12821 case OPC_SHLL_QB_DSP: 12822 { 12823 op2 = MASK_SHLL_QB(ctx->opcode); 12824 switch (op2) { 12825 case OPC_SHLL_QB: 12826 check_dsp(ctx); 12827 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12828 break; 12829 case OPC_SHLLV_QB: 12830 check_dsp(ctx); 12831 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12832 break; 12833 case OPC_SHLL_PH: 12834 check_dsp(ctx); 12835 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12836 break; 12837 case OPC_SHLLV_PH: 12838 check_dsp(ctx); 12839 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12840 break; 12841 case OPC_SHLL_S_PH: 12842 check_dsp(ctx); 12843 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12844 break; 12845 case OPC_SHLLV_S_PH: 12846 check_dsp(ctx); 12847 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12848 break; 12849 case OPC_SHLL_S_W: 12850 check_dsp(ctx); 12851 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12852 break; 12853 case OPC_SHLLV_S_W: 12854 check_dsp(ctx); 12855 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12856 break; 12857 case OPC_SHRL_QB: 12858 check_dsp(ctx); 12859 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12860 break; 12861 case OPC_SHRLV_QB: 12862 check_dsp(ctx); 12863 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12864 break; 12865 case OPC_SHRL_PH: 12866 check_dsp_r2(ctx); 12867 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12868 break; 12869 case OPC_SHRLV_PH: 12870 check_dsp_r2(ctx); 12871 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12872 break; 12873 case OPC_SHRA_QB: 12874 check_dsp_r2(ctx); 12875 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12876 break; 12877 case OPC_SHRA_R_QB: 12878 check_dsp_r2(ctx); 12879 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12880 break; 12881 case OPC_SHRAV_QB: 12882 check_dsp_r2(ctx); 12883 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12884 break; 12885 case OPC_SHRAV_R_QB: 12886 check_dsp_r2(ctx); 12887 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12888 break; 12889 case OPC_SHRA_PH: 12890 check_dsp(ctx); 12891 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12892 break; 12893 case OPC_SHRA_R_PH: 12894 check_dsp(ctx); 12895 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12896 break; 12897 case OPC_SHRAV_PH: 12898 check_dsp(ctx); 12899 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12900 break; 12901 case OPC_SHRAV_R_PH: 12902 check_dsp(ctx); 12903 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12904 break; 12905 case OPC_SHRA_R_W: 12906 check_dsp(ctx); 12907 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12908 break; 12909 case OPC_SHRAV_R_W: 12910 check_dsp(ctx); 12911 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12912 break; 12913 default: /* Invalid */ 12914 MIPS_INVAL("MASK SHLL.QB"); 12915 gen_reserved_instruction(ctx); 12916 break; 12917 } 12918 break; 12919 } 12920 #ifdef TARGET_MIPS64 12921 case OPC_SHLL_OB_DSP: 12922 op2 = MASK_SHLL_OB(ctx->opcode); 12923 switch (op2) { 12924 case OPC_SHLL_PW: 12925 check_dsp(ctx); 12926 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12927 break; 12928 case OPC_SHLLV_PW: 12929 check_dsp(ctx); 12930 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12931 break; 12932 case OPC_SHLL_S_PW: 12933 check_dsp(ctx); 12934 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12935 break; 12936 case OPC_SHLLV_S_PW: 12937 check_dsp(ctx); 12938 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12939 break; 12940 case OPC_SHLL_OB: 12941 check_dsp(ctx); 12942 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12943 break; 12944 case OPC_SHLLV_OB: 12945 check_dsp(ctx); 12946 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12947 break; 12948 case OPC_SHLL_QH: 12949 check_dsp(ctx); 12950 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12951 break; 12952 case OPC_SHLLV_QH: 12953 check_dsp(ctx); 12954 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12955 break; 12956 case OPC_SHLL_S_QH: 12957 check_dsp(ctx); 12958 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12959 break; 12960 case OPC_SHLLV_S_QH: 12961 check_dsp(ctx); 12962 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12963 break; 12964 case OPC_SHRA_OB: 12965 check_dsp_r2(ctx); 12966 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12967 break; 12968 case OPC_SHRAV_OB: 12969 check_dsp_r2(ctx); 12970 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12971 break; 12972 case OPC_SHRA_R_OB: 12973 check_dsp_r2(ctx); 12974 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12975 break; 12976 case OPC_SHRAV_R_OB: 12977 check_dsp_r2(ctx); 12978 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12979 break; 12980 case OPC_SHRA_PW: 12981 check_dsp(ctx); 12982 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12983 break; 12984 case OPC_SHRAV_PW: 12985 check_dsp(ctx); 12986 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12987 break; 12988 case OPC_SHRA_R_PW: 12989 check_dsp(ctx); 12990 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12991 break; 12992 case OPC_SHRAV_R_PW: 12993 check_dsp(ctx); 12994 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12995 break; 12996 case OPC_SHRA_QH: 12997 check_dsp(ctx); 12998 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12999 break; 13000 case OPC_SHRAV_QH: 13001 check_dsp(ctx); 13002 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 13003 break; 13004 case OPC_SHRA_R_QH: 13005 check_dsp(ctx); 13006 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 13007 break; 13008 case OPC_SHRAV_R_QH: 13009 check_dsp(ctx); 13010 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 13011 break; 13012 case OPC_SHRL_OB: 13013 check_dsp(ctx); 13014 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 13015 break; 13016 case OPC_SHRLV_OB: 13017 check_dsp(ctx); 13018 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 13019 break; 13020 case OPC_SHRL_QH: 13021 check_dsp_r2(ctx); 13022 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 13023 break; 13024 case OPC_SHRLV_QH: 13025 check_dsp_r2(ctx); 13026 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 13027 break; 13028 default: /* Invalid */ 13029 MIPS_INVAL("MASK SHLL.OB"); 13030 gen_reserved_instruction(ctx); 13031 break; 13032 } 13033 break; 13034 #endif 13035 } 13036 13037 tcg_temp_free(t0); 13038 tcg_temp_free(v1_t); 13039 tcg_temp_free(v2_t); 13040 } 13041 13042 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 13043 int ret, int v1, int v2, int check_ret) 13044 { 13045 TCGv_i32 t0; 13046 TCGv v1_t; 13047 TCGv v2_t; 13048 13049 if ((ret == 0) && (check_ret == 1)) { 13050 /* Treat as NOP. */ 13051 return; 13052 } 13053 13054 t0 = tcg_temp_new_i32(); 13055 v1_t = tcg_temp_new(); 13056 v2_t = tcg_temp_new(); 13057 13058 tcg_gen_movi_i32(t0, ret); 13059 gen_load_gpr(v1_t, v1); 13060 gen_load_gpr(v2_t, v2); 13061 13062 switch (op1) { 13063 /* 13064 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13065 * the same mask and op1. 13066 */ 13067 case OPC_MULT_G_2E: 13068 check_dsp_r2(ctx); 13069 switch (op2) { 13070 case OPC_MUL_PH: 13071 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13072 break; 13073 case OPC_MUL_S_PH: 13074 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13075 break; 13076 case OPC_MULQ_S_W: 13077 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13078 break; 13079 case OPC_MULQ_RS_W: 13080 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13081 break; 13082 } 13083 break; 13084 case OPC_DPA_W_PH_DSP: 13085 switch (op2) { 13086 case OPC_DPAU_H_QBL: 13087 check_dsp(ctx); 13088 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 13089 break; 13090 case OPC_DPAU_H_QBR: 13091 check_dsp(ctx); 13092 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 13093 break; 13094 case OPC_DPSU_H_QBL: 13095 check_dsp(ctx); 13096 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 13097 break; 13098 case OPC_DPSU_H_QBR: 13099 check_dsp(ctx); 13100 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 13101 break; 13102 case OPC_DPA_W_PH: 13103 check_dsp_r2(ctx); 13104 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 13105 break; 13106 case OPC_DPAX_W_PH: 13107 check_dsp_r2(ctx); 13108 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 13109 break; 13110 case OPC_DPAQ_S_W_PH: 13111 check_dsp(ctx); 13112 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13113 break; 13114 case OPC_DPAQX_S_W_PH: 13115 check_dsp_r2(ctx); 13116 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13117 break; 13118 case OPC_DPAQX_SA_W_PH: 13119 check_dsp_r2(ctx); 13120 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13121 break; 13122 case OPC_DPS_W_PH: 13123 check_dsp_r2(ctx); 13124 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 13125 break; 13126 case OPC_DPSX_W_PH: 13127 check_dsp_r2(ctx); 13128 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 13129 break; 13130 case OPC_DPSQ_S_W_PH: 13131 check_dsp(ctx); 13132 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13133 break; 13134 case OPC_DPSQX_S_W_PH: 13135 check_dsp_r2(ctx); 13136 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13137 break; 13138 case OPC_DPSQX_SA_W_PH: 13139 check_dsp_r2(ctx); 13140 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13141 break; 13142 case OPC_MULSAQ_S_W_PH: 13143 check_dsp(ctx); 13144 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13145 break; 13146 case OPC_DPAQ_SA_L_W: 13147 check_dsp(ctx); 13148 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13149 break; 13150 case OPC_DPSQ_SA_L_W: 13151 check_dsp(ctx); 13152 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13153 break; 13154 case OPC_MAQ_S_W_PHL: 13155 check_dsp(ctx); 13156 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 13157 break; 13158 case OPC_MAQ_S_W_PHR: 13159 check_dsp(ctx); 13160 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 13161 break; 13162 case OPC_MAQ_SA_W_PHL: 13163 check_dsp(ctx); 13164 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 13165 break; 13166 case OPC_MAQ_SA_W_PHR: 13167 check_dsp(ctx); 13168 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 13169 break; 13170 case OPC_MULSA_W_PH: 13171 check_dsp_r2(ctx); 13172 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 13173 break; 13174 } 13175 break; 13176 #ifdef TARGET_MIPS64 13177 case OPC_DPAQ_W_QH_DSP: 13178 { 13179 int ac = ret & 0x03; 13180 tcg_gen_movi_i32(t0, ac); 13181 13182 switch (op2) { 13183 case OPC_DMADD: 13184 check_dsp(ctx); 13185 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 13186 break; 13187 case OPC_DMADDU: 13188 check_dsp(ctx); 13189 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 13190 break; 13191 case OPC_DMSUB: 13192 check_dsp(ctx); 13193 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 13194 break; 13195 case OPC_DMSUBU: 13196 check_dsp(ctx); 13197 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 13198 break; 13199 case OPC_DPA_W_QH: 13200 check_dsp_r2(ctx); 13201 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 13202 break; 13203 case OPC_DPAQ_S_W_QH: 13204 check_dsp(ctx); 13205 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13206 break; 13207 case OPC_DPAQ_SA_L_PW: 13208 check_dsp(ctx); 13209 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13210 break; 13211 case OPC_DPAU_H_OBL: 13212 check_dsp(ctx); 13213 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 13214 break; 13215 case OPC_DPAU_H_OBR: 13216 check_dsp(ctx); 13217 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 13218 break; 13219 case OPC_DPS_W_QH: 13220 check_dsp_r2(ctx); 13221 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 13222 break; 13223 case OPC_DPSQ_S_W_QH: 13224 check_dsp(ctx); 13225 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13226 break; 13227 case OPC_DPSQ_SA_L_PW: 13228 check_dsp(ctx); 13229 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13230 break; 13231 case OPC_DPSU_H_OBL: 13232 check_dsp(ctx); 13233 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 13234 break; 13235 case OPC_DPSU_H_OBR: 13236 check_dsp(ctx); 13237 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 13238 break; 13239 case OPC_MAQ_S_L_PWL: 13240 check_dsp(ctx); 13241 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 13242 break; 13243 case OPC_MAQ_S_L_PWR: 13244 check_dsp(ctx); 13245 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 13246 break; 13247 case OPC_MAQ_S_W_QHLL: 13248 check_dsp(ctx); 13249 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 13250 break; 13251 case OPC_MAQ_SA_W_QHLL: 13252 check_dsp(ctx); 13253 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 13254 break; 13255 case OPC_MAQ_S_W_QHLR: 13256 check_dsp(ctx); 13257 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 13258 break; 13259 case OPC_MAQ_SA_W_QHLR: 13260 check_dsp(ctx); 13261 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 13262 break; 13263 case OPC_MAQ_S_W_QHRL: 13264 check_dsp(ctx); 13265 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 13266 break; 13267 case OPC_MAQ_SA_W_QHRL: 13268 check_dsp(ctx); 13269 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 13270 break; 13271 case OPC_MAQ_S_W_QHRR: 13272 check_dsp(ctx); 13273 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 13274 break; 13275 case OPC_MAQ_SA_W_QHRR: 13276 check_dsp(ctx); 13277 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 13278 break; 13279 case OPC_MULSAQ_S_L_PW: 13280 check_dsp(ctx); 13281 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 13282 break; 13283 case OPC_MULSAQ_S_W_QH: 13284 check_dsp(ctx); 13285 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13286 break; 13287 } 13288 } 13289 break; 13290 #endif 13291 case OPC_ADDU_QB_DSP: 13292 switch (op2) { 13293 case OPC_MULEU_S_PH_QBL: 13294 check_dsp(ctx); 13295 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13296 break; 13297 case OPC_MULEU_S_PH_QBR: 13298 check_dsp(ctx); 13299 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13300 break; 13301 case OPC_MULQ_RS_PH: 13302 check_dsp(ctx); 13303 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13304 break; 13305 case OPC_MULEQ_S_W_PHL: 13306 check_dsp(ctx); 13307 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13308 break; 13309 case OPC_MULEQ_S_W_PHR: 13310 check_dsp(ctx); 13311 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13312 break; 13313 case OPC_MULQ_S_PH: 13314 check_dsp_r2(ctx); 13315 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13316 break; 13317 } 13318 break; 13319 #ifdef TARGET_MIPS64 13320 case OPC_ADDU_OB_DSP: 13321 switch (op2) { 13322 case OPC_MULEQ_S_PW_QHL: 13323 check_dsp(ctx); 13324 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13325 break; 13326 case OPC_MULEQ_S_PW_QHR: 13327 check_dsp(ctx); 13328 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13329 break; 13330 case OPC_MULEU_S_QH_OBL: 13331 check_dsp(ctx); 13332 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13333 break; 13334 case OPC_MULEU_S_QH_OBR: 13335 check_dsp(ctx); 13336 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13337 break; 13338 case OPC_MULQ_RS_QH: 13339 check_dsp(ctx); 13340 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13341 break; 13342 } 13343 break; 13344 #endif 13345 } 13346 13347 tcg_temp_free_i32(t0); 13348 tcg_temp_free(v1_t); 13349 tcg_temp_free(v2_t); 13350 } 13351 13352 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13353 int ret, int val) 13354 { 13355 int16_t imm; 13356 TCGv t0; 13357 TCGv val_t; 13358 13359 if (ret == 0) { 13360 /* Treat as NOP. */ 13361 return; 13362 } 13363 13364 t0 = tcg_temp_new(); 13365 val_t = tcg_temp_new(); 13366 gen_load_gpr(val_t, val); 13367 13368 switch (op1) { 13369 case OPC_ABSQ_S_PH_DSP: 13370 switch (op2) { 13371 case OPC_BITREV: 13372 check_dsp(ctx); 13373 gen_helper_bitrev(cpu_gpr[ret], val_t); 13374 break; 13375 case OPC_REPL_QB: 13376 check_dsp(ctx); 13377 { 13378 target_long result; 13379 imm = (ctx->opcode >> 16) & 0xFF; 13380 result = (uint32_t)imm << 24 | 13381 (uint32_t)imm << 16 | 13382 (uint32_t)imm << 8 | 13383 (uint32_t)imm; 13384 result = (int32_t)result; 13385 tcg_gen_movi_tl(cpu_gpr[ret], result); 13386 } 13387 break; 13388 case OPC_REPLV_QB: 13389 check_dsp(ctx); 13390 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13391 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13392 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13393 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13394 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13395 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13396 break; 13397 case OPC_REPL_PH: 13398 check_dsp(ctx); 13399 { 13400 imm = (ctx->opcode >> 16) & 0x03FF; 13401 imm = (int16_t)(imm << 6) >> 6; 13402 tcg_gen_movi_tl(cpu_gpr[ret], \ 13403 (target_long)((int32_t)imm << 16 | \ 13404 (uint16_t)imm)); 13405 } 13406 break; 13407 case OPC_REPLV_PH: 13408 check_dsp(ctx); 13409 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13410 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13411 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13412 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13413 break; 13414 } 13415 break; 13416 #ifdef TARGET_MIPS64 13417 case OPC_ABSQ_S_QH_DSP: 13418 switch (op2) { 13419 case OPC_REPL_OB: 13420 check_dsp(ctx); 13421 { 13422 target_long temp; 13423 13424 imm = (ctx->opcode >> 16) & 0xFF; 13425 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 13426 temp = (temp << 16) | temp; 13427 temp = (temp << 32) | temp; 13428 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13429 break; 13430 } 13431 case OPC_REPL_PW: 13432 check_dsp(ctx); 13433 { 13434 target_long temp; 13435 13436 imm = (ctx->opcode >> 16) & 0x03FF; 13437 imm = (int16_t)(imm << 6) >> 6; 13438 temp = ((target_long)imm << 32) \ 13439 | ((target_long)imm & 0xFFFFFFFF); 13440 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13441 break; 13442 } 13443 case OPC_REPL_QH: 13444 check_dsp(ctx); 13445 { 13446 target_long temp; 13447 13448 imm = (ctx->opcode >> 16) & 0x03FF; 13449 imm = (int16_t)(imm << 6) >> 6; 13450 13451 temp = ((uint64_t)(uint16_t)imm << 48) | 13452 ((uint64_t)(uint16_t)imm << 32) | 13453 ((uint64_t)(uint16_t)imm << 16) | 13454 (uint64_t)(uint16_t)imm; 13455 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13456 break; 13457 } 13458 case OPC_REPLV_OB: 13459 check_dsp(ctx); 13460 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13461 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13462 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13463 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13464 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13465 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13466 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13467 break; 13468 case OPC_REPLV_PW: 13469 check_dsp(ctx); 13470 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 13471 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13472 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13473 break; 13474 case OPC_REPLV_QH: 13475 check_dsp(ctx); 13476 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13477 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13478 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13479 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13480 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13481 break; 13482 } 13483 break; 13484 #endif 13485 } 13486 tcg_temp_free(t0); 13487 tcg_temp_free(val_t); 13488 } 13489 13490 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 13491 uint32_t op1, uint32_t op2, 13492 int ret, int v1, int v2, int check_ret) 13493 { 13494 TCGv t1; 13495 TCGv v1_t; 13496 TCGv v2_t; 13497 13498 if ((ret == 0) && (check_ret == 1)) { 13499 /* Treat as NOP. */ 13500 return; 13501 } 13502 13503 t1 = tcg_temp_new(); 13504 v1_t = tcg_temp_new(); 13505 v2_t = tcg_temp_new(); 13506 13507 gen_load_gpr(v1_t, v1); 13508 gen_load_gpr(v2_t, v2); 13509 13510 switch (op1) { 13511 case OPC_CMPU_EQ_QB_DSP: 13512 switch (op2) { 13513 case OPC_CMPU_EQ_QB: 13514 check_dsp(ctx); 13515 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 13516 break; 13517 case OPC_CMPU_LT_QB: 13518 check_dsp(ctx); 13519 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 13520 break; 13521 case OPC_CMPU_LE_QB: 13522 check_dsp(ctx); 13523 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 13524 break; 13525 case OPC_CMPGU_EQ_QB: 13526 check_dsp(ctx); 13527 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 13528 break; 13529 case OPC_CMPGU_LT_QB: 13530 check_dsp(ctx); 13531 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 13532 break; 13533 case OPC_CMPGU_LE_QB: 13534 check_dsp(ctx); 13535 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 13536 break; 13537 case OPC_CMPGDU_EQ_QB: 13538 check_dsp_r2(ctx); 13539 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 13540 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13541 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13542 tcg_gen_shli_tl(t1, t1, 24); 13543 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13544 break; 13545 case OPC_CMPGDU_LT_QB: 13546 check_dsp_r2(ctx); 13547 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 13548 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13549 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13550 tcg_gen_shli_tl(t1, t1, 24); 13551 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13552 break; 13553 case OPC_CMPGDU_LE_QB: 13554 check_dsp_r2(ctx); 13555 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 13556 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13557 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13558 tcg_gen_shli_tl(t1, t1, 24); 13559 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13560 break; 13561 case OPC_CMP_EQ_PH: 13562 check_dsp(ctx); 13563 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 13564 break; 13565 case OPC_CMP_LT_PH: 13566 check_dsp(ctx); 13567 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 13568 break; 13569 case OPC_CMP_LE_PH: 13570 check_dsp(ctx); 13571 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 13572 break; 13573 case OPC_PICK_QB: 13574 check_dsp(ctx); 13575 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13576 break; 13577 case OPC_PICK_PH: 13578 check_dsp(ctx); 13579 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13580 break; 13581 case OPC_PACKRL_PH: 13582 check_dsp(ctx); 13583 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 13584 break; 13585 } 13586 break; 13587 #ifdef TARGET_MIPS64 13588 case OPC_CMPU_EQ_OB_DSP: 13589 switch (op2) { 13590 case OPC_CMP_EQ_PW: 13591 check_dsp(ctx); 13592 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 13593 break; 13594 case OPC_CMP_LT_PW: 13595 check_dsp(ctx); 13596 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 13597 break; 13598 case OPC_CMP_LE_PW: 13599 check_dsp(ctx); 13600 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 13601 break; 13602 case OPC_CMP_EQ_QH: 13603 check_dsp(ctx); 13604 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 13605 break; 13606 case OPC_CMP_LT_QH: 13607 check_dsp(ctx); 13608 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 13609 break; 13610 case OPC_CMP_LE_QH: 13611 check_dsp(ctx); 13612 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 13613 break; 13614 case OPC_CMPGDU_EQ_OB: 13615 check_dsp_r2(ctx); 13616 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13617 break; 13618 case OPC_CMPGDU_LT_OB: 13619 check_dsp_r2(ctx); 13620 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13621 break; 13622 case OPC_CMPGDU_LE_OB: 13623 check_dsp_r2(ctx); 13624 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13625 break; 13626 case OPC_CMPGU_EQ_OB: 13627 check_dsp(ctx); 13628 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 13629 break; 13630 case OPC_CMPGU_LT_OB: 13631 check_dsp(ctx); 13632 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 13633 break; 13634 case OPC_CMPGU_LE_OB: 13635 check_dsp(ctx); 13636 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 13637 break; 13638 case OPC_CMPU_EQ_OB: 13639 check_dsp(ctx); 13640 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 13641 break; 13642 case OPC_CMPU_LT_OB: 13643 check_dsp(ctx); 13644 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 13645 break; 13646 case OPC_CMPU_LE_OB: 13647 check_dsp(ctx); 13648 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 13649 break; 13650 case OPC_PACKRL_PW: 13651 check_dsp(ctx); 13652 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 13653 break; 13654 case OPC_PICK_OB: 13655 check_dsp(ctx); 13656 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13657 break; 13658 case OPC_PICK_PW: 13659 check_dsp(ctx); 13660 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13661 break; 13662 case OPC_PICK_QH: 13663 check_dsp(ctx); 13664 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13665 break; 13666 } 13667 break; 13668 #endif 13669 } 13670 13671 tcg_temp_free(t1); 13672 tcg_temp_free(v1_t); 13673 tcg_temp_free(v2_t); 13674 } 13675 13676 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 13677 uint32_t op1, int rt, int rs, int sa) 13678 { 13679 TCGv t0; 13680 13681 check_dsp_r2(ctx); 13682 13683 if (rt == 0) { 13684 /* Treat as NOP. */ 13685 return; 13686 } 13687 13688 t0 = tcg_temp_new(); 13689 gen_load_gpr(t0, rs); 13690 13691 switch (op1) { 13692 case OPC_APPEND_DSP: 13693 switch (MASK_APPEND(ctx->opcode)) { 13694 case OPC_APPEND: 13695 if (sa != 0) { 13696 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 13697 } 13698 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13699 break; 13700 case OPC_PREPEND: 13701 if (sa != 0) { 13702 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 13703 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13704 tcg_gen_shli_tl(t0, t0, 32 - sa); 13705 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13706 } 13707 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13708 break; 13709 case OPC_BALIGN: 13710 sa &= 3; 13711 if (sa != 0 && sa != 2) { 13712 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13713 tcg_gen_ext32u_tl(t0, t0); 13714 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13715 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13716 } 13717 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13718 break; 13719 default: /* Invalid */ 13720 MIPS_INVAL("MASK APPEND"); 13721 gen_reserved_instruction(ctx); 13722 break; 13723 } 13724 break; 13725 #ifdef TARGET_MIPS64 13726 case OPC_DAPPEND_DSP: 13727 switch (MASK_DAPPEND(ctx->opcode)) { 13728 case OPC_DAPPEND: 13729 if (sa != 0) { 13730 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13731 } 13732 break; 13733 case OPC_PREPENDD: 13734 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13735 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13736 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13737 break; 13738 case OPC_PREPENDW: 13739 if (sa != 0) { 13740 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13741 tcg_gen_shli_tl(t0, t0, 64 - sa); 13742 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13743 } 13744 break; 13745 case OPC_DBALIGN: 13746 sa &= 7; 13747 if (sa != 0 && sa != 2 && sa != 4) { 13748 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13749 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13750 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13751 } 13752 break; 13753 default: /* Invalid */ 13754 MIPS_INVAL("MASK DAPPEND"); 13755 gen_reserved_instruction(ctx); 13756 break; 13757 } 13758 break; 13759 #endif 13760 } 13761 tcg_temp_free(t0); 13762 } 13763 13764 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13765 int ret, int v1, int v2, int check_ret) 13766 13767 { 13768 TCGv t0; 13769 TCGv t1; 13770 TCGv v1_t; 13771 TCGv v2_t; 13772 int16_t imm; 13773 13774 if ((ret == 0) && (check_ret == 1)) { 13775 /* Treat as NOP. */ 13776 return; 13777 } 13778 13779 t0 = tcg_temp_new(); 13780 t1 = tcg_temp_new(); 13781 v1_t = tcg_temp_new(); 13782 v2_t = tcg_temp_new(); 13783 13784 gen_load_gpr(v1_t, v1); 13785 gen_load_gpr(v2_t, v2); 13786 13787 switch (op1) { 13788 case OPC_EXTR_W_DSP: 13789 check_dsp(ctx); 13790 switch (op2) { 13791 case OPC_EXTR_W: 13792 tcg_gen_movi_tl(t0, v2); 13793 tcg_gen_movi_tl(t1, v1); 13794 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13795 break; 13796 case OPC_EXTR_R_W: 13797 tcg_gen_movi_tl(t0, v2); 13798 tcg_gen_movi_tl(t1, v1); 13799 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13800 break; 13801 case OPC_EXTR_RS_W: 13802 tcg_gen_movi_tl(t0, v2); 13803 tcg_gen_movi_tl(t1, v1); 13804 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13805 break; 13806 case OPC_EXTR_S_H: 13807 tcg_gen_movi_tl(t0, v2); 13808 tcg_gen_movi_tl(t1, v1); 13809 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13810 break; 13811 case OPC_EXTRV_S_H: 13812 tcg_gen_movi_tl(t0, v2); 13813 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13814 break; 13815 case OPC_EXTRV_W: 13816 tcg_gen_movi_tl(t0, v2); 13817 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13818 break; 13819 case OPC_EXTRV_R_W: 13820 tcg_gen_movi_tl(t0, v2); 13821 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13822 break; 13823 case OPC_EXTRV_RS_W: 13824 tcg_gen_movi_tl(t0, v2); 13825 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13826 break; 13827 case OPC_EXTP: 13828 tcg_gen_movi_tl(t0, v2); 13829 tcg_gen_movi_tl(t1, v1); 13830 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13831 break; 13832 case OPC_EXTPV: 13833 tcg_gen_movi_tl(t0, v2); 13834 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13835 break; 13836 case OPC_EXTPDP: 13837 tcg_gen_movi_tl(t0, v2); 13838 tcg_gen_movi_tl(t1, v1); 13839 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13840 break; 13841 case OPC_EXTPDPV: 13842 tcg_gen_movi_tl(t0, v2); 13843 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13844 break; 13845 case OPC_SHILO: 13846 imm = (ctx->opcode >> 20) & 0x3F; 13847 tcg_gen_movi_tl(t0, ret); 13848 tcg_gen_movi_tl(t1, imm); 13849 gen_helper_shilo(t0, t1, cpu_env); 13850 break; 13851 case OPC_SHILOV: 13852 tcg_gen_movi_tl(t0, ret); 13853 gen_helper_shilo(t0, v1_t, cpu_env); 13854 break; 13855 case OPC_MTHLIP: 13856 tcg_gen_movi_tl(t0, ret); 13857 gen_helper_mthlip(t0, v1_t, cpu_env); 13858 break; 13859 case OPC_WRDSP: 13860 imm = (ctx->opcode >> 11) & 0x3FF; 13861 tcg_gen_movi_tl(t0, imm); 13862 gen_helper_wrdsp(v1_t, t0, cpu_env); 13863 break; 13864 case OPC_RDDSP: 13865 imm = (ctx->opcode >> 16) & 0x03FF; 13866 tcg_gen_movi_tl(t0, imm); 13867 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13868 break; 13869 } 13870 break; 13871 #ifdef TARGET_MIPS64 13872 case OPC_DEXTR_W_DSP: 13873 check_dsp(ctx); 13874 switch (op2) { 13875 case OPC_DMTHLIP: 13876 tcg_gen_movi_tl(t0, ret); 13877 gen_helper_dmthlip(v1_t, t0, cpu_env); 13878 break; 13879 case OPC_DSHILO: 13880 { 13881 int shift = (ctx->opcode >> 19) & 0x7F; 13882 int ac = (ctx->opcode >> 11) & 0x03; 13883 tcg_gen_movi_tl(t0, shift); 13884 tcg_gen_movi_tl(t1, ac); 13885 gen_helper_dshilo(t0, t1, cpu_env); 13886 break; 13887 } 13888 case OPC_DSHILOV: 13889 { 13890 int ac = (ctx->opcode >> 11) & 0x03; 13891 tcg_gen_movi_tl(t0, ac); 13892 gen_helper_dshilo(v1_t, t0, cpu_env); 13893 break; 13894 } 13895 case OPC_DEXTP: 13896 tcg_gen_movi_tl(t0, v2); 13897 tcg_gen_movi_tl(t1, v1); 13898 13899 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13900 break; 13901 case OPC_DEXTPV: 13902 tcg_gen_movi_tl(t0, v2); 13903 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13904 break; 13905 case OPC_DEXTPDP: 13906 tcg_gen_movi_tl(t0, v2); 13907 tcg_gen_movi_tl(t1, v1); 13908 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13909 break; 13910 case OPC_DEXTPDPV: 13911 tcg_gen_movi_tl(t0, v2); 13912 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13913 break; 13914 case OPC_DEXTR_L: 13915 tcg_gen_movi_tl(t0, v2); 13916 tcg_gen_movi_tl(t1, v1); 13917 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13918 break; 13919 case OPC_DEXTR_R_L: 13920 tcg_gen_movi_tl(t0, v2); 13921 tcg_gen_movi_tl(t1, v1); 13922 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13923 break; 13924 case OPC_DEXTR_RS_L: 13925 tcg_gen_movi_tl(t0, v2); 13926 tcg_gen_movi_tl(t1, v1); 13927 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13928 break; 13929 case OPC_DEXTR_W: 13930 tcg_gen_movi_tl(t0, v2); 13931 tcg_gen_movi_tl(t1, v1); 13932 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13933 break; 13934 case OPC_DEXTR_R_W: 13935 tcg_gen_movi_tl(t0, v2); 13936 tcg_gen_movi_tl(t1, v1); 13937 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13938 break; 13939 case OPC_DEXTR_RS_W: 13940 tcg_gen_movi_tl(t0, v2); 13941 tcg_gen_movi_tl(t1, v1); 13942 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13943 break; 13944 case OPC_DEXTR_S_H: 13945 tcg_gen_movi_tl(t0, v2); 13946 tcg_gen_movi_tl(t1, v1); 13947 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13948 break; 13949 case OPC_DEXTRV_S_H: 13950 tcg_gen_movi_tl(t0, v2); 13951 tcg_gen_movi_tl(t1, v1); 13952 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13953 break; 13954 case OPC_DEXTRV_L: 13955 tcg_gen_movi_tl(t0, v2); 13956 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13957 break; 13958 case OPC_DEXTRV_R_L: 13959 tcg_gen_movi_tl(t0, v2); 13960 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13961 break; 13962 case OPC_DEXTRV_RS_L: 13963 tcg_gen_movi_tl(t0, v2); 13964 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13965 break; 13966 case OPC_DEXTRV_W: 13967 tcg_gen_movi_tl(t0, v2); 13968 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13969 break; 13970 case OPC_DEXTRV_R_W: 13971 tcg_gen_movi_tl(t0, v2); 13972 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13973 break; 13974 case OPC_DEXTRV_RS_W: 13975 tcg_gen_movi_tl(t0, v2); 13976 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13977 break; 13978 } 13979 break; 13980 #endif 13981 } 13982 13983 tcg_temp_free(t0); 13984 tcg_temp_free(t1); 13985 tcg_temp_free(v1_t); 13986 tcg_temp_free(v2_t); 13987 } 13988 13989 /* End MIPSDSP functions. */ 13990 13991 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13992 { 13993 int rs, rt, rd, sa; 13994 uint32_t op1, op2; 13995 13996 rs = (ctx->opcode >> 21) & 0x1f; 13997 rt = (ctx->opcode >> 16) & 0x1f; 13998 rd = (ctx->opcode >> 11) & 0x1f; 13999 sa = (ctx->opcode >> 6) & 0x1f; 14000 14001 op1 = MASK_SPECIAL(ctx->opcode); 14002 switch (op1) { 14003 case OPC_MULT: 14004 case OPC_MULTU: 14005 case OPC_DIV: 14006 case OPC_DIVU: 14007 op2 = MASK_R6_MULDIV(ctx->opcode); 14008 switch (op2) { 14009 case R6_OPC_MUL: 14010 case R6_OPC_MUH: 14011 case R6_OPC_MULU: 14012 case R6_OPC_MUHU: 14013 case R6_OPC_DIV: 14014 case R6_OPC_MOD: 14015 case R6_OPC_DIVU: 14016 case R6_OPC_MODU: 14017 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14018 break; 14019 default: 14020 MIPS_INVAL("special_r6 muldiv"); 14021 gen_reserved_instruction(ctx); 14022 break; 14023 } 14024 break; 14025 case OPC_SELEQZ: 14026 case OPC_SELNEZ: 14027 gen_cond_move(ctx, op1, rd, rs, rt); 14028 break; 14029 case R6_OPC_CLO: 14030 case R6_OPC_CLZ: 14031 if (rt == 0 && sa == 1) { 14032 /* 14033 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14034 * We need additionally to check other fields. 14035 */ 14036 gen_cl(ctx, op1, rd, rs); 14037 } else { 14038 gen_reserved_instruction(ctx); 14039 } 14040 break; 14041 case R6_OPC_SDBBP: 14042 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14043 gen_helper_do_semihosting(cpu_env); 14044 } else { 14045 if (ctx->hflags & MIPS_HFLAG_SBRI) { 14046 gen_reserved_instruction(ctx); 14047 } else { 14048 generate_exception_end(ctx, EXCP_DBp); 14049 } 14050 } 14051 break; 14052 #if defined(TARGET_MIPS64) 14053 case R6_OPC_DCLO: 14054 case R6_OPC_DCLZ: 14055 if (rt == 0 && sa == 1) { 14056 /* 14057 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14058 * We need additionally to check other fields. 14059 */ 14060 check_mips_64(ctx); 14061 gen_cl(ctx, op1, rd, rs); 14062 } else { 14063 gen_reserved_instruction(ctx); 14064 } 14065 break; 14066 case OPC_DMULT: 14067 case OPC_DMULTU: 14068 case OPC_DDIV: 14069 case OPC_DDIVU: 14070 14071 op2 = MASK_R6_MULDIV(ctx->opcode); 14072 switch (op2) { 14073 case R6_OPC_DMUL: 14074 case R6_OPC_DMUH: 14075 case R6_OPC_DMULU: 14076 case R6_OPC_DMUHU: 14077 case R6_OPC_DDIV: 14078 case R6_OPC_DMOD: 14079 case R6_OPC_DDIVU: 14080 case R6_OPC_DMODU: 14081 check_mips_64(ctx); 14082 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14083 break; 14084 default: 14085 MIPS_INVAL("special_r6 muldiv"); 14086 gen_reserved_instruction(ctx); 14087 break; 14088 } 14089 break; 14090 #endif 14091 default: /* Invalid */ 14092 MIPS_INVAL("special_r6"); 14093 gen_reserved_instruction(ctx); 14094 break; 14095 } 14096 } 14097 14098 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 14099 { 14100 int rs = extract32(ctx->opcode, 21, 5); 14101 int rt = extract32(ctx->opcode, 16, 5); 14102 int rd = extract32(ctx->opcode, 11, 5); 14103 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 14104 14105 switch (op1) { 14106 case OPC_MOVN: /* Conditional move */ 14107 case OPC_MOVZ: 14108 gen_cond_move(ctx, op1, rd, rs, rt); 14109 break; 14110 case OPC_MFHI: /* Move from HI/LO */ 14111 case OPC_MFLO: 14112 gen_HILO(ctx, op1, 0, rd); 14113 break; 14114 case OPC_MTHI: 14115 case OPC_MTLO: /* Move to HI/LO */ 14116 gen_HILO(ctx, op1, 0, rs); 14117 break; 14118 case OPC_MULT: 14119 case OPC_MULTU: 14120 gen_mul_txx9(ctx, op1, rd, rs, rt); 14121 break; 14122 case OPC_DIV: 14123 case OPC_DIVU: 14124 gen_muldiv(ctx, op1, 0, rs, rt); 14125 break; 14126 #if defined(TARGET_MIPS64) 14127 case OPC_DMULT: 14128 case OPC_DMULTU: 14129 case OPC_DDIV: 14130 case OPC_DDIVU: 14131 check_insn_opc_user_only(ctx, INSN_R5900); 14132 gen_muldiv(ctx, op1, 0, rs, rt); 14133 break; 14134 #endif 14135 case OPC_JR: 14136 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14137 break; 14138 default: /* Invalid */ 14139 MIPS_INVAL("special_tx79"); 14140 gen_reserved_instruction(ctx); 14141 break; 14142 } 14143 } 14144 14145 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 14146 { 14147 int rs, rt, rd, sa; 14148 uint32_t op1; 14149 14150 rs = (ctx->opcode >> 21) & 0x1f; 14151 rt = (ctx->opcode >> 16) & 0x1f; 14152 rd = (ctx->opcode >> 11) & 0x1f; 14153 sa = (ctx->opcode >> 6) & 0x1f; 14154 14155 op1 = MASK_SPECIAL(ctx->opcode); 14156 switch (op1) { 14157 case OPC_MOVN: /* Conditional move */ 14158 case OPC_MOVZ: 14159 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 14160 INSN_LOONGSON2E | INSN_LOONGSON2F); 14161 gen_cond_move(ctx, op1, rd, rs, rt); 14162 break; 14163 case OPC_MFHI: /* Move from HI/LO */ 14164 case OPC_MFLO: 14165 gen_HILO(ctx, op1, rs & 3, rd); 14166 break; 14167 case OPC_MTHI: 14168 case OPC_MTLO: /* Move to HI/LO */ 14169 gen_HILO(ctx, op1, rd & 3, rs); 14170 break; 14171 case OPC_MOVCI: 14172 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 14173 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 14174 check_cp1_enabled(ctx); 14175 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 14176 (ctx->opcode >> 16) & 1); 14177 } else { 14178 generate_exception_err(ctx, EXCP_CpU, 1); 14179 } 14180 break; 14181 case OPC_MULT: 14182 case OPC_MULTU: 14183 if (sa) { 14184 check_insn(ctx, INSN_VR54XX); 14185 op1 = MASK_MUL_VR54XX(ctx->opcode); 14186 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 14187 } else { 14188 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14189 } 14190 break; 14191 case OPC_DIV: 14192 case OPC_DIVU: 14193 gen_muldiv(ctx, op1, 0, rs, rt); 14194 break; 14195 #if defined(TARGET_MIPS64) 14196 case OPC_DMULT: 14197 case OPC_DMULTU: 14198 case OPC_DDIV: 14199 case OPC_DDIVU: 14200 check_insn(ctx, ISA_MIPS3); 14201 check_mips_64(ctx); 14202 gen_muldiv(ctx, op1, 0, rs, rt); 14203 break; 14204 #endif 14205 case OPC_JR: 14206 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14207 break; 14208 case OPC_SPIM: 14209 #ifdef MIPS_STRICT_STANDARD 14210 MIPS_INVAL("SPIM"); 14211 gen_reserved_instruction(ctx); 14212 #else 14213 /* Implemented as RI exception for now. */ 14214 MIPS_INVAL("spim (unofficial)"); 14215 gen_reserved_instruction(ctx); 14216 #endif 14217 break; 14218 default: /* Invalid */ 14219 MIPS_INVAL("special_legacy"); 14220 gen_reserved_instruction(ctx); 14221 break; 14222 } 14223 } 14224 14225 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 14226 { 14227 int rs, rt, rd, sa; 14228 uint32_t op1; 14229 14230 rs = (ctx->opcode >> 21) & 0x1f; 14231 rt = (ctx->opcode >> 16) & 0x1f; 14232 rd = (ctx->opcode >> 11) & 0x1f; 14233 sa = (ctx->opcode >> 6) & 0x1f; 14234 14235 op1 = MASK_SPECIAL(ctx->opcode); 14236 switch (op1) { 14237 case OPC_SLL: /* Shift with immediate */ 14238 if (sa == 5 && rd == 0 && 14239 rs == 0 && rt == 0) { /* PAUSE */ 14240 if ((ctx->insn_flags & ISA_MIPS_R6) && 14241 (ctx->hflags & MIPS_HFLAG_BMASK)) { 14242 gen_reserved_instruction(ctx); 14243 break; 14244 } 14245 } 14246 /* Fallthrough */ 14247 case OPC_SRA: 14248 gen_shift_imm(ctx, op1, rd, rt, sa); 14249 break; 14250 case OPC_SRL: 14251 switch ((ctx->opcode >> 21) & 0x1f) { 14252 case 1: 14253 /* rotr is decoded as srl on non-R2 CPUs */ 14254 if (ctx->insn_flags & ISA_MIPS_R2) { 14255 op1 = OPC_ROTR; 14256 } 14257 /* Fallthrough */ 14258 case 0: 14259 gen_shift_imm(ctx, op1, rd, rt, sa); 14260 break; 14261 default: 14262 gen_reserved_instruction(ctx); 14263 break; 14264 } 14265 break; 14266 case OPC_ADD: 14267 case OPC_ADDU: 14268 case OPC_SUB: 14269 case OPC_SUBU: 14270 gen_arith(ctx, op1, rd, rs, rt); 14271 break; 14272 case OPC_SLLV: /* Shifts */ 14273 case OPC_SRAV: 14274 gen_shift(ctx, op1, rd, rs, rt); 14275 break; 14276 case OPC_SRLV: 14277 switch ((ctx->opcode >> 6) & 0x1f) { 14278 case 1: 14279 /* rotrv is decoded as srlv on non-R2 CPUs */ 14280 if (ctx->insn_flags & ISA_MIPS_R2) { 14281 op1 = OPC_ROTRV; 14282 } 14283 /* Fallthrough */ 14284 case 0: 14285 gen_shift(ctx, op1, rd, rs, rt); 14286 break; 14287 default: 14288 gen_reserved_instruction(ctx); 14289 break; 14290 } 14291 break; 14292 case OPC_SLT: /* Set on less than */ 14293 case OPC_SLTU: 14294 gen_slt(ctx, op1, rd, rs, rt); 14295 break; 14296 case OPC_AND: /* Logic*/ 14297 case OPC_OR: 14298 case OPC_NOR: 14299 case OPC_XOR: 14300 gen_logic(ctx, op1, rd, rs, rt); 14301 break; 14302 case OPC_JALR: 14303 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14304 break; 14305 case OPC_TGE: /* Traps */ 14306 case OPC_TGEU: 14307 case OPC_TLT: 14308 case OPC_TLTU: 14309 case OPC_TEQ: 14310 case OPC_TNE: 14311 check_insn(ctx, ISA_MIPS2); 14312 gen_trap(ctx, op1, rs, rt, -1); 14313 break; 14314 case OPC_PMON: 14315 /* Pmon entry point, also R4010 selsl */ 14316 #ifdef MIPS_STRICT_STANDARD 14317 MIPS_INVAL("PMON / selsl"); 14318 gen_reserved_instruction(ctx); 14319 #else 14320 gen_helper_0e0i(pmon, sa); 14321 #endif 14322 break; 14323 case OPC_SYSCALL: 14324 generate_exception_end(ctx, EXCP_SYSCALL); 14325 break; 14326 case OPC_BREAK: 14327 generate_exception_end(ctx, EXCP_BREAK); 14328 break; 14329 case OPC_SYNC: 14330 check_insn(ctx, ISA_MIPS2); 14331 gen_sync(extract32(ctx->opcode, 6, 5)); 14332 break; 14333 14334 #if defined(TARGET_MIPS64) 14335 /* MIPS64 specific opcodes */ 14336 case OPC_DSLL: 14337 case OPC_DSRA: 14338 case OPC_DSLL32: 14339 case OPC_DSRA32: 14340 check_insn(ctx, ISA_MIPS3); 14341 check_mips_64(ctx); 14342 gen_shift_imm(ctx, op1, rd, rt, sa); 14343 break; 14344 case OPC_DSRL: 14345 switch ((ctx->opcode >> 21) & 0x1f) { 14346 case 1: 14347 /* drotr is decoded as dsrl on non-R2 CPUs */ 14348 if (ctx->insn_flags & ISA_MIPS_R2) { 14349 op1 = OPC_DROTR; 14350 } 14351 /* Fallthrough */ 14352 case 0: 14353 check_insn(ctx, ISA_MIPS3); 14354 check_mips_64(ctx); 14355 gen_shift_imm(ctx, op1, rd, rt, sa); 14356 break; 14357 default: 14358 gen_reserved_instruction(ctx); 14359 break; 14360 } 14361 break; 14362 case OPC_DSRL32: 14363 switch ((ctx->opcode >> 21) & 0x1f) { 14364 case 1: 14365 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 14366 if (ctx->insn_flags & ISA_MIPS_R2) { 14367 op1 = OPC_DROTR32; 14368 } 14369 /* Fallthrough */ 14370 case 0: 14371 check_insn(ctx, ISA_MIPS3); 14372 check_mips_64(ctx); 14373 gen_shift_imm(ctx, op1, rd, rt, sa); 14374 break; 14375 default: 14376 gen_reserved_instruction(ctx); 14377 break; 14378 } 14379 break; 14380 case OPC_DADD: 14381 case OPC_DADDU: 14382 case OPC_DSUB: 14383 case OPC_DSUBU: 14384 check_insn(ctx, ISA_MIPS3); 14385 check_mips_64(ctx); 14386 gen_arith(ctx, op1, rd, rs, rt); 14387 break; 14388 case OPC_DSLLV: 14389 case OPC_DSRAV: 14390 check_insn(ctx, ISA_MIPS3); 14391 check_mips_64(ctx); 14392 gen_shift(ctx, op1, rd, rs, rt); 14393 break; 14394 case OPC_DSRLV: 14395 switch ((ctx->opcode >> 6) & 0x1f) { 14396 case 1: 14397 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 14398 if (ctx->insn_flags & ISA_MIPS_R2) { 14399 op1 = OPC_DROTRV; 14400 } 14401 /* Fallthrough */ 14402 case 0: 14403 check_insn(ctx, ISA_MIPS3); 14404 check_mips_64(ctx); 14405 gen_shift(ctx, op1, rd, rs, rt); 14406 break; 14407 default: 14408 gen_reserved_instruction(ctx); 14409 break; 14410 } 14411 break; 14412 #endif 14413 default: 14414 if (ctx->insn_flags & ISA_MIPS_R6) { 14415 decode_opc_special_r6(env, ctx); 14416 } else if (ctx->insn_flags & INSN_R5900) { 14417 decode_opc_special_tx79(env, ctx); 14418 } else { 14419 decode_opc_special_legacy(env, ctx); 14420 } 14421 } 14422 } 14423 14424 14425 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 14426 { 14427 int rs, rt, rd; 14428 uint32_t op1; 14429 14430 rs = (ctx->opcode >> 21) & 0x1f; 14431 rt = (ctx->opcode >> 16) & 0x1f; 14432 rd = (ctx->opcode >> 11) & 0x1f; 14433 14434 op1 = MASK_SPECIAL2(ctx->opcode); 14435 switch (op1) { 14436 case OPC_MADD: /* Multiply and add/sub */ 14437 case OPC_MADDU: 14438 case OPC_MSUB: 14439 case OPC_MSUBU: 14440 check_insn(ctx, ISA_MIPS_R1); 14441 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14442 break; 14443 case OPC_MUL: 14444 gen_arith(ctx, op1, rd, rs, rt); 14445 break; 14446 case OPC_DIV_G_2F: 14447 case OPC_DIVU_G_2F: 14448 case OPC_MULT_G_2F: 14449 case OPC_MULTU_G_2F: 14450 case OPC_MOD_G_2F: 14451 case OPC_MODU_G_2F: 14452 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14453 gen_loongson_integer(ctx, op1, rd, rs, rt); 14454 break; 14455 case OPC_CLO: 14456 case OPC_CLZ: 14457 check_insn(ctx, ISA_MIPS_R1); 14458 gen_cl(ctx, op1, rd, rs); 14459 break; 14460 case OPC_SDBBP: 14461 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14462 gen_helper_do_semihosting(cpu_env); 14463 } else { 14464 /* 14465 * XXX: not clear which exception should be raised 14466 * when in debug mode... 14467 */ 14468 check_insn(ctx, ISA_MIPS_R1); 14469 generate_exception_end(ctx, EXCP_DBp); 14470 } 14471 break; 14472 #if defined(TARGET_MIPS64) 14473 case OPC_DCLO: 14474 case OPC_DCLZ: 14475 check_insn(ctx, ISA_MIPS_R1); 14476 check_mips_64(ctx); 14477 gen_cl(ctx, op1, rd, rs); 14478 break; 14479 case OPC_DMULT_G_2F: 14480 case OPC_DMULTU_G_2F: 14481 case OPC_DDIV_G_2F: 14482 case OPC_DDIVU_G_2F: 14483 case OPC_DMOD_G_2F: 14484 case OPC_DMODU_G_2F: 14485 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14486 gen_loongson_integer(ctx, op1, rd, rs, rt); 14487 break; 14488 #endif 14489 default: /* Invalid */ 14490 MIPS_INVAL("special2_legacy"); 14491 gen_reserved_instruction(ctx); 14492 break; 14493 } 14494 } 14495 14496 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 14497 { 14498 int rs, rt, rd, sa; 14499 uint32_t op1, op2; 14500 int16_t imm; 14501 14502 rs = (ctx->opcode >> 21) & 0x1f; 14503 rt = (ctx->opcode >> 16) & 0x1f; 14504 rd = (ctx->opcode >> 11) & 0x1f; 14505 sa = (ctx->opcode >> 6) & 0x1f; 14506 imm = (int16_t)ctx->opcode >> 7; 14507 14508 op1 = MASK_SPECIAL3(ctx->opcode); 14509 switch (op1) { 14510 case R6_OPC_PREF: 14511 if (rt >= 24) { 14512 /* hint codes 24-31 are reserved and signal RI */ 14513 gen_reserved_instruction(ctx); 14514 } 14515 /* Treat as NOP. */ 14516 break; 14517 case R6_OPC_CACHE: 14518 check_cp0_enabled(ctx); 14519 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14520 gen_cache_operation(ctx, rt, rs, imm); 14521 } 14522 break; 14523 case R6_OPC_SC: 14524 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14525 break; 14526 case R6_OPC_LL: 14527 gen_ld(ctx, op1, rt, rs, imm); 14528 break; 14529 case OPC_BSHFL: 14530 { 14531 if (rd == 0) { 14532 /* Treat as NOP. */ 14533 break; 14534 } 14535 op2 = MASK_BSHFL(ctx->opcode); 14536 switch (op2) { 14537 case OPC_ALIGN: 14538 case OPC_ALIGN_1: 14539 case OPC_ALIGN_2: 14540 case OPC_ALIGN_3: 14541 gen_align(ctx, 32, rd, rs, rt, sa & 3); 14542 break; 14543 case OPC_BITSWAP: 14544 gen_bitswap(ctx, op2, rd, rt); 14545 break; 14546 } 14547 } 14548 break; 14549 #ifndef CONFIG_USER_ONLY 14550 case OPC_GINV: 14551 if (unlikely(ctx->gi <= 1)) { 14552 gen_reserved_instruction(ctx); 14553 } 14554 check_cp0_enabled(ctx); 14555 switch ((ctx->opcode >> 6) & 3) { 14556 case 0: /* GINVI */ 14557 /* Treat as NOP. */ 14558 break; 14559 case 2: /* GINVT */ 14560 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 14561 break; 14562 default: 14563 gen_reserved_instruction(ctx); 14564 break; 14565 } 14566 break; 14567 #endif 14568 #if defined(TARGET_MIPS64) 14569 case R6_OPC_SCD: 14570 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 14571 break; 14572 case R6_OPC_LLD: 14573 gen_ld(ctx, op1, rt, rs, imm); 14574 break; 14575 case OPC_DBSHFL: 14576 check_mips_64(ctx); 14577 { 14578 if (rd == 0) { 14579 /* Treat as NOP. */ 14580 break; 14581 } 14582 op2 = MASK_DBSHFL(ctx->opcode); 14583 switch (op2) { 14584 case OPC_DALIGN: 14585 case OPC_DALIGN_1: 14586 case OPC_DALIGN_2: 14587 case OPC_DALIGN_3: 14588 case OPC_DALIGN_4: 14589 case OPC_DALIGN_5: 14590 case OPC_DALIGN_6: 14591 case OPC_DALIGN_7: 14592 gen_align(ctx, 64, rd, rs, rt, sa & 7); 14593 break; 14594 case OPC_DBITSWAP: 14595 gen_bitswap(ctx, op2, rd, rt); 14596 break; 14597 } 14598 14599 } 14600 break; 14601 #endif 14602 default: /* Invalid */ 14603 MIPS_INVAL("special3_r6"); 14604 gen_reserved_instruction(ctx); 14605 break; 14606 } 14607 } 14608 14609 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 14610 { 14611 int rs, rt, rd; 14612 uint32_t op1, op2; 14613 14614 rs = (ctx->opcode >> 21) & 0x1f; 14615 rt = (ctx->opcode >> 16) & 0x1f; 14616 rd = (ctx->opcode >> 11) & 0x1f; 14617 14618 op1 = MASK_SPECIAL3(ctx->opcode); 14619 switch (op1) { 14620 case OPC_DIV_G_2E: 14621 case OPC_DIVU_G_2E: 14622 case OPC_MOD_G_2E: 14623 case OPC_MODU_G_2E: 14624 case OPC_MULT_G_2E: 14625 case OPC_MULTU_G_2E: 14626 /* 14627 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 14628 * the same mask and op1. 14629 */ 14630 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 14631 op2 = MASK_ADDUH_QB(ctx->opcode); 14632 switch (op2) { 14633 case OPC_ADDUH_QB: 14634 case OPC_ADDUH_R_QB: 14635 case OPC_ADDQH_PH: 14636 case OPC_ADDQH_R_PH: 14637 case OPC_ADDQH_W: 14638 case OPC_ADDQH_R_W: 14639 case OPC_SUBUH_QB: 14640 case OPC_SUBUH_R_QB: 14641 case OPC_SUBQH_PH: 14642 case OPC_SUBQH_R_PH: 14643 case OPC_SUBQH_W: 14644 case OPC_SUBQH_R_W: 14645 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14646 break; 14647 case OPC_MUL_PH: 14648 case OPC_MUL_S_PH: 14649 case OPC_MULQ_S_W: 14650 case OPC_MULQ_RS_W: 14651 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14652 break; 14653 default: 14654 MIPS_INVAL("MASK ADDUH.QB"); 14655 gen_reserved_instruction(ctx); 14656 break; 14657 } 14658 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 14659 gen_loongson_integer(ctx, op1, rd, rs, rt); 14660 } else { 14661 gen_reserved_instruction(ctx); 14662 } 14663 break; 14664 case OPC_LX_DSP: 14665 op2 = MASK_LX(ctx->opcode); 14666 switch (op2) { 14667 #if defined(TARGET_MIPS64) 14668 case OPC_LDX: 14669 #endif 14670 case OPC_LBUX: 14671 case OPC_LHX: 14672 case OPC_LWX: 14673 gen_mipsdsp_ld(ctx, op2, rd, rs, rt); 14674 break; 14675 default: /* Invalid */ 14676 MIPS_INVAL("MASK LX"); 14677 gen_reserved_instruction(ctx); 14678 break; 14679 } 14680 break; 14681 case OPC_ABSQ_S_PH_DSP: 14682 op2 = MASK_ABSQ_S_PH(ctx->opcode); 14683 switch (op2) { 14684 case OPC_ABSQ_S_QB: 14685 case OPC_ABSQ_S_PH: 14686 case OPC_ABSQ_S_W: 14687 case OPC_PRECEQ_W_PHL: 14688 case OPC_PRECEQ_W_PHR: 14689 case OPC_PRECEQU_PH_QBL: 14690 case OPC_PRECEQU_PH_QBR: 14691 case OPC_PRECEQU_PH_QBLA: 14692 case OPC_PRECEQU_PH_QBRA: 14693 case OPC_PRECEU_PH_QBL: 14694 case OPC_PRECEU_PH_QBR: 14695 case OPC_PRECEU_PH_QBLA: 14696 case OPC_PRECEU_PH_QBRA: 14697 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14698 break; 14699 case OPC_BITREV: 14700 case OPC_REPL_QB: 14701 case OPC_REPLV_QB: 14702 case OPC_REPL_PH: 14703 case OPC_REPLV_PH: 14704 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14705 break; 14706 default: 14707 MIPS_INVAL("MASK ABSQ_S.PH"); 14708 gen_reserved_instruction(ctx); 14709 break; 14710 } 14711 break; 14712 case OPC_ADDU_QB_DSP: 14713 op2 = MASK_ADDU_QB(ctx->opcode); 14714 switch (op2) { 14715 case OPC_ADDQ_PH: 14716 case OPC_ADDQ_S_PH: 14717 case OPC_ADDQ_S_W: 14718 case OPC_ADDU_QB: 14719 case OPC_ADDU_S_QB: 14720 case OPC_ADDU_PH: 14721 case OPC_ADDU_S_PH: 14722 case OPC_SUBQ_PH: 14723 case OPC_SUBQ_S_PH: 14724 case OPC_SUBQ_S_W: 14725 case OPC_SUBU_QB: 14726 case OPC_SUBU_S_QB: 14727 case OPC_SUBU_PH: 14728 case OPC_SUBU_S_PH: 14729 case OPC_ADDSC: 14730 case OPC_ADDWC: 14731 case OPC_MODSUB: 14732 case OPC_RADDU_W_QB: 14733 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14734 break; 14735 case OPC_MULEU_S_PH_QBL: 14736 case OPC_MULEU_S_PH_QBR: 14737 case OPC_MULQ_RS_PH: 14738 case OPC_MULEQ_S_W_PHL: 14739 case OPC_MULEQ_S_W_PHR: 14740 case OPC_MULQ_S_PH: 14741 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14742 break; 14743 default: /* Invalid */ 14744 MIPS_INVAL("MASK ADDU.QB"); 14745 gen_reserved_instruction(ctx); 14746 break; 14747 14748 } 14749 break; 14750 case OPC_CMPU_EQ_QB_DSP: 14751 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14752 switch (op2) { 14753 case OPC_PRECR_SRA_PH_W: 14754 case OPC_PRECR_SRA_R_PH_W: 14755 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14756 break; 14757 case OPC_PRECR_QB_PH: 14758 case OPC_PRECRQ_QB_PH: 14759 case OPC_PRECRQ_PH_W: 14760 case OPC_PRECRQ_RS_PH_W: 14761 case OPC_PRECRQU_S_QB_PH: 14762 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14763 break; 14764 case OPC_CMPU_EQ_QB: 14765 case OPC_CMPU_LT_QB: 14766 case OPC_CMPU_LE_QB: 14767 case OPC_CMP_EQ_PH: 14768 case OPC_CMP_LT_PH: 14769 case OPC_CMP_LE_PH: 14770 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14771 break; 14772 case OPC_CMPGU_EQ_QB: 14773 case OPC_CMPGU_LT_QB: 14774 case OPC_CMPGU_LE_QB: 14775 case OPC_CMPGDU_EQ_QB: 14776 case OPC_CMPGDU_LT_QB: 14777 case OPC_CMPGDU_LE_QB: 14778 case OPC_PICK_QB: 14779 case OPC_PICK_PH: 14780 case OPC_PACKRL_PH: 14781 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14782 break; 14783 default: /* Invalid */ 14784 MIPS_INVAL("MASK CMPU.EQ.QB"); 14785 gen_reserved_instruction(ctx); 14786 break; 14787 } 14788 break; 14789 case OPC_SHLL_QB_DSP: 14790 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14791 break; 14792 case OPC_DPA_W_PH_DSP: 14793 op2 = MASK_DPA_W_PH(ctx->opcode); 14794 switch (op2) { 14795 case OPC_DPAU_H_QBL: 14796 case OPC_DPAU_H_QBR: 14797 case OPC_DPSU_H_QBL: 14798 case OPC_DPSU_H_QBR: 14799 case OPC_DPA_W_PH: 14800 case OPC_DPAX_W_PH: 14801 case OPC_DPAQ_S_W_PH: 14802 case OPC_DPAQX_S_W_PH: 14803 case OPC_DPAQX_SA_W_PH: 14804 case OPC_DPS_W_PH: 14805 case OPC_DPSX_W_PH: 14806 case OPC_DPSQ_S_W_PH: 14807 case OPC_DPSQX_S_W_PH: 14808 case OPC_DPSQX_SA_W_PH: 14809 case OPC_MULSAQ_S_W_PH: 14810 case OPC_DPAQ_SA_L_W: 14811 case OPC_DPSQ_SA_L_W: 14812 case OPC_MAQ_S_W_PHL: 14813 case OPC_MAQ_S_W_PHR: 14814 case OPC_MAQ_SA_W_PHL: 14815 case OPC_MAQ_SA_W_PHR: 14816 case OPC_MULSA_W_PH: 14817 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14818 break; 14819 default: /* Invalid */ 14820 MIPS_INVAL("MASK DPAW.PH"); 14821 gen_reserved_instruction(ctx); 14822 break; 14823 } 14824 break; 14825 case OPC_INSV_DSP: 14826 op2 = MASK_INSV(ctx->opcode); 14827 switch (op2) { 14828 case OPC_INSV: 14829 check_dsp(ctx); 14830 { 14831 TCGv t0, t1; 14832 14833 if (rt == 0) { 14834 break; 14835 } 14836 14837 t0 = tcg_temp_new(); 14838 t1 = tcg_temp_new(); 14839 14840 gen_load_gpr(t0, rt); 14841 gen_load_gpr(t1, rs); 14842 14843 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14844 14845 tcg_temp_free(t0); 14846 tcg_temp_free(t1); 14847 break; 14848 } 14849 default: /* Invalid */ 14850 MIPS_INVAL("MASK INSV"); 14851 gen_reserved_instruction(ctx); 14852 break; 14853 } 14854 break; 14855 case OPC_APPEND_DSP: 14856 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14857 break; 14858 case OPC_EXTR_W_DSP: 14859 op2 = MASK_EXTR_W(ctx->opcode); 14860 switch (op2) { 14861 case OPC_EXTR_W: 14862 case OPC_EXTR_R_W: 14863 case OPC_EXTR_RS_W: 14864 case OPC_EXTR_S_H: 14865 case OPC_EXTRV_S_H: 14866 case OPC_EXTRV_W: 14867 case OPC_EXTRV_R_W: 14868 case OPC_EXTRV_RS_W: 14869 case OPC_EXTP: 14870 case OPC_EXTPV: 14871 case OPC_EXTPDP: 14872 case OPC_EXTPDPV: 14873 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14874 break; 14875 case OPC_RDDSP: 14876 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14877 break; 14878 case OPC_SHILO: 14879 case OPC_SHILOV: 14880 case OPC_MTHLIP: 14881 case OPC_WRDSP: 14882 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14883 break; 14884 default: /* Invalid */ 14885 MIPS_INVAL("MASK EXTR.W"); 14886 gen_reserved_instruction(ctx); 14887 break; 14888 } 14889 break; 14890 #if defined(TARGET_MIPS64) 14891 case OPC_DDIV_G_2E: 14892 case OPC_DDIVU_G_2E: 14893 case OPC_DMULT_G_2E: 14894 case OPC_DMULTU_G_2E: 14895 case OPC_DMOD_G_2E: 14896 case OPC_DMODU_G_2E: 14897 check_insn(ctx, INSN_LOONGSON2E); 14898 gen_loongson_integer(ctx, op1, rd, rs, rt); 14899 break; 14900 case OPC_ABSQ_S_QH_DSP: 14901 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14902 switch (op2) { 14903 case OPC_PRECEQ_L_PWL: 14904 case OPC_PRECEQ_L_PWR: 14905 case OPC_PRECEQ_PW_QHL: 14906 case OPC_PRECEQ_PW_QHR: 14907 case OPC_PRECEQ_PW_QHLA: 14908 case OPC_PRECEQ_PW_QHRA: 14909 case OPC_PRECEQU_QH_OBL: 14910 case OPC_PRECEQU_QH_OBR: 14911 case OPC_PRECEQU_QH_OBLA: 14912 case OPC_PRECEQU_QH_OBRA: 14913 case OPC_PRECEU_QH_OBL: 14914 case OPC_PRECEU_QH_OBR: 14915 case OPC_PRECEU_QH_OBLA: 14916 case OPC_PRECEU_QH_OBRA: 14917 case OPC_ABSQ_S_OB: 14918 case OPC_ABSQ_S_PW: 14919 case OPC_ABSQ_S_QH: 14920 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14921 break; 14922 case OPC_REPL_OB: 14923 case OPC_REPL_PW: 14924 case OPC_REPL_QH: 14925 case OPC_REPLV_OB: 14926 case OPC_REPLV_PW: 14927 case OPC_REPLV_QH: 14928 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14929 break; 14930 default: /* Invalid */ 14931 MIPS_INVAL("MASK ABSQ_S.QH"); 14932 gen_reserved_instruction(ctx); 14933 break; 14934 } 14935 break; 14936 case OPC_ADDU_OB_DSP: 14937 op2 = MASK_ADDU_OB(ctx->opcode); 14938 switch (op2) { 14939 case OPC_RADDU_L_OB: 14940 case OPC_SUBQ_PW: 14941 case OPC_SUBQ_S_PW: 14942 case OPC_SUBQ_QH: 14943 case OPC_SUBQ_S_QH: 14944 case OPC_SUBU_OB: 14945 case OPC_SUBU_S_OB: 14946 case OPC_SUBU_QH: 14947 case OPC_SUBU_S_QH: 14948 case OPC_SUBUH_OB: 14949 case OPC_SUBUH_R_OB: 14950 case OPC_ADDQ_PW: 14951 case OPC_ADDQ_S_PW: 14952 case OPC_ADDQ_QH: 14953 case OPC_ADDQ_S_QH: 14954 case OPC_ADDU_OB: 14955 case OPC_ADDU_S_OB: 14956 case OPC_ADDU_QH: 14957 case OPC_ADDU_S_QH: 14958 case OPC_ADDUH_OB: 14959 case OPC_ADDUH_R_OB: 14960 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14961 break; 14962 case OPC_MULEQ_S_PW_QHL: 14963 case OPC_MULEQ_S_PW_QHR: 14964 case OPC_MULEU_S_QH_OBL: 14965 case OPC_MULEU_S_QH_OBR: 14966 case OPC_MULQ_RS_QH: 14967 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14968 break; 14969 default: /* Invalid */ 14970 MIPS_INVAL("MASK ADDU.OB"); 14971 gen_reserved_instruction(ctx); 14972 break; 14973 } 14974 break; 14975 case OPC_CMPU_EQ_OB_DSP: 14976 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14977 switch (op2) { 14978 case OPC_PRECR_SRA_QH_PW: 14979 case OPC_PRECR_SRA_R_QH_PW: 14980 /* Return value is rt. */ 14981 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14982 break; 14983 case OPC_PRECR_OB_QH: 14984 case OPC_PRECRQ_OB_QH: 14985 case OPC_PRECRQ_PW_L: 14986 case OPC_PRECRQ_QH_PW: 14987 case OPC_PRECRQ_RS_QH_PW: 14988 case OPC_PRECRQU_S_OB_QH: 14989 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14990 break; 14991 case OPC_CMPU_EQ_OB: 14992 case OPC_CMPU_LT_OB: 14993 case OPC_CMPU_LE_OB: 14994 case OPC_CMP_EQ_QH: 14995 case OPC_CMP_LT_QH: 14996 case OPC_CMP_LE_QH: 14997 case OPC_CMP_EQ_PW: 14998 case OPC_CMP_LT_PW: 14999 case OPC_CMP_LE_PW: 15000 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 15001 break; 15002 case OPC_CMPGDU_EQ_OB: 15003 case OPC_CMPGDU_LT_OB: 15004 case OPC_CMPGDU_LE_OB: 15005 case OPC_CMPGU_EQ_OB: 15006 case OPC_CMPGU_LT_OB: 15007 case OPC_CMPGU_LE_OB: 15008 case OPC_PACKRL_PW: 15009 case OPC_PICK_OB: 15010 case OPC_PICK_PW: 15011 case OPC_PICK_QH: 15012 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 15013 break; 15014 default: /* Invalid */ 15015 MIPS_INVAL("MASK CMPU_EQ.OB"); 15016 gen_reserved_instruction(ctx); 15017 break; 15018 } 15019 break; 15020 case OPC_DAPPEND_DSP: 15021 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 15022 break; 15023 case OPC_DEXTR_W_DSP: 15024 op2 = MASK_DEXTR_W(ctx->opcode); 15025 switch (op2) { 15026 case OPC_DEXTP: 15027 case OPC_DEXTPDP: 15028 case OPC_DEXTPDPV: 15029 case OPC_DEXTPV: 15030 case OPC_DEXTR_L: 15031 case OPC_DEXTR_R_L: 15032 case OPC_DEXTR_RS_L: 15033 case OPC_DEXTR_W: 15034 case OPC_DEXTR_R_W: 15035 case OPC_DEXTR_RS_W: 15036 case OPC_DEXTR_S_H: 15037 case OPC_DEXTRV_L: 15038 case OPC_DEXTRV_R_L: 15039 case OPC_DEXTRV_RS_L: 15040 case OPC_DEXTRV_S_H: 15041 case OPC_DEXTRV_W: 15042 case OPC_DEXTRV_R_W: 15043 case OPC_DEXTRV_RS_W: 15044 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 15045 break; 15046 case OPC_DMTHLIP: 15047 case OPC_DSHILO: 15048 case OPC_DSHILOV: 15049 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 15050 break; 15051 default: /* Invalid */ 15052 MIPS_INVAL("MASK EXTR.W"); 15053 gen_reserved_instruction(ctx); 15054 break; 15055 } 15056 break; 15057 case OPC_DPAQ_W_QH_DSP: 15058 op2 = MASK_DPAQ_W_QH(ctx->opcode); 15059 switch (op2) { 15060 case OPC_DPAU_H_OBL: 15061 case OPC_DPAU_H_OBR: 15062 case OPC_DPSU_H_OBL: 15063 case OPC_DPSU_H_OBR: 15064 case OPC_DPA_W_QH: 15065 case OPC_DPAQ_S_W_QH: 15066 case OPC_DPS_W_QH: 15067 case OPC_DPSQ_S_W_QH: 15068 case OPC_MULSAQ_S_W_QH: 15069 case OPC_DPAQ_SA_L_PW: 15070 case OPC_DPSQ_SA_L_PW: 15071 case OPC_MULSAQ_S_L_PW: 15072 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15073 break; 15074 case OPC_MAQ_S_W_QHLL: 15075 case OPC_MAQ_S_W_QHLR: 15076 case OPC_MAQ_S_W_QHRL: 15077 case OPC_MAQ_S_W_QHRR: 15078 case OPC_MAQ_SA_W_QHLL: 15079 case OPC_MAQ_SA_W_QHLR: 15080 case OPC_MAQ_SA_W_QHRL: 15081 case OPC_MAQ_SA_W_QHRR: 15082 case OPC_MAQ_S_L_PWL: 15083 case OPC_MAQ_S_L_PWR: 15084 case OPC_DMADD: 15085 case OPC_DMADDU: 15086 case OPC_DMSUB: 15087 case OPC_DMSUBU: 15088 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15089 break; 15090 default: /* Invalid */ 15091 MIPS_INVAL("MASK DPAQ.W.QH"); 15092 gen_reserved_instruction(ctx); 15093 break; 15094 } 15095 break; 15096 case OPC_DINSV_DSP: 15097 op2 = MASK_INSV(ctx->opcode); 15098 switch (op2) { 15099 case OPC_DINSV: 15100 { 15101 TCGv t0, t1; 15102 15103 check_dsp(ctx); 15104 15105 if (rt == 0) { 15106 break; 15107 } 15108 15109 t0 = tcg_temp_new(); 15110 t1 = tcg_temp_new(); 15111 15112 gen_load_gpr(t0, rt); 15113 gen_load_gpr(t1, rs); 15114 15115 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 15116 15117 tcg_temp_free(t0); 15118 tcg_temp_free(t1); 15119 break; 15120 } 15121 default: /* Invalid */ 15122 MIPS_INVAL("MASK DINSV"); 15123 gen_reserved_instruction(ctx); 15124 break; 15125 } 15126 break; 15127 case OPC_SHLL_OB_DSP: 15128 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 15129 break; 15130 #endif 15131 default: /* Invalid */ 15132 MIPS_INVAL("special3_legacy"); 15133 gen_reserved_instruction(ctx); 15134 break; 15135 } 15136 } 15137 15138 15139 #if defined(TARGET_MIPS64) 15140 15141 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 15142 { 15143 uint32_t opc = MASK_MMI(ctx->opcode); 15144 int rs = extract32(ctx->opcode, 21, 5); 15145 int rt = extract32(ctx->opcode, 16, 5); 15146 int rd = extract32(ctx->opcode, 11, 5); 15147 15148 switch (opc) { 15149 case MMI_OPC_MULT1: 15150 case MMI_OPC_MULTU1: 15151 case MMI_OPC_MADD: 15152 case MMI_OPC_MADDU: 15153 case MMI_OPC_MADD1: 15154 case MMI_OPC_MADDU1: 15155 gen_mul_txx9(ctx, opc, rd, rs, rt); 15156 break; 15157 case MMI_OPC_DIV1: 15158 case MMI_OPC_DIVU1: 15159 gen_div1_tx79(ctx, opc, rs, rt); 15160 break; 15161 default: 15162 MIPS_INVAL("TX79 MMI class"); 15163 gen_reserved_instruction(ctx); 15164 break; 15165 } 15166 } 15167 15168 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 15169 { 15170 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 15171 } 15172 15173 /* 15174 * The TX79-specific instruction Store Quadword 15175 * 15176 * +--------+-------+-------+------------------------+ 15177 * | 011111 | base | rt | offset | SQ 15178 * +--------+-------+-------+------------------------+ 15179 * 6 5 5 16 15180 * 15181 * has the same opcode as the Read Hardware Register instruction 15182 * 15183 * +--------+-------+-------+-------+-------+--------+ 15184 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 15185 * +--------+-------+-------+-------+-------+--------+ 15186 * 6 5 5 5 5 6 15187 * 15188 * that is required, trapped and emulated by the Linux kernel. However, all 15189 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 15190 * offset is odd. Therefore all valid SQ instructions can execute normally. 15191 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 15192 * between SQ and RDHWR, as the Linux kernel does. 15193 */ 15194 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 15195 { 15196 int base = extract32(ctx->opcode, 21, 5); 15197 int rt = extract32(ctx->opcode, 16, 5); 15198 int offset = extract32(ctx->opcode, 0, 16); 15199 15200 #ifdef CONFIG_USER_ONLY 15201 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 15202 uint32_t op2 = extract32(ctx->opcode, 6, 5); 15203 15204 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 15205 int rd = extract32(ctx->opcode, 11, 5); 15206 15207 gen_rdhwr(ctx, rt, rd, 0); 15208 return; 15209 } 15210 #endif 15211 15212 gen_mmi_sq(ctx, base, rt, offset); 15213 } 15214 15215 #endif 15216 15217 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 15218 { 15219 int rs, rt, rd, sa; 15220 uint32_t op1, op2; 15221 int16_t imm; 15222 15223 rs = (ctx->opcode >> 21) & 0x1f; 15224 rt = (ctx->opcode >> 16) & 0x1f; 15225 rd = (ctx->opcode >> 11) & 0x1f; 15226 sa = (ctx->opcode >> 6) & 0x1f; 15227 imm = sextract32(ctx->opcode, 7, 9); 15228 15229 op1 = MASK_SPECIAL3(ctx->opcode); 15230 15231 /* 15232 * EVA loads and stores overlap Loongson 2E instructions decoded by 15233 * decode_opc_special3_legacy(), so be careful to allow their decoding when 15234 * EVA is absent. 15235 */ 15236 if (ctx->eva) { 15237 switch (op1) { 15238 case OPC_LWLE: 15239 case OPC_LWRE: 15240 case OPC_LBUE: 15241 case OPC_LHUE: 15242 case OPC_LBE: 15243 case OPC_LHE: 15244 case OPC_LLE: 15245 case OPC_LWE: 15246 check_cp0_enabled(ctx); 15247 gen_ld(ctx, op1, rt, rs, imm); 15248 return; 15249 case OPC_SWLE: 15250 case OPC_SWRE: 15251 case OPC_SBE: 15252 case OPC_SHE: 15253 case OPC_SWE: 15254 check_cp0_enabled(ctx); 15255 gen_st(ctx, op1, rt, rs, imm); 15256 return; 15257 case OPC_SCE: 15258 check_cp0_enabled(ctx); 15259 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 15260 return; 15261 case OPC_CACHEE: 15262 check_eva(ctx); 15263 check_cp0_enabled(ctx); 15264 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15265 gen_cache_operation(ctx, rt, rs, imm); 15266 } 15267 return; 15268 case OPC_PREFE: 15269 check_cp0_enabled(ctx); 15270 /* Treat as NOP. */ 15271 return; 15272 } 15273 } 15274 15275 switch (op1) { 15276 case OPC_EXT: 15277 case OPC_INS: 15278 check_insn(ctx, ISA_MIPS_R2); 15279 gen_bitops(ctx, op1, rt, rs, sa, rd); 15280 break; 15281 case OPC_BSHFL: 15282 op2 = MASK_BSHFL(ctx->opcode); 15283 switch (op2) { 15284 case OPC_ALIGN: 15285 case OPC_ALIGN_1: 15286 case OPC_ALIGN_2: 15287 case OPC_ALIGN_3: 15288 case OPC_BITSWAP: 15289 check_insn(ctx, ISA_MIPS_R6); 15290 decode_opc_special3_r6(env, ctx); 15291 break; 15292 default: 15293 check_insn(ctx, ISA_MIPS_R2); 15294 gen_bshfl(ctx, op2, rt, rd); 15295 break; 15296 } 15297 break; 15298 #if defined(TARGET_MIPS64) 15299 case OPC_DEXTM: 15300 case OPC_DEXTU: 15301 case OPC_DEXT: 15302 case OPC_DINSM: 15303 case OPC_DINSU: 15304 case OPC_DINS: 15305 check_insn(ctx, ISA_MIPS_R2); 15306 check_mips_64(ctx); 15307 gen_bitops(ctx, op1, rt, rs, sa, rd); 15308 break; 15309 case OPC_DBSHFL: 15310 op2 = MASK_DBSHFL(ctx->opcode); 15311 switch (op2) { 15312 case OPC_DALIGN: 15313 case OPC_DALIGN_1: 15314 case OPC_DALIGN_2: 15315 case OPC_DALIGN_3: 15316 case OPC_DALIGN_4: 15317 case OPC_DALIGN_5: 15318 case OPC_DALIGN_6: 15319 case OPC_DALIGN_7: 15320 case OPC_DBITSWAP: 15321 check_insn(ctx, ISA_MIPS_R6); 15322 decode_opc_special3_r6(env, ctx); 15323 break; 15324 default: 15325 check_insn(ctx, ISA_MIPS_R2); 15326 check_mips_64(ctx); 15327 op2 = MASK_DBSHFL(ctx->opcode); 15328 gen_bshfl(ctx, op2, rt, rd); 15329 break; 15330 } 15331 break; 15332 #endif 15333 case OPC_RDHWR: 15334 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 15335 break; 15336 case OPC_FORK: 15337 check_mt(ctx); 15338 { 15339 TCGv t0 = tcg_temp_new(); 15340 TCGv t1 = tcg_temp_new(); 15341 15342 gen_load_gpr(t0, rt); 15343 gen_load_gpr(t1, rs); 15344 gen_helper_fork(t0, t1); 15345 tcg_temp_free(t0); 15346 tcg_temp_free(t1); 15347 } 15348 break; 15349 case OPC_YIELD: 15350 check_mt(ctx); 15351 { 15352 TCGv t0 = tcg_temp_new(); 15353 15354 gen_load_gpr(t0, rs); 15355 gen_helper_yield(t0, cpu_env, t0); 15356 gen_store_gpr(t0, rd); 15357 tcg_temp_free(t0); 15358 } 15359 break; 15360 default: 15361 if (ctx->insn_flags & ISA_MIPS_R6) { 15362 decode_opc_special3_r6(env, ctx); 15363 } else { 15364 decode_opc_special3_legacy(env, ctx); 15365 } 15366 } 15367 } 15368 15369 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 15370 { 15371 int32_t offset; 15372 int rs, rt, rd, sa; 15373 uint32_t op, op1; 15374 int16_t imm; 15375 15376 op = MASK_OP_MAJOR(ctx->opcode); 15377 rs = (ctx->opcode >> 21) & 0x1f; 15378 rt = (ctx->opcode >> 16) & 0x1f; 15379 rd = (ctx->opcode >> 11) & 0x1f; 15380 sa = (ctx->opcode >> 6) & 0x1f; 15381 imm = (int16_t)ctx->opcode; 15382 switch (op) { 15383 case OPC_SPECIAL: 15384 decode_opc_special(env, ctx); 15385 break; 15386 case OPC_SPECIAL2: 15387 #if defined(TARGET_MIPS64) 15388 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 15389 decode_mmi(env, ctx); 15390 break; 15391 } 15392 #endif 15393 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 15394 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 15395 gen_arith(ctx, OPC_MUL, rd, rs, rt); 15396 } else { 15397 decode_ase_mxu(ctx, ctx->opcode); 15398 } 15399 break; 15400 } 15401 decode_opc_special2_legacy(env, ctx); 15402 break; 15403 case OPC_SPECIAL3: 15404 #if defined(TARGET_MIPS64) 15405 if (ctx->insn_flags & INSN_R5900) { 15406 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 15407 } else { 15408 decode_opc_special3(env, ctx); 15409 } 15410 #else 15411 decode_opc_special3(env, ctx); 15412 #endif 15413 break; 15414 case OPC_REGIMM: 15415 op1 = MASK_REGIMM(ctx->opcode); 15416 switch (op1) { 15417 case OPC_BLTZL: /* REGIMM branches */ 15418 case OPC_BGEZL: 15419 case OPC_BLTZALL: 15420 case OPC_BGEZALL: 15421 check_insn(ctx, ISA_MIPS2); 15422 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15423 /* Fallthrough */ 15424 case OPC_BLTZ: 15425 case OPC_BGEZ: 15426 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15427 break; 15428 case OPC_BLTZAL: 15429 case OPC_BGEZAL: 15430 if (ctx->insn_flags & ISA_MIPS_R6) { 15431 if (rs == 0) { 15432 /* OPC_NAL, OPC_BAL */ 15433 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 15434 } else { 15435 gen_reserved_instruction(ctx); 15436 } 15437 } else { 15438 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15439 } 15440 break; 15441 case OPC_TGEI: /* REGIMM traps */ 15442 case OPC_TGEIU: 15443 case OPC_TLTI: 15444 case OPC_TLTIU: 15445 case OPC_TEQI: 15446 15447 case OPC_TNEI: 15448 check_insn(ctx, ISA_MIPS2); 15449 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15450 gen_trap(ctx, op1, rs, -1, imm); 15451 break; 15452 case OPC_SIGRIE: 15453 check_insn(ctx, ISA_MIPS_R6); 15454 gen_reserved_instruction(ctx); 15455 break; 15456 case OPC_SYNCI: 15457 check_insn(ctx, ISA_MIPS_R2); 15458 /* 15459 * Break the TB to be able to sync copied instructions 15460 * immediately. 15461 */ 15462 ctx->base.is_jmp = DISAS_STOP; 15463 break; 15464 case OPC_BPOSGE32: /* MIPS DSP branch */ 15465 #if defined(TARGET_MIPS64) 15466 case OPC_BPOSGE64: 15467 #endif 15468 check_dsp(ctx); 15469 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 15470 break; 15471 #if defined(TARGET_MIPS64) 15472 case OPC_DAHI: 15473 check_insn(ctx, ISA_MIPS_R6); 15474 check_mips_64(ctx); 15475 if (rs != 0) { 15476 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 15477 } 15478 break; 15479 case OPC_DATI: 15480 check_insn(ctx, ISA_MIPS_R6); 15481 check_mips_64(ctx); 15482 if (rs != 0) { 15483 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 15484 } 15485 break; 15486 #endif 15487 default: /* Invalid */ 15488 MIPS_INVAL("regimm"); 15489 gen_reserved_instruction(ctx); 15490 break; 15491 } 15492 break; 15493 case OPC_CP0: 15494 check_cp0_enabled(ctx); 15495 op1 = MASK_CP0(ctx->opcode); 15496 switch (op1) { 15497 case OPC_MFC0: 15498 case OPC_MTC0: 15499 case OPC_MFTR: 15500 case OPC_MTTR: 15501 case OPC_MFHC0: 15502 case OPC_MTHC0: 15503 #if defined(TARGET_MIPS64) 15504 case OPC_DMFC0: 15505 case OPC_DMTC0: 15506 #endif 15507 #ifndef CONFIG_USER_ONLY 15508 gen_cp0(env, ctx, op1, rt, rd); 15509 #endif /* !CONFIG_USER_ONLY */ 15510 break; 15511 case OPC_C0: 15512 case OPC_C0_1: 15513 case OPC_C0_2: 15514 case OPC_C0_3: 15515 case OPC_C0_4: 15516 case OPC_C0_5: 15517 case OPC_C0_6: 15518 case OPC_C0_7: 15519 case OPC_C0_8: 15520 case OPC_C0_9: 15521 case OPC_C0_A: 15522 case OPC_C0_B: 15523 case OPC_C0_C: 15524 case OPC_C0_D: 15525 case OPC_C0_E: 15526 case OPC_C0_F: 15527 #ifndef CONFIG_USER_ONLY 15528 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 15529 #endif /* !CONFIG_USER_ONLY */ 15530 break; 15531 case OPC_MFMC0: 15532 #ifndef CONFIG_USER_ONLY 15533 { 15534 uint32_t op2; 15535 TCGv t0 = tcg_temp_new(); 15536 15537 op2 = MASK_MFMC0(ctx->opcode); 15538 switch (op2) { 15539 case OPC_DMT: 15540 check_cp0_mt(ctx); 15541 gen_helper_dmt(t0); 15542 gen_store_gpr(t0, rt); 15543 break; 15544 case OPC_EMT: 15545 check_cp0_mt(ctx); 15546 gen_helper_emt(t0); 15547 gen_store_gpr(t0, rt); 15548 break; 15549 case OPC_DVPE: 15550 check_cp0_mt(ctx); 15551 gen_helper_dvpe(t0, cpu_env); 15552 gen_store_gpr(t0, rt); 15553 break; 15554 case OPC_EVPE: 15555 check_cp0_mt(ctx); 15556 gen_helper_evpe(t0, cpu_env); 15557 gen_store_gpr(t0, rt); 15558 break; 15559 case OPC_DVP: 15560 check_insn(ctx, ISA_MIPS_R6); 15561 if (ctx->vp) { 15562 gen_helper_dvp(t0, cpu_env); 15563 gen_store_gpr(t0, rt); 15564 } 15565 break; 15566 case OPC_EVP: 15567 check_insn(ctx, ISA_MIPS_R6); 15568 if (ctx->vp) { 15569 gen_helper_evp(t0, cpu_env); 15570 gen_store_gpr(t0, rt); 15571 } 15572 break; 15573 case OPC_DI: 15574 check_insn(ctx, ISA_MIPS_R2); 15575 save_cpu_state(ctx, 1); 15576 gen_helper_di(t0, cpu_env); 15577 gen_store_gpr(t0, rt); 15578 /* 15579 * Stop translation as we may have switched 15580 * the execution mode. 15581 */ 15582 ctx->base.is_jmp = DISAS_STOP; 15583 break; 15584 case OPC_EI: 15585 check_insn(ctx, ISA_MIPS_R2); 15586 save_cpu_state(ctx, 1); 15587 gen_helper_ei(t0, cpu_env); 15588 gen_store_gpr(t0, rt); 15589 /* 15590 * DISAS_STOP isn't sufficient, we need to ensure we break 15591 * out of translated code to check for pending interrupts. 15592 */ 15593 gen_save_pc(ctx->base.pc_next + 4); 15594 ctx->base.is_jmp = DISAS_EXIT; 15595 break; 15596 default: /* Invalid */ 15597 MIPS_INVAL("mfmc0"); 15598 gen_reserved_instruction(ctx); 15599 break; 15600 } 15601 tcg_temp_free(t0); 15602 } 15603 #endif /* !CONFIG_USER_ONLY */ 15604 break; 15605 case OPC_RDPGPR: 15606 check_insn(ctx, ISA_MIPS_R2); 15607 gen_load_srsgpr(rt, rd); 15608 break; 15609 case OPC_WRPGPR: 15610 check_insn(ctx, ISA_MIPS_R2); 15611 gen_store_srsgpr(rt, rd); 15612 break; 15613 default: 15614 MIPS_INVAL("cp0"); 15615 gen_reserved_instruction(ctx); 15616 break; 15617 } 15618 break; 15619 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 15620 if (ctx->insn_flags & ISA_MIPS_R6) { 15621 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 15622 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15623 } else { 15624 /* OPC_ADDI */ 15625 /* Arithmetic with immediate opcode */ 15626 gen_arith_imm(ctx, op, rt, rs, imm); 15627 } 15628 break; 15629 case OPC_ADDIU: 15630 gen_arith_imm(ctx, op, rt, rs, imm); 15631 break; 15632 case OPC_SLTI: /* Set on less than with immediate opcode */ 15633 case OPC_SLTIU: 15634 gen_slt_imm(ctx, op, rt, rs, imm); 15635 break; 15636 case OPC_ANDI: /* Arithmetic with immediate opcode */ 15637 case OPC_LUI: /* OPC_AUI */ 15638 case OPC_ORI: 15639 case OPC_XORI: 15640 gen_logic_imm(ctx, op, rt, rs, imm); 15641 break; 15642 case OPC_J: /* Jump */ 15643 case OPC_JAL: 15644 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15645 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15646 break; 15647 /* Branch */ 15648 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 15649 if (ctx->insn_flags & ISA_MIPS_R6) { 15650 if (rt == 0) { 15651 gen_reserved_instruction(ctx); 15652 break; 15653 } 15654 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 15655 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15656 } else { 15657 /* OPC_BLEZL */ 15658 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15659 } 15660 break; 15661 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 15662 if (ctx->insn_flags & ISA_MIPS_R6) { 15663 if (rt == 0) { 15664 gen_reserved_instruction(ctx); 15665 break; 15666 } 15667 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 15668 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15669 } else { 15670 /* OPC_BGTZL */ 15671 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15672 } 15673 break; 15674 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 15675 if (rt == 0) { 15676 /* OPC_BLEZ */ 15677 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15678 } else { 15679 check_insn(ctx, ISA_MIPS_R6); 15680 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 15681 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15682 } 15683 break; 15684 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 15685 if (rt == 0) { 15686 /* OPC_BGTZ */ 15687 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15688 } else { 15689 check_insn(ctx, ISA_MIPS_R6); 15690 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 15691 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15692 } 15693 break; 15694 case OPC_BEQL: 15695 case OPC_BNEL: 15696 check_insn(ctx, ISA_MIPS2); 15697 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15698 /* Fallthrough */ 15699 case OPC_BEQ: 15700 case OPC_BNE: 15701 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15702 break; 15703 case OPC_LL: /* Load and stores */ 15704 check_insn(ctx, ISA_MIPS2); 15705 if (ctx->insn_flags & INSN_R5900) { 15706 check_insn_opc_user_only(ctx, INSN_R5900); 15707 } 15708 /* Fallthrough */ 15709 case OPC_LWL: 15710 case OPC_LWR: 15711 case OPC_LB: 15712 case OPC_LH: 15713 case OPC_LW: 15714 case OPC_LWPC: 15715 case OPC_LBU: 15716 case OPC_LHU: 15717 gen_ld(ctx, op, rt, rs, imm); 15718 break; 15719 case OPC_SWL: 15720 case OPC_SWR: 15721 case OPC_SB: 15722 case OPC_SH: 15723 case OPC_SW: 15724 gen_st(ctx, op, rt, rs, imm); 15725 break; 15726 case OPC_SC: 15727 check_insn(ctx, ISA_MIPS2); 15728 if (ctx->insn_flags & INSN_R5900) { 15729 check_insn_opc_user_only(ctx, INSN_R5900); 15730 } 15731 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 15732 break; 15733 case OPC_CACHE: 15734 check_cp0_enabled(ctx); 15735 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 15736 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15737 gen_cache_operation(ctx, rt, rs, imm); 15738 } 15739 /* Treat as NOP. */ 15740 break; 15741 case OPC_PREF: 15742 if (ctx->insn_flags & INSN_R5900) { 15743 /* Treat as NOP. */ 15744 } else { 15745 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 15746 /* Treat as NOP. */ 15747 } 15748 break; 15749 15750 /* Floating point (COP1). */ 15751 case OPC_LWC1: 15752 case OPC_LDC1: 15753 case OPC_SWC1: 15754 case OPC_SDC1: 15755 gen_cop1_ldst(ctx, op, rt, rs, imm); 15756 break; 15757 15758 case OPC_CP1: 15759 op1 = MASK_CP1(ctx->opcode); 15760 15761 switch (op1) { 15762 case OPC_MFHC1: 15763 case OPC_MTHC1: 15764 check_cp1_enabled(ctx); 15765 check_insn(ctx, ISA_MIPS_R2); 15766 /* fall through */ 15767 case OPC_MFC1: 15768 case OPC_CFC1: 15769 case OPC_MTC1: 15770 case OPC_CTC1: 15771 check_cp1_enabled(ctx); 15772 gen_cp1(ctx, op1, rt, rd); 15773 break; 15774 #if defined(TARGET_MIPS64) 15775 case OPC_DMFC1: 15776 case OPC_DMTC1: 15777 check_cp1_enabled(ctx); 15778 check_insn(ctx, ISA_MIPS3); 15779 check_mips_64(ctx); 15780 gen_cp1(ctx, op1, rt, rd); 15781 break; 15782 #endif 15783 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15784 check_cp1_enabled(ctx); 15785 if (ctx->insn_flags & ISA_MIPS_R6) { 15786 /* OPC_BC1EQZ */ 15787 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15788 rt, imm << 2, 4); 15789 } else { 15790 /* OPC_BC1ANY2 */ 15791 check_cop1x(ctx); 15792 check_insn(ctx, ASE_MIPS3D); 15793 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15794 (rt >> 2) & 0x7, imm << 2); 15795 } 15796 break; 15797 case OPC_BC1NEZ: 15798 check_cp1_enabled(ctx); 15799 check_insn(ctx, ISA_MIPS_R6); 15800 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15801 rt, imm << 2, 4); 15802 break; 15803 case OPC_BC1ANY4: 15804 check_cp1_enabled(ctx); 15805 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15806 check_cop1x(ctx); 15807 check_insn(ctx, ASE_MIPS3D); 15808 /* fall through */ 15809 case OPC_BC1: 15810 check_cp1_enabled(ctx); 15811 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15812 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15813 (rt >> 2) & 0x7, imm << 2); 15814 break; 15815 case OPC_PS_FMT: 15816 check_ps(ctx); 15817 /* fall through */ 15818 case OPC_S_FMT: 15819 case OPC_D_FMT: 15820 check_cp1_enabled(ctx); 15821 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15822 (imm >> 8) & 0x7); 15823 break; 15824 case OPC_W_FMT: 15825 case OPC_L_FMT: 15826 { 15827 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15828 check_cp1_enabled(ctx); 15829 if (ctx->insn_flags & ISA_MIPS_R6) { 15830 switch (r6_op) { 15831 case R6_OPC_CMP_AF_S: 15832 case R6_OPC_CMP_UN_S: 15833 case R6_OPC_CMP_EQ_S: 15834 case R6_OPC_CMP_UEQ_S: 15835 case R6_OPC_CMP_LT_S: 15836 case R6_OPC_CMP_ULT_S: 15837 case R6_OPC_CMP_LE_S: 15838 case R6_OPC_CMP_ULE_S: 15839 case R6_OPC_CMP_SAF_S: 15840 case R6_OPC_CMP_SUN_S: 15841 case R6_OPC_CMP_SEQ_S: 15842 case R6_OPC_CMP_SEUQ_S: 15843 case R6_OPC_CMP_SLT_S: 15844 case R6_OPC_CMP_SULT_S: 15845 case R6_OPC_CMP_SLE_S: 15846 case R6_OPC_CMP_SULE_S: 15847 case R6_OPC_CMP_OR_S: 15848 case R6_OPC_CMP_UNE_S: 15849 case R6_OPC_CMP_NE_S: 15850 case R6_OPC_CMP_SOR_S: 15851 case R6_OPC_CMP_SUNE_S: 15852 case R6_OPC_CMP_SNE_S: 15853 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15854 break; 15855 case R6_OPC_CMP_AF_D: 15856 case R6_OPC_CMP_UN_D: 15857 case R6_OPC_CMP_EQ_D: 15858 case R6_OPC_CMP_UEQ_D: 15859 case R6_OPC_CMP_LT_D: 15860 case R6_OPC_CMP_ULT_D: 15861 case R6_OPC_CMP_LE_D: 15862 case R6_OPC_CMP_ULE_D: 15863 case R6_OPC_CMP_SAF_D: 15864 case R6_OPC_CMP_SUN_D: 15865 case R6_OPC_CMP_SEQ_D: 15866 case R6_OPC_CMP_SEUQ_D: 15867 case R6_OPC_CMP_SLT_D: 15868 case R6_OPC_CMP_SULT_D: 15869 case R6_OPC_CMP_SLE_D: 15870 case R6_OPC_CMP_SULE_D: 15871 case R6_OPC_CMP_OR_D: 15872 case R6_OPC_CMP_UNE_D: 15873 case R6_OPC_CMP_NE_D: 15874 case R6_OPC_CMP_SOR_D: 15875 case R6_OPC_CMP_SUNE_D: 15876 case R6_OPC_CMP_SNE_D: 15877 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15878 break; 15879 default: 15880 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15881 rt, rd, sa, (imm >> 8) & 0x7); 15882 15883 break; 15884 } 15885 } else { 15886 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15887 (imm >> 8) & 0x7); 15888 } 15889 break; 15890 } 15891 default: 15892 MIPS_INVAL("cp1"); 15893 gen_reserved_instruction(ctx); 15894 break; 15895 } 15896 break; 15897 15898 /* Compact branches [R6] and COP2 [non-R6] */ 15899 case OPC_BC: /* OPC_LWC2 */ 15900 case OPC_BALC: /* OPC_SWC2 */ 15901 if (ctx->insn_flags & ISA_MIPS_R6) { 15902 /* OPC_BC, OPC_BALC */ 15903 gen_compute_compact_branch(ctx, op, 0, 0, 15904 sextract32(ctx->opcode << 2, 0, 28)); 15905 } else if (ctx->insn_flags & ASE_LEXT) { 15906 gen_loongson_lswc2(ctx, rt, rs, rd); 15907 } else { 15908 /* OPC_LWC2, OPC_SWC2 */ 15909 /* COP2: Not implemented. */ 15910 generate_exception_err(ctx, EXCP_CpU, 2); 15911 } 15912 break; 15913 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15914 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15915 if (ctx->insn_flags & ISA_MIPS_R6) { 15916 if (rs != 0) { 15917 /* OPC_BEQZC, OPC_BNEZC */ 15918 gen_compute_compact_branch(ctx, op, rs, 0, 15919 sextract32(ctx->opcode << 2, 0, 23)); 15920 } else { 15921 /* OPC_JIC, OPC_JIALC */ 15922 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15923 } 15924 } else if (ctx->insn_flags & ASE_LEXT) { 15925 gen_loongson_lsdc2(ctx, rt, rs, rd); 15926 } else { 15927 /* OPC_LWC2, OPC_SWC2 */ 15928 /* COP2: Not implemented. */ 15929 generate_exception_err(ctx, EXCP_CpU, 2); 15930 } 15931 break; 15932 case OPC_CP2: 15933 check_insn(ctx, ASE_LMMI); 15934 /* Note that these instructions use different fields. */ 15935 gen_loongson_multimedia(ctx, sa, rd, rt); 15936 break; 15937 15938 case OPC_CP3: 15939 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15940 check_cp1_enabled(ctx); 15941 op1 = MASK_CP3(ctx->opcode); 15942 switch (op1) { 15943 case OPC_LUXC1: 15944 case OPC_SUXC1: 15945 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15946 /* Fallthrough */ 15947 case OPC_LWXC1: 15948 case OPC_LDXC1: 15949 case OPC_SWXC1: 15950 case OPC_SDXC1: 15951 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15952 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15953 break; 15954 case OPC_PREFX: 15955 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15956 /* Treat as NOP. */ 15957 break; 15958 case OPC_ALNV_PS: 15959 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15960 /* Fallthrough */ 15961 case OPC_MADD_S: 15962 case OPC_MADD_D: 15963 case OPC_MADD_PS: 15964 case OPC_MSUB_S: 15965 case OPC_MSUB_D: 15966 case OPC_MSUB_PS: 15967 case OPC_NMADD_S: 15968 case OPC_NMADD_D: 15969 case OPC_NMADD_PS: 15970 case OPC_NMSUB_S: 15971 case OPC_NMSUB_D: 15972 case OPC_NMSUB_PS: 15973 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15974 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15975 break; 15976 default: 15977 MIPS_INVAL("cp3"); 15978 gen_reserved_instruction(ctx); 15979 break; 15980 } 15981 } else { 15982 generate_exception_err(ctx, EXCP_CpU, 1); 15983 } 15984 break; 15985 15986 #if defined(TARGET_MIPS64) 15987 /* MIPS64 opcodes */ 15988 case OPC_LLD: 15989 if (ctx->insn_flags & INSN_R5900) { 15990 check_insn_opc_user_only(ctx, INSN_R5900); 15991 } 15992 /* fall through */ 15993 case OPC_LDL: 15994 case OPC_LDR: 15995 case OPC_LWU: 15996 case OPC_LD: 15997 check_insn(ctx, ISA_MIPS3); 15998 check_mips_64(ctx); 15999 gen_ld(ctx, op, rt, rs, imm); 16000 break; 16001 case OPC_SDL: 16002 case OPC_SDR: 16003 case OPC_SD: 16004 check_insn(ctx, ISA_MIPS3); 16005 check_mips_64(ctx); 16006 gen_st(ctx, op, rt, rs, imm); 16007 break; 16008 case OPC_SCD: 16009 check_insn(ctx, ISA_MIPS3); 16010 if (ctx->insn_flags & INSN_R5900) { 16011 check_insn_opc_user_only(ctx, INSN_R5900); 16012 } 16013 check_mips_64(ctx); 16014 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 16015 break; 16016 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 16017 if (ctx->insn_flags & ISA_MIPS_R6) { 16018 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 16019 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16020 } else { 16021 /* OPC_DADDI */ 16022 check_insn(ctx, ISA_MIPS3); 16023 check_mips_64(ctx); 16024 gen_arith_imm(ctx, op, rt, rs, imm); 16025 } 16026 break; 16027 case OPC_DADDIU: 16028 check_insn(ctx, ISA_MIPS3); 16029 check_mips_64(ctx); 16030 gen_arith_imm(ctx, op, rt, rs, imm); 16031 break; 16032 #else 16033 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 16034 if (ctx->insn_flags & ISA_MIPS_R6) { 16035 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16036 } else { 16037 MIPS_INVAL("major opcode"); 16038 gen_reserved_instruction(ctx); 16039 } 16040 break; 16041 #endif 16042 case OPC_DAUI: /* OPC_JALX */ 16043 if (ctx->insn_flags & ISA_MIPS_R6) { 16044 #if defined(TARGET_MIPS64) 16045 /* OPC_DAUI */ 16046 check_mips_64(ctx); 16047 if (rs == 0) { 16048 generate_exception(ctx, EXCP_RI); 16049 } else if (rt != 0) { 16050 TCGv t0 = tcg_temp_new(); 16051 gen_load_gpr(t0, rs); 16052 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 16053 tcg_temp_free(t0); 16054 } 16055 #else 16056 gen_reserved_instruction(ctx); 16057 MIPS_INVAL("major opcode"); 16058 #endif 16059 } else { 16060 /* OPC_JALX */ 16061 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 16062 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 16063 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 16064 } 16065 break; 16066 case OPC_MDMX: 16067 /* MDMX: Not implemented. */ 16068 break; 16069 case OPC_PCREL: 16070 check_insn(ctx, ISA_MIPS_R6); 16071 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 16072 break; 16073 default: /* Invalid */ 16074 MIPS_INVAL("major opcode"); 16075 return false; 16076 } 16077 return true; 16078 } 16079 16080 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 16081 { 16082 /* make sure instructions are on a word boundary */ 16083 if (ctx->base.pc_next & 0x3) { 16084 env->CP0_BadVAddr = ctx->base.pc_next; 16085 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 16086 return; 16087 } 16088 16089 /* Handle blikely not taken case */ 16090 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 16091 TCGLabel *l1 = gen_new_label(); 16092 16093 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 16094 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 16095 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 16096 gen_set_label(l1); 16097 } 16098 16099 /* Transition to the auto-generated decoder. */ 16100 16101 /* ISA extensions */ 16102 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 16103 return; 16104 } 16105 16106 /* ISA (from latest to oldest) */ 16107 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 16108 return; 16109 } 16110 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 16111 return; 16112 } 16113 16114 if (decode_opc_legacy(env, ctx)) { 16115 return; 16116 } 16117 16118 gen_reserved_instruction(ctx); 16119 } 16120 16121 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 16122 { 16123 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16124 CPUMIPSState *env = cs->env_ptr; 16125 16126 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 16127 ctx->saved_pc = -1; 16128 ctx->insn_flags = env->insn_flags; 16129 ctx->CP0_Config1 = env->CP0_Config1; 16130 ctx->CP0_Config2 = env->CP0_Config2; 16131 ctx->CP0_Config3 = env->CP0_Config3; 16132 ctx->CP0_Config5 = env->CP0_Config5; 16133 ctx->btarget = 0; 16134 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 16135 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 16136 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 16137 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 16138 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 16139 ctx->PAMask = env->PAMask; 16140 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 16141 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 16142 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 16143 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 16144 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 16145 /* Restore delay slot state from the tb context. */ 16146 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 16147 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 16148 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 16149 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 16150 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 16151 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 16152 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 16153 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 16154 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 16155 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 16156 restore_cpu_state(env, ctx); 16157 #ifdef CONFIG_USER_ONLY 16158 ctx->mem_idx = MIPS_HFLAG_UM; 16159 #else 16160 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 16161 #endif 16162 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 | 16163 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; 16164 16165 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 16166 ctx->hflags); 16167 } 16168 16169 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 16170 { 16171 } 16172 16173 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 16174 { 16175 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16176 16177 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 16178 ctx->btarget); 16179 } 16180 16181 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 16182 { 16183 CPUMIPSState *env = cs->env_ptr; 16184 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16185 int insn_bytes; 16186 int is_slot; 16187 16188 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 16189 if (ctx->insn_flags & ISA_NANOMIPS32) { 16190 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16191 insn_bytes = decode_isa_nanomips(env, ctx); 16192 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 16193 ctx->opcode = translator_ldl(env, ctx->base.pc_next); 16194 insn_bytes = 4; 16195 decode_opc(env, ctx); 16196 } else if (ctx->insn_flags & ASE_MICROMIPS) { 16197 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16198 insn_bytes = decode_isa_micromips(env, ctx); 16199 } else if (ctx->insn_flags & ASE_MIPS16) { 16200 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16201 insn_bytes = decode_ase_mips16e(env, ctx); 16202 } else { 16203 gen_reserved_instruction(ctx); 16204 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 16205 return; 16206 } 16207 16208 if (ctx->hflags & MIPS_HFLAG_BMASK) { 16209 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 16210 MIPS_HFLAG_FBNSLOT))) { 16211 /* 16212 * Force to generate branch as there is neither delay nor 16213 * forbidden slot. 16214 */ 16215 is_slot = 1; 16216 } 16217 if ((ctx->hflags & MIPS_HFLAG_M16) && 16218 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 16219 /* 16220 * Force to generate branch as microMIPS R6 doesn't restrict 16221 * branches in the forbidden slot. 16222 */ 16223 is_slot = 1; 16224 } 16225 } 16226 if (is_slot) { 16227 gen_branch(ctx, insn_bytes); 16228 } 16229 ctx->base.pc_next += insn_bytes; 16230 16231 if (ctx->base.is_jmp != DISAS_NEXT) { 16232 return; 16233 } 16234 /* 16235 * Execute a branch and its delay slot as a single instruction. 16236 * This is what GDB expects and is consistent with what the 16237 * hardware does (e.g. if a delay slot instruction faults, the 16238 * reported PC is the PC of the branch). 16239 */ 16240 if (ctx->base.singlestep_enabled && 16241 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) { 16242 ctx->base.is_jmp = DISAS_TOO_MANY; 16243 } 16244 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) { 16245 ctx->base.is_jmp = DISAS_TOO_MANY; 16246 } 16247 } 16248 16249 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 16250 { 16251 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16252 16253 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { 16254 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); 16255 gen_helper_raise_exception_debug(cpu_env); 16256 } else { 16257 switch (ctx->base.is_jmp) { 16258 case DISAS_STOP: 16259 gen_save_pc(ctx->base.pc_next); 16260 tcg_gen_lookup_and_goto_ptr(); 16261 break; 16262 case DISAS_NEXT: 16263 case DISAS_TOO_MANY: 16264 save_cpu_state(ctx, 0); 16265 gen_goto_tb(ctx, 0, ctx->base.pc_next); 16266 break; 16267 case DISAS_EXIT: 16268 tcg_gen_exit_tb(NULL, 0); 16269 break; 16270 case DISAS_NORETURN: 16271 break; 16272 default: 16273 g_assert_not_reached(); 16274 } 16275 } 16276 } 16277 16278 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 16279 { 16280 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 16281 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 16282 } 16283 16284 static const TranslatorOps mips_tr_ops = { 16285 .init_disas_context = mips_tr_init_disas_context, 16286 .tb_start = mips_tr_tb_start, 16287 .insn_start = mips_tr_insn_start, 16288 .translate_insn = mips_tr_translate_insn, 16289 .tb_stop = mips_tr_tb_stop, 16290 .disas_log = mips_tr_disas_log, 16291 }; 16292 16293 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 16294 { 16295 DisasContext ctx; 16296 16297 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns); 16298 } 16299 16300 void mips_tcg_init(void) 16301 { 16302 int i; 16303 16304 cpu_gpr[0] = NULL; 16305 for (i = 1; i < 32; i++) 16306 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 16307 offsetof(CPUMIPSState, 16308 active_tc.gpr[i]), 16309 regnames[i]); 16310 #if defined(TARGET_MIPS64) 16311 cpu_gpr_hi[0] = NULL; 16312 16313 for (unsigned i = 1; i < 32; i++) { 16314 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 16315 16316 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 16317 offsetof(CPUMIPSState, 16318 active_tc.gpr_hi[i]), 16319 rname); 16320 } 16321 #endif /* !TARGET_MIPS64 */ 16322 for (i = 0; i < 32; i++) { 16323 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 16324 16325 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 16326 } 16327 msa_translate_init(); 16328 cpu_PC = tcg_global_mem_new(cpu_env, 16329 offsetof(CPUMIPSState, active_tc.PC), "PC"); 16330 for (i = 0; i < MIPS_DSP_ACC; i++) { 16331 cpu_HI[i] = tcg_global_mem_new(cpu_env, 16332 offsetof(CPUMIPSState, active_tc.HI[i]), 16333 regnames_HI[i]); 16334 cpu_LO[i] = tcg_global_mem_new(cpu_env, 16335 offsetof(CPUMIPSState, active_tc.LO[i]), 16336 regnames_LO[i]); 16337 } 16338 cpu_dspctrl = tcg_global_mem_new(cpu_env, 16339 offsetof(CPUMIPSState, 16340 active_tc.DSPControl), 16341 "DSPControl"); 16342 bcond = tcg_global_mem_new(cpu_env, 16343 offsetof(CPUMIPSState, bcond), "bcond"); 16344 btarget = tcg_global_mem_new(cpu_env, 16345 offsetof(CPUMIPSState, btarget), "btarget"); 16346 hflags = tcg_global_mem_new_i32(cpu_env, 16347 offsetof(CPUMIPSState, hflags), "hflags"); 16348 16349 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 16350 offsetof(CPUMIPSState, active_fpu.fcr0), 16351 "fcr0"); 16352 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 16353 offsetof(CPUMIPSState, active_fpu.fcr31), 16354 "fcr31"); 16355 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 16356 "lladdr"); 16357 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 16358 "llval"); 16359 16360 if (TARGET_LONG_BITS == 32) { 16361 mxu_translate_init(); 16362 } 16363 } 16364 16365 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, 16366 target_ulong *data) 16367 { 16368 env->active_tc.PC = data[0]; 16369 env->hflags &= ~MIPS_HFLAG_BMASK; 16370 env->hflags |= data[1]; 16371 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 16372 case MIPS_HFLAG_BR: 16373 break; 16374 case MIPS_HFLAG_BC: 16375 case MIPS_HFLAG_BL: 16376 case MIPS_HFLAG_B: 16377 env->btarget = data[2]; 16378 break; 16379 } 16380 } 16381