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 "target/mips/trace.h" 35 #include "trace-tcg.h" 36 #include "exec/translator.h" 37 #include "exec/log.h" 38 #include "qemu/qemu-print.h" 39 #include "fpu_helper.h" 40 #include "translate.h" 41 42 /* 43 * Many sysemu-only helpers are not reachable for user-only. 44 * Define stub generators here, so that we need not either sprinkle 45 * ifdefs through the translator, nor provide the helper function. 46 */ 47 #define STUB_HELPER(NAME, ...) \ 48 static inline void gen_helper_##NAME(__VA_ARGS__) \ 49 { g_assert_not_reached(); } 50 51 #ifdef CONFIG_USER_ONLY 52 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 53 #endif 54 55 enum { 56 /* indirect opcode tables */ 57 OPC_SPECIAL = (0x00 << 26), 58 OPC_REGIMM = (0x01 << 26), 59 OPC_CP0 = (0x10 << 26), 60 OPC_CP2 = (0x12 << 26), 61 OPC_CP3 = (0x13 << 26), 62 OPC_SPECIAL2 = (0x1C << 26), 63 OPC_SPECIAL3 = (0x1F << 26), 64 /* arithmetic with immediate */ 65 OPC_ADDI = (0x08 << 26), 66 OPC_ADDIU = (0x09 << 26), 67 OPC_SLTI = (0x0A << 26), 68 OPC_SLTIU = (0x0B << 26), 69 /* logic with immediate */ 70 OPC_ANDI = (0x0C << 26), 71 OPC_ORI = (0x0D << 26), 72 OPC_XORI = (0x0E << 26), 73 OPC_LUI = (0x0F << 26), 74 /* arithmetic with immediate */ 75 OPC_DADDI = (0x18 << 26), 76 OPC_DADDIU = (0x19 << 26), 77 /* Jump and branches */ 78 OPC_J = (0x02 << 26), 79 OPC_JAL = (0x03 << 26), 80 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 81 OPC_BEQL = (0x14 << 26), 82 OPC_BNE = (0x05 << 26), 83 OPC_BNEL = (0x15 << 26), 84 OPC_BLEZ = (0x06 << 26), 85 OPC_BLEZL = (0x16 << 26), 86 OPC_BGTZ = (0x07 << 26), 87 OPC_BGTZL = (0x17 << 26), 88 OPC_JALX = (0x1D << 26), 89 OPC_DAUI = (0x1D << 26), 90 /* Load and stores */ 91 OPC_LDL = (0x1A << 26), 92 OPC_LDR = (0x1B << 26), 93 OPC_LB = (0x20 << 26), 94 OPC_LH = (0x21 << 26), 95 OPC_LWL = (0x22 << 26), 96 OPC_LW = (0x23 << 26), 97 OPC_LWPC = OPC_LW | 0x5, 98 OPC_LBU = (0x24 << 26), 99 OPC_LHU = (0x25 << 26), 100 OPC_LWR = (0x26 << 26), 101 OPC_LWU = (0x27 << 26), 102 OPC_SB = (0x28 << 26), 103 OPC_SH = (0x29 << 26), 104 OPC_SWL = (0x2A << 26), 105 OPC_SW = (0x2B << 26), 106 OPC_SDL = (0x2C << 26), 107 OPC_SDR = (0x2D << 26), 108 OPC_SWR = (0x2E << 26), 109 OPC_LL = (0x30 << 26), 110 OPC_LLD = (0x34 << 26), 111 OPC_LD = (0x37 << 26), 112 OPC_LDPC = OPC_LD | 0x5, 113 OPC_SC = (0x38 << 26), 114 OPC_SCD = (0x3C << 26), 115 OPC_SD = (0x3F << 26), 116 /* Floating point load/store */ 117 OPC_LWC1 = (0x31 << 26), 118 OPC_LWC2 = (0x32 << 26), 119 OPC_LDC1 = (0x35 << 26), 120 OPC_LDC2 = (0x36 << 26), 121 OPC_SWC1 = (0x39 << 26), 122 OPC_SWC2 = (0x3A << 26), 123 OPC_SDC1 = (0x3D << 26), 124 OPC_SDC2 = (0x3E << 26), 125 /* Compact Branches */ 126 OPC_BLEZALC = (0x06 << 26), 127 OPC_BGEZALC = (0x06 << 26), 128 OPC_BGEUC = (0x06 << 26), 129 OPC_BGTZALC = (0x07 << 26), 130 OPC_BLTZALC = (0x07 << 26), 131 OPC_BLTUC = (0x07 << 26), 132 OPC_BOVC = (0x08 << 26), 133 OPC_BEQZALC = (0x08 << 26), 134 OPC_BEQC = (0x08 << 26), 135 OPC_BLEZC = (0x16 << 26), 136 OPC_BGEZC = (0x16 << 26), 137 OPC_BGEC = (0x16 << 26), 138 OPC_BGTZC = (0x17 << 26), 139 OPC_BLTZC = (0x17 << 26), 140 OPC_BLTC = (0x17 << 26), 141 OPC_BNVC = (0x18 << 26), 142 OPC_BNEZALC = (0x18 << 26), 143 OPC_BNEC = (0x18 << 26), 144 OPC_BC = (0x32 << 26), 145 OPC_BEQZC = (0x36 << 26), 146 OPC_JIC = (0x36 << 26), 147 OPC_BALC = (0x3A << 26), 148 OPC_BNEZC = (0x3E << 26), 149 OPC_JIALC = (0x3E << 26), 150 /* MDMX ASE specific */ 151 OPC_MDMX = (0x1E << 26), 152 /* Cache and prefetch */ 153 OPC_CACHE = (0x2F << 26), 154 OPC_PREF = (0x33 << 26), 155 /* PC-relative address computation / loads */ 156 OPC_PCREL = (0x3B << 26), 157 }; 158 159 /* PC-relative address computation / loads */ 160 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 161 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 162 enum { 163 /* Instructions determined by bits 19 and 20 */ 164 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 165 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 166 OPC_LWUPC = OPC_PCREL | (2 << 19), 167 168 /* Instructions determined by bits 16 ... 20 */ 169 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 170 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 171 172 /* Other */ 173 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 174 }; 175 176 /* MIPS special opcodes */ 177 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 178 179 enum { 180 /* Shifts */ 181 OPC_SLL = 0x00 | OPC_SPECIAL, 182 /* NOP is SLL r0, r0, 0 */ 183 /* SSNOP is SLL r0, r0, 1 */ 184 /* EHB is SLL r0, r0, 3 */ 185 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 186 OPC_ROTR = OPC_SRL | (1 << 21), 187 OPC_SRA = 0x03 | OPC_SPECIAL, 188 OPC_SLLV = 0x04 | OPC_SPECIAL, 189 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 190 OPC_ROTRV = OPC_SRLV | (1 << 6), 191 OPC_SRAV = 0x07 | OPC_SPECIAL, 192 OPC_DSLLV = 0x14 | OPC_SPECIAL, 193 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 194 OPC_DROTRV = OPC_DSRLV | (1 << 6), 195 OPC_DSRAV = 0x17 | OPC_SPECIAL, 196 OPC_DSLL = 0x38 | OPC_SPECIAL, 197 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 198 OPC_DROTR = OPC_DSRL | (1 << 21), 199 OPC_DSRA = 0x3B | OPC_SPECIAL, 200 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 201 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 202 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 203 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 204 /* Multiplication / division */ 205 OPC_MULT = 0x18 | OPC_SPECIAL, 206 OPC_MULTU = 0x19 | OPC_SPECIAL, 207 OPC_DIV = 0x1A | OPC_SPECIAL, 208 OPC_DIVU = 0x1B | OPC_SPECIAL, 209 OPC_DMULT = 0x1C | OPC_SPECIAL, 210 OPC_DMULTU = 0x1D | OPC_SPECIAL, 211 OPC_DDIV = 0x1E | OPC_SPECIAL, 212 OPC_DDIVU = 0x1F | OPC_SPECIAL, 213 214 /* 2 registers arithmetic / logic */ 215 OPC_ADD = 0x20 | OPC_SPECIAL, 216 OPC_ADDU = 0x21 | OPC_SPECIAL, 217 OPC_SUB = 0x22 | OPC_SPECIAL, 218 OPC_SUBU = 0x23 | OPC_SPECIAL, 219 OPC_AND = 0x24 | OPC_SPECIAL, 220 OPC_OR = 0x25 | OPC_SPECIAL, 221 OPC_XOR = 0x26 | OPC_SPECIAL, 222 OPC_NOR = 0x27 | OPC_SPECIAL, 223 OPC_SLT = 0x2A | OPC_SPECIAL, 224 OPC_SLTU = 0x2B | OPC_SPECIAL, 225 OPC_DADD = 0x2C | OPC_SPECIAL, 226 OPC_DADDU = 0x2D | OPC_SPECIAL, 227 OPC_DSUB = 0x2E | OPC_SPECIAL, 228 OPC_DSUBU = 0x2F | OPC_SPECIAL, 229 /* Jumps */ 230 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 231 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 232 /* Traps */ 233 OPC_TGE = 0x30 | OPC_SPECIAL, 234 OPC_TGEU = 0x31 | OPC_SPECIAL, 235 OPC_TLT = 0x32 | OPC_SPECIAL, 236 OPC_TLTU = 0x33 | OPC_SPECIAL, 237 OPC_TEQ = 0x34 | OPC_SPECIAL, 238 OPC_TNE = 0x36 | OPC_SPECIAL, 239 /* HI / LO registers load & stores */ 240 OPC_MFHI = 0x10 | OPC_SPECIAL, 241 OPC_MTHI = 0x11 | OPC_SPECIAL, 242 OPC_MFLO = 0x12 | OPC_SPECIAL, 243 OPC_MTLO = 0x13 | OPC_SPECIAL, 244 /* Conditional moves */ 245 OPC_MOVZ = 0x0A | OPC_SPECIAL, 246 OPC_MOVN = 0x0B | OPC_SPECIAL, 247 248 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 249 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 250 251 OPC_MOVCI = 0x01 | OPC_SPECIAL, 252 253 /* Special */ 254 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 255 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 256 OPC_BREAK = 0x0D | OPC_SPECIAL, 257 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 258 OPC_SYNC = 0x0F | OPC_SPECIAL, 259 260 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 261 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 262 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 263 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 264 }; 265 266 /* 267 * R6 Multiply and Divide instructions have the same opcode 268 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 269 */ 270 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 271 272 enum { 273 R6_OPC_MUL = OPC_MULT | (2 << 6), 274 R6_OPC_MUH = OPC_MULT | (3 << 6), 275 R6_OPC_MULU = OPC_MULTU | (2 << 6), 276 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 277 R6_OPC_DIV = OPC_DIV | (2 << 6), 278 R6_OPC_MOD = OPC_DIV | (3 << 6), 279 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 280 R6_OPC_MODU = OPC_DIVU | (3 << 6), 281 282 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 283 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 284 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 285 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 286 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 287 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 288 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 289 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 290 291 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 292 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 293 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 294 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 295 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 296 }; 297 298 /* Multiplication variants of the vr54xx. */ 299 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) 300 301 enum { 302 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, 303 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, 304 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, 305 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, 306 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, 307 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, 308 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, 309 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, 310 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, 311 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, 312 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, 313 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, 314 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, 315 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, 316 }; 317 318 /* REGIMM (rt field) opcodes */ 319 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 320 321 enum { 322 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 323 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 324 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 325 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 326 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 327 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 328 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 329 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 330 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 331 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 332 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 333 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 334 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 335 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 336 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 337 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 338 339 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 340 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 341 }; 342 343 /* Special2 opcodes */ 344 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 345 346 enum { 347 /* Multiply & xxx operations */ 348 OPC_MADD = 0x00 | OPC_SPECIAL2, 349 OPC_MADDU = 0x01 | OPC_SPECIAL2, 350 OPC_MUL = 0x02 | OPC_SPECIAL2, 351 OPC_MSUB = 0x04 | OPC_SPECIAL2, 352 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 353 /* Loongson 2F */ 354 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 355 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 356 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 357 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 358 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 359 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 360 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 361 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 362 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 363 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 364 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 365 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 366 /* Misc */ 367 OPC_CLZ = 0x20 | OPC_SPECIAL2, 368 OPC_CLO = 0x21 | OPC_SPECIAL2, 369 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 370 OPC_DCLO = 0x25 | OPC_SPECIAL2, 371 /* Special */ 372 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 373 }; 374 375 /* Special3 opcodes */ 376 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 377 378 enum { 379 OPC_EXT = 0x00 | OPC_SPECIAL3, 380 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 381 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 382 OPC_DEXT = 0x03 | OPC_SPECIAL3, 383 OPC_INS = 0x04 | OPC_SPECIAL3, 384 OPC_DINSM = 0x05 | OPC_SPECIAL3, 385 OPC_DINSU = 0x06 | OPC_SPECIAL3, 386 OPC_DINS = 0x07 | OPC_SPECIAL3, 387 OPC_FORK = 0x08 | OPC_SPECIAL3, 388 OPC_YIELD = 0x09 | OPC_SPECIAL3, 389 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 390 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 391 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 392 OPC_GINV = 0x3D | OPC_SPECIAL3, 393 394 /* Loongson 2E */ 395 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 396 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 397 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 398 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 399 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 400 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 401 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 402 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 403 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 404 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 405 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 406 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 407 408 /* MIPS DSP Load */ 409 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 410 /* MIPS DSP Arithmetic */ 411 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 412 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 413 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 414 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 415 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 416 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 417 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 418 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 419 /* MIPS DSP GPR-Based Shift Sub-class */ 420 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 421 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 422 /* MIPS DSP Multiply Sub-class insns */ 423 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 424 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 425 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 426 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 427 /* DSP Bit/Manipulation Sub-class */ 428 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 429 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 430 /* MIPS DSP Append Sub-class */ 431 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 432 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 433 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 434 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 435 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 436 437 /* EVA */ 438 OPC_LWLE = 0x19 | OPC_SPECIAL3, 439 OPC_LWRE = 0x1A | OPC_SPECIAL3, 440 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 441 OPC_SBE = 0x1C | OPC_SPECIAL3, 442 OPC_SHE = 0x1D | OPC_SPECIAL3, 443 OPC_SCE = 0x1E | OPC_SPECIAL3, 444 OPC_SWE = 0x1F | OPC_SPECIAL3, 445 OPC_SWLE = 0x21 | OPC_SPECIAL3, 446 OPC_SWRE = 0x22 | OPC_SPECIAL3, 447 OPC_PREFE = 0x23 | OPC_SPECIAL3, 448 OPC_LBUE = 0x28 | OPC_SPECIAL3, 449 OPC_LHUE = 0x29 | OPC_SPECIAL3, 450 OPC_LBE = 0x2C | OPC_SPECIAL3, 451 OPC_LHE = 0x2D | OPC_SPECIAL3, 452 OPC_LLE = 0x2E | OPC_SPECIAL3, 453 OPC_LWE = 0x2F | OPC_SPECIAL3, 454 455 /* R6 */ 456 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 457 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 458 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 459 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 460 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 461 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 462 }; 463 464 /* Loongson EXT load/store quad word opcodes */ 465 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 466 enum { 467 OPC_GSLQ = 0x0020 | OPC_LWC2, 468 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 469 OPC_GSSHFL = OPC_LWC2, 470 OPC_GSSQ = 0x0020 | OPC_SWC2, 471 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 472 OPC_GSSHFS = OPC_SWC2, 473 }; 474 475 /* Loongson EXT shifted load/store opcodes */ 476 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 477 enum { 478 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 479 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 480 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 481 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 482 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 483 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 484 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 485 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 486 }; 487 488 /* Loongson EXT LDC2/SDC2 opcodes */ 489 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 490 491 enum { 492 OPC_GSLBX = 0x0 | OPC_LDC2, 493 OPC_GSLHX = 0x1 | OPC_LDC2, 494 OPC_GSLWX = 0x2 | OPC_LDC2, 495 OPC_GSLDX = 0x3 | OPC_LDC2, 496 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 497 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 498 OPC_GSSBX = 0x0 | OPC_SDC2, 499 OPC_GSSHX = 0x1 | OPC_SDC2, 500 OPC_GSSWX = 0x2 | OPC_SDC2, 501 OPC_GSSDX = 0x3 | OPC_SDC2, 502 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 503 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 504 }; 505 506 /* BSHFL opcodes */ 507 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 508 509 enum { 510 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 511 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 512 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 513 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 514 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 515 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 516 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 517 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 518 }; 519 520 /* DBSHFL opcodes */ 521 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 522 523 enum { 524 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 525 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 526 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 527 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 528 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 529 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 530 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 531 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 532 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 533 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 534 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 535 }; 536 537 /* MIPS DSP REGIMM opcodes */ 538 enum { 539 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 540 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 541 }; 542 543 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 544 /* MIPS DSP Load */ 545 enum { 546 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 547 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 548 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 549 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 550 }; 551 552 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 553 enum { 554 /* MIPS DSP Arithmetic Sub-class */ 555 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 556 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 557 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 558 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 559 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 560 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 561 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 562 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 563 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 564 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 565 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 566 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 567 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 568 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 569 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 570 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 571 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 572 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 573 /* MIPS DSP Multiply Sub-class insns */ 574 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 575 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 576 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 577 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 578 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 579 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 580 }; 581 582 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 583 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 584 enum { 585 /* MIPS DSP Arithmetic Sub-class */ 586 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 587 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 588 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 589 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 590 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 591 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 592 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 593 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 594 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 595 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 596 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 597 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 598 /* MIPS DSP Multiply Sub-class insns */ 599 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 600 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 601 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 602 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 603 }; 604 605 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 606 enum { 607 /* MIPS DSP Arithmetic Sub-class */ 608 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 609 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 610 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 611 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 612 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 613 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 614 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 615 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 616 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 617 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 618 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 619 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 620 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 621 /* DSP Bit/Manipulation Sub-class */ 622 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 623 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 624 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 625 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 626 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 627 }; 628 629 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 630 enum { 631 /* MIPS DSP Arithmetic Sub-class */ 632 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 633 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 634 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 635 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 636 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 637 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 638 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 639 /* DSP Compare-Pick Sub-class */ 640 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 641 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 642 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 643 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 644 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 645 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 646 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 647 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 648 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 649 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 650 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 651 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 652 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 653 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 654 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 655 }; 656 657 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 658 enum { 659 /* MIPS DSP GPR-Based Shift Sub-class */ 660 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 661 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 662 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 663 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 664 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 665 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 666 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 667 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 668 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 669 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 670 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 671 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 672 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 673 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 674 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 675 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 676 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 677 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 678 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 679 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 680 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 681 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 682 }; 683 684 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 685 enum { 686 /* MIPS DSP Multiply Sub-class insns */ 687 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 688 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 689 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 690 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 691 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 692 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 693 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 694 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 695 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 696 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 697 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 698 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 699 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 700 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 701 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 702 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 703 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 704 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 705 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 706 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 707 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 708 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 709 }; 710 711 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 712 enum { 713 /* DSP Bit/Manipulation Sub-class */ 714 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 715 }; 716 717 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 718 enum { 719 /* MIPS DSP Append Sub-class */ 720 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 721 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 722 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 723 }; 724 725 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 726 enum { 727 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 728 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 729 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 730 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 731 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 732 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 733 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 734 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 735 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 736 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 737 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 738 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 739 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 740 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 741 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 742 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 743 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 744 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 745 }; 746 747 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 748 enum { 749 /* MIPS DSP Arithmetic Sub-class */ 750 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 752 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 753 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 754 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 755 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 756 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 757 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 758 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 759 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 760 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 761 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 762 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 763 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 764 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 765 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 766 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 767 /* DSP Bit/Manipulation Sub-class */ 768 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 769 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 770 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 771 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 772 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 773 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 774 }; 775 776 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 777 enum { 778 /* MIPS DSP Multiply Sub-class insns */ 779 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 780 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 781 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 782 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 783 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 784 /* MIPS DSP Arithmetic Sub-class */ 785 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 786 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 787 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 788 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 789 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 790 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 791 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 792 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 793 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 794 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 795 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 796 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 797 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 798 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 799 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 800 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 801 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 802 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 803 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 804 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 805 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 806 }; 807 808 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 809 enum { 810 /* DSP Compare-Pick Sub-class */ 811 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 817 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 818 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 819 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 820 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 821 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 822 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 823 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 824 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 825 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 826 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 827 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 828 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 829 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 830 /* MIPS DSP Arithmetic Sub-class */ 831 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 832 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 833 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 834 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 835 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 836 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 837 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 838 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 839 }; 840 841 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 842 enum { 843 /* DSP Append Sub-class */ 844 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 845 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 846 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 847 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 848 }; 849 850 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 851 enum { 852 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 853 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 854 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 855 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 856 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 857 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 858 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 859 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 860 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 861 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 862 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 863 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 864 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 865 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 866 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 867 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 868 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 869 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 870 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 871 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 872 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 873 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 874 }; 875 876 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 877 enum { 878 /* DSP Bit/Manipulation Sub-class */ 879 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 880 }; 881 882 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 883 enum { 884 /* MIPS DSP Multiply Sub-class insns */ 885 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 889 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 890 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 891 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 892 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 893 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 894 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 895 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 896 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 897 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 898 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 899 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 900 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 901 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 902 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 903 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 904 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 905 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 906 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 907 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 908 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 909 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 910 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 911 }; 912 913 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 914 enum { 915 /* MIPS DSP GPR-Based Shift Sub-class */ 916 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 920 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 921 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 922 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 923 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 924 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 925 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 926 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 927 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 928 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 929 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 930 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 931 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 932 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 933 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 934 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 935 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 936 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 937 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 938 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 939 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 940 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 941 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 942 }; 943 944 /* Coprocessor 0 (rs field) */ 945 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 946 947 enum { 948 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 949 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 950 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 951 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 952 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 953 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 954 OPC_MFTR = (0x08 << 21) | OPC_CP0, 955 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 956 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 957 OPC_MTTR = (0x0C << 21) | OPC_CP0, 958 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 959 OPC_C0 = (0x10 << 21) | OPC_CP0, 960 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 961 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 962 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 963 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 964 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 965 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 966 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 967 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 968 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 969 OPC_C0_A = (0x1A << 21) | OPC_CP0, 970 OPC_C0_B = (0x1B << 21) | OPC_CP0, 971 OPC_C0_C = (0x1C << 21) | OPC_CP0, 972 OPC_C0_D = (0x1D << 21) | OPC_CP0, 973 OPC_C0_E = (0x1E << 21) | OPC_CP0, 974 OPC_C0_F = (0x1F << 21) | OPC_CP0, 975 }; 976 977 /* MFMC0 opcodes */ 978 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 979 980 enum { 981 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 982 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 983 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 984 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 985 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 986 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 987 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 988 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 989 }; 990 991 /* Coprocessor 0 (with rs == C0) */ 992 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 993 994 enum { 995 OPC_TLBR = 0x01 | OPC_C0, 996 OPC_TLBWI = 0x02 | OPC_C0, 997 OPC_TLBINV = 0x03 | OPC_C0, 998 OPC_TLBINVF = 0x04 | OPC_C0, 999 OPC_TLBWR = 0x06 | OPC_C0, 1000 OPC_TLBP = 0x08 | OPC_C0, 1001 OPC_RFE = 0x10 | OPC_C0, 1002 OPC_ERET = 0x18 | OPC_C0, 1003 OPC_DERET = 0x1F | OPC_C0, 1004 OPC_WAIT = 0x20 | OPC_C0, 1005 }; 1006 1007 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 1008 1009 enum { 1010 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 1011 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 1012 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 1013 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 1014 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 1015 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 1016 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 1017 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 1018 OPC_BC2 = (0x08 << 21) | OPC_CP2, 1019 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 1020 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 1021 }; 1022 1023 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1024 1025 enum { 1026 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1027 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1028 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1029 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1030 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1031 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1032 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1033 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1034 1035 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1036 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1037 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1038 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1039 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1040 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1041 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1042 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1043 1044 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1045 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1046 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1047 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1048 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1049 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1050 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1051 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1052 1053 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1054 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1055 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1056 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1057 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1058 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1059 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1060 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1061 1062 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1063 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1064 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1065 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1066 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1067 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1068 1069 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1070 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1071 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1072 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1073 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1074 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1075 1076 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1077 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1078 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1079 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1080 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1081 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1082 1083 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1084 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1085 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1086 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1087 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1088 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1089 1090 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1091 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1092 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1093 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1094 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1095 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1096 1097 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1098 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1099 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1100 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1101 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1102 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1103 1104 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1105 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1106 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1107 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1108 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1109 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1110 1111 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1112 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1113 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1114 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1115 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1116 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1117 }; 1118 1119 1120 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1121 1122 enum { 1123 OPC_LWXC1 = 0x00 | OPC_CP3, 1124 OPC_LDXC1 = 0x01 | OPC_CP3, 1125 OPC_LUXC1 = 0x05 | OPC_CP3, 1126 OPC_SWXC1 = 0x08 | OPC_CP3, 1127 OPC_SDXC1 = 0x09 | OPC_CP3, 1128 OPC_SUXC1 = 0x0D | OPC_CP3, 1129 OPC_PREFX = 0x0F | OPC_CP3, 1130 OPC_ALNV_PS = 0x1E | OPC_CP3, 1131 OPC_MADD_S = 0x20 | OPC_CP3, 1132 OPC_MADD_D = 0x21 | OPC_CP3, 1133 OPC_MADD_PS = 0x26 | OPC_CP3, 1134 OPC_MSUB_S = 0x28 | OPC_CP3, 1135 OPC_MSUB_D = 0x29 | OPC_CP3, 1136 OPC_MSUB_PS = 0x2E | OPC_CP3, 1137 OPC_NMADD_S = 0x30 | OPC_CP3, 1138 OPC_NMADD_D = 0x31 | OPC_CP3, 1139 OPC_NMADD_PS = 0x36 | OPC_CP3, 1140 OPC_NMSUB_S = 0x38 | OPC_CP3, 1141 OPC_NMSUB_D = 0x39 | OPC_CP3, 1142 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1143 }; 1144 1145 /* 1146 * MMI (MultiMedia Instruction) encodings 1147 * ====================================== 1148 * 1149 * MMI instructions encoding table keys: 1150 * 1151 * * This code is reserved for future use. An attempt to execute it 1152 * causes a Reserved Instruction exception. 1153 * % This code indicates an instruction class. The instruction word 1154 * must be further decoded by examining additional tables that show 1155 * the values for other instruction fields. 1156 * # This code is reserved for the unsupported instructions DMULT, 1157 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1158 * to execute it causes a Reserved Instruction exception. 1159 * 1160 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1161 * 1162 * 31 26 0 1163 * +--------+----------------------------------------+ 1164 * | opcode | | 1165 * +--------+----------------------------------------+ 1166 * 1167 * opcode bits 28..26 1168 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1169 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1170 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1171 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1172 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1173 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1174 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1175 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1176 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1177 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1178 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1179 */ 1180 1181 enum { 1182 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1183 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */ 1184 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1185 }; 1186 1187 /* 1188 * MMI instructions with opcode field = MMI: 1189 * 1190 * 31 26 5 0 1191 * +--------+-------------------------------+--------+ 1192 * | MMI | |function| 1193 * +--------+-------------------------------+--------+ 1194 * 1195 * function bits 2..0 1196 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1197 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1198 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1199 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1200 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1201 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1202 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1203 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1204 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1205 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1206 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1207 */ 1208 1209 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1210 enum { 1211 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1212 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1213 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1214 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1215 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1216 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1217 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1218 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1219 }; 1220 1221 /* global register indices */ 1222 TCGv cpu_gpr[32], cpu_PC; 1223 /* 1224 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1225 * and the upper halves in cpu_gpr_hi[]. 1226 */ 1227 TCGv_i64 cpu_gpr_hi[32]; 1228 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1229 static TCGv cpu_dspctrl, btarget; 1230 TCGv bcond; 1231 static TCGv cpu_lladdr, cpu_llval; 1232 static TCGv_i32 hflags; 1233 TCGv_i32 fpu_fcr0, fpu_fcr31; 1234 TCGv_i64 fpu_f64[32]; 1235 1236 #include "exec/gen-icount.h" 1237 1238 #define gen_helper_0e0i(name, arg) do { \ 1239 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 1240 gen_helper_##name(cpu_env, helper_tmp); \ 1241 tcg_temp_free_i32(helper_tmp); \ 1242 } while (0) 1243 1244 #define gen_helper_0e1i(name, arg1, arg2) do { \ 1245 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1246 gen_helper_##name(cpu_env, arg1, helper_tmp); \ 1247 tcg_temp_free_i32(helper_tmp); \ 1248 } while (0) 1249 1250 #define gen_helper_1e0i(name, ret, arg1) do { \ 1251 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ 1252 gen_helper_##name(ret, cpu_env, helper_tmp); \ 1253 tcg_temp_free_i32(helper_tmp); \ 1254 } while (0) 1255 1256 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \ 1257 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1258 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ 1259 tcg_temp_free_i32(helper_tmp); \ 1260 } while (0) 1261 1262 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ 1263 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1264 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ 1265 tcg_temp_free_i32(helper_tmp); \ 1266 } while (0) 1267 1268 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ 1269 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1270 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ 1271 tcg_temp_free_i32(helper_tmp); \ 1272 } while (0) 1273 1274 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ 1275 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 1276 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ 1277 tcg_temp_free_i32(helper_tmp); \ 1278 } while (0) 1279 1280 #define DISAS_STOP DISAS_TARGET_0 1281 #define DISAS_EXIT DISAS_TARGET_1 1282 1283 static const char * const regnames_HI[] = { 1284 "HI0", "HI1", "HI2", "HI3", 1285 }; 1286 1287 static const char * const regnames_LO[] = { 1288 "LO0", "LO1", "LO2", "LO3", 1289 }; 1290 1291 /* General purpose registers moves. */ 1292 void gen_load_gpr(TCGv t, int reg) 1293 { 1294 if (reg == 0) { 1295 tcg_gen_movi_tl(t, 0); 1296 } else { 1297 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1298 } 1299 } 1300 1301 void gen_store_gpr(TCGv t, int reg) 1302 { 1303 if (reg != 0) { 1304 tcg_gen_mov_tl(cpu_gpr[reg], t); 1305 } 1306 } 1307 1308 #if defined(TARGET_MIPS64) 1309 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1310 { 1311 if (reg == 0) { 1312 tcg_gen_movi_i64(t, 0); 1313 } else { 1314 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1315 } 1316 } 1317 1318 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1319 { 1320 if (reg != 0) { 1321 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1322 } 1323 } 1324 #endif /* TARGET_MIPS64 */ 1325 1326 /* Moves to/from shadow registers. */ 1327 static inline void gen_load_srsgpr(int from, int to) 1328 { 1329 TCGv t0 = tcg_temp_new(); 1330 1331 if (from == 0) { 1332 tcg_gen_movi_tl(t0, 0); 1333 } else { 1334 TCGv_i32 t2 = tcg_temp_new_i32(); 1335 TCGv_ptr addr = tcg_temp_new_ptr(); 1336 1337 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1338 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1339 tcg_gen_andi_i32(t2, t2, 0xf); 1340 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1341 tcg_gen_ext_i32_ptr(addr, t2); 1342 tcg_gen_add_ptr(addr, cpu_env, addr); 1343 1344 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1345 tcg_temp_free_ptr(addr); 1346 tcg_temp_free_i32(t2); 1347 } 1348 gen_store_gpr(t0, to); 1349 tcg_temp_free(t0); 1350 } 1351 1352 static inline void gen_store_srsgpr(int from, int to) 1353 { 1354 if (to != 0) { 1355 TCGv t0 = tcg_temp_new(); 1356 TCGv_i32 t2 = tcg_temp_new_i32(); 1357 TCGv_ptr addr = tcg_temp_new_ptr(); 1358 1359 gen_load_gpr(t0, from); 1360 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1361 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1362 tcg_gen_andi_i32(t2, t2, 0xf); 1363 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1364 tcg_gen_ext_i32_ptr(addr, t2); 1365 tcg_gen_add_ptr(addr, cpu_env, addr); 1366 1367 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1368 tcg_temp_free_ptr(addr); 1369 tcg_temp_free_i32(t2); 1370 tcg_temp_free(t0); 1371 } 1372 } 1373 1374 /* Tests */ 1375 static inline void gen_save_pc(target_ulong pc) 1376 { 1377 tcg_gen_movi_tl(cpu_PC, pc); 1378 } 1379 1380 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1381 { 1382 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1383 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1384 gen_save_pc(ctx->base.pc_next); 1385 ctx->saved_pc = ctx->base.pc_next; 1386 } 1387 if (ctx->hflags != ctx->saved_hflags) { 1388 tcg_gen_movi_i32(hflags, ctx->hflags); 1389 ctx->saved_hflags = ctx->hflags; 1390 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1391 case MIPS_HFLAG_BR: 1392 break; 1393 case MIPS_HFLAG_BC: 1394 case MIPS_HFLAG_BL: 1395 case MIPS_HFLAG_B: 1396 tcg_gen_movi_tl(btarget, ctx->btarget); 1397 break; 1398 } 1399 } 1400 } 1401 1402 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1403 { 1404 ctx->saved_hflags = ctx->hflags; 1405 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1406 case MIPS_HFLAG_BR: 1407 break; 1408 case MIPS_HFLAG_BC: 1409 case MIPS_HFLAG_BL: 1410 case MIPS_HFLAG_B: 1411 ctx->btarget = env->btarget; 1412 break; 1413 } 1414 } 1415 1416 void generate_exception_err(DisasContext *ctx, int excp, int err) 1417 { 1418 TCGv_i32 texcp = tcg_const_i32(excp); 1419 TCGv_i32 terr = tcg_const_i32(err); 1420 save_cpu_state(ctx, 1); 1421 gen_helper_raise_exception_err(cpu_env, texcp, terr); 1422 tcg_temp_free_i32(terr); 1423 tcg_temp_free_i32(texcp); 1424 ctx->base.is_jmp = DISAS_NORETURN; 1425 } 1426 1427 void generate_exception(DisasContext *ctx, int excp) 1428 { 1429 gen_helper_0e0i(raise_exception, excp); 1430 } 1431 1432 void generate_exception_end(DisasContext *ctx, int excp) 1433 { 1434 generate_exception_err(ctx, excp, 0); 1435 } 1436 1437 void gen_reserved_instruction(DisasContext *ctx) 1438 { 1439 generate_exception_end(ctx, EXCP_RI); 1440 } 1441 1442 /* Floating point register moves. */ 1443 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1444 { 1445 if (ctx->hflags & MIPS_HFLAG_FRE) { 1446 generate_exception(ctx, EXCP_RI); 1447 } 1448 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1449 } 1450 1451 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1452 { 1453 TCGv_i64 t64; 1454 if (ctx->hflags & MIPS_HFLAG_FRE) { 1455 generate_exception(ctx, EXCP_RI); 1456 } 1457 t64 = tcg_temp_new_i64(); 1458 tcg_gen_extu_i32_i64(t64, t); 1459 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1460 tcg_temp_free_i64(t64); 1461 } 1462 1463 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1464 { 1465 if (ctx->hflags & MIPS_HFLAG_F64) { 1466 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1467 } else { 1468 gen_load_fpr32(ctx, t, reg | 1); 1469 } 1470 } 1471 1472 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1473 { 1474 if (ctx->hflags & MIPS_HFLAG_F64) { 1475 TCGv_i64 t64 = tcg_temp_new_i64(); 1476 tcg_gen_extu_i32_i64(t64, t); 1477 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1478 tcg_temp_free_i64(t64); 1479 } else { 1480 gen_store_fpr32(ctx, t, reg | 1); 1481 } 1482 } 1483 1484 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1485 { 1486 if (ctx->hflags & MIPS_HFLAG_F64) { 1487 tcg_gen_mov_i64(t, fpu_f64[reg]); 1488 } else { 1489 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1490 } 1491 } 1492 1493 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1494 { 1495 if (ctx->hflags & MIPS_HFLAG_F64) { 1496 tcg_gen_mov_i64(fpu_f64[reg], t); 1497 } else { 1498 TCGv_i64 t0; 1499 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1500 t0 = tcg_temp_new_i64(); 1501 tcg_gen_shri_i64(t0, t, 32); 1502 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1503 tcg_temp_free_i64(t0); 1504 } 1505 } 1506 1507 int get_fp_bit(int cc) 1508 { 1509 if (cc) { 1510 return 24 + cc; 1511 } else { 1512 return 23; 1513 } 1514 } 1515 1516 /* Addresses computation */ 1517 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1518 { 1519 tcg_gen_add_tl(ret, arg0, arg1); 1520 1521 #if defined(TARGET_MIPS64) 1522 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1523 tcg_gen_ext32s_i64(ret, ret); 1524 } 1525 #endif 1526 } 1527 1528 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1529 target_long ofs) 1530 { 1531 tcg_gen_addi_tl(ret, base, ofs); 1532 1533 #if defined(TARGET_MIPS64) 1534 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1535 tcg_gen_ext32s_i64(ret, ret); 1536 } 1537 #endif 1538 } 1539 1540 /* Addresses computation (translation time) */ 1541 static target_long addr_add(DisasContext *ctx, target_long base, 1542 target_long offset) 1543 { 1544 target_long sum = base + offset; 1545 1546 #if defined(TARGET_MIPS64) 1547 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1548 sum = (int32_t)sum; 1549 } 1550 #endif 1551 return sum; 1552 } 1553 1554 /* Sign-extract the low 32-bits to a target_long. */ 1555 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1556 { 1557 #if defined(TARGET_MIPS64) 1558 tcg_gen_ext32s_i64(ret, arg); 1559 #else 1560 tcg_gen_extrl_i64_i32(ret, arg); 1561 #endif 1562 } 1563 1564 /* Sign-extract the high 32-bits to a target_long. */ 1565 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1566 { 1567 #if defined(TARGET_MIPS64) 1568 tcg_gen_sari_i64(ret, arg, 32); 1569 #else 1570 tcg_gen_extrh_i64_i32(ret, arg); 1571 #endif 1572 } 1573 1574 bool check_cp0_enabled(DisasContext *ctx) 1575 { 1576 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1577 generate_exception_end(ctx, EXCP_CpU); 1578 return false; 1579 } 1580 return true; 1581 } 1582 1583 void check_cp1_enabled(DisasContext *ctx) 1584 { 1585 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1586 generate_exception_err(ctx, EXCP_CpU, 1); 1587 } 1588 } 1589 1590 /* 1591 * Verify that the processor is running with COP1X instructions enabled. 1592 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1593 * opcode tables. 1594 */ 1595 void check_cop1x(DisasContext *ctx) 1596 { 1597 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1598 gen_reserved_instruction(ctx); 1599 } 1600 } 1601 1602 /* 1603 * Verify that the processor is running with 64-bit floating-point 1604 * operations enabled. 1605 */ 1606 void check_cp1_64bitmode(DisasContext *ctx) 1607 { 1608 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { 1609 gen_reserved_instruction(ctx); 1610 } 1611 } 1612 1613 /* 1614 * Verify if floating point register is valid; an operation is not defined 1615 * if bit 0 of any register specification is set and the FR bit in the 1616 * Status register equals zero, since the register numbers specify an 1617 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1618 * in the Status register equals one, both even and odd register numbers 1619 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1620 * 1621 * Multiple 64 bit wide registers can be checked by calling 1622 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1623 */ 1624 void check_cp1_registers(DisasContext *ctx, int regs) 1625 { 1626 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1627 gen_reserved_instruction(ctx); 1628 } 1629 } 1630 1631 /* 1632 * Verify that the processor is running with DSP instructions enabled. 1633 * This is enabled by CP0 Status register MX(24) bit. 1634 */ 1635 static inline void check_dsp(DisasContext *ctx) 1636 { 1637 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1638 if (ctx->insn_flags & ASE_DSP) { 1639 generate_exception_end(ctx, EXCP_DSPDIS); 1640 } else { 1641 gen_reserved_instruction(ctx); 1642 } 1643 } 1644 } 1645 1646 static inline void check_dsp_r2(DisasContext *ctx) 1647 { 1648 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1649 if (ctx->insn_flags & ASE_DSP) { 1650 generate_exception_end(ctx, EXCP_DSPDIS); 1651 } else { 1652 gen_reserved_instruction(ctx); 1653 } 1654 } 1655 } 1656 1657 static inline void check_dsp_r3(DisasContext *ctx) 1658 { 1659 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1660 if (ctx->insn_flags & ASE_DSP) { 1661 generate_exception_end(ctx, EXCP_DSPDIS); 1662 } else { 1663 gen_reserved_instruction(ctx); 1664 } 1665 } 1666 } 1667 1668 /* 1669 * This code generates a "reserved instruction" exception if the 1670 * CPU does not support the instruction set corresponding to flags. 1671 */ 1672 void check_insn(DisasContext *ctx, uint64_t flags) 1673 { 1674 if (unlikely(!(ctx->insn_flags & flags))) { 1675 gen_reserved_instruction(ctx); 1676 } 1677 } 1678 1679 /* 1680 * This code generates a "reserved instruction" exception if the 1681 * CPU has corresponding flag set which indicates that the instruction 1682 * has been removed. 1683 */ 1684 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1685 { 1686 if (unlikely(ctx->insn_flags & flags)) { 1687 gen_reserved_instruction(ctx); 1688 } 1689 } 1690 1691 /* 1692 * The Linux kernel traps certain reserved instruction exceptions to 1693 * emulate the corresponding instructions. QEMU is the kernel in user 1694 * mode, so those traps are emulated by accepting the instructions. 1695 * 1696 * A reserved instruction exception is generated for flagged CPUs if 1697 * QEMU runs in system mode. 1698 */ 1699 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1700 { 1701 #ifndef CONFIG_USER_ONLY 1702 check_insn_opc_removed(ctx, flags); 1703 #endif 1704 } 1705 1706 /* 1707 * This code generates a "reserved instruction" exception if the 1708 * CPU does not support 64-bit paired-single (PS) floating point data type. 1709 */ 1710 static inline void check_ps(DisasContext *ctx) 1711 { 1712 if (unlikely(!ctx->ps)) { 1713 generate_exception(ctx, EXCP_RI); 1714 } 1715 check_cp1_64bitmode(ctx); 1716 } 1717 1718 /* 1719 * This code generates a "reserved instruction" exception if cpu is not 1720 * 64-bit or 64-bit instructions are not enabled. 1721 */ 1722 void check_mips_64(DisasContext *ctx) 1723 { 1724 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1725 gen_reserved_instruction(ctx); 1726 } 1727 } 1728 1729 #ifndef CONFIG_USER_ONLY 1730 static inline void check_mvh(DisasContext *ctx) 1731 { 1732 if (unlikely(!ctx->mvh)) { 1733 generate_exception(ctx, EXCP_RI); 1734 } 1735 } 1736 #endif 1737 1738 /* 1739 * This code generates a "reserved instruction" exception if the 1740 * Config5 XNP bit is set. 1741 */ 1742 static inline void check_xnp(DisasContext *ctx) 1743 { 1744 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1745 gen_reserved_instruction(ctx); 1746 } 1747 } 1748 1749 #ifndef CONFIG_USER_ONLY 1750 /* 1751 * This code generates a "reserved instruction" exception if the 1752 * Config3 PW bit is NOT set. 1753 */ 1754 static inline void check_pw(DisasContext *ctx) 1755 { 1756 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1757 gen_reserved_instruction(ctx); 1758 } 1759 } 1760 #endif 1761 1762 /* 1763 * This code generates a "reserved instruction" exception if the 1764 * Config3 MT bit is NOT set. 1765 */ 1766 static inline void check_mt(DisasContext *ctx) 1767 { 1768 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1769 gen_reserved_instruction(ctx); 1770 } 1771 } 1772 1773 #ifndef CONFIG_USER_ONLY 1774 /* 1775 * This code generates a "coprocessor unusable" exception if CP0 is not 1776 * available, and, if that is not the case, generates a "reserved instruction" 1777 * exception if the Config5 MT bit is NOT set. This is needed for availability 1778 * control of some of MT ASE instructions. 1779 */ 1780 static inline void check_cp0_mt(DisasContext *ctx) 1781 { 1782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1783 generate_exception_end(ctx, EXCP_CpU); 1784 } else { 1785 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1786 gen_reserved_instruction(ctx); 1787 } 1788 } 1789 } 1790 #endif 1791 1792 /* 1793 * This code generates a "reserved instruction" exception if the 1794 * Config5 NMS bit is set. 1795 */ 1796 static inline void check_nms(DisasContext *ctx) 1797 { 1798 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1799 gen_reserved_instruction(ctx); 1800 } 1801 } 1802 1803 /* 1804 * This code generates a "reserved instruction" exception if the 1805 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1806 * Config2 TL, and Config5 L2C are unset. 1807 */ 1808 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1809 { 1810 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1811 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1812 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1813 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1814 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1815 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1816 gen_reserved_instruction(ctx); 1817 } 1818 } 1819 1820 /* 1821 * This code generates a "reserved instruction" exception if the 1822 * Config5 EVA bit is NOT set. 1823 */ 1824 static inline void check_eva(DisasContext *ctx) 1825 { 1826 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1827 gen_reserved_instruction(ctx); 1828 } 1829 } 1830 1831 1832 /* 1833 * Define small wrappers for gen_load_fpr* so that we have a uniform 1834 * calling interface for 32 and 64-bit FPRs. No sense in changing 1835 * all callers for gen_load_fpr32 when we need the CTX parameter for 1836 * this one use. 1837 */ 1838 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1839 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1840 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1841 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1842 int ft, int fs, int cc) \ 1843 { \ 1844 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1845 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1846 switch (ifmt) { \ 1847 case FMT_PS: \ 1848 check_ps(ctx); \ 1849 break; \ 1850 case FMT_D: \ 1851 if (abs) { \ 1852 check_cop1x(ctx); \ 1853 } \ 1854 check_cp1_registers(ctx, fs | ft); \ 1855 break; \ 1856 case FMT_S: \ 1857 if (abs) { \ 1858 check_cop1x(ctx); \ 1859 } \ 1860 break; \ 1861 } \ 1862 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1863 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1864 switch (n) { \ 1865 case 0: \ 1866 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1867 break; \ 1868 case 1: \ 1869 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1870 break; \ 1871 case 2: \ 1872 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1873 break; \ 1874 case 3: \ 1875 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1876 break; \ 1877 case 4: \ 1878 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1879 break; \ 1880 case 5: \ 1881 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1882 break; \ 1883 case 6: \ 1884 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1885 break; \ 1886 case 7: \ 1887 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1888 break; \ 1889 case 8: \ 1890 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1891 break; \ 1892 case 9: \ 1893 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1894 break; \ 1895 case 10: \ 1896 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1897 break; \ 1898 case 11: \ 1899 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1900 break; \ 1901 case 12: \ 1902 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1903 break; \ 1904 case 13: \ 1905 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1906 break; \ 1907 case 14: \ 1908 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1909 break; \ 1910 case 15: \ 1911 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1912 break; \ 1913 default: \ 1914 abort(); \ 1915 } \ 1916 tcg_temp_free_i##bits(fp0); \ 1917 tcg_temp_free_i##bits(fp1); \ 1918 } 1919 1920 FOP_CONDS(, 0, d, FMT_D, 64) 1921 FOP_CONDS(abs, 1, d, FMT_D, 64) 1922 FOP_CONDS(, 0, s, FMT_S, 32) 1923 FOP_CONDS(abs, 1, s, FMT_S, 32) 1924 FOP_CONDS(, 0, ps, FMT_PS, 64) 1925 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1926 #undef FOP_CONDS 1927 1928 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1929 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1930 int ft, int fs, int fd) \ 1931 { \ 1932 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1933 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1934 if (ifmt == FMT_D) { \ 1935 check_cp1_registers(ctx, fs | ft | fd); \ 1936 } \ 1937 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1938 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1939 switch (n) { \ 1940 case 0: \ 1941 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1942 break; \ 1943 case 1: \ 1944 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1945 break; \ 1946 case 2: \ 1947 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1948 break; \ 1949 case 3: \ 1950 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1951 break; \ 1952 case 4: \ 1953 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1954 break; \ 1955 case 5: \ 1956 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1957 break; \ 1958 case 6: \ 1959 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1960 break; \ 1961 case 7: \ 1962 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1963 break; \ 1964 case 8: \ 1965 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1966 break; \ 1967 case 9: \ 1968 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1969 break; \ 1970 case 10: \ 1971 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1972 break; \ 1973 case 11: \ 1974 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1975 break; \ 1976 case 12: \ 1977 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1978 break; \ 1979 case 13: \ 1980 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1981 break; \ 1982 case 14: \ 1983 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1984 break; \ 1985 case 15: \ 1986 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1987 break; \ 1988 case 17: \ 1989 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1990 break; \ 1991 case 18: \ 1992 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1993 break; \ 1994 case 19: \ 1995 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1996 break; \ 1997 case 25: \ 1998 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1999 break; \ 2000 case 26: \ 2001 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 2002 break; \ 2003 case 27: \ 2004 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 2005 break; \ 2006 default: \ 2007 abort(); \ 2008 } \ 2009 STORE; \ 2010 tcg_temp_free_i ## bits(fp0); \ 2011 tcg_temp_free_i ## bits(fp1); \ 2012 } 2013 2014 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 2015 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 2016 #undef FOP_CONDNS 2017 #undef gen_ldcmp_fpr32 2018 #undef gen_ldcmp_fpr64 2019 2020 /* load/store instructions. */ 2021 #ifdef CONFIG_USER_ONLY 2022 #define OP_LD_ATOMIC(insn, fname) \ 2023 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2024 DisasContext *ctx) \ 2025 { \ 2026 TCGv t0 = tcg_temp_new(); \ 2027 tcg_gen_mov_tl(t0, arg1); \ 2028 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 2029 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 2030 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 2031 tcg_temp_free(t0); \ 2032 } 2033 #else 2034 #define OP_LD_ATOMIC(insn, fname) \ 2035 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2036 DisasContext *ctx) \ 2037 { \ 2038 gen_helper_1e1i(insn, ret, arg1, mem_idx); \ 2039 } 2040 #endif 2041 OP_LD_ATOMIC(ll, ld32s); 2042 #if defined(TARGET_MIPS64) 2043 OP_LD_ATOMIC(lld, ld64); 2044 #endif 2045 #undef OP_LD_ATOMIC 2046 2047 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 2048 { 2049 if (base == 0) { 2050 tcg_gen_movi_tl(addr, offset); 2051 } else if (offset == 0) { 2052 gen_load_gpr(addr, base); 2053 } else { 2054 tcg_gen_movi_tl(addr, offset); 2055 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 2056 } 2057 } 2058 2059 static target_ulong pc_relative_pc(DisasContext *ctx) 2060 { 2061 target_ulong pc = ctx->base.pc_next; 2062 2063 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2064 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2065 2066 pc -= branch_bytes; 2067 } 2068 2069 pc &= ~(target_ulong)3; 2070 return pc; 2071 } 2072 2073 /* Load */ 2074 static void gen_ld(DisasContext *ctx, uint32_t opc, 2075 int rt, int base, int offset) 2076 { 2077 TCGv t0, t1, t2; 2078 int mem_idx = ctx->mem_idx; 2079 2080 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2081 INSN_LOONGSON3A)) { 2082 /* 2083 * Loongson CPU uses a load to zero register for prefetch. 2084 * We emulate it as a NOP. On other CPU we must perform the 2085 * actual memory access. 2086 */ 2087 return; 2088 } 2089 2090 t0 = tcg_temp_new(); 2091 gen_base_offset_addr(ctx, t0, base, offset); 2092 2093 switch (opc) { 2094 #if defined(TARGET_MIPS64) 2095 case OPC_LWU: 2096 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2097 ctx->default_tcg_memop_mask); 2098 gen_store_gpr(t0, rt); 2099 break; 2100 case OPC_LD: 2101 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | 2102 ctx->default_tcg_memop_mask); 2103 gen_store_gpr(t0, rt); 2104 break; 2105 case OPC_LLD: 2106 case R6_OPC_LLD: 2107 op_ld_lld(t0, t0, mem_idx, ctx); 2108 gen_store_gpr(t0, rt); 2109 break; 2110 case OPC_LDL: 2111 t1 = tcg_temp_new(); 2112 /* 2113 * Do a byte access to possibly trigger a page 2114 * fault with the unaligned address. 2115 */ 2116 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2117 tcg_gen_andi_tl(t1, t0, 7); 2118 #ifndef TARGET_WORDS_BIGENDIAN 2119 tcg_gen_xori_tl(t1, t1, 7); 2120 #endif 2121 tcg_gen_shli_tl(t1, t1, 3); 2122 tcg_gen_andi_tl(t0, t0, ~7); 2123 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2124 tcg_gen_shl_tl(t0, t0, t1); 2125 t2 = tcg_const_tl(-1); 2126 tcg_gen_shl_tl(t2, t2, t1); 2127 gen_load_gpr(t1, rt); 2128 tcg_gen_andc_tl(t1, t1, t2); 2129 tcg_temp_free(t2); 2130 tcg_gen_or_tl(t0, t0, t1); 2131 tcg_temp_free(t1); 2132 gen_store_gpr(t0, rt); 2133 break; 2134 case OPC_LDR: 2135 t1 = tcg_temp_new(); 2136 /* 2137 * Do a byte access to possibly trigger a page 2138 * fault with the unaligned address. 2139 */ 2140 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2141 tcg_gen_andi_tl(t1, t0, 7); 2142 #ifdef TARGET_WORDS_BIGENDIAN 2143 tcg_gen_xori_tl(t1, t1, 7); 2144 #endif 2145 tcg_gen_shli_tl(t1, t1, 3); 2146 tcg_gen_andi_tl(t0, t0, ~7); 2147 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2148 tcg_gen_shr_tl(t0, t0, t1); 2149 tcg_gen_xori_tl(t1, t1, 63); 2150 t2 = tcg_const_tl(0xfffffffffffffffeull); 2151 tcg_gen_shl_tl(t2, t2, t1); 2152 gen_load_gpr(t1, rt); 2153 tcg_gen_and_tl(t1, t1, t2); 2154 tcg_temp_free(t2); 2155 tcg_gen_or_tl(t0, t0, t1); 2156 tcg_temp_free(t1); 2157 gen_store_gpr(t0, rt); 2158 break; 2159 case OPC_LDPC: 2160 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2161 gen_op_addr_add(ctx, t0, t0, t1); 2162 tcg_temp_free(t1); 2163 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2164 gen_store_gpr(t0, rt); 2165 break; 2166 #endif 2167 case OPC_LWPC: 2168 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2169 gen_op_addr_add(ctx, t0, t0, t1); 2170 tcg_temp_free(t1); 2171 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2172 gen_store_gpr(t0, rt); 2173 break; 2174 case OPC_LWE: 2175 mem_idx = MIPS_HFLAG_UM; 2176 /* fall through */ 2177 case OPC_LW: 2178 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2179 ctx->default_tcg_memop_mask); 2180 gen_store_gpr(t0, rt); 2181 break; 2182 case OPC_LHE: 2183 mem_idx = MIPS_HFLAG_UM; 2184 /* fall through */ 2185 case OPC_LH: 2186 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2187 ctx->default_tcg_memop_mask); 2188 gen_store_gpr(t0, rt); 2189 break; 2190 case OPC_LHUE: 2191 mem_idx = MIPS_HFLAG_UM; 2192 /* fall through */ 2193 case OPC_LHU: 2194 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2195 ctx->default_tcg_memop_mask); 2196 gen_store_gpr(t0, rt); 2197 break; 2198 case OPC_LBE: 2199 mem_idx = MIPS_HFLAG_UM; 2200 /* fall through */ 2201 case OPC_LB: 2202 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2203 gen_store_gpr(t0, rt); 2204 break; 2205 case OPC_LBUE: 2206 mem_idx = MIPS_HFLAG_UM; 2207 /* fall through */ 2208 case OPC_LBU: 2209 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2210 gen_store_gpr(t0, rt); 2211 break; 2212 case OPC_LWLE: 2213 mem_idx = MIPS_HFLAG_UM; 2214 /* fall through */ 2215 case OPC_LWL: 2216 t1 = tcg_temp_new(); 2217 /* 2218 * Do a byte access to possibly trigger a page 2219 * fault with the unaligned address. 2220 */ 2221 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2222 tcg_gen_andi_tl(t1, t0, 3); 2223 #ifndef TARGET_WORDS_BIGENDIAN 2224 tcg_gen_xori_tl(t1, t1, 3); 2225 #endif 2226 tcg_gen_shli_tl(t1, t1, 3); 2227 tcg_gen_andi_tl(t0, t0, ~3); 2228 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2229 tcg_gen_shl_tl(t0, t0, t1); 2230 t2 = tcg_const_tl(-1); 2231 tcg_gen_shl_tl(t2, t2, t1); 2232 gen_load_gpr(t1, rt); 2233 tcg_gen_andc_tl(t1, t1, t2); 2234 tcg_temp_free(t2); 2235 tcg_gen_or_tl(t0, t0, t1); 2236 tcg_temp_free(t1); 2237 tcg_gen_ext32s_tl(t0, t0); 2238 gen_store_gpr(t0, rt); 2239 break; 2240 case OPC_LWRE: 2241 mem_idx = MIPS_HFLAG_UM; 2242 /* fall through */ 2243 case OPC_LWR: 2244 t1 = tcg_temp_new(); 2245 /* 2246 * Do a byte access to possibly trigger a page 2247 * fault with the unaligned address. 2248 */ 2249 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2250 tcg_gen_andi_tl(t1, t0, 3); 2251 #ifdef TARGET_WORDS_BIGENDIAN 2252 tcg_gen_xori_tl(t1, t1, 3); 2253 #endif 2254 tcg_gen_shli_tl(t1, t1, 3); 2255 tcg_gen_andi_tl(t0, t0, ~3); 2256 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2257 tcg_gen_shr_tl(t0, t0, t1); 2258 tcg_gen_xori_tl(t1, t1, 31); 2259 t2 = tcg_const_tl(0xfffffffeull); 2260 tcg_gen_shl_tl(t2, t2, t1); 2261 gen_load_gpr(t1, rt); 2262 tcg_gen_and_tl(t1, t1, t2); 2263 tcg_temp_free(t2); 2264 tcg_gen_or_tl(t0, t0, t1); 2265 tcg_temp_free(t1); 2266 tcg_gen_ext32s_tl(t0, t0); 2267 gen_store_gpr(t0, rt); 2268 break; 2269 case OPC_LLE: 2270 mem_idx = MIPS_HFLAG_UM; 2271 /* fall through */ 2272 case OPC_LL: 2273 case R6_OPC_LL: 2274 op_ld_ll(t0, t0, mem_idx, ctx); 2275 gen_store_gpr(t0, rt); 2276 break; 2277 } 2278 tcg_temp_free(t0); 2279 } 2280 2281 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset, 2282 uint32_t reg1, uint32_t reg2) 2283 { 2284 TCGv taddr = tcg_temp_new(); 2285 TCGv_i64 tval = tcg_temp_new_i64(); 2286 TCGv tmp1 = tcg_temp_new(); 2287 TCGv tmp2 = tcg_temp_new(); 2288 2289 gen_base_offset_addr(ctx, taddr, base, offset); 2290 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx); 2291 #ifdef TARGET_WORDS_BIGENDIAN 2292 tcg_gen_extr_i64_tl(tmp2, tmp1, tval); 2293 #else 2294 tcg_gen_extr_i64_tl(tmp1, tmp2, tval); 2295 #endif 2296 gen_store_gpr(tmp1, reg1); 2297 tcg_temp_free(tmp1); 2298 gen_store_gpr(tmp2, reg2); 2299 tcg_temp_free(tmp2); 2300 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp)); 2301 tcg_temp_free_i64(tval); 2302 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr)); 2303 tcg_temp_free(taddr); 2304 } 2305 2306 /* Store */ 2307 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2308 int base, int offset) 2309 { 2310 TCGv t0 = tcg_temp_new(); 2311 TCGv t1 = tcg_temp_new(); 2312 int mem_idx = ctx->mem_idx; 2313 2314 gen_base_offset_addr(ctx, t0, base, offset); 2315 gen_load_gpr(t1, rt); 2316 switch (opc) { 2317 #if defined(TARGET_MIPS64) 2318 case OPC_SD: 2319 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | 2320 ctx->default_tcg_memop_mask); 2321 break; 2322 case OPC_SDL: 2323 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2324 break; 2325 case OPC_SDR: 2326 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2327 break; 2328 #endif 2329 case OPC_SWE: 2330 mem_idx = MIPS_HFLAG_UM; 2331 /* fall through */ 2332 case OPC_SW: 2333 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2334 ctx->default_tcg_memop_mask); 2335 break; 2336 case OPC_SHE: 2337 mem_idx = MIPS_HFLAG_UM; 2338 /* fall through */ 2339 case OPC_SH: 2340 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2341 ctx->default_tcg_memop_mask); 2342 break; 2343 case OPC_SBE: 2344 mem_idx = MIPS_HFLAG_UM; 2345 /* fall through */ 2346 case OPC_SB: 2347 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2348 break; 2349 case OPC_SWLE: 2350 mem_idx = MIPS_HFLAG_UM; 2351 /* fall through */ 2352 case OPC_SWL: 2353 gen_helper_0e2i(swl, t1, t0, mem_idx); 2354 break; 2355 case OPC_SWRE: 2356 mem_idx = MIPS_HFLAG_UM; 2357 /* fall through */ 2358 case OPC_SWR: 2359 gen_helper_0e2i(swr, t1, t0, mem_idx); 2360 break; 2361 } 2362 tcg_temp_free(t0); 2363 tcg_temp_free(t1); 2364 } 2365 2366 2367 /* Store conditional */ 2368 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2369 MemOp tcg_mo, bool eva) 2370 { 2371 TCGv addr, t0, val; 2372 TCGLabel *l1 = gen_new_label(); 2373 TCGLabel *done = gen_new_label(); 2374 2375 t0 = tcg_temp_new(); 2376 addr = tcg_temp_new(); 2377 /* compare the address against that of the preceding LL */ 2378 gen_base_offset_addr(ctx, addr, base, offset); 2379 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2380 tcg_temp_free(addr); 2381 tcg_gen_movi_tl(t0, 0); 2382 gen_store_gpr(t0, rt); 2383 tcg_gen_br(done); 2384 2385 gen_set_label(l1); 2386 /* generate cmpxchg */ 2387 val = tcg_temp_new(); 2388 gen_load_gpr(val, rt); 2389 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2390 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2391 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2392 gen_store_gpr(t0, rt); 2393 tcg_temp_free(val); 2394 2395 gen_set_label(done); 2396 tcg_temp_free(t0); 2397 } 2398 2399 2400 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset, 2401 uint32_t reg1, uint32_t reg2, bool eva) 2402 { 2403 TCGv taddr = tcg_temp_local_new(); 2404 TCGv lladdr = tcg_temp_local_new(); 2405 TCGv_i64 tval = tcg_temp_new_i64(); 2406 TCGv_i64 llval = tcg_temp_new_i64(); 2407 TCGv_i64 val = tcg_temp_new_i64(); 2408 TCGv tmp1 = tcg_temp_new(); 2409 TCGv tmp2 = tcg_temp_new(); 2410 TCGLabel *lab_fail = gen_new_label(); 2411 TCGLabel *lab_done = gen_new_label(); 2412 2413 gen_base_offset_addr(ctx, taddr, base, offset); 2414 2415 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr)); 2416 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail); 2417 2418 gen_load_gpr(tmp1, reg1); 2419 gen_load_gpr(tmp2, reg2); 2420 2421 #ifdef TARGET_WORDS_BIGENDIAN 2422 tcg_gen_concat_tl_i64(tval, tmp2, tmp1); 2423 #else 2424 tcg_gen_concat_tl_i64(tval, tmp1, tmp2); 2425 #endif 2426 2427 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp)); 2428 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval, 2429 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64); 2430 if (reg1 != 0) { 2431 tcg_gen_movi_tl(cpu_gpr[reg1], 1); 2432 } 2433 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done); 2434 2435 gen_set_label(lab_fail); 2436 2437 if (reg1 != 0) { 2438 tcg_gen_movi_tl(cpu_gpr[reg1], 0); 2439 } 2440 gen_set_label(lab_done); 2441 tcg_gen_movi_tl(lladdr, -1); 2442 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr)); 2443 } 2444 2445 /* Load and store */ 2446 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2447 TCGv t0) 2448 { 2449 /* 2450 * Don't do NOP if destination is zero: we must perform the actual 2451 * memory access. 2452 */ 2453 switch (opc) { 2454 case OPC_LWC1: 2455 { 2456 TCGv_i32 fp0 = tcg_temp_new_i32(); 2457 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2458 ctx->default_tcg_memop_mask); 2459 gen_store_fpr32(ctx, fp0, ft); 2460 tcg_temp_free_i32(fp0); 2461 } 2462 break; 2463 case OPC_SWC1: 2464 { 2465 TCGv_i32 fp0 = tcg_temp_new_i32(); 2466 gen_load_fpr32(ctx, fp0, ft); 2467 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2468 ctx->default_tcg_memop_mask); 2469 tcg_temp_free_i32(fp0); 2470 } 2471 break; 2472 case OPC_LDC1: 2473 { 2474 TCGv_i64 fp0 = tcg_temp_new_i64(); 2475 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2476 ctx->default_tcg_memop_mask); 2477 gen_store_fpr64(ctx, fp0, ft); 2478 tcg_temp_free_i64(fp0); 2479 } 2480 break; 2481 case OPC_SDC1: 2482 { 2483 TCGv_i64 fp0 = tcg_temp_new_i64(); 2484 gen_load_fpr64(ctx, fp0, ft); 2485 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2486 ctx->default_tcg_memop_mask); 2487 tcg_temp_free_i64(fp0); 2488 } 2489 break; 2490 default: 2491 MIPS_INVAL("flt_ldst"); 2492 gen_reserved_instruction(ctx); 2493 break; 2494 } 2495 } 2496 2497 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2498 int rs, int16_t imm) 2499 { 2500 TCGv t0 = tcg_temp_new(); 2501 2502 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2503 check_cp1_enabled(ctx); 2504 switch (op) { 2505 case OPC_LDC1: 2506 case OPC_SDC1: 2507 check_insn(ctx, ISA_MIPS2); 2508 /* Fallthrough */ 2509 default: 2510 gen_base_offset_addr(ctx, t0, rs, imm); 2511 gen_flt_ldst(ctx, op, rt, t0); 2512 } 2513 } else { 2514 generate_exception_err(ctx, EXCP_CpU, 1); 2515 } 2516 tcg_temp_free(t0); 2517 } 2518 2519 /* Arithmetic with immediate operand */ 2520 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2521 int rt, int rs, int imm) 2522 { 2523 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2524 2525 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2526 /* 2527 * If no destination, treat it as a NOP. 2528 * For addi, we must generate the overflow exception when needed. 2529 */ 2530 return; 2531 } 2532 switch (opc) { 2533 case OPC_ADDI: 2534 { 2535 TCGv t0 = tcg_temp_local_new(); 2536 TCGv t1 = tcg_temp_new(); 2537 TCGv t2 = tcg_temp_new(); 2538 TCGLabel *l1 = gen_new_label(); 2539 2540 gen_load_gpr(t1, rs); 2541 tcg_gen_addi_tl(t0, t1, uimm); 2542 tcg_gen_ext32s_tl(t0, t0); 2543 2544 tcg_gen_xori_tl(t1, t1, ~uimm); 2545 tcg_gen_xori_tl(t2, t0, uimm); 2546 tcg_gen_and_tl(t1, t1, t2); 2547 tcg_temp_free(t2); 2548 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2549 tcg_temp_free(t1); 2550 /* operands of same sign, result different sign */ 2551 generate_exception(ctx, EXCP_OVERFLOW); 2552 gen_set_label(l1); 2553 tcg_gen_ext32s_tl(t0, t0); 2554 gen_store_gpr(t0, rt); 2555 tcg_temp_free(t0); 2556 } 2557 break; 2558 case OPC_ADDIU: 2559 if (rs != 0) { 2560 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2561 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2562 } else { 2563 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2564 } 2565 break; 2566 #if defined(TARGET_MIPS64) 2567 case OPC_DADDI: 2568 { 2569 TCGv t0 = tcg_temp_local_new(); 2570 TCGv t1 = tcg_temp_new(); 2571 TCGv t2 = tcg_temp_new(); 2572 TCGLabel *l1 = gen_new_label(); 2573 2574 gen_load_gpr(t1, rs); 2575 tcg_gen_addi_tl(t0, t1, uimm); 2576 2577 tcg_gen_xori_tl(t1, t1, ~uimm); 2578 tcg_gen_xori_tl(t2, t0, uimm); 2579 tcg_gen_and_tl(t1, t1, t2); 2580 tcg_temp_free(t2); 2581 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2582 tcg_temp_free(t1); 2583 /* operands of same sign, result different sign */ 2584 generate_exception(ctx, EXCP_OVERFLOW); 2585 gen_set_label(l1); 2586 gen_store_gpr(t0, rt); 2587 tcg_temp_free(t0); 2588 } 2589 break; 2590 case OPC_DADDIU: 2591 if (rs != 0) { 2592 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2593 } else { 2594 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2595 } 2596 break; 2597 #endif 2598 } 2599 } 2600 2601 /* Logic with immediate operand */ 2602 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2603 int rt, int rs, int16_t imm) 2604 { 2605 target_ulong uimm; 2606 2607 if (rt == 0) { 2608 /* If no destination, treat it as a NOP. */ 2609 return; 2610 } 2611 uimm = (uint16_t)imm; 2612 switch (opc) { 2613 case OPC_ANDI: 2614 if (likely(rs != 0)) { 2615 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2616 } else { 2617 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2618 } 2619 break; 2620 case OPC_ORI: 2621 if (rs != 0) { 2622 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2623 } else { 2624 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2625 } 2626 break; 2627 case OPC_XORI: 2628 if (likely(rs != 0)) { 2629 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2630 } else { 2631 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2632 } 2633 break; 2634 case OPC_LUI: 2635 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2636 /* OPC_AUI */ 2637 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2638 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2639 } else { 2640 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2641 } 2642 break; 2643 2644 default: 2645 break; 2646 } 2647 } 2648 2649 /* Set on less than with immediate operand */ 2650 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2651 int rt, int rs, int16_t imm) 2652 { 2653 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2654 TCGv t0; 2655 2656 if (rt == 0) { 2657 /* If no destination, treat it as a NOP. */ 2658 return; 2659 } 2660 t0 = tcg_temp_new(); 2661 gen_load_gpr(t0, rs); 2662 switch (opc) { 2663 case OPC_SLTI: 2664 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2665 break; 2666 case OPC_SLTIU: 2667 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2668 break; 2669 } 2670 tcg_temp_free(t0); 2671 } 2672 2673 /* Shifts with immediate operand */ 2674 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2675 int rt, int rs, int16_t imm) 2676 { 2677 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2678 TCGv t0; 2679 2680 if (rt == 0) { 2681 /* If no destination, treat it as a NOP. */ 2682 return; 2683 } 2684 2685 t0 = tcg_temp_new(); 2686 gen_load_gpr(t0, rs); 2687 switch (opc) { 2688 case OPC_SLL: 2689 tcg_gen_shli_tl(t0, t0, uimm); 2690 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2691 break; 2692 case OPC_SRA: 2693 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2694 break; 2695 case OPC_SRL: 2696 if (uimm != 0) { 2697 tcg_gen_ext32u_tl(t0, t0); 2698 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2699 } else { 2700 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2701 } 2702 break; 2703 case OPC_ROTR: 2704 if (uimm != 0) { 2705 TCGv_i32 t1 = tcg_temp_new_i32(); 2706 2707 tcg_gen_trunc_tl_i32(t1, t0); 2708 tcg_gen_rotri_i32(t1, t1, uimm); 2709 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2710 tcg_temp_free_i32(t1); 2711 } else { 2712 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2713 } 2714 break; 2715 #if defined(TARGET_MIPS64) 2716 case OPC_DSLL: 2717 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2718 break; 2719 case OPC_DSRA: 2720 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2721 break; 2722 case OPC_DSRL: 2723 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2724 break; 2725 case OPC_DROTR: 2726 if (uimm != 0) { 2727 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2728 } else { 2729 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2730 } 2731 break; 2732 case OPC_DSLL32: 2733 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2734 break; 2735 case OPC_DSRA32: 2736 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2737 break; 2738 case OPC_DSRL32: 2739 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2740 break; 2741 case OPC_DROTR32: 2742 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2743 break; 2744 #endif 2745 } 2746 tcg_temp_free(t0); 2747 } 2748 2749 /* Arithmetic */ 2750 static void gen_arith(DisasContext *ctx, uint32_t opc, 2751 int rd, int rs, int rt) 2752 { 2753 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2754 && opc != OPC_DADD && opc != OPC_DSUB) { 2755 /* 2756 * If no destination, treat it as a NOP. 2757 * For add & sub, we must generate the overflow exception when needed. 2758 */ 2759 return; 2760 } 2761 2762 switch (opc) { 2763 case OPC_ADD: 2764 { 2765 TCGv t0 = tcg_temp_local_new(); 2766 TCGv t1 = tcg_temp_new(); 2767 TCGv t2 = tcg_temp_new(); 2768 TCGLabel *l1 = gen_new_label(); 2769 2770 gen_load_gpr(t1, rs); 2771 gen_load_gpr(t2, rt); 2772 tcg_gen_add_tl(t0, t1, t2); 2773 tcg_gen_ext32s_tl(t0, t0); 2774 tcg_gen_xor_tl(t1, t1, t2); 2775 tcg_gen_xor_tl(t2, t0, t2); 2776 tcg_gen_andc_tl(t1, t2, t1); 2777 tcg_temp_free(t2); 2778 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2779 tcg_temp_free(t1); 2780 /* operands of same sign, result different sign */ 2781 generate_exception(ctx, EXCP_OVERFLOW); 2782 gen_set_label(l1); 2783 gen_store_gpr(t0, rd); 2784 tcg_temp_free(t0); 2785 } 2786 break; 2787 case OPC_ADDU: 2788 if (rs != 0 && rt != 0) { 2789 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2790 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2791 } else if (rs == 0 && rt != 0) { 2792 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2793 } else if (rs != 0 && rt == 0) { 2794 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2795 } else { 2796 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2797 } 2798 break; 2799 case OPC_SUB: 2800 { 2801 TCGv t0 = tcg_temp_local_new(); 2802 TCGv t1 = tcg_temp_new(); 2803 TCGv t2 = tcg_temp_new(); 2804 TCGLabel *l1 = gen_new_label(); 2805 2806 gen_load_gpr(t1, rs); 2807 gen_load_gpr(t2, rt); 2808 tcg_gen_sub_tl(t0, t1, t2); 2809 tcg_gen_ext32s_tl(t0, t0); 2810 tcg_gen_xor_tl(t2, t1, t2); 2811 tcg_gen_xor_tl(t1, t0, t1); 2812 tcg_gen_and_tl(t1, t1, t2); 2813 tcg_temp_free(t2); 2814 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2815 tcg_temp_free(t1); 2816 /* 2817 * operands of different sign, first operand and the result 2818 * of different sign 2819 */ 2820 generate_exception(ctx, EXCP_OVERFLOW); 2821 gen_set_label(l1); 2822 gen_store_gpr(t0, rd); 2823 tcg_temp_free(t0); 2824 } 2825 break; 2826 case OPC_SUBU: 2827 if (rs != 0 && rt != 0) { 2828 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2829 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2830 } else if (rs == 0 && rt != 0) { 2831 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2832 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2833 } else if (rs != 0 && rt == 0) { 2834 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2835 } else { 2836 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2837 } 2838 break; 2839 #if defined(TARGET_MIPS64) 2840 case OPC_DADD: 2841 { 2842 TCGv t0 = tcg_temp_local_new(); 2843 TCGv t1 = tcg_temp_new(); 2844 TCGv t2 = tcg_temp_new(); 2845 TCGLabel *l1 = gen_new_label(); 2846 2847 gen_load_gpr(t1, rs); 2848 gen_load_gpr(t2, rt); 2849 tcg_gen_add_tl(t0, t1, t2); 2850 tcg_gen_xor_tl(t1, t1, t2); 2851 tcg_gen_xor_tl(t2, t0, t2); 2852 tcg_gen_andc_tl(t1, t2, t1); 2853 tcg_temp_free(t2); 2854 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2855 tcg_temp_free(t1); 2856 /* operands of same sign, result different sign */ 2857 generate_exception(ctx, EXCP_OVERFLOW); 2858 gen_set_label(l1); 2859 gen_store_gpr(t0, rd); 2860 tcg_temp_free(t0); 2861 } 2862 break; 2863 case OPC_DADDU: 2864 if (rs != 0 && rt != 0) { 2865 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2866 } else if (rs == 0 && rt != 0) { 2867 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2868 } else if (rs != 0 && rt == 0) { 2869 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2870 } else { 2871 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2872 } 2873 break; 2874 case OPC_DSUB: 2875 { 2876 TCGv t0 = tcg_temp_local_new(); 2877 TCGv t1 = tcg_temp_new(); 2878 TCGv t2 = tcg_temp_new(); 2879 TCGLabel *l1 = gen_new_label(); 2880 2881 gen_load_gpr(t1, rs); 2882 gen_load_gpr(t2, rt); 2883 tcg_gen_sub_tl(t0, t1, t2); 2884 tcg_gen_xor_tl(t2, t1, t2); 2885 tcg_gen_xor_tl(t1, t0, t1); 2886 tcg_gen_and_tl(t1, t1, t2); 2887 tcg_temp_free(t2); 2888 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2889 tcg_temp_free(t1); 2890 /* 2891 * Operands of different sign, first operand and result different 2892 * sign. 2893 */ 2894 generate_exception(ctx, EXCP_OVERFLOW); 2895 gen_set_label(l1); 2896 gen_store_gpr(t0, rd); 2897 tcg_temp_free(t0); 2898 } 2899 break; 2900 case OPC_DSUBU: 2901 if (rs != 0 && rt != 0) { 2902 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2903 } else if (rs == 0 && rt != 0) { 2904 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2905 } else if (rs != 0 && rt == 0) { 2906 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2907 } else { 2908 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2909 } 2910 break; 2911 #endif 2912 case OPC_MUL: 2913 if (likely(rs != 0 && rt != 0)) { 2914 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2915 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2916 } else { 2917 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2918 } 2919 break; 2920 } 2921 } 2922 2923 /* Conditional move */ 2924 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2925 int rd, int rs, int rt) 2926 { 2927 TCGv t0, t1, t2; 2928 2929 if (rd == 0) { 2930 /* If no destination, treat it as a NOP. */ 2931 return; 2932 } 2933 2934 t0 = tcg_temp_new(); 2935 gen_load_gpr(t0, rt); 2936 t1 = tcg_const_tl(0); 2937 t2 = tcg_temp_new(); 2938 gen_load_gpr(t2, rs); 2939 switch (opc) { 2940 case OPC_MOVN: 2941 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2942 break; 2943 case OPC_MOVZ: 2944 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2945 break; 2946 case OPC_SELNEZ: 2947 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2948 break; 2949 case OPC_SELEQZ: 2950 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2951 break; 2952 } 2953 tcg_temp_free(t2); 2954 tcg_temp_free(t1); 2955 tcg_temp_free(t0); 2956 } 2957 2958 /* Logic */ 2959 static void gen_logic(DisasContext *ctx, uint32_t opc, 2960 int rd, int rs, int rt) 2961 { 2962 if (rd == 0) { 2963 /* If no destination, treat it as a NOP. */ 2964 return; 2965 } 2966 2967 switch (opc) { 2968 case OPC_AND: 2969 if (likely(rs != 0 && rt != 0)) { 2970 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2971 } else { 2972 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2973 } 2974 break; 2975 case OPC_NOR: 2976 if (rs != 0 && rt != 0) { 2977 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2978 } else if (rs == 0 && rt != 0) { 2979 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2980 } else if (rs != 0 && rt == 0) { 2981 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2982 } else { 2983 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2984 } 2985 break; 2986 case OPC_OR: 2987 if (likely(rs != 0 && rt != 0)) { 2988 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2989 } else if (rs == 0 && rt != 0) { 2990 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2991 } else if (rs != 0 && rt == 0) { 2992 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2993 } else { 2994 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2995 } 2996 break; 2997 case OPC_XOR: 2998 if (likely(rs != 0 && rt != 0)) { 2999 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 3000 } else if (rs == 0 && rt != 0) { 3001 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 3002 } else if (rs != 0 && rt == 0) { 3003 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 3004 } else { 3005 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3006 } 3007 break; 3008 } 3009 } 3010 3011 /* Set on lower than */ 3012 static void gen_slt(DisasContext *ctx, uint32_t opc, 3013 int rd, int rs, int rt) 3014 { 3015 TCGv t0, t1; 3016 3017 if (rd == 0) { 3018 /* If no destination, treat it as a NOP. */ 3019 return; 3020 } 3021 3022 t0 = tcg_temp_new(); 3023 t1 = tcg_temp_new(); 3024 gen_load_gpr(t0, rs); 3025 gen_load_gpr(t1, rt); 3026 switch (opc) { 3027 case OPC_SLT: 3028 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 3029 break; 3030 case OPC_SLTU: 3031 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 3032 break; 3033 } 3034 tcg_temp_free(t0); 3035 tcg_temp_free(t1); 3036 } 3037 3038 /* Shifts */ 3039 static void gen_shift(DisasContext *ctx, uint32_t opc, 3040 int rd, int rs, int rt) 3041 { 3042 TCGv t0, t1; 3043 3044 if (rd == 0) { 3045 /* 3046 * If no destination, treat it as a NOP. 3047 * For add & sub, we must generate the overflow exception when needed. 3048 */ 3049 return; 3050 } 3051 3052 t0 = tcg_temp_new(); 3053 t1 = tcg_temp_new(); 3054 gen_load_gpr(t0, rs); 3055 gen_load_gpr(t1, rt); 3056 switch (opc) { 3057 case OPC_SLLV: 3058 tcg_gen_andi_tl(t0, t0, 0x1f); 3059 tcg_gen_shl_tl(t0, t1, t0); 3060 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 3061 break; 3062 case OPC_SRAV: 3063 tcg_gen_andi_tl(t0, t0, 0x1f); 3064 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 3065 break; 3066 case OPC_SRLV: 3067 tcg_gen_ext32u_tl(t1, t1); 3068 tcg_gen_andi_tl(t0, t0, 0x1f); 3069 tcg_gen_shr_tl(t0, t1, t0); 3070 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 3071 break; 3072 case OPC_ROTRV: 3073 { 3074 TCGv_i32 t2 = tcg_temp_new_i32(); 3075 TCGv_i32 t3 = tcg_temp_new_i32(); 3076 3077 tcg_gen_trunc_tl_i32(t2, t0); 3078 tcg_gen_trunc_tl_i32(t3, t1); 3079 tcg_gen_andi_i32(t2, t2, 0x1f); 3080 tcg_gen_rotr_i32(t2, t3, t2); 3081 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3082 tcg_temp_free_i32(t2); 3083 tcg_temp_free_i32(t3); 3084 } 3085 break; 3086 #if defined(TARGET_MIPS64) 3087 case OPC_DSLLV: 3088 tcg_gen_andi_tl(t0, t0, 0x3f); 3089 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 3090 break; 3091 case OPC_DSRAV: 3092 tcg_gen_andi_tl(t0, t0, 0x3f); 3093 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 3094 break; 3095 case OPC_DSRLV: 3096 tcg_gen_andi_tl(t0, t0, 0x3f); 3097 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 3098 break; 3099 case OPC_DROTRV: 3100 tcg_gen_andi_tl(t0, t0, 0x3f); 3101 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 3102 break; 3103 #endif 3104 } 3105 tcg_temp_free(t0); 3106 tcg_temp_free(t1); 3107 } 3108 3109 /* Arithmetic on HI/LO registers */ 3110 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 3111 { 3112 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 3113 /* Treat as NOP. */ 3114 return; 3115 } 3116 3117 if (acc != 0) { 3118 check_dsp(ctx); 3119 } 3120 3121 switch (opc) { 3122 case OPC_MFHI: 3123 #if defined(TARGET_MIPS64) 3124 if (acc != 0) { 3125 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 3126 } else 3127 #endif 3128 { 3129 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 3130 } 3131 break; 3132 case OPC_MFLO: 3133 #if defined(TARGET_MIPS64) 3134 if (acc != 0) { 3135 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3136 } else 3137 #endif 3138 { 3139 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3140 } 3141 break; 3142 case OPC_MTHI: 3143 if (reg != 0) { 3144 #if defined(TARGET_MIPS64) 3145 if (acc != 0) { 3146 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3147 } else 3148 #endif 3149 { 3150 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3151 } 3152 } else { 3153 tcg_gen_movi_tl(cpu_HI[acc], 0); 3154 } 3155 break; 3156 case OPC_MTLO: 3157 if (reg != 0) { 3158 #if defined(TARGET_MIPS64) 3159 if (acc != 0) { 3160 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3161 } else 3162 #endif 3163 { 3164 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3165 } 3166 } else { 3167 tcg_gen_movi_tl(cpu_LO[acc], 0); 3168 } 3169 break; 3170 } 3171 } 3172 3173 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3174 MemOp memop) 3175 { 3176 TCGv t0 = tcg_const_tl(addr); 3177 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3178 gen_store_gpr(t0, reg); 3179 tcg_temp_free(t0); 3180 } 3181 3182 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3183 int rs) 3184 { 3185 target_long offset; 3186 target_long addr; 3187 3188 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3189 case OPC_ADDIUPC: 3190 if (rs != 0) { 3191 offset = sextract32(ctx->opcode << 2, 0, 21); 3192 addr = addr_add(ctx, pc, offset); 3193 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3194 } 3195 break; 3196 case R6_OPC_LWPC: 3197 offset = sextract32(ctx->opcode << 2, 0, 21); 3198 addr = addr_add(ctx, pc, offset); 3199 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3200 break; 3201 #if defined(TARGET_MIPS64) 3202 case OPC_LWUPC: 3203 check_mips_64(ctx); 3204 offset = sextract32(ctx->opcode << 2, 0, 21); 3205 addr = addr_add(ctx, pc, offset); 3206 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3207 break; 3208 #endif 3209 default: 3210 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3211 case OPC_AUIPC: 3212 if (rs != 0) { 3213 offset = sextract32(ctx->opcode, 0, 16) << 16; 3214 addr = addr_add(ctx, pc, offset); 3215 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3216 } 3217 break; 3218 case OPC_ALUIPC: 3219 if (rs != 0) { 3220 offset = sextract32(ctx->opcode, 0, 16) << 16; 3221 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3222 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3223 } 3224 break; 3225 #if defined(TARGET_MIPS64) 3226 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3227 case R6_OPC_LDPC + (1 << 16): 3228 case R6_OPC_LDPC + (2 << 16): 3229 case R6_OPC_LDPC + (3 << 16): 3230 check_mips_64(ctx); 3231 offset = sextract32(ctx->opcode << 3, 0, 21); 3232 addr = addr_add(ctx, (pc & ~0x7), offset); 3233 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ); 3234 break; 3235 #endif 3236 default: 3237 MIPS_INVAL("OPC_PCREL"); 3238 gen_reserved_instruction(ctx); 3239 break; 3240 } 3241 break; 3242 } 3243 } 3244 3245 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3246 { 3247 TCGv t0, t1; 3248 3249 if (rd == 0) { 3250 /* Treat as NOP. */ 3251 return; 3252 } 3253 3254 t0 = tcg_temp_new(); 3255 t1 = tcg_temp_new(); 3256 3257 gen_load_gpr(t0, rs); 3258 gen_load_gpr(t1, rt); 3259 3260 switch (opc) { 3261 case R6_OPC_DIV: 3262 { 3263 TCGv t2 = tcg_temp_new(); 3264 TCGv t3 = tcg_temp_new(); 3265 tcg_gen_ext32s_tl(t0, t0); 3266 tcg_gen_ext32s_tl(t1, t1); 3267 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3268 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3269 tcg_gen_and_tl(t2, t2, t3); 3270 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3271 tcg_gen_or_tl(t2, t2, t3); 3272 tcg_gen_movi_tl(t3, 0); 3273 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3274 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3276 tcg_temp_free(t3); 3277 tcg_temp_free(t2); 3278 } 3279 break; 3280 case R6_OPC_MOD: 3281 { 3282 TCGv t2 = tcg_temp_new(); 3283 TCGv t3 = tcg_temp_new(); 3284 tcg_gen_ext32s_tl(t0, t0); 3285 tcg_gen_ext32s_tl(t1, t1); 3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3287 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3288 tcg_gen_and_tl(t2, t2, t3); 3289 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3290 tcg_gen_or_tl(t2, t2, t3); 3291 tcg_gen_movi_tl(t3, 0); 3292 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3293 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3294 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3295 tcg_temp_free(t3); 3296 tcg_temp_free(t2); 3297 } 3298 break; 3299 case R6_OPC_DIVU: 3300 { 3301 TCGv t2 = tcg_const_tl(0); 3302 TCGv t3 = tcg_const_tl(1); 3303 tcg_gen_ext32u_tl(t0, t0); 3304 tcg_gen_ext32u_tl(t1, t1); 3305 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3306 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3307 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3308 tcg_temp_free(t3); 3309 tcg_temp_free(t2); 3310 } 3311 break; 3312 case R6_OPC_MODU: 3313 { 3314 TCGv t2 = tcg_const_tl(0); 3315 TCGv t3 = tcg_const_tl(1); 3316 tcg_gen_ext32u_tl(t0, t0); 3317 tcg_gen_ext32u_tl(t1, t1); 3318 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3319 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3320 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3321 tcg_temp_free(t3); 3322 tcg_temp_free(t2); 3323 } 3324 break; 3325 case R6_OPC_MUL: 3326 { 3327 TCGv_i32 t2 = tcg_temp_new_i32(); 3328 TCGv_i32 t3 = tcg_temp_new_i32(); 3329 tcg_gen_trunc_tl_i32(t2, t0); 3330 tcg_gen_trunc_tl_i32(t3, t1); 3331 tcg_gen_mul_i32(t2, t2, t3); 3332 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3333 tcg_temp_free_i32(t2); 3334 tcg_temp_free_i32(t3); 3335 } 3336 break; 3337 case R6_OPC_MUH: 3338 { 3339 TCGv_i32 t2 = tcg_temp_new_i32(); 3340 TCGv_i32 t3 = tcg_temp_new_i32(); 3341 tcg_gen_trunc_tl_i32(t2, t0); 3342 tcg_gen_trunc_tl_i32(t3, t1); 3343 tcg_gen_muls2_i32(t2, t3, t2, t3); 3344 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3345 tcg_temp_free_i32(t2); 3346 tcg_temp_free_i32(t3); 3347 } 3348 break; 3349 case R6_OPC_MULU: 3350 { 3351 TCGv_i32 t2 = tcg_temp_new_i32(); 3352 TCGv_i32 t3 = tcg_temp_new_i32(); 3353 tcg_gen_trunc_tl_i32(t2, t0); 3354 tcg_gen_trunc_tl_i32(t3, t1); 3355 tcg_gen_mul_i32(t2, t2, t3); 3356 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3357 tcg_temp_free_i32(t2); 3358 tcg_temp_free_i32(t3); 3359 } 3360 break; 3361 case R6_OPC_MUHU: 3362 { 3363 TCGv_i32 t2 = tcg_temp_new_i32(); 3364 TCGv_i32 t3 = tcg_temp_new_i32(); 3365 tcg_gen_trunc_tl_i32(t2, t0); 3366 tcg_gen_trunc_tl_i32(t3, t1); 3367 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3368 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3369 tcg_temp_free_i32(t2); 3370 tcg_temp_free_i32(t3); 3371 } 3372 break; 3373 #if defined(TARGET_MIPS64) 3374 case R6_OPC_DDIV: 3375 { 3376 TCGv t2 = tcg_temp_new(); 3377 TCGv t3 = tcg_temp_new(); 3378 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3380 tcg_gen_and_tl(t2, t2, t3); 3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3382 tcg_gen_or_tl(t2, t2, t3); 3383 tcg_gen_movi_tl(t3, 0); 3384 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3385 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3386 tcg_temp_free(t3); 3387 tcg_temp_free(t2); 3388 } 3389 break; 3390 case R6_OPC_DMOD: 3391 { 3392 TCGv t2 = tcg_temp_new(); 3393 TCGv t3 = tcg_temp_new(); 3394 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3395 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3396 tcg_gen_and_tl(t2, t2, t3); 3397 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3398 tcg_gen_or_tl(t2, t2, t3); 3399 tcg_gen_movi_tl(t3, 0); 3400 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3401 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3402 tcg_temp_free(t3); 3403 tcg_temp_free(t2); 3404 } 3405 break; 3406 case R6_OPC_DDIVU: 3407 { 3408 TCGv t2 = tcg_const_tl(0); 3409 TCGv t3 = tcg_const_tl(1); 3410 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3411 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3412 tcg_temp_free(t3); 3413 tcg_temp_free(t2); 3414 } 3415 break; 3416 case R6_OPC_DMODU: 3417 { 3418 TCGv t2 = tcg_const_tl(0); 3419 TCGv t3 = tcg_const_tl(1); 3420 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3421 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3422 tcg_temp_free(t3); 3423 tcg_temp_free(t2); 3424 } 3425 break; 3426 case R6_OPC_DMUL: 3427 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3428 break; 3429 case R6_OPC_DMUH: 3430 { 3431 TCGv t2 = tcg_temp_new(); 3432 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3433 tcg_temp_free(t2); 3434 } 3435 break; 3436 case R6_OPC_DMULU: 3437 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3438 break; 3439 case R6_OPC_DMUHU: 3440 { 3441 TCGv t2 = tcg_temp_new(); 3442 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3443 tcg_temp_free(t2); 3444 } 3445 break; 3446 #endif 3447 default: 3448 MIPS_INVAL("r6 mul/div"); 3449 gen_reserved_instruction(ctx); 3450 goto out; 3451 } 3452 out: 3453 tcg_temp_free(t0); 3454 tcg_temp_free(t1); 3455 } 3456 3457 #if defined(TARGET_MIPS64) 3458 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3459 { 3460 TCGv t0, t1; 3461 3462 t0 = tcg_temp_new(); 3463 t1 = tcg_temp_new(); 3464 3465 gen_load_gpr(t0, rs); 3466 gen_load_gpr(t1, rt); 3467 3468 switch (opc) { 3469 case MMI_OPC_DIV1: 3470 { 3471 TCGv t2 = tcg_temp_new(); 3472 TCGv t3 = tcg_temp_new(); 3473 tcg_gen_ext32s_tl(t0, t0); 3474 tcg_gen_ext32s_tl(t1, t1); 3475 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3476 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3477 tcg_gen_and_tl(t2, t2, t3); 3478 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3479 tcg_gen_or_tl(t2, t2, t3); 3480 tcg_gen_movi_tl(t3, 0); 3481 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3482 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3483 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3484 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3485 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3486 tcg_temp_free(t3); 3487 tcg_temp_free(t2); 3488 } 3489 break; 3490 case MMI_OPC_DIVU1: 3491 { 3492 TCGv t2 = tcg_const_tl(0); 3493 TCGv t3 = tcg_const_tl(1); 3494 tcg_gen_ext32u_tl(t0, t0); 3495 tcg_gen_ext32u_tl(t1, t1); 3496 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3497 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3498 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3499 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3500 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3501 tcg_temp_free(t3); 3502 tcg_temp_free(t2); 3503 } 3504 break; 3505 default: 3506 MIPS_INVAL("div1 TX79"); 3507 gen_reserved_instruction(ctx); 3508 goto out; 3509 } 3510 out: 3511 tcg_temp_free(t0); 3512 tcg_temp_free(t1); 3513 } 3514 #endif 3515 3516 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3517 int acc, int rs, int rt) 3518 { 3519 TCGv t0, t1; 3520 3521 t0 = tcg_temp_new(); 3522 t1 = tcg_temp_new(); 3523 3524 gen_load_gpr(t0, rs); 3525 gen_load_gpr(t1, rt); 3526 3527 if (acc != 0) { 3528 check_dsp(ctx); 3529 } 3530 3531 switch (opc) { 3532 case OPC_DIV: 3533 { 3534 TCGv t2 = tcg_temp_new(); 3535 TCGv t3 = tcg_temp_new(); 3536 tcg_gen_ext32s_tl(t0, t0); 3537 tcg_gen_ext32s_tl(t1, t1); 3538 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3539 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3540 tcg_gen_and_tl(t2, t2, t3); 3541 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3542 tcg_gen_or_tl(t2, t2, t3); 3543 tcg_gen_movi_tl(t3, 0); 3544 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3545 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3546 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3547 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3548 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3549 tcg_temp_free(t3); 3550 tcg_temp_free(t2); 3551 } 3552 break; 3553 case OPC_DIVU: 3554 { 3555 TCGv t2 = tcg_const_tl(0); 3556 TCGv t3 = tcg_const_tl(1); 3557 tcg_gen_ext32u_tl(t0, t0); 3558 tcg_gen_ext32u_tl(t1, t1); 3559 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3560 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3561 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3562 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3563 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3564 tcg_temp_free(t3); 3565 tcg_temp_free(t2); 3566 } 3567 break; 3568 case OPC_MULT: 3569 { 3570 TCGv_i32 t2 = tcg_temp_new_i32(); 3571 TCGv_i32 t3 = tcg_temp_new_i32(); 3572 tcg_gen_trunc_tl_i32(t2, t0); 3573 tcg_gen_trunc_tl_i32(t3, t1); 3574 tcg_gen_muls2_i32(t2, t3, t2, t3); 3575 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3576 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3577 tcg_temp_free_i32(t2); 3578 tcg_temp_free_i32(t3); 3579 } 3580 break; 3581 case OPC_MULTU: 3582 { 3583 TCGv_i32 t2 = tcg_temp_new_i32(); 3584 TCGv_i32 t3 = tcg_temp_new_i32(); 3585 tcg_gen_trunc_tl_i32(t2, t0); 3586 tcg_gen_trunc_tl_i32(t3, t1); 3587 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3588 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3589 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3590 tcg_temp_free_i32(t2); 3591 tcg_temp_free_i32(t3); 3592 } 3593 break; 3594 #if defined(TARGET_MIPS64) 3595 case OPC_DDIV: 3596 { 3597 TCGv t2 = tcg_temp_new(); 3598 TCGv t3 = tcg_temp_new(); 3599 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3600 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3601 tcg_gen_and_tl(t2, t2, t3); 3602 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3603 tcg_gen_or_tl(t2, t2, t3); 3604 tcg_gen_movi_tl(t3, 0); 3605 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3606 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3607 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3608 tcg_temp_free(t3); 3609 tcg_temp_free(t2); 3610 } 3611 break; 3612 case OPC_DDIVU: 3613 { 3614 TCGv t2 = tcg_const_tl(0); 3615 TCGv t3 = tcg_const_tl(1); 3616 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3617 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3618 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3619 tcg_temp_free(t3); 3620 tcg_temp_free(t2); 3621 } 3622 break; 3623 case OPC_DMULT: 3624 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3625 break; 3626 case OPC_DMULTU: 3627 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3628 break; 3629 #endif 3630 case OPC_MADD: 3631 { 3632 TCGv_i64 t2 = tcg_temp_new_i64(); 3633 TCGv_i64 t3 = tcg_temp_new_i64(); 3634 3635 tcg_gen_ext_tl_i64(t2, t0); 3636 tcg_gen_ext_tl_i64(t3, t1); 3637 tcg_gen_mul_i64(t2, t2, t3); 3638 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3639 tcg_gen_add_i64(t2, t2, t3); 3640 tcg_temp_free_i64(t3); 3641 gen_move_low32(cpu_LO[acc], t2); 3642 gen_move_high32(cpu_HI[acc], t2); 3643 tcg_temp_free_i64(t2); 3644 } 3645 break; 3646 case OPC_MADDU: 3647 { 3648 TCGv_i64 t2 = tcg_temp_new_i64(); 3649 TCGv_i64 t3 = tcg_temp_new_i64(); 3650 3651 tcg_gen_ext32u_tl(t0, t0); 3652 tcg_gen_ext32u_tl(t1, t1); 3653 tcg_gen_extu_tl_i64(t2, t0); 3654 tcg_gen_extu_tl_i64(t3, t1); 3655 tcg_gen_mul_i64(t2, t2, t3); 3656 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3657 tcg_gen_add_i64(t2, t2, t3); 3658 tcg_temp_free_i64(t3); 3659 gen_move_low32(cpu_LO[acc], t2); 3660 gen_move_high32(cpu_HI[acc], t2); 3661 tcg_temp_free_i64(t2); 3662 } 3663 break; 3664 case OPC_MSUB: 3665 { 3666 TCGv_i64 t2 = tcg_temp_new_i64(); 3667 TCGv_i64 t3 = tcg_temp_new_i64(); 3668 3669 tcg_gen_ext_tl_i64(t2, t0); 3670 tcg_gen_ext_tl_i64(t3, t1); 3671 tcg_gen_mul_i64(t2, t2, t3); 3672 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3673 tcg_gen_sub_i64(t2, t3, t2); 3674 tcg_temp_free_i64(t3); 3675 gen_move_low32(cpu_LO[acc], t2); 3676 gen_move_high32(cpu_HI[acc], t2); 3677 tcg_temp_free_i64(t2); 3678 } 3679 break; 3680 case OPC_MSUBU: 3681 { 3682 TCGv_i64 t2 = tcg_temp_new_i64(); 3683 TCGv_i64 t3 = tcg_temp_new_i64(); 3684 3685 tcg_gen_ext32u_tl(t0, t0); 3686 tcg_gen_ext32u_tl(t1, t1); 3687 tcg_gen_extu_tl_i64(t2, t0); 3688 tcg_gen_extu_tl_i64(t3, t1); 3689 tcg_gen_mul_i64(t2, t2, t3); 3690 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3691 tcg_gen_sub_i64(t2, t3, t2); 3692 tcg_temp_free_i64(t3); 3693 gen_move_low32(cpu_LO[acc], t2); 3694 gen_move_high32(cpu_HI[acc], t2); 3695 tcg_temp_free_i64(t2); 3696 } 3697 break; 3698 default: 3699 MIPS_INVAL("mul/div"); 3700 gen_reserved_instruction(ctx); 3701 goto out; 3702 } 3703 out: 3704 tcg_temp_free(t0); 3705 tcg_temp_free(t1); 3706 } 3707 3708 /* 3709 * These MULT[U] and MADD[U] instructions implemented in for example 3710 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3711 * architectures are special three-operand variants with the syntax 3712 * 3713 * MULT[U][1] rd, rs, rt 3714 * 3715 * such that 3716 * 3717 * (rd, LO, HI) <- rs * rt 3718 * 3719 * and 3720 * 3721 * MADD[U][1] rd, rs, rt 3722 * 3723 * such that 3724 * 3725 * (rd, LO, HI) <- (LO, HI) + rs * rt 3726 * 3727 * where the low-order 32-bits of the result is placed into both the 3728 * GPR rd and the special register LO. The high-order 32-bits of the 3729 * result is placed into the special register HI. 3730 * 3731 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3732 * which is the zero register that always reads as 0. 3733 */ 3734 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3735 int rd, int rs, int rt) 3736 { 3737 TCGv t0 = tcg_temp_new(); 3738 TCGv t1 = tcg_temp_new(); 3739 int acc = 0; 3740 3741 gen_load_gpr(t0, rs); 3742 gen_load_gpr(t1, rt); 3743 3744 switch (opc) { 3745 case MMI_OPC_MULT1: 3746 acc = 1; 3747 /* Fall through */ 3748 case OPC_MULT: 3749 { 3750 TCGv_i32 t2 = tcg_temp_new_i32(); 3751 TCGv_i32 t3 = tcg_temp_new_i32(); 3752 tcg_gen_trunc_tl_i32(t2, t0); 3753 tcg_gen_trunc_tl_i32(t3, t1); 3754 tcg_gen_muls2_i32(t2, t3, t2, t3); 3755 if (rd) { 3756 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3757 } 3758 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3759 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3760 tcg_temp_free_i32(t2); 3761 tcg_temp_free_i32(t3); 3762 } 3763 break; 3764 case MMI_OPC_MULTU1: 3765 acc = 1; 3766 /* Fall through */ 3767 case OPC_MULTU: 3768 { 3769 TCGv_i32 t2 = tcg_temp_new_i32(); 3770 TCGv_i32 t3 = tcg_temp_new_i32(); 3771 tcg_gen_trunc_tl_i32(t2, t0); 3772 tcg_gen_trunc_tl_i32(t3, t1); 3773 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3774 if (rd) { 3775 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3776 } 3777 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3778 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3779 tcg_temp_free_i32(t2); 3780 tcg_temp_free_i32(t3); 3781 } 3782 break; 3783 case MMI_OPC_MADD1: 3784 acc = 1; 3785 /* Fall through */ 3786 case MMI_OPC_MADD: 3787 { 3788 TCGv_i64 t2 = tcg_temp_new_i64(); 3789 TCGv_i64 t3 = tcg_temp_new_i64(); 3790 3791 tcg_gen_ext_tl_i64(t2, t0); 3792 tcg_gen_ext_tl_i64(t3, t1); 3793 tcg_gen_mul_i64(t2, t2, t3); 3794 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3795 tcg_gen_add_i64(t2, t2, t3); 3796 tcg_temp_free_i64(t3); 3797 gen_move_low32(cpu_LO[acc], t2); 3798 gen_move_high32(cpu_HI[acc], t2); 3799 if (rd) { 3800 gen_move_low32(cpu_gpr[rd], t2); 3801 } 3802 tcg_temp_free_i64(t2); 3803 } 3804 break; 3805 case MMI_OPC_MADDU1: 3806 acc = 1; 3807 /* Fall through */ 3808 case MMI_OPC_MADDU: 3809 { 3810 TCGv_i64 t2 = tcg_temp_new_i64(); 3811 TCGv_i64 t3 = tcg_temp_new_i64(); 3812 3813 tcg_gen_ext32u_tl(t0, t0); 3814 tcg_gen_ext32u_tl(t1, t1); 3815 tcg_gen_extu_tl_i64(t2, t0); 3816 tcg_gen_extu_tl_i64(t3, t1); 3817 tcg_gen_mul_i64(t2, t2, t3); 3818 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3819 tcg_gen_add_i64(t2, t2, t3); 3820 tcg_temp_free_i64(t3); 3821 gen_move_low32(cpu_LO[acc], t2); 3822 gen_move_high32(cpu_HI[acc], t2); 3823 if (rd) { 3824 gen_move_low32(cpu_gpr[rd], t2); 3825 } 3826 tcg_temp_free_i64(t2); 3827 } 3828 break; 3829 default: 3830 MIPS_INVAL("mul/madd TXx9"); 3831 gen_reserved_instruction(ctx); 3832 goto out; 3833 } 3834 3835 out: 3836 tcg_temp_free(t0); 3837 tcg_temp_free(t1); 3838 } 3839 3840 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, 3841 int rd, int rs, int rt) 3842 { 3843 TCGv t0 = tcg_temp_new(); 3844 TCGv t1 = tcg_temp_new(); 3845 3846 gen_load_gpr(t0, rs); 3847 gen_load_gpr(t1, rt); 3848 3849 switch (opc) { 3850 case OPC_VR54XX_MULS: 3851 gen_helper_muls(t0, cpu_env, t0, t1); 3852 break; 3853 case OPC_VR54XX_MULSU: 3854 gen_helper_mulsu(t0, cpu_env, t0, t1); 3855 break; 3856 case OPC_VR54XX_MACC: 3857 gen_helper_macc(t0, cpu_env, t0, t1); 3858 break; 3859 case OPC_VR54XX_MACCU: 3860 gen_helper_maccu(t0, cpu_env, t0, t1); 3861 break; 3862 case OPC_VR54XX_MSAC: 3863 gen_helper_msac(t0, cpu_env, t0, t1); 3864 break; 3865 case OPC_VR54XX_MSACU: 3866 gen_helper_msacu(t0, cpu_env, t0, t1); 3867 break; 3868 case OPC_VR54XX_MULHI: 3869 gen_helper_mulhi(t0, cpu_env, t0, t1); 3870 break; 3871 case OPC_VR54XX_MULHIU: 3872 gen_helper_mulhiu(t0, cpu_env, t0, t1); 3873 break; 3874 case OPC_VR54XX_MULSHI: 3875 gen_helper_mulshi(t0, cpu_env, t0, t1); 3876 break; 3877 case OPC_VR54XX_MULSHIU: 3878 gen_helper_mulshiu(t0, cpu_env, t0, t1); 3879 break; 3880 case OPC_VR54XX_MACCHI: 3881 gen_helper_macchi(t0, cpu_env, t0, t1); 3882 break; 3883 case OPC_VR54XX_MACCHIU: 3884 gen_helper_macchiu(t0, cpu_env, t0, t1); 3885 break; 3886 case OPC_VR54XX_MSACHI: 3887 gen_helper_msachi(t0, cpu_env, t0, t1); 3888 break; 3889 case OPC_VR54XX_MSACHIU: 3890 gen_helper_msachiu(t0, cpu_env, t0, t1); 3891 break; 3892 default: 3893 MIPS_INVAL("mul vr54xx"); 3894 gen_reserved_instruction(ctx); 3895 goto out; 3896 } 3897 gen_store_gpr(t0, rd); 3898 3899 out: 3900 tcg_temp_free(t0); 3901 tcg_temp_free(t1); 3902 } 3903 3904 static void gen_cl(DisasContext *ctx, uint32_t opc, 3905 int rd, int rs) 3906 { 3907 TCGv t0; 3908 3909 if (rd == 0) { 3910 /* Treat as NOP. */ 3911 return; 3912 } 3913 t0 = cpu_gpr[rd]; 3914 gen_load_gpr(t0, rs); 3915 3916 switch (opc) { 3917 case OPC_CLO: 3918 case R6_OPC_CLO: 3919 #if defined(TARGET_MIPS64) 3920 case OPC_DCLO: 3921 case R6_OPC_DCLO: 3922 #endif 3923 tcg_gen_not_tl(t0, t0); 3924 break; 3925 } 3926 3927 switch (opc) { 3928 case OPC_CLO: 3929 case R6_OPC_CLO: 3930 case OPC_CLZ: 3931 case R6_OPC_CLZ: 3932 tcg_gen_ext32u_tl(t0, t0); 3933 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3934 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3935 break; 3936 #if defined(TARGET_MIPS64) 3937 case OPC_DCLO: 3938 case R6_OPC_DCLO: 3939 case OPC_DCLZ: 3940 case R6_OPC_DCLZ: 3941 tcg_gen_clzi_i64(t0, t0, 64); 3942 break; 3943 #endif 3944 } 3945 } 3946 3947 /* Godson integer instructions */ 3948 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3949 int rd, int rs, int rt) 3950 { 3951 TCGv t0, t1; 3952 3953 if (rd == 0) { 3954 /* Treat as NOP. */ 3955 return; 3956 } 3957 3958 switch (opc) { 3959 case OPC_MULT_G_2E: 3960 case OPC_MULT_G_2F: 3961 case OPC_MULTU_G_2E: 3962 case OPC_MULTU_G_2F: 3963 #if defined(TARGET_MIPS64) 3964 case OPC_DMULT_G_2E: 3965 case OPC_DMULT_G_2F: 3966 case OPC_DMULTU_G_2E: 3967 case OPC_DMULTU_G_2F: 3968 #endif 3969 t0 = tcg_temp_new(); 3970 t1 = tcg_temp_new(); 3971 break; 3972 default: 3973 t0 = tcg_temp_local_new(); 3974 t1 = tcg_temp_local_new(); 3975 break; 3976 } 3977 3978 gen_load_gpr(t0, rs); 3979 gen_load_gpr(t1, rt); 3980 3981 switch (opc) { 3982 case OPC_MULT_G_2E: 3983 case OPC_MULT_G_2F: 3984 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3985 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3986 break; 3987 case OPC_MULTU_G_2E: 3988 case OPC_MULTU_G_2F: 3989 tcg_gen_ext32u_tl(t0, t0); 3990 tcg_gen_ext32u_tl(t1, t1); 3991 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3992 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3993 break; 3994 case OPC_DIV_G_2E: 3995 case OPC_DIV_G_2F: 3996 { 3997 TCGLabel *l1 = gen_new_label(); 3998 TCGLabel *l2 = gen_new_label(); 3999 TCGLabel *l3 = gen_new_label(); 4000 tcg_gen_ext32s_tl(t0, t0); 4001 tcg_gen_ext32s_tl(t1, t1); 4002 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4003 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4004 tcg_gen_br(l3); 4005 gen_set_label(l1); 4006 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 4007 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 4008 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4009 tcg_gen_br(l3); 4010 gen_set_label(l2); 4011 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 4012 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 4013 gen_set_label(l3); 4014 } 4015 break; 4016 case OPC_DIVU_G_2E: 4017 case OPC_DIVU_G_2F: 4018 { 4019 TCGLabel *l1 = gen_new_label(); 4020 TCGLabel *l2 = gen_new_label(); 4021 tcg_gen_ext32u_tl(t0, t0); 4022 tcg_gen_ext32u_tl(t1, t1); 4023 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4024 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4025 tcg_gen_br(l2); 4026 gen_set_label(l1); 4027 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 4028 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 4029 gen_set_label(l2); 4030 } 4031 break; 4032 case OPC_MOD_G_2E: 4033 case OPC_MOD_G_2F: 4034 { 4035 TCGLabel *l1 = gen_new_label(); 4036 TCGLabel *l2 = gen_new_label(); 4037 TCGLabel *l3 = gen_new_label(); 4038 tcg_gen_ext32u_tl(t0, t0); 4039 tcg_gen_ext32u_tl(t1, t1); 4040 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 4041 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 4042 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 4043 gen_set_label(l1); 4044 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4045 tcg_gen_br(l3); 4046 gen_set_label(l2); 4047 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 4048 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 4049 gen_set_label(l3); 4050 } 4051 break; 4052 case OPC_MODU_G_2E: 4053 case OPC_MODU_G_2F: 4054 { 4055 TCGLabel *l1 = gen_new_label(); 4056 TCGLabel *l2 = gen_new_label(); 4057 tcg_gen_ext32u_tl(t0, t0); 4058 tcg_gen_ext32u_tl(t1, t1); 4059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4060 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4061 tcg_gen_br(l2); 4062 gen_set_label(l1); 4063 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 4064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 4065 gen_set_label(l2); 4066 } 4067 break; 4068 #if defined(TARGET_MIPS64) 4069 case OPC_DMULT_G_2E: 4070 case OPC_DMULT_G_2F: 4071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4072 break; 4073 case OPC_DMULTU_G_2E: 4074 case OPC_DMULTU_G_2F: 4075 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4076 break; 4077 case OPC_DDIV_G_2E: 4078 case OPC_DDIV_G_2F: 4079 { 4080 TCGLabel *l1 = gen_new_label(); 4081 TCGLabel *l2 = gen_new_label(); 4082 TCGLabel *l3 = gen_new_label(); 4083 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4084 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4085 tcg_gen_br(l3); 4086 gen_set_label(l1); 4087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4089 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4090 tcg_gen_br(l3); 4091 gen_set_label(l2); 4092 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 4093 gen_set_label(l3); 4094 } 4095 break; 4096 case OPC_DDIVU_G_2E: 4097 case OPC_DDIVU_G_2F: 4098 { 4099 TCGLabel *l1 = gen_new_label(); 4100 TCGLabel *l2 = gen_new_label(); 4101 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4102 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4103 tcg_gen_br(l2); 4104 gen_set_label(l1); 4105 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 4106 gen_set_label(l2); 4107 } 4108 break; 4109 case OPC_DMOD_G_2E: 4110 case OPC_DMOD_G_2F: 4111 { 4112 TCGLabel *l1 = gen_new_label(); 4113 TCGLabel *l2 = gen_new_label(); 4114 TCGLabel *l3 = gen_new_label(); 4115 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 4116 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4117 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4118 gen_set_label(l1); 4119 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4120 tcg_gen_br(l3); 4121 gen_set_label(l2); 4122 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 4123 gen_set_label(l3); 4124 } 4125 break; 4126 case OPC_DMODU_G_2E: 4127 case OPC_DMODU_G_2F: 4128 { 4129 TCGLabel *l1 = gen_new_label(); 4130 TCGLabel *l2 = gen_new_label(); 4131 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4132 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4133 tcg_gen_br(l2); 4134 gen_set_label(l1); 4135 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 4136 gen_set_label(l2); 4137 } 4138 break; 4139 #endif 4140 } 4141 4142 tcg_temp_free(t0); 4143 tcg_temp_free(t1); 4144 } 4145 4146 /* Loongson multimedia instructions */ 4147 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 4148 { 4149 uint32_t opc, shift_max; 4150 TCGv_i64 t0, t1; 4151 TCGCond cond; 4152 4153 opc = MASK_LMMI(ctx->opcode); 4154 switch (opc) { 4155 case OPC_ADD_CP2: 4156 case OPC_SUB_CP2: 4157 case OPC_DADD_CP2: 4158 case OPC_DSUB_CP2: 4159 t0 = tcg_temp_local_new_i64(); 4160 t1 = tcg_temp_local_new_i64(); 4161 break; 4162 default: 4163 t0 = tcg_temp_new_i64(); 4164 t1 = tcg_temp_new_i64(); 4165 break; 4166 } 4167 4168 check_cp1_enabled(ctx); 4169 gen_load_fpr64(ctx, t0, rs); 4170 gen_load_fpr64(ctx, t1, rt); 4171 4172 switch (opc) { 4173 case OPC_PADDSH: 4174 gen_helper_paddsh(t0, t0, t1); 4175 break; 4176 case OPC_PADDUSH: 4177 gen_helper_paddush(t0, t0, t1); 4178 break; 4179 case OPC_PADDH: 4180 gen_helper_paddh(t0, t0, t1); 4181 break; 4182 case OPC_PADDW: 4183 gen_helper_paddw(t0, t0, t1); 4184 break; 4185 case OPC_PADDSB: 4186 gen_helper_paddsb(t0, t0, t1); 4187 break; 4188 case OPC_PADDUSB: 4189 gen_helper_paddusb(t0, t0, t1); 4190 break; 4191 case OPC_PADDB: 4192 gen_helper_paddb(t0, t0, t1); 4193 break; 4194 4195 case OPC_PSUBSH: 4196 gen_helper_psubsh(t0, t0, t1); 4197 break; 4198 case OPC_PSUBUSH: 4199 gen_helper_psubush(t0, t0, t1); 4200 break; 4201 case OPC_PSUBH: 4202 gen_helper_psubh(t0, t0, t1); 4203 break; 4204 case OPC_PSUBW: 4205 gen_helper_psubw(t0, t0, t1); 4206 break; 4207 case OPC_PSUBSB: 4208 gen_helper_psubsb(t0, t0, t1); 4209 break; 4210 case OPC_PSUBUSB: 4211 gen_helper_psubusb(t0, t0, t1); 4212 break; 4213 case OPC_PSUBB: 4214 gen_helper_psubb(t0, t0, t1); 4215 break; 4216 4217 case OPC_PSHUFH: 4218 gen_helper_pshufh(t0, t0, t1); 4219 break; 4220 case OPC_PACKSSWH: 4221 gen_helper_packsswh(t0, t0, t1); 4222 break; 4223 case OPC_PACKSSHB: 4224 gen_helper_packsshb(t0, t0, t1); 4225 break; 4226 case OPC_PACKUSHB: 4227 gen_helper_packushb(t0, t0, t1); 4228 break; 4229 4230 case OPC_PUNPCKLHW: 4231 gen_helper_punpcklhw(t0, t0, t1); 4232 break; 4233 case OPC_PUNPCKHHW: 4234 gen_helper_punpckhhw(t0, t0, t1); 4235 break; 4236 case OPC_PUNPCKLBH: 4237 gen_helper_punpcklbh(t0, t0, t1); 4238 break; 4239 case OPC_PUNPCKHBH: 4240 gen_helper_punpckhbh(t0, t0, t1); 4241 break; 4242 case OPC_PUNPCKLWD: 4243 gen_helper_punpcklwd(t0, t0, t1); 4244 break; 4245 case OPC_PUNPCKHWD: 4246 gen_helper_punpckhwd(t0, t0, t1); 4247 break; 4248 4249 case OPC_PAVGH: 4250 gen_helper_pavgh(t0, t0, t1); 4251 break; 4252 case OPC_PAVGB: 4253 gen_helper_pavgb(t0, t0, t1); 4254 break; 4255 case OPC_PMAXSH: 4256 gen_helper_pmaxsh(t0, t0, t1); 4257 break; 4258 case OPC_PMINSH: 4259 gen_helper_pminsh(t0, t0, t1); 4260 break; 4261 case OPC_PMAXUB: 4262 gen_helper_pmaxub(t0, t0, t1); 4263 break; 4264 case OPC_PMINUB: 4265 gen_helper_pminub(t0, t0, t1); 4266 break; 4267 4268 case OPC_PCMPEQW: 4269 gen_helper_pcmpeqw(t0, t0, t1); 4270 break; 4271 case OPC_PCMPGTW: 4272 gen_helper_pcmpgtw(t0, t0, t1); 4273 break; 4274 case OPC_PCMPEQH: 4275 gen_helper_pcmpeqh(t0, t0, t1); 4276 break; 4277 case OPC_PCMPGTH: 4278 gen_helper_pcmpgth(t0, t0, t1); 4279 break; 4280 case OPC_PCMPEQB: 4281 gen_helper_pcmpeqb(t0, t0, t1); 4282 break; 4283 case OPC_PCMPGTB: 4284 gen_helper_pcmpgtb(t0, t0, t1); 4285 break; 4286 4287 case OPC_PSLLW: 4288 gen_helper_psllw(t0, t0, t1); 4289 break; 4290 case OPC_PSLLH: 4291 gen_helper_psllh(t0, t0, t1); 4292 break; 4293 case OPC_PSRLW: 4294 gen_helper_psrlw(t0, t0, t1); 4295 break; 4296 case OPC_PSRLH: 4297 gen_helper_psrlh(t0, t0, t1); 4298 break; 4299 case OPC_PSRAW: 4300 gen_helper_psraw(t0, t0, t1); 4301 break; 4302 case OPC_PSRAH: 4303 gen_helper_psrah(t0, t0, t1); 4304 break; 4305 4306 case OPC_PMULLH: 4307 gen_helper_pmullh(t0, t0, t1); 4308 break; 4309 case OPC_PMULHH: 4310 gen_helper_pmulhh(t0, t0, t1); 4311 break; 4312 case OPC_PMULHUH: 4313 gen_helper_pmulhuh(t0, t0, t1); 4314 break; 4315 case OPC_PMADDHW: 4316 gen_helper_pmaddhw(t0, t0, t1); 4317 break; 4318 4319 case OPC_PASUBUB: 4320 gen_helper_pasubub(t0, t0, t1); 4321 break; 4322 case OPC_BIADD: 4323 gen_helper_biadd(t0, t0); 4324 break; 4325 case OPC_PMOVMSKB: 4326 gen_helper_pmovmskb(t0, t0); 4327 break; 4328 4329 case OPC_PADDD: 4330 tcg_gen_add_i64(t0, t0, t1); 4331 break; 4332 case OPC_PSUBD: 4333 tcg_gen_sub_i64(t0, t0, t1); 4334 break; 4335 case OPC_XOR_CP2: 4336 tcg_gen_xor_i64(t0, t0, t1); 4337 break; 4338 case OPC_NOR_CP2: 4339 tcg_gen_nor_i64(t0, t0, t1); 4340 break; 4341 case OPC_AND_CP2: 4342 tcg_gen_and_i64(t0, t0, t1); 4343 break; 4344 case OPC_OR_CP2: 4345 tcg_gen_or_i64(t0, t0, t1); 4346 break; 4347 4348 case OPC_PANDN: 4349 tcg_gen_andc_i64(t0, t1, t0); 4350 break; 4351 4352 case OPC_PINSRH_0: 4353 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4354 break; 4355 case OPC_PINSRH_1: 4356 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4357 break; 4358 case OPC_PINSRH_2: 4359 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4360 break; 4361 case OPC_PINSRH_3: 4362 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4363 break; 4364 4365 case OPC_PEXTRH: 4366 tcg_gen_andi_i64(t1, t1, 3); 4367 tcg_gen_shli_i64(t1, t1, 4); 4368 tcg_gen_shr_i64(t0, t0, t1); 4369 tcg_gen_ext16u_i64(t0, t0); 4370 break; 4371 4372 case OPC_ADDU_CP2: 4373 tcg_gen_add_i64(t0, t0, t1); 4374 tcg_gen_ext32s_i64(t0, t0); 4375 break; 4376 case OPC_SUBU_CP2: 4377 tcg_gen_sub_i64(t0, t0, t1); 4378 tcg_gen_ext32s_i64(t0, t0); 4379 break; 4380 4381 case OPC_SLL_CP2: 4382 shift_max = 32; 4383 goto do_shift; 4384 case OPC_SRL_CP2: 4385 shift_max = 32; 4386 goto do_shift; 4387 case OPC_SRA_CP2: 4388 shift_max = 32; 4389 goto do_shift; 4390 case OPC_DSLL_CP2: 4391 shift_max = 64; 4392 goto do_shift; 4393 case OPC_DSRL_CP2: 4394 shift_max = 64; 4395 goto do_shift; 4396 case OPC_DSRA_CP2: 4397 shift_max = 64; 4398 goto do_shift; 4399 do_shift: 4400 /* Make sure shift count isn't TCG undefined behaviour. */ 4401 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4402 4403 switch (opc) { 4404 case OPC_SLL_CP2: 4405 case OPC_DSLL_CP2: 4406 tcg_gen_shl_i64(t0, t0, t1); 4407 break; 4408 case OPC_SRA_CP2: 4409 case OPC_DSRA_CP2: 4410 /* 4411 * Since SRA is UndefinedResult without sign-extended inputs, 4412 * we can treat SRA and DSRA the same. 4413 */ 4414 tcg_gen_sar_i64(t0, t0, t1); 4415 break; 4416 case OPC_SRL_CP2: 4417 /* We want to shift in zeros for SRL; zero-extend first. */ 4418 tcg_gen_ext32u_i64(t0, t0); 4419 /* FALLTHRU */ 4420 case OPC_DSRL_CP2: 4421 tcg_gen_shr_i64(t0, t0, t1); 4422 break; 4423 } 4424 4425 if (shift_max == 32) { 4426 tcg_gen_ext32s_i64(t0, t0); 4427 } 4428 4429 /* Shifts larger than MAX produce zero. */ 4430 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4431 tcg_gen_neg_i64(t1, t1); 4432 tcg_gen_and_i64(t0, t0, t1); 4433 break; 4434 4435 case OPC_ADD_CP2: 4436 case OPC_DADD_CP2: 4437 { 4438 TCGv_i64 t2 = tcg_temp_new_i64(); 4439 TCGLabel *lab = gen_new_label(); 4440 4441 tcg_gen_mov_i64(t2, t0); 4442 tcg_gen_add_i64(t0, t1, t2); 4443 if (opc == OPC_ADD_CP2) { 4444 tcg_gen_ext32s_i64(t0, t0); 4445 } 4446 tcg_gen_xor_i64(t1, t1, t2); 4447 tcg_gen_xor_i64(t2, t2, t0); 4448 tcg_gen_andc_i64(t1, t2, t1); 4449 tcg_temp_free_i64(t2); 4450 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4451 generate_exception(ctx, EXCP_OVERFLOW); 4452 gen_set_label(lab); 4453 break; 4454 } 4455 4456 case OPC_SUB_CP2: 4457 case OPC_DSUB_CP2: 4458 { 4459 TCGv_i64 t2 = tcg_temp_new_i64(); 4460 TCGLabel *lab = gen_new_label(); 4461 4462 tcg_gen_mov_i64(t2, t0); 4463 tcg_gen_sub_i64(t0, t1, t2); 4464 if (opc == OPC_SUB_CP2) { 4465 tcg_gen_ext32s_i64(t0, t0); 4466 } 4467 tcg_gen_xor_i64(t1, t1, t2); 4468 tcg_gen_xor_i64(t2, t2, t0); 4469 tcg_gen_and_i64(t1, t1, t2); 4470 tcg_temp_free_i64(t2); 4471 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4472 generate_exception(ctx, EXCP_OVERFLOW); 4473 gen_set_label(lab); 4474 break; 4475 } 4476 4477 case OPC_PMULUW: 4478 tcg_gen_ext32u_i64(t0, t0); 4479 tcg_gen_ext32u_i64(t1, t1); 4480 tcg_gen_mul_i64(t0, t0, t1); 4481 break; 4482 4483 case OPC_SEQU_CP2: 4484 case OPC_SEQ_CP2: 4485 cond = TCG_COND_EQ; 4486 goto do_cc_cond; 4487 break; 4488 case OPC_SLTU_CP2: 4489 cond = TCG_COND_LTU; 4490 goto do_cc_cond; 4491 break; 4492 case OPC_SLT_CP2: 4493 cond = TCG_COND_LT; 4494 goto do_cc_cond; 4495 break; 4496 case OPC_SLEU_CP2: 4497 cond = TCG_COND_LEU; 4498 goto do_cc_cond; 4499 break; 4500 case OPC_SLE_CP2: 4501 cond = TCG_COND_LE; 4502 do_cc_cond: 4503 { 4504 int cc = (ctx->opcode >> 8) & 0x7; 4505 TCGv_i64 t64 = tcg_temp_new_i64(); 4506 TCGv_i32 t32 = tcg_temp_new_i32(); 4507 4508 tcg_gen_setcond_i64(cond, t64, t0, t1); 4509 tcg_gen_extrl_i64_i32(t32, t64); 4510 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4511 get_fp_bit(cc), 1); 4512 4513 tcg_temp_free_i32(t32); 4514 tcg_temp_free_i64(t64); 4515 } 4516 goto no_rd; 4517 break; 4518 default: 4519 MIPS_INVAL("loongson_cp2"); 4520 gen_reserved_instruction(ctx); 4521 return; 4522 } 4523 4524 gen_store_fpr64(ctx, t0, rd); 4525 4526 no_rd: 4527 tcg_temp_free_i64(t0); 4528 tcg_temp_free_i64(t1); 4529 } 4530 4531 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4532 int rs, int rd) 4533 { 4534 TCGv t0, t1, t2; 4535 TCGv_i32 fp0; 4536 #if defined(TARGET_MIPS64) 4537 int lsq_rt1 = ctx->opcode & 0x1f; 4538 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4539 #endif 4540 int shf_offset = sextract32(ctx->opcode, 6, 8); 4541 4542 t0 = tcg_temp_new(); 4543 4544 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4545 #if defined(TARGET_MIPS64) 4546 case OPC_GSLQ: 4547 t1 = tcg_temp_new(); 4548 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4549 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4550 ctx->default_tcg_memop_mask); 4551 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4552 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4553 ctx->default_tcg_memop_mask); 4554 gen_store_gpr(t1, rt); 4555 gen_store_gpr(t0, lsq_rt1); 4556 tcg_temp_free(t1); 4557 break; 4558 case OPC_GSLQC1: 4559 check_cp1_enabled(ctx); 4560 t1 = tcg_temp_new(); 4561 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4562 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4563 ctx->default_tcg_memop_mask); 4564 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4565 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4566 ctx->default_tcg_memop_mask); 4567 gen_store_fpr64(ctx, t1, rt); 4568 gen_store_fpr64(ctx, t0, lsq_rt1); 4569 tcg_temp_free(t1); 4570 break; 4571 case OPC_GSSQ: 4572 t1 = tcg_temp_new(); 4573 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4574 gen_load_gpr(t1, rt); 4575 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4576 ctx->default_tcg_memop_mask); 4577 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4578 gen_load_gpr(t1, lsq_rt1); 4579 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4580 ctx->default_tcg_memop_mask); 4581 tcg_temp_free(t1); 4582 break; 4583 case OPC_GSSQC1: 4584 check_cp1_enabled(ctx); 4585 t1 = tcg_temp_new(); 4586 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4587 gen_load_fpr64(ctx, t1, rt); 4588 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4589 ctx->default_tcg_memop_mask); 4590 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4591 gen_load_fpr64(ctx, t1, lsq_rt1); 4592 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4593 ctx->default_tcg_memop_mask); 4594 tcg_temp_free(t1); 4595 break; 4596 #endif 4597 case OPC_GSSHFL: 4598 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4599 case OPC_GSLWLC1: 4600 check_cp1_enabled(ctx); 4601 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4602 t1 = tcg_temp_new(); 4603 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4604 tcg_gen_andi_tl(t1, t0, 3); 4605 #ifndef TARGET_WORDS_BIGENDIAN 4606 tcg_gen_xori_tl(t1, t1, 3); 4607 #endif 4608 tcg_gen_shli_tl(t1, t1, 3); 4609 tcg_gen_andi_tl(t0, t0, ~3); 4610 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4611 tcg_gen_shl_tl(t0, t0, t1); 4612 t2 = tcg_const_tl(-1); 4613 tcg_gen_shl_tl(t2, t2, t1); 4614 fp0 = tcg_temp_new_i32(); 4615 gen_load_fpr32(ctx, fp0, rt); 4616 tcg_gen_ext_i32_tl(t1, fp0); 4617 tcg_gen_andc_tl(t1, t1, t2); 4618 tcg_temp_free(t2); 4619 tcg_gen_or_tl(t0, t0, t1); 4620 tcg_temp_free(t1); 4621 #if defined(TARGET_MIPS64) 4622 tcg_gen_extrl_i64_i32(fp0, t0); 4623 #else 4624 tcg_gen_ext32s_tl(fp0, t0); 4625 #endif 4626 gen_store_fpr32(ctx, fp0, rt); 4627 tcg_temp_free_i32(fp0); 4628 break; 4629 case OPC_GSLWRC1: 4630 check_cp1_enabled(ctx); 4631 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4632 t1 = tcg_temp_new(); 4633 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4634 tcg_gen_andi_tl(t1, t0, 3); 4635 #ifdef TARGET_WORDS_BIGENDIAN 4636 tcg_gen_xori_tl(t1, t1, 3); 4637 #endif 4638 tcg_gen_shli_tl(t1, t1, 3); 4639 tcg_gen_andi_tl(t0, t0, ~3); 4640 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4641 tcg_gen_shr_tl(t0, t0, t1); 4642 tcg_gen_xori_tl(t1, t1, 31); 4643 t2 = tcg_const_tl(0xfffffffeull); 4644 tcg_gen_shl_tl(t2, t2, t1); 4645 fp0 = tcg_temp_new_i32(); 4646 gen_load_fpr32(ctx, fp0, rt); 4647 tcg_gen_ext_i32_tl(t1, fp0); 4648 tcg_gen_and_tl(t1, t1, t2); 4649 tcg_temp_free(t2); 4650 tcg_gen_or_tl(t0, t0, t1); 4651 tcg_temp_free(t1); 4652 #if defined(TARGET_MIPS64) 4653 tcg_gen_extrl_i64_i32(fp0, t0); 4654 #else 4655 tcg_gen_ext32s_tl(fp0, t0); 4656 #endif 4657 gen_store_fpr32(ctx, fp0, rt); 4658 tcg_temp_free_i32(fp0); 4659 break; 4660 #if defined(TARGET_MIPS64) 4661 case OPC_GSLDLC1: 4662 check_cp1_enabled(ctx); 4663 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4664 t1 = tcg_temp_new(); 4665 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4666 tcg_gen_andi_tl(t1, t0, 7); 4667 #ifndef TARGET_WORDS_BIGENDIAN 4668 tcg_gen_xori_tl(t1, t1, 7); 4669 #endif 4670 tcg_gen_shli_tl(t1, t1, 3); 4671 tcg_gen_andi_tl(t0, t0, ~7); 4672 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4673 tcg_gen_shl_tl(t0, t0, t1); 4674 t2 = tcg_const_tl(-1); 4675 tcg_gen_shl_tl(t2, t2, t1); 4676 gen_load_fpr64(ctx, t1, rt); 4677 tcg_gen_andc_tl(t1, t1, t2); 4678 tcg_temp_free(t2); 4679 tcg_gen_or_tl(t0, t0, t1); 4680 tcg_temp_free(t1); 4681 gen_store_fpr64(ctx, t0, rt); 4682 break; 4683 case OPC_GSLDRC1: 4684 check_cp1_enabled(ctx); 4685 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4686 t1 = tcg_temp_new(); 4687 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4688 tcg_gen_andi_tl(t1, t0, 7); 4689 #ifdef TARGET_WORDS_BIGENDIAN 4690 tcg_gen_xori_tl(t1, t1, 7); 4691 #endif 4692 tcg_gen_shli_tl(t1, t1, 3); 4693 tcg_gen_andi_tl(t0, t0, ~7); 4694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4695 tcg_gen_shr_tl(t0, t0, t1); 4696 tcg_gen_xori_tl(t1, t1, 63); 4697 t2 = tcg_const_tl(0xfffffffffffffffeull); 4698 tcg_gen_shl_tl(t2, t2, t1); 4699 gen_load_fpr64(ctx, t1, rt); 4700 tcg_gen_and_tl(t1, t1, t2); 4701 tcg_temp_free(t2); 4702 tcg_gen_or_tl(t0, t0, t1); 4703 tcg_temp_free(t1); 4704 gen_store_fpr64(ctx, t0, rt); 4705 break; 4706 #endif 4707 default: 4708 MIPS_INVAL("loongson_gsshfl"); 4709 gen_reserved_instruction(ctx); 4710 break; 4711 } 4712 break; 4713 case OPC_GSSHFS: 4714 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4715 case OPC_GSSWLC1: 4716 check_cp1_enabled(ctx); 4717 t1 = tcg_temp_new(); 4718 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4719 fp0 = tcg_temp_new_i32(); 4720 gen_load_fpr32(ctx, fp0, rt); 4721 tcg_gen_ext_i32_tl(t1, fp0); 4722 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4723 tcg_temp_free_i32(fp0); 4724 tcg_temp_free(t1); 4725 break; 4726 case OPC_GSSWRC1: 4727 check_cp1_enabled(ctx); 4728 t1 = tcg_temp_new(); 4729 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4730 fp0 = tcg_temp_new_i32(); 4731 gen_load_fpr32(ctx, fp0, rt); 4732 tcg_gen_ext_i32_tl(t1, fp0); 4733 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4734 tcg_temp_free_i32(fp0); 4735 tcg_temp_free(t1); 4736 break; 4737 #if defined(TARGET_MIPS64) 4738 case OPC_GSSDLC1: 4739 check_cp1_enabled(ctx); 4740 t1 = tcg_temp_new(); 4741 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4742 gen_load_fpr64(ctx, t1, rt); 4743 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4744 tcg_temp_free(t1); 4745 break; 4746 case OPC_GSSDRC1: 4747 check_cp1_enabled(ctx); 4748 t1 = tcg_temp_new(); 4749 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4750 gen_load_fpr64(ctx, t1, rt); 4751 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4752 tcg_temp_free(t1); 4753 break; 4754 #endif 4755 default: 4756 MIPS_INVAL("loongson_gsshfs"); 4757 gen_reserved_instruction(ctx); 4758 break; 4759 } 4760 break; 4761 default: 4762 MIPS_INVAL("loongson_gslsq"); 4763 gen_reserved_instruction(ctx); 4764 break; 4765 } 4766 tcg_temp_free(t0); 4767 } 4768 4769 /* Loongson EXT LDC2/SDC2 */ 4770 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4771 int rs, int rd) 4772 { 4773 int offset = sextract32(ctx->opcode, 3, 8); 4774 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4775 TCGv t0, t1; 4776 TCGv_i32 fp0; 4777 4778 /* Pre-conditions */ 4779 switch (opc) { 4780 case OPC_GSLBX: 4781 case OPC_GSLHX: 4782 case OPC_GSLWX: 4783 case OPC_GSLDX: 4784 /* prefetch, implement as NOP */ 4785 if (rt == 0) { 4786 return; 4787 } 4788 break; 4789 case OPC_GSSBX: 4790 case OPC_GSSHX: 4791 case OPC_GSSWX: 4792 case OPC_GSSDX: 4793 break; 4794 case OPC_GSLWXC1: 4795 #if defined(TARGET_MIPS64) 4796 case OPC_GSLDXC1: 4797 #endif 4798 check_cp1_enabled(ctx); 4799 /* prefetch, implement as NOP */ 4800 if (rt == 0) { 4801 return; 4802 } 4803 break; 4804 case OPC_GSSWXC1: 4805 #if defined(TARGET_MIPS64) 4806 case OPC_GSSDXC1: 4807 #endif 4808 check_cp1_enabled(ctx); 4809 break; 4810 default: 4811 MIPS_INVAL("loongson_lsdc2"); 4812 gen_reserved_instruction(ctx); 4813 return; 4814 break; 4815 } 4816 4817 t0 = tcg_temp_new(); 4818 4819 gen_base_offset_addr(ctx, t0, rs, offset); 4820 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4821 4822 switch (opc) { 4823 case OPC_GSLBX: 4824 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4825 gen_store_gpr(t0, rt); 4826 break; 4827 case OPC_GSLHX: 4828 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4829 ctx->default_tcg_memop_mask); 4830 gen_store_gpr(t0, rt); 4831 break; 4832 case OPC_GSLWX: 4833 gen_base_offset_addr(ctx, t0, rs, offset); 4834 if (rd) { 4835 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4836 } 4837 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4838 ctx->default_tcg_memop_mask); 4839 gen_store_gpr(t0, rt); 4840 break; 4841 #if defined(TARGET_MIPS64) 4842 case OPC_GSLDX: 4843 gen_base_offset_addr(ctx, t0, rs, offset); 4844 if (rd) { 4845 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4846 } 4847 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4848 ctx->default_tcg_memop_mask); 4849 gen_store_gpr(t0, rt); 4850 break; 4851 #endif 4852 case OPC_GSLWXC1: 4853 check_cp1_enabled(ctx); 4854 gen_base_offset_addr(ctx, t0, rs, offset); 4855 if (rd) { 4856 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4857 } 4858 fp0 = tcg_temp_new_i32(); 4859 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4860 ctx->default_tcg_memop_mask); 4861 gen_store_fpr32(ctx, fp0, rt); 4862 tcg_temp_free_i32(fp0); 4863 break; 4864 #if defined(TARGET_MIPS64) 4865 case OPC_GSLDXC1: 4866 check_cp1_enabled(ctx); 4867 gen_base_offset_addr(ctx, t0, rs, offset); 4868 if (rd) { 4869 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4870 } 4871 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4872 ctx->default_tcg_memop_mask); 4873 gen_store_fpr64(ctx, t0, rt); 4874 break; 4875 #endif 4876 case OPC_GSSBX: 4877 t1 = tcg_temp_new(); 4878 gen_load_gpr(t1, rt); 4879 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4880 tcg_temp_free(t1); 4881 break; 4882 case OPC_GSSHX: 4883 t1 = tcg_temp_new(); 4884 gen_load_gpr(t1, rt); 4885 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4886 ctx->default_tcg_memop_mask); 4887 tcg_temp_free(t1); 4888 break; 4889 case OPC_GSSWX: 4890 t1 = tcg_temp_new(); 4891 gen_load_gpr(t1, rt); 4892 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4893 ctx->default_tcg_memop_mask); 4894 tcg_temp_free(t1); 4895 break; 4896 #if defined(TARGET_MIPS64) 4897 case OPC_GSSDX: 4898 t1 = tcg_temp_new(); 4899 gen_load_gpr(t1, rt); 4900 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4901 ctx->default_tcg_memop_mask); 4902 tcg_temp_free(t1); 4903 break; 4904 #endif 4905 case OPC_GSSWXC1: 4906 fp0 = tcg_temp_new_i32(); 4907 gen_load_fpr32(ctx, fp0, rt); 4908 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4909 ctx->default_tcg_memop_mask); 4910 tcg_temp_free_i32(fp0); 4911 break; 4912 #if defined(TARGET_MIPS64) 4913 case OPC_GSSDXC1: 4914 t1 = tcg_temp_new(); 4915 gen_load_fpr64(ctx, t1, rt); 4916 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | 4917 ctx->default_tcg_memop_mask); 4918 tcg_temp_free(t1); 4919 break; 4920 #endif 4921 default: 4922 break; 4923 } 4924 4925 tcg_temp_free(t0); 4926 } 4927 4928 /* Traps */ 4929 static void gen_trap(DisasContext *ctx, uint32_t opc, 4930 int rs, int rt, int16_t imm) 4931 { 4932 int cond; 4933 TCGv t0 = tcg_temp_new(); 4934 TCGv t1 = tcg_temp_new(); 4935 4936 cond = 0; 4937 /* Load needed operands */ 4938 switch (opc) { 4939 case OPC_TEQ: 4940 case OPC_TGE: 4941 case OPC_TGEU: 4942 case OPC_TLT: 4943 case OPC_TLTU: 4944 case OPC_TNE: 4945 /* Compare two registers */ 4946 if (rs != rt) { 4947 gen_load_gpr(t0, rs); 4948 gen_load_gpr(t1, rt); 4949 cond = 1; 4950 } 4951 break; 4952 case OPC_TEQI: 4953 case OPC_TGEI: 4954 case OPC_TGEIU: 4955 case OPC_TLTI: 4956 case OPC_TLTIU: 4957 case OPC_TNEI: 4958 /* Compare register to immediate */ 4959 if (rs != 0 || imm != 0) { 4960 gen_load_gpr(t0, rs); 4961 tcg_gen_movi_tl(t1, (int32_t)imm); 4962 cond = 1; 4963 } 4964 break; 4965 } 4966 if (cond == 0) { 4967 switch (opc) { 4968 case OPC_TEQ: /* rs == rs */ 4969 case OPC_TEQI: /* r0 == 0 */ 4970 case OPC_TGE: /* rs >= rs */ 4971 case OPC_TGEI: /* r0 >= 0 */ 4972 case OPC_TGEU: /* rs >= rs unsigned */ 4973 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4974 /* Always trap */ 4975 generate_exception_end(ctx, EXCP_TRAP); 4976 break; 4977 case OPC_TLT: /* rs < rs */ 4978 case OPC_TLTI: /* r0 < 0 */ 4979 case OPC_TLTU: /* rs < rs unsigned */ 4980 case OPC_TLTIU: /* r0 < 0 unsigned */ 4981 case OPC_TNE: /* rs != rs */ 4982 case OPC_TNEI: /* r0 != 0 */ 4983 /* Never trap: treat as NOP. */ 4984 break; 4985 } 4986 } else { 4987 TCGLabel *l1 = gen_new_label(); 4988 4989 switch (opc) { 4990 case OPC_TEQ: 4991 case OPC_TEQI: 4992 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4993 break; 4994 case OPC_TGE: 4995 case OPC_TGEI: 4996 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4997 break; 4998 case OPC_TGEU: 4999 case OPC_TGEIU: 5000 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 5001 break; 5002 case OPC_TLT: 5003 case OPC_TLTI: 5004 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 5005 break; 5006 case OPC_TLTU: 5007 case OPC_TLTIU: 5008 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 5009 break; 5010 case OPC_TNE: 5011 case OPC_TNEI: 5012 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 5013 break; 5014 } 5015 generate_exception(ctx, EXCP_TRAP); 5016 gen_set_label(l1); 5017 } 5018 tcg_temp_free(t0); 5019 tcg_temp_free(t1); 5020 } 5021 5022 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) 5023 { 5024 if (unlikely(ctx->base.singlestep_enabled)) { 5025 return false; 5026 } 5027 5028 #ifndef CONFIG_USER_ONLY 5029 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 5030 #else 5031 return true; 5032 #endif 5033 } 5034 5035 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 5036 { 5037 if (use_goto_tb(ctx, dest)) { 5038 tcg_gen_goto_tb(n); 5039 gen_save_pc(dest); 5040 tcg_gen_exit_tb(ctx->base.tb, n); 5041 } else { 5042 gen_save_pc(dest); 5043 if (ctx->base.singlestep_enabled) { 5044 save_cpu_state(ctx, 0); 5045 gen_helper_raise_exception_debug(cpu_env); 5046 } 5047 tcg_gen_lookup_and_goto_ptr(); 5048 } 5049 } 5050 5051 /* Branches (before delay slot) */ 5052 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 5053 int insn_bytes, 5054 int rs, int rt, int32_t offset, 5055 int delayslot_size) 5056 { 5057 target_ulong btgt = -1; 5058 int blink = 0; 5059 int bcond_compute = 0; 5060 TCGv t0 = tcg_temp_new(); 5061 TCGv t1 = tcg_temp_new(); 5062 5063 if (ctx->hflags & MIPS_HFLAG_BMASK) { 5064 #ifdef MIPS_DEBUG_DISAS 5065 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 5066 TARGET_FMT_lx "\n", ctx->base.pc_next); 5067 #endif 5068 gen_reserved_instruction(ctx); 5069 goto out; 5070 } 5071 5072 /* Load needed operands */ 5073 switch (opc) { 5074 case OPC_BEQ: 5075 case OPC_BEQL: 5076 case OPC_BNE: 5077 case OPC_BNEL: 5078 /* Compare two registers */ 5079 if (rs != rt) { 5080 gen_load_gpr(t0, rs); 5081 gen_load_gpr(t1, rt); 5082 bcond_compute = 1; 5083 } 5084 btgt = ctx->base.pc_next + insn_bytes + offset; 5085 break; 5086 case OPC_BGEZ: 5087 case OPC_BGEZAL: 5088 case OPC_BGEZALL: 5089 case OPC_BGEZL: 5090 case OPC_BGTZ: 5091 case OPC_BGTZL: 5092 case OPC_BLEZ: 5093 case OPC_BLEZL: 5094 case OPC_BLTZ: 5095 case OPC_BLTZAL: 5096 case OPC_BLTZALL: 5097 case OPC_BLTZL: 5098 /* Compare to zero */ 5099 if (rs != 0) { 5100 gen_load_gpr(t0, rs); 5101 bcond_compute = 1; 5102 } 5103 btgt = ctx->base.pc_next + insn_bytes + offset; 5104 break; 5105 case OPC_BPOSGE32: 5106 #if defined(TARGET_MIPS64) 5107 case OPC_BPOSGE64: 5108 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 5109 #else 5110 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 5111 #endif 5112 bcond_compute = 1; 5113 btgt = ctx->base.pc_next + insn_bytes + offset; 5114 break; 5115 case OPC_J: 5116 case OPC_JAL: 5117 case OPC_JALX: 5118 /* Jump to immediate */ 5119 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 5120 (uint32_t)offset; 5121 break; 5122 case OPC_JR: 5123 case OPC_JALR: 5124 /* Jump to register */ 5125 if (offset != 0 && offset != 16) { 5126 /* 5127 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 5128 * others are reserved. 5129 */ 5130 MIPS_INVAL("jump hint"); 5131 gen_reserved_instruction(ctx); 5132 goto out; 5133 } 5134 gen_load_gpr(btarget, rs); 5135 break; 5136 default: 5137 MIPS_INVAL("branch/jump"); 5138 gen_reserved_instruction(ctx); 5139 goto out; 5140 } 5141 if (bcond_compute == 0) { 5142 /* No condition to be computed */ 5143 switch (opc) { 5144 case OPC_BEQ: /* rx == rx */ 5145 case OPC_BEQL: /* rx == rx likely */ 5146 case OPC_BGEZ: /* 0 >= 0 */ 5147 case OPC_BGEZL: /* 0 >= 0 likely */ 5148 case OPC_BLEZ: /* 0 <= 0 */ 5149 case OPC_BLEZL: /* 0 <= 0 likely */ 5150 /* Always take */ 5151 ctx->hflags |= MIPS_HFLAG_B; 5152 break; 5153 case OPC_BGEZAL: /* 0 >= 0 */ 5154 case OPC_BGEZALL: /* 0 >= 0 likely */ 5155 /* Always take and link */ 5156 blink = 31; 5157 ctx->hflags |= MIPS_HFLAG_B; 5158 break; 5159 case OPC_BNE: /* rx != rx */ 5160 case OPC_BGTZ: /* 0 > 0 */ 5161 case OPC_BLTZ: /* 0 < 0 */ 5162 /* Treat as NOP. */ 5163 goto out; 5164 case OPC_BLTZAL: /* 0 < 0 */ 5165 /* 5166 * Handle as an unconditional branch to get correct delay 5167 * slot checking. 5168 */ 5169 blink = 31; 5170 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 5171 ctx->hflags |= MIPS_HFLAG_B; 5172 break; 5173 case OPC_BLTZALL: /* 0 < 0 likely */ 5174 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 5175 /* Skip the instruction in the delay slot */ 5176 ctx->base.pc_next += 4; 5177 goto out; 5178 case OPC_BNEL: /* rx != rx likely */ 5179 case OPC_BGTZL: /* 0 > 0 likely */ 5180 case OPC_BLTZL: /* 0 < 0 likely */ 5181 /* Skip the instruction in the delay slot */ 5182 ctx->base.pc_next += 4; 5183 goto out; 5184 case OPC_J: 5185 ctx->hflags |= MIPS_HFLAG_B; 5186 break; 5187 case OPC_JALX: 5188 ctx->hflags |= MIPS_HFLAG_BX; 5189 /* Fallthrough */ 5190 case OPC_JAL: 5191 blink = 31; 5192 ctx->hflags |= MIPS_HFLAG_B; 5193 break; 5194 case OPC_JR: 5195 ctx->hflags |= MIPS_HFLAG_BR; 5196 break; 5197 case OPC_JALR: 5198 blink = rt; 5199 ctx->hflags |= MIPS_HFLAG_BR; 5200 break; 5201 default: 5202 MIPS_INVAL("branch/jump"); 5203 gen_reserved_instruction(ctx); 5204 goto out; 5205 } 5206 } else { 5207 switch (opc) { 5208 case OPC_BEQ: 5209 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5210 goto not_likely; 5211 case OPC_BEQL: 5212 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5213 goto likely; 5214 case OPC_BNE: 5215 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5216 goto not_likely; 5217 case OPC_BNEL: 5218 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5219 goto likely; 5220 case OPC_BGEZ: 5221 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5222 goto not_likely; 5223 case OPC_BGEZL: 5224 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5225 goto likely; 5226 case OPC_BGEZAL: 5227 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5228 blink = 31; 5229 goto not_likely; 5230 case OPC_BGEZALL: 5231 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5232 blink = 31; 5233 goto likely; 5234 case OPC_BGTZ: 5235 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5236 goto not_likely; 5237 case OPC_BGTZL: 5238 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5239 goto likely; 5240 case OPC_BLEZ: 5241 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5242 goto not_likely; 5243 case OPC_BLEZL: 5244 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5245 goto likely; 5246 case OPC_BLTZ: 5247 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5248 goto not_likely; 5249 case OPC_BLTZL: 5250 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5251 goto likely; 5252 case OPC_BPOSGE32: 5253 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5254 goto not_likely; 5255 #if defined(TARGET_MIPS64) 5256 case OPC_BPOSGE64: 5257 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5258 goto not_likely; 5259 #endif 5260 case OPC_BLTZAL: 5261 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5262 blink = 31; 5263 not_likely: 5264 ctx->hflags |= MIPS_HFLAG_BC; 5265 break; 5266 case OPC_BLTZALL: 5267 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5268 blink = 31; 5269 likely: 5270 ctx->hflags |= MIPS_HFLAG_BL; 5271 break; 5272 default: 5273 MIPS_INVAL("conditional branch/jump"); 5274 gen_reserved_instruction(ctx); 5275 goto out; 5276 } 5277 } 5278 5279 ctx->btarget = btgt; 5280 5281 switch (delayslot_size) { 5282 case 2: 5283 ctx->hflags |= MIPS_HFLAG_BDS16; 5284 break; 5285 case 4: 5286 ctx->hflags |= MIPS_HFLAG_BDS32; 5287 break; 5288 } 5289 5290 if (blink > 0) { 5291 int post_delay = insn_bytes + delayslot_size; 5292 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5293 5294 tcg_gen_movi_tl(cpu_gpr[blink], 5295 ctx->base.pc_next + post_delay + lowbit); 5296 } 5297 5298 out: 5299 if (insn_bytes == 2) { 5300 ctx->hflags |= MIPS_HFLAG_B16; 5301 } 5302 tcg_temp_free(t0); 5303 tcg_temp_free(t1); 5304 } 5305 5306 5307 /* nanoMIPS Branches */ 5308 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, 5309 int insn_bytes, 5310 int rs, int rt, int32_t offset) 5311 { 5312 target_ulong btgt = -1; 5313 int bcond_compute = 0; 5314 TCGv t0 = tcg_temp_new(); 5315 TCGv t1 = tcg_temp_new(); 5316 5317 /* Load needed operands */ 5318 switch (opc) { 5319 case OPC_BEQ: 5320 case OPC_BNE: 5321 /* Compare two registers */ 5322 if (rs != rt) { 5323 gen_load_gpr(t0, rs); 5324 gen_load_gpr(t1, rt); 5325 bcond_compute = 1; 5326 } 5327 btgt = ctx->base.pc_next + insn_bytes + offset; 5328 break; 5329 case OPC_BGEZAL: 5330 /* Compare to zero */ 5331 if (rs != 0) { 5332 gen_load_gpr(t0, rs); 5333 bcond_compute = 1; 5334 } 5335 btgt = ctx->base.pc_next + insn_bytes + offset; 5336 break; 5337 case OPC_BPOSGE32: 5338 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 5339 bcond_compute = 1; 5340 btgt = ctx->base.pc_next + insn_bytes + offset; 5341 break; 5342 case OPC_JR: 5343 case OPC_JALR: 5344 /* Jump to register */ 5345 if (offset != 0 && offset != 16) { 5346 /* 5347 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 5348 * others are reserved. 5349 */ 5350 MIPS_INVAL("jump hint"); 5351 gen_reserved_instruction(ctx); 5352 goto out; 5353 } 5354 gen_load_gpr(btarget, rs); 5355 break; 5356 default: 5357 MIPS_INVAL("branch/jump"); 5358 gen_reserved_instruction(ctx); 5359 goto out; 5360 } 5361 if (bcond_compute == 0) { 5362 /* No condition to be computed */ 5363 switch (opc) { 5364 case OPC_BEQ: /* rx == rx */ 5365 /* Always take */ 5366 ctx->hflags |= MIPS_HFLAG_B; 5367 break; 5368 case OPC_BGEZAL: /* 0 >= 0 */ 5369 /* Always take and link */ 5370 tcg_gen_movi_tl(cpu_gpr[31], 5371 ctx->base.pc_next + insn_bytes); 5372 ctx->hflags |= MIPS_HFLAG_B; 5373 break; 5374 case OPC_BNE: /* rx != rx */ 5375 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 5376 /* Skip the instruction in the delay slot */ 5377 ctx->base.pc_next += 4; 5378 goto out; 5379 case OPC_JR: 5380 ctx->hflags |= MIPS_HFLAG_BR; 5381 break; 5382 case OPC_JALR: 5383 if (rt > 0) { 5384 tcg_gen_movi_tl(cpu_gpr[rt], 5385 ctx->base.pc_next + insn_bytes); 5386 } 5387 ctx->hflags |= MIPS_HFLAG_BR; 5388 break; 5389 default: 5390 MIPS_INVAL("branch/jump"); 5391 gen_reserved_instruction(ctx); 5392 goto out; 5393 } 5394 } else { 5395 switch (opc) { 5396 case OPC_BEQ: 5397 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5398 goto not_likely; 5399 case OPC_BNE: 5400 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5401 goto not_likely; 5402 case OPC_BGEZAL: 5403 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5404 tcg_gen_movi_tl(cpu_gpr[31], 5405 ctx->base.pc_next + insn_bytes); 5406 goto not_likely; 5407 case OPC_BPOSGE32: 5408 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5409 not_likely: 5410 ctx->hflags |= MIPS_HFLAG_BC; 5411 break; 5412 default: 5413 MIPS_INVAL("conditional branch/jump"); 5414 gen_reserved_instruction(ctx); 5415 goto out; 5416 } 5417 } 5418 5419 ctx->btarget = btgt; 5420 5421 out: 5422 if (insn_bytes == 2) { 5423 ctx->hflags |= MIPS_HFLAG_B16; 5424 } 5425 tcg_temp_free(t0); 5426 tcg_temp_free(t1); 5427 } 5428 5429 5430 /* special3 bitfield operations */ 5431 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5432 int rs, int lsb, int msb) 5433 { 5434 TCGv t0 = tcg_temp_new(); 5435 TCGv t1 = tcg_temp_new(); 5436 5437 gen_load_gpr(t1, rs); 5438 switch (opc) { 5439 case OPC_EXT: 5440 if (lsb + msb > 31) { 5441 goto fail; 5442 } 5443 if (msb != 31) { 5444 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5445 } else { 5446 /* 5447 * The two checks together imply that lsb == 0, 5448 * so this is a simple sign-extension. 5449 */ 5450 tcg_gen_ext32s_tl(t0, t1); 5451 } 5452 break; 5453 #if defined(TARGET_MIPS64) 5454 case OPC_DEXTU: 5455 lsb += 32; 5456 goto do_dext; 5457 case OPC_DEXTM: 5458 msb += 32; 5459 goto do_dext; 5460 case OPC_DEXT: 5461 do_dext: 5462 if (lsb + msb > 63) { 5463 goto fail; 5464 } 5465 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5466 break; 5467 #endif 5468 case OPC_INS: 5469 if (lsb > msb) { 5470 goto fail; 5471 } 5472 gen_load_gpr(t0, rt); 5473 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5474 tcg_gen_ext32s_tl(t0, t0); 5475 break; 5476 #if defined(TARGET_MIPS64) 5477 case OPC_DINSU: 5478 lsb += 32; 5479 /* FALLTHRU */ 5480 case OPC_DINSM: 5481 msb += 32; 5482 /* FALLTHRU */ 5483 case OPC_DINS: 5484 if (lsb > msb) { 5485 goto fail; 5486 } 5487 gen_load_gpr(t0, rt); 5488 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5489 break; 5490 #endif 5491 default: 5492 fail: 5493 MIPS_INVAL("bitops"); 5494 gen_reserved_instruction(ctx); 5495 tcg_temp_free(t0); 5496 tcg_temp_free(t1); 5497 return; 5498 } 5499 gen_store_gpr(t0, rt); 5500 tcg_temp_free(t0); 5501 tcg_temp_free(t1); 5502 } 5503 5504 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5505 { 5506 TCGv t0; 5507 5508 if (rd == 0) { 5509 /* If no destination, treat it as a NOP. */ 5510 return; 5511 } 5512 5513 t0 = tcg_temp_new(); 5514 gen_load_gpr(t0, rt); 5515 switch (op2) { 5516 case OPC_WSBH: 5517 { 5518 TCGv t1 = tcg_temp_new(); 5519 TCGv t2 = tcg_const_tl(0x00FF00FF); 5520 5521 tcg_gen_shri_tl(t1, t0, 8); 5522 tcg_gen_and_tl(t1, t1, t2); 5523 tcg_gen_and_tl(t0, t0, t2); 5524 tcg_gen_shli_tl(t0, t0, 8); 5525 tcg_gen_or_tl(t0, t0, t1); 5526 tcg_temp_free(t2); 5527 tcg_temp_free(t1); 5528 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5529 } 5530 break; 5531 case OPC_SEB: 5532 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5533 break; 5534 case OPC_SEH: 5535 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5536 break; 5537 #if defined(TARGET_MIPS64) 5538 case OPC_DSBH: 5539 { 5540 TCGv t1 = tcg_temp_new(); 5541 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5542 5543 tcg_gen_shri_tl(t1, t0, 8); 5544 tcg_gen_and_tl(t1, t1, t2); 5545 tcg_gen_and_tl(t0, t0, t2); 5546 tcg_gen_shli_tl(t0, t0, 8); 5547 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5548 tcg_temp_free(t2); 5549 tcg_temp_free(t1); 5550 } 5551 break; 5552 case OPC_DSHD: 5553 { 5554 TCGv t1 = tcg_temp_new(); 5555 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5556 5557 tcg_gen_shri_tl(t1, t0, 16); 5558 tcg_gen_and_tl(t1, t1, t2); 5559 tcg_gen_and_tl(t0, t0, t2); 5560 tcg_gen_shli_tl(t0, t0, 16); 5561 tcg_gen_or_tl(t0, t0, t1); 5562 tcg_gen_shri_tl(t1, t0, 32); 5563 tcg_gen_shli_tl(t0, t0, 32); 5564 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5565 tcg_temp_free(t2); 5566 tcg_temp_free(t1); 5567 } 5568 break; 5569 #endif 5570 default: 5571 MIPS_INVAL("bsfhl"); 5572 gen_reserved_instruction(ctx); 5573 tcg_temp_free(t0); 5574 return; 5575 } 5576 tcg_temp_free(t0); 5577 } 5578 5579 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5580 int rt, int bits) 5581 { 5582 TCGv t0; 5583 if (rd == 0) { 5584 /* Treat as NOP. */ 5585 return; 5586 } 5587 t0 = tcg_temp_new(); 5588 if (bits == 0 || bits == wordsz) { 5589 if (bits == 0) { 5590 gen_load_gpr(t0, rt); 5591 } else { 5592 gen_load_gpr(t0, rs); 5593 } 5594 switch (wordsz) { 5595 case 32: 5596 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5597 break; 5598 #if defined(TARGET_MIPS64) 5599 case 64: 5600 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5601 break; 5602 #endif 5603 } 5604 } else { 5605 TCGv t1 = tcg_temp_new(); 5606 gen_load_gpr(t0, rt); 5607 gen_load_gpr(t1, rs); 5608 switch (wordsz) { 5609 case 32: 5610 { 5611 TCGv_i64 t2 = tcg_temp_new_i64(); 5612 tcg_gen_concat_tl_i64(t2, t1, t0); 5613 tcg_gen_shri_i64(t2, t2, 32 - bits); 5614 gen_move_low32(cpu_gpr[rd], t2); 5615 tcg_temp_free_i64(t2); 5616 } 5617 break; 5618 #if defined(TARGET_MIPS64) 5619 case 64: 5620 tcg_gen_shli_tl(t0, t0, bits); 5621 tcg_gen_shri_tl(t1, t1, 64 - bits); 5622 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5623 break; 5624 #endif 5625 } 5626 tcg_temp_free(t1); 5627 } 5628 5629 tcg_temp_free(t0); 5630 } 5631 5632 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, 5633 int bp) 5634 { 5635 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5636 } 5637 5638 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt, 5639 int shift) 5640 { 5641 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift); 5642 } 5643 5644 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5645 { 5646 TCGv t0; 5647 if (rd == 0) { 5648 /* Treat as NOP. */ 5649 return; 5650 } 5651 t0 = tcg_temp_new(); 5652 gen_load_gpr(t0, rt); 5653 switch (opc) { 5654 case OPC_BITSWAP: 5655 gen_helper_bitswap(cpu_gpr[rd], t0); 5656 break; 5657 #if defined(TARGET_MIPS64) 5658 case OPC_DBITSWAP: 5659 gen_helper_dbitswap(cpu_gpr[rd], t0); 5660 break; 5661 #endif 5662 } 5663 tcg_temp_free(t0); 5664 } 5665 5666 #ifndef CONFIG_USER_ONLY 5667 /* CP0 (MMU and control) */ 5668 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5669 { 5670 TCGv_i64 t0 = tcg_temp_new_i64(); 5671 TCGv_i64 t1 = tcg_temp_new_i64(); 5672 5673 tcg_gen_ext_tl_i64(t0, arg); 5674 tcg_gen_ld_i64(t1, cpu_env, off); 5675 #if defined(TARGET_MIPS64) 5676 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5677 #else 5678 tcg_gen_concat32_i64(t1, t1, t0); 5679 #endif 5680 tcg_gen_st_i64(t1, cpu_env, off); 5681 tcg_temp_free_i64(t1); 5682 tcg_temp_free_i64(t0); 5683 } 5684 5685 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5686 { 5687 TCGv_i64 t0 = tcg_temp_new_i64(); 5688 TCGv_i64 t1 = tcg_temp_new_i64(); 5689 5690 tcg_gen_ext_tl_i64(t0, arg); 5691 tcg_gen_ld_i64(t1, cpu_env, off); 5692 tcg_gen_concat32_i64(t1, t1, t0); 5693 tcg_gen_st_i64(t1, cpu_env, off); 5694 tcg_temp_free_i64(t1); 5695 tcg_temp_free_i64(t0); 5696 } 5697 5698 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5699 { 5700 TCGv_i64 t0 = tcg_temp_new_i64(); 5701 5702 tcg_gen_ld_i64(t0, cpu_env, off); 5703 #if defined(TARGET_MIPS64) 5704 tcg_gen_shri_i64(t0, t0, 30); 5705 #else 5706 tcg_gen_shri_i64(t0, t0, 32); 5707 #endif 5708 gen_move_low32(arg, t0); 5709 tcg_temp_free_i64(t0); 5710 } 5711 5712 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5713 { 5714 TCGv_i64 t0 = tcg_temp_new_i64(); 5715 5716 tcg_gen_ld_i64(t0, cpu_env, off); 5717 tcg_gen_shri_i64(t0, t0, 32 + shift); 5718 gen_move_low32(arg, t0); 5719 tcg_temp_free_i64(t0); 5720 } 5721 5722 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5723 { 5724 TCGv_i32 t0 = tcg_temp_new_i32(); 5725 5726 tcg_gen_ld_i32(t0, cpu_env, off); 5727 tcg_gen_ext_i32_tl(arg, t0); 5728 tcg_temp_free_i32(t0); 5729 } 5730 5731 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5732 { 5733 tcg_gen_ld_tl(arg, cpu_env, off); 5734 tcg_gen_ext32s_tl(arg, arg); 5735 } 5736 5737 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5738 { 5739 TCGv_i32 t0 = tcg_temp_new_i32(); 5740 5741 tcg_gen_trunc_tl_i32(t0, arg); 5742 tcg_gen_st_i32(t0, cpu_env, off); 5743 tcg_temp_free_i32(t0); 5744 } 5745 5746 #define CP0_CHECK(c) \ 5747 do { \ 5748 if (!(c)) { \ 5749 goto cp0_unimplemented; \ 5750 } \ 5751 } while (0) 5752 5753 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5754 { 5755 const char *register_name = "invalid"; 5756 5757 switch (reg) { 5758 case CP0_REGISTER_02: 5759 switch (sel) { 5760 case 0: 5761 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5762 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5763 register_name = "EntryLo0"; 5764 break; 5765 default: 5766 goto cp0_unimplemented; 5767 } 5768 break; 5769 case CP0_REGISTER_03: 5770 switch (sel) { 5771 case CP0_REG03__ENTRYLO1: 5772 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5773 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5774 register_name = "EntryLo1"; 5775 break; 5776 default: 5777 goto cp0_unimplemented; 5778 } 5779 break; 5780 case CP0_REGISTER_09: 5781 switch (sel) { 5782 case CP0_REG09__SAAR: 5783 CP0_CHECK(ctx->saar); 5784 gen_helper_mfhc0_saar(arg, cpu_env); 5785 register_name = "SAAR"; 5786 break; 5787 default: 5788 goto cp0_unimplemented; 5789 } 5790 break; 5791 case CP0_REGISTER_17: 5792 switch (sel) { 5793 case CP0_REG17__LLADDR: 5794 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5795 ctx->CP0_LLAddr_shift); 5796 register_name = "LLAddr"; 5797 break; 5798 case CP0_REG17__MAAR: 5799 CP0_CHECK(ctx->mrp); 5800 gen_helper_mfhc0_maar(arg, cpu_env); 5801 register_name = "MAAR"; 5802 break; 5803 default: 5804 goto cp0_unimplemented; 5805 } 5806 break; 5807 case CP0_REGISTER_19: 5808 switch (sel) { 5809 case CP0_REG19__WATCHHI0: 5810 case CP0_REG19__WATCHHI1: 5811 case CP0_REG19__WATCHHI2: 5812 case CP0_REG19__WATCHHI3: 5813 case CP0_REG19__WATCHHI4: 5814 case CP0_REG19__WATCHHI5: 5815 case CP0_REG19__WATCHHI6: 5816 case CP0_REG19__WATCHHI7: 5817 /* upper 32 bits are only available when Config5MI != 0 */ 5818 CP0_CHECK(ctx->mi); 5819 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5820 register_name = "WatchHi"; 5821 break; 5822 default: 5823 goto cp0_unimplemented; 5824 } 5825 break; 5826 case CP0_REGISTER_28: 5827 switch (sel) { 5828 case 0: 5829 case 2: 5830 case 4: 5831 case 6: 5832 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5833 register_name = "TagLo"; 5834 break; 5835 default: 5836 goto cp0_unimplemented; 5837 } 5838 break; 5839 default: 5840 goto cp0_unimplemented; 5841 } 5842 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5843 return; 5844 5845 cp0_unimplemented: 5846 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5847 register_name, reg, sel); 5848 tcg_gen_movi_tl(arg, 0); 5849 } 5850 5851 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5852 { 5853 const char *register_name = "invalid"; 5854 uint64_t mask = ctx->PAMask >> 36; 5855 5856 switch (reg) { 5857 case CP0_REGISTER_02: 5858 switch (sel) { 5859 case 0: 5860 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5861 tcg_gen_andi_tl(arg, arg, mask); 5862 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5863 register_name = "EntryLo0"; 5864 break; 5865 default: 5866 goto cp0_unimplemented; 5867 } 5868 break; 5869 case CP0_REGISTER_03: 5870 switch (sel) { 5871 case CP0_REG03__ENTRYLO1: 5872 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5873 tcg_gen_andi_tl(arg, arg, mask); 5874 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5875 register_name = "EntryLo1"; 5876 break; 5877 default: 5878 goto cp0_unimplemented; 5879 } 5880 break; 5881 case CP0_REGISTER_09: 5882 switch (sel) { 5883 case CP0_REG09__SAAR: 5884 CP0_CHECK(ctx->saar); 5885 gen_helper_mthc0_saar(cpu_env, arg); 5886 register_name = "SAAR"; 5887 break; 5888 default: 5889 goto cp0_unimplemented; 5890 } 5891 break; 5892 case CP0_REGISTER_17: 5893 switch (sel) { 5894 case CP0_REG17__LLADDR: 5895 /* 5896 * LLAddr is read-only (the only exception is bit 0 if LLB is 5897 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5898 * relevant for modern MIPS cores supporting MTHC0, therefore 5899 * treating MTHC0 to LLAddr as NOP. 5900 */ 5901 register_name = "LLAddr"; 5902 break; 5903 case CP0_REG17__MAAR: 5904 CP0_CHECK(ctx->mrp); 5905 gen_helper_mthc0_maar(cpu_env, arg); 5906 register_name = "MAAR"; 5907 break; 5908 default: 5909 goto cp0_unimplemented; 5910 } 5911 break; 5912 case CP0_REGISTER_19: 5913 switch (sel) { 5914 case CP0_REG19__WATCHHI0: 5915 case CP0_REG19__WATCHHI1: 5916 case CP0_REG19__WATCHHI2: 5917 case CP0_REG19__WATCHHI3: 5918 case CP0_REG19__WATCHHI4: 5919 case CP0_REG19__WATCHHI5: 5920 case CP0_REG19__WATCHHI6: 5921 case CP0_REG19__WATCHHI7: 5922 /* upper 32 bits are only available when Config5MI != 0 */ 5923 CP0_CHECK(ctx->mi); 5924 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5925 register_name = "WatchHi"; 5926 break; 5927 default: 5928 goto cp0_unimplemented; 5929 } 5930 break; 5931 case CP0_REGISTER_28: 5932 switch (sel) { 5933 case 0: 5934 case 2: 5935 case 4: 5936 case 6: 5937 tcg_gen_andi_tl(arg, arg, mask); 5938 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5939 register_name = "TagLo"; 5940 break; 5941 default: 5942 goto cp0_unimplemented; 5943 } 5944 break; 5945 default: 5946 goto cp0_unimplemented; 5947 } 5948 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5949 return; 5950 5951 cp0_unimplemented: 5952 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5953 register_name, reg, sel); 5954 } 5955 5956 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5957 { 5958 if (ctx->insn_flags & ISA_MIPS_R6) { 5959 tcg_gen_movi_tl(arg, 0); 5960 } else { 5961 tcg_gen_movi_tl(arg, ~0); 5962 } 5963 } 5964 5965 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5966 { 5967 const char *register_name = "invalid"; 5968 5969 if (sel != 0) { 5970 check_insn(ctx, ISA_MIPS_R1); 5971 } 5972 5973 switch (reg) { 5974 case CP0_REGISTER_00: 5975 switch (sel) { 5976 case CP0_REG00__INDEX: 5977 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5978 register_name = "Index"; 5979 break; 5980 case CP0_REG00__MVPCONTROL: 5981 CP0_CHECK(ctx->insn_flags & ASE_MT); 5982 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5983 register_name = "MVPControl"; 5984 break; 5985 case CP0_REG00__MVPCONF0: 5986 CP0_CHECK(ctx->insn_flags & ASE_MT); 5987 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5988 register_name = "MVPConf0"; 5989 break; 5990 case CP0_REG00__MVPCONF1: 5991 CP0_CHECK(ctx->insn_flags & ASE_MT); 5992 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5993 register_name = "MVPConf1"; 5994 break; 5995 case CP0_REG00__VPCONTROL: 5996 CP0_CHECK(ctx->vp); 5997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5998 register_name = "VPControl"; 5999 break; 6000 default: 6001 goto cp0_unimplemented; 6002 } 6003 break; 6004 case CP0_REGISTER_01: 6005 switch (sel) { 6006 case CP0_REG01__RANDOM: 6007 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6008 gen_helper_mfc0_random(arg, cpu_env); 6009 register_name = "Random"; 6010 break; 6011 case CP0_REG01__VPECONTROL: 6012 CP0_CHECK(ctx->insn_flags & ASE_MT); 6013 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6014 register_name = "VPEControl"; 6015 break; 6016 case CP0_REG01__VPECONF0: 6017 CP0_CHECK(ctx->insn_flags & ASE_MT); 6018 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6019 register_name = "VPEConf0"; 6020 break; 6021 case CP0_REG01__VPECONF1: 6022 CP0_CHECK(ctx->insn_flags & ASE_MT); 6023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6024 register_name = "VPEConf1"; 6025 break; 6026 case CP0_REG01__YQMASK: 6027 CP0_CHECK(ctx->insn_flags & ASE_MT); 6028 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 6029 register_name = "YQMask"; 6030 break; 6031 case CP0_REG01__VPESCHEDULE: 6032 CP0_CHECK(ctx->insn_flags & ASE_MT); 6033 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 6034 register_name = "VPESchedule"; 6035 break; 6036 case CP0_REG01__VPESCHEFBACK: 6037 CP0_CHECK(ctx->insn_flags & ASE_MT); 6038 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6039 register_name = "VPEScheFBack"; 6040 break; 6041 case CP0_REG01__VPEOPT: 6042 CP0_CHECK(ctx->insn_flags & ASE_MT); 6043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6044 register_name = "VPEOpt"; 6045 break; 6046 default: 6047 goto cp0_unimplemented; 6048 } 6049 break; 6050 case CP0_REGISTER_02: 6051 switch (sel) { 6052 case CP0_REG02__ENTRYLO0: 6053 { 6054 TCGv_i64 tmp = tcg_temp_new_i64(); 6055 tcg_gen_ld_i64(tmp, cpu_env, 6056 offsetof(CPUMIPSState, CP0_EntryLo0)); 6057 #if defined(TARGET_MIPS64) 6058 if (ctx->rxi) { 6059 /* Move RI/XI fields to bits 31:30 */ 6060 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 6061 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 6062 } 6063 #endif 6064 gen_move_low32(arg, tmp); 6065 tcg_temp_free_i64(tmp); 6066 } 6067 register_name = "EntryLo0"; 6068 break; 6069 case CP0_REG02__TCSTATUS: 6070 CP0_CHECK(ctx->insn_flags & ASE_MT); 6071 gen_helper_mfc0_tcstatus(arg, cpu_env); 6072 register_name = "TCStatus"; 6073 break; 6074 case CP0_REG02__TCBIND: 6075 CP0_CHECK(ctx->insn_flags & ASE_MT); 6076 gen_helper_mfc0_tcbind(arg, cpu_env); 6077 register_name = "TCBind"; 6078 break; 6079 case CP0_REG02__TCRESTART: 6080 CP0_CHECK(ctx->insn_flags & ASE_MT); 6081 gen_helper_mfc0_tcrestart(arg, cpu_env); 6082 register_name = "TCRestart"; 6083 break; 6084 case CP0_REG02__TCHALT: 6085 CP0_CHECK(ctx->insn_flags & ASE_MT); 6086 gen_helper_mfc0_tchalt(arg, cpu_env); 6087 register_name = "TCHalt"; 6088 break; 6089 case CP0_REG02__TCCONTEXT: 6090 CP0_CHECK(ctx->insn_flags & ASE_MT); 6091 gen_helper_mfc0_tccontext(arg, cpu_env); 6092 register_name = "TCContext"; 6093 break; 6094 case CP0_REG02__TCSCHEDULE: 6095 CP0_CHECK(ctx->insn_flags & ASE_MT); 6096 gen_helper_mfc0_tcschedule(arg, cpu_env); 6097 register_name = "TCSchedule"; 6098 break; 6099 case CP0_REG02__TCSCHEFBACK: 6100 CP0_CHECK(ctx->insn_flags & ASE_MT); 6101 gen_helper_mfc0_tcschefback(arg, cpu_env); 6102 register_name = "TCScheFBack"; 6103 break; 6104 default: 6105 goto cp0_unimplemented; 6106 } 6107 break; 6108 case CP0_REGISTER_03: 6109 switch (sel) { 6110 case CP0_REG03__ENTRYLO1: 6111 { 6112 TCGv_i64 tmp = tcg_temp_new_i64(); 6113 tcg_gen_ld_i64(tmp, cpu_env, 6114 offsetof(CPUMIPSState, CP0_EntryLo1)); 6115 #if defined(TARGET_MIPS64) 6116 if (ctx->rxi) { 6117 /* Move RI/XI fields to bits 31:30 */ 6118 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 6119 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 6120 } 6121 #endif 6122 gen_move_low32(arg, tmp); 6123 tcg_temp_free_i64(tmp); 6124 } 6125 register_name = "EntryLo1"; 6126 break; 6127 case CP0_REG03__GLOBALNUM: 6128 CP0_CHECK(ctx->vp); 6129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6130 register_name = "GlobalNumber"; 6131 break; 6132 default: 6133 goto cp0_unimplemented; 6134 } 6135 break; 6136 case CP0_REGISTER_04: 6137 switch (sel) { 6138 case CP0_REG04__CONTEXT: 6139 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 6140 tcg_gen_ext32s_tl(arg, arg); 6141 register_name = "Context"; 6142 break; 6143 case CP0_REG04__CONTEXTCONFIG: 6144 /* SmartMIPS ASE */ 6145 /* gen_helper_mfc0_contextconfig(arg); */ 6146 register_name = "ContextConfig"; 6147 goto cp0_unimplemented; 6148 case CP0_REG04__USERLOCAL: 6149 CP0_CHECK(ctx->ulri); 6150 tcg_gen_ld_tl(arg, cpu_env, 6151 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6152 tcg_gen_ext32s_tl(arg, arg); 6153 register_name = "UserLocal"; 6154 break; 6155 case CP0_REG04__MMID: 6156 CP0_CHECK(ctx->mi); 6157 gen_helper_mtc0_memorymapid(cpu_env, arg); 6158 register_name = "MMID"; 6159 break; 6160 default: 6161 goto cp0_unimplemented; 6162 } 6163 break; 6164 case CP0_REGISTER_05: 6165 switch (sel) { 6166 case CP0_REG05__PAGEMASK: 6167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6168 register_name = "PageMask"; 6169 break; 6170 case CP0_REG05__PAGEGRAIN: 6171 check_insn(ctx, ISA_MIPS_R2); 6172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6173 register_name = "PageGrain"; 6174 break; 6175 case CP0_REG05__SEGCTL0: 6176 CP0_CHECK(ctx->sc); 6177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6178 tcg_gen_ext32s_tl(arg, arg); 6179 register_name = "SegCtl0"; 6180 break; 6181 case CP0_REG05__SEGCTL1: 6182 CP0_CHECK(ctx->sc); 6183 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6184 tcg_gen_ext32s_tl(arg, arg); 6185 register_name = "SegCtl1"; 6186 break; 6187 case CP0_REG05__SEGCTL2: 6188 CP0_CHECK(ctx->sc); 6189 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6190 tcg_gen_ext32s_tl(arg, arg); 6191 register_name = "SegCtl2"; 6192 break; 6193 case CP0_REG05__PWBASE: 6194 check_pw(ctx); 6195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6196 register_name = "PWBase"; 6197 break; 6198 case CP0_REG05__PWFIELD: 6199 check_pw(ctx); 6200 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 6201 register_name = "PWField"; 6202 break; 6203 case CP0_REG05__PWSIZE: 6204 check_pw(ctx); 6205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 6206 register_name = "PWSize"; 6207 break; 6208 default: 6209 goto cp0_unimplemented; 6210 } 6211 break; 6212 case CP0_REGISTER_06: 6213 switch (sel) { 6214 case CP0_REG06__WIRED: 6215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6216 register_name = "Wired"; 6217 break; 6218 case CP0_REG06__SRSCONF0: 6219 check_insn(ctx, ISA_MIPS_R2); 6220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6221 register_name = "SRSConf0"; 6222 break; 6223 case CP0_REG06__SRSCONF1: 6224 check_insn(ctx, ISA_MIPS_R2); 6225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6226 register_name = "SRSConf1"; 6227 break; 6228 case CP0_REG06__SRSCONF2: 6229 check_insn(ctx, ISA_MIPS_R2); 6230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6231 register_name = "SRSConf2"; 6232 break; 6233 case CP0_REG06__SRSCONF3: 6234 check_insn(ctx, ISA_MIPS_R2); 6235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6236 register_name = "SRSConf3"; 6237 break; 6238 case CP0_REG06__SRSCONF4: 6239 check_insn(ctx, ISA_MIPS_R2); 6240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6241 register_name = "SRSConf4"; 6242 break; 6243 case CP0_REG06__PWCTL: 6244 check_pw(ctx); 6245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6246 register_name = "PWCtl"; 6247 break; 6248 default: 6249 goto cp0_unimplemented; 6250 } 6251 break; 6252 case CP0_REGISTER_07: 6253 switch (sel) { 6254 case CP0_REG07__HWRENA: 6255 check_insn(ctx, ISA_MIPS_R2); 6256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6257 register_name = "HWREna"; 6258 break; 6259 default: 6260 goto cp0_unimplemented; 6261 } 6262 break; 6263 case CP0_REGISTER_08: 6264 switch (sel) { 6265 case CP0_REG08__BADVADDR: 6266 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6267 tcg_gen_ext32s_tl(arg, arg); 6268 register_name = "BadVAddr"; 6269 break; 6270 case CP0_REG08__BADINSTR: 6271 CP0_CHECK(ctx->bi); 6272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6273 register_name = "BadInstr"; 6274 break; 6275 case CP0_REG08__BADINSTRP: 6276 CP0_CHECK(ctx->bp); 6277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6278 register_name = "BadInstrP"; 6279 break; 6280 case CP0_REG08__BADINSTRX: 6281 CP0_CHECK(ctx->bi); 6282 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6283 tcg_gen_andi_tl(arg, arg, ~0xffff); 6284 register_name = "BadInstrX"; 6285 break; 6286 default: 6287 goto cp0_unimplemented; 6288 } 6289 break; 6290 case CP0_REGISTER_09: 6291 switch (sel) { 6292 case CP0_REG09__COUNT: 6293 /* Mark as an IO operation because we read the time. */ 6294 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6295 gen_io_start(); 6296 } 6297 gen_helper_mfc0_count(arg, cpu_env); 6298 /* 6299 * Break the TB to be able to take timer interrupts immediately 6300 * after reading count. DISAS_STOP isn't sufficient, we need to 6301 * ensure we break completely out of translated code. 6302 */ 6303 gen_save_pc(ctx->base.pc_next + 4); 6304 ctx->base.is_jmp = DISAS_EXIT; 6305 register_name = "Count"; 6306 break; 6307 case CP0_REG09__SAARI: 6308 CP0_CHECK(ctx->saar); 6309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 6310 register_name = "SAARI"; 6311 break; 6312 case CP0_REG09__SAAR: 6313 CP0_CHECK(ctx->saar); 6314 gen_helper_mfc0_saar(arg, cpu_env); 6315 register_name = "SAAR"; 6316 break; 6317 default: 6318 goto cp0_unimplemented; 6319 } 6320 break; 6321 case CP0_REGISTER_10: 6322 switch (sel) { 6323 case CP0_REG10__ENTRYHI: 6324 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6325 tcg_gen_ext32s_tl(arg, arg); 6326 register_name = "EntryHi"; 6327 break; 6328 default: 6329 goto cp0_unimplemented; 6330 } 6331 break; 6332 case CP0_REGISTER_11: 6333 switch (sel) { 6334 case CP0_REG11__COMPARE: 6335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6336 register_name = "Compare"; 6337 break; 6338 /* 6,7 are implementation dependent */ 6339 default: 6340 goto cp0_unimplemented; 6341 } 6342 break; 6343 case CP0_REGISTER_12: 6344 switch (sel) { 6345 case CP0_REG12__STATUS: 6346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6347 register_name = "Status"; 6348 break; 6349 case CP0_REG12__INTCTL: 6350 check_insn(ctx, ISA_MIPS_R2); 6351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6352 register_name = "IntCtl"; 6353 break; 6354 case CP0_REG12__SRSCTL: 6355 check_insn(ctx, ISA_MIPS_R2); 6356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6357 register_name = "SRSCtl"; 6358 break; 6359 case CP0_REG12__SRSMAP: 6360 check_insn(ctx, ISA_MIPS_R2); 6361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6362 register_name = "SRSMap"; 6363 break; 6364 default: 6365 goto cp0_unimplemented; 6366 } 6367 break; 6368 case CP0_REGISTER_13: 6369 switch (sel) { 6370 case CP0_REG13__CAUSE: 6371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6372 register_name = "Cause"; 6373 break; 6374 default: 6375 goto cp0_unimplemented; 6376 } 6377 break; 6378 case CP0_REGISTER_14: 6379 switch (sel) { 6380 case CP0_REG14__EPC: 6381 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6382 tcg_gen_ext32s_tl(arg, arg); 6383 register_name = "EPC"; 6384 break; 6385 default: 6386 goto cp0_unimplemented; 6387 } 6388 break; 6389 case CP0_REGISTER_15: 6390 switch (sel) { 6391 case CP0_REG15__PRID: 6392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6393 register_name = "PRid"; 6394 break; 6395 case CP0_REG15__EBASE: 6396 check_insn(ctx, ISA_MIPS_R2); 6397 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6398 tcg_gen_ext32s_tl(arg, arg); 6399 register_name = "EBase"; 6400 break; 6401 case CP0_REG15__CMGCRBASE: 6402 check_insn(ctx, ISA_MIPS_R2); 6403 CP0_CHECK(ctx->cmgcr); 6404 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6405 tcg_gen_ext32s_tl(arg, arg); 6406 register_name = "CMGCRBase"; 6407 break; 6408 default: 6409 goto cp0_unimplemented; 6410 } 6411 break; 6412 case CP0_REGISTER_16: 6413 switch (sel) { 6414 case CP0_REG16__CONFIG: 6415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6416 register_name = "Config"; 6417 break; 6418 case CP0_REG16__CONFIG1: 6419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6420 register_name = "Config1"; 6421 break; 6422 case CP0_REG16__CONFIG2: 6423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6424 register_name = "Config2"; 6425 break; 6426 case CP0_REG16__CONFIG3: 6427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6428 register_name = "Config3"; 6429 break; 6430 case CP0_REG16__CONFIG4: 6431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6432 register_name = "Config4"; 6433 break; 6434 case CP0_REG16__CONFIG5: 6435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6436 register_name = "Config5"; 6437 break; 6438 /* 6,7 are implementation dependent */ 6439 case CP0_REG16__CONFIG6: 6440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6441 register_name = "Config6"; 6442 break; 6443 case CP0_REG16__CONFIG7: 6444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6445 register_name = "Config7"; 6446 break; 6447 default: 6448 goto cp0_unimplemented; 6449 } 6450 break; 6451 case CP0_REGISTER_17: 6452 switch (sel) { 6453 case CP0_REG17__LLADDR: 6454 gen_helper_mfc0_lladdr(arg, cpu_env); 6455 register_name = "LLAddr"; 6456 break; 6457 case CP0_REG17__MAAR: 6458 CP0_CHECK(ctx->mrp); 6459 gen_helper_mfc0_maar(arg, cpu_env); 6460 register_name = "MAAR"; 6461 break; 6462 case CP0_REG17__MAARI: 6463 CP0_CHECK(ctx->mrp); 6464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6465 register_name = "MAARI"; 6466 break; 6467 default: 6468 goto cp0_unimplemented; 6469 } 6470 break; 6471 case CP0_REGISTER_18: 6472 switch (sel) { 6473 case CP0_REG18__WATCHLO0: 6474 case CP0_REG18__WATCHLO1: 6475 case CP0_REG18__WATCHLO2: 6476 case CP0_REG18__WATCHLO3: 6477 case CP0_REG18__WATCHLO4: 6478 case CP0_REG18__WATCHLO5: 6479 case CP0_REG18__WATCHLO6: 6480 case CP0_REG18__WATCHLO7: 6481 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6482 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6483 register_name = "WatchLo"; 6484 break; 6485 default: 6486 goto cp0_unimplemented; 6487 } 6488 break; 6489 case CP0_REGISTER_19: 6490 switch (sel) { 6491 case CP0_REG19__WATCHHI0: 6492 case CP0_REG19__WATCHHI1: 6493 case CP0_REG19__WATCHHI2: 6494 case CP0_REG19__WATCHHI3: 6495 case CP0_REG19__WATCHHI4: 6496 case CP0_REG19__WATCHHI5: 6497 case CP0_REG19__WATCHHI6: 6498 case CP0_REG19__WATCHHI7: 6499 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6500 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6501 register_name = "WatchHi"; 6502 break; 6503 default: 6504 goto cp0_unimplemented; 6505 } 6506 break; 6507 case CP0_REGISTER_20: 6508 switch (sel) { 6509 case CP0_REG20__XCONTEXT: 6510 #if defined(TARGET_MIPS64) 6511 check_insn(ctx, ISA_MIPS3); 6512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6513 tcg_gen_ext32s_tl(arg, arg); 6514 register_name = "XContext"; 6515 break; 6516 #endif 6517 default: 6518 goto cp0_unimplemented; 6519 } 6520 break; 6521 case CP0_REGISTER_21: 6522 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6523 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6524 switch (sel) { 6525 case 0: 6526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6527 register_name = "Framemask"; 6528 break; 6529 default: 6530 goto cp0_unimplemented; 6531 } 6532 break; 6533 case CP0_REGISTER_22: 6534 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6535 register_name = "'Diagnostic"; /* implementation dependent */ 6536 break; 6537 case CP0_REGISTER_23: 6538 switch (sel) { 6539 case CP0_REG23__DEBUG: 6540 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6541 register_name = "Debug"; 6542 break; 6543 case CP0_REG23__TRACECONTROL: 6544 /* PDtrace support */ 6545 /* gen_helper_mfc0_tracecontrol(arg); */ 6546 register_name = "TraceControl"; 6547 goto cp0_unimplemented; 6548 case CP0_REG23__TRACECONTROL2: 6549 /* PDtrace support */ 6550 /* gen_helper_mfc0_tracecontrol2(arg); */ 6551 register_name = "TraceControl2"; 6552 goto cp0_unimplemented; 6553 case CP0_REG23__USERTRACEDATA1: 6554 /* PDtrace support */ 6555 /* gen_helper_mfc0_usertracedata1(arg);*/ 6556 register_name = "UserTraceData1"; 6557 goto cp0_unimplemented; 6558 case CP0_REG23__TRACEIBPC: 6559 /* PDtrace support */ 6560 /* gen_helper_mfc0_traceibpc(arg); */ 6561 register_name = "TraceIBPC"; 6562 goto cp0_unimplemented; 6563 case CP0_REG23__TRACEDBPC: 6564 /* PDtrace support */ 6565 /* gen_helper_mfc0_tracedbpc(arg); */ 6566 register_name = "TraceDBPC"; 6567 goto cp0_unimplemented; 6568 default: 6569 goto cp0_unimplemented; 6570 } 6571 break; 6572 case CP0_REGISTER_24: 6573 switch (sel) { 6574 case CP0_REG24__DEPC: 6575 /* EJTAG support */ 6576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6577 tcg_gen_ext32s_tl(arg, arg); 6578 register_name = "DEPC"; 6579 break; 6580 default: 6581 goto cp0_unimplemented; 6582 } 6583 break; 6584 case CP0_REGISTER_25: 6585 switch (sel) { 6586 case CP0_REG25__PERFCTL0: 6587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6588 register_name = "Performance0"; 6589 break; 6590 case CP0_REG25__PERFCNT0: 6591 /* gen_helper_mfc0_performance1(arg); */ 6592 register_name = "Performance1"; 6593 goto cp0_unimplemented; 6594 case CP0_REG25__PERFCTL1: 6595 /* gen_helper_mfc0_performance2(arg); */ 6596 register_name = "Performance2"; 6597 goto cp0_unimplemented; 6598 case CP0_REG25__PERFCNT1: 6599 /* gen_helper_mfc0_performance3(arg); */ 6600 register_name = "Performance3"; 6601 goto cp0_unimplemented; 6602 case CP0_REG25__PERFCTL2: 6603 /* gen_helper_mfc0_performance4(arg); */ 6604 register_name = "Performance4"; 6605 goto cp0_unimplemented; 6606 case CP0_REG25__PERFCNT2: 6607 /* gen_helper_mfc0_performance5(arg); */ 6608 register_name = "Performance5"; 6609 goto cp0_unimplemented; 6610 case CP0_REG25__PERFCTL3: 6611 /* gen_helper_mfc0_performance6(arg); */ 6612 register_name = "Performance6"; 6613 goto cp0_unimplemented; 6614 case CP0_REG25__PERFCNT3: 6615 /* gen_helper_mfc0_performance7(arg); */ 6616 register_name = "Performance7"; 6617 goto cp0_unimplemented; 6618 default: 6619 goto cp0_unimplemented; 6620 } 6621 break; 6622 case CP0_REGISTER_26: 6623 switch (sel) { 6624 case CP0_REG26__ERRCTL: 6625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6626 register_name = "ErrCtl"; 6627 break; 6628 default: 6629 goto cp0_unimplemented; 6630 } 6631 break; 6632 case CP0_REGISTER_27: 6633 switch (sel) { 6634 case CP0_REG27__CACHERR: 6635 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6636 register_name = "CacheErr"; 6637 break; 6638 default: 6639 goto cp0_unimplemented; 6640 } 6641 break; 6642 case CP0_REGISTER_28: 6643 switch (sel) { 6644 case CP0_REG28__TAGLO: 6645 case CP0_REG28__TAGLO1: 6646 case CP0_REG28__TAGLO2: 6647 case CP0_REG28__TAGLO3: 6648 { 6649 TCGv_i64 tmp = tcg_temp_new_i64(); 6650 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6651 gen_move_low32(arg, tmp); 6652 tcg_temp_free_i64(tmp); 6653 } 6654 register_name = "TagLo"; 6655 break; 6656 case CP0_REG28__DATALO: 6657 case CP0_REG28__DATALO1: 6658 case CP0_REG28__DATALO2: 6659 case CP0_REG28__DATALO3: 6660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6661 register_name = "DataLo"; 6662 break; 6663 default: 6664 goto cp0_unimplemented; 6665 } 6666 break; 6667 case CP0_REGISTER_29: 6668 switch (sel) { 6669 case CP0_REG29__TAGHI: 6670 case CP0_REG29__TAGHI1: 6671 case CP0_REG29__TAGHI2: 6672 case CP0_REG29__TAGHI3: 6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6674 register_name = "TagHi"; 6675 break; 6676 case CP0_REG29__DATAHI: 6677 case CP0_REG29__DATAHI1: 6678 case CP0_REG29__DATAHI2: 6679 case CP0_REG29__DATAHI3: 6680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6681 register_name = "DataHi"; 6682 break; 6683 default: 6684 goto cp0_unimplemented; 6685 } 6686 break; 6687 case CP0_REGISTER_30: 6688 switch (sel) { 6689 case CP0_REG30__ERROREPC: 6690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6691 tcg_gen_ext32s_tl(arg, arg); 6692 register_name = "ErrorEPC"; 6693 break; 6694 default: 6695 goto cp0_unimplemented; 6696 } 6697 break; 6698 case CP0_REGISTER_31: 6699 switch (sel) { 6700 case CP0_REG31__DESAVE: 6701 /* EJTAG support */ 6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6703 register_name = "DESAVE"; 6704 break; 6705 case CP0_REG31__KSCRATCH1: 6706 case CP0_REG31__KSCRATCH2: 6707 case CP0_REG31__KSCRATCH3: 6708 case CP0_REG31__KSCRATCH4: 6709 case CP0_REG31__KSCRATCH5: 6710 case CP0_REG31__KSCRATCH6: 6711 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6712 tcg_gen_ld_tl(arg, cpu_env, 6713 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6714 tcg_gen_ext32s_tl(arg, arg); 6715 register_name = "KScratch"; 6716 break; 6717 default: 6718 goto cp0_unimplemented; 6719 } 6720 break; 6721 default: 6722 goto cp0_unimplemented; 6723 } 6724 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6725 return; 6726 6727 cp0_unimplemented: 6728 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6729 register_name, reg, sel); 6730 gen_mfc0_unimplemented(ctx, arg); 6731 } 6732 6733 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6734 { 6735 const char *register_name = "invalid"; 6736 6737 if (sel != 0) { 6738 check_insn(ctx, ISA_MIPS_R1); 6739 } 6740 6741 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6742 gen_io_start(); 6743 } 6744 6745 switch (reg) { 6746 case CP0_REGISTER_00: 6747 switch (sel) { 6748 case CP0_REG00__INDEX: 6749 gen_helper_mtc0_index(cpu_env, arg); 6750 register_name = "Index"; 6751 break; 6752 case CP0_REG00__MVPCONTROL: 6753 CP0_CHECK(ctx->insn_flags & ASE_MT); 6754 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6755 register_name = "MVPControl"; 6756 break; 6757 case CP0_REG00__MVPCONF0: 6758 CP0_CHECK(ctx->insn_flags & ASE_MT); 6759 /* ignored */ 6760 register_name = "MVPConf0"; 6761 break; 6762 case CP0_REG00__MVPCONF1: 6763 CP0_CHECK(ctx->insn_flags & ASE_MT); 6764 /* ignored */ 6765 register_name = "MVPConf1"; 6766 break; 6767 case CP0_REG00__VPCONTROL: 6768 CP0_CHECK(ctx->vp); 6769 /* ignored */ 6770 register_name = "VPControl"; 6771 break; 6772 default: 6773 goto cp0_unimplemented; 6774 } 6775 break; 6776 case CP0_REGISTER_01: 6777 switch (sel) { 6778 case CP0_REG01__RANDOM: 6779 /* ignored */ 6780 register_name = "Random"; 6781 break; 6782 case CP0_REG01__VPECONTROL: 6783 CP0_CHECK(ctx->insn_flags & ASE_MT); 6784 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6785 register_name = "VPEControl"; 6786 break; 6787 case CP0_REG01__VPECONF0: 6788 CP0_CHECK(ctx->insn_flags & ASE_MT); 6789 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6790 register_name = "VPEConf0"; 6791 break; 6792 case CP0_REG01__VPECONF1: 6793 CP0_CHECK(ctx->insn_flags & ASE_MT); 6794 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6795 register_name = "VPEConf1"; 6796 break; 6797 case CP0_REG01__YQMASK: 6798 CP0_CHECK(ctx->insn_flags & ASE_MT); 6799 gen_helper_mtc0_yqmask(cpu_env, arg); 6800 register_name = "YQMask"; 6801 break; 6802 case CP0_REG01__VPESCHEDULE: 6803 CP0_CHECK(ctx->insn_flags & ASE_MT); 6804 tcg_gen_st_tl(arg, cpu_env, 6805 offsetof(CPUMIPSState, CP0_VPESchedule)); 6806 register_name = "VPESchedule"; 6807 break; 6808 case CP0_REG01__VPESCHEFBACK: 6809 CP0_CHECK(ctx->insn_flags & ASE_MT); 6810 tcg_gen_st_tl(arg, cpu_env, 6811 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6812 register_name = "VPEScheFBack"; 6813 break; 6814 case CP0_REG01__VPEOPT: 6815 CP0_CHECK(ctx->insn_flags & ASE_MT); 6816 gen_helper_mtc0_vpeopt(cpu_env, arg); 6817 register_name = "VPEOpt"; 6818 break; 6819 default: 6820 goto cp0_unimplemented; 6821 } 6822 break; 6823 case CP0_REGISTER_02: 6824 switch (sel) { 6825 case CP0_REG02__ENTRYLO0: 6826 gen_helper_mtc0_entrylo0(cpu_env, arg); 6827 register_name = "EntryLo0"; 6828 break; 6829 case CP0_REG02__TCSTATUS: 6830 CP0_CHECK(ctx->insn_flags & ASE_MT); 6831 gen_helper_mtc0_tcstatus(cpu_env, arg); 6832 register_name = "TCStatus"; 6833 break; 6834 case CP0_REG02__TCBIND: 6835 CP0_CHECK(ctx->insn_flags & ASE_MT); 6836 gen_helper_mtc0_tcbind(cpu_env, arg); 6837 register_name = "TCBind"; 6838 break; 6839 case CP0_REG02__TCRESTART: 6840 CP0_CHECK(ctx->insn_flags & ASE_MT); 6841 gen_helper_mtc0_tcrestart(cpu_env, arg); 6842 register_name = "TCRestart"; 6843 break; 6844 case CP0_REG02__TCHALT: 6845 CP0_CHECK(ctx->insn_flags & ASE_MT); 6846 gen_helper_mtc0_tchalt(cpu_env, arg); 6847 register_name = "TCHalt"; 6848 break; 6849 case CP0_REG02__TCCONTEXT: 6850 CP0_CHECK(ctx->insn_flags & ASE_MT); 6851 gen_helper_mtc0_tccontext(cpu_env, arg); 6852 register_name = "TCContext"; 6853 break; 6854 case CP0_REG02__TCSCHEDULE: 6855 CP0_CHECK(ctx->insn_flags & ASE_MT); 6856 gen_helper_mtc0_tcschedule(cpu_env, arg); 6857 register_name = "TCSchedule"; 6858 break; 6859 case CP0_REG02__TCSCHEFBACK: 6860 CP0_CHECK(ctx->insn_flags & ASE_MT); 6861 gen_helper_mtc0_tcschefback(cpu_env, arg); 6862 register_name = "TCScheFBack"; 6863 break; 6864 default: 6865 goto cp0_unimplemented; 6866 } 6867 break; 6868 case CP0_REGISTER_03: 6869 switch (sel) { 6870 case CP0_REG03__ENTRYLO1: 6871 gen_helper_mtc0_entrylo1(cpu_env, arg); 6872 register_name = "EntryLo1"; 6873 break; 6874 case CP0_REG03__GLOBALNUM: 6875 CP0_CHECK(ctx->vp); 6876 /* ignored */ 6877 register_name = "GlobalNumber"; 6878 break; 6879 default: 6880 goto cp0_unimplemented; 6881 } 6882 break; 6883 case CP0_REGISTER_04: 6884 switch (sel) { 6885 case CP0_REG04__CONTEXT: 6886 gen_helper_mtc0_context(cpu_env, arg); 6887 register_name = "Context"; 6888 break; 6889 case CP0_REG04__CONTEXTCONFIG: 6890 /* SmartMIPS ASE */ 6891 /* gen_helper_mtc0_contextconfig(arg); */ 6892 register_name = "ContextConfig"; 6893 goto cp0_unimplemented; 6894 case CP0_REG04__USERLOCAL: 6895 CP0_CHECK(ctx->ulri); 6896 tcg_gen_st_tl(arg, cpu_env, 6897 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6898 register_name = "UserLocal"; 6899 break; 6900 case CP0_REG04__MMID: 6901 CP0_CHECK(ctx->mi); 6902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6903 register_name = "MMID"; 6904 break; 6905 default: 6906 goto cp0_unimplemented; 6907 } 6908 break; 6909 case CP0_REGISTER_05: 6910 switch (sel) { 6911 case CP0_REG05__PAGEMASK: 6912 gen_helper_mtc0_pagemask(cpu_env, arg); 6913 register_name = "PageMask"; 6914 break; 6915 case CP0_REG05__PAGEGRAIN: 6916 check_insn(ctx, ISA_MIPS_R2); 6917 gen_helper_mtc0_pagegrain(cpu_env, arg); 6918 register_name = "PageGrain"; 6919 ctx->base.is_jmp = DISAS_STOP; 6920 break; 6921 case CP0_REG05__SEGCTL0: 6922 CP0_CHECK(ctx->sc); 6923 gen_helper_mtc0_segctl0(cpu_env, arg); 6924 register_name = "SegCtl0"; 6925 break; 6926 case CP0_REG05__SEGCTL1: 6927 CP0_CHECK(ctx->sc); 6928 gen_helper_mtc0_segctl1(cpu_env, arg); 6929 register_name = "SegCtl1"; 6930 break; 6931 case CP0_REG05__SEGCTL2: 6932 CP0_CHECK(ctx->sc); 6933 gen_helper_mtc0_segctl2(cpu_env, arg); 6934 register_name = "SegCtl2"; 6935 break; 6936 case CP0_REG05__PWBASE: 6937 check_pw(ctx); 6938 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6939 register_name = "PWBase"; 6940 break; 6941 case CP0_REG05__PWFIELD: 6942 check_pw(ctx); 6943 gen_helper_mtc0_pwfield(cpu_env, arg); 6944 register_name = "PWField"; 6945 break; 6946 case CP0_REG05__PWSIZE: 6947 check_pw(ctx); 6948 gen_helper_mtc0_pwsize(cpu_env, arg); 6949 register_name = "PWSize"; 6950 break; 6951 default: 6952 goto cp0_unimplemented; 6953 } 6954 break; 6955 case CP0_REGISTER_06: 6956 switch (sel) { 6957 case CP0_REG06__WIRED: 6958 gen_helper_mtc0_wired(cpu_env, arg); 6959 register_name = "Wired"; 6960 break; 6961 case CP0_REG06__SRSCONF0: 6962 check_insn(ctx, ISA_MIPS_R2); 6963 gen_helper_mtc0_srsconf0(cpu_env, arg); 6964 register_name = "SRSConf0"; 6965 break; 6966 case CP0_REG06__SRSCONF1: 6967 check_insn(ctx, ISA_MIPS_R2); 6968 gen_helper_mtc0_srsconf1(cpu_env, arg); 6969 register_name = "SRSConf1"; 6970 break; 6971 case CP0_REG06__SRSCONF2: 6972 check_insn(ctx, ISA_MIPS_R2); 6973 gen_helper_mtc0_srsconf2(cpu_env, arg); 6974 register_name = "SRSConf2"; 6975 break; 6976 case CP0_REG06__SRSCONF3: 6977 check_insn(ctx, ISA_MIPS_R2); 6978 gen_helper_mtc0_srsconf3(cpu_env, arg); 6979 register_name = "SRSConf3"; 6980 break; 6981 case CP0_REG06__SRSCONF4: 6982 check_insn(ctx, ISA_MIPS_R2); 6983 gen_helper_mtc0_srsconf4(cpu_env, arg); 6984 register_name = "SRSConf4"; 6985 break; 6986 case CP0_REG06__PWCTL: 6987 check_pw(ctx); 6988 gen_helper_mtc0_pwctl(cpu_env, arg); 6989 register_name = "PWCtl"; 6990 break; 6991 default: 6992 goto cp0_unimplemented; 6993 } 6994 break; 6995 case CP0_REGISTER_07: 6996 switch (sel) { 6997 case CP0_REG07__HWRENA: 6998 check_insn(ctx, ISA_MIPS_R2); 6999 gen_helper_mtc0_hwrena(cpu_env, arg); 7000 ctx->base.is_jmp = DISAS_STOP; 7001 register_name = "HWREna"; 7002 break; 7003 default: 7004 goto cp0_unimplemented; 7005 } 7006 break; 7007 case CP0_REGISTER_08: 7008 switch (sel) { 7009 case CP0_REG08__BADVADDR: 7010 /* ignored */ 7011 register_name = "BadVAddr"; 7012 break; 7013 case CP0_REG08__BADINSTR: 7014 /* ignored */ 7015 register_name = "BadInstr"; 7016 break; 7017 case CP0_REG08__BADINSTRP: 7018 /* ignored */ 7019 register_name = "BadInstrP"; 7020 break; 7021 case CP0_REG08__BADINSTRX: 7022 /* ignored */ 7023 register_name = "BadInstrX"; 7024 break; 7025 default: 7026 goto cp0_unimplemented; 7027 } 7028 break; 7029 case CP0_REGISTER_09: 7030 switch (sel) { 7031 case CP0_REG09__COUNT: 7032 gen_helper_mtc0_count(cpu_env, arg); 7033 register_name = "Count"; 7034 break; 7035 case CP0_REG09__SAARI: 7036 CP0_CHECK(ctx->saar); 7037 gen_helper_mtc0_saari(cpu_env, arg); 7038 register_name = "SAARI"; 7039 break; 7040 case CP0_REG09__SAAR: 7041 CP0_CHECK(ctx->saar); 7042 gen_helper_mtc0_saar(cpu_env, arg); 7043 register_name = "SAAR"; 7044 break; 7045 default: 7046 goto cp0_unimplemented; 7047 } 7048 break; 7049 case CP0_REGISTER_10: 7050 switch (sel) { 7051 case CP0_REG10__ENTRYHI: 7052 gen_helper_mtc0_entryhi(cpu_env, arg); 7053 register_name = "EntryHi"; 7054 break; 7055 default: 7056 goto cp0_unimplemented; 7057 } 7058 break; 7059 case CP0_REGISTER_11: 7060 switch (sel) { 7061 case CP0_REG11__COMPARE: 7062 gen_helper_mtc0_compare(cpu_env, arg); 7063 register_name = "Compare"; 7064 break; 7065 /* 6,7 are implementation dependent */ 7066 default: 7067 goto cp0_unimplemented; 7068 } 7069 break; 7070 case CP0_REGISTER_12: 7071 switch (sel) { 7072 case CP0_REG12__STATUS: 7073 save_cpu_state(ctx, 1); 7074 gen_helper_mtc0_status(cpu_env, arg); 7075 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7076 gen_save_pc(ctx->base.pc_next + 4); 7077 ctx->base.is_jmp = DISAS_EXIT; 7078 register_name = "Status"; 7079 break; 7080 case CP0_REG12__INTCTL: 7081 check_insn(ctx, ISA_MIPS_R2); 7082 gen_helper_mtc0_intctl(cpu_env, arg); 7083 /* Stop translation as we may have switched the execution mode */ 7084 ctx->base.is_jmp = DISAS_STOP; 7085 register_name = "IntCtl"; 7086 break; 7087 case CP0_REG12__SRSCTL: 7088 check_insn(ctx, ISA_MIPS_R2); 7089 gen_helper_mtc0_srsctl(cpu_env, arg); 7090 /* Stop translation as we may have switched the execution mode */ 7091 ctx->base.is_jmp = DISAS_STOP; 7092 register_name = "SRSCtl"; 7093 break; 7094 case CP0_REG12__SRSMAP: 7095 check_insn(ctx, ISA_MIPS_R2); 7096 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7097 /* Stop translation as we may have switched the execution mode */ 7098 ctx->base.is_jmp = DISAS_STOP; 7099 register_name = "SRSMap"; 7100 break; 7101 default: 7102 goto cp0_unimplemented; 7103 } 7104 break; 7105 case CP0_REGISTER_13: 7106 switch (sel) { 7107 case CP0_REG13__CAUSE: 7108 save_cpu_state(ctx, 1); 7109 gen_helper_mtc0_cause(cpu_env, arg); 7110 /* 7111 * Stop translation as we may have triggered an interrupt. 7112 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7113 * translated code to check for pending interrupts. 7114 */ 7115 gen_save_pc(ctx->base.pc_next + 4); 7116 ctx->base.is_jmp = DISAS_EXIT; 7117 register_name = "Cause"; 7118 break; 7119 default: 7120 goto cp0_unimplemented; 7121 } 7122 break; 7123 case CP0_REGISTER_14: 7124 switch (sel) { 7125 case CP0_REG14__EPC: 7126 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7127 register_name = "EPC"; 7128 break; 7129 default: 7130 goto cp0_unimplemented; 7131 } 7132 break; 7133 case CP0_REGISTER_15: 7134 switch (sel) { 7135 case CP0_REG15__PRID: 7136 /* ignored */ 7137 register_name = "PRid"; 7138 break; 7139 case CP0_REG15__EBASE: 7140 check_insn(ctx, ISA_MIPS_R2); 7141 gen_helper_mtc0_ebase(cpu_env, arg); 7142 register_name = "EBase"; 7143 break; 7144 default: 7145 goto cp0_unimplemented; 7146 } 7147 break; 7148 case CP0_REGISTER_16: 7149 switch (sel) { 7150 case CP0_REG16__CONFIG: 7151 gen_helper_mtc0_config0(cpu_env, arg); 7152 register_name = "Config"; 7153 /* Stop translation as we may have switched the execution mode */ 7154 ctx->base.is_jmp = DISAS_STOP; 7155 break; 7156 case CP0_REG16__CONFIG1: 7157 /* ignored, read only */ 7158 register_name = "Config1"; 7159 break; 7160 case CP0_REG16__CONFIG2: 7161 gen_helper_mtc0_config2(cpu_env, arg); 7162 register_name = "Config2"; 7163 /* Stop translation as we may have switched the execution mode */ 7164 ctx->base.is_jmp = DISAS_STOP; 7165 break; 7166 case CP0_REG16__CONFIG3: 7167 gen_helper_mtc0_config3(cpu_env, arg); 7168 register_name = "Config3"; 7169 /* Stop translation as we may have switched the execution mode */ 7170 ctx->base.is_jmp = DISAS_STOP; 7171 break; 7172 case CP0_REG16__CONFIG4: 7173 gen_helper_mtc0_config4(cpu_env, arg); 7174 register_name = "Config4"; 7175 ctx->base.is_jmp = DISAS_STOP; 7176 break; 7177 case CP0_REG16__CONFIG5: 7178 gen_helper_mtc0_config5(cpu_env, arg); 7179 register_name = "Config5"; 7180 /* Stop translation as we may have switched the execution mode */ 7181 ctx->base.is_jmp = DISAS_STOP; 7182 break; 7183 /* 6,7 are implementation dependent */ 7184 case CP0_REG16__CONFIG6: 7185 /* ignored */ 7186 register_name = "Config6"; 7187 break; 7188 case CP0_REG16__CONFIG7: 7189 /* ignored */ 7190 register_name = "Config7"; 7191 break; 7192 default: 7193 register_name = "Invalid config selector"; 7194 goto cp0_unimplemented; 7195 } 7196 break; 7197 case CP0_REGISTER_17: 7198 switch (sel) { 7199 case CP0_REG17__LLADDR: 7200 gen_helper_mtc0_lladdr(cpu_env, arg); 7201 register_name = "LLAddr"; 7202 break; 7203 case CP0_REG17__MAAR: 7204 CP0_CHECK(ctx->mrp); 7205 gen_helper_mtc0_maar(cpu_env, arg); 7206 register_name = "MAAR"; 7207 break; 7208 case CP0_REG17__MAARI: 7209 CP0_CHECK(ctx->mrp); 7210 gen_helper_mtc0_maari(cpu_env, arg); 7211 register_name = "MAARI"; 7212 break; 7213 default: 7214 goto cp0_unimplemented; 7215 } 7216 break; 7217 case CP0_REGISTER_18: 7218 switch (sel) { 7219 case CP0_REG18__WATCHLO0: 7220 case CP0_REG18__WATCHLO1: 7221 case CP0_REG18__WATCHLO2: 7222 case CP0_REG18__WATCHLO3: 7223 case CP0_REG18__WATCHLO4: 7224 case CP0_REG18__WATCHLO5: 7225 case CP0_REG18__WATCHLO6: 7226 case CP0_REG18__WATCHLO7: 7227 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7228 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7229 register_name = "WatchLo"; 7230 break; 7231 default: 7232 goto cp0_unimplemented; 7233 } 7234 break; 7235 case CP0_REGISTER_19: 7236 switch (sel) { 7237 case CP0_REG19__WATCHHI0: 7238 case CP0_REG19__WATCHHI1: 7239 case CP0_REG19__WATCHHI2: 7240 case CP0_REG19__WATCHHI3: 7241 case CP0_REG19__WATCHHI4: 7242 case CP0_REG19__WATCHHI5: 7243 case CP0_REG19__WATCHHI6: 7244 case CP0_REG19__WATCHHI7: 7245 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7246 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7247 register_name = "WatchHi"; 7248 break; 7249 default: 7250 goto cp0_unimplemented; 7251 } 7252 break; 7253 case CP0_REGISTER_20: 7254 switch (sel) { 7255 case CP0_REG20__XCONTEXT: 7256 #if defined(TARGET_MIPS64) 7257 check_insn(ctx, ISA_MIPS3); 7258 gen_helper_mtc0_xcontext(cpu_env, arg); 7259 register_name = "XContext"; 7260 break; 7261 #endif 7262 default: 7263 goto cp0_unimplemented; 7264 } 7265 break; 7266 case CP0_REGISTER_21: 7267 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7268 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7269 switch (sel) { 7270 case 0: 7271 gen_helper_mtc0_framemask(cpu_env, arg); 7272 register_name = "Framemask"; 7273 break; 7274 default: 7275 goto cp0_unimplemented; 7276 } 7277 break; 7278 case CP0_REGISTER_22: 7279 /* ignored */ 7280 register_name = "Diagnostic"; /* implementation dependent */ 7281 break; 7282 case CP0_REGISTER_23: 7283 switch (sel) { 7284 case CP0_REG23__DEBUG: 7285 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 7286 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7287 gen_save_pc(ctx->base.pc_next + 4); 7288 ctx->base.is_jmp = DISAS_EXIT; 7289 register_name = "Debug"; 7290 break; 7291 case CP0_REG23__TRACECONTROL: 7292 /* PDtrace support */ 7293 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 7294 register_name = "TraceControl"; 7295 /* Stop translation as we may have switched the execution mode */ 7296 ctx->base.is_jmp = DISAS_STOP; 7297 goto cp0_unimplemented; 7298 case CP0_REG23__TRACECONTROL2: 7299 /* PDtrace support */ 7300 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 7301 register_name = "TraceControl2"; 7302 /* Stop translation as we may have switched the execution mode */ 7303 ctx->base.is_jmp = DISAS_STOP; 7304 goto cp0_unimplemented; 7305 case CP0_REG23__USERTRACEDATA1: 7306 /* Stop translation as we may have switched the execution mode */ 7307 ctx->base.is_jmp = DISAS_STOP; 7308 /* PDtrace support */ 7309 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 7310 register_name = "UserTraceData"; 7311 /* Stop translation as we may have switched the execution mode */ 7312 ctx->base.is_jmp = DISAS_STOP; 7313 goto cp0_unimplemented; 7314 case CP0_REG23__TRACEIBPC: 7315 /* PDtrace support */ 7316 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 7317 /* Stop translation as we may have switched the execution mode */ 7318 ctx->base.is_jmp = DISAS_STOP; 7319 register_name = "TraceIBPC"; 7320 goto cp0_unimplemented; 7321 case CP0_REG23__TRACEDBPC: 7322 /* PDtrace support */ 7323 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 7324 /* Stop translation as we may have switched the execution mode */ 7325 ctx->base.is_jmp = DISAS_STOP; 7326 register_name = "TraceDBPC"; 7327 goto cp0_unimplemented; 7328 default: 7329 goto cp0_unimplemented; 7330 } 7331 break; 7332 case CP0_REGISTER_24: 7333 switch (sel) { 7334 case CP0_REG24__DEPC: 7335 /* EJTAG support */ 7336 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7337 register_name = "DEPC"; 7338 break; 7339 default: 7340 goto cp0_unimplemented; 7341 } 7342 break; 7343 case CP0_REGISTER_25: 7344 switch (sel) { 7345 case CP0_REG25__PERFCTL0: 7346 gen_helper_mtc0_performance0(cpu_env, arg); 7347 register_name = "Performance0"; 7348 break; 7349 case CP0_REG25__PERFCNT0: 7350 /* gen_helper_mtc0_performance1(arg); */ 7351 register_name = "Performance1"; 7352 goto cp0_unimplemented; 7353 case CP0_REG25__PERFCTL1: 7354 /* gen_helper_mtc0_performance2(arg); */ 7355 register_name = "Performance2"; 7356 goto cp0_unimplemented; 7357 case CP0_REG25__PERFCNT1: 7358 /* gen_helper_mtc0_performance3(arg); */ 7359 register_name = "Performance3"; 7360 goto cp0_unimplemented; 7361 case CP0_REG25__PERFCTL2: 7362 /* gen_helper_mtc0_performance4(arg); */ 7363 register_name = "Performance4"; 7364 goto cp0_unimplemented; 7365 case CP0_REG25__PERFCNT2: 7366 /* gen_helper_mtc0_performance5(arg); */ 7367 register_name = "Performance5"; 7368 goto cp0_unimplemented; 7369 case CP0_REG25__PERFCTL3: 7370 /* gen_helper_mtc0_performance6(arg); */ 7371 register_name = "Performance6"; 7372 goto cp0_unimplemented; 7373 case CP0_REG25__PERFCNT3: 7374 /* gen_helper_mtc0_performance7(arg); */ 7375 register_name = "Performance7"; 7376 goto cp0_unimplemented; 7377 default: 7378 goto cp0_unimplemented; 7379 } 7380 break; 7381 case CP0_REGISTER_26: 7382 switch (sel) { 7383 case CP0_REG26__ERRCTL: 7384 gen_helper_mtc0_errctl(cpu_env, arg); 7385 ctx->base.is_jmp = DISAS_STOP; 7386 register_name = "ErrCtl"; 7387 break; 7388 default: 7389 goto cp0_unimplemented; 7390 } 7391 break; 7392 case CP0_REGISTER_27: 7393 switch (sel) { 7394 case CP0_REG27__CACHERR: 7395 /* ignored */ 7396 register_name = "CacheErr"; 7397 break; 7398 default: 7399 goto cp0_unimplemented; 7400 } 7401 break; 7402 case CP0_REGISTER_28: 7403 switch (sel) { 7404 case CP0_REG28__TAGLO: 7405 case CP0_REG28__TAGLO1: 7406 case CP0_REG28__TAGLO2: 7407 case CP0_REG28__TAGLO3: 7408 gen_helper_mtc0_taglo(cpu_env, arg); 7409 register_name = "TagLo"; 7410 break; 7411 case CP0_REG28__DATALO: 7412 case CP0_REG28__DATALO1: 7413 case CP0_REG28__DATALO2: 7414 case CP0_REG28__DATALO3: 7415 gen_helper_mtc0_datalo(cpu_env, arg); 7416 register_name = "DataLo"; 7417 break; 7418 default: 7419 goto cp0_unimplemented; 7420 } 7421 break; 7422 case CP0_REGISTER_29: 7423 switch (sel) { 7424 case CP0_REG29__TAGHI: 7425 case CP0_REG29__TAGHI1: 7426 case CP0_REG29__TAGHI2: 7427 case CP0_REG29__TAGHI3: 7428 gen_helper_mtc0_taghi(cpu_env, arg); 7429 register_name = "TagHi"; 7430 break; 7431 case CP0_REG29__DATAHI: 7432 case CP0_REG29__DATAHI1: 7433 case CP0_REG29__DATAHI2: 7434 case CP0_REG29__DATAHI3: 7435 gen_helper_mtc0_datahi(cpu_env, arg); 7436 register_name = "DataHi"; 7437 break; 7438 default: 7439 register_name = "invalid sel"; 7440 goto cp0_unimplemented; 7441 } 7442 break; 7443 case CP0_REGISTER_30: 7444 switch (sel) { 7445 case CP0_REG30__ERROREPC: 7446 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7447 register_name = "ErrorEPC"; 7448 break; 7449 default: 7450 goto cp0_unimplemented; 7451 } 7452 break; 7453 case CP0_REGISTER_31: 7454 switch (sel) { 7455 case CP0_REG31__DESAVE: 7456 /* EJTAG support */ 7457 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7458 register_name = "DESAVE"; 7459 break; 7460 case CP0_REG31__KSCRATCH1: 7461 case CP0_REG31__KSCRATCH2: 7462 case CP0_REG31__KSCRATCH3: 7463 case CP0_REG31__KSCRATCH4: 7464 case CP0_REG31__KSCRATCH5: 7465 case CP0_REG31__KSCRATCH6: 7466 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7467 tcg_gen_st_tl(arg, cpu_env, 7468 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7469 register_name = "KScratch"; 7470 break; 7471 default: 7472 goto cp0_unimplemented; 7473 } 7474 break; 7475 default: 7476 goto cp0_unimplemented; 7477 } 7478 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7479 7480 /* For simplicity assume that all writes can cause interrupts. */ 7481 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7482 /* 7483 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7484 * translated code to check for pending interrupts. 7485 */ 7486 gen_save_pc(ctx->base.pc_next + 4); 7487 ctx->base.is_jmp = DISAS_EXIT; 7488 } 7489 return; 7490 7491 cp0_unimplemented: 7492 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7493 register_name, reg, sel); 7494 } 7495 7496 #if defined(TARGET_MIPS64) 7497 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7498 { 7499 const char *register_name = "invalid"; 7500 7501 if (sel != 0) { 7502 check_insn(ctx, ISA_MIPS_R1); 7503 } 7504 7505 switch (reg) { 7506 case CP0_REGISTER_00: 7507 switch (sel) { 7508 case CP0_REG00__INDEX: 7509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7510 register_name = "Index"; 7511 break; 7512 case CP0_REG00__MVPCONTROL: 7513 CP0_CHECK(ctx->insn_flags & ASE_MT); 7514 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7515 register_name = "MVPControl"; 7516 break; 7517 case CP0_REG00__MVPCONF0: 7518 CP0_CHECK(ctx->insn_flags & ASE_MT); 7519 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7520 register_name = "MVPConf0"; 7521 break; 7522 case CP0_REG00__MVPCONF1: 7523 CP0_CHECK(ctx->insn_flags & ASE_MT); 7524 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7525 register_name = "MVPConf1"; 7526 break; 7527 case CP0_REG00__VPCONTROL: 7528 CP0_CHECK(ctx->vp); 7529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7530 register_name = "VPControl"; 7531 break; 7532 default: 7533 goto cp0_unimplemented; 7534 } 7535 break; 7536 case CP0_REGISTER_01: 7537 switch (sel) { 7538 case CP0_REG01__RANDOM: 7539 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7540 gen_helper_mfc0_random(arg, cpu_env); 7541 register_name = "Random"; 7542 break; 7543 case CP0_REG01__VPECONTROL: 7544 CP0_CHECK(ctx->insn_flags & ASE_MT); 7545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7546 register_name = "VPEControl"; 7547 break; 7548 case CP0_REG01__VPECONF0: 7549 CP0_CHECK(ctx->insn_flags & ASE_MT); 7550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7551 register_name = "VPEConf0"; 7552 break; 7553 case CP0_REG01__VPECONF1: 7554 CP0_CHECK(ctx->insn_flags & ASE_MT); 7555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7556 register_name = "VPEConf1"; 7557 break; 7558 case CP0_REG01__YQMASK: 7559 CP0_CHECK(ctx->insn_flags & ASE_MT); 7560 tcg_gen_ld_tl(arg, cpu_env, 7561 offsetof(CPUMIPSState, CP0_YQMask)); 7562 register_name = "YQMask"; 7563 break; 7564 case CP0_REG01__VPESCHEDULE: 7565 CP0_CHECK(ctx->insn_flags & ASE_MT); 7566 tcg_gen_ld_tl(arg, cpu_env, 7567 offsetof(CPUMIPSState, CP0_VPESchedule)); 7568 register_name = "VPESchedule"; 7569 break; 7570 case CP0_REG01__VPESCHEFBACK: 7571 CP0_CHECK(ctx->insn_flags & ASE_MT); 7572 tcg_gen_ld_tl(arg, cpu_env, 7573 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7574 register_name = "VPEScheFBack"; 7575 break; 7576 case CP0_REG01__VPEOPT: 7577 CP0_CHECK(ctx->insn_flags & ASE_MT); 7578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7579 register_name = "VPEOpt"; 7580 break; 7581 default: 7582 goto cp0_unimplemented; 7583 } 7584 break; 7585 case CP0_REGISTER_02: 7586 switch (sel) { 7587 case CP0_REG02__ENTRYLO0: 7588 tcg_gen_ld_tl(arg, cpu_env, 7589 offsetof(CPUMIPSState, CP0_EntryLo0)); 7590 register_name = "EntryLo0"; 7591 break; 7592 case CP0_REG02__TCSTATUS: 7593 CP0_CHECK(ctx->insn_flags & ASE_MT); 7594 gen_helper_mfc0_tcstatus(arg, cpu_env); 7595 register_name = "TCStatus"; 7596 break; 7597 case CP0_REG02__TCBIND: 7598 CP0_CHECK(ctx->insn_flags & ASE_MT); 7599 gen_helper_mfc0_tcbind(arg, cpu_env); 7600 register_name = "TCBind"; 7601 break; 7602 case CP0_REG02__TCRESTART: 7603 CP0_CHECK(ctx->insn_flags & ASE_MT); 7604 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7605 register_name = "TCRestart"; 7606 break; 7607 case CP0_REG02__TCHALT: 7608 CP0_CHECK(ctx->insn_flags & ASE_MT); 7609 gen_helper_dmfc0_tchalt(arg, cpu_env); 7610 register_name = "TCHalt"; 7611 break; 7612 case CP0_REG02__TCCONTEXT: 7613 CP0_CHECK(ctx->insn_flags & ASE_MT); 7614 gen_helper_dmfc0_tccontext(arg, cpu_env); 7615 register_name = "TCContext"; 7616 break; 7617 case CP0_REG02__TCSCHEDULE: 7618 CP0_CHECK(ctx->insn_flags & ASE_MT); 7619 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7620 register_name = "TCSchedule"; 7621 break; 7622 case CP0_REG02__TCSCHEFBACK: 7623 CP0_CHECK(ctx->insn_flags & ASE_MT); 7624 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7625 register_name = "TCScheFBack"; 7626 break; 7627 default: 7628 goto cp0_unimplemented; 7629 } 7630 break; 7631 case CP0_REGISTER_03: 7632 switch (sel) { 7633 case CP0_REG03__ENTRYLO1: 7634 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7635 register_name = "EntryLo1"; 7636 break; 7637 case CP0_REG03__GLOBALNUM: 7638 CP0_CHECK(ctx->vp); 7639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7640 register_name = "GlobalNumber"; 7641 break; 7642 default: 7643 goto cp0_unimplemented; 7644 } 7645 break; 7646 case CP0_REGISTER_04: 7647 switch (sel) { 7648 case CP0_REG04__CONTEXT: 7649 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7650 register_name = "Context"; 7651 break; 7652 case CP0_REG04__CONTEXTCONFIG: 7653 /* SmartMIPS ASE */ 7654 /* gen_helper_dmfc0_contextconfig(arg); */ 7655 register_name = "ContextConfig"; 7656 goto cp0_unimplemented; 7657 case CP0_REG04__USERLOCAL: 7658 CP0_CHECK(ctx->ulri); 7659 tcg_gen_ld_tl(arg, cpu_env, 7660 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7661 register_name = "UserLocal"; 7662 break; 7663 case CP0_REG04__MMID: 7664 CP0_CHECK(ctx->mi); 7665 gen_helper_mtc0_memorymapid(cpu_env, arg); 7666 register_name = "MMID"; 7667 break; 7668 default: 7669 goto cp0_unimplemented; 7670 } 7671 break; 7672 case CP0_REGISTER_05: 7673 switch (sel) { 7674 case CP0_REG05__PAGEMASK: 7675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7676 register_name = "PageMask"; 7677 break; 7678 case CP0_REG05__PAGEGRAIN: 7679 check_insn(ctx, ISA_MIPS_R2); 7680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7681 register_name = "PageGrain"; 7682 break; 7683 case CP0_REG05__SEGCTL0: 7684 CP0_CHECK(ctx->sc); 7685 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7686 register_name = "SegCtl0"; 7687 break; 7688 case CP0_REG05__SEGCTL1: 7689 CP0_CHECK(ctx->sc); 7690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7691 register_name = "SegCtl1"; 7692 break; 7693 case CP0_REG05__SEGCTL2: 7694 CP0_CHECK(ctx->sc); 7695 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7696 register_name = "SegCtl2"; 7697 break; 7698 case CP0_REG05__PWBASE: 7699 check_pw(ctx); 7700 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7701 register_name = "PWBase"; 7702 break; 7703 case CP0_REG05__PWFIELD: 7704 check_pw(ctx); 7705 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7706 register_name = "PWField"; 7707 break; 7708 case CP0_REG05__PWSIZE: 7709 check_pw(ctx); 7710 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7711 register_name = "PWSize"; 7712 break; 7713 default: 7714 goto cp0_unimplemented; 7715 } 7716 break; 7717 case CP0_REGISTER_06: 7718 switch (sel) { 7719 case CP0_REG06__WIRED: 7720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7721 register_name = "Wired"; 7722 break; 7723 case CP0_REG06__SRSCONF0: 7724 check_insn(ctx, ISA_MIPS_R2); 7725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7726 register_name = "SRSConf0"; 7727 break; 7728 case CP0_REG06__SRSCONF1: 7729 check_insn(ctx, ISA_MIPS_R2); 7730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7731 register_name = "SRSConf1"; 7732 break; 7733 case CP0_REG06__SRSCONF2: 7734 check_insn(ctx, ISA_MIPS_R2); 7735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7736 register_name = "SRSConf2"; 7737 break; 7738 case CP0_REG06__SRSCONF3: 7739 check_insn(ctx, ISA_MIPS_R2); 7740 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7741 register_name = "SRSConf3"; 7742 break; 7743 case CP0_REG06__SRSCONF4: 7744 check_insn(ctx, ISA_MIPS_R2); 7745 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7746 register_name = "SRSConf4"; 7747 break; 7748 case CP0_REG06__PWCTL: 7749 check_pw(ctx); 7750 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7751 register_name = "PWCtl"; 7752 break; 7753 default: 7754 goto cp0_unimplemented; 7755 } 7756 break; 7757 case CP0_REGISTER_07: 7758 switch (sel) { 7759 case CP0_REG07__HWRENA: 7760 check_insn(ctx, ISA_MIPS_R2); 7761 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7762 register_name = "HWREna"; 7763 break; 7764 default: 7765 goto cp0_unimplemented; 7766 } 7767 break; 7768 case CP0_REGISTER_08: 7769 switch (sel) { 7770 case CP0_REG08__BADVADDR: 7771 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7772 register_name = "BadVAddr"; 7773 break; 7774 case CP0_REG08__BADINSTR: 7775 CP0_CHECK(ctx->bi); 7776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7777 register_name = "BadInstr"; 7778 break; 7779 case CP0_REG08__BADINSTRP: 7780 CP0_CHECK(ctx->bp); 7781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7782 register_name = "BadInstrP"; 7783 break; 7784 case CP0_REG08__BADINSTRX: 7785 CP0_CHECK(ctx->bi); 7786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7787 tcg_gen_andi_tl(arg, arg, ~0xffff); 7788 register_name = "BadInstrX"; 7789 break; 7790 default: 7791 goto cp0_unimplemented; 7792 } 7793 break; 7794 case CP0_REGISTER_09: 7795 switch (sel) { 7796 case CP0_REG09__COUNT: 7797 /* Mark as an IO operation because we read the time. */ 7798 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7799 gen_io_start(); 7800 } 7801 gen_helper_mfc0_count(arg, cpu_env); 7802 /* 7803 * Break the TB to be able to take timer interrupts immediately 7804 * after reading count. DISAS_STOP isn't sufficient, we need to 7805 * ensure we break completely out of translated code. 7806 */ 7807 gen_save_pc(ctx->base.pc_next + 4); 7808 ctx->base.is_jmp = DISAS_EXIT; 7809 register_name = "Count"; 7810 break; 7811 case CP0_REG09__SAARI: 7812 CP0_CHECK(ctx->saar); 7813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7814 register_name = "SAARI"; 7815 break; 7816 case CP0_REG09__SAAR: 7817 CP0_CHECK(ctx->saar); 7818 gen_helper_dmfc0_saar(arg, cpu_env); 7819 register_name = "SAAR"; 7820 break; 7821 default: 7822 goto cp0_unimplemented; 7823 } 7824 break; 7825 case CP0_REGISTER_10: 7826 switch (sel) { 7827 case CP0_REG10__ENTRYHI: 7828 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7829 register_name = "EntryHi"; 7830 break; 7831 default: 7832 goto cp0_unimplemented; 7833 } 7834 break; 7835 case CP0_REGISTER_11: 7836 switch (sel) { 7837 case CP0_REG11__COMPARE: 7838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7839 register_name = "Compare"; 7840 break; 7841 /* 6,7 are implementation dependent */ 7842 default: 7843 goto cp0_unimplemented; 7844 } 7845 break; 7846 case CP0_REGISTER_12: 7847 switch (sel) { 7848 case CP0_REG12__STATUS: 7849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7850 register_name = "Status"; 7851 break; 7852 case CP0_REG12__INTCTL: 7853 check_insn(ctx, ISA_MIPS_R2); 7854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7855 register_name = "IntCtl"; 7856 break; 7857 case CP0_REG12__SRSCTL: 7858 check_insn(ctx, ISA_MIPS_R2); 7859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7860 register_name = "SRSCtl"; 7861 break; 7862 case CP0_REG12__SRSMAP: 7863 check_insn(ctx, ISA_MIPS_R2); 7864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7865 register_name = "SRSMap"; 7866 break; 7867 default: 7868 goto cp0_unimplemented; 7869 } 7870 break; 7871 case CP0_REGISTER_13: 7872 switch (sel) { 7873 case CP0_REG13__CAUSE: 7874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7875 register_name = "Cause"; 7876 break; 7877 default: 7878 goto cp0_unimplemented; 7879 } 7880 break; 7881 case CP0_REGISTER_14: 7882 switch (sel) { 7883 case CP0_REG14__EPC: 7884 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7885 register_name = "EPC"; 7886 break; 7887 default: 7888 goto cp0_unimplemented; 7889 } 7890 break; 7891 case CP0_REGISTER_15: 7892 switch (sel) { 7893 case CP0_REG15__PRID: 7894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7895 register_name = "PRid"; 7896 break; 7897 case CP0_REG15__EBASE: 7898 check_insn(ctx, ISA_MIPS_R2); 7899 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7900 register_name = "EBase"; 7901 break; 7902 case CP0_REG15__CMGCRBASE: 7903 check_insn(ctx, ISA_MIPS_R2); 7904 CP0_CHECK(ctx->cmgcr); 7905 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7906 register_name = "CMGCRBase"; 7907 break; 7908 default: 7909 goto cp0_unimplemented; 7910 } 7911 break; 7912 case CP0_REGISTER_16: 7913 switch (sel) { 7914 case CP0_REG16__CONFIG: 7915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7916 register_name = "Config"; 7917 break; 7918 case CP0_REG16__CONFIG1: 7919 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7920 register_name = "Config1"; 7921 break; 7922 case CP0_REG16__CONFIG2: 7923 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7924 register_name = "Config2"; 7925 break; 7926 case CP0_REG16__CONFIG3: 7927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7928 register_name = "Config3"; 7929 break; 7930 case CP0_REG16__CONFIG4: 7931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7932 register_name = "Config4"; 7933 break; 7934 case CP0_REG16__CONFIG5: 7935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7936 register_name = "Config5"; 7937 break; 7938 /* 6,7 are implementation dependent */ 7939 case CP0_REG16__CONFIG6: 7940 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7941 register_name = "Config6"; 7942 break; 7943 case CP0_REG16__CONFIG7: 7944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7945 register_name = "Config7"; 7946 break; 7947 default: 7948 goto cp0_unimplemented; 7949 } 7950 break; 7951 case CP0_REGISTER_17: 7952 switch (sel) { 7953 case CP0_REG17__LLADDR: 7954 gen_helper_dmfc0_lladdr(arg, cpu_env); 7955 register_name = "LLAddr"; 7956 break; 7957 case CP0_REG17__MAAR: 7958 CP0_CHECK(ctx->mrp); 7959 gen_helper_dmfc0_maar(arg, cpu_env); 7960 register_name = "MAAR"; 7961 break; 7962 case CP0_REG17__MAARI: 7963 CP0_CHECK(ctx->mrp); 7964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7965 register_name = "MAARI"; 7966 break; 7967 default: 7968 goto cp0_unimplemented; 7969 } 7970 break; 7971 case CP0_REGISTER_18: 7972 switch (sel) { 7973 case CP0_REG18__WATCHLO0: 7974 case CP0_REG18__WATCHLO1: 7975 case CP0_REG18__WATCHLO2: 7976 case CP0_REG18__WATCHLO3: 7977 case CP0_REG18__WATCHLO4: 7978 case CP0_REG18__WATCHLO5: 7979 case CP0_REG18__WATCHLO6: 7980 case CP0_REG18__WATCHLO7: 7981 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7982 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7983 register_name = "WatchLo"; 7984 break; 7985 default: 7986 goto cp0_unimplemented; 7987 } 7988 break; 7989 case CP0_REGISTER_19: 7990 switch (sel) { 7991 case CP0_REG19__WATCHHI0: 7992 case CP0_REG19__WATCHHI1: 7993 case CP0_REG19__WATCHHI2: 7994 case CP0_REG19__WATCHHI3: 7995 case CP0_REG19__WATCHHI4: 7996 case CP0_REG19__WATCHHI5: 7997 case CP0_REG19__WATCHHI6: 7998 case CP0_REG19__WATCHHI7: 7999 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8000 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 8001 register_name = "WatchHi"; 8002 break; 8003 default: 8004 goto cp0_unimplemented; 8005 } 8006 break; 8007 case CP0_REGISTER_20: 8008 switch (sel) { 8009 case CP0_REG20__XCONTEXT: 8010 check_insn(ctx, ISA_MIPS3); 8011 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 8012 register_name = "XContext"; 8013 break; 8014 default: 8015 goto cp0_unimplemented; 8016 } 8017 break; 8018 case CP0_REGISTER_21: 8019 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8020 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8021 switch (sel) { 8022 case 0: 8023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 8024 register_name = "Framemask"; 8025 break; 8026 default: 8027 goto cp0_unimplemented; 8028 } 8029 break; 8030 case CP0_REGISTER_22: 8031 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 8032 register_name = "'Diagnostic"; /* implementation dependent */ 8033 break; 8034 case CP0_REGISTER_23: 8035 switch (sel) { 8036 case CP0_REG23__DEBUG: 8037 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 8038 register_name = "Debug"; 8039 break; 8040 case CP0_REG23__TRACECONTROL: 8041 /* PDtrace support */ 8042 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 8043 register_name = "TraceControl"; 8044 goto cp0_unimplemented; 8045 case CP0_REG23__TRACECONTROL2: 8046 /* PDtrace support */ 8047 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 8048 register_name = "TraceControl2"; 8049 goto cp0_unimplemented; 8050 case CP0_REG23__USERTRACEDATA1: 8051 /* PDtrace support */ 8052 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 8053 register_name = "UserTraceData1"; 8054 goto cp0_unimplemented; 8055 case CP0_REG23__TRACEIBPC: 8056 /* PDtrace support */ 8057 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 8058 register_name = "TraceIBPC"; 8059 goto cp0_unimplemented; 8060 case CP0_REG23__TRACEDBPC: 8061 /* PDtrace support */ 8062 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 8063 register_name = "TraceDBPC"; 8064 goto cp0_unimplemented; 8065 default: 8066 goto cp0_unimplemented; 8067 } 8068 break; 8069 case CP0_REGISTER_24: 8070 switch (sel) { 8071 case CP0_REG24__DEPC: 8072 /* EJTAG support */ 8073 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8074 register_name = "DEPC"; 8075 break; 8076 default: 8077 goto cp0_unimplemented; 8078 } 8079 break; 8080 case CP0_REGISTER_25: 8081 switch (sel) { 8082 case CP0_REG25__PERFCTL0: 8083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 8084 register_name = "Performance0"; 8085 break; 8086 case CP0_REG25__PERFCNT0: 8087 /* gen_helper_dmfc0_performance1(arg); */ 8088 register_name = "Performance1"; 8089 goto cp0_unimplemented; 8090 case CP0_REG25__PERFCTL1: 8091 /* gen_helper_dmfc0_performance2(arg); */ 8092 register_name = "Performance2"; 8093 goto cp0_unimplemented; 8094 case CP0_REG25__PERFCNT1: 8095 /* gen_helper_dmfc0_performance3(arg); */ 8096 register_name = "Performance3"; 8097 goto cp0_unimplemented; 8098 case CP0_REG25__PERFCTL2: 8099 /* gen_helper_dmfc0_performance4(arg); */ 8100 register_name = "Performance4"; 8101 goto cp0_unimplemented; 8102 case CP0_REG25__PERFCNT2: 8103 /* gen_helper_dmfc0_performance5(arg); */ 8104 register_name = "Performance5"; 8105 goto cp0_unimplemented; 8106 case CP0_REG25__PERFCTL3: 8107 /* gen_helper_dmfc0_performance6(arg); */ 8108 register_name = "Performance6"; 8109 goto cp0_unimplemented; 8110 case CP0_REG25__PERFCNT3: 8111 /* gen_helper_dmfc0_performance7(arg); */ 8112 register_name = "Performance7"; 8113 goto cp0_unimplemented; 8114 default: 8115 goto cp0_unimplemented; 8116 } 8117 break; 8118 case CP0_REGISTER_26: 8119 switch (sel) { 8120 case CP0_REG26__ERRCTL: 8121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 8122 register_name = "ErrCtl"; 8123 break; 8124 default: 8125 goto cp0_unimplemented; 8126 } 8127 break; 8128 case CP0_REGISTER_27: 8129 switch (sel) { 8130 /* ignored */ 8131 case CP0_REG27__CACHERR: 8132 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 8133 register_name = "CacheErr"; 8134 break; 8135 default: 8136 goto cp0_unimplemented; 8137 } 8138 break; 8139 case CP0_REGISTER_28: 8140 switch (sel) { 8141 case CP0_REG28__TAGLO: 8142 case CP0_REG28__TAGLO1: 8143 case CP0_REG28__TAGLO2: 8144 case CP0_REG28__TAGLO3: 8145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 8146 register_name = "TagLo"; 8147 break; 8148 case CP0_REG28__DATALO: 8149 case CP0_REG28__DATALO1: 8150 case CP0_REG28__DATALO2: 8151 case CP0_REG28__DATALO3: 8152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 8153 register_name = "DataLo"; 8154 break; 8155 default: 8156 goto cp0_unimplemented; 8157 } 8158 break; 8159 case CP0_REGISTER_29: 8160 switch (sel) { 8161 case CP0_REG29__TAGHI: 8162 case CP0_REG29__TAGHI1: 8163 case CP0_REG29__TAGHI2: 8164 case CP0_REG29__TAGHI3: 8165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 8166 register_name = "TagHi"; 8167 break; 8168 case CP0_REG29__DATAHI: 8169 case CP0_REG29__DATAHI1: 8170 case CP0_REG29__DATAHI2: 8171 case CP0_REG29__DATAHI3: 8172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 8173 register_name = "DataHi"; 8174 break; 8175 default: 8176 goto cp0_unimplemented; 8177 } 8178 break; 8179 case CP0_REGISTER_30: 8180 switch (sel) { 8181 case CP0_REG30__ERROREPC: 8182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8183 register_name = "ErrorEPC"; 8184 break; 8185 default: 8186 goto cp0_unimplemented; 8187 } 8188 break; 8189 case CP0_REGISTER_31: 8190 switch (sel) { 8191 case CP0_REG31__DESAVE: 8192 /* EJTAG support */ 8193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8194 register_name = "DESAVE"; 8195 break; 8196 case CP0_REG31__KSCRATCH1: 8197 case CP0_REG31__KSCRATCH2: 8198 case CP0_REG31__KSCRATCH3: 8199 case CP0_REG31__KSCRATCH4: 8200 case CP0_REG31__KSCRATCH5: 8201 case CP0_REG31__KSCRATCH6: 8202 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8203 tcg_gen_ld_tl(arg, cpu_env, 8204 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8205 register_name = "KScratch"; 8206 break; 8207 default: 8208 goto cp0_unimplemented; 8209 } 8210 break; 8211 default: 8212 goto cp0_unimplemented; 8213 } 8214 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 8215 return; 8216 8217 cp0_unimplemented: 8218 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 8219 register_name, reg, sel); 8220 gen_mfc0_unimplemented(ctx, arg); 8221 } 8222 8223 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 8224 { 8225 const char *register_name = "invalid"; 8226 8227 if (sel != 0) { 8228 check_insn(ctx, ISA_MIPS_R1); 8229 } 8230 8231 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8232 gen_io_start(); 8233 } 8234 8235 switch (reg) { 8236 case CP0_REGISTER_00: 8237 switch (sel) { 8238 case CP0_REG00__INDEX: 8239 gen_helper_mtc0_index(cpu_env, arg); 8240 register_name = "Index"; 8241 break; 8242 case CP0_REG00__MVPCONTROL: 8243 CP0_CHECK(ctx->insn_flags & ASE_MT); 8244 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 8245 register_name = "MVPControl"; 8246 break; 8247 case CP0_REG00__MVPCONF0: 8248 CP0_CHECK(ctx->insn_flags & ASE_MT); 8249 /* ignored */ 8250 register_name = "MVPConf0"; 8251 break; 8252 case CP0_REG00__MVPCONF1: 8253 CP0_CHECK(ctx->insn_flags & ASE_MT); 8254 /* ignored */ 8255 register_name = "MVPConf1"; 8256 break; 8257 case CP0_REG00__VPCONTROL: 8258 CP0_CHECK(ctx->vp); 8259 /* ignored */ 8260 register_name = "VPControl"; 8261 break; 8262 default: 8263 goto cp0_unimplemented; 8264 } 8265 break; 8266 case CP0_REGISTER_01: 8267 switch (sel) { 8268 case CP0_REG01__RANDOM: 8269 /* ignored */ 8270 register_name = "Random"; 8271 break; 8272 case CP0_REG01__VPECONTROL: 8273 CP0_CHECK(ctx->insn_flags & ASE_MT); 8274 gen_helper_mtc0_vpecontrol(cpu_env, arg); 8275 register_name = "VPEControl"; 8276 break; 8277 case CP0_REG01__VPECONF0: 8278 CP0_CHECK(ctx->insn_flags & ASE_MT); 8279 gen_helper_mtc0_vpeconf0(cpu_env, arg); 8280 register_name = "VPEConf0"; 8281 break; 8282 case CP0_REG01__VPECONF1: 8283 CP0_CHECK(ctx->insn_flags & ASE_MT); 8284 gen_helper_mtc0_vpeconf1(cpu_env, arg); 8285 register_name = "VPEConf1"; 8286 break; 8287 case CP0_REG01__YQMASK: 8288 CP0_CHECK(ctx->insn_flags & ASE_MT); 8289 gen_helper_mtc0_yqmask(cpu_env, arg); 8290 register_name = "YQMask"; 8291 break; 8292 case CP0_REG01__VPESCHEDULE: 8293 CP0_CHECK(ctx->insn_flags & ASE_MT); 8294 tcg_gen_st_tl(arg, cpu_env, 8295 offsetof(CPUMIPSState, CP0_VPESchedule)); 8296 register_name = "VPESchedule"; 8297 break; 8298 case CP0_REG01__VPESCHEFBACK: 8299 CP0_CHECK(ctx->insn_flags & ASE_MT); 8300 tcg_gen_st_tl(arg, cpu_env, 8301 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 8302 register_name = "VPEScheFBack"; 8303 break; 8304 case CP0_REG01__VPEOPT: 8305 CP0_CHECK(ctx->insn_flags & ASE_MT); 8306 gen_helper_mtc0_vpeopt(cpu_env, arg); 8307 register_name = "VPEOpt"; 8308 break; 8309 default: 8310 goto cp0_unimplemented; 8311 } 8312 break; 8313 case CP0_REGISTER_02: 8314 switch (sel) { 8315 case CP0_REG02__ENTRYLO0: 8316 gen_helper_dmtc0_entrylo0(cpu_env, arg); 8317 register_name = "EntryLo0"; 8318 break; 8319 case CP0_REG02__TCSTATUS: 8320 CP0_CHECK(ctx->insn_flags & ASE_MT); 8321 gen_helper_mtc0_tcstatus(cpu_env, arg); 8322 register_name = "TCStatus"; 8323 break; 8324 case CP0_REG02__TCBIND: 8325 CP0_CHECK(ctx->insn_flags & ASE_MT); 8326 gen_helper_mtc0_tcbind(cpu_env, arg); 8327 register_name = "TCBind"; 8328 break; 8329 case CP0_REG02__TCRESTART: 8330 CP0_CHECK(ctx->insn_flags & ASE_MT); 8331 gen_helper_mtc0_tcrestart(cpu_env, arg); 8332 register_name = "TCRestart"; 8333 break; 8334 case CP0_REG02__TCHALT: 8335 CP0_CHECK(ctx->insn_flags & ASE_MT); 8336 gen_helper_mtc0_tchalt(cpu_env, arg); 8337 register_name = "TCHalt"; 8338 break; 8339 case CP0_REG02__TCCONTEXT: 8340 CP0_CHECK(ctx->insn_flags & ASE_MT); 8341 gen_helper_mtc0_tccontext(cpu_env, arg); 8342 register_name = "TCContext"; 8343 break; 8344 case CP0_REG02__TCSCHEDULE: 8345 CP0_CHECK(ctx->insn_flags & ASE_MT); 8346 gen_helper_mtc0_tcschedule(cpu_env, arg); 8347 register_name = "TCSchedule"; 8348 break; 8349 case CP0_REG02__TCSCHEFBACK: 8350 CP0_CHECK(ctx->insn_flags & ASE_MT); 8351 gen_helper_mtc0_tcschefback(cpu_env, arg); 8352 register_name = "TCScheFBack"; 8353 break; 8354 default: 8355 goto cp0_unimplemented; 8356 } 8357 break; 8358 case CP0_REGISTER_03: 8359 switch (sel) { 8360 case CP0_REG03__ENTRYLO1: 8361 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8362 register_name = "EntryLo1"; 8363 break; 8364 case CP0_REG03__GLOBALNUM: 8365 CP0_CHECK(ctx->vp); 8366 /* ignored */ 8367 register_name = "GlobalNumber"; 8368 break; 8369 default: 8370 goto cp0_unimplemented; 8371 } 8372 break; 8373 case CP0_REGISTER_04: 8374 switch (sel) { 8375 case CP0_REG04__CONTEXT: 8376 gen_helper_mtc0_context(cpu_env, arg); 8377 register_name = "Context"; 8378 break; 8379 case CP0_REG04__CONTEXTCONFIG: 8380 /* SmartMIPS ASE */ 8381 /* gen_helper_dmtc0_contextconfig(arg); */ 8382 register_name = "ContextConfig"; 8383 goto cp0_unimplemented; 8384 case CP0_REG04__USERLOCAL: 8385 CP0_CHECK(ctx->ulri); 8386 tcg_gen_st_tl(arg, cpu_env, 8387 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8388 register_name = "UserLocal"; 8389 break; 8390 case CP0_REG04__MMID: 8391 CP0_CHECK(ctx->mi); 8392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8393 register_name = "MMID"; 8394 break; 8395 default: 8396 goto cp0_unimplemented; 8397 } 8398 break; 8399 case CP0_REGISTER_05: 8400 switch (sel) { 8401 case CP0_REG05__PAGEMASK: 8402 gen_helper_mtc0_pagemask(cpu_env, arg); 8403 register_name = "PageMask"; 8404 break; 8405 case CP0_REG05__PAGEGRAIN: 8406 check_insn(ctx, ISA_MIPS_R2); 8407 gen_helper_mtc0_pagegrain(cpu_env, arg); 8408 register_name = "PageGrain"; 8409 break; 8410 case CP0_REG05__SEGCTL0: 8411 CP0_CHECK(ctx->sc); 8412 gen_helper_mtc0_segctl0(cpu_env, arg); 8413 register_name = "SegCtl0"; 8414 break; 8415 case CP0_REG05__SEGCTL1: 8416 CP0_CHECK(ctx->sc); 8417 gen_helper_mtc0_segctl1(cpu_env, arg); 8418 register_name = "SegCtl1"; 8419 break; 8420 case CP0_REG05__SEGCTL2: 8421 CP0_CHECK(ctx->sc); 8422 gen_helper_mtc0_segctl2(cpu_env, arg); 8423 register_name = "SegCtl2"; 8424 break; 8425 case CP0_REG05__PWBASE: 8426 check_pw(ctx); 8427 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8428 register_name = "PWBase"; 8429 break; 8430 case CP0_REG05__PWFIELD: 8431 check_pw(ctx); 8432 gen_helper_mtc0_pwfield(cpu_env, arg); 8433 register_name = "PWField"; 8434 break; 8435 case CP0_REG05__PWSIZE: 8436 check_pw(ctx); 8437 gen_helper_mtc0_pwsize(cpu_env, arg); 8438 register_name = "PWSize"; 8439 break; 8440 default: 8441 goto cp0_unimplemented; 8442 } 8443 break; 8444 case CP0_REGISTER_06: 8445 switch (sel) { 8446 case CP0_REG06__WIRED: 8447 gen_helper_mtc0_wired(cpu_env, arg); 8448 register_name = "Wired"; 8449 break; 8450 case CP0_REG06__SRSCONF0: 8451 check_insn(ctx, ISA_MIPS_R2); 8452 gen_helper_mtc0_srsconf0(cpu_env, arg); 8453 register_name = "SRSConf0"; 8454 break; 8455 case CP0_REG06__SRSCONF1: 8456 check_insn(ctx, ISA_MIPS_R2); 8457 gen_helper_mtc0_srsconf1(cpu_env, arg); 8458 register_name = "SRSConf1"; 8459 break; 8460 case CP0_REG06__SRSCONF2: 8461 check_insn(ctx, ISA_MIPS_R2); 8462 gen_helper_mtc0_srsconf2(cpu_env, arg); 8463 register_name = "SRSConf2"; 8464 break; 8465 case CP0_REG06__SRSCONF3: 8466 check_insn(ctx, ISA_MIPS_R2); 8467 gen_helper_mtc0_srsconf3(cpu_env, arg); 8468 register_name = "SRSConf3"; 8469 break; 8470 case CP0_REG06__SRSCONF4: 8471 check_insn(ctx, ISA_MIPS_R2); 8472 gen_helper_mtc0_srsconf4(cpu_env, arg); 8473 register_name = "SRSConf4"; 8474 break; 8475 case CP0_REG06__PWCTL: 8476 check_pw(ctx); 8477 gen_helper_mtc0_pwctl(cpu_env, arg); 8478 register_name = "PWCtl"; 8479 break; 8480 default: 8481 goto cp0_unimplemented; 8482 } 8483 break; 8484 case CP0_REGISTER_07: 8485 switch (sel) { 8486 case CP0_REG07__HWRENA: 8487 check_insn(ctx, ISA_MIPS_R2); 8488 gen_helper_mtc0_hwrena(cpu_env, arg); 8489 ctx->base.is_jmp = DISAS_STOP; 8490 register_name = "HWREna"; 8491 break; 8492 default: 8493 goto cp0_unimplemented; 8494 } 8495 break; 8496 case CP0_REGISTER_08: 8497 switch (sel) { 8498 case CP0_REG08__BADVADDR: 8499 /* ignored */ 8500 register_name = "BadVAddr"; 8501 break; 8502 case CP0_REG08__BADINSTR: 8503 /* ignored */ 8504 register_name = "BadInstr"; 8505 break; 8506 case CP0_REG08__BADINSTRP: 8507 /* ignored */ 8508 register_name = "BadInstrP"; 8509 break; 8510 case CP0_REG08__BADINSTRX: 8511 /* ignored */ 8512 register_name = "BadInstrX"; 8513 break; 8514 default: 8515 goto cp0_unimplemented; 8516 } 8517 break; 8518 case CP0_REGISTER_09: 8519 switch (sel) { 8520 case CP0_REG09__COUNT: 8521 gen_helper_mtc0_count(cpu_env, arg); 8522 register_name = "Count"; 8523 break; 8524 case CP0_REG09__SAARI: 8525 CP0_CHECK(ctx->saar); 8526 gen_helper_mtc0_saari(cpu_env, arg); 8527 register_name = "SAARI"; 8528 break; 8529 case CP0_REG09__SAAR: 8530 CP0_CHECK(ctx->saar); 8531 gen_helper_mtc0_saar(cpu_env, arg); 8532 register_name = "SAAR"; 8533 break; 8534 default: 8535 goto cp0_unimplemented; 8536 } 8537 /* Stop translation as we may have switched the execution mode */ 8538 ctx->base.is_jmp = DISAS_STOP; 8539 break; 8540 case CP0_REGISTER_10: 8541 switch (sel) { 8542 case CP0_REG10__ENTRYHI: 8543 gen_helper_mtc0_entryhi(cpu_env, arg); 8544 register_name = "EntryHi"; 8545 break; 8546 default: 8547 goto cp0_unimplemented; 8548 } 8549 break; 8550 case CP0_REGISTER_11: 8551 switch (sel) { 8552 case CP0_REG11__COMPARE: 8553 gen_helper_mtc0_compare(cpu_env, arg); 8554 register_name = "Compare"; 8555 break; 8556 /* 6,7 are implementation dependent */ 8557 default: 8558 goto cp0_unimplemented; 8559 } 8560 /* Stop translation as we may have switched the execution mode */ 8561 ctx->base.is_jmp = DISAS_STOP; 8562 break; 8563 case CP0_REGISTER_12: 8564 switch (sel) { 8565 case CP0_REG12__STATUS: 8566 save_cpu_state(ctx, 1); 8567 gen_helper_mtc0_status(cpu_env, arg); 8568 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8569 gen_save_pc(ctx->base.pc_next + 4); 8570 ctx->base.is_jmp = DISAS_EXIT; 8571 register_name = "Status"; 8572 break; 8573 case CP0_REG12__INTCTL: 8574 check_insn(ctx, ISA_MIPS_R2); 8575 gen_helper_mtc0_intctl(cpu_env, arg); 8576 /* Stop translation as we may have switched the execution mode */ 8577 ctx->base.is_jmp = DISAS_STOP; 8578 register_name = "IntCtl"; 8579 break; 8580 case CP0_REG12__SRSCTL: 8581 check_insn(ctx, ISA_MIPS_R2); 8582 gen_helper_mtc0_srsctl(cpu_env, arg); 8583 /* Stop translation as we may have switched the execution mode */ 8584 ctx->base.is_jmp = DISAS_STOP; 8585 register_name = "SRSCtl"; 8586 break; 8587 case CP0_REG12__SRSMAP: 8588 check_insn(ctx, ISA_MIPS_R2); 8589 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8590 /* Stop translation as we may have switched the execution mode */ 8591 ctx->base.is_jmp = DISAS_STOP; 8592 register_name = "SRSMap"; 8593 break; 8594 default: 8595 goto cp0_unimplemented; 8596 } 8597 break; 8598 case CP0_REGISTER_13: 8599 switch (sel) { 8600 case CP0_REG13__CAUSE: 8601 save_cpu_state(ctx, 1); 8602 gen_helper_mtc0_cause(cpu_env, arg); 8603 /* 8604 * Stop translation as we may have triggered an interrupt. 8605 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8606 * translated code to check for pending interrupts. 8607 */ 8608 gen_save_pc(ctx->base.pc_next + 4); 8609 ctx->base.is_jmp = DISAS_EXIT; 8610 register_name = "Cause"; 8611 break; 8612 default: 8613 goto cp0_unimplemented; 8614 } 8615 break; 8616 case CP0_REGISTER_14: 8617 switch (sel) { 8618 case CP0_REG14__EPC: 8619 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8620 register_name = "EPC"; 8621 break; 8622 default: 8623 goto cp0_unimplemented; 8624 } 8625 break; 8626 case CP0_REGISTER_15: 8627 switch (sel) { 8628 case CP0_REG15__PRID: 8629 /* ignored */ 8630 register_name = "PRid"; 8631 break; 8632 case CP0_REG15__EBASE: 8633 check_insn(ctx, ISA_MIPS_R2); 8634 gen_helper_mtc0_ebase(cpu_env, arg); 8635 register_name = "EBase"; 8636 break; 8637 default: 8638 goto cp0_unimplemented; 8639 } 8640 break; 8641 case CP0_REGISTER_16: 8642 switch (sel) { 8643 case CP0_REG16__CONFIG: 8644 gen_helper_mtc0_config0(cpu_env, arg); 8645 register_name = "Config"; 8646 /* Stop translation as we may have switched the execution mode */ 8647 ctx->base.is_jmp = DISAS_STOP; 8648 break; 8649 case CP0_REG16__CONFIG1: 8650 /* ignored, read only */ 8651 register_name = "Config1"; 8652 break; 8653 case CP0_REG16__CONFIG2: 8654 gen_helper_mtc0_config2(cpu_env, arg); 8655 register_name = "Config2"; 8656 /* Stop translation as we may have switched the execution mode */ 8657 ctx->base.is_jmp = DISAS_STOP; 8658 break; 8659 case CP0_REG16__CONFIG3: 8660 gen_helper_mtc0_config3(cpu_env, arg); 8661 register_name = "Config3"; 8662 /* Stop translation as we may have switched the execution mode */ 8663 ctx->base.is_jmp = DISAS_STOP; 8664 break; 8665 case CP0_REG16__CONFIG4: 8666 /* currently ignored */ 8667 register_name = "Config4"; 8668 break; 8669 case CP0_REG16__CONFIG5: 8670 gen_helper_mtc0_config5(cpu_env, arg); 8671 register_name = "Config5"; 8672 /* Stop translation as we may have switched the execution mode */ 8673 ctx->base.is_jmp = DISAS_STOP; 8674 break; 8675 /* 6,7 are implementation dependent */ 8676 default: 8677 register_name = "Invalid config selector"; 8678 goto cp0_unimplemented; 8679 } 8680 break; 8681 case CP0_REGISTER_17: 8682 switch (sel) { 8683 case CP0_REG17__LLADDR: 8684 gen_helper_mtc0_lladdr(cpu_env, arg); 8685 register_name = "LLAddr"; 8686 break; 8687 case CP0_REG17__MAAR: 8688 CP0_CHECK(ctx->mrp); 8689 gen_helper_mtc0_maar(cpu_env, arg); 8690 register_name = "MAAR"; 8691 break; 8692 case CP0_REG17__MAARI: 8693 CP0_CHECK(ctx->mrp); 8694 gen_helper_mtc0_maari(cpu_env, arg); 8695 register_name = "MAARI"; 8696 break; 8697 default: 8698 goto cp0_unimplemented; 8699 } 8700 break; 8701 case CP0_REGISTER_18: 8702 switch (sel) { 8703 case CP0_REG18__WATCHLO0: 8704 case CP0_REG18__WATCHLO1: 8705 case CP0_REG18__WATCHLO2: 8706 case CP0_REG18__WATCHLO3: 8707 case CP0_REG18__WATCHLO4: 8708 case CP0_REG18__WATCHLO5: 8709 case CP0_REG18__WATCHLO6: 8710 case CP0_REG18__WATCHLO7: 8711 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8712 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8713 register_name = "WatchLo"; 8714 break; 8715 default: 8716 goto cp0_unimplemented; 8717 } 8718 break; 8719 case CP0_REGISTER_19: 8720 switch (sel) { 8721 case CP0_REG19__WATCHHI0: 8722 case CP0_REG19__WATCHHI1: 8723 case CP0_REG19__WATCHHI2: 8724 case CP0_REG19__WATCHHI3: 8725 case CP0_REG19__WATCHHI4: 8726 case CP0_REG19__WATCHHI5: 8727 case CP0_REG19__WATCHHI6: 8728 case CP0_REG19__WATCHHI7: 8729 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8730 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8731 register_name = "WatchHi"; 8732 break; 8733 default: 8734 goto cp0_unimplemented; 8735 } 8736 break; 8737 case CP0_REGISTER_20: 8738 switch (sel) { 8739 case CP0_REG20__XCONTEXT: 8740 check_insn(ctx, ISA_MIPS3); 8741 gen_helper_mtc0_xcontext(cpu_env, arg); 8742 register_name = "XContext"; 8743 break; 8744 default: 8745 goto cp0_unimplemented; 8746 } 8747 break; 8748 case CP0_REGISTER_21: 8749 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8750 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8751 switch (sel) { 8752 case 0: 8753 gen_helper_mtc0_framemask(cpu_env, arg); 8754 register_name = "Framemask"; 8755 break; 8756 default: 8757 goto cp0_unimplemented; 8758 } 8759 break; 8760 case CP0_REGISTER_22: 8761 /* ignored */ 8762 register_name = "Diagnostic"; /* implementation dependent */ 8763 break; 8764 case CP0_REGISTER_23: 8765 switch (sel) { 8766 case CP0_REG23__DEBUG: 8767 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8768 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8769 gen_save_pc(ctx->base.pc_next + 4); 8770 ctx->base.is_jmp = DISAS_EXIT; 8771 register_name = "Debug"; 8772 break; 8773 case CP0_REG23__TRACECONTROL: 8774 /* PDtrace support */ 8775 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8776 /* Stop translation as we may have switched the execution mode */ 8777 ctx->base.is_jmp = DISAS_STOP; 8778 register_name = "TraceControl"; 8779 goto cp0_unimplemented; 8780 case CP0_REG23__TRACECONTROL2: 8781 /* PDtrace support */ 8782 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8783 /* Stop translation as we may have switched the execution mode */ 8784 ctx->base.is_jmp = DISAS_STOP; 8785 register_name = "TraceControl2"; 8786 goto cp0_unimplemented; 8787 case CP0_REG23__USERTRACEDATA1: 8788 /* PDtrace support */ 8789 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8790 /* Stop translation as we may have switched the execution mode */ 8791 ctx->base.is_jmp = DISAS_STOP; 8792 register_name = "UserTraceData1"; 8793 goto cp0_unimplemented; 8794 case CP0_REG23__TRACEIBPC: 8795 /* PDtrace support */ 8796 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8797 /* Stop translation as we may have switched the execution mode */ 8798 ctx->base.is_jmp = DISAS_STOP; 8799 register_name = "TraceIBPC"; 8800 goto cp0_unimplemented; 8801 case CP0_REG23__TRACEDBPC: 8802 /* PDtrace support */ 8803 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8804 /* Stop translation as we may have switched the execution mode */ 8805 ctx->base.is_jmp = DISAS_STOP; 8806 register_name = "TraceDBPC"; 8807 goto cp0_unimplemented; 8808 default: 8809 goto cp0_unimplemented; 8810 } 8811 break; 8812 case CP0_REGISTER_24: 8813 switch (sel) { 8814 case CP0_REG24__DEPC: 8815 /* EJTAG support */ 8816 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8817 register_name = "DEPC"; 8818 break; 8819 default: 8820 goto cp0_unimplemented; 8821 } 8822 break; 8823 case CP0_REGISTER_25: 8824 switch (sel) { 8825 case CP0_REG25__PERFCTL0: 8826 gen_helper_mtc0_performance0(cpu_env, arg); 8827 register_name = "Performance0"; 8828 break; 8829 case CP0_REG25__PERFCNT0: 8830 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8831 register_name = "Performance1"; 8832 goto cp0_unimplemented; 8833 case CP0_REG25__PERFCTL1: 8834 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8835 register_name = "Performance2"; 8836 goto cp0_unimplemented; 8837 case CP0_REG25__PERFCNT1: 8838 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8839 register_name = "Performance3"; 8840 goto cp0_unimplemented; 8841 case CP0_REG25__PERFCTL2: 8842 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8843 register_name = "Performance4"; 8844 goto cp0_unimplemented; 8845 case CP0_REG25__PERFCNT2: 8846 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8847 register_name = "Performance5"; 8848 goto cp0_unimplemented; 8849 case CP0_REG25__PERFCTL3: 8850 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8851 register_name = "Performance6"; 8852 goto cp0_unimplemented; 8853 case CP0_REG25__PERFCNT3: 8854 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8855 register_name = "Performance7"; 8856 goto cp0_unimplemented; 8857 default: 8858 goto cp0_unimplemented; 8859 } 8860 break; 8861 case CP0_REGISTER_26: 8862 switch (sel) { 8863 case CP0_REG26__ERRCTL: 8864 gen_helper_mtc0_errctl(cpu_env, arg); 8865 ctx->base.is_jmp = DISAS_STOP; 8866 register_name = "ErrCtl"; 8867 break; 8868 default: 8869 goto cp0_unimplemented; 8870 } 8871 break; 8872 case CP0_REGISTER_27: 8873 switch (sel) { 8874 case CP0_REG27__CACHERR: 8875 /* ignored */ 8876 register_name = "CacheErr"; 8877 break; 8878 default: 8879 goto cp0_unimplemented; 8880 } 8881 break; 8882 case CP0_REGISTER_28: 8883 switch (sel) { 8884 case CP0_REG28__TAGLO: 8885 case CP0_REG28__TAGLO1: 8886 case CP0_REG28__TAGLO2: 8887 case CP0_REG28__TAGLO3: 8888 gen_helper_mtc0_taglo(cpu_env, arg); 8889 register_name = "TagLo"; 8890 break; 8891 case CP0_REG28__DATALO: 8892 case CP0_REG28__DATALO1: 8893 case CP0_REG28__DATALO2: 8894 case CP0_REG28__DATALO3: 8895 gen_helper_mtc0_datalo(cpu_env, arg); 8896 register_name = "DataLo"; 8897 break; 8898 default: 8899 goto cp0_unimplemented; 8900 } 8901 break; 8902 case CP0_REGISTER_29: 8903 switch (sel) { 8904 case CP0_REG29__TAGHI: 8905 case CP0_REG29__TAGHI1: 8906 case CP0_REG29__TAGHI2: 8907 case CP0_REG29__TAGHI3: 8908 gen_helper_mtc0_taghi(cpu_env, arg); 8909 register_name = "TagHi"; 8910 break; 8911 case CP0_REG29__DATAHI: 8912 case CP0_REG29__DATAHI1: 8913 case CP0_REG29__DATAHI2: 8914 case CP0_REG29__DATAHI3: 8915 gen_helper_mtc0_datahi(cpu_env, arg); 8916 register_name = "DataHi"; 8917 break; 8918 default: 8919 register_name = "invalid sel"; 8920 goto cp0_unimplemented; 8921 } 8922 break; 8923 case CP0_REGISTER_30: 8924 switch (sel) { 8925 case CP0_REG30__ERROREPC: 8926 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8927 register_name = "ErrorEPC"; 8928 break; 8929 default: 8930 goto cp0_unimplemented; 8931 } 8932 break; 8933 case CP0_REGISTER_31: 8934 switch (sel) { 8935 case CP0_REG31__DESAVE: 8936 /* EJTAG support */ 8937 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8938 register_name = "DESAVE"; 8939 break; 8940 case CP0_REG31__KSCRATCH1: 8941 case CP0_REG31__KSCRATCH2: 8942 case CP0_REG31__KSCRATCH3: 8943 case CP0_REG31__KSCRATCH4: 8944 case CP0_REG31__KSCRATCH5: 8945 case CP0_REG31__KSCRATCH6: 8946 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8947 tcg_gen_st_tl(arg, cpu_env, 8948 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8949 register_name = "KScratch"; 8950 break; 8951 default: 8952 goto cp0_unimplemented; 8953 } 8954 break; 8955 default: 8956 goto cp0_unimplemented; 8957 } 8958 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8959 8960 /* For simplicity assume that all writes can cause interrupts. */ 8961 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8962 /* 8963 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8964 * translated code to check for pending interrupts. 8965 */ 8966 gen_save_pc(ctx->base.pc_next + 4); 8967 ctx->base.is_jmp = DISAS_EXIT; 8968 } 8969 return; 8970 8971 cp0_unimplemented: 8972 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8973 register_name, reg, sel); 8974 } 8975 #endif /* TARGET_MIPS64 */ 8976 8977 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8978 int u, int sel, int h) 8979 { 8980 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8981 TCGv t0 = tcg_temp_local_new(); 8982 8983 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8984 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8985 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8986 tcg_gen_movi_tl(t0, -1); 8987 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8988 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8989 tcg_gen_movi_tl(t0, -1); 8990 } else if (u == 0) { 8991 switch (rt) { 8992 case 1: 8993 switch (sel) { 8994 case 1: 8995 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8996 break; 8997 case 2: 8998 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8999 break; 9000 default: 9001 goto die; 9002 break; 9003 } 9004 break; 9005 case 2: 9006 switch (sel) { 9007 case 1: 9008 gen_helper_mftc0_tcstatus(t0, cpu_env); 9009 break; 9010 case 2: 9011 gen_helper_mftc0_tcbind(t0, cpu_env); 9012 break; 9013 case 3: 9014 gen_helper_mftc0_tcrestart(t0, cpu_env); 9015 break; 9016 case 4: 9017 gen_helper_mftc0_tchalt(t0, cpu_env); 9018 break; 9019 case 5: 9020 gen_helper_mftc0_tccontext(t0, cpu_env); 9021 break; 9022 case 6: 9023 gen_helper_mftc0_tcschedule(t0, cpu_env); 9024 break; 9025 case 7: 9026 gen_helper_mftc0_tcschefback(t0, cpu_env); 9027 break; 9028 default: 9029 gen_mfc0(ctx, t0, rt, sel); 9030 break; 9031 } 9032 break; 9033 case 10: 9034 switch (sel) { 9035 case 0: 9036 gen_helper_mftc0_entryhi(t0, cpu_env); 9037 break; 9038 default: 9039 gen_mfc0(ctx, t0, rt, sel); 9040 break; 9041 } 9042 break; 9043 case 12: 9044 switch (sel) { 9045 case 0: 9046 gen_helper_mftc0_status(t0, cpu_env); 9047 break; 9048 default: 9049 gen_mfc0(ctx, t0, rt, sel); 9050 break; 9051 } 9052 break; 9053 case 13: 9054 switch (sel) { 9055 case 0: 9056 gen_helper_mftc0_cause(t0, cpu_env); 9057 break; 9058 default: 9059 goto die; 9060 break; 9061 } 9062 break; 9063 case 14: 9064 switch (sel) { 9065 case 0: 9066 gen_helper_mftc0_epc(t0, cpu_env); 9067 break; 9068 default: 9069 goto die; 9070 break; 9071 } 9072 break; 9073 case 15: 9074 switch (sel) { 9075 case 1: 9076 gen_helper_mftc0_ebase(t0, cpu_env); 9077 break; 9078 default: 9079 goto die; 9080 break; 9081 } 9082 break; 9083 case 16: 9084 switch (sel) { 9085 case 0: 9086 case 1: 9087 case 2: 9088 case 3: 9089 case 4: 9090 case 5: 9091 case 6: 9092 case 7: 9093 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 9094 break; 9095 default: 9096 goto die; 9097 break; 9098 } 9099 break; 9100 case 23: 9101 switch (sel) { 9102 case 0: 9103 gen_helper_mftc0_debug(t0, cpu_env); 9104 break; 9105 default: 9106 gen_mfc0(ctx, t0, rt, sel); 9107 break; 9108 } 9109 break; 9110 default: 9111 gen_mfc0(ctx, t0, rt, sel); 9112 } 9113 } else { 9114 switch (sel) { 9115 /* GPR registers. */ 9116 case 0: 9117 gen_helper_1e0i(mftgpr, t0, rt); 9118 break; 9119 /* Auxiliary CPU registers */ 9120 case 1: 9121 switch (rt) { 9122 case 0: 9123 gen_helper_1e0i(mftlo, t0, 0); 9124 break; 9125 case 1: 9126 gen_helper_1e0i(mfthi, t0, 0); 9127 break; 9128 case 2: 9129 gen_helper_1e0i(mftacx, t0, 0); 9130 break; 9131 case 4: 9132 gen_helper_1e0i(mftlo, t0, 1); 9133 break; 9134 case 5: 9135 gen_helper_1e0i(mfthi, t0, 1); 9136 break; 9137 case 6: 9138 gen_helper_1e0i(mftacx, t0, 1); 9139 break; 9140 case 8: 9141 gen_helper_1e0i(mftlo, t0, 2); 9142 break; 9143 case 9: 9144 gen_helper_1e0i(mfthi, t0, 2); 9145 break; 9146 case 10: 9147 gen_helper_1e0i(mftacx, t0, 2); 9148 break; 9149 case 12: 9150 gen_helper_1e0i(mftlo, t0, 3); 9151 break; 9152 case 13: 9153 gen_helper_1e0i(mfthi, t0, 3); 9154 break; 9155 case 14: 9156 gen_helper_1e0i(mftacx, t0, 3); 9157 break; 9158 case 16: 9159 gen_helper_mftdsp(t0, cpu_env); 9160 break; 9161 default: 9162 goto die; 9163 } 9164 break; 9165 /* Floating point (COP1). */ 9166 case 2: 9167 /* XXX: For now we support only a single FPU context. */ 9168 if (h == 0) { 9169 TCGv_i32 fp0 = tcg_temp_new_i32(); 9170 9171 gen_load_fpr32(ctx, fp0, rt); 9172 tcg_gen_ext_i32_tl(t0, fp0); 9173 tcg_temp_free_i32(fp0); 9174 } else { 9175 TCGv_i32 fp0 = tcg_temp_new_i32(); 9176 9177 gen_load_fpr32h(ctx, fp0, rt); 9178 tcg_gen_ext_i32_tl(t0, fp0); 9179 tcg_temp_free_i32(fp0); 9180 } 9181 break; 9182 case 3: 9183 /* XXX: For now we support only a single FPU context. */ 9184 gen_helper_1e0i(cfc1, t0, rt); 9185 break; 9186 /* COP2: Not implemented. */ 9187 case 4: 9188 case 5: 9189 /* fall through */ 9190 default: 9191 goto die; 9192 } 9193 } 9194 trace_mips_translate_tr("mftr", rt, u, sel, h); 9195 gen_store_gpr(t0, rd); 9196 tcg_temp_free(t0); 9197 return; 9198 9199 die: 9200 tcg_temp_free(t0); 9201 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 9202 gen_reserved_instruction(ctx); 9203 } 9204 9205 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 9206 int u, int sel, int h) 9207 { 9208 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 9209 TCGv t0 = tcg_temp_local_new(); 9210 9211 gen_load_gpr(t0, rt); 9212 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 9213 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 9214 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 9215 /* NOP */ 9216 ; 9217 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 9218 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 9219 /* NOP */ 9220 ; 9221 } else if (u == 0) { 9222 switch (rd) { 9223 case 1: 9224 switch (sel) { 9225 case 1: 9226 gen_helper_mttc0_vpecontrol(cpu_env, t0); 9227 break; 9228 case 2: 9229 gen_helper_mttc0_vpeconf0(cpu_env, t0); 9230 break; 9231 default: 9232 goto die; 9233 break; 9234 } 9235 break; 9236 case 2: 9237 switch (sel) { 9238 case 1: 9239 gen_helper_mttc0_tcstatus(cpu_env, t0); 9240 break; 9241 case 2: 9242 gen_helper_mttc0_tcbind(cpu_env, t0); 9243 break; 9244 case 3: 9245 gen_helper_mttc0_tcrestart(cpu_env, t0); 9246 break; 9247 case 4: 9248 gen_helper_mttc0_tchalt(cpu_env, t0); 9249 break; 9250 case 5: 9251 gen_helper_mttc0_tccontext(cpu_env, t0); 9252 break; 9253 case 6: 9254 gen_helper_mttc0_tcschedule(cpu_env, t0); 9255 break; 9256 case 7: 9257 gen_helper_mttc0_tcschefback(cpu_env, t0); 9258 break; 9259 default: 9260 gen_mtc0(ctx, t0, rd, sel); 9261 break; 9262 } 9263 break; 9264 case 10: 9265 switch (sel) { 9266 case 0: 9267 gen_helper_mttc0_entryhi(cpu_env, t0); 9268 break; 9269 default: 9270 gen_mtc0(ctx, t0, rd, sel); 9271 break; 9272 } 9273 break; 9274 case 12: 9275 switch (sel) { 9276 case 0: 9277 gen_helper_mttc0_status(cpu_env, t0); 9278 break; 9279 default: 9280 gen_mtc0(ctx, t0, rd, sel); 9281 break; 9282 } 9283 break; 9284 case 13: 9285 switch (sel) { 9286 case 0: 9287 gen_helper_mttc0_cause(cpu_env, t0); 9288 break; 9289 default: 9290 goto die; 9291 break; 9292 } 9293 break; 9294 case 15: 9295 switch (sel) { 9296 case 1: 9297 gen_helper_mttc0_ebase(cpu_env, t0); 9298 break; 9299 default: 9300 goto die; 9301 break; 9302 } 9303 break; 9304 case 23: 9305 switch (sel) { 9306 case 0: 9307 gen_helper_mttc0_debug(cpu_env, t0); 9308 break; 9309 default: 9310 gen_mtc0(ctx, t0, rd, sel); 9311 break; 9312 } 9313 break; 9314 default: 9315 gen_mtc0(ctx, t0, rd, sel); 9316 } 9317 } else { 9318 switch (sel) { 9319 /* GPR registers. */ 9320 case 0: 9321 gen_helper_0e1i(mttgpr, t0, rd); 9322 break; 9323 /* Auxiliary CPU registers */ 9324 case 1: 9325 switch (rd) { 9326 case 0: 9327 gen_helper_0e1i(mttlo, t0, 0); 9328 break; 9329 case 1: 9330 gen_helper_0e1i(mtthi, t0, 0); 9331 break; 9332 case 2: 9333 gen_helper_0e1i(mttacx, t0, 0); 9334 break; 9335 case 4: 9336 gen_helper_0e1i(mttlo, t0, 1); 9337 break; 9338 case 5: 9339 gen_helper_0e1i(mtthi, t0, 1); 9340 break; 9341 case 6: 9342 gen_helper_0e1i(mttacx, t0, 1); 9343 break; 9344 case 8: 9345 gen_helper_0e1i(mttlo, t0, 2); 9346 break; 9347 case 9: 9348 gen_helper_0e1i(mtthi, t0, 2); 9349 break; 9350 case 10: 9351 gen_helper_0e1i(mttacx, t0, 2); 9352 break; 9353 case 12: 9354 gen_helper_0e1i(mttlo, t0, 3); 9355 break; 9356 case 13: 9357 gen_helper_0e1i(mtthi, t0, 3); 9358 break; 9359 case 14: 9360 gen_helper_0e1i(mttacx, t0, 3); 9361 break; 9362 case 16: 9363 gen_helper_mttdsp(cpu_env, t0); 9364 break; 9365 default: 9366 goto die; 9367 } 9368 break; 9369 /* Floating point (COP1). */ 9370 case 2: 9371 /* XXX: For now we support only a single FPU context. */ 9372 if (h == 0) { 9373 TCGv_i32 fp0 = tcg_temp_new_i32(); 9374 9375 tcg_gen_trunc_tl_i32(fp0, t0); 9376 gen_store_fpr32(ctx, fp0, rd); 9377 tcg_temp_free_i32(fp0); 9378 } else { 9379 TCGv_i32 fp0 = tcg_temp_new_i32(); 9380 9381 tcg_gen_trunc_tl_i32(fp0, t0); 9382 gen_store_fpr32h(ctx, fp0, rd); 9383 tcg_temp_free_i32(fp0); 9384 } 9385 break; 9386 case 3: 9387 /* XXX: For now we support only a single FPU context. */ 9388 { 9389 TCGv_i32 fs_tmp = tcg_const_i32(rd); 9390 9391 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9392 tcg_temp_free_i32(fs_tmp); 9393 } 9394 /* Stop translation as we may have changed hflags */ 9395 ctx->base.is_jmp = DISAS_STOP; 9396 break; 9397 /* COP2: Not implemented. */ 9398 case 4: 9399 case 5: 9400 /* fall through */ 9401 default: 9402 goto die; 9403 } 9404 } 9405 trace_mips_translate_tr("mttr", rd, u, sel, h); 9406 tcg_temp_free(t0); 9407 return; 9408 9409 die: 9410 tcg_temp_free(t0); 9411 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9412 gen_reserved_instruction(ctx); 9413 } 9414 9415 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9416 int rt, int rd) 9417 { 9418 const char *opn = "ldst"; 9419 9420 check_cp0_enabled(ctx); 9421 switch (opc) { 9422 case OPC_MFC0: 9423 if (rt == 0) { 9424 /* Treat as NOP. */ 9425 return; 9426 } 9427 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9428 opn = "mfc0"; 9429 break; 9430 case OPC_MTC0: 9431 { 9432 TCGv t0 = tcg_temp_new(); 9433 9434 gen_load_gpr(t0, rt); 9435 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9436 tcg_temp_free(t0); 9437 } 9438 opn = "mtc0"; 9439 break; 9440 #if defined(TARGET_MIPS64) 9441 case OPC_DMFC0: 9442 check_insn(ctx, ISA_MIPS3); 9443 if (rt == 0) { 9444 /* Treat as NOP. */ 9445 return; 9446 } 9447 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9448 opn = "dmfc0"; 9449 break; 9450 case OPC_DMTC0: 9451 check_insn(ctx, ISA_MIPS3); 9452 { 9453 TCGv t0 = tcg_temp_new(); 9454 9455 gen_load_gpr(t0, rt); 9456 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9457 tcg_temp_free(t0); 9458 } 9459 opn = "dmtc0"; 9460 break; 9461 #endif 9462 case OPC_MFHC0: 9463 check_mvh(ctx); 9464 if (rt == 0) { 9465 /* Treat as NOP. */ 9466 return; 9467 } 9468 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9469 opn = "mfhc0"; 9470 break; 9471 case OPC_MTHC0: 9472 check_mvh(ctx); 9473 { 9474 TCGv t0 = tcg_temp_new(); 9475 gen_load_gpr(t0, rt); 9476 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9477 tcg_temp_free(t0); 9478 } 9479 opn = "mthc0"; 9480 break; 9481 case OPC_MFTR: 9482 check_cp0_enabled(ctx); 9483 if (rd == 0) { 9484 /* Treat as NOP. */ 9485 return; 9486 } 9487 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9488 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9489 opn = "mftr"; 9490 break; 9491 case OPC_MTTR: 9492 check_cp0_enabled(ctx); 9493 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9494 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9495 opn = "mttr"; 9496 break; 9497 case OPC_TLBWI: 9498 opn = "tlbwi"; 9499 if (!env->tlb->helper_tlbwi) { 9500 goto die; 9501 } 9502 gen_helper_tlbwi(cpu_env); 9503 break; 9504 case OPC_TLBINV: 9505 opn = "tlbinv"; 9506 if (ctx->ie >= 2) { 9507 if (!env->tlb->helper_tlbinv) { 9508 goto die; 9509 } 9510 gen_helper_tlbinv(cpu_env); 9511 } /* treat as nop if TLBINV not supported */ 9512 break; 9513 case OPC_TLBINVF: 9514 opn = "tlbinvf"; 9515 if (ctx->ie >= 2) { 9516 if (!env->tlb->helper_tlbinvf) { 9517 goto die; 9518 } 9519 gen_helper_tlbinvf(cpu_env); 9520 } /* treat as nop if TLBINV not supported */ 9521 break; 9522 case OPC_TLBWR: 9523 opn = "tlbwr"; 9524 if (!env->tlb->helper_tlbwr) { 9525 goto die; 9526 } 9527 gen_helper_tlbwr(cpu_env); 9528 break; 9529 case OPC_TLBP: 9530 opn = "tlbp"; 9531 if (!env->tlb->helper_tlbp) { 9532 goto die; 9533 } 9534 gen_helper_tlbp(cpu_env); 9535 break; 9536 case OPC_TLBR: 9537 opn = "tlbr"; 9538 if (!env->tlb->helper_tlbr) { 9539 goto die; 9540 } 9541 gen_helper_tlbr(cpu_env); 9542 break; 9543 case OPC_ERET: /* OPC_ERETNC */ 9544 if ((ctx->insn_flags & ISA_MIPS_R6) && 9545 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9546 goto die; 9547 } else { 9548 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9549 if (ctx->opcode & (1 << bit_shift)) { 9550 /* OPC_ERETNC */ 9551 opn = "eretnc"; 9552 check_insn(ctx, ISA_MIPS_R5); 9553 gen_helper_eretnc(cpu_env); 9554 } else { 9555 /* OPC_ERET */ 9556 opn = "eret"; 9557 check_insn(ctx, ISA_MIPS2); 9558 gen_helper_eret(cpu_env); 9559 } 9560 ctx->base.is_jmp = DISAS_EXIT; 9561 } 9562 break; 9563 case OPC_DERET: 9564 opn = "deret"; 9565 check_insn(ctx, ISA_MIPS_R1); 9566 if ((ctx->insn_flags & ISA_MIPS_R6) && 9567 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9568 goto die; 9569 } 9570 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9571 MIPS_INVAL(opn); 9572 gen_reserved_instruction(ctx); 9573 } else { 9574 gen_helper_deret(cpu_env); 9575 ctx->base.is_jmp = DISAS_EXIT; 9576 } 9577 break; 9578 case OPC_WAIT: 9579 opn = "wait"; 9580 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9581 if ((ctx->insn_flags & ISA_MIPS_R6) && 9582 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9583 goto die; 9584 } 9585 /* If we get an exception, we want to restart at next instruction */ 9586 ctx->base.pc_next += 4; 9587 save_cpu_state(ctx, 1); 9588 ctx->base.pc_next -= 4; 9589 gen_helper_wait(cpu_env); 9590 ctx->base.is_jmp = DISAS_NORETURN; 9591 break; 9592 default: 9593 die: 9594 MIPS_INVAL(opn); 9595 gen_reserved_instruction(ctx); 9596 return; 9597 } 9598 (void)opn; /* avoid a compiler warning */ 9599 } 9600 #endif /* !CONFIG_USER_ONLY */ 9601 9602 /* CP1 Branches (before delay slot) */ 9603 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9604 int32_t cc, int32_t offset) 9605 { 9606 target_ulong btarget; 9607 TCGv_i32 t0 = tcg_temp_new_i32(); 9608 9609 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9610 gen_reserved_instruction(ctx); 9611 goto out; 9612 } 9613 9614 if (cc != 0) { 9615 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9616 } 9617 9618 btarget = ctx->base.pc_next + 4 + offset; 9619 9620 switch (op) { 9621 case OPC_BC1F: 9622 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9623 tcg_gen_not_i32(t0, t0); 9624 tcg_gen_andi_i32(t0, t0, 1); 9625 tcg_gen_extu_i32_tl(bcond, t0); 9626 goto not_likely; 9627 case OPC_BC1FL: 9628 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9629 tcg_gen_not_i32(t0, t0); 9630 tcg_gen_andi_i32(t0, t0, 1); 9631 tcg_gen_extu_i32_tl(bcond, t0); 9632 goto likely; 9633 case OPC_BC1T: 9634 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9635 tcg_gen_andi_i32(t0, t0, 1); 9636 tcg_gen_extu_i32_tl(bcond, t0); 9637 goto not_likely; 9638 case OPC_BC1TL: 9639 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9640 tcg_gen_andi_i32(t0, t0, 1); 9641 tcg_gen_extu_i32_tl(bcond, t0); 9642 likely: 9643 ctx->hflags |= MIPS_HFLAG_BL; 9644 break; 9645 case OPC_BC1FANY2: 9646 { 9647 TCGv_i32 t1 = tcg_temp_new_i32(); 9648 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9649 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9650 tcg_gen_nand_i32(t0, t0, t1); 9651 tcg_temp_free_i32(t1); 9652 tcg_gen_andi_i32(t0, t0, 1); 9653 tcg_gen_extu_i32_tl(bcond, t0); 9654 } 9655 goto not_likely; 9656 case OPC_BC1TANY2: 9657 { 9658 TCGv_i32 t1 = tcg_temp_new_i32(); 9659 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9660 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9661 tcg_gen_or_i32(t0, t0, t1); 9662 tcg_temp_free_i32(t1); 9663 tcg_gen_andi_i32(t0, t0, 1); 9664 tcg_gen_extu_i32_tl(bcond, t0); 9665 } 9666 goto not_likely; 9667 case OPC_BC1FANY4: 9668 { 9669 TCGv_i32 t1 = tcg_temp_new_i32(); 9670 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9671 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9672 tcg_gen_and_i32(t0, t0, t1); 9673 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9674 tcg_gen_and_i32(t0, t0, t1); 9675 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9676 tcg_gen_nand_i32(t0, t0, t1); 9677 tcg_temp_free_i32(t1); 9678 tcg_gen_andi_i32(t0, t0, 1); 9679 tcg_gen_extu_i32_tl(bcond, t0); 9680 } 9681 goto not_likely; 9682 case OPC_BC1TANY4: 9683 { 9684 TCGv_i32 t1 = tcg_temp_new_i32(); 9685 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9686 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9687 tcg_gen_or_i32(t0, t0, t1); 9688 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9689 tcg_gen_or_i32(t0, t0, t1); 9690 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9691 tcg_gen_or_i32(t0, t0, t1); 9692 tcg_temp_free_i32(t1); 9693 tcg_gen_andi_i32(t0, t0, 1); 9694 tcg_gen_extu_i32_tl(bcond, t0); 9695 } 9696 not_likely: 9697 ctx->hflags |= MIPS_HFLAG_BC; 9698 break; 9699 default: 9700 MIPS_INVAL("cp1 cond branch"); 9701 gen_reserved_instruction(ctx); 9702 goto out; 9703 } 9704 ctx->btarget = btarget; 9705 ctx->hflags |= MIPS_HFLAG_BDS32; 9706 out: 9707 tcg_temp_free_i32(t0); 9708 } 9709 9710 /* R6 CP1 Branches */ 9711 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9712 int32_t ft, int32_t offset, 9713 int delayslot_size) 9714 { 9715 target_ulong btarget; 9716 TCGv_i64 t0 = tcg_temp_new_i64(); 9717 9718 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9719 #ifdef MIPS_DEBUG_DISAS 9720 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9721 "\n", ctx->base.pc_next); 9722 #endif 9723 gen_reserved_instruction(ctx); 9724 goto out; 9725 } 9726 9727 gen_load_fpr64(ctx, t0, ft); 9728 tcg_gen_andi_i64(t0, t0, 1); 9729 9730 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9731 9732 switch (op) { 9733 case OPC_BC1EQZ: 9734 tcg_gen_xori_i64(t0, t0, 1); 9735 ctx->hflags |= MIPS_HFLAG_BC; 9736 break; 9737 case OPC_BC1NEZ: 9738 /* t0 already set */ 9739 ctx->hflags |= MIPS_HFLAG_BC; 9740 break; 9741 default: 9742 MIPS_INVAL("cp1 cond branch"); 9743 gen_reserved_instruction(ctx); 9744 goto out; 9745 } 9746 9747 tcg_gen_trunc_i64_tl(bcond, t0); 9748 9749 ctx->btarget = btarget; 9750 9751 switch (delayslot_size) { 9752 case 2: 9753 ctx->hflags |= MIPS_HFLAG_BDS16; 9754 break; 9755 case 4: 9756 ctx->hflags |= MIPS_HFLAG_BDS32; 9757 break; 9758 } 9759 9760 out: 9761 tcg_temp_free_i64(t0); 9762 } 9763 9764 /* Coprocessor 1 (FPU) */ 9765 9766 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9767 9768 enum fopcode { 9769 OPC_ADD_S = FOP(0, FMT_S), 9770 OPC_SUB_S = FOP(1, FMT_S), 9771 OPC_MUL_S = FOP(2, FMT_S), 9772 OPC_DIV_S = FOP(3, FMT_S), 9773 OPC_SQRT_S = FOP(4, FMT_S), 9774 OPC_ABS_S = FOP(5, FMT_S), 9775 OPC_MOV_S = FOP(6, FMT_S), 9776 OPC_NEG_S = FOP(7, FMT_S), 9777 OPC_ROUND_L_S = FOP(8, FMT_S), 9778 OPC_TRUNC_L_S = FOP(9, FMT_S), 9779 OPC_CEIL_L_S = FOP(10, FMT_S), 9780 OPC_FLOOR_L_S = FOP(11, FMT_S), 9781 OPC_ROUND_W_S = FOP(12, FMT_S), 9782 OPC_TRUNC_W_S = FOP(13, FMT_S), 9783 OPC_CEIL_W_S = FOP(14, FMT_S), 9784 OPC_FLOOR_W_S = FOP(15, FMT_S), 9785 OPC_SEL_S = FOP(16, FMT_S), 9786 OPC_MOVCF_S = FOP(17, FMT_S), 9787 OPC_MOVZ_S = FOP(18, FMT_S), 9788 OPC_MOVN_S = FOP(19, FMT_S), 9789 OPC_SELEQZ_S = FOP(20, FMT_S), 9790 OPC_RECIP_S = FOP(21, FMT_S), 9791 OPC_RSQRT_S = FOP(22, FMT_S), 9792 OPC_SELNEZ_S = FOP(23, FMT_S), 9793 OPC_MADDF_S = FOP(24, FMT_S), 9794 OPC_MSUBF_S = FOP(25, FMT_S), 9795 OPC_RINT_S = FOP(26, FMT_S), 9796 OPC_CLASS_S = FOP(27, FMT_S), 9797 OPC_MIN_S = FOP(28, FMT_S), 9798 OPC_RECIP2_S = FOP(28, FMT_S), 9799 OPC_MINA_S = FOP(29, FMT_S), 9800 OPC_RECIP1_S = FOP(29, FMT_S), 9801 OPC_MAX_S = FOP(30, FMT_S), 9802 OPC_RSQRT1_S = FOP(30, FMT_S), 9803 OPC_MAXA_S = FOP(31, FMT_S), 9804 OPC_RSQRT2_S = FOP(31, FMT_S), 9805 OPC_CVT_D_S = FOP(33, FMT_S), 9806 OPC_CVT_W_S = FOP(36, FMT_S), 9807 OPC_CVT_L_S = FOP(37, FMT_S), 9808 OPC_CVT_PS_S = FOP(38, FMT_S), 9809 OPC_CMP_F_S = FOP(48, FMT_S), 9810 OPC_CMP_UN_S = FOP(49, FMT_S), 9811 OPC_CMP_EQ_S = FOP(50, FMT_S), 9812 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9813 OPC_CMP_OLT_S = FOP(52, FMT_S), 9814 OPC_CMP_ULT_S = FOP(53, FMT_S), 9815 OPC_CMP_OLE_S = FOP(54, FMT_S), 9816 OPC_CMP_ULE_S = FOP(55, FMT_S), 9817 OPC_CMP_SF_S = FOP(56, FMT_S), 9818 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9819 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9820 OPC_CMP_NGL_S = FOP(59, FMT_S), 9821 OPC_CMP_LT_S = FOP(60, FMT_S), 9822 OPC_CMP_NGE_S = FOP(61, FMT_S), 9823 OPC_CMP_LE_S = FOP(62, FMT_S), 9824 OPC_CMP_NGT_S = FOP(63, FMT_S), 9825 9826 OPC_ADD_D = FOP(0, FMT_D), 9827 OPC_SUB_D = FOP(1, FMT_D), 9828 OPC_MUL_D = FOP(2, FMT_D), 9829 OPC_DIV_D = FOP(3, FMT_D), 9830 OPC_SQRT_D = FOP(4, FMT_D), 9831 OPC_ABS_D = FOP(5, FMT_D), 9832 OPC_MOV_D = FOP(6, FMT_D), 9833 OPC_NEG_D = FOP(7, FMT_D), 9834 OPC_ROUND_L_D = FOP(8, FMT_D), 9835 OPC_TRUNC_L_D = FOP(9, FMT_D), 9836 OPC_CEIL_L_D = FOP(10, FMT_D), 9837 OPC_FLOOR_L_D = FOP(11, FMT_D), 9838 OPC_ROUND_W_D = FOP(12, FMT_D), 9839 OPC_TRUNC_W_D = FOP(13, FMT_D), 9840 OPC_CEIL_W_D = FOP(14, FMT_D), 9841 OPC_FLOOR_W_D = FOP(15, FMT_D), 9842 OPC_SEL_D = FOP(16, FMT_D), 9843 OPC_MOVCF_D = FOP(17, FMT_D), 9844 OPC_MOVZ_D = FOP(18, FMT_D), 9845 OPC_MOVN_D = FOP(19, FMT_D), 9846 OPC_SELEQZ_D = FOP(20, FMT_D), 9847 OPC_RECIP_D = FOP(21, FMT_D), 9848 OPC_RSQRT_D = FOP(22, FMT_D), 9849 OPC_SELNEZ_D = FOP(23, FMT_D), 9850 OPC_MADDF_D = FOP(24, FMT_D), 9851 OPC_MSUBF_D = FOP(25, FMT_D), 9852 OPC_RINT_D = FOP(26, FMT_D), 9853 OPC_CLASS_D = FOP(27, FMT_D), 9854 OPC_MIN_D = FOP(28, FMT_D), 9855 OPC_RECIP2_D = FOP(28, FMT_D), 9856 OPC_MINA_D = FOP(29, FMT_D), 9857 OPC_RECIP1_D = FOP(29, FMT_D), 9858 OPC_MAX_D = FOP(30, FMT_D), 9859 OPC_RSQRT1_D = FOP(30, FMT_D), 9860 OPC_MAXA_D = FOP(31, FMT_D), 9861 OPC_RSQRT2_D = FOP(31, FMT_D), 9862 OPC_CVT_S_D = FOP(32, FMT_D), 9863 OPC_CVT_W_D = FOP(36, FMT_D), 9864 OPC_CVT_L_D = FOP(37, FMT_D), 9865 OPC_CMP_F_D = FOP(48, FMT_D), 9866 OPC_CMP_UN_D = FOP(49, FMT_D), 9867 OPC_CMP_EQ_D = FOP(50, FMT_D), 9868 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9869 OPC_CMP_OLT_D = FOP(52, FMT_D), 9870 OPC_CMP_ULT_D = FOP(53, FMT_D), 9871 OPC_CMP_OLE_D = FOP(54, FMT_D), 9872 OPC_CMP_ULE_D = FOP(55, FMT_D), 9873 OPC_CMP_SF_D = FOP(56, FMT_D), 9874 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9875 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9876 OPC_CMP_NGL_D = FOP(59, FMT_D), 9877 OPC_CMP_LT_D = FOP(60, FMT_D), 9878 OPC_CMP_NGE_D = FOP(61, FMT_D), 9879 OPC_CMP_LE_D = FOP(62, FMT_D), 9880 OPC_CMP_NGT_D = FOP(63, FMT_D), 9881 9882 OPC_CVT_S_W = FOP(32, FMT_W), 9883 OPC_CVT_D_W = FOP(33, FMT_W), 9884 OPC_CVT_S_L = FOP(32, FMT_L), 9885 OPC_CVT_D_L = FOP(33, FMT_L), 9886 OPC_CVT_PS_PW = FOP(38, FMT_W), 9887 9888 OPC_ADD_PS = FOP(0, FMT_PS), 9889 OPC_SUB_PS = FOP(1, FMT_PS), 9890 OPC_MUL_PS = FOP(2, FMT_PS), 9891 OPC_DIV_PS = FOP(3, FMT_PS), 9892 OPC_ABS_PS = FOP(5, FMT_PS), 9893 OPC_MOV_PS = FOP(6, FMT_PS), 9894 OPC_NEG_PS = FOP(7, FMT_PS), 9895 OPC_MOVCF_PS = FOP(17, FMT_PS), 9896 OPC_MOVZ_PS = FOP(18, FMT_PS), 9897 OPC_MOVN_PS = FOP(19, FMT_PS), 9898 OPC_ADDR_PS = FOP(24, FMT_PS), 9899 OPC_MULR_PS = FOP(26, FMT_PS), 9900 OPC_RECIP2_PS = FOP(28, FMT_PS), 9901 OPC_RECIP1_PS = FOP(29, FMT_PS), 9902 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9903 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9904 9905 OPC_CVT_S_PU = FOP(32, FMT_PS), 9906 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9907 OPC_CVT_S_PL = FOP(40, FMT_PS), 9908 OPC_PLL_PS = FOP(44, FMT_PS), 9909 OPC_PLU_PS = FOP(45, FMT_PS), 9910 OPC_PUL_PS = FOP(46, FMT_PS), 9911 OPC_PUU_PS = FOP(47, FMT_PS), 9912 OPC_CMP_F_PS = FOP(48, FMT_PS), 9913 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9914 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9915 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9916 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9917 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9918 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9919 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9920 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9921 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9922 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9923 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9924 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9925 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9926 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9927 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9928 }; 9929 9930 enum r6_f_cmp_op { 9931 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9932 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9933 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9934 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9935 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9936 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9937 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9938 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9939 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9940 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9941 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9942 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9943 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9944 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9945 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9946 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9947 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9948 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9949 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9950 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9951 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9952 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9953 9954 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9955 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9956 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9957 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9958 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9959 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9960 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9961 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9962 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9963 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9964 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9965 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9966 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9967 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9968 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9969 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9970 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9971 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9972 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9973 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9974 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9975 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9976 }; 9977 9978 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9979 { 9980 TCGv t0 = tcg_temp_new(); 9981 9982 switch (opc) { 9983 case OPC_MFC1: 9984 { 9985 TCGv_i32 fp0 = tcg_temp_new_i32(); 9986 9987 gen_load_fpr32(ctx, fp0, fs); 9988 tcg_gen_ext_i32_tl(t0, fp0); 9989 tcg_temp_free_i32(fp0); 9990 } 9991 gen_store_gpr(t0, rt); 9992 break; 9993 case OPC_MTC1: 9994 gen_load_gpr(t0, rt); 9995 { 9996 TCGv_i32 fp0 = tcg_temp_new_i32(); 9997 9998 tcg_gen_trunc_tl_i32(fp0, t0); 9999 gen_store_fpr32(ctx, fp0, fs); 10000 tcg_temp_free_i32(fp0); 10001 } 10002 break; 10003 case OPC_CFC1: 10004 gen_helper_1e0i(cfc1, t0, fs); 10005 gen_store_gpr(t0, rt); 10006 break; 10007 case OPC_CTC1: 10008 gen_load_gpr(t0, rt); 10009 save_cpu_state(ctx, 0); 10010 { 10011 TCGv_i32 fs_tmp = tcg_const_i32(fs); 10012 10013 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 10014 tcg_temp_free_i32(fs_tmp); 10015 } 10016 /* Stop translation as we may have changed hflags */ 10017 ctx->base.is_jmp = DISAS_STOP; 10018 break; 10019 #if defined(TARGET_MIPS64) 10020 case OPC_DMFC1: 10021 gen_load_fpr64(ctx, t0, fs); 10022 gen_store_gpr(t0, rt); 10023 break; 10024 case OPC_DMTC1: 10025 gen_load_gpr(t0, rt); 10026 gen_store_fpr64(ctx, t0, fs); 10027 break; 10028 #endif 10029 case OPC_MFHC1: 10030 { 10031 TCGv_i32 fp0 = tcg_temp_new_i32(); 10032 10033 gen_load_fpr32h(ctx, fp0, fs); 10034 tcg_gen_ext_i32_tl(t0, fp0); 10035 tcg_temp_free_i32(fp0); 10036 } 10037 gen_store_gpr(t0, rt); 10038 break; 10039 case OPC_MTHC1: 10040 gen_load_gpr(t0, rt); 10041 { 10042 TCGv_i32 fp0 = tcg_temp_new_i32(); 10043 10044 tcg_gen_trunc_tl_i32(fp0, t0); 10045 gen_store_fpr32h(ctx, fp0, fs); 10046 tcg_temp_free_i32(fp0); 10047 } 10048 break; 10049 default: 10050 MIPS_INVAL("cp1 move"); 10051 gen_reserved_instruction(ctx); 10052 goto out; 10053 } 10054 10055 out: 10056 tcg_temp_free(t0); 10057 } 10058 10059 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 10060 { 10061 TCGLabel *l1; 10062 TCGCond cond; 10063 TCGv_i32 t0; 10064 10065 if (rd == 0) { 10066 /* Treat as NOP. */ 10067 return; 10068 } 10069 10070 if (tf) { 10071 cond = TCG_COND_EQ; 10072 } else { 10073 cond = TCG_COND_NE; 10074 } 10075 10076 l1 = gen_new_label(); 10077 t0 = tcg_temp_new_i32(); 10078 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 10079 tcg_gen_brcondi_i32(cond, t0, 0, l1); 10080 tcg_temp_free_i32(t0); 10081 gen_load_gpr(cpu_gpr[rd], rs); 10082 gen_set_label(l1); 10083 } 10084 10085 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 10086 int tf) 10087 { 10088 int cond; 10089 TCGv_i32 t0 = tcg_temp_new_i32(); 10090 TCGLabel *l1 = gen_new_label(); 10091 10092 if (tf) { 10093 cond = TCG_COND_EQ; 10094 } else { 10095 cond = TCG_COND_NE; 10096 } 10097 10098 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 10099 tcg_gen_brcondi_i32(cond, t0, 0, l1); 10100 gen_load_fpr32(ctx, t0, fs); 10101 gen_store_fpr32(ctx, t0, fd); 10102 gen_set_label(l1); 10103 tcg_temp_free_i32(t0); 10104 } 10105 10106 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 10107 int tf) 10108 { 10109 int cond; 10110 TCGv_i32 t0 = tcg_temp_new_i32(); 10111 TCGv_i64 fp0; 10112 TCGLabel *l1 = gen_new_label(); 10113 10114 if (tf) { 10115 cond = TCG_COND_EQ; 10116 } else { 10117 cond = TCG_COND_NE; 10118 } 10119 10120 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 10121 tcg_gen_brcondi_i32(cond, t0, 0, l1); 10122 tcg_temp_free_i32(t0); 10123 fp0 = tcg_temp_new_i64(); 10124 gen_load_fpr64(ctx, fp0, fs); 10125 gen_store_fpr64(ctx, fp0, fd); 10126 tcg_temp_free_i64(fp0); 10127 gen_set_label(l1); 10128 } 10129 10130 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 10131 int cc, int tf) 10132 { 10133 int cond; 10134 TCGv_i32 t0 = tcg_temp_new_i32(); 10135 TCGLabel *l1 = gen_new_label(); 10136 TCGLabel *l2 = gen_new_label(); 10137 10138 if (tf) { 10139 cond = TCG_COND_EQ; 10140 } else { 10141 cond = TCG_COND_NE; 10142 } 10143 10144 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 10145 tcg_gen_brcondi_i32(cond, t0, 0, l1); 10146 gen_load_fpr32(ctx, t0, fs); 10147 gen_store_fpr32(ctx, t0, fd); 10148 gen_set_label(l1); 10149 10150 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 10151 tcg_gen_brcondi_i32(cond, t0, 0, l2); 10152 gen_load_fpr32h(ctx, t0, fs); 10153 gen_store_fpr32h(ctx, t0, fd); 10154 tcg_temp_free_i32(t0); 10155 gen_set_label(l2); 10156 } 10157 10158 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 10159 int fs) 10160 { 10161 TCGv_i32 t1 = tcg_const_i32(0); 10162 TCGv_i32 fp0 = tcg_temp_new_i32(); 10163 TCGv_i32 fp1 = tcg_temp_new_i32(); 10164 TCGv_i32 fp2 = tcg_temp_new_i32(); 10165 gen_load_fpr32(ctx, fp0, fd); 10166 gen_load_fpr32(ctx, fp1, ft); 10167 gen_load_fpr32(ctx, fp2, fs); 10168 10169 switch (op1) { 10170 case OPC_SEL_S: 10171 tcg_gen_andi_i32(fp0, fp0, 1); 10172 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 10173 break; 10174 case OPC_SELEQZ_S: 10175 tcg_gen_andi_i32(fp1, fp1, 1); 10176 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 10177 break; 10178 case OPC_SELNEZ_S: 10179 tcg_gen_andi_i32(fp1, fp1, 1); 10180 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 10181 break; 10182 default: 10183 MIPS_INVAL("gen_sel_s"); 10184 gen_reserved_instruction(ctx); 10185 break; 10186 } 10187 10188 gen_store_fpr32(ctx, fp0, fd); 10189 tcg_temp_free_i32(fp2); 10190 tcg_temp_free_i32(fp1); 10191 tcg_temp_free_i32(fp0); 10192 tcg_temp_free_i32(t1); 10193 } 10194 10195 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 10196 int fs) 10197 { 10198 TCGv_i64 t1 = tcg_const_i64(0); 10199 TCGv_i64 fp0 = tcg_temp_new_i64(); 10200 TCGv_i64 fp1 = tcg_temp_new_i64(); 10201 TCGv_i64 fp2 = tcg_temp_new_i64(); 10202 gen_load_fpr64(ctx, fp0, fd); 10203 gen_load_fpr64(ctx, fp1, ft); 10204 gen_load_fpr64(ctx, fp2, fs); 10205 10206 switch (op1) { 10207 case OPC_SEL_D: 10208 tcg_gen_andi_i64(fp0, fp0, 1); 10209 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 10210 break; 10211 case OPC_SELEQZ_D: 10212 tcg_gen_andi_i64(fp1, fp1, 1); 10213 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 10214 break; 10215 case OPC_SELNEZ_D: 10216 tcg_gen_andi_i64(fp1, fp1, 1); 10217 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 10218 break; 10219 default: 10220 MIPS_INVAL("gen_sel_d"); 10221 gen_reserved_instruction(ctx); 10222 break; 10223 } 10224 10225 gen_store_fpr64(ctx, fp0, fd); 10226 tcg_temp_free_i64(fp2); 10227 tcg_temp_free_i64(fp1); 10228 tcg_temp_free_i64(fp0); 10229 tcg_temp_free_i64(t1); 10230 } 10231 10232 static void gen_farith(DisasContext *ctx, enum fopcode op1, 10233 int ft, int fs, int fd, int cc) 10234 { 10235 uint32_t func = ctx->opcode & 0x3f; 10236 switch (op1) { 10237 case OPC_ADD_S: 10238 { 10239 TCGv_i32 fp0 = tcg_temp_new_i32(); 10240 TCGv_i32 fp1 = tcg_temp_new_i32(); 10241 10242 gen_load_fpr32(ctx, fp0, fs); 10243 gen_load_fpr32(ctx, fp1, ft); 10244 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 10245 tcg_temp_free_i32(fp1); 10246 gen_store_fpr32(ctx, fp0, fd); 10247 tcg_temp_free_i32(fp0); 10248 } 10249 break; 10250 case OPC_SUB_S: 10251 { 10252 TCGv_i32 fp0 = tcg_temp_new_i32(); 10253 TCGv_i32 fp1 = tcg_temp_new_i32(); 10254 10255 gen_load_fpr32(ctx, fp0, fs); 10256 gen_load_fpr32(ctx, fp1, ft); 10257 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 10258 tcg_temp_free_i32(fp1); 10259 gen_store_fpr32(ctx, fp0, fd); 10260 tcg_temp_free_i32(fp0); 10261 } 10262 break; 10263 case OPC_MUL_S: 10264 { 10265 TCGv_i32 fp0 = tcg_temp_new_i32(); 10266 TCGv_i32 fp1 = tcg_temp_new_i32(); 10267 10268 gen_load_fpr32(ctx, fp0, fs); 10269 gen_load_fpr32(ctx, fp1, ft); 10270 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 10271 tcg_temp_free_i32(fp1); 10272 gen_store_fpr32(ctx, fp0, fd); 10273 tcg_temp_free_i32(fp0); 10274 } 10275 break; 10276 case OPC_DIV_S: 10277 { 10278 TCGv_i32 fp0 = tcg_temp_new_i32(); 10279 TCGv_i32 fp1 = tcg_temp_new_i32(); 10280 10281 gen_load_fpr32(ctx, fp0, fs); 10282 gen_load_fpr32(ctx, fp1, ft); 10283 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 10284 tcg_temp_free_i32(fp1); 10285 gen_store_fpr32(ctx, fp0, fd); 10286 tcg_temp_free_i32(fp0); 10287 } 10288 break; 10289 case OPC_SQRT_S: 10290 { 10291 TCGv_i32 fp0 = tcg_temp_new_i32(); 10292 10293 gen_load_fpr32(ctx, fp0, fs); 10294 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 10295 gen_store_fpr32(ctx, fp0, fd); 10296 tcg_temp_free_i32(fp0); 10297 } 10298 break; 10299 case OPC_ABS_S: 10300 { 10301 TCGv_i32 fp0 = tcg_temp_new_i32(); 10302 10303 gen_load_fpr32(ctx, fp0, fs); 10304 if (ctx->abs2008) { 10305 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 10306 } else { 10307 gen_helper_float_abs_s(fp0, fp0); 10308 } 10309 gen_store_fpr32(ctx, fp0, fd); 10310 tcg_temp_free_i32(fp0); 10311 } 10312 break; 10313 case OPC_MOV_S: 10314 { 10315 TCGv_i32 fp0 = tcg_temp_new_i32(); 10316 10317 gen_load_fpr32(ctx, fp0, fs); 10318 gen_store_fpr32(ctx, fp0, fd); 10319 tcg_temp_free_i32(fp0); 10320 } 10321 break; 10322 case OPC_NEG_S: 10323 { 10324 TCGv_i32 fp0 = tcg_temp_new_i32(); 10325 10326 gen_load_fpr32(ctx, fp0, fs); 10327 if (ctx->abs2008) { 10328 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 10329 } else { 10330 gen_helper_float_chs_s(fp0, fp0); 10331 } 10332 gen_store_fpr32(ctx, fp0, fd); 10333 tcg_temp_free_i32(fp0); 10334 } 10335 break; 10336 case OPC_ROUND_L_S: 10337 check_cp1_64bitmode(ctx); 10338 { 10339 TCGv_i32 fp32 = tcg_temp_new_i32(); 10340 TCGv_i64 fp64 = tcg_temp_new_i64(); 10341 10342 gen_load_fpr32(ctx, fp32, fs); 10343 if (ctx->nan2008) { 10344 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10345 } else { 10346 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10347 } 10348 tcg_temp_free_i32(fp32); 10349 gen_store_fpr64(ctx, fp64, fd); 10350 tcg_temp_free_i64(fp64); 10351 } 10352 break; 10353 case OPC_TRUNC_L_S: 10354 check_cp1_64bitmode(ctx); 10355 { 10356 TCGv_i32 fp32 = tcg_temp_new_i32(); 10357 TCGv_i64 fp64 = tcg_temp_new_i64(); 10358 10359 gen_load_fpr32(ctx, fp32, fs); 10360 if (ctx->nan2008) { 10361 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10362 } else { 10363 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10364 } 10365 tcg_temp_free_i32(fp32); 10366 gen_store_fpr64(ctx, fp64, fd); 10367 tcg_temp_free_i64(fp64); 10368 } 10369 break; 10370 case OPC_CEIL_L_S: 10371 check_cp1_64bitmode(ctx); 10372 { 10373 TCGv_i32 fp32 = tcg_temp_new_i32(); 10374 TCGv_i64 fp64 = tcg_temp_new_i64(); 10375 10376 gen_load_fpr32(ctx, fp32, fs); 10377 if (ctx->nan2008) { 10378 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10379 } else { 10380 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10381 } 10382 tcg_temp_free_i32(fp32); 10383 gen_store_fpr64(ctx, fp64, fd); 10384 tcg_temp_free_i64(fp64); 10385 } 10386 break; 10387 case OPC_FLOOR_L_S: 10388 check_cp1_64bitmode(ctx); 10389 { 10390 TCGv_i32 fp32 = tcg_temp_new_i32(); 10391 TCGv_i64 fp64 = tcg_temp_new_i64(); 10392 10393 gen_load_fpr32(ctx, fp32, fs); 10394 if (ctx->nan2008) { 10395 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10396 } else { 10397 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10398 } 10399 tcg_temp_free_i32(fp32); 10400 gen_store_fpr64(ctx, fp64, fd); 10401 tcg_temp_free_i64(fp64); 10402 } 10403 break; 10404 case OPC_ROUND_W_S: 10405 { 10406 TCGv_i32 fp0 = tcg_temp_new_i32(); 10407 10408 gen_load_fpr32(ctx, fp0, fs); 10409 if (ctx->nan2008) { 10410 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10411 } else { 10412 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10413 } 10414 gen_store_fpr32(ctx, fp0, fd); 10415 tcg_temp_free_i32(fp0); 10416 } 10417 break; 10418 case OPC_TRUNC_W_S: 10419 { 10420 TCGv_i32 fp0 = tcg_temp_new_i32(); 10421 10422 gen_load_fpr32(ctx, fp0, fs); 10423 if (ctx->nan2008) { 10424 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10425 } else { 10426 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10427 } 10428 gen_store_fpr32(ctx, fp0, fd); 10429 tcg_temp_free_i32(fp0); 10430 } 10431 break; 10432 case OPC_CEIL_W_S: 10433 { 10434 TCGv_i32 fp0 = tcg_temp_new_i32(); 10435 10436 gen_load_fpr32(ctx, fp0, fs); 10437 if (ctx->nan2008) { 10438 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10439 } else { 10440 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10441 } 10442 gen_store_fpr32(ctx, fp0, fd); 10443 tcg_temp_free_i32(fp0); 10444 } 10445 break; 10446 case OPC_FLOOR_W_S: 10447 { 10448 TCGv_i32 fp0 = tcg_temp_new_i32(); 10449 10450 gen_load_fpr32(ctx, fp0, fs); 10451 if (ctx->nan2008) { 10452 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10453 } else { 10454 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10455 } 10456 gen_store_fpr32(ctx, fp0, fd); 10457 tcg_temp_free_i32(fp0); 10458 } 10459 break; 10460 case OPC_SEL_S: 10461 check_insn(ctx, ISA_MIPS_R6); 10462 gen_sel_s(ctx, op1, fd, ft, fs); 10463 break; 10464 case OPC_SELEQZ_S: 10465 check_insn(ctx, ISA_MIPS_R6); 10466 gen_sel_s(ctx, op1, fd, ft, fs); 10467 break; 10468 case OPC_SELNEZ_S: 10469 check_insn(ctx, ISA_MIPS_R6); 10470 gen_sel_s(ctx, op1, fd, ft, fs); 10471 break; 10472 case OPC_MOVCF_S: 10473 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10474 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10475 break; 10476 case OPC_MOVZ_S: 10477 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10478 { 10479 TCGLabel *l1 = gen_new_label(); 10480 TCGv_i32 fp0; 10481 10482 if (ft != 0) { 10483 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10484 } 10485 fp0 = tcg_temp_new_i32(); 10486 gen_load_fpr32(ctx, fp0, fs); 10487 gen_store_fpr32(ctx, fp0, fd); 10488 tcg_temp_free_i32(fp0); 10489 gen_set_label(l1); 10490 } 10491 break; 10492 case OPC_MOVN_S: 10493 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10494 { 10495 TCGLabel *l1 = gen_new_label(); 10496 TCGv_i32 fp0; 10497 10498 if (ft != 0) { 10499 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10500 fp0 = tcg_temp_new_i32(); 10501 gen_load_fpr32(ctx, fp0, fs); 10502 gen_store_fpr32(ctx, fp0, fd); 10503 tcg_temp_free_i32(fp0); 10504 gen_set_label(l1); 10505 } 10506 } 10507 break; 10508 case OPC_RECIP_S: 10509 { 10510 TCGv_i32 fp0 = tcg_temp_new_i32(); 10511 10512 gen_load_fpr32(ctx, fp0, fs); 10513 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10514 gen_store_fpr32(ctx, fp0, fd); 10515 tcg_temp_free_i32(fp0); 10516 } 10517 break; 10518 case OPC_RSQRT_S: 10519 { 10520 TCGv_i32 fp0 = tcg_temp_new_i32(); 10521 10522 gen_load_fpr32(ctx, fp0, fs); 10523 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10524 gen_store_fpr32(ctx, fp0, fd); 10525 tcg_temp_free_i32(fp0); 10526 } 10527 break; 10528 case OPC_MADDF_S: 10529 check_insn(ctx, ISA_MIPS_R6); 10530 { 10531 TCGv_i32 fp0 = tcg_temp_new_i32(); 10532 TCGv_i32 fp1 = tcg_temp_new_i32(); 10533 TCGv_i32 fp2 = tcg_temp_new_i32(); 10534 gen_load_fpr32(ctx, fp0, fs); 10535 gen_load_fpr32(ctx, fp1, ft); 10536 gen_load_fpr32(ctx, fp2, fd); 10537 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10538 gen_store_fpr32(ctx, fp2, fd); 10539 tcg_temp_free_i32(fp2); 10540 tcg_temp_free_i32(fp1); 10541 tcg_temp_free_i32(fp0); 10542 } 10543 break; 10544 case OPC_MSUBF_S: 10545 check_insn(ctx, ISA_MIPS_R6); 10546 { 10547 TCGv_i32 fp0 = tcg_temp_new_i32(); 10548 TCGv_i32 fp1 = tcg_temp_new_i32(); 10549 TCGv_i32 fp2 = tcg_temp_new_i32(); 10550 gen_load_fpr32(ctx, fp0, fs); 10551 gen_load_fpr32(ctx, fp1, ft); 10552 gen_load_fpr32(ctx, fp2, fd); 10553 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10554 gen_store_fpr32(ctx, fp2, fd); 10555 tcg_temp_free_i32(fp2); 10556 tcg_temp_free_i32(fp1); 10557 tcg_temp_free_i32(fp0); 10558 } 10559 break; 10560 case OPC_RINT_S: 10561 check_insn(ctx, ISA_MIPS_R6); 10562 { 10563 TCGv_i32 fp0 = tcg_temp_new_i32(); 10564 gen_load_fpr32(ctx, fp0, fs); 10565 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10566 gen_store_fpr32(ctx, fp0, fd); 10567 tcg_temp_free_i32(fp0); 10568 } 10569 break; 10570 case OPC_CLASS_S: 10571 check_insn(ctx, ISA_MIPS_R6); 10572 { 10573 TCGv_i32 fp0 = tcg_temp_new_i32(); 10574 gen_load_fpr32(ctx, fp0, fs); 10575 gen_helper_float_class_s(fp0, cpu_env, fp0); 10576 gen_store_fpr32(ctx, fp0, fd); 10577 tcg_temp_free_i32(fp0); 10578 } 10579 break; 10580 case OPC_MIN_S: /* OPC_RECIP2_S */ 10581 if (ctx->insn_flags & ISA_MIPS_R6) { 10582 /* OPC_MIN_S */ 10583 TCGv_i32 fp0 = tcg_temp_new_i32(); 10584 TCGv_i32 fp1 = tcg_temp_new_i32(); 10585 TCGv_i32 fp2 = tcg_temp_new_i32(); 10586 gen_load_fpr32(ctx, fp0, fs); 10587 gen_load_fpr32(ctx, fp1, ft); 10588 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10589 gen_store_fpr32(ctx, fp2, fd); 10590 tcg_temp_free_i32(fp2); 10591 tcg_temp_free_i32(fp1); 10592 tcg_temp_free_i32(fp0); 10593 } else { 10594 /* OPC_RECIP2_S */ 10595 check_cp1_64bitmode(ctx); 10596 { 10597 TCGv_i32 fp0 = tcg_temp_new_i32(); 10598 TCGv_i32 fp1 = tcg_temp_new_i32(); 10599 10600 gen_load_fpr32(ctx, fp0, fs); 10601 gen_load_fpr32(ctx, fp1, ft); 10602 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10603 tcg_temp_free_i32(fp1); 10604 gen_store_fpr32(ctx, fp0, fd); 10605 tcg_temp_free_i32(fp0); 10606 } 10607 } 10608 break; 10609 case OPC_MINA_S: /* OPC_RECIP1_S */ 10610 if (ctx->insn_flags & ISA_MIPS_R6) { 10611 /* OPC_MINA_S */ 10612 TCGv_i32 fp0 = tcg_temp_new_i32(); 10613 TCGv_i32 fp1 = tcg_temp_new_i32(); 10614 TCGv_i32 fp2 = tcg_temp_new_i32(); 10615 gen_load_fpr32(ctx, fp0, fs); 10616 gen_load_fpr32(ctx, fp1, ft); 10617 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10618 gen_store_fpr32(ctx, fp2, fd); 10619 tcg_temp_free_i32(fp2); 10620 tcg_temp_free_i32(fp1); 10621 tcg_temp_free_i32(fp0); 10622 } else { 10623 /* OPC_RECIP1_S */ 10624 check_cp1_64bitmode(ctx); 10625 { 10626 TCGv_i32 fp0 = tcg_temp_new_i32(); 10627 10628 gen_load_fpr32(ctx, fp0, fs); 10629 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10630 gen_store_fpr32(ctx, fp0, fd); 10631 tcg_temp_free_i32(fp0); 10632 } 10633 } 10634 break; 10635 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10636 if (ctx->insn_flags & ISA_MIPS_R6) { 10637 /* OPC_MAX_S */ 10638 TCGv_i32 fp0 = tcg_temp_new_i32(); 10639 TCGv_i32 fp1 = tcg_temp_new_i32(); 10640 gen_load_fpr32(ctx, fp0, fs); 10641 gen_load_fpr32(ctx, fp1, ft); 10642 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10643 gen_store_fpr32(ctx, fp1, fd); 10644 tcg_temp_free_i32(fp1); 10645 tcg_temp_free_i32(fp0); 10646 } else { 10647 /* OPC_RSQRT1_S */ 10648 check_cp1_64bitmode(ctx); 10649 { 10650 TCGv_i32 fp0 = tcg_temp_new_i32(); 10651 10652 gen_load_fpr32(ctx, fp0, fs); 10653 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10654 gen_store_fpr32(ctx, fp0, fd); 10655 tcg_temp_free_i32(fp0); 10656 } 10657 } 10658 break; 10659 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10660 if (ctx->insn_flags & ISA_MIPS_R6) { 10661 /* OPC_MAXA_S */ 10662 TCGv_i32 fp0 = tcg_temp_new_i32(); 10663 TCGv_i32 fp1 = tcg_temp_new_i32(); 10664 gen_load_fpr32(ctx, fp0, fs); 10665 gen_load_fpr32(ctx, fp1, ft); 10666 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10667 gen_store_fpr32(ctx, fp1, fd); 10668 tcg_temp_free_i32(fp1); 10669 tcg_temp_free_i32(fp0); 10670 } else { 10671 /* OPC_RSQRT2_S */ 10672 check_cp1_64bitmode(ctx); 10673 { 10674 TCGv_i32 fp0 = tcg_temp_new_i32(); 10675 TCGv_i32 fp1 = tcg_temp_new_i32(); 10676 10677 gen_load_fpr32(ctx, fp0, fs); 10678 gen_load_fpr32(ctx, fp1, ft); 10679 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10680 tcg_temp_free_i32(fp1); 10681 gen_store_fpr32(ctx, fp0, fd); 10682 tcg_temp_free_i32(fp0); 10683 } 10684 } 10685 break; 10686 case OPC_CVT_D_S: 10687 check_cp1_registers(ctx, fd); 10688 { 10689 TCGv_i32 fp32 = tcg_temp_new_i32(); 10690 TCGv_i64 fp64 = tcg_temp_new_i64(); 10691 10692 gen_load_fpr32(ctx, fp32, fs); 10693 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10694 tcg_temp_free_i32(fp32); 10695 gen_store_fpr64(ctx, fp64, fd); 10696 tcg_temp_free_i64(fp64); 10697 } 10698 break; 10699 case OPC_CVT_W_S: 10700 { 10701 TCGv_i32 fp0 = tcg_temp_new_i32(); 10702 10703 gen_load_fpr32(ctx, fp0, fs); 10704 if (ctx->nan2008) { 10705 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10706 } else { 10707 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10708 } 10709 gen_store_fpr32(ctx, fp0, fd); 10710 tcg_temp_free_i32(fp0); 10711 } 10712 break; 10713 case OPC_CVT_L_S: 10714 check_cp1_64bitmode(ctx); 10715 { 10716 TCGv_i32 fp32 = tcg_temp_new_i32(); 10717 TCGv_i64 fp64 = tcg_temp_new_i64(); 10718 10719 gen_load_fpr32(ctx, fp32, fs); 10720 if (ctx->nan2008) { 10721 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10722 } else { 10723 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10724 } 10725 tcg_temp_free_i32(fp32); 10726 gen_store_fpr64(ctx, fp64, fd); 10727 tcg_temp_free_i64(fp64); 10728 } 10729 break; 10730 case OPC_CVT_PS_S: 10731 check_ps(ctx); 10732 { 10733 TCGv_i64 fp64 = tcg_temp_new_i64(); 10734 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10735 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10736 10737 gen_load_fpr32(ctx, fp32_0, fs); 10738 gen_load_fpr32(ctx, fp32_1, ft); 10739 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10740 tcg_temp_free_i32(fp32_1); 10741 tcg_temp_free_i32(fp32_0); 10742 gen_store_fpr64(ctx, fp64, fd); 10743 tcg_temp_free_i64(fp64); 10744 } 10745 break; 10746 case OPC_CMP_F_S: 10747 case OPC_CMP_UN_S: 10748 case OPC_CMP_EQ_S: 10749 case OPC_CMP_UEQ_S: 10750 case OPC_CMP_OLT_S: 10751 case OPC_CMP_ULT_S: 10752 case OPC_CMP_OLE_S: 10753 case OPC_CMP_ULE_S: 10754 case OPC_CMP_SF_S: 10755 case OPC_CMP_NGLE_S: 10756 case OPC_CMP_SEQ_S: 10757 case OPC_CMP_NGL_S: 10758 case OPC_CMP_LT_S: 10759 case OPC_CMP_NGE_S: 10760 case OPC_CMP_LE_S: 10761 case OPC_CMP_NGT_S: 10762 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10763 if (ctx->opcode & (1 << 6)) { 10764 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10765 } else { 10766 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10767 } 10768 break; 10769 case OPC_ADD_D: 10770 check_cp1_registers(ctx, fs | ft | fd); 10771 { 10772 TCGv_i64 fp0 = tcg_temp_new_i64(); 10773 TCGv_i64 fp1 = tcg_temp_new_i64(); 10774 10775 gen_load_fpr64(ctx, fp0, fs); 10776 gen_load_fpr64(ctx, fp1, ft); 10777 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10778 tcg_temp_free_i64(fp1); 10779 gen_store_fpr64(ctx, fp0, fd); 10780 tcg_temp_free_i64(fp0); 10781 } 10782 break; 10783 case OPC_SUB_D: 10784 check_cp1_registers(ctx, fs | ft | fd); 10785 { 10786 TCGv_i64 fp0 = tcg_temp_new_i64(); 10787 TCGv_i64 fp1 = tcg_temp_new_i64(); 10788 10789 gen_load_fpr64(ctx, fp0, fs); 10790 gen_load_fpr64(ctx, fp1, ft); 10791 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10792 tcg_temp_free_i64(fp1); 10793 gen_store_fpr64(ctx, fp0, fd); 10794 tcg_temp_free_i64(fp0); 10795 } 10796 break; 10797 case OPC_MUL_D: 10798 check_cp1_registers(ctx, fs | ft | fd); 10799 { 10800 TCGv_i64 fp0 = tcg_temp_new_i64(); 10801 TCGv_i64 fp1 = tcg_temp_new_i64(); 10802 10803 gen_load_fpr64(ctx, fp0, fs); 10804 gen_load_fpr64(ctx, fp1, ft); 10805 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10806 tcg_temp_free_i64(fp1); 10807 gen_store_fpr64(ctx, fp0, fd); 10808 tcg_temp_free_i64(fp0); 10809 } 10810 break; 10811 case OPC_DIV_D: 10812 check_cp1_registers(ctx, fs | ft | fd); 10813 { 10814 TCGv_i64 fp0 = tcg_temp_new_i64(); 10815 TCGv_i64 fp1 = tcg_temp_new_i64(); 10816 10817 gen_load_fpr64(ctx, fp0, fs); 10818 gen_load_fpr64(ctx, fp1, ft); 10819 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10820 tcg_temp_free_i64(fp1); 10821 gen_store_fpr64(ctx, fp0, fd); 10822 tcg_temp_free_i64(fp0); 10823 } 10824 break; 10825 case OPC_SQRT_D: 10826 check_cp1_registers(ctx, fs | fd); 10827 { 10828 TCGv_i64 fp0 = tcg_temp_new_i64(); 10829 10830 gen_load_fpr64(ctx, fp0, fs); 10831 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10832 gen_store_fpr64(ctx, fp0, fd); 10833 tcg_temp_free_i64(fp0); 10834 } 10835 break; 10836 case OPC_ABS_D: 10837 check_cp1_registers(ctx, fs | fd); 10838 { 10839 TCGv_i64 fp0 = tcg_temp_new_i64(); 10840 10841 gen_load_fpr64(ctx, fp0, fs); 10842 if (ctx->abs2008) { 10843 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10844 } else { 10845 gen_helper_float_abs_d(fp0, fp0); 10846 } 10847 gen_store_fpr64(ctx, fp0, fd); 10848 tcg_temp_free_i64(fp0); 10849 } 10850 break; 10851 case OPC_MOV_D: 10852 check_cp1_registers(ctx, fs | fd); 10853 { 10854 TCGv_i64 fp0 = tcg_temp_new_i64(); 10855 10856 gen_load_fpr64(ctx, fp0, fs); 10857 gen_store_fpr64(ctx, fp0, fd); 10858 tcg_temp_free_i64(fp0); 10859 } 10860 break; 10861 case OPC_NEG_D: 10862 check_cp1_registers(ctx, fs | fd); 10863 { 10864 TCGv_i64 fp0 = tcg_temp_new_i64(); 10865 10866 gen_load_fpr64(ctx, fp0, fs); 10867 if (ctx->abs2008) { 10868 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10869 } else { 10870 gen_helper_float_chs_d(fp0, fp0); 10871 } 10872 gen_store_fpr64(ctx, fp0, fd); 10873 tcg_temp_free_i64(fp0); 10874 } 10875 break; 10876 case OPC_ROUND_L_D: 10877 check_cp1_64bitmode(ctx); 10878 { 10879 TCGv_i64 fp0 = tcg_temp_new_i64(); 10880 10881 gen_load_fpr64(ctx, fp0, fs); 10882 if (ctx->nan2008) { 10883 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10884 } else { 10885 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10886 } 10887 gen_store_fpr64(ctx, fp0, fd); 10888 tcg_temp_free_i64(fp0); 10889 } 10890 break; 10891 case OPC_TRUNC_L_D: 10892 check_cp1_64bitmode(ctx); 10893 { 10894 TCGv_i64 fp0 = tcg_temp_new_i64(); 10895 10896 gen_load_fpr64(ctx, fp0, fs); 10897 if (ctx->nan2008) { 10898 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10899 } else { 10900 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10901 } 10902 gen_store_fpr64(ctx, fp0, fd); 10903 tcg_temp_free_i64(fp0); 10904 } 10905 break; 10906 case OPC_CEIL_L_D: 10907 check_cp1_64bitmode(ctx); 10908 { 10909 TCGv_i64 fp0 = tcg_temp_new_i64(); 10910 10911 gen_load_fpr64(ctx, fp0, fs); 10912 if (ctx->nan2008) { 10913 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10914 } else { 10915 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10916 } 10917 gen_store_fpr64(ctx, fp0, fd); 10918 tcg_temp_free_i64(fp0); 10919 } 10920 break; 10921 case OPC_FLOOR_L_D: 10922 check_cp1_64bitmode(ctx); 10923 { 10924 TCGv_i64 fp0 = tcg_temp_new_i64(); 10925 10926 gen_load_fpr64(ctx, fp0, fs); 10927 if (ctx->nan2008) { 10928 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10929 } else { 10930 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10931 } 10932 gen_store_fpr64(ctx, fp0, fd); 10933 tcg_temp_free_i64(fp0); 10934 } 10935 break; 10936 case OPC_ROUND_W_D: 10937 check_cp1_registers(ctx, fs); 10938 { 10939 TCGv_i32 fp32 = tcg_temp_new_i32(); 10940 TCGv_i64 fp64 = tcg_temp_new_i64(); 10941 10942 gen_load_fpr64(ctx, fp64, fs); 10943 if (ctx->nan2008) { 10944 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10945 } else { 10946 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10947 } 10948 tcg_temp_free_i64(fp64); 10949 gen_store_fpr32(ctx, fp32, fd); 10950 tcg_temp_free_i32(fp32); 10951 } 10952 break; 10953 case OPC_TRUNC_W_D: 10954 check_cp1_registers(ctx, fs); 10955 { 10956 TCGv_i32 fp32 = tcg_temp_new_i32(); 10957 TCGv_i64 fp64 = tcg_temp_new_i64(); 10958 10959 gen_load_fpr64(ctx, fp64, fs); 10960 if (ctx->nan2008) { 10961 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10962 } else { 10963 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10964 } 10965 tcg_temp_free_i64(fp64); 10966 gen_store_fpr32(ctx, fp32, fd); 10967 tcg_temp_free_i32(fp32); 10968 } 10969 break; 10970 case OPC_CEIL_W_D: 10971 check_cp1_registers(ctx, fs); 10972 { 10973 TCGv_i32 fp32 = tcg_temp_new_i32(); 10974 TCGv_i64 fp64 = tcg_temp_new_i64(); 10975 10976 gen_load_fpr64(ctx, fp64, fs); 10977 if (ctx->nan2008) { 10978 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10979 } else { 10980 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10981 } 10982 tcg_temp_free_i64(fp64); 10983 gen_store_fpr32(ctx, fp32, fd); 10984 tcg_temp_free_i32(fp32); 10985 } 10986 break; 10987 case OPC_FLOOR_W_D: 10988 check_cp1_registers(ctx, fs); 10989 { 10990 TCGv_i32 fp32 = tcg_temp_new_i32(); 10991 TCGv_i64 fp64 = tcg_temp_new_i64(); 10992 10993 gen_load_fpr64(ctx, fp64, fs); 10994 if (ctx->nan2008) { 10995 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10996 } else { 10997 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10998 } 10999 tcg_temp_free_i64(fp64); 11000 gen_store_fpr32(ctx, fp32, fd); 11001 tcg_temp_free_i32(fp32); 11002 } 11003 break; 11004 case OPC_SEL_D: 11005 check_insn(ctx, ISA_MIPS_R6); 11006 gen_sel_d(ctx, op1, fd, ft, fs); 11007 break; 11008 case OPC_SELEQZ_D: 11009 check_insn(ctx, ISA_MIPS_R6); 11010 gen_sel_d(ctx, op1, fd, ft, fs); 11011 break; 11012 case OPC_SELNEZ_D: 11013 check_insn(ctx, ISA_MIPS_R6); 11014 gen_sel_d(ctx, op1, fd, ft, fs); 11015 break; 11016 case OPC_MOVCF_D: 11017 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11018 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11019 break; 11020 case OPC_MOVZ_D: 11021 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11022 { 11023 TCGLabel *l1 = gen_new_label(); 11024 TCGv_i64 fp0; 11025 11026 if (ft != 0) { 11027 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11028 } 11029 fp0 = tcg_temp_new_i64(); 11030 gen_load_fpr64(ctx, fp0, fs); 11031 gen_store_fpr64(ctx, fp0, fd); 11032 tcg_temp_free_i64(fp0); 11033 gen_set_label(l1); 11034 } 11035 break; 11036 case OPC_MOVN_D: 11037 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11038 { 11039 TCGLabel *l1 = gen_new_label(); 11040 TCGv_i64 fp0; 11041 11042 if (ft != 0) { 11043 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11044 fp0 = tcg_temp_new_i64(); 11045 gen_load_fpr64(ctx, fp0, fs); 11046 gen_store_fpr64(ctx, fp0, fd); 11047 tcg_temp_free_i64(fp0); 11048 gen_set_label(l1); 11049 } 11050 } 11051 break; 11052 case OPC_RECIP_D: 11053 check_cp1_registers(ctx, fs | fd); 11054 { 11055 TCGv_i64 fp0 = tcg_temp_new_i64(); 11056 11057 gen_load_fpr64(ctx, fp0, fs); 11058 gen_helper_float_recip_d(fp0, cpu_env, fp0); 11059 gen_store_fpr64(ctx, fp0, fd); 11060 tcg_temp_free_i64(fp0); 11061 } 11062 break; 11063 case OPC_RSQRT_D: 11064 check_cp1_registers(ctx, fs | fd); 11065 { 11066 TCGv_i64 fp0 = tcg_temp_new_i64(); 11067 11068 gen_load_fpr64(ctx, fp0, fs); 11069 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 11070 gen_store_fpr64(ctx, fp0, fd); 11071 tcg_temp_free_i64(fp0); 11072 } 11073 break; 11074 case OPC_MADDF_D: 11075 check_insn(ctx, ISA_MIPS_R6); 11076 { 11077 TCGv_i64 fp0 = tcg_temp_new_i64(); 11078 TCGv_i64 fp1 = tcg_temp_new_i64(); 11079 TCGv_i64 fp2 = tcg_temp_new_i64(); 11080 gen_load_fpr64(ctx, fp0, fs); 11081 gen_load_fpr64(ctx, fp1, ft); 11082 gen_load_fpr64(ctx, fp2, fd); 11083 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 11084 gen_store_fpr64(ctx, fp2, fd); 11085 tcg_temp_free_i64(fp2); 11086 tcg_temp_free_i64(fp1); 11087 tcg_temp_free_i64(fp0); 11088 } 11089 break; 11090 case OPC_MSUBF_D: 11091 check_insn(ctx, ISA_MIPS_R6); 11092 { 11093 TCGv_i64 fp0 = tcg_temp_new_i64(); 11094 TCGv_i64 fp1 = tcg_temp_new_i64(); 11095 TCGv_i64 fp2 = tcg_temp_new_i64(); 11096 gen_load_fpr64(ctx, fp0, fs); 11097 gen_load_fpr64(ctx, fp1, ft); 11098 gen_load_fpr64(ctx, fp2, fd); 11099 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 11100 gen_store_fpr64(ctx, fp2, fd); 11101 tcg_temp_free_i64(fp2); 11102 tcg_temp_free_i64(fp1); 11103 tcg_temp_free_i64(fp0); 11104 } 11105 break; 11106 case OPC_RINT_D: 11107 check_insn(ctx, ISA_MIPS_R6); 11108 { 11109 TCGv_i64 fp0 = tcg_temp_new_i64(); 11110 gen_load_fpr64(ctx, fp0, fs); 11111 gen_helper_float_rint_d(fp0, cpu_env, fp0); 11112 gen_store_fpr64(ctx, fp0, fd); 11113 tcg_temp_free_i64(fp0); 11114 } 11115 break; 11116 case OPC_CLASS_D: 11117 check_insn(ctx, ISA_MIPS_R6); 11118 { 11119 TCGv_i64 fp0 = tcg_temp_new_i64(); 11120 gen_load_fpr64(ctx, fp0, fs); 11121 gen_helper_float_class_d(fp0, cpu_env, fp0); 11122 gen_store_fpr64(ctx, fp0, fd); 11123 tcg_temp_free_i64(fp0); 11124 } 11125 break; 11126 case OPC_MIN_D: /* OPC_RECIP2_D */ 11127 if (ctx->insn_flags & ISA_MIPS_R6) { 11128 /* OPC_MIN_D */ 11129 TCGv_i64 fp0 = tcg_temp_new_i64(); 11130 TCGv_i64 fp1 = tcg_temp_new_i64(); 11131 gen_load_fpr64(ctx, fp0, fs); 11132 gen_load_fpr64(ctx, fp1, ft); 11133 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 11134 gen_store_fpr64(ctx, fp1, fd); 11135 tcg_temp_free_i64(fp1); 11136 tcg_temp_free_i64(fp0); 11137 } else { 11138 /* OPC_RECIP2_D */ 11139 check_cp1_64bitmode(ctx); 11140 { 11141 TCGv_i64 fp0 = tcg_temp_new_i64(); 11142 TCGv_i64 fp1 = tcg_temp_new_i64(); 11143 11144 gen_load_fpr64(ctx, fp0, fs); 11145 gen_load_fpr64(ctx, fp1, ft); 11146 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 11147 tcg_temp_free_i64(fp1); 11148 gen_store_fpr64(ctx, fp0, fd); 11149 tcg_temp_free_i64(fp0); 11150 } 11151 } 11152 break; 11153 case OPC_MINA_D: /* OPC_RECIP1_D */ 11154 if (ctx->insn_flags & ISA_MIPS_R6) { 11155 /* OPC_MINA_D */ 11156 TCGv_i64 fp0 = tcg_temp_new_i64(); 11157 TCGv_i64 fp1 = tcg_temp_new_i64(); 11158 gen_load_fpr64(ctx, fp0, fs); 11159 gen_load_fpr64(ctx, fp1, ft); 11160 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 11161 gen_store_fpr64(ctx, fp1, fd); 11162 tcg_temp_free_i64(fp1); 11163 tcg_temp_free_i64(fp0); 11164 } else { 11165 /* OPC_RECIP1_D */ 11166 check_cp1_64bitmode(ctx); 11167 { 11168 TCGv_i64 fp0 = tcg_temp_new_i64(); 11169 11170 gen_load_fpr64(ctx, fp0, fs); 11171 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 11172 gen_store_fpr64(ctx, fp0, fd); 11173 tcg_temp_free_i64(fp0); 11174 } 11175 } 11176 break; 11177 case OPC_MAX_D: /* OPC_RSQRT1_D */ 11178 if (ctx->insn_flags & ISA_MIPS_R6) { 11179 /* OPC_MAX_D */ 11180 TCGv_i64 fp0 = tcg_temp_new_i64(); 11181 TCGv_i64 fp1 = tcg_temp_new_i64(); 11182 gen_load_fpr64(ctx, fp0, fs); 11183 gen_load_fpr64(ctx, fp1, ft); 11184 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 11185 gen_store_fpr64(ctx, fp1, fd); 11186 tcg_temp_free_i64(fp1); 11187 tcg_temp_free_i64(fp0); 11188 } else { 11189 /* OPC_RSQRT1_D */ 11190 check_cp1_64bitmode(ctx); 11191 { 11192 TCGv_i64 fp0 = tcg_temp_new_i64(); 11193 11194 gen_load_fpr64(ctx, fp0, fs); 11195 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 11196 gen_store_fpr64(ctx, fp0, fd); 11197 tcg_temp_free_i64(fp0); 11198 } 11199 } 11200 break; 11201 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 11202 if (ctx->insn_flags & ISA_MIPS_R6) { 11203 /* OPC_MAXA_D */ 11204 TCGv_i64 fp0 = tcg_temp_new_i64(); 11205 TCGv_i64 fp1 = tcg_temp_new_i64(); 11206 gen_load_fpr64(ctx, fp0, fs); 11207 gen_load_fpr64(ctx, fp1, ft); 11208 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 11209 gen_store_fpr64(ctx, fp1, fd); 11210 tcg_temp_free_i64(fp1); 11211 tcg_temp_free_i64(fp0); 11212 } else { 11213 /* OPC_RSQRT2_D */ 11214 check_cp1_64bitmode(ctx); 11215 { 11216 TCGv_i64 fp0 = tcg_temp_new_i64(); 11217 TCGv_i64 fp1 = tcg_temp_new_i64(); 11218 11219 gen_load_fpr64(ctx, fp0, fs); 11220 gen_load_fpr64(ctx, fp1, ft); 11221 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 11222 tcg_temp_free_i64(fp1); 11223 gen_store_fpr64(ctx, fp0, fd); 11224 tcg_temp_free_i64(fp0); 11225 } 11226 } 11227 break; 11228 case OPC_CMP_F_D: 11229 case OPC_CMP_UN_D: 11230 case OPC_CMP_EQ_D: 11231 case OPC_CMP_UEQ_D: 11232 case OPC_CMP_OLT_D: 11233 case OPC_CMP_ULT_D: 11234 case OPC_CMP_OLE_D: 11235 case OPC_CMP_ULE_D: 11236 case OPC_CMP_SF_D: 11237 case OPC_CMP_NGLE_D: 11238 case OPC_CMP_SEQ_D: 11239 case OPC_CMP_NGL_D: 11240 case OPC_CMP_LT_D: 11241 case OPC_CMP_NGE_D: 11242 case OPC_CMP_LE_D: 11243 case OPC_CMP_NGT_D: 11244 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11245 if (ctx->opcode & (1 << 6)) { 11246 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 11247 } else { 11248 gen_cmp_d(ctx, func - 48, ft, fs, cc); 11249 } 11250 break; 11251 case OPC_CVT_S_D: 11252 check_cp1_registers(ctx, fs); 11253 { 11254 TCGv_i32 fp32 = tcg_temp_new_i32(); 11255 TCGv_i64 fp64 = tcg_temp_new_i64(); 11256 11257 gen_load_fpr64(ctx, fp64, fs); 11258 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 11259 tcg_temp_free_i64(fp64); 11260 gen_store_fpr32(ctx, fp32, fd); 11261 tcg_temp_free_i32(fp32); 11262 } 11263 break; 11264 case OPC_CVT_W_D: 11265 check_cp1_registers(ctx, fs); 11266 { 11267 TCGv_i32 fp32 = tcg_temp_new_i32(); 11268 TCGv_i64 fp64 = tcg_temp_new_i64(); 11269 11270 gen_load_fpr64(ctx, fp64, fs); 11271 if (ctx->nan2008) { 11272 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 11273 } else { 11274 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 11275 } 11276 tcg_temp_free_i64(fp64); 11277 gen_store_fpr32(ctx, fp32, fd); 11278 tcg_temp_free_i32(fp32); 11279 } 11280 break; 11281 case OPC_CVT_L_D: 11282 check_cp1_64bitmode(ctx); 11283 { 11284 TCGv_i64 fp0 = tcg_temp_new_i64(); 11285 11286 gen_load_fpr64(ctx, fp0, fs); 11287 if (ctx->nan2008) { 11288 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 11289 } else { 11290 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 11291 } 11292 gen_store_fpr64(ctx, fp0, fd); 11293 tcg_temp_free_i64(fp0); 11294 } 11295 break; 11296 case OPC_CVT_S_W: 11297 { 11298 TCGv_i32 fp0 = tcg_temp_new_i32(); 11299 11300 gen_load_fpr32(ctx, fp0, fs); 11301 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 11302 gen_store_fpr32(ctx, fp0, fd); 11303 tcg_temp_free_i32(fp0); 11304 } 11305 break; 11306 case OPC_CVT_D_W: 11307 check_cp1_registers(ctx, fd); 11308 { 11309 TCGv_i32 fp32 = tcg_temp_new_i32(); 11310 TCGv_i64 fp64 = tcg_temp_new_i64(); 11311 11312 gen_load_fpr32(ctx, fp32, fs); 11313 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 11314 tcg_temp_free_i32(fp32); 11315 gen_store_fpr64(ctx, fp64, fd); 11316 tcg_temp_free_i64(fp64); 11317 } 11318 break; 11319 case OPC_CVT_S_L: 11320 check_cp1_64bitmode(ctx); 11321 { 11322 TCGv_i32 fp32 = tcg_temp_new_i32(); 11323 TCGv_i64 fp64 = tcg_temp_new_i64(); 11324 11325 gen_load_fpr64(ctx, fp64, fs); 11326 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 11327 tcg_temp_free_i64(fp64); 11328 gen_store_fpr32(ctx, fp32, fd); 11329 tcg_temp_free_i32(fp32); 11330 } 11331 break; 11332 case OPC_CVT_D_L: 11333 check_cp1_64bitmode(ctx); 11334 { 11335 TCGv_i64 fp0 = tcg_temp_new_i64(); 11336 11337 gen_load_fpr64(ctx, fp0, fs); 11338 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11339 gen_store_fpr64(ctx, fp0, fd); 11340 tcg_temp_free_i64(fp0); 11341 } 11342 break; 11343 case OPC_CVT_PS_PW: 11344 check_ps(ctx); 11345 { 11346 TCGv_i64 fp0 = tcg_temp_new_i64(); 11347 11348 gen_load_fpr64(ctx, fp0, fs); 11349 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11350 gen_store_fpr64(ctx, fp0, fd); 11351 tcg_temp_free_i64(fp0); 11352 } 11353 break; 11354 case OPC_ADD_PS: 11355 check_ps(ctx); 11356 { 11357 TCGv_i64 fp0 = tcg_temp_new_i64(); 11358 TCGv_i64 fp1 = tcg_temp_new_i64(); 11359 11360 gen_load_fpr64(ctx, fp0, fs); 11361 gen_load_fpr64(ctx, fp1, ft); 11362 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11363 tcg_temp_free_i64(fp1); 11364 gen_store_fpr64(ctx, fp0, fd); 11365 tcg_temp_free_i64(fp0); 11366 } 11367 break; 11368 case OPC_SUB_PS: 11369 check_ps(ctx); 11370 { 11371 TCGv_i64 fp0 = tcg_temp_new_i64(); 11372 TCGv_i64 fp1 = tcg_temp_new_i64(); 11373 11374 gen_load_fpr64(ctx, fp0, fs); 11375 gen_load_fpr64(ctx, fp1, ft); 11376 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11377 tcg_temp_free_i64(fp1); 11378 gen_store_fpr64(ctx, fp0, fd); 11379 tcg_temp_free_i64(fp0); 11380 } 11381 break; 11382 case OPC_MUL_PS: 11383 check_ps(ctx); 11384 { 11385 TCGv_i64 fp0 = tcg_temp_new_i64(); 11386 TCGv_i64 fp1 = tcg_temp_new_i64(); 11387 11388 gen_load_fpr64(ctx, fp0, fs); 11389 gen_load_fpr64(ctx, fp1, ft); 11390 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11391 tcg_temp_free_i64(fp1); 11392 gen_store_fpr64(ctx, fp0, fd); 11393 tcg_temp_free_i64(fp0); 11394 } 11395 break; 11396 case OPC_ABS_PS: 11397 check_ps(ctx); 11398 { 11399 TCGv_i64 fp0 = tcg_temp_new_i64(); 11400 11401 gen_load_fpr64(ctx, fp0, fs); 11402 gen_helper_float_abs_ps(fp0, fp0); 11403 gen_store_fpr64(ctx, fp0, fd); 11404 tcg_temp_free_i64(fp0); 11405 } 11406 break; 11407 case OPC_MOV_PS: 11408 check_ps(ctx); 11409 { 11410 TCGv_i64 fp0 = tcg_temp_new_i64(); 11411 11412 gen_load_fpr64(ctx, fp0, fs); 11413 gen_store_fpr64(ctx, fp0, fd); 11414 tcg_temp_free_i64(fp0); 11415 } 11416 break; 11417 case OPC_NEG_PS: 11418 check_ps(ctx); 11419 { 11420 TCGv_i64 fp0 = tcg_temp_new_i64(); 11421 11422 gen_load_fpr64(ctx, fp0, fs); 11423 gen_helper_float_chs_ps(fp0, fp0); 11424 gen_store_fpr64(ctx, fp0, fd); 11425 tcg_temp_free_i64(fp0); 11426 } 11427 break; 11428 case OPC_MOVCF_PS: 11429 check_ps(ctx); 11430 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11431 break; 11432 case OPC_MOVZ_PS: 11433 check_ps(ctx); 11434 { 11435 TCGLabel *l1 = gen_new_label(); 11436 TCGv_i64 fp0; 11437 11438 if (ft != 0) { 11439 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11440 } 11441 fp0 = tcg_temp_new_i64(); 11442 gen_load_fpr64(ctx, fp0, fs); 11443 gen_store_fpr64(ctx, fp0, fd); 11444 tcg_temp_free_i64(fp0); 11445 gen_set_label(l1); 11446 } 11447 break; 11448 case OPC_MOVN_PS: 11449 check_ps(ctx); 11450 { 11451 TCGLabel *l1 = gen_new_label(); 11452 TCGv_i64 fp0; 11453 11454 if (ft != 0) { 11455 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11456 fp0 = tcg_temp_new_i64(); 11457 gen_load_fpr64(ctx, fp0, fs); 11458 gen_store_fpr64(ctx, fp0, fd); 11459 tcg_temp_free_i64(fp0); 11460 gen_set_label(l1); 11461 } 11462 } 11463 break; 11464 case OPC_ADDR_PS: 11465 check_ps(ctx); 11466 { 11467 TCGv_i64 fp0 = tcg_temp_new_i64(); 11468 TCGv_i64 fp1 = tcg_temp_new_i64(); 11469 11470 gen_load_fpr64(ctx, fp0, ft); 11471 gen_load_fpr64(ctx, fp1, fs); 11472 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11473 tcg_temp_free_i64(fp1); 11474 gen_store_fpr64(ctx, fp0, fd); 11475 tcg_temp_free_i64(fp0); 11476 } 11477 break; 11478 case OPC_MULR_PS: 11479 check_ps(ctx); 11480 { 11481 TCGv_i64 fp0 = tcg_temp_new_i64(); 11482 TCGv_i64 fp1 = tcg_temp_new_i64(); 11483 11484 gen_load_fpr64(ctx, fp0, ft); 11485 gen_load_fpr64(ctx, fp1, fs); 11486 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11487 tcg_temp_free_i64(fp1); 11488 gen_store_fpr64(ctx, fp0, fd); 11489 tcg_temp_free_i64(fp0); 11490 } 11491 break; 11492 case OPC_RECIP2_PS: 11493 check_ps(ctx); 11494 { 11495 TCGv_i64 fp0 = tcg_temp_new_i64(); 11496 TCGv_i64 fp1 = tcg_temp_new_i64(); 11497 11498 gen_load_fpr64(ctx, fp0, fs); 11499 gen_load_fpr64(ctx, fp1, ft); 11500 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11501 tcg_temp_free_i64(fp1); 11502 gen_store_fpr64(ctx, fp0, fd); 11503 tcg_temp_free_i64(fp0); 11504 } 11505 break; 11506 case OPC_RECIP1_PS: 11507 check_ps(ctx); 11508 { 11509 TCGv_i64 fp0 = tcg_temp_new_i64(); 11510 11511 gen_load_fpr64(ctx, fp0, fs); 11512 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11513 gen_store_fpr64(ctx, fp0, fd); 11514 tcg_temp_free_i64(fp0); 11515 } 11516 break; 11517 case OPC_RSQRT1_PS: 11518 check_ps(ctx); 11519 { 11520 TCGv_i64 fp0 = tcg_temp_new_i64(); 11521 11522 gen_load_fpr64(ctx, fp0, fs); 11523 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11524 gen_store_fpr64(ctx, fp0, fd); 11525 tcg_temp_free_i64(fp0); 11526 } 11527 break; 11528 case OPC_RSQRT2_PS: 11529 check_ps(ctx); 11530 { 11531 TCGv_i64 fp0 = tcg_temp_new_i64(); 11532 TCGv_i64 fp1 = tcg_temp_new_i64(); 11533 11534 gen_load_fpr64(ctx, fp0, fs); 11535 gen_load_fpr64(ctx, fp1, ft); 11536 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11537 tcg_temp_free_i64(fp1); 11538 gen_store_fpr64(ctx, fp0, fd); 11539 tcg_temp_free_i64(fp0); 11540 } 11541 break; 11542 case OPC_CVT_S_PU: 11543 check_cp1_64bitmode(ctx); 11544 { 11545 TCGv_i32 fp0 = tcg_temp_new_i32(); 11546 11547 gen_load_fpr32h(ctx, fp0, fs); 11548 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11549 gen_store_fpr32(ctx, fp0, fd); 11550 tcg_temp_free_i32(fp0); 11551 } 11552 break; 11553 case OPC_CVT_PW_PS: 11554 check_ps(ctx); 11555 { 11556 TCGv_i64 fp0 = tcg_temp_new_i64(); 11557 11558 gen_load_fpr64(ctx, fp0, fs); 11559 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11560 gen_store_fpr64(ctx, fp0, fd); 11561 tcg_temp_free_i64(fp0); 11562 } 11563 break; 11564 case OPC_CVT_S_PL: 11565 check_cp1_64bitmode(ctx); 11566 { 11567 TCGv_i32 fp0 = tcg_temp_new_i32(); 11568 11569 gen_load_fpr32(ctx, fp0, fs); 11570 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11571 gen_store_fpr32(ctx, fp0, fd); 11572 tcg_temp_free_i32(fp0); 11573 } 11574 break; 11575 case OPC_PLL_PS: 11576 check_ps(ctx); 11577 { 11578 TCGv_i32 fp0 = tcg_temp_new_i32(); 11579 TCGv_i32 fp1 = tcg_temp_new_i32(); 11580 11581 gen_load_fpr32(ctx, fp0, fs); 11582 gen_load_fpr32(ctx, fp1, ft); 11583 gen_store_fpr32h(ctx, fp0, fd); 11584 gen_store_fpr32(ctx, fp1, fd); 11585 tcg_temp_free_i32(fp0); 11586 tcg_temp_free_i32(fp1); 11587 } 11588 break; 11589 case OPC_PLU_PS: 11590 check_ps(ctx); 11591 { 11592 TCGv_i32 fp0 = tcg_temp_new_i32(); 11593 TCGv_i32 fp1 = tcg_temp_new_i32(); 11594 11595 gen_load_fpr32(ctx, fp0, fs); 11596 gen_load_fpr32h(ctx, fp1, ft); 11597 gen_store_fpr32(ctx, fp1, fd); 11598 gen_store_fpr32h(ctx, fp0, fd); 11599 tcg_temp_free_i32(fp0); 11600 tcg_temp_free_i32(fp1); 11601 } 11602 break; 11603 case OPC_PUL_PS: 11604 check_ps(ctx); 11605 { 11606 TCGv_i32 fp0 = tcg_temp_new_i32(); 11607 TCGv_i32 fp1 = tcg_temp_new_i32(); 11608 11609 gen_load_fpr32h(ctx, fp0, fs); 11610 gen_load_fpr32(ctx, fp1, ft); 11611 gen_store_fpr32(ctx, fp1, fd); 11612 gen_store_fpr32h(ctx, fp0, fd); 11613 tcg_temp_free_i32(fp0); 11614 tcg_temp_free_i32(fp1); 11615 } 11616 break; 11617 case OPC_PUU_PS: 11618 check_ps(ctx); 11619 { 11620 TCGv_i32 fp0 = tcg_temp_new_i32(); 11621 TCGv_i32 fp1 = tcg_temp_new_i32(); 11622 11623 gen_load_fpr32h(ctx, fp0, fs); 11624 gen_load_fpr32h(ctx, fp1, ft); 11625 gen_store_fpr32(ctx, fp1, fd); 11626 gen_store_fpr32h(ctx, fp0, fd); 11627 tcg_temp_free_i32(fp0); 11628 tcg_temp_free_i32(fp1); 11629 } 11630 break; 11631 case OPC_CMP_F_PS: 11632 case OPC_CMP_UN_PS: 11633 case OPC_CMP_EQ_PS: 11634 case OPC_CMP_UEQ_PS: 11635 case OPC_CMP_OLT_PS: 11636 case OPC_CMP_ULT_PS: 11637 case OPC_CMP_OLE_PS: 11638 case OPC_CMP_ULE_PS: 11639 case OPC_CMP_SF_PS: 11640 case OPC_CMP_NGLE_PS: 11641 case OPC_CMP_SEQ_PS: 11642 case OPC_CMP_NGL_PS: 11643 case OPC_CMP_LT_PS: 11644 case OPC_CMP_NGE_PS: 11645 case OPC_CMP_LE_PS: 11646 case OPC_CMP_NGT_PS: 11647 if (ctx->opcode & (1 << 6)) { 11648 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11649 } else { 11650 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11651 } 11652 break; 11653 default: 11654 MIPS_INVAL("farith"); 11655 gen_reserved_instruction(ctx); 11656 return; 11657 } 11658 } 11659 11660 /* Coprocessor 3 (FPU) */ 11661 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11662 int fd, int fs, int base, int index) 11663 { 11664 TCGv t0 = tcg_temp_new(); 11665 11666 if (base == 0) { 11667 gen_load_gpr(t0, index); 11668 } else if (index == 0) { 11669 gen_load_gpr(t0, base); 11670 } else { 11671 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11672 } 11673 /* 11674 * Don't do NOP if destination is zero: we must perform the actual 11675 * memory access. 11676 */ 11677 switch (opc) { 11678 case OPC_LWXC1: 11679 check_cop1x(ctx); 11680 { 11681 TCGv_i32 fp0 = tcg_temp_new_i32(); 11682 11683 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11684 tcg_gen_trunc_tl_i32(fp0, t0); 11685 gen_store_fpr32(ctx, fp0, fd); 11686 tcg_temp_free_i32(fp0); 11687 } 11688 break; 11689 case OPC_LDXC1: 11690 check_cop1x(ctx); 11691 check_cp1_registers(ctx, fd); 11692 { 11693 TCGv_i64 fp0 = tcg_temp_new_i64(); 11694 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11695 gen_store_fpr64(ctx, fp0, fd); 11696 tcg_temp_free_i64(fp0); 11697 } 11698 break; 11699 case OPC_LUXC1: 11700 check_cp1_64bitmode(ctx); 11701 tcg_gen_andi_tl(t0, t0, ~0x7); 11702 { 11703 TCGv_i64 fp0 = tcg_temp_new_i64(); 11704 11705 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11706 gen_store_fpr64(ctx, fp0, fd); 11707 tcg_temp_free_i64(fp0); 11708 } 11709 break; 11710 case OPC_SWXC1: 11711 check_cop1x(ctx); 11712 { 11713 TCGv_i32 fp0 = tcg_temp_new_i32(); 11714 gen_load_fpr32(ctx, fp0, fs); 11715 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11716 tcg_temp_free_i32(fp0); 11717 } 11718 break; 11719 case OPC_SDXC1: 11720 check_cop1x(ctx); 11721 check_cp1_registers(ctx, fs); 11722 { 11723 TCGv_i64 fp0 = tcg_temp_new_i64(); 11724 gen_load_fpr64(ctx, fp0, fs); 11725 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11726 tcg_temp_free_i64(fp0); 11727 } 11728 break; 11729 case OPC_SUXC1: 11730 check_cp1_64bitmode(ctx); 11731 tcg_gen_andi_tl(t0, t0, ~0x7); 11732 { 11733 TCGv_i64 fp0 = tcg_temp_new_i64(); 11734 gen_load_fpr64(ctx, fp0, fs); 11735 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11736 tcg_temp_free_i64(fp0); 11737 } 11738 break; 11739 } 11740 tcg_temp_free(t0); 11741 } 11742 11743 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11744 int fd, int fr, int fs, int ft) 11745 { 11746 switch (opc) { 11747 case OPC_ALNV_PS: 11748 check_ps(ctx); 11749 { 11750 TCGv t0 = tcg_temp_local_new(); 11751 TCGv_i32 fp = tcg_temp_new_i32(); 11752 TCGv_i32 fph = tcg_temp_new_i32(); 11753 TCGLabel *l1 = gen_new_label(); 11754 TCGLabel *l2 = gen_new_label(); 11755 11756 gen_load_gpr(t0, fr); 11757 tcg_gen_andi_tl(t0, t0, 0x7); 11758 11759 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11760 gen_load_fpr32(ctx, fp, fs); 11761 gen_load_fpr32h(ctx, fph, fs); 11762 gen_store_fpr32(ctx, fp, fd); 11763 gen_store_fpr32h(ctx, fph, fd); 11764 tcg_gen_br(l2); 11765 gen_set_label(l1); 11766 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11767 tcg_temp_free(t0); 11768 #ifdef TARGET_WORDS_BIGENDIAN 11769 gen_load_fpr32(ctx, fp, fs); 11770 gen_load_fpr32h(ctx, fph, ft); 11771 gen_store_fpr32h(ctx, fp, fd); 11772 gen_store_fpr32(ctx, fph, fd); 11773 #else 11774 gen_load_fpr32h(ctx, fph, fs); 11775 gen_load_fpr32(ctx, fp, ft); 11776 gen_store_fpr32(ctx, fph, fd); 11777 gen_store_fpr32h(ctx, fp, fd); 11778 #endif 11779 gen_set_label(l2); 11780 tcg_temp_free_i32(fp); 11781 tcg_temp_free_i32(fph); 11782 } 11783 break; 11784 case OPC_MADD_S: 11785 check_cop1x(ctx); 11786 { 11787 TCGv_i32 fp0 = tcg_temp_new_i32(); 11788 TCGv_i32 fp1 = tcg_temp_new_i32(); 11789 TCGv_i32 fp2 = tcg_temp_new_i32(); 11790 11791 gen_load_fpr32(ctx, fp0, fs); 11792 gen_load_fpr32(ctx, fp1, ft); 11793 gen_load_fpr32(ctx, fp2, fr); 11794 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11795 tcg_temp_free_i32(fp0); 11796 tcg_temp_free_i32(fp1); 11797 gen_store_fpr32(ctx, fp2, fd); 11798 tcg_temp_free_i32(fp2); 11799 } 11800 break; 11801 case OPC_MADD_D: 11802 check_cop1x(ctx); 11803 check_cp1_registers(ctx, fd | fs | ft | fr); 11804 { 11805 TCGv_i64 fp0 = tcg_temp_new_i64(); 11806 TCGv_i64 fp1 = tcg_temp_new_i64(); 11807 TCGv_i64 fp2 = tcg_temp_new_i64(); 11808 11809 gen_load_fpr64(ctx, fp0, fs); 11810 gen_load_fpr64(ctx, fp1, ft); 11811 gen_load_fpr64(ctx, fp2, fr); 11812 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11813 tcg_temp_free_i64(fp0); 11814 tcg_temp_free_i64(fp1); 11815 gen_store_fpr64(ctx, fp2, fd); 11816 tcg_temp_free_i64(fp2); 11817 } 11818 break; 11819 case OPC_MADD_PS: 11820 check_ps(ctx); 11821 { 11822 TCGv_i64 fp0 = tcg_temp_new_i64(); 11823 TCGv_i64 fp1 = tcg_temp_new_i64(); 11824 TCGv_i64 fp2 = tcg_temp_new_i64(); 11825 11826 gen_load_fpr64(ctx, fp0, fs); 11827 gen_load_fpr64(ctx, fp1, ft); 11828 gen_load_fpr64(ctx, fp2, fr); 11829 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11830 tcg_temp_free_i64(fp0); 11831 tcg_temp_free_i64(fp1); 11832 gen_store_fpr64(ctx, fp2, fd); 11833 tcg_temp_free_i64(fp2); 11834 } 11835 break; 11836 case OPC_MSUB_S: 11837 check_cop1x(ctx); 11838 { 11839 TCGv_i32 fp0 = tcg_temp_new_i32(); 11840 TCGv_i32 fp1 = tcg_temp_new_i32(); 11841 TCGv_i32 fp2 = tcg_temp_new_i32(); 11842 11843 gen_load_fpr32(ctx, fp0, fs); 11844 gen_load_fpr32(ctx, fp1, ft); 11845 gen_load_fpr32(ctx, fp2, fr); 11846 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11847 tcg_temp_free_i32(fp0); 11848 tcg_temp_free_i32(fp1); 11849 gen_store_fpr32(ctx, fp2, fd); 11850 tcg_temp_free_i32(fp2); 11851 } 11852 break; 11853 case OPC_MSUB_D: 11854 check_cop1x(ctx); 11855 check_cp1_registers(ctx, fd | fs | ft | fr); 11856 { 11857 TCGv_i64 fp0 = tcg_temp_new_i64(); 11858 TCGv_i64 fp1 = tcg_temp_new_i64(); 11859 TCGv_i64 fp2 = tcg_temp_new_i64(); 11860 11861 gen_load_fpr64(ctx, fp0, fs); 11862 gen_load_fpr64(ctx, fp1, ft); 11863 gen_load_fpr64(ctx, fp2, fr); 11864 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11865 tcg_temp_free_i64(fp0); 11866 tcg_temp_free_i64(fp1); 11867 gen_store_fpr64(ctx, fp2, fd); 11868 tcg_temp_free_i64(fp2); 11869 } 11870 break; 11871 case OPC_MSUB_PS: 11872 check_ps(ctx); 11873 { 11874 TCGv_i64 fp0 = tcg_temp_new_i64(); 11875 TCGv_i64 fp1 = tcg_temp_new_i64(); 11876 TCGv_i64 fp2 = tcg_temp_new_i64(); 11877 11878 gen_load_fpr64(ctx, fp0, fs); 11879 gen_load_fpr64(ctx, fp1, ft); 11880 gen_load_fpr64(ctx, fp2, fr); 11881 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11882 tcg_temp_free_i64(fp0); 11883 tcg_temp_free_i64(fp1); 11884 gen_store_fpr64(ctx, fp2, fd); 11885 tcg_temp_free_i64(fp2); 11886 } 11887 break; 11888 case OPC_NMADD_S: 11889 check_cop1x(ctx); 11890 { 11891 TCGv_i32 fp0 = tcg_temp_new_i32(); 11892 TCGv_i32 fp1 = tcg_temp_new_i32(); 11893 TCGv_i32 fp2 = tcg_temp_new_i32(); 11894 11895 gen_load_fpr32(ctx, fp0, fs); 11896 gen_load_fpr32(ctx, fp1, ft); 11897 gen_load_fpr32(ctx, fp2, fr); 11898 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11899 tcg_temp_free_i32(fp0); 11900 tcg_temp_free_i32(fp1); 11901 gen_store_fpr32(ctx, fp2, fd); 11902 tcg_temp_free_i32(fp2); 11903 } 11904 break; 11905 case OPC_NMADD_D: 11906 check_cop1x(ctx); 11907 check_cp1_registers(ctx, fd | fs | ft | fr); 11908 { 11909 TCGv_i64 fp0 = tcg_temp_new_i64(); 11910 TCGv_i64 fp1 = tcg_temp_new_i64(); 11911 TCGv_i64 fp2 = tcg_temp_new_i64(); 11912 11913 gen_load_fpr64(ctx, fp0, fs); 11914 gen_load_fpr64(ctx, fp1, ft); 11915 gen_load_fpr64(ctx, fp2, fr); 11916 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11917 tcg_temp_free_i64(fp0); 11918 tcg_temp_free_i64(fp1); 11919 gen_store_fpr64(ctx, fp2, fd); 11920 tcg_temp_free_i64(fp2); 11921 } 11922 break; 11923 case OPC_NMADD_PS: 11924 check_ps(ctx); 11925 { 11926 TCGv_i64 fp0 = tcg_temp_new_i64(); 11927 TCGv_i64 fp1 = tcg_temp_new_i64(); 11928 TCGv_i64 fp2 = tcg_temp_new_i64(); 11929 11930 gen_load_fpr64(ctx, fp0, fs); 11931 gen_load_fpr64(ctx, fp1, ft); 11932 gen_load_fpr64(ctx, fp2, fr); 11933 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11934 tcg_temp_free_i64(fp0); 11935 tcg_temp_free_i64(fp1); 11936 gen_store_fpr64(ctx, fp2, fd); 11937 tcg_temp_free_i64(fp2); 11938 } 11939 break; 11940 case OPC_NMSUB_S: 11941 check_cop1x(ctx); 11942 { 11943 TCGv_i32 fp0 = tcg_temp_new_i32(); 11944 TCGv_i32 fp1 = tcg_temp_new_i32(); 11945 TCGv_i32 fp2 = tcg_temp_new_i32(); 11946 11947 gen_load_fpr32(ctx, fp0, fs); 11948 gen_load_fpr32(ctx, fp1, ft); 11949 gen_load_fpr32(ctx, fp2, fr); 11950 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11951 tcg_temp_free_i32(fp0); 11952 tcg_temp_free_i32(fp1); 11953 gen_store_fpr32(ctx, fp2, fd); 11954 tcg_temp_free_i32(fp2); 11955 } 11956 break; 11957 case OPC_NMSUB_D: 11958 check_cop1x(ctx); 11959 check_cp1_registers(ctx, fd | fs | ft | fr); 11960 { 11961 TCGv_i64 fp0 = tcg_temp_new_i64(); 11962 TCGv_i64 fp1 = tcg_temp_new_i64(); 11963 TCGv_i64 fp2 = tcg_temp_new_i64(); 11964 11965 gen_load_fpr64(ctx, fp0, fs); 11966 gen_load_fpr64(ctx, fp1, ft); 11967 gen_load_fpr64(ctx, fp2, fr); 11968 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11969 tcg_temp_free_i64(fp0); 11970 tcg_temp_free_i64(fp1); 11971 gen_store_fpr64(ctx, fp2, fd); 11972 tcg_temp_free_i64(fp2); 11973 } 11974 break; 11975 case OPC_NMSUB_PS: 11976 check_ps(ctx); 11977 { 11978 TCGv_i64 fp0 = tcg_temp_new_i64(); 11979 TCGv_i64 fp1 = tcg_temp_new_i64(); 11980 TCGv_i64 fp2 = tcg_temp_new_i64(); 11981 11982 gen_load_fpr64(ctx, fp0, fs); 11983 gen_load_fpr64(ctx, fp1, ft); 11984 gen_load_fpr64(ctx, fp2, fr); 11985 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11986 tcg_temp_free_i64(fp0); 11987 tcg_temp_free_i64(fp1); 11988 gen_store_fpr64(ctx, fp2, fd); 11989 tcg_temp_free_i64(fp2); 11990 } 11991 break; 11992 default: 11993 MIPS_INVAL("flt3_arith"); 11994 gen_reserved_instruction(ctx); 11995 return; 11996 } 11997 } 11998 11999 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 12000 { 12001 TCGv t0; 12002 12003 #if !defined(CONFIG_USER_ONLY) 12004 /* 12005 * The Linux kernel will emulate rdhwr if it's not supported natively. 12006 * Therefore only check the ISA in system mode. 12007 */ 12008 check_insn(ctx, ISA_MIPS_R2); 12009 #endif 12010 t0 = tcg_temp_new(); 12011 12012 switch (rd) { 12013 case 0: 12014 gen_helper_rdhwr_cpunum(t0, cpu_env); 12015 gen_store_gpr(t0, rt); 12016 break; 12017 case 1: 12018 gen_helper_rdhwr_synci_step(t0, cpu_env); 12019 gen_store_gpr(t0, rt); 12020 break; 12021 case 2: 12022 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 12023 gen_io_start(); 12024 } 12025 gen_helper_rdhwr_cc(t0, cpu_env); 12026 gen_store_gpr(t0, rt); 12027 /* 12028 * Break the TB to be able to take timer interrupts immediately 12029 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 12030 * we break completely out of translated code. 12031 */ 12032 gen_save_pc(ctx->base.pc_next + 4); 12033 ctx->base.is_jmp = DISAS_EXIT; 12034 break; 12035 case 3: 12036 gen_helper_rdhwr_ccres(t0, cpu_env); 12037 gen_store_gpr(t0, rt); 12038 break; 12039 case 4: 12040 check_insn(ctx, ISA_MIPS_R6); 12041 if (sel != 0) { 12042 /* 12043 * Performance counter registers are not implemented other than 12044 * control register 0. 12045 */ 12046 generate_exception(ctx, EXCP_RI); 12047 } 12048 gen_helper_rdhwr_performance(t0, cpu_env); 12049 gen_store_gpr(t0, rt); 12050 break; 12051 case 5: 12052 check_insn(ctx, ISA_MIPS_R6); 12053 gen_helper_rdhwr_xnp(t0, cpu_env); 12054 gen_store_gpr(t0, rt); 12055 break; 12056 case 29: 12057 #if defined(CONFIG_USER_ONLY) 12058 tcg_gen_ld_tl(t0, cpu_env, 12059 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 12060 gen_store_gpr(t0, rt); 12061 break; 12062 #else 12063 if ((ctx->hflags & MIPS_HFLAG_CP0) || 12064 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 12065 tcg_gen_ld_tl(t0, cpu_env, 12066 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 12067 gen_store_gpr(t0, rt); 12068 } else { 12069 gen_reserved_instruction(ctx); 12070 } 12071 break; 12072 #endif 12073 default: /* Invalid */ 12074 MIPS_INVAL("rdhwr"); 12075 gen_reserved_instruction(ctx); 12076 break; 12077 } 12078 tcg_temp_free(t0); 12079 } 12080 12081 static inline void clear_branch_hflags(DisasContext *ctx) 12082 { 12083 ctx->hflags &= ~MIPS_HFLAG_BMASK; 12084 if (ctx->base.is_jmp == DISAS_NEXT) { 12085 save_cpu_state(ctx, 0); 12086 } else { 12087 /* 12088 * It is not safe to save ctx->hflags as hflags may be changed 12089 * in execution time by the instruction in delay / forbidden slot. 12090 */ 12091 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 12092 } 12093 } 12094 12095 static void gen_branch(DisasContext *ctx, int insn_bytes) 12096 { 12097 if (ctx->hflags & MIPS_HFLAG_BMASK) { 12098 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 12099 /* Branches completion */ 12100 clear_branch_hflags(ctx); 12101 ctx->base.is_jmp = DISAS_NORETURN; 12102 /* FIXME: Need to clear can_do_io. */ 12103 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 12104 case MIPS_HFLAG_FBNSLOT: 12105 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 12106 break; 12107 case MIPS_HFLAG_B: 12108 /* unconditional branch */ 12109 if (proc_hflags & MIPS_HFLAG_BX) { 12110 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 12111 } 12112 gen_goto_tb(ctx, 0, ctx->btarget); 12113 break; 12114 case MIPS_HFLAG_BL: 12115 /* blikely taken case */ 12116 gen_goto_tb(ctx, 0, ctx->btarget); 12117 break; 12118 case MIPS_HFLAG_BC: 12119 /* Conditional branch */ 12120 { 12121 TCGLabel *l1 = gen_new_label(); 12122 12123 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 12124 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 12125 gen_set_label(l1); 12126 gen_goto_tb(ctx, 0, ctx->btarget); 12127 } 12128 break; 12129 case MIPS_HFLAG_BR: 12130 /* unconditional branch to register */ 12131 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 12132 TCGv t0 = tcg_temp_new(); 12133 TCGv_i32 t1 = tcg_temp_new_i32(); 12134 12135 tcg_gen_andi_tl(t0, btarget, 0x1); 12136 tcg_gen_trunc_tl_i32(t1, t0); 12137 tcg_temp_free(t0); 12138 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 12139 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 12140 tcg_gen_or_i32(hflags, hflags, t1); 12141 tcg_temp_free_i32(t1); 12142 12143 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 12144 } else { 12145 tcg_gen_mov_tl(cpu_PC, btarget); 12146 } 12147 if (ctx->base.singlestep_enabled) { 12148 save_cpu_state(ctx, 0); 12149 gen_helper_raise_exception_debug(cpu_env); 12150 } 12151 tcg_gen_lookup_and_goto_ptr(); 12152 break; 12153 default: 12154 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); 12155 abort(); 12156 } 12157 } 12158 } 12159 12160 /* Compact Branches */ 12161 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 12162 int rs, int rt, int32_t offset) 12163 { 12164 int bcond_compute = 0; 12165 TCGv t0 = tcg_temp_new(); 12166 TCGv t1 = tcg_temp_new(); 12167 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 12168 12169 if (ctx->hflags & MIPS_HFLAG_BMASK) { 12170 #ifdef MIPS_DEBUG_DISAS 12171 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 12172 "\n", ctx->base.pc_next); 12173 #endif 12174 gen_reserved_instruction(ctx); 12175 goto out; 12176 } 12177 12178 /* Load needed operands and calculate btarget */ 12179 switch (opc) { 12180 /* compact branch */ 12181 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 12182 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 12183 gen_load_gpr(t0, rs); 12184 gen_load_gpr(t1, rt); 12185 bcond_compute = 1; 12186 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12187 if (rs <= rt && rs == 0) { 12188 /* OPC_BEQZALC, OPC_BNEZALC */ 12189 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12190 } 12191 break; 12192 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 12193 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 12194 gen_load_gpr(t0, rs); 12195 gen_load_gpr(t1, rt); 12196 bcond_compute = 1; 12197 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12198 break; 12199 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 12200 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12201 if (rs == 0 || rs == rt) { 12202 /* OPC_BLEZALC, OPC_BGEZALC */ 12203 /* OPC_BGTZALC, OPC_BLTZALC */ 12204 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12205 } 12206 gen_load_gpr(t0, rs); 12207 gen_load_gpr(t1, rt); 12208 bcond_compute = 1; 12209 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12210 break; 12211 case OPC_BC: 12212 case OPC_BALC: 12213 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12214 break; 12215 case OPC_BEQZC: 12216 case OPC_BNEZC: 12217 if (rs != 0) { 12218 /* OPC_BEQZC, OPC_BNEZC */ 12219 gen_load_gpr(t0, rs); 12220 bcond_compute = 1; 12221 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12222 } else { 12223 /* OPC_JIC, OPC_JIALC */ 12224 TCGv tbase = tcg_temp_new(); 12225 TCGv toffset = tcg_temp_new(); 12226 12227 gen_load_gpr(tbase, rt); 12228 tcg_gen_movi_tl(toffset, offset); 12229 gen_op_addr_add(ctx, btarget, tbase, toffset); 12230 tcg_temp_free(tbase); 12231 tcg_temp_free(toffset); 12232 } 12233 break; 12234 default: 12235 MIPS_INVAL("Compact branch/jump"); 12236 gen_reserved_instruction(ctx); 12237 goto out; 12238 } 12239 12240 if (bcond_compute == 0) { 12241 /* Uncoditional compact branch */ 12242 switch (opc) { 12243 case OPC_JIALC: 12244 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12245 /* Fallthrough */ 12246 case OPC_JIC: 12247 ctx->hflags |= MIPS_HFLAG_BR; 12248 break; 12249 case OPC_BALC: 12250 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12251 /* Fallthrough */ 12252 case OPC_BC: 12253 ctx->hflags |= MIPS_HFLAG_B; 12254 break; 12255 default: 12256 MIPS_INVAL("Compact branch/jump"); 12257 gen_reserved_instruction(ctx); 12258 goto out; 12259 } 12260 12261 /* Generating branch here as compact branches don't have delay slot */ 12262 gen_branch(ctx, 4); 12263 } else { 12264 /* Conditional compact branch */ 12265 TCGLabel *fs = gen_new_label(); 12266 save_cpu_state(ctx, 0); 12267 12268 switch (opc) { 12269 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 12270 if (rs == 0 && rt != 0) { 12271 /* OPC_BLEZALC */ 12272 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12273 } else if (rs != 0 && rt != 0 && rs == rt) { 12274 /* OPC_BGEZALC */ 12275 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12276 } else { 12277 /* OPC_BGEUC */ 12278 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 12279 } 12280 break; 12281 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12282 if (rs == 0 && rt != 0) { 12283 /* OPC_BGTZALC */ 12284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12285 } else if (rs != 0 && rt != 0 && rs == rt) { 12286 /* OPC_BLTZALC */ 12287 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12288 } else { 12289 /* OPC_BLTUC */ 12290 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 12291 } 12292 break; 12293 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 12294 if (rs == 0 && rt != 0) { 12295 /* OPC_BLEZC */ 12296 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12297 } else if (rs != 0 && rt != 0 && rs == rt) { 12298 /* OPC_BGEZC */ 12299 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12300 } else { 12301 /* OPC_BGEC */ 12302 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 12303 } 12304 break; 12305 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 12306 if (rs == 0 && rt != 0) { 12307 /* OPC_BGTZC */ 12308 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12309 } else if (rs != 0 && rt != 0 && rs == rt) { 12310 /* OPC_BLTZC */ 12311 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12312 } else { 12313 /* OPC_BLTC */ 12314 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 12315 } 12316 break; 12317 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 12318 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 12319 if (rs >= rt) { 12320 /* OPC_BOVC, OPC_BNVC */ 12321 TCGv t2 = tcg_temp_new(); 12322 TCGv t3 = tcg_temp_new(); 12323 TCGv t4 = tcg_temp_new(); 12324 TCGv input_overflow = tcg_temp_new(); 12325 12326 gen_load_gpr(t0, rs); 12327 gen_load_gpr(t1, rt); 12328 tcg_gen_ext32s_tl(t2, t0); 12329 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 12330 tcg_gen_ext32s_tl(t3, t1); 12331 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 12332 tcg_gen_or_tl(input_overflow, input_overflow, t4); 12333 12334 tcg_gen_add_tl(t4, t2, t3); 12335 tcg_gen_ext32s_tl(t4, t4); 12336 tcg_gen_xor_tl(t2, t2, t3); 12337 tcg_gen_xor_tl(t3, t4, t3); 12338 tcg_gen_andc_tl(t2, t3, t2); 12339 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 12340 tcg_gen_or_tl(t4, t4, input_overflow); 12341 if (opc == OPC_BOVC) { 12342 /* OPC_BOVC */ 12343 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12344 } else { 12345 /* OPC_BNVC */ 12346 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12347 } 12348 tcg_temp_free(input_overflow); 12349 tcg_temp_free(t4); 12350 tcg_temp_free(t3); 12351 tcg_temp_free(t2); 12352 } else if (rs < rt && rs == 0) { 12353 /* OPC_BEQZALC, OPC_BNEZALC */ 12354 if (opc == OPC_BEQZALC) { 12355 /* OPC_BEQZALC */ 12356 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12357 } else { 12358 /* OPC_BNEZALC */ 12359 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12360 } 12361 } else { 12362 /* OPC_BEQC, OPC_BNEC */ 12363 if (opc == OPC_BEQC) { 12364 /* OPC_BEQC */ 12365 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12366 } else { 12367 /* OPC_BNEC */ 12368 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12369 } 12370 } 12371 break; 12372 case OPC_BEQZC: 12373 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12374 break; 12375 case OPC_BNEZC: 12376 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12377 break; 12378 default: 12379 MIPS_INVAL("Compact conditional branch/jump"); 12380 gen_reserved_instruction(ctx); 12381 goto out; 12382 } 12383 12384 /* Generating branch here as compact branches don't have delay slot */ 12385 gen_goto_tb(ctx, 1, ctx->btarget); 12386 gen_set_label(fs); 12387 12388 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12389 } 12390 12391 out: 12392 tcg_temp_free(t0); 12393 tcg_temp_free(t1); 12394 } 12395 12396 /* ISA extensions (ASEs) */ 12397 /* MIPS16 extension to MIPS32 */ 12398 12399 /* MIPS16 major opcodes */ 12400 enum { 12401 M16_OPC_ADDIUSP = 0x00, 12402 M16_OPC_ADDIUPC = 0x01, 12403 M16_OPC_B = 0x02, 12404 M16_OPC_JAL = 0x03, 12405 M16_OPC_BEQZ = 0x04, 12406 M16_OPC_BNEQZ = 0x05, 12407 M16_OPC_SHIFT = 0x06, 12408 M16_OPC_LD = 0x07, 12409 M16_OPC_RRIA = 0x08, 12410 M16_OPC_ADDIU8 = 0x09, 12411 M16_OPC_SLTI = 0x0a, 12412 M16_OPC_SLTIU = 0x0b, 12413 M16_OPC_I8 = 0x0c, 12414 M16_OPC_LI = 0x0d, 12415 M16_OPC_CMPI = 0x0e, 12416 M16_OPC_SD = 0x0f, 12417 M16_OPC_LB = 0x10, 12418 M16_OPC_LH = 0x11, 12419 M16_OPC_LWSP = 0x12, 12420 M16_OPC_LW = 0x13, 12421 M16_OPC_LBU = 0x14, 12422 M16_OPC_LHU = 0x15, 12423 M16_OPC_LWPC = 0x16, 12424 M16_OPC_LWU = 0x17, 12425 M16_OPC_SB = 0x18, 12426 M16_OPC_SH = 0x19, 12427 M16_OPC_SWSP = 0x1a, 12428 M16_OPC_SW = 0x1b, 12429 M16_OPC_RRR = 0x1c, 12430 M16_OPC_RR = 0x1d, 12431 M16_OPC_EXTEND = 0x1e, 12432 M16_OPC_I64 = 0x1f 12433 }; 12434 12435 /* I8 funct field */ 12436 enum { 12437 I8_BTEQZ = 0x0, 12438 I8_BTNEZ = 0x1, 12439 I8_SWRASP = 0x2, 12440 I8_ADJSP = 0x3, 12441 I8_SVRS = 0x4, 12442 I8_MOV32R = 0x5, 12443 I8_MOVR32 = 0x7 12444 }; 12445 12446 /* RRR f field */ 12447 enum { 12448 RRR_DADDU = 0x0, 12449 RRR_ADDU = 0x1, 12450 RRR_DSUBU = 0x2, 12451 RRR_SUBU = 0x3 12452 }; 12453 12454 /* RR funct field */ 12455 enum { 12456 RR_JR = 0x00, 12457 RR_SDBBP = 0x01, 12458 RR_SLT = 0x02, 12459 RR_SLTU = 0x03, 12460 RR_SLLV = 0x04, 12461 RR_BREAK = 0x05, 12462 RR_SRLV = 0x06, 12463 RR_SRAV = 0x07, 12464 RR_DSRL = 0x08, 12465 RR_CMP = 0x0a, 12466 RR_NEG = 0x0b, 12467 RR_AND = 0x0c, 12468 RR_OR = 0x0d, 12469 RR_XOR = 0x0e, 12470 RR_NOT = 0x0f, 12471 RR_MFHI = 0x10, 12472 RR_CNVT = 0x11, 12473 RR_MFLO = 0x12, 12474 RR_DSRA = 0x13, 12475 RR_DSLLV = 0x14, 12476 RR_DSRLV = 0x16, 12477 RR_DSRAV = 0x17, 12478 RR_MULT = 0x18, 12479 RR_MULTU = 0x19, 12480 RR_DIV = 0x1a, 12481 RR_DIVU = 0x1b, 12482 RR_DMULT = 0x1c, 12483 RR_DMULTU = 0x1d, 12484 RR_DDIV = 0x1e, 12485 RR_DDIVU = 0x1f 12486 }; 12487 12488 /* I64 funct field */ 12489 enum { 12490 I64_LDSP = 0x0, 12491 I64_SDSP = 0x1, 12492 I64_SDRASP = 0x2, 12493 I64_DADJSP = 0x3, 12494 I64_LDPC = 0x4, 12495 I64_DADDIU5 = 0x5, 12496 I64_DADDIUPC = 0x6, 12497 I64_DADDIUSP = 0x7 12498 }; 12499 12500 /* RR ry field for CNVT */ 12501 enum { 12502 RR_RY_CNVT_ZEB = 0x0, 12503 RR_RY_CNVT_ZEH = 0x1, 12504 RR_RY_CNVT_ZEW = 0x2, 12505 RR_RY_CNVT_SEB = 0x4, 12506 RR_RY_CNVT_SEH = 0x5, 12507 RR_RY_CNVT_SEW = 0x6, 12508 }; 12509 12510 static int xlat(int r) 12511 { 12512 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; 12513 12514 return map[r]; 12515 } 12516 12517 static void gen_mips16_save(DisasContext *ctx, 12518 int xsregs, int aregs, 12519 int do_ra, int do_s0, int do_s1, 12520 int framesize) 12521 { 12522 TCGv t0 = tcg_temp_new(); 12523 TCGv t1 = tcg_temp_new(); 12524 TCGv t2 = tcg_temp_new(); 12525 int args, astatic; 12526 12527 switch (aregs) { 12528 case 0: 12529 case 1: 12530 case 2: 12531 case 3: 12532 case 11: 12533 args = 0; 12534 break; 12535 case 4: 12536 case 5: 12537 case 6: 12538 case 7: 12539 args = 1; 12540 break; 12541 case 8: 12542 case 9: 12543 case 10: 12544 args = 2; 12545 break; 12546 case 12: 12547 case 13: 12548 args = 3; 12549 break; 12550 case 14: 12551 args = 4; 12552 break; 12553 default: 12554 gen_reserved_instruction(ctx); 12555 return; 12556 } 12557 12558 switch (args) { 12559 case 4: 12560 gen_base_offset_addr(ctx, t0, 29, 12); 12561 gen_load_gpr(t1, 7); 12562 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 12563 /* Fall through */ 12564 case 3: 12565 gen_base_offset_addr(ctx, t0, 29, 8); 12566 gen_load_gpr(t1, 6); 12567 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 12568 /* Fall through */ 12569 case 2: 12570 gen_base_offset_addr(ctx, t0, 29, 4); 12571 gen_load_gpr(t1, 5); 12572 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 12573 /* Fall through */ 12574 case 1: 12575 gen_base_offset_addr(ctx, t0, 29, 0); 12576 gen_load_gpr(t1, 4); 12577 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 12578 } 12579 12580 gen_load_gpr(t0, 29); 12581 12582 #define DECR_AND_STORE(reg) do { \ 12583 tcg_gen_movi_tl(t2, -4); \ 12584 gen_op_addr_add(ctx, t0, t0, t2); \ 12585 gen_load_gpr(t1, reg); \ 12586 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \ 12587 } while (0) 12588 12589 if (do_ra) { 12590 DECR_AND_STORE(31); 12591 } 12592 12593 switch (xsregs) { 12594 case 7: 12595 DECR_AND_STORE(30); 12596 /* Fall through */ 12597 case 6: 12598 DECR_AND_STORE(23); 12599 /* Fall through */ 12600 case 5: 12601 DECR_AND_STORE(22); 12602 /* Fall through */ 12603 case 4: 12604 DECR_AND_STORE(21); 12605 /* Fall through */ 12606 case 3: 12607 DECR_AND_STORE(20); 12608 /* Fall through */ 12609 case 2: 12610 DECR_AND_STORE(19); 12611 /* Fall through */ 12612 case 1: 12613 DECR_AND_STORE(18); 12614 } 12615 12616 if (do_s1) { 12617 DECR_AND_STORE(17); 12618 } 12619 if (do_s0) { 12620 DECR_AND_STORE(16); 12621 } 12622 12623 switch (aregs) { 12624 case 0: 12625 case 4: 12626 case 8: 12627 case 12: 12628 case 14: 12629 astatic = 0; 12630 break; 12631 case 1: 12632 case 5: 12633 case 9: 12634 case 13: 12635 astatic = 1; 12636 break; 12637 case 2: 12638 case 6: 12639 case 10: 12640 astatic = 2; 12641 break; 12642 case 3: 12643 case 7: 12644 astatic = 3; 12645 break; 12646 case 11: 12647 astatic = 4; 12648 break; 12649 default: 12650 gen_reserved_instruction(ctx); 12651 return; 12652 } 12653 12654 if (astatic > 0) { 12655 DECR_AND_STORE(7); 12656 if (astatic > 1) { 12657 DECR_AND_STORE(6); 12658 if (astatic > 2) { 12659 DECR_AND_STORE(5); 12660 if (astatic > 3) { 12661 DECR_AND_STORE(4); 12662 } 12663 } 12664 } 12665 } 12666 #undef DECR_AND_STORE 12667 12668 tcg_gen_movi_tl(t2, -framesize); 12669 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); 12670 tcg_temp_free(t0); 12671 tcg_temp_free(t1); 12672 tcg_temp_free(t2); 12673 } 12674 12675 static void gen_mips16_restore(DisasContext *ctx, 12676 int xsregs, int aregs, 12677 int do_ra, int do_s0, int do_s1, 12678 int framesize) 12679 { 12680 int astatic; 12681 TCGv t0 = tcg_temp_new(); 12682 TCGv t1 = tcg_temp_new(); 12683 TCGv t2 = tcg_temp_new(); 12684 12685 tcg_gen_movi_tl(t2, framesize); 12686 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2); 12687 12688 #define DECR_AND_LOAD(reg) do { \ 12689 tcg_gen_movi_tl(t2, -4); \ 12690 gen_op_addr_add(ctx, t0, t0, t2); \ 12691 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \ 12692 gen_store_gpr(t1, reg); \ 12693 } while (0) 12694 12695 if (do_ra) { 12696 DECR_AND_LOAD(31); 12697 } 12698 12699 switch (xsregs) { 12700 case 7: 12701 DECR_AND_LOAD(30); 12702 /* Fall through */ 12703 case 6: 12704 DECR_AND_LOAD(23); 12705 /* Fall through */ 12706 case 5: 12707 DECR_AND_LOAD(22); 12708 /* Fall through */ 12709 case 4: 12710 DECR_AND_LOAD(21); 12711 /* Fall through */ 12712 case 3: 12713 DECR_AND_LOAD(20); 12714 /* Fall through */ 12715 case 2: 12716 DECR_AND_LOAD(19); 12717 /* Fall through */ 12718 case 1: 12719 DECR_AND_LOAD(18); 12720 } 12721 12722 if (do_s1) { 12723 DECR_AND_LOAD(17); 12724 } 12725 if (do_s0) { 12726 DECR_AND_LOAD(16); 12727 } 12728 12729 switch (aregs) { 12730 case 0: 12731 case 4: 12732 case 8: 12733 case 12: 12734 case 14: 12735 astatic = 0; 12736 break; 12737 case 1: 12738 case 5: 12739 case 9: 12740 case 13: 12741 astatic = 1; 12742 break; 12743 case 2: 12744 case 6: 12745 case 10: 12746 astatic = 2; 12747 break; 12748 case 3: 12749 case 7: 12750 astatic = 3; 12751 break; 12752 case 11: 12753 astatic = 4; 12754 break; 12755 default: 12756 gen_reserved_instruction(ctx); 12757 return; 12758 } 12759 12760 if (astatic > 0) { 12761 DECR_AND_LOAD(7); 12762 if (astatic > 1) { 12763 DECR_AND_LOAD(6); 12764 if (astatic > 2) { 12765 DECR_AND_LOAD(5); 12766 if (astatic > 3) { 12767 DECR_AND_LOAD(4); 12768 } 12769 } 12770 } 12771 } 12772 #undef DECR_AND_LOAD 12773 12774 tcg_gen_movi_tl(t2, framesize); 12775 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); 12776 tcg_temp_free(t0); 12777 tcg_temp_free(t1); 12778 tcg_temp_free(t2); 12779 } 12780 12781 static void gen_addiupc(DisasContext *ctx, int rx, int imm, 12782 int is_64_bit, int extended) 12783 { 12784 TCGv t0; 12785 12786 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12787 gen_reserved_instruction(ctx); 12788 return; 12789 } 12790 12791 t0 = tcg_temp_new(); 12792 12793 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12794 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12795 if (!is_64_bit) { 12796 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12797 } 12798 12799 tcg_temp_free(t0); 12800 } 12801 12802 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12803 int16_t offset) 12804 { 12805 TCGv_i32 t0 = tcg_const_i32(op); 12806 TCGv t1 = tcg_temp_new(); 12807 gen_base_offset_addr(ctx, t1, base, offset); 12808 gen_helper_cache(cpu_env, t1, t0); 12809 tcg_temp_free(t1); 12810 tcg_temp_free_i32(t0); 12811 } 12812 12813 #if defined(TARGET_MIPS64) 12814 static void decode_i64_mips16(DisasContext *ctx, 12815 int ry, int funct, int16_t offset, 12816 int extended) 12817 { 12818 switch (funct) { 12819 case I64_LDSP: 12820 check_insn(ctx, ISA_MIPS3); 12821 check_mips_64(ctx); 12822 offset = extended ? offset : offset << 3; 12823 gen_ld(ctx, OPC_LD, ry, 29, offset); 12824 break; 12825 case I64_SDSP: 12826 check_insn(ctx, ISA_MIPS3); 12827 check_mips_64(ctx); 12828 offset = extended ? offset : offset << 3; 12829 gen_st(ctx, OPC_SD, ry, 29, offset); 12830 break; 12831 case I64_SDRASP: 12832 check_insn(ctx, ISA_MIPS3); 12833 check_mips_64(ctx); 12834 offset = extended ? offset : (ctx->opcode & 0xff) << 3; 12835 gen_st(ctx, OPC_SD, 31, 29, offset); 12836 break; 12837 case I64_DADJSP: 12838 check_insn(ctx, ISA_MIPS3); 12839 check_mips_64(ctx); 12840 offset = extended ? offset : ((int8_t)ctx->opcode) << 3; 12841 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset); 12842 break; 12843 case I64_LDPC: 12844 check_insn(ctx, ISA_MIPS3); 12845 check_mips_64(ctx); 12846 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12847 gen_reserved_instruction(ctx); 12848 } else { 12849 offset = extended ? offset : offset << 3; 12850 gen_ld(ctx, OPC_LDPC, ry, 0, offset); 12851 } 12852 break; 12853 case I64_DADDIU5: 12854 check_insn(ctx, ISA_MIPS3); 12855 check_mips_64(ctx); 12856 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3; 12857 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset); 12858 break; 12859 case I64_DADDIUPC: 12860 check_insn(ctx, ISA_MIPS3); 12861 check_mips_64(ctx); 12862 offset = extended ? offset : offset << 2; 12863 gen_addiupc(ctx, ry, offset, 1, extended); 12864 break; 12865 case I64_DADDIUSP: 12866 check_insn(ctx, ISA_MIPS3); 12867 check_mips_64(ctx); 12868 offset = extended ? offset : offset << 2; 12869 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset); 12870 break; 12871 } 12872 } 12873 #endif 12874 12875 static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) 12876 { 12877 int extend = translator_lduw(env, ctx->base.pc_next + 2); 12878 int op, rx, ry, funct, sa; 12879 int16_t imm, offset; 12880 12881 ctx->opcode = (ctx->opcode << 16) | extend; 12882 op = (ctx->opcode >> 11) & 0x1f; 12883 sa = (ctx->opcode >> 22) & 0x1f; 12884 funct = (ctx->opcode >> 8) & 0x7; 12885 rx = xlat((ctx->opcode >> 8) & 0x7); 12886 ry = xlat((ctx->opcode >> 5) & 0x7); 12887 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11 12888 | ((ctx->opcode >> 21) & 0x3f) << 5 12889 | (ctx->opcode & 0x1f)); 12890 12891 /* 12892 * The extended opcodes cleverly reuse the opcodes from their 16-bit 12893 * counterparts. 12894 */ 12895 switch (op) { 12896 case M16_OPC_ADDIUSP: 12897 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); 12898 break; 12899 case M16_OPC_ADDIUPC: 12900 gen_addiupc(ctx, rx, imm, 0, 1); 12901 break; 12902 case M16_OPC_B: 12903 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0); 12904 /* No delay slot, so just process as a normal instruction */ 12905 break; 12906 case M16_OPC_BEQZ: 12907 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0); 12908 /* No delay slot, so just process as a normal instruction */ 12909 break; 12910 case M16_OPC_BNEQZ: 12911 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0); 12912 /* No delay slot, so just process as a normal instruction */ 12913 break; 12914 case M16_OPC_SHIFT: 12915 switch (ctx->opcode & 0x3) { 12916 case 0x0: 12917 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); 12918 break; 12919 case 0x1: 12920 #if defined(TARGET_MIPS64) 12921 check_mips_64(ctx); 12922 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); 12923 #else 12924 gen_reserved_instruction(ctx); 12925 #endif 12926 break; 12927 case 0x2: 12928 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); 12929 break; 12930 case 0x3: 12931 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); 12932 break; 12933 } 12934 break; 12935 #if defined(TARGET_MIPS64) 12936 case M16_OPC_LD: 12937 check_insn(ctx, ISA_MIPS3); 12938 check_mips_64(ctx); 12939 gen_ld(ctx, OPC_LD, ry, rx, offset); 12940 break; 12941 #endif 12942 case M16_OPC_RRIA: 12943 imm = ctx->opcode & 0xf; 12944 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4; 12945 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11; 12946 imm = (int16_t) (imm << 1) >> 1; 12947 if ((ctx->opcode >> 4) & 0x1) { 12948 #if defined(TARGET_MIPS64) 12949 check_mips_64(ctx); 12950 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); 12951 #else 12952 gen_reserved_instruction(ctx); 12953 #endif 12954 } else { 12955 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); 12956 } 12957 break; 12958 case M16_OPC_ADDIU8: 12959 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); 12960 break; 12961 case M16_OPC_SLTI: 12962 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); 12963 break; 12964 case M16_OPC_SLTIU: 12965 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); 12966 break; 12967 case M16_OPC_I8: 12968 switch (funct) { 12969 case I8_BTEQZ: 12970 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0); 12971 break; 12972 case I8_BTNEZ: 12973 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0); 12974 break; 12975 case I8_SWRASP: 12976 gen_st(ctx, OPC_SW, 31, 29, imm); 12977 break; 12978 case I8_ADJSP: 12979 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm); 12980 break; 12981 case I8_SVRS: 12982 check_insn(ctx, ISA_MIPS_R1); 12983 { 12984 int xsregs = (ctx->opcode >> 24) & 0x7; 12985 int aregs = (ctx->opcode >> 16) & 0xf; 12986 int do_ra = (ctx->opcode >> 6) & 0x1; 12987 int do_s0 = (ctx->opcode >> 5) & 0x1; 12988 int do_s1 = (ctx->opcode >> 4) & 0x1; 12989 int framesize = (((ctx->opcode >> 20) & 0xf) << 4 12990 | (ctx->opcode & 0xf)) << 3; 12991 12992 if (ctx->opcode & (1 << 7)) { 12993 gen_mips16_save(ctx, xsregs, aregs, 12994 do_ra, do_s0, do_s1, 12995 framesize); 12996 } else { 12997 gen_mips16_restore(ctx, xsregs, aregs, 12998 do_ra, do_s0, do_s1, 12999 framesize); 13000 } 13001 } 13002 break; 13003 default: 13004 gen_reserved_instruction(ctx); 13005 break; 13006 } 13007 break; 13008 case M16_OPC_LI: 13009 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm); 13010 break; 13011 case M16_OPC_CMPI: 13012 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm); 13013 break; 13014 #if defined(TARGET_MIPS64) 13015 case M16_OPC_SD: 13016 check_insn(ctx, ISA_MIPS3); 13017 check_mips_64(ctx); 13018 gen_st(ctx, OPC_SD, ry, rx, offset); 13019 break; 13020 #endif 13021 case M16_OPC_LB: 13022 gen_ld(ctx, OPC_LB, ry, rx, offset); 13023 break; 13024 case M16_OPC_LH: 13025 gen_ld(ctx, OPC_LH, ry, rx, offset); 13026 break; 13027 case M16_OPC_LWSP: 13028 gen_ld(ctx, OPC_LW, rx, 29, offset); 13029 break; 13030 case M16_OPC_LW: 13031 gen_ld(ctx, OPC_LW, ry, rx, offset); 13032 break; 13033 case M16_OPC_LBU: 13034 gen_ld(ctx, OPC_LBU, ry, rx, offset); 13035 break; 13036 case M16_OPC_LHU: 13037 gen_ld(ctx, OPC_LHU, ry, rx, offset); 13038 break; 13039 case M16_OPC_LWPC: 13040 gen_ld(ctx, OPC_LWPC, rx, 0, offset); 13041 break; 13042 #if defined(TARGET_MIPS64) 13043 case M16_OPC_LWU: 13044 check_insn(ctx, ISA_MIPS3); 13045 check_mips_64(ctx); 13046 gen_ld(ctx, OPC_LWU, ry, rx, offset); 13047 break; 13048 #endif 13049 case M16_OPC_SB: 13050 gen_st(ctx, OPC_SB, ry, rx, offset); 13051 break; 13052 case M16_OPC_SH: 13053 gen_st(ctx, OPC_SH, ry, rx, offset); 13054 break; 13055 case M16_OPC_SWSP: 13056 gen_st(ctx, OPC_SW, rx, 29, offset); 13057 break; 13058 case M16_OPC_SW: 13059 gen_st(ctx, OPC_SW, ry, rx, offset); 13060 break; 13061 #if defined(TARGET_MIPS64) 13062 case M16_OPC_I64: 13063 decode_i64_mips16(ctx, ry, funct, offset, 1); 13064 break; 13065 #endif 13066 default: 13067 gen_reserved_instruction(ctx); 13068 break; 13069 } 13070 13071 return 4; 13072 } 13073 13074 static inline bool is_uhi(int sdbbp_code) 13075 { 13076 #ifdef CONFIG_USER_ONLY 13077 return false; 13078 #else 13079 return semihosting_enabled() && sdbbp_code == 1; 13080 #endif 13081 } 13082 13083 #ifdef CONFIG_USER_ONLY 13084 /* The above should dead-code away any calls to this..*/ 13085 static inline void gen_helper_do_semihosting(void *env) 13086 { 13087 g_assert_not_reached(); 13088 } 13089 #endif 13090 13091 static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx) 13092 { 13093 int rx, ry; 13094 int sa; 13095 int op, cnvt_op, op1, offset; 13096 int funct; 13097 int n_bytes; 13098 13099 op = (ctx->opcode >> 11) & 0x1f; 13100 sa = (ctx->opcode >> 2) & 0x7; 13101 sa = sa == 0 ? 8 : sa; 13102 rx = xlat((ctx->opcode >> 8) & 0x7); 13103 cnvt_op = (ctx->opcode >> 5) & 0x7; 13104 ry = xlat((ctx->opcode >> 5) & 0x7); 13105 op1 = offset = ctx->opcode & 0x1f; 13106 13107 n_bytes = 2; 13108 13109 switch (op) { 13110 case M16_OPC_ADDIUSP: 13111 { 13112 int16_t imm = ((uint8_t) ctx->opcode) << 2; 13113 13114 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm); 13115 } 13116 break; 13117 case M16_OPC_ADDIUPC: 13118 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0); 13119 break; 13120 case M16_OPC_B: 13121 offset = (ctx->opcode & 0x7ff) << 1; 13122 offset = (int16_t)(offset << 4) >> 4; 13123 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0); 13124 /* No delay slot, so just process as a normal instruction */ 13125 break; 13126 case M16_OPC_JAL: 13127 offset = translator_lduw(env, ctx->base.pc_next + 2); 13128 offset = (((ctx->opcode & 0x1f) << 21) 13129 | ((ctx->opcode >> 5) & 0x1f) << 16 13130 | offset) << 2; 13131 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL; 13132 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2); 13133 n_bytes = 4; 13134 break; 13135 case M16_OPC_BEQZ: 13136 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, 13137 ((int8_t)ctx->opcode) << 1, 0); 13138 /* No delay slot, so just process as a normal instruction */ 13139 break; 13140 case M16_OPC_BNEQZ: 13141 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, 13142 ((int8_t)ctx->opcode) << 1, 0); 13143 /* No delay slot, so just process as a normal instruction */ 13144 break; 13145 case M16_OPC_SHIFT: 13146 switch (ctx->opcode & 0x3) { 13147 case 0x0: 13148 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa); 13149 break; 13150 case 0x1: 13151 #if defined(TARGET_MIPS64) 13152 check_insn(ctx, ISA_MIPS3); 13153 check_mips_64(ctx); 13154 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa); 13155 #else 13156 gen_reserved_instruction(ctx); 13157 #endif 13158 break; 13159 case 0x2: 13160 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa); 13161 break; 13162 case 0x3: 13163 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa); 13164 break; 13165 } 13166 break; 13167 #if defined(TARGET_MIPS64) 13168 case M16_OPC_LD: 13169 check_insn(ctx, ISA_MIPS3); 13170 check_mips_64(ctx); 13171 gen_ld(ctx, OPC_LD, ry, rx, offset << 3); 13172 break; 13173 #endif 13174 case M16_OPC_RRIA: 13175 { 13176 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4; 13177 13178 if ((ctx->opcode >> 4) & 1) { 13179 #if defined(TARGET_MIPS64) 13180 check_insn(ctx, ISA_MIPS3); 13181 check_mips_64(ctx); 13182 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm); 13183 #else 13184 gen_reserved_instruction(ctx); 13185 #endif 13186 } else { 13187 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm); 13188 } 13189 } 13190 break; 13191 case M16_OPC_ADDIU8: 13192 { 13193 int16_t imm = (int8_t) ctx->opcode; 13194 13195 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm); 13196 } 13197 break; 13198 case M16_OPC_SLTI: 13199 { 13200 int16_t imm = (uint8_t) ctx->opcode; 13201 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm); 13202 } 13203 break; 13204 case M16_OPC_SLTIU: 13205 { 13206 int16_t imm = (uint8_t) ctx->opcode; 13207 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm); 13208 } 13209 break; 13210 case M16_OPC_I8: 13211 { 13212 int reg32; 13213 13214 funct = (ctx->opcode >> 8) & 0x7; 13215 switch (funct) { 13216 case I8_BTEQZ: 13217 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0, 13218 ((int8_t)ctx->opcode) << 1, 0); 13219 break; 13220 case I8_BTNEZ: 13221 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0, 13222 ((int8_t)ctx->opcode) << 1, 0); 13223 break; 13224 case I8_SWRASP: 13225 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2); 13226 break; 13227 case I8_ADJSP: 13228 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, 13229 ((int8_t)ctx->opcode) << 3); 13230 break; 13231 case I8_SVRS: 13232 check_insn(ctx, ISA_MIPS_R1); 13233 { 13234 int do_ra = ctx->opcode & (1 << 6); 13235 int do_s0 = ctx->opcode & (1 << 5); 13236 int do_s1 = ctx->opcode & (1 << 4); 13237 int framesize = ctx->opcode & 0xf; 13238 13239 if (framesize == 0) { 13240 framesize = 128; 13241 } else { 13242 framesize = framesize << 3; 13243 } 13244 13245 if (ctx->opcode & (1 << 7)) { 13246 gen_mips16_save(ctx, 0, 0, 13247 do_ra, do_s0, do_s1, framesize); 13248 } else { 13249 gen_mips16_restore(ctx, 0, 0, 13250 do_ra, do_s0, do_s1, framesize); 13251 } 13252 } 13253 break; 13254 case I8_MOV32R: 13255 { 13256 int rz = xlat(ctx->opcode & 0x7); 13257 13258 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) | 13259 ((ctx->opcode >> 5) & 0x7); 13260 gen_arith(ctx, OPC_ADDU, reg32, rz, 0); 13261 } 13262 break; 13263 case I8_MOVR32: 13264 reg32 = ctx->opcode & 0x1f; 13265 gen_arith(ctx, OPC_ADDU, ry, reg32, 0); 13266 break; 13267 default: 13268 gen_reserved_instruction(ctx); 13269 break; 13270 } 13271 } 13272 break; 13273 case M16_OPC_LI: 13274 { 13275 int16_t imm = (uint8_t) ctx->opcode; 13276 13277 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm); 13278 } 13279 break; 13280 case M16_OPC_CMPI: 13281 { 13282 int16_t imm = (uint8_t) ctx->opcode; 13283 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm); 13284 } 13285 break; 13286 #if defined(TARGET_MIPS64) 13287 case M16_OPC_SD: 13288 check_insn(ctx, ISA_MIPS3); 13289 check_mips_64(ctx); 13290 gen_st(ctx, OPC_SD, ry, rx, offset << 3); 13291 break; 13292 #endif 13293 case M16_OPC_LB: 13294 gen_ld(ctx, OPC_LB, ry, rx, offset); 13295 break; 13296 case M16_OPC_LH: 13297 gen_ld(ctx, OPC_LH, ry, rx, offset << 1); 13298 break; 13299 case M16_OPC_LWSP: 13300 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2); 13301 break; 13302 case M16_OPC_LW: 13303 gen_ld(ctx, OPC_LW, ry, rx, offset << 2); 13304 break; 13305 case M16_OPC_LBU: 13306 gen_ld(ctx, OPC_LBU, ry, rx, offset); 13307 break; 13308 case M16_OPC_LHU: 13309 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1); 13310 break; 13311 case M16_OPC_LWPC: 13312 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2); 13313 break; 13314 #if defined(TARGET_MIPS64) 13315 case M16_OPC_LWU: 13316 check_insn(ctx, ISA_MIPS3); 13317 check_mips_64(ctx); 13318 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2); 13319 break; 13320 #endif 13321 case M16_OPC_SB: 13322 gen_st(ctx, OPC_SB, ry, rx, offset); 13323 break; 13324 case M16_OPC_SH: 13325 gen_st(ctx, OPC_SH, ry, rx, offset << 1); 13326 break; 13327 case M16_OPC_SWSP: 13328 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2); 13329 break; 13330 case M16_OPC_SW: 13331 gen_st(ctx, OPC_SW, ry, rx, offset << 2); 13332 break; 13333 case M16_OPC_RRR: 13334 { 13335 int rz = xlat((ctx->opcode >> 2) & 0x7); 13336 int mips32_op; 13337 13338 switch (ctx->opcode & 0x3) { 13339 case RRR_ADDU: 13340 mips32_op = OPC_ADDU; 13341 break; 13342 case RRR_SUBU: 13343 mips32_op = OPC_SUBU; 13344 break; 13345 #if defined(TARGET_MIPS64) 13346 case RRR_DADDU: 13347 mips32_op = OPC_DADDU; 13348 check_insn(ctx, ISA_MIPS3); 13349 check_mips_64(ctx); 13350 break; 13351 case RRR_DSUBU: 13352 mips32_op = OPC_DSUBU; 13353 check_insn(ctx, ISA_MIPS3); 13354 check_mips_64(ctx); 13355 break; 13356 #endif 13357 default: 13358 gen_reserved_instruction(ctx); 13359 goto done; 13360 } 13361 13362 gen_arith(ctx, mips32_op, rz, rx, ry); 13363 done: 13364 ; 13365 } 13366 break; 13367 case M16_OPC_RR: 13368 switch (op1) { 13369 case RR_JR: 13370 { 13371 int nd = (ctx->opcode >> 7) & 0x1; 13372 int link = (ctx->opcode >> 6) & 0x1; 13373 int ra = (ctx->opcode >> 5) & 0x1; 13374 13375 if (nd) { 13376 check_insn(ctx, ISA_MIPS_R1); 13377 } 13378 13379 if (link) { 13380 op = OPC_JALR; 13381 } else { 13382 op = OPC_JR; 13383 } 13384 13385 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0, 13386 (nd ? 0 : 2)); 13387 } 13388 break; 13389 case RR_SDBBP: 13390 if (is_uhi(extract32(ctx->opcode, 5, 6))) { 13391 gen_helper_do_semihosting(cpu_env); 13392 } else { 13393 /* 13394 * XXX: not clear which exception should be raised 13395 * when in debug mode... 13396 */ 13397 check_insn(ctx, ISA_MIPS_R1); 13398 generate_exception_end(ctx, EXCP_DBp); 13399 } 13400 break; 13401 case RR_SLT: 13402 gen_slt(ctx, OPC_SLT, 24, rx, ry); 13403 break; 13404 case RR_SLTU: 13405 gen_slt(ctx, OPC_SLTU, 24, rx, ry); 13406 break; 13407 case RR_BREAK: 13408 generate_exception_end(ctx, EXCP_BREAK); 13409 break; 13410 case RR_SLLV: 13411 gen_shift(ctx, OPC_SLLV, ry, rx, ry); 13412 break; 13413 case RR_SRLV: 13414 gen_shift(ctx, OPC_SRLV, ry, rx, ry); 13415 break; 13416 case RR_SRAV: 13417 gen_shift(ctx, OPC_SRAV, ry, rx, ry); 13418 break; 13419 #if defined(TARGET_MIPS64) 13420 case RR_DSRL: 13421 check_insn(ctx, ISA_MIPS3); 13422 check_mips_64(ctx); 13423 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa); 13424 break; 13425 #endif 13426 case RR_CMP: 13427 gen_logic(ctx, OPC_XOR, 24, rx, ry); 13428 break; 13429 case RR_NEG: 13430 gen_arith(ctx, OPC_SUBU, rx, 0, ry); 13431 break; 13432 case RR_AND: 13433 gen_logic(ctx, OPC_AND, rx, rx, ry); 13434 break; 13435 case RR_OR: 13436 gen_logic(ctx, OPC_OR, rx, rx, ry); 13437 break; 13438 case RR_XOR: 13439 gen_logic(ctx, OPC_XOR, rx, rx, ry); 13440 break; 13441 case RR_NOT: 13442 gen_logic(ctx, OPC_NOR, rx, ry, 0); 13443 break; 13444 case RR_MFHI: 13445 gen_HILO(ctx, OPC_MFHI, 0, rx); 13446 break; 13447 case RR_CNVT: 13448 check_insn(ctx, ISA_MIPS_R1); 13449 switch (cnvt_op) { 13450 case RR_RY_CNVT_ZEB: 13451 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]); 13452 break; 13453 case RR_RY_CNVT_ZEH: 13454 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]); 13455 break; 13456 case RR_RY_CNVT_SEB: 13457 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]); 13458 break; 13459 case RR_RY_CNVT_SEH: 13460 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]); 13461 break; 13462 #if defined(TARGET_MIPS64) 13463 case RR_RY_CNVT_ZEW: 13464 check_insn(ctx, ISA_MIPS_R1); 13465 check_mips_64(ctx); 13466 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); 13467 break; 13468 case RR_RY_CNVT_SEW: 13469 check_insn(ctx, ISA_MIPS_R1); 13470 check_mips_64(ctx); 13471 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 13472 break; 13473 #endif 13474 default: 13475 gen_reserved_instruction(ctx); 13476 break; 13477 } 13478 break; 13479 case RR_MFLO: 13480 gen_HILO(ctx, OPC_MFLO, 0, rx); 13481 break; 13482 #if defined(TARGET_MIPS64) 13483 case RR_DSRA: 13484 check_insn(ctx, ISA_MIPS3); 13485 check_mips_64(ctx); 13486 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa); 13487 break; 13488 case RR_DSLLV: 13489 check_insn(ctx, ISA_MIPS3); 13490 check_mips_64(ctx); 13491 gen_shift(ctx, OPC_DSLLV, ry, rx, ry); 13492 break; 13493 case RR_DSRLV: 13494 check_insn(ctx, ISA_MIPS3); 13495 check_mips_64(ctx); 13496 gen_shift(ctx, OPC_DSRLV, ry, rx, ry); 13497 break; 13498 case RR_DSRAV: 13499 check_insn(ctx, ISA_MIPS3); 13500 check_mips_64(ctx); 13501 gen_shift(ctx, OPC_DSRAV, ry, rx, ry); 13502 break; 13503 #endif 13504 case RR_MULT: 13505 gen_muldiv(ctx, OPC_MULT, 0, rx, ry); 13506 break; 13507 case RR_MULTU: 13508 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry); 13509 break; 13510 case RR_DIV: 13511 gen_muldiv(ctx, OPC_DIV, 0, rx, ry); 13512 break; 13513 case RR_DIVU: 13514 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry); 13515 break; 13516 #if defined(TARGET_MIPS64) 13517 case RR_DMULT: 13518 check_insn(ctx, ISA_MIPS3); 13519 check_mips_64(ctx); 13520 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry); 13521 break; 13522 case RR_DMULTU: 13523 check_insn(ctx, ISA_MIPS3); 13524 check_mips_64(ctx); 13525 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry); 13526 break; 13527 case RR_DDIV: 13528 check_insn(ctx, ISA_MIPS3); 13529 check_mips_64(ctx); 13530 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry); 13531 break; 13532 case RR_DDIVU: 13533 check_insn(ctx, ISA_MIPS3); 13534 check_mips_64(ctx); 13535 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry); 13536 break; 13537 #endif 13538 default: 13539 gen_reserved_instruction(ctx); 13540 break; 13541 } 13542 break; 13543 case M16_OPC_EXTEND: 13544 decode_extended_mips16_opc(env, ctx); 13545 n_bytes = 4; 13546 break; 13547 #if defined(TARGET_MIPS64) 13548 case M16_OPC_I64: 13549 funct = (ctx->opcode >> 8) & 0x7; 13550 decode_i64_mips16(ctx, ry, funct, offset, 0); 13551 break; 13552 #endif 13553 default: 13554 gen_reserved_instruction(ctx); 13555 break; 13556 } 13557 13558 return n_bytes; 13559 } 13560 13561 /* microMIPS extension to MIPS32/MIPS64 */ 13562 13563 /* 13564 * microMIPS32/microMIPS64 major opcodes 13565 * 13566 * 1. MIPS Architecture for Programmers Volume II-B: 13567 * The microMIPS32 Instruction Set (Revision 3.05) 13568 * 13569 * Table 6.2 microMIPS32 Encoding of Major Opcode Field 13570 * 13571 * 2. MIPS Architecture For Programmers Volume II-A: 13572 * The MIPS64 Instruction Set (Revision 3.51) 13573 */ 13574 13575 enum { 13576 POOL32A = 0x00, 13577 POOL16A = 0x01, 13578 LBU16 = 0x02, 13579 MOVE16 = 0x03, 13580 ADDI32 = 0x04, 13581 R6_LUI = 0x04, 13582 AUI = 0x04, 13583 LBU32 = 0x05, 13584 SB32 = 0x06, 13585 LB32 = 0x07, 13586 13587 POOL32B = 0x08, 13588 POOL16B = 0x09, 13589 LHU16 = 0x0a, 13590 ANDI16 = 0x0b, 13591 ADDIU32 = 0x0c, 13592 LHU32 = 0x0d, 13593 SH32 = 0x0e, 13594 LH32 = 0x0f, 13595 13596 POOL32I = 0x10, 13597 POOL16C = 0x11, 13598 LWSP16 = 0x12, 13599 POOL16D = 0x13, 13600 ORI32 = 0x14, 13601 POOL32F = 0x15, 13602 POOL32S = 0x16, /* MIPS64 */ 13603 DADDIU32 = 0x17, /* MIPS64 */ 13604 13605 POOL32C = 0x18, 13606 LWGP16 = 0x19, 13607 LW16 = 0x1a, 13608 POOL16E = 0x1b, 13609 XORI32 = 0x1c, 13610 JALS32 = 0x1d, 13611 BOVC = 0x1d, 13612 BEQC = 0x1d, 13613 BEQZALC = 0x1d, 13614 ADDIUPC = 0x1e, 13615 PCREL = 0x1e, 13616 BNVC = 0x1f, 13617 BNEC = 0x1f, 13618 BNEZALC = 0x1f, 13619 13620 R6_BEQZC = 0x20, 13621 JIC = 0x20, 13622 POOL16F = 0x21, 13623 SB16 = 0x22, 13624 BEQZ16 = 0x23, 13625 BEQZC16 = 0x23, 13626 SLTI32 = 0x24, 13627 BEQ32 = 0x25, 13628 BC = 0x25, 13629 SWC132 = 0x26, 13630 LWC132 = 0x27, 13631 13632 /* 0x29 is reserved */ 13633 RES_29 = 0x29, 13634 R6_BNEZC = 0x28, 13635 JIALC = 0x28, 13636 SH16 = 0x2a, 13637 BNEZ16 = 0x2b, 13638 BNEZC16 = 0x2b, 13639 SLTIU32 = 0x2c, 13640 BNE32 = 0x2d, 13641 BALC = 0x2d, 13642 SDC132 = 0x2e, 13643 LDC132 = 0x2f, 13644 13645 /* 0x31 is reserved */ 13646 RES_31 = 0x31, 13647 BLEZALC = 0x30, 13648 BGEZALC = 0x30, 13649 BGEUC = 0x30, 13650 SWSP16 = 0x32, 13651 B16 = 0x33, 13652 BC16 = 0x33, 13653 ANDI32 = 0x34, 13654 J32 = 0x35, 13655 BGTZC = 0x35, 13656 BLTZC = 0x35, 13657 BLTC = 0x35, 13658 SD32 = 0x36, /* MIPS64 */ 13659 LD32 = 0x37, /* MIPS64 */ 13660 13661 /* 0x39 is reserved */ 13662 RES_39 = 0x39, 13663 BGTZALC = 0x38, 13664 BLTZALC = 0x38, 13665 BLTUC = 0x38, 13666 SW16 = 0x3a, 13667 LI16 = 0x3b, 13668 JALX32 = 0x3c, 13669 JAL32 = 0x3d, 13670 BLEZC = 0x3d, 13671 BGEZC = 0x3d, 13672 BGEC = 0x3d, 13673 SW32 = 0x3e, 13674 LW32 = 0x3f 13675 }; 13676 13677 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */ 13678 enum { 13679 ADDIUPC_00 = 0x00, 13680 ADDIUPC_01 = 0x01, 13681 ADDIUPC_02 = 0x02, 13682 ADDIUPC_03 = 0x03, 13683 ADDIUPC_04 = 0x04, 13684 ADDIUPC_05 = 0x05, 13685 ADDIUPC_06 = 0x06, 13686 ADDIUPC_07 = 0x07, 13687 AUIPC = 0x1e, 13688 ALUIPC = 0x1f, 13689 LWPC_08 = 0x08, 13690 LWPC_09 = 0x09, 13691 LWPC_0A = 0x0A, 13692 LWPC_0B = 0x0B, 13693 LWPC_0C = 0x0C, 13694 LWPC_0D = 0x0D, 13695 LWPC_0E = 0x0E, 13696 LWPC_0F = 0x0F, 13697 }; 13698 13699 /* POOL32A encoding of minor opcode field */ 13700 13701 enum { 13702 /* 13703 * These opcodes are distinguished only by bits 9..6; those bits are 13704 * what are recorded below. 13705 */ 13706 SLL32 = 0x0, 13707 SRL32 = 0x1, 13708 SRA = 0x2, 13709 ROTR = 0x3, 13710 SELEQZ = 0x5, 13711 SELNEZ = 0x6, 13712 R6_RDHWR = 0x7, 13713 13714 SLLV = 0x0, 13715 SRLV = 0x1, 13716 SRAV = 0x2, 13717 ROTRV = 0x3, 13718 ADD = 0x4, 13719 ADDU32 = 0x5, 13720 SUB = 0x6, 13721 SUBU32 = 0x7, 13722 MUL = 0x8, 13723 AND = 0x9, 13724 OR32 = 0xa, 13725 NOR = 0xb, 13726 XOR32 = 0xc, 13727 SLT = 0xd, 13728 SLTU = 0xe, 13729 13730 MOVN = 0x0, 13731 R6_MUL = 0x0, 13732 MOVZ = 0x1, 13733 MUH = 0x1, 13734 MULU = 0x2, 13735 MUHU = 0x3, 13736 LWXS = 0x4, 13737 R6_DIV = 0x4, 13738 MOD = 0x5, 13739 R6_DIVU = 0x6, 13740 MODU = 0x7, 13741 13742 /* The following can be distinguished by their lower 6 bits. */ 13743 BREAK32 = 0x07, 13744 INS = 0x0c, 13745 LSA = 0x0f, 13746 ALIGN = 0x1f, 13747 EXT = 0x2c, 13748 POOL32AXF = 0x3c, 13749 SIGRIE = 0x3f 13750 }; 13751 13752 /* POOL32AXF encoding of minor opcode field extension */ 13753 13754 /* 13755 * 1. MIPS Architecture for Programmers Volume II-B: 13756 * The microMIPS32 Instruction Set (Revision 3.05) 13757 * 13758 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field 13759 * 13760 * 2. MIPS Architecture for Programmers VolumeIV-e: 13761 * The MIPS DSP Application-Specific Extension 13762 * to the microMIPS32 Architecture (Revision 2.34) 13763 * 13764 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field 13765 */ 13766 13767 enum { 13768 /* bits 11..6 */ 13769 TEQ = 0x00, 13770 TGE = 0x08, 13771 TGEU = 0x10, 13772 TLT = 0x20, 13773 TLTU = 0x28, 13774 TNE = 0x30, 13775 13776 MFC0 = 0x03, 13777 MTC0 = 0x0b, 13778 13779 /* begin of microMIPS32 DSP */ 13780 13781 /* bits 13..12 for 0x01 */ 13782 MFHI_ACC = 0x0, 13783 MFLO_ACC = 0x1, 13784 MTHI_ACC = 0x2, 13785 MTLO_ACC = 0x3, 13786 13787 /* bits 13..12 for 0x2a */ 13788 MADD_ACC = 0x0, 13789 MADDU_ACC = 0x1, 13790 MSUB_ACC = 0x2, 13791 MSUBU_ACC = 0x3, 13792 13793 /* bits 13..12 for 0x32 */ 13794 MULT_ACC = 0x0, 13795 MULTU_ACC = 0x1, 13796 13797 /* end of microMIPS32 DSP */ 13798 13799 /* bits 15..12 for 0x2c */ 13800 BITSWAP = 0x0, 13801 SEB = 0x2, 13802 SEH = 0x3, 13803 CLO = 0x4, 13804 CLZ = 0x5, 13805 RDHWR = 0x6, 13806 WSBH = 0x7, 13807 MULT = 0x8, 13808 MULTU = 0x9, 13809 DIV = 0xa, 13810 DIVU = 0xb, 13811 MADD = 0xc, 13812 MADDU = 0xd, 13813 MSUB = 0xe, 13814 MSUBU = 0xf, 13815 13816 /* bits 15..12 for 0x34 */ 13817 MFC2 = 0x4, 13818 MTC2 = 0x5, 13819 MFHC2 = 0x8, 13820 MTHC2 = 0x9, 13821 CFC2 = 0xc, 13822 CTC2 = 0xd, 13823 13824 /* bits 15..12 for 0x3c */ 13825 JALR = 0x0, 13826 JR = 0x0, /* alias */ 13827 JALRC = 0x0, 13828 JRC = 0x0, 13829 JALR_HB = 0x1, 13830 JALRC_HB = 0x1, 13831 JALRS = 0x4, 13832 JALRS_HB = 0x5, 13833 13834 /* bits 15..12 for 0x05 */ 13835 RDPGPR = 0xe, 13836 WRPGPR = 0xf, 13837 13838 /* bits 15..12 for 0x0d */ 13839 TLBP = 0x0, 13840 TLBR = 0x1, 13841 TLBWI = 0x2, 13842 TLBWR = 0x3, 13843 TLBINV = 0x4, 13844 TLBINVF = 0x5, 13845 WAIT = 0x9, 13846 IRET = 0xd, 13847 DERET = 0xe, 13848 ERET = 0xf, 13849 13850 /* bits 15..12 for 0x15 */ 13851 DMT = 0x0, 13852 DVPE = 0x1, 13853 EMT = 0x2, 13854 EVPE = 0x3, 13855 13856 /* bits 15..12 for 0x1d */ 13857 DI = 0x4, 13858 EI = 0x5, 13859 13860 /* bits 15..12 for 0x2d */ 13861 SYNC = 0x6, 13862 SYSCALL = 0x8, 13863 SDBBP = 0xd, 13864 13865 /* bits 15..12 for 0x35 */ 13866 MFHI32 = 0x0, 13867 MFLO32 = 0x1, 13868 MTHI32 = 0x2, 13869 MTLO32 = 0x3, 13870 }; 13871 13872 /* POOL32B encoding of minor opcode field (bits 15..12) */ 13873 13874 enum { 13875 LWC2 = 0x0, 13876 LWP = 0x1, 13877 LDP = 0x4, 13878 LWM32 = 0x5, 13879 CACHE = 0x6, 13880 LDM = 0x7, 13881 SWC2 = 0x8, 13882 SWP = 0x9, 13883 SDP = 0xc, 13884 SWM32 = 0xd, 13885 SDM = 0xf 13886 }; 13887 13888 /* POOL32C encoding of minor opcode field (bits 15..12) */ 13889 13890 enum { 13891 LWL = 0x0, 13892 SWL = 0x8, 13893 LWR = 0x1, 13894 SWR = 0x9, 13895 PREF = 0x2, 13896 ST_EVA = 0xa, 13897 LL = 0x3, 13898 SC = 0xb, 13899 LDL = 0x4, 13900 SDL = 0xc, 13901 LDR = 0x5, 13902 SDR = 0xd, 13903 LD_EVA = 0x6, 13904 LWU = 0xe, 13905 LLD = 0x7, 13906 SCD = 0xf 13907 }; 13908 13909 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */ 13910 13911 enum { 13912 LBUE = 0x0, 13913 LHUE = 0x1, 13914 LWLE = 0x2, 13915 LWRE = 0x3, 13916 LBE = 0x4, 13917 LHE = 0x5, 13918 LLE = 0x6, 13919 LWE = 0x7, 13920 }; 13921 13922 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */ 13923 13924 enum { 13925 SWLE = 0x0, 13926 SWRE = 0x1, 13927 PREFE = 0x2, 13928 CACHEE = 0x3, 13929 SBE = 0x4, 13930 SHE = 0x5, 13931 SCE = 0x6, 13932 SWE = 0x7, 13933 }; 13934 13935 /* POOL32F encoding of minor opcode field (bits 5..0) */ 13936 13937 enum { 13938 /* These are the bit 7..6 values */ 13939 ADD_FMT = 0x0, 13940 13941 SUB_FMT = 0x1, 13942 13943 MUL_FMT = 0x2, 13944 13945 DIV_FMT = 0x3, 13946 13947 /* These are the bit 8..6 values */ 13948 MOVN_FMT = 0x0, 13949 RSQRT2_FMT = 0x0, 13950 MOVF_FMT = 0x0, 13951 RINT_FMT = 0x0, 13952 SELNEZ_FMT = 0x0, 13953 13954 MOVZ_FMT = 0x1, 13955 LWXC1 = 0x1, 13956 MOVT_FMT = 0x1, 13957 CLASS_FMT = 0x1, 13958 SELEQZ_FMT = 0x1, 13959 13960 PLL_PS = 0x2, 13961 SWXC1 = 0x2, 13962 SEL_FMT = 0x2, 13963 13964 PLU_PS = 0x3, 13965 LDXC1 = 0x3, 13966 13967 MOVN_FMT_04 = 0x4, 13968 PUL_PS = 0x4, 13969 SDXC1 = 0x4, 13970 RECIP2_FMT = 0x4, 13971 13972 MOVZ_FMT_05 = 0x05, 13973 PUU_PS = 0x5, 13974 LUXC1 = 0x5, 13975 13976 CVT_PS_S = 0x6, 13977 SUXC1 = 0x6, 13978 ADDR_PS = 0x6, 13979 PREFX = 0x6, 13980 MADDF_FMT = 0x6, 13981 13982 MULR_PS = 0x7, 13983 MSUBF_FMT = 0x7, 13984 13985 MADD_S = 0x01, 13986 MADD_D = 0x09, 13987 MADD_PS = 0x11, 13988 ALNV_PS = 0x19, 13989 MSUB_S = 0x21, 13990 MSUB_D = 0x29, 13991 MSUB_PS = 0x31, 13992 13993 NMADD_S = 0x02, 13994 NMADD_D = 0x0a, 13995 NMADD_PS = 0x12, 13996 NMSUB_S = 0x22, 13997 NMSUB_D = 0x2a, 13998 NMSUB_PS = 0x32, 13999 14000 MIN_FMT = 0x3, 14001 MAX_FMT = 0xb, 14002 MINA_FMT = 0x23, 14003 MAXA_FMT = 0x2b, 14004 POOL32FXF = 0x3b, 14005 14006 CABS_COND_FMT = 0x1c, /* MIPS3D */ 14007 C_COND_FMT = 0x3c, 14008 14009 CMP_CONDN_S = 0x5, 14010 CMP_CONDN_D = 0x15 14011 }; 14012 14013 /* POOL32Fxf encoding of minor opcode extension field */ 14014 14015 enum { 14016 CVT_L = 0x04, 14017 RSQRT_FMT = 0x08, 14018 FLOOR_L = 0x0c, 14019 CVT_PW_PS = 0x1c, 14020 CVT_W = 0x24, 14021 SQRT_FMT = 0x28, 14022 FLOOR_W = 0x2c, 14023 CVT_PS_PW = 0x3c, 14024 CFC1 = 0x40, 14025 RECIP_FMT = 0x48, 14026 CEIL_L = 0x4c, 14027 CTC1 = 0x60, 14028 CEIL_W = 0x6c, 14029 MFC1 = 0x80, 14030 CVT_S_PL = 0x84, 14031 TRUNC_L = 0x8c, 14032 MTC1 = 0xa0, 14033 CVT_S_PU = 0xa4, 14034 TRUNC_W = 0xac, 14035 MFHC1 = 0xc0, 14036 ROUND_L = 0xcc, 14037 MTHC1 = 0xe0, 14038 ROUND_W = 0xec, 14039 14040 MOV_FMT = 0x01, 14041 MOVF = 0x05, 14042 ABS_FMT = 0x0d, 14043 RSQRT1_FMT = 0x1d, 14044 MOVT = 0x25, 14045 NEG_FMT = 0x2d, 14046 CVT_D = 0x4d, 14047 RECIP1_FMT = 0x5d, 14048 CVT_S = 0x6d 14049 }; 14050 14051 /* POOL32I encoding of minor opcode field (bits 25..21) */ 14052 14053 enum { 14054 BLTZ = 0x00, 14055 BLTZAL = 0x01, 14056 BGEZ = 0x02, 14057 BGEZAL = 0x03, 14058 BLEZ = 0x04, 14059 BNEZC = 0x05, 14060 BGTZ = 0x06, 14061 BEQZC = 0x07, 14062 TLTI = 0x08, 14063 BC1EQZC = 0x08, 14064 TGEI = 0x09, 14065 BC1NEZC = 0x09, 14066 TLTIU = 0x0a, 14067 BC2EQZC = 0x0a, 14068 TGEIU = 0x0b, 14069 BC2NEZC = 0x0a, 14070 TNEI = 0x0c, 14071 R6_SYNCI = 0x0c, 14072 LUI = 0x0d, 14073 TEQI = 0x0e, 14074 SYNCI = 0x10, 14075 BLTZALS = 0x11, 14076 BGEZALS = 0x13, 14077 BC2F = 0x14, 14078 BC2T = 0x15, 14079 BPOSGE64 = 0x1a, 14080 BPOSGE32 = 0x1b, 14081 /* These overlap and are distinguished by bit16 of the instruction */ 14082 BC1F = 0x1c, 14083 BC1T = 0x1d, 14084 BC1ANY2F = 0x1c, 14085 BC1ANY2T = 0x1d, 14086 BC1ANY4F = 0x1e, 14087 BC1ANY4T = 0x1f 14088 }; 14089 14090 /* POOL16A encoding of minor opcode field */ 14091 14092 enum { 14093 ADDU16 = 0x0, 14094 SUBU16 = 0x1 14095 }; 14096 14097 /* POOL16B encoding of minor opcode field */ 14098 14099 enum { 14100 SLL16 = 0x0, 14101 SRL16 = 0x1 14102 }; 14103 14104 /* POOL16C encoding of minor opcode field */ 14105 14106 enum { 14107 NOT16 = 0x00, 14108 XOR16 = 0x04, 14109 AND16 = 0x08, 14110 OR16 = 0x0c, 14111 LWM16 = 0x10, 14112 SWM16 = 0x14, 14113 JR16 = 0x18, 14114 JRC16 = 0x1a, 14115 JALR16 = 0x1c, 14116 JALR16S = 0x1e, 14117 MFHI16 = 0x20, 14118 MFLO16 = 0x24, 14119 BREAK16 = 0x28, 14120 SDBBP16 = 0x2c, 14121 JRADDIUSP = 0x30 14122 }; 14123 14124 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */ 14125 14126 enum { 14127 R6_NOT16 = 0x00, 14128 R6_AND16 = 0x01, 14129 R6_LWM16 = 0x02, 14130 R6_JRC16 = 0x03, 14131 MOVEP = 0x04, 14132 MOVEP_05 = 0x05, 14133 MOVEP_06 = 0x06, 14134 MOVEP_07 = 0x07, 14135 R6_XOR16 = 0x08, 14136 R6_OR16 = 0x09, 14137 R6_SWM16 = 0x0a, 14138 JALRC16 = 0x0b, 14139 MOVEP_0C = 0x0c, 14140 MOVEP_0D = 0x0d, 14141 MOVEP_0E = 0x0e, 14142 MOVEP_0F = 0x0f, 14143 JRCADDIUSP = 0x13, 14144 R6_BREAK16 = 0x1b, 14145 R6_SDBBP16 = 0x3b 14146 }; 14147 14148 /* POOL16D encoding of minor opcode field */ 14149 14150 enum { 14151 ADDIUS5 = 0x0, 14152 ADDIUSP = 0x1 14153 }; 14154 14155 /* POOL16E encoding of minor opcode field */ 14156 14157 enum { 14158 ADDIUR2 = 0x0, 14159 ADDIUR1SP = 0x1 14160 }; 14161 14162 static int mmreg(int r) 14163 { 14164 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; 14165 14166 return map[r]; 14167 } 14168 14169 /* Used for 16-bit store instructions. */ 14170 static int mmreg2(int r) 14171 { 14172 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; 14173 14174 return map[r]; 14175 } 14176 14177 #define uMIPS_RD(op) ((op >> 7) & 0x7) 14178 #define uMIPS_RS(op) ((op >> 4) & 0x7) 14179 #define uMIPS_RS2(op) uMIPS_RS(op) 14180 #define uMIPS_RS1(op) ((op >> 1) & 0x7) 14181 #define uMIPS_RD5(op) ((op >> 5) & 0x1f) 14182 #define uMIPS_RS5(op) (op & 0x1f) 14183 14184 /* Signed immediate */ 14185 #define SIMM(op, start, width) \ 14186 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ 14187 << (32 - width)) \ 14188 >> (32 - width)) 14189 /* Zero-extended immediate */ 14190 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) 14191 14192 static void gen_addiur1sp(DisasContext *ctx) 14193 { 14194 int rd = mmreg(uMIPS_RD(ctx->opcode)); 14195 14196 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2); 14197 } 14198 14199 static void gen_addiur2(DisasContext *ctx) 14200 { 14201 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 }; 14202 int rd = mmreg(uMIPS_RD(ctx->opcode)); 14203 int rs = mmreg(uMIPS_RS(ctx->opcode)); 14204 14205 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]); 14206 } 14207 14208 static void gen_addiusp(DisasContext *ctx) 14209 { 14210 int encoded = ZIMM(ctx->opcode, 1, 9); 14211 int decoded; 14212 14213 if (encoded <= 1) { 14214 decoded = 256 + encoded; 14215 } else if (encoded <= 255) { 14216 decoded = encoded; 14217 } else if (encoded <= 509) { 14218 decoded = encoded - 512; 14219 } else { 14220 decoded = encoded - 768; 14221 } 14222 14223 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2); 14224 } 14225 14226 static void gen_addius5(DisasContext *ctx) 14227 { 14228 int imm = SIMM(ctx->opcode, 1, 4); 14229 int rd = (ctx->opcode >> 5) & 0x1f; 14230 14231 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm); 14232 } 14233 14234 static void gen_andi16(DisasContext *ctx) 14235 { 14236 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16, 14237 31, 32, 63, 64, 255, 32768, 65535 }; 14238 int rd = mmreg(uMIPS_RD(ctx->opcode)); 14239 int rs = mmreg(uMIPS_RS(ctx->opcode)); 14240 int encoded = ZIMM(ctx->opcode, 0, 4); 14241 14242 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]); 14243 } 14244 14245 static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist, 14246 int base, int16_t offset) 14247 { 14248 TCGv t0, t1; 14249 TCGv_i32 t2; 14250 14251 if (ctx->hflags & MIPS_HFLAG_BMASK) { 14252 gen_reserved_instruction(ctx); 14253 return; 14254 } 14255 14256 t0 = tcg_temp_new(); 14257 14258 gen_base_offset_addr(ctx, t0, base, offset); 14259 14260 t1 = tcg_const_tl(reglist); 14261 t2 = tcg_const_i32(ctx->mem_idx); 14262 14263 save_cpu_state(ctx, 1); 14264 switch (opc) { 14265 case LWM32: 14266 gen_helper_lwm(cpu_env, t0, t1, t2); 14267 break; 14268 case SWM32: 14269 gen_helper_swm(cpu_env, t0, t1, t2); 14270 break; 14271 #ifdef TARGET_MIPS64 14272 case LDM: 14273 gen_helper_ldm(cpu_env, t0, t1, t2); 14274 break; 14275 case SDM: 14276 gen_helper_sdm(cpu_env, t0, t1, t2); 14277 break; 14278 #endif 14279 } 14280 tcg_temp_free(t0); 14281 tcg_temp_free(t1); 14282 tcg_temp_free_i32(t2); 14283 } 14284 14285 14286 static void gen_pool16c_insn(DisasContext *ctx) 14287 { 14288 int rd = mmreg((ctx->opcode >> 3) & 0x7); 14289 int rs = mmreg(ctx->opcode & 0x7); 14290 14291 switch (((ctx->opcode) >> 4) & 0x3f) { 14292 case NOT16 + 0: 14293 case NOT16 + 1: 14294 case NOT16 + 2: 14295 case NOT16 + 3: 14296 gen_logic(ctx, OPC_NOR, rd, rs, 0); 14297 break; 14298 case XOR16 + 0: 14299 case XOR16 + 1: 14300 case XOR16 + 2: 14301 case XOR16 + 3: 14302 gen_logic(ctx, OPC_XOR, rd, rd, rs); 14303 break; 14304 case AND16 + 0: 14305 case AND16 + 1: 14306 case AND16 + 2: 14307 case AND16 + 3: 14308 gen_logic(ctx, OPC_AND, rd, rd, rs); 14309 break; 14310 case OR16 + 0: 14311 case OR16 + 1: 14312 case OR16 + 2: 14313 case OR16 + 3: 14314 gen_logic(ctx, OPC_OR, rd, rd, rs); 14315 break; 14316 case LWM16 + 0: 14317 case LWM16 + 1: 14318 case LWM16 + 2: 14319 case LWM16 + 3: 14320 { 14321 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 }; 14322 int offset = ZIMM(ctx->opcode, 0, 4); 14323 14324 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3], 14325 29, offset << 2); 14326 } 14327 break; 14328 case SWM16 + 0: 14329 case SWM16 + 1: 14330 case SWM16 + 2: 14331 case SWM16 + 3: 14332 { 14333 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 }; 14334 int offset = ZIMM(ctx->opcode, 0, 4); 14335 14336 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3], 14337 29, offset << 2); 14338 } 14339 break; 14340 case JR16 + 0: 14341 case JR16 + 1: 14342 { 14343 int reg = ctx->opcode & 0x1f; 14344 14345 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4); 14346 } 14347 break; 14348 case JRC16 + 0: 14349 case JRC16 + 1: 14350 { 14351 int reg = ctx->opcode & 0x1f; 14352 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0); 14353 /* 14354 * Let normal delay slot handling in our caller take us 14355 * to the branch target. 14356 */ 14357 } 14358 break; 14359 case JALR16 + 0: 14360 case JALR16 + 1: 14361 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4); 14362 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 14363 break; 14364 case JALR16S + 0: 14365 case JALR16S + 1: 14366 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2); 14367 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 14368 break; 14369 case MFHI16 + 0: 14370 case MFHI16 + 1: 14371 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode)); 14372 break; 14373 case MFLO16 + 0: 14374 case MFLO16 + 1: 14375 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode)); 14376 break; 14377 case BREAK16: 14378 generate_exception_end(ctx, EXCP_BREAK); 14379 break; 14380 case SDBBP16: 14381 if (is_uhi(extract32(ctx->opcode, 0, 4))) { 14382 gen_helper_do_semihosting(cpu_env); 14383 } else { 14384 /* 14385 * XXX: not clear which exception should be raised 14386 * when in debug mode... 14387 */ 14388 check_insn(ctx, ISA_MIPS_R1); 14389 generate_exception_end(ctx, EXCP_DBp); 14390 } 14391 break; 14392 case JRADDIUSP + 0: 14393 case JRADDIUSP + 1: 14394 { 14395 int imm = ZIMM(ctx->opcode, 0, 5); 14396 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); 14397 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); 14398 /* 14399 * Let normal delay slot handling in our caller take us 14400 * to the branch target. 14401 */ 14402 } 14403 break; 14404 default: 14405 gen_reserved_instruction(ctx); 14406 break; 14407 } 14408 } 14409 14410 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt, 14411 int enc_rs) 14412 { 14413 int rd, re; 14414 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 }; 14415 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 }; 14416 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 }; 14417 14418 rd = rd_enc[enc_dest]; 14419 re = re_enc[enc_dest]; 14420 gen_load_gpr(cpu_gpr[rd], rs_rt_enc[enc_rs]); 14421 gen_load_gpr(cpu_gpr[re], rs_rt_enc[enc_rt]); 14422 } 14423 14424 static void gen_pool16c_r6_insn(DisasContext *ctx) 14425 { 14426 int rt = mmreg((ctx->opcode >> 7) & 0x7); 14427 int rs = mmreg((ctx->opcode >> 4) & 0x7); 14428 14429 switch (ctx->opcode & 0xf) { 14430 case R6_NOT16: 14431 gen_logic(ctx, OPC_NOR, rt, rs, 0); 14432 break; 14433 case R6_AND16: 14434 gen_logic(ctx, OPC_AND, rt, rt, rs); 14435 break; 14436 case R6_LWM16: 14437 { 14438 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2); 14439 int offset = extract32(ctx->opcode, 4, 4); 14440 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2); 14441 } 14442 break; 14443 case R6_JRC16: /* JRCADDIUSP */ 14444 if ((ctx->opcode >> 4) & 1) { 14445 /* JRCADDIUSP */ 14446 int imm = extract32(ctx->opcode, 5, 5); 14447 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0); 14448 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); 14449 } else { 14450 /* JRC16 */ 14451 rs = extract32(ctx->opcode, 5, 5); 14452 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0); 14453 } 14454 break; 14455 case MOVEP: 14456 case MOVEP_05: 14457 case MOVEP_06: 14458 case MOVEP_07: 14459 case MOVEP_0C: 14460 case MOVEP_0D: 14461 case MOVEP_0E: 14462 case MOVEP_0F: 14463 { 14464 int enc_dest = uMIPS_RD(ctx->opcode); 14465 int enc_rt = uMIPS_RS2(ctx->opcode); 14466 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4); 14467 gen_movep(ctx, enc_dest, enc_rt, enc_rs); 14468 } 14469 break; 14470 case R6_XOR16: 14471 gen_logic(ctx, OPC_XOR, rt, rt, rs); 14472 break; 14473 case R6_OR16: 14474 gen_logic(ctx, OPC_OR, rt, rt, rs); 14475 break; 14476 case R6_SWM16: 14477 { 14478 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2); 14479 int offset = extract32(ctx->opcode, 4, 4); 14480 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2); 14481 } 14482 break; 14483 case JALRC16: /* BREAK16, SDBBP16 */ 14484 switch (ctx->opcode & 0x3f) { 14485 case JALRC16: 14486 case JALRC16 + 0x20: 14487 /* JALRC16 */ 14488 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f, 14489 31, 0, 0); 14490 break; 14491 case R6_BREAK16: 14492 /* BREAK16 */ 14493 generate_exception(ctx, EXCP_BREAK); 14494 break; 14495 case R6_SDBBP16: 14496 /* SDBBP16 */ 14497 if (is_uhi(extract32(ctx->opcode, 6, 4))) { 14498 gen_helper_do_semihosting(cpu_env); 14499 } else { 14500 if (ctx->hflags & MIPS_HFLAG_SBRI) { 14501 generate_exception(ctx, EXCP_RI); 14502 } else { 14503 generate_exception(ctx, EXCP_DBp); 14504 } 14505 } 14506 break; 14507 } 14508 break; 14509 default: 14510 generate_exception(ctx, EXCP_RI); 14511 break; 14512 } 14513 } 14514 14515 static void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 14516 { 14517 TCGv t0 = tcg_temp_new(); 14518 TCGv t1 = tcg_temp_new(); 14519 14520 gen_load_gpr(t0, base); 14521 14522 if (index != 0) { 14523 gen_load_gpr(t1, index); 14524 tcg_gen_shli_tl(t1, t1, 2); 14525 gen_op_addr_add(ctx, t0, t1, t0); 14526 } 14527 14528 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 14529 gen_store_gpr(t1, rd); 14530 14531 tcg_temp_free(t0); 14532 tcg_temp_free(t1); 14533 } 14534 14535 static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd, 14536 int base, int16_t offset) 14537 { 14538 TCGv t0, t1; 14539 14540 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) { 14541 gen_reserved_instruction(ctx); 14542 return; 14543 } 14544 14545 t0 = tcg_temp_new(); 14546 t1 = tcg_temp_new(); 14547 14548 gen_base_offset_addr(ctx, t0, base, offset); 14549 14550 switch (opc) { 14551 case LWP: 14552 if (rd == base) { 14553 gen_reserved_instruction(ctx); 14554 return; 14555 } 14556 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 14557 gen_store_gpr(t1, rd); 14558 tcg_gen_movi_tl(t1, 4); 14559 gen_op_addr_add(ctx, t0, t0, t1); 14560 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 14561 gen_store_gpr(t1, rd + 1); 14562 break; 14563 case SWP: 14564 gen_load_gpr(t1, rd); 14565 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 14566 tcg_gen_movi_tl(t1, 4); 14567 gen_op_addr_add(ctx, t0, t0, t1); 14568 gen_load_gpr(t1, rd + 1); 14569 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 14570 break; 14571 #ifdef TARGET_MIPS64 14572 case LDP: 14573 if (rd == base) { 14574 gen_reserved_instruction(ctx); 14575 return; 14576 } 14577 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); 14578 gen_store_gpr(t1, rd); 14579 tcg_gen_movi_tl(t1, 8); 14580 gen_op_addr_add(ctx, t0, t0, t1); 14581 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ); 14582 gen_store_gpr(t1, rd + 1); 14583 break; 14584 case SDP: 14585 gen_load_gpr(t1, rd); 14586 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); 14587 tcg_gen_movi_tl(t1, 8); 14588 gen_op_addr_add(ctx, t0, t0, t1); 14589 gen_load_gpr(t1, rd + 1); 14590 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ); 14591 break; 14592 #endif 14593 } 14594 tcg_temp_free(t0); 14595 tcg_temp_free(t1); 14596 } 14597 14598 static void gen_sync(int stype) 14599 { 14600 TCGBar tcg_mo = TCG_BAR_SC; 14601 14602 switch (stype) { 14603 case 0x4: /* SYNC_WMB */ 14604 tcg_mo |= TCG_MO_ST_ST; 14605 break; 14606 case 0x10: /* SYNC_MB */ 14607 tcg_mo |= TCG_MO_ALL; 14608 break; 14609 case 0x11: /* SYNC_ACQUIRE */ 14610 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 14611 break; 14612 case 0x12: /* SYNC_RELEASE */ 14613 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 14614 break; 14615 case 0x13: /* SYNC_RMB */ 14616 tcg_mo |= TCG_MO_LD_LD; 14617 break; 14618 default: 14619 tcg_mo |= TCG_MO_ALL; 14620 break; 14621 } 14622 14623 tcg_gen_mb(tcg_mo); 14624 } 14625 14626 static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs) 14627 { 14628 int extension = (ctx->opcode >> 6) & 0x3f; 14629 int minor = (ctx->opcode >> 12) & 0xf; 14630 uint32_t mips32_op; 14631 14632 switch (extension) { 14633 case TEQ: 14634 mips32_op = OPC_TEQ; 14635 goto do_trap; 14636 case TGE: 14637 mips32_op = OPC_TGE; 14638 goto do_trap; 14639 case TGEU: 14640 mips32_op = OPC_TGEU; 14641 goto do_trap; 14642 case TLT: 14643 mips32_op = OPC_TLT; 14644 goto do_trap; 14645 case TLTU: 14646 mips32_op = OPC_TLTU; 14647 goto do_trap; 14648 case TNE: 14649 mips32_op = OPC_TNE; 14650 do_trap: 14651 gen_trap(ctx, mips32_op, rs, rt, -1); 14652 break; 14653 #ifndef CONFIG_USER_ONLY 14654 case MFC0: 14655 case MFC0 + 32: 14656 check_cp0_enabled(ctx); 14657 if (rt == 0) { 14658 /* Treat as NOP. */ 14659 break; 14660 } 14661 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7); 14662 break; 14663 case MTC0: 14664 case MTC0 + 32: 14665 check_cp0_enabled(ctx); 14666 { 14667 TCGv t0 = tcg_temp_new(); 14668 14669 gen_load_gpr(t0, rt); 14670 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7); 14671 tcg_temp_free(t0); 14672 } 14673 break; 14674 #endif 14675 case 0x2a: 14676 switch (minor & 3) { 14677 case MADD_ACC: 14678 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt); 14679 break; 14680 case MADDU_ACC: 14681 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt); 14682 break; 14683 case MSUB_ACC: 14684 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt); 14685 break; 14686 case MSUBU_ACC: 14687 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt); 14688 break; 14689 default: 14690 goto pool32axf_invalid; 14691 } 14692 break; 14693 case 0x32: 14694 switch (minor & 3) { 14695 case MULT_ACC: 14696 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt); 14697 break; 14698 case MULTU_ACC: 14699 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt); 14700 break; 14701 default: 14702 goto pool32axf_invalid; 14703 } 14704 break; 14705 case 0x2c: 14706 switch (minor) { 14707 case BITSWAP: 14708 check_insn(ctx, ISA_MIPS_R6); 14709 gen_bitswap(ctx, OPC_BITSWAP, rs, rt); 14710 break; 14711 case SEB: 14712 gen_bshfl(ctx, OPC_SEB, rs, rt); 14713 break; 14714 case SEH: 14715 gen_bshfl(ctx, OPC_SEH, rs, rt); 14716 break; 14717 case CLO: 14718 mips32_op = OPC_CLO; 14719 goto do_cl; 14720 case CLZ: 14721 mips32_op = OPC_CLZ; 14722 do_cl: 14723 check_insn(ctx, ISA_MIPS_R1); 14724 gen_cl(ctx, mips32_op, rt, rs); 14725 break; 14726 case RDHWR: 14727 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14728 gen_rdhwr(ctx, rt, rs, 0); 14729 break; 14730 case WSBH: 14731 gen_bshfl(ctx, OPC_WSBH, rs, rt); 14732 break; 14733 case MULT: 14734 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14735 mips32_op = OPC_MULT; 14736 goto do_mul; 14737 case MULTU: 14738 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14739 mips32_op = OPC_MULTU; 14740 goto do_mul; 14741 case DIV: 14742 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14743 mips32_op = OPC_DIV; 14744 goto do_div; 14745 case DIVU: 14746 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14747 mips32_op = OPC_DIVU; 14748 goto do_div; 14749 do_div: 14750 check_insn(ctx, ISA_MIPS_R1); 14751 gen_muldiv(ctx, mips32_op, 0, rs, rt); 14752 break; 14753 case MADD: 14754 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14755 mips32_op = OPC_MADD; 14756 goto do_mul; 14757 case MADDU: 14758 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14759 mips32_op = OPC_MADDU; 14760 goto do_mul; 14761 case MSUB: 14762 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14763 mips32_op = OPC_MSUB; 14764 goto do_mul; 14765 case MSUBU: 14766 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14767 mips32_op = OPC_MSUBU; 14768 do_mul: 14769 check_insn(ctx, ISA_MIPS_R1); 14770 gen_muldiv(ctx, mips32_op, 0, rs, rt); 14771 break; 14772 default: 14773 goto pool32axf_invalid; 14774 } 14775 break; 14776 case 0x34: 14777 switch (minor) { 14778 case MFC2: 14779 case MTC2: 14780 case MFHC2: 14781 case MTHC2: 14782 case CFC2: 14783 case CTC2: 14784 generate_exception_err(ctx, EXCP_CpU, 2); 14785 break; 14786 default: 14787 goto pool32axf_invalid; 14788 } 14789 break; 14790 case 0x3c: 14791 switch (minor) { 14792 case JALR: /* JALRC */ 14793 case JALR_HB: /* JALRC_HB */ 14794 if (ctx->insn_flags & ISA_MIPS_R6) { 14795 /* JALRC, JALRC_HB */ 14796 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0); 14797 } else { 14798 /* JALR, JALR_HB */ 14799 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4); 14800 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 14801 } 14802 break; 14803 case JALRS: 14804 case JALRS_HB: 14805 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14806 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2); 14807 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 14808 break; 14809 default: 14810 goto pool32axf_invalid; 14811 } 14812 break; 14813 case 0x05: 14814 switch (minor) { 14815 case RDPGPR: 14816 check_cp0_enabled(ctx); 14817 check_insn(ctx, ISA_MIPS_R2); 14818 gen_load_srsgpr(rs, rt); 14819 break; 14820 case WRPGPR: 14821 check_cp0_enabled(ctx); 14822 check_insn(ctx, ISA_MIPS_R2); 14823 gen_store_srsgpr(rs, rt); 14824 break; 14825 default: 14826 goto pool32axf_invalid; 14827 } 14828 break; 14829 #ifndef CONFIG_USER_ONLY 14830 case 0x0d: 14831 switch (minor) { 14832 case TLBP: 14833 mips32_op = OPC_TLBP; 14834 goto do_cp0; 14835 case TLBR: 14836 mips32_op = OPC_TLBR; 14837 goto do_cp0; 14838 case TLBWI: 14839 mips32_op = OPC_TLBWI; 14840 goto do_cp0; 14841 case TLBWR: 14842 mips32_op = OPC_TLBWR; 14843 goto do_cp0; 14844 case TLBINV: 14845 mips32_op = OPC_TLBINV; 14846 goto do_cp0; 14847 case TLBINVF: 14848 mips32_op = OPC_TLBINVF; 14849 goto do_cp0; 14850 case WAIT: 14851 mips32_op = OPC_WAIT; 14852 goto do_cp0; 14853 case DERET: 14854 mips32_op = OPC_DERET; 14855 goto do_cp0; 14856 case ERET: 14857 mips32_op = OPC_ERET; 14858 do_cp0: 14859 gen_cp0(env, ctx, mips32_op, rt, rs); 14860 break; 14861 default: 14862 goto pool32axf_invalid; 14863 } 14864 break; 14865 case 0x1d: 14866 switch (minor) { 14867 case DI: 14868 check_cp0_enabled(ctx); 14869 { 14870 TCGv t0 = tcg_temp_new(); 14871 14872 save_cpu_state(ctx, 1); 14873 gen_helper_di(t0, cpu_env); 14874 gen_store_gpr(t0, rs); 14875 /* 14876 * Stop translation as we may have switched the execution 14877 * mode. 14878 */ 14879 ctx->base.is_jmp = DISAS_STOP; 14880 tcg_temp_free(t0); 14881 } 14882 break; 14883 case EI: 14884 check_cp0_enabled(ctx); 14885 { 14886 TCGv t0 = tcg_temp_new(); 14887 14888 save_cpu_state(ctx, 1); 14889 gen_helper_ei(t0, cpu_env); 14890 gen_store_gpr(t0, rs); 14891 /* 14892 * DISAS_STOP isn't sufficient, we need to ensure we break out 14893 * of translated code to check for pending interrupts. 14894 */ 14895 gen_save_pc(ctx->base.pc_next + 4); 14896 ctx->base.is_jmp = DISAS_EXIT; 14897 tcg_temp_free(t0); 14898 } 14899 break; 14900 default: 14901 goto pool32axf_invalid; 14902 } 14903 break; 14904 #endif 14905 case 0x2d: 14906 switch (minor) { 14907 case SYNC: 14908 gen_sync(extract32(ctx->opcode, 16, 5)); 14909 break; 14910 case SYSCALL: 14911 generate_exception_end(ctx, EXCP_SYSCALL); 14912 break; 14913 case SDBBP: 14914 if (is_uhi(extract32(ctx->opcode, 16, 10))) { 14915 gen_helper_do_semihosting(cpu_env); 14916 } else { 14917 check_insn(ctx, ISA_MIPS_R1); 14918 if (ctx->hflags & MIPS_HFLAG_SBRI) { 14919 gen_reserved_instruction(ctx); 14920 } else { 14921 generate_exception_end(ctx, EXCP_DBp); 14922 } 14923 } 14924 break; 14925 default: 14926 goto pool32axf_invalid; 14927 } 14928 break; 14929 case 0x01: 14930 switch (minor & 3) { 14931 case MFHI_ACC: 14932 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs); 14933 break; 14934 case MFLO_ACC: 14935 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs); 14936 break; 14937 case MTHI_ACC: 14938 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs); 14939 break; 14940 case MTLO_ACC: 14941 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs); 14942 break; 14943 default: 14944 goto pool32axf_invalid; 14945 } 14946 break; 14947 case 0x35: 14948 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14949 switch (minor) { 14950 case MFHI32: 14951 gen_HILO(ctx, OPC_MFHI, 0, rs); 14952 break; 14953 case MFLO32: 14954 gen_HILO(ctx, OPC_MFLO, 0, rs); 14955 break; 14956 case MTHI32: 14957 gen_HILO(ctx, OPC_MTHI, 0, rs); 14958 break; 14959 case MTLO32: 14960 gen_HILO(ctx, OPC_MTLO, 0, rs); 14961 break; 14962 default: 14963 goto pool32axf_invalid; 14964 } 14965 break; 14966 default: 14967 pool32axf_invalid: 14968 MIPS_INVAL("pool32axf"); 14969 gen_reserved_instruction(ctx); 14970 break; 14971 } 14972 } 14973 14974 /* 14975 * Values for microMIPS fmt field. Variable-width, depending on which 14976 * formats the instruction supports. 14977 */ 14978 enum { 14979 FMT_SD_S = 0, 14980 FMT_SD_D = 1, 14981 14982 FMT_SDPS_S = 0, 14983 FMT_SDPS_D = 1, 14984 FMT_SDPS_PS = 2, 14985 14986 FMT_SWL_S = 0, 14987 FMT_SWL_W = 1, 14988 FMT_SWL_L = 2, 14989 14990 FMT_DWL_D = 0, 14991 FMT_DWL_W = 1, 14992 FMT_DWL_L = 2 14993 }; 14994 14995 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs) 14996 { 14997 int extension = (ctx->opcode >> 6) & 0x3ff; 14998 uint32_t mips32_op; 14999 15000 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc) 15001 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc) 15002 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc) 15003 15004 switch (extension) { 15005 case FLOAT_1BIT_FMT(CFC1, 0): 15006 mips32_op = OPC_CFC1; 15007 goto do_cp1; 15008 case FLOAT_1BIT_FMT(CTC1, 0): 15009 mips32_op = OPC_CTC1; 15010 goto do_cp1; 15011 case FLOAT_1BIT_FMT(MFC1, 0): 15012 mips32_op = OPC_MFC1; 15013 goto do_cp1; 15014 case FLOAT_1BIT_FMT(MTC1, 0): 15015 mips32_op = OPC_MTC1; 15016 goto do_cp1; 15017 case FLOAT_1BIT_FMT(MFHC1, 0): 15018 mips32_op = OPC_MFHC1; 15019 goto do_cp1; 15020 case FLOAT_1BIT_FMT(MTHC1, 0): 15021 mips32_op = OPC_MTHC1; 15022 do_cp1: 15023 gen_cp1(ctx, mips32_op, rt, rs); 15024 break; 15025 15026 /* Reciprocal square root */ 15027 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S): 15028 mips32_op = OPC_RSQRT_S; 15029 goto do_unaryfp; 15030 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D): 15031 mips32_op = OPC_RSQRT_D; 15032 goto do_unaryfp; 15033 15034 /* Square root */ 15035 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S): 15036 mips32_op = OPC_SQRT_S; 15037 goto do_unaryfp; 15038 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D): 15039 mips32_op = OPC_SQRT_D; 15040 goto do_unaryfp; 15041 15042 /* Reciprocal */ 15043 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S): 15044 mips32_op = OPC_RECIP_S; 15045 goto do_unaryfp; 15046 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D): 15047 mips32_op = OPC_RECIP_D; 15048 goto do_unaryfp; 15049 15050 /* Floor */ 15051 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S): 15052 mips32_op = OPC_FLOOR_L_S; 15053 goto do_unaryfp; 15054 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D): 15055 mips32_op = OPC_FLOOR_L_D; 15056 goto do_unaryfp; 15057 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S): 15058 mips32_op = OPC_FLOOR_W_S; 15059 goto do_unaryfp; 15060 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D): 15061 mips32_op = OPC_FLOOR_W_D; 15062 goto do_unaryfp; 15063 15064 /* Ceiling */ 15065 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S): 15066 mips32_op = OPC_CEIL_L_S; 15067 goto do_unaryfp; 15068 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D): 15069 mips32_op = OPC_CEIL_L_D; 15070 goto do_unaryfp; 15071 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S): 15072 mips32_op = OPC_CEIL_W_S; 15073 goto do_unaryfp; 15074 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D): 15075 mips32_op = OPC_CEIL_W_D; 15076 goto do_unaryfp; 15077 15078 /* Truncation */ 15079 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S): 15080 mips32_op = OPC_TRUNC_L_S; 15081 goto do_unaryfp; 15082 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D): 15083 mips32_op = OPC_TRUNC_L_D; 15084 goto do_unaryfp; 15085 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S): 15086 mips32_op = OPC_TRUNC_W_S; 15087 goto do_unaryfp; 15088 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D): 15089 mips32_op = OPC_TRUNC_W_D; 15090 goto do_unaryfp; 15091 15092 /* Round */ 15093 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S): 15094 mips32_op = OPC_ROUND_L_S; 15095 goto do_unaryfp; 15096 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D): 15097 mips32_op = OPC_ROUND_L_D; 15098 goto do_unaryfp; 15099 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S): 15100 mips32_op = OPC_ROUND_W_S; 15101 goto do_unaryfp; 15102 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D): 15103 mips32_op = OPC_ROUND_W_D; 15104 goto do_unaryfp; 15105 15106 /* Integer to floating-point conversion */ 15107 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S): 15108 mips32_op = OPC_CVT_L_S; 15109 goto do_unaryfp; 15110 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D): 15111 mips32_op = OPC_CVT_L_D; 15112 goto do_unaryfp; 15113 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S): 15114 mips32_op = OPC_CVT_W_S; 15115 goto do_unaryfp; 15116 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D): 15117 mips32_op = OPC_CVT_W_D; 15118 goto do_unaryfp; 15119 15120 /* Paired-foo conversions */ 15121 case FLOAT_1BIT_FMT(CVT_S_PL, 0): 15122 mips32_op = OPC_CVT_S_PL; 15123 goto do_unaryfp; 15124 case FLOAT_1BIT_FMT(CVT_S_PU, 0): 15125 mips32_op = OPC_CVT_S_PU; 15126 goto do_unaryfp; 15127 case FLOAT_1BIT_FMT(CVT_PW_PS, 0): 15128 mips32_op = OPC_CVT_PW_PS; 15129 goto do_unaryfp; 15130 case FLOAT_1BIT_FMT(CVT_PS_PW, 0): 15131 mips32_op = OPC_CVT_PS_PW; 15132 goto do_unaryfp; 15133 15134 /* Floating-point moves */ 15135 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S): 15136 mips32_op = OPC_MOV_S; 15137 goto do_unaryfp; 15138 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D): 15139 mips32_op = OPC_MOV_D; 15140 goto do_unaryfp; 15141 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS): 15142 mips32_op = OPC_MOV_PS; 15143 goto do_unaryfp; 15144 15145 /* Absolute value */ 15146 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S): 15147 mips32_op = OPC_ABS_S; 15148 goto do_unaryfp; 15149 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D): 15150 mips32_op = OPC_ABS_D; 15151 goto do_unaryfp; 15152 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS): 15153 mips32_op = OPC_ABS_PS; 15154 goto do_unaryfp; 15155 15156 /* Negation */ 15157 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S): 15158 mips32_op = OPC_NEG_S; 15159 goto do_unaryfp; 15160 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D): 15161 mips32_op = OPC_NEG_D; 15162 goto do_unaryfp; 15163 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS): 15164 mips32_op = OPC_NEG_PS; 15165 goto do_unaryfp; 15166 15167 /* Reciprocal square root step */ 15168 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S): 15169 mips32_op = OPC_RSQRT1_S; 15170 goto do_unaryfp; 15171 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D): 15172 mips32_op = OPC_RSQRT1_D; 15173 goto do_unaryfp; 15174 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS): 15175 mips32_op = OPC_RSQRT1_PS; 15176 goto do_unaryfp; 15177 15178 /* Reciprocal step */ 15179 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S): 15180 mips32_op = OPC_RECIP1_S; 15181 goto do_unaryfp; 15182 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D): 15183 mips32_op = OPC_RECIP1_S; 15184 goto do_unaryfp; 15185 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS): 15186 mips32_op = OPC_RECIP1_PS; 15187 goto do_unaryfp; 15188 15189 /* Conversions from double */ 15190 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S): 15191 mips32_op = OPC_CVT_D_S; 15192 goto do_unaryfp; 15193 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W): 15194 mips32_op = OPC_CVT_D_W; 15195 goto do_unaryfp; 15196 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L): 15197 mips32_op = OPC_CVT_D_L; 15198 goto do_unaryfp; 15199 15200 /* Conversions from single */ 15201 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D): 15202 mips32_op = OPC_CVT_S_D; 15203 goto do_unaryfp; 15204 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W): 15205 mips32_op = OPC_CVT_S_W; 15206 goto do_unaryfp; 15207 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L): 15208 mips32_op = OPC_CVT_S_L; 15209 do_unaryfp: 15210 gen_farith(ctx, mips32_op, -1, rs, rt, 0); 15211 break; 15212 15213 /* Conditional moves on floating-point codes */ 15214 case COND_FLOAT_MOV(MOVT, 0): 15215 case COND_FLOAT_MOV(MOVT, 1): 15216 case COND_FLOAT_MOV(MOVT, 2): 15217 case COND_FLOAT_MOV(MOVT, 3): 15218 case COND_FLOAT_MOV(MOVT, 4): 15219 case COND_FLOAT_MOV(MOVT, 5): 15220 case COND_FLOAT_MOV(MOVT, 6): 15221 case COND_FLOAT_MOV(MOVT, 7): 15222 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15223 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1); 15224 break; 15225 case COND_FLOAT_MOV(MOVF, 0): 15226 case COND_FLOAT_MOV(MOVF, 1): 15227 case COND_FLOAT_MOV(MOVF, 2): 15228 case COND_FLOAT_MOV(MOVF, 3): 15229 case COND_FLOAT_MOV(MOVF, 4): 15230 case COND_FLOAT_MOV(MOVF, 5): 15231 case COND_FLOAT_MOV(MOVF, 6): 15232 case COND_FLOAT_MOV(MOVF, 7): 15233 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15234 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0); 15235 break; 15236 default: 15237 MIPS_INVAL("pool32fxf"); 15238 gen_reserved_instruction(ctx); 15239 break; 15240 } 15241 } 15242 15243 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) 15244 { 15245 int32_t offset; 15246 uint16_t insn; 15247 int rt, rs, rd, rr; 15248 int16_t imm; 15249 uint32_t op, minor, minor2, mips32_op; 15250 uint32_t cond, fmt, cc; 15251 15252 insn = translator_lduw(env, ctx->base.pc_next + 2); 15253 ctx->opcode = (ctx->opcode << 16) | insn; 15254 15255 rt = (ctx->opcode >> 21) & 0x1f; 15256 rs = (ctx->opcode >> 16) & 0x1f; 15257 rd = (ctx->opcode >> 11) & 0x1f; 15258 rr = (ctx->opcode >> 6) & 0x1f; 15259 imm = (int16_t) ctx->opcode; 15260 15261 op = (ctx->opcode >> 26) & 0x3f; 15262 switch (op) { 15263 case POOL32A: 15264 minor = ctx->opcode & 0x3f; 15265 switch (minor) { 15266 case 0x00: 15267 minor = (ctx->opcode >> 6) & 0xf; 15268 switch (minor) { 15269 case SLL32: 15270 mips32_op = OPC_SLL; 15271 goto do_shifti; 15272 case SRA: 15273 mips32_op = OPC_SRA; 15274 goto do_shifti; 15275 case SRL32: 15276 mips32_op = OPC_SRL; 15277 goto do_shifti; 15278 case ROTR: 15279 mips32_op = OPC_ROTR; 15280 do_shifti: 15281 gen_shift_imm(ctx, mips32_op, rt, rs, rd); 15282 break; 15283 case SELEQZ: 15284 check_insn(ctx, ISA_MIPS_R6); 15285 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt); 15286 break; 15287 case SELNEZ: 15288 check_insn(ctx, ISA_MIPS_R6); 15289 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt); 15290 break; 15291 case R6_RDHWR: 15292 check_insn(ctx, ISA_MIPS_R6); 15293 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); 15294 break; 15295 default: 15296 goto pool32a_invalid; 15297 } 15298 break; 15299 case 0x10: 15300 minor = (ctx->opcode >> 6) & 0xf; 15301 switch (minor) { 15302 /* Arithmetic */ 15303 case ADD: 15304 mips32_op = OPC_ADD; 15305 goto do_arith; 15306 case ADDU32: 15307 mips32_op = OPC_ADDU; 15308 goto do_arith; 15309 case SUB: 15310 mips32_op = OPC_SUB; 15311 goto do_arith; 15312 case SUBU32: 15313 mips32_op = OPC_SUBU; 15314 goto do_arith; 15315 case MUL: 15316 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15317 mips32_op = OPC_MUL; 15318 do_arith: 15319 gen_arith(ctx, mips32_op, rd, rs, rt); 15320 break; 15321 /* Shifts */ 15322 case SLLV: 15323 mips32_op = OPC_SLLV; 15324 goto do_shift; 15325 case SRLV: 15326 mips32_op = OPC_SRLV; 15327 goto do_shift; 15328 case SRAV: 15329 mips32_op = OPC_SRAV; 15330 goto do_shift; 15331 case ROTRV: 15332 mips32_op = OPC_ROTRV; 15333 do_shift: 15334 gen_shift(ctx, mips32_op, rd, rs, rt); 15335 break; 15336 /* Logical operations */ 15337 case AND: 15338 mips32_op = OPC_AND; 15339 goto do_logic; 15340 case OR32: 15341 mips32_op = OPC_OR; 15342 goto do_logic; 15343 case NOR: 15344 mips32_op = OPC_NOR; 15345 goto do_logic; 15346 case XOR32: 15347 mips32_op = OPC_XOR; 15348 do_logic: 15349 gen_logic(ctx, mips32_op, rd, rs, rt); 15350 break; 15351 /* Set less than */ 15352 case SLT: 15353 mips32_op = OPC_SLT; 15354 goto do_slt; 15355 case SLTU: 15356 mips32_op = OPC_SLTU; 15357 do_slt: 15358 gen_slt(ctx, mips32_op, rd, rs, rt); 15359 break; 15360 default: 15361 goto pool32a_invalid; 15362 } 15363 break; 15364 case 0x18: 15365 minor = (ctx->opcode >> 6) & 0xf; 15366 switch (minor) { 15367 /* Conditional moves */ 15368 case MOVN: /* MUL */ 15369 if (ctx->insn_flags & ISA_MIPS_R6) { 15370 /* MUL */ 15371 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); 15372 } else { 15373 /* MOVN */ 15374 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); 15375 } 15376 break; 15377 case MOVZ: /* MUH */ 15378 if (ctx->insn_flags & ISA_MIPS_R6) { 15379 /* MUH */ 15380 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); 15381 } else { 15382 /* MOVZ */ 15383 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); 15384 } 15385 break; 15386 case MULU: 15387 check_insn(ctx, ISA_MIPS_R6); 15388 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); 15389 break; 15390 case MUHU: 15391 check_insn(ctx, ISA_MIPS_R6); 15392 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); 15393 break; 15394 case LWXS: /* DIV */ 15395 if (ctx->insn_flags & ISA_MIPS_R6) { 15396 /* DIV */ 15397 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); 15398 } else { 15399 /* LWXS */ 15400 gen_ldxs(ctx, rs, rt, rd); 15401 } 15402 break; 15403 case MOD: 15404 check_insn(ctx, ISA_MIPS_R6); 15405 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); 15406 break; 15407 case R6_DIVU: 15408 check_insn(ctx, ISA_MIPS_R6); 15409 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); 15410 break; 15411 case MODU: 15412 check_insn(ctx, ISA_MIPS_R6); 15413 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); 15414 break; 15415 default: 15416 goto pool32a_invalid; 15417 } 15418 break; 15419 case INS: 15420 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd); 15421 return; 15422 case LSA: 15423 check_insn(ctx, ISA_MIPS_R6); 15424 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2)); 15425 break; 15426 case ALIGN: 15427 check_insn(ctx, ISA_MIPS_R6); 15428 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2)); 15429 break; 15430 case EXT: 15431 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd); 15432 return; 15433 case POOL32AXF: 15434 gen_pool32axf(env, ctx, rt, rs); 15435 break; 15436 case BREAK32: 15437 generate_exception_end(ctx, EXCP_BREAK); 15438 break; 15439 case SIGRIE: 15440 check_insn(ctx, ISA_MIPS_R6); 15441 gen_reserved_instruction(ctx); 15442 break; 15443 default: 15444 pool32a_invalid: 15445 MIPS_INVAL("pool32a"); 15446 gen_reserved_instruction(ctx); 15447 break; 15448 } 15449 break; 15450 case POOL32B: 15451 minor = (ctx->opcode >> 12) & 0xf; 15452 switch (minor) { 15453 case CACHE: 15454 check_cp0_enabled(ctx); 15455 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15456 gen_cache_operation(ctx, rt, rs, imm); 15457 } 15458 break; 15459 case LWC2: 15460 case SWC2: 15461 /* COP2: Not implemented. */ 15462 generate_exception_err(ctx, EXCP_CpU, 2); 15463 break; 15464 #ifdef TARGET_MIPS64 15465 case LDP: 15466 case SDP: 15467 check_insn(ctx, ISA_MIPS3); 15468 check_mips_64(ctx); 15469 #endif 15470 /* fall through */ 15471 case LWP: 15472 case SWP: 15473 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); 15474 break; 15475 #ifdef TARGET_MIPS64 15476 case LDM: 15477 case SDM: 15478 check_insn(ctx, ISA_MIPS3); 15479 check_mips_64(ctx); 15480 #endif 15481 /* fall through */ 15482 case LWM32: 15483 case SWM32: 15484 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); 15485 break; 15486 default: 15487 MIPS_INVAL("pool32b"); 15488 gen_reserved_instruction(ctx); 15489 break; 15490 } 15491 break; 15492 case POOL32F: 15493 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15494 minor = ctx->opcode & 0x3f; 15495 check_cp1_enabled(ctx); 15496 switch (minor) { 15497 case ALNV_PS: 15498 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15499 mips32_op = OPC_ALNV_PS; 15500 goto do_madd; 15501 case MADD_S: 15502 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15503 mips32_op = OPC_MADD_S; 15504 goto do_madd; 15505 case MADD_D: 15506 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15507 mips32_op = OPC_MADD_D; 15508 goto do_madd; 15509 case MADD_PS: 15510 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15511 mips32_op = OPC_MADD_PS; 15512 goto do_madd; 15513 case MSUB_S: 15514 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15515 mips32_op = OPC_MSUB_S; 15516 goto do_madd; 15517 case MSUB_D: 15518 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15519 mips32_op = OPC_MSUB_D; 15520 goto do_madd; 15521 case MSUB_PS: 15522 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15523 mips32_op = OPC_MSUB_PS; 15524 goto do_madd; 15525 case NMADD_S: 15526 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15527 mips32_op = OPC_NMADD_S; 15528 goto do_madd; 15529 case NMADD_D: 15530 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15531 mips32_op = OPC_NMADD_D; 15532 goto do_madd; 15533 case NMADD_PS: 15534 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15535 mips32_op = OPC_NMADD_PS; 15536 goto do_madd; 15537 case NMSUB_S: 15538 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15539 mips32_op = OPC_NMSUB_S; 15540 goto do_madd; 15541 case NMSUB_D: 15542 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15543 mips32_op = OPC_NMSUB_D; 15544 goto do_madd; 15545 case NMSUB_PS: 15546 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15547 mips32_op = OPC_NMSUB_PS; 15548 do_madd: 15549 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt); 15550 break; 15551 case CABS_COND_FMT: 15552 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15553 cond = (ctx->opcode >> 6) & 0xf; 15554 cc = (ctx->opcode >> 13) & 0x7; 15555 fmt = (ctx->opcode >> 10) & 0x3; 15556 switch (fmt) { 15557 case 0x0: 15558 gen_cmpabs_s(ctx, cond, rt, rs, cc); 15559 break; 15560 case 0x1: 15561 gen_cmpabs_d(ctx, cond, rt, rs, cc); 15562 break; 15563 case 0x2: 15564 gen_cmpabs_ps(ctx, cond, rt, rs, cc); 15565 break; 15566 default: 15567 goto pool32f_invalid; 15568 } 15569 break; 15570 case C_COND_FMT: 15571 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15572 cond = (ctx->opcode >> 6) & 0xf; 15573 cc = (ctx->opcode >> 13) & 0x7; 15574 fmt = (ctx->opcode >> 10) & 0x3; 15575 switch (fmt) { 15576 case 0x0: 15577 gen_cmp_s(ctx, cond, rt, rs, cc); 15578 break; 15579 case 0x1: 15580 gen_cmp_d(ctx, cond, rt, rs, cc); 15581 break; 15582 case 0x2: 15583 gen_cmp_ps(ctx, cond, rt, rs, cc); 15584 break; 15585 default: 15586 goto pool32f_invalid; 15587 } 15588 break; 15589 case CMP_CONDN_S: 15590 check_insn(ctx, ISA_MIPS_R6); 15591 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); 15592 break; 15593 case CMP_CONDN_D: 15594 check_insn(ctx, ISA_MIPS_R6); 15595 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd); 15596 break; 15597 case POOL32FXF: 15598 gen_pool32fxf(ctx, rt, rs); 15599 break; 15600 case 0x00: 15601 /* PLL foo */ 15602 switch ((ctx->opcode >> 6) & 0x7) { 15603 case PLL_PS: 15604 mips32_op = OPC_PLL_PS; 15605 goto do_ps; 15606 case PLU_PS: 15607 mips32_op = OPC_PLU_PS; 15608 goto do_ps; 15609 case PUL_PS: 15610 mips32_op = OPC_PUL_PS; 15611 goto do_ps; 15612 case PUU_PS: 15613 mips32_op = OPC_PUU_PS; 15614 goto do_ps; 15615 case CVT_PS_S: 15616 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15617 mips32_op = OPC_CVT_PS_S; 15618 do_ps: 15619 gen_farith(ctx, mips32_op, rt, rs, rd, 0); 15620 break; 15621 default: 15622 goto pool32f_invalid; 15623 } 15624 break; 15625 case MIN_FMT: 15626 check_insn(ctx, ISA_MIPS_R6); 15627 switch ((ctx->opcode >> 9) & 0x3) { 15628 case FMT_SDPS_S: 15629 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); 15630 break; 15631 case FMT_SDPS_D: 15632 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); 15633 break; 15634 default: 15635 goto pool32f_invalid; 15636 } 15637 break; 15638 case 0x08: 15639 /* [LS][WDU]XC1 */ 15640 switch ((ctx->opcode >> 6) & 0x7) { 15641 case LWXC1: 15642 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15643 mips32_op = OPC_LWXC1; 15644 goto do_ldst_cp1; 15645 case SWXC1: 15646 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15647 mips32_op = OPC_SWXC1; 15648 goto do_ldst_cp1; 15649 case LDXC1: 15650 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15651 mips32_op = OPC_LDXC1; 15652 goto do_ldst_cp1; 15653 case SDXC1: 15654 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15655 mips32_op = OPC_SDXC1; 15656 goto do_ldst_cp1; 15657 case LUXC1: 15658 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15659 mips32_op = OPC_LUXC1; 15660 goto do_ldst_cp1; 15661 case SUXC1: 15662 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15663 mips32_op = OPC_SUXC1; 15664 do_ldst_cp1: 15665 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs); 15666 break; 15667 default: 15668 goto pool32f_invalid; 15669 } 15670 break; 15671 case MAX_FMT: 15672 check_insn(ctx, ISA_MIPS_R6); 15673 switch ((ctx->opcode >> 9) & 0x3) { 15674 case FMT_SDPS_S: 15675 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); 15676 break; 15677 case FMT_SDPS_D: 15678 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); 15679 break; 15680 default: 15681 goto pool32f_invalid; 15682 } 15683 break; 15684 case 0x18: 15685 /* 3D insns */ 15686 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15687 fmt = (ctx->opcode >> 9) & 0x3; 15688 switch ((ctx->opcode >> 6) & 0x7) { 15689 case RSQRT2_FMT: 15690 switch (fmt) { 15691 case FMT_SDPS_S: 15692 mips32_op = OPC_RSQRT2_S; 15693 goto do_3d; 15694 case FMT_SDPS_D: 15695 mips32_op = OPC_RSQRT2_D; 15696 goto do_3d; 15697 case FMT_SDPS_PS: 15698 mips32_op = OPC_RSQRT2_PS; 15699 goto do_3d; 15700 default: 15701 goto pool32f_invalid; 15702 } 15703 break; 15704 case RECIP2_FMT: 15705 switch (fmt) { 15706 case FMT_SDPS_S: 15707 mips32_op = OPC_RECIP2_S; 15708 goto do_3d; 15709 case FMT_SDPS_D: 15710 mips32_op = OPC_RECIP2_D; 15711 goto do_3d; 15712 case FMT_SDPS_PS: 15713 mips32_op = OPC_RECIP2_PS; 15714 goto do_3d; 15715 default: 15716 goto pool32f_invalid; 15717 } 15718 break; 15719 case ADDR_PS: 15720 mips32_op = OPC_ADDR_PS; 15721 goto do_3d; 15722 case MULR_PS: 15723 mips32_op = OPC_MULR_PS; 15724 do_3d: 15725 gen_farith(ctx, mips32_op, rt, rs, rd, 0); 15726 break; 15727 default: 15728 goto pool32f_invalid; 15729 } 15730 break; 15731 case 0x20: 15732 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/ 15733 cc = (ctx->opcode >> 13) & 0x7; 15734 fmt = (ctx->opcode >> 9) & 0x3; 15735 switch ((ctx->opcode >> 6) & 0x7) { 15736 case MOVF_FMT: /* RINT_FMT */ 15737 if (ctx->insn_flags & ISA_MIPS_R6) { 15738 /* RINT_FMT */ 15739 switch (fmt) { 15740 case FMT_SDPS_S: 15741 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); 15742 break; 15743 case FMT_SDPS_D: 15744 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); 15745 break; 15746 default: 15747 goto pool32f_invalid; 15748 } 15749 } else { 15750 /* MOVF_FMT */ 15751 switch (fmt) { 15752 case FMT_SDPS_S: 15753 gen_movcf_s(ctx, rs, rt, cc, 0); 15754 break; 15755 case FMT_SDPS_D: 15756 gen_movcf_d(ctx, rs, rt, cc, 0); 15757 break; 15758 case FMT_SDPS_PS: 15759 check_ps(ctx); 15760 gen_movcf_ps(ctx, rs, rt, cc, 0); 15761 break; 15762 default: 15763 goto pool32f_invalid; 15764 } 15765 } 15766 break; 15767 case MOVT_FMT: /* CLASS_FMT */ 15768 if (ctx->insn_flags & ISA_MIPS_R6) { 15769 /* CLASS_FMT */ 15770 switch (fmt) { 15771 case FMT_SDPS_S: 15772 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); 15773 break; 15774 case FMT_SDPS_D: 15775 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); 15776 break; 15777 default: 15778 goto pool32f_invalid; 15779 } 15780 } else { 15781 /* MOVT_FMT */ 15782 switch (fmt) { 15783 case FMT_SDPS_S: 15784 gen_movcf_s(ctx, rs, rt, cc, 1); 15785 break; 15786 case FMT_SDPS_D: 15787 gen_movcf_d(ctx, rs, rt, cc, 1); 15788 break; 15789 case FMT_SDPS_PS: 15790 check_ps(ctx); 15791 gen_movcf_ps(ctx, rs, rt, cc, 1); 15792 break; 15793 default: 15794 goto pool32f_invalid; 15795 } 15796 } 15797 break; 15798 case PREFX: 15799 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15800 break; 15801 default: 15802 goto pool32f_invalid; 15803 } 15804 break; 15805 #define FINSN_3ARG_SDPS(prfx) \ 15806 switch ((ctx->opcode >> 8) & 0x3) { \ 15807 case FMT_SDPS_S: \ 15808 mips32_op = OPC_##prfx##_S; \ 15809 goto do_fpop; \ 15810 case FMT_SDPS_D: \ 15811 mips32_op = OPC_##prfx##_D; \ 15812 goto do_fpop; \ 15813 case FMT_SDPS_PS: \ 15814 check_ps(ctx); \ 15815 mips32_op = OPC_##prfx##_PS; \ 15816 goto do_fpop; \ 15817 default: \ 15818 goto pool32f_invalid; \ 15819 } 15820 case MINA_FMT: 15821 check_insn(ctx, ISA_MIPS_R6); 15822 switch ((ctx->opcode >> 9) & 0x3) { 15823 case FMT_SDPS_S: 15824 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); 15825 break; 15826 case FMT_SDPS_D: 15827 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); 15828 break; 15829 default: 15830 goto pool32f_invalid; 15831 } 15832 break; 15833 case MAXA_FMT: 15834 check_insn(ctx, ISA_MIPS_R6); 15835 switch ((ctx->opcode >> 9) & 0x3) { 15836 case FMT_SDPS_S: 15837 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); 15838 break; 15839 case FMT_SDPS_D: 15840 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); 15841 break; 15842 default: 15843 goto pool32f_invalid; 15844 } 15845 break; 15846 case 0x30: 15847 /* regular FP ops */ 15848 switch ((ctx->opcode >> 6) & 0x3) { 15849 case ADD_FMT: 15850 FINSN_3ARG_SDPS(ADD); 15851 break; 15852 case SUB_FMT: 15853 FINSN_3ARG_SDPS(SUB); 15854 break; 15855 case MUL_FMT: 15856 FINSN_3ARG_SDPS(MUL); 15857 break; 15858 case DIV_FMT: 15859 fmt = (ctx->opcode >> 8) & 0x3; 15860 if (fmt == 1) { 15861 mips32_op = OPC_DIV_D; 15862 } else if (fmt == 0) { 15863 mips32_op = OPC_DIV_S; 15864 } else { 15865 goto pool32f_invalid; 15866 } 15867 goto do_fpop; 15868 default: 15869 goto pool32f_invalid; 15870 } 15871 break; 15872 case 0x38: 15873 /* cmovs */ 15874 switch ((ctx->opcode >> 6) & 0x7) { 15875 case MOVN_FMT: /* SELEQZ_FMT */ 15876 if (ctx->insn_flags & ISA_MIPS_R6) { 15877 /* SELEQZ_FMT */ 15878 switch ((ctx->opcode >> 9) & 0x3) { 15879 case FMT_SDPS_S: 15880 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); 15881 break; 15882 case FMT_SDPS_D: 15883 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); 15884 break; 15885 default: 15886 goto pool32f_invalid; 15887 } 15888 } else { 15889 /* MOVN_FMT */ 15890 FINSN_3ARG_SDPS(MOVN); 15891 } 15892 break; 15893 case MOVN_FMT_04: 15894 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15895 FINSN_3ARG_SDPS(MOVN); 15896 break; 15897 case MOVZ_FMT: /* SELNEZ_FMT */ 15898 if (ctx->insn_flags & ISA_MIPS_R6) { 15899 /* SELNEZ_FMT */ 15900 switch ((ctx->opcode >> 9) & 0x3) { 15901 case FMT_SDPS_S: 15902 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); 15903 break; 15904 case FMT_SDPS_D: 15905 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); 15906 break; 15907 default: 15908 goto pool32f_invalid; 15909 } 15910 } else { 15911 /* MOVZ_FMT */ 15912 FINSN_3ARG_SDPS(MOVZ); 15913 } 15914 break; 15915 case MOVZ_FMT_05: 15916 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15917 FINSN_3ARG_SDPS(MOVZ); 15918 break; 15919 case SEL_FMT: 15920 check_insn(ctx, ISA_MIPS_R6); 15921 switch ((ctx->opcode >> 9) & 0x3) { 15922 case FMT_SDPS_S: 15923 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); 15924 break; 15925 case FMT_SDPS_D: 15926 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); 15927 break; 15928 default: 15929 goto pool32f_invalid; 15930 } 15931 break; 15932 case MADDF_FMT: 15933 check_insn(ctx, ISA_MIPS_R6); 15934 switch ((ctx->opcode >> 9) & 0x3) { 15935 case FMT_SDPS_S: 15936 mips32_op = OPC_MADDF_S; 15937 goto do_fpop; 15938 case FMT_SDPS_D: 15939 mips32_op = OPC_MADDF_D; 15940 goto do_fpop; 15941 default: 15942 goto pool32f_invalid; 15943 } 15944 break; 15945 case MSUBF_FMT: 15946 check_insn(ctx, ISA_MIPS_R6); 15947 switch ((ctx->opcode >> 9) & 0x3) { 15948 case FMT_SDPS_S: 15949 mips32_op = OPC_MSUBF_S; 15950 goto do_fpop; 15951 case FMT_SDPS_D: 15952 mips32_op = OPC_MSUBF_D; 15953 goto do_fpop; 15954 default: 15955 goto pool32f_invalid; 15956 } 15957 break; 15958 default: 15959 goto pool32f_invalid; 15960 } 15961 break; 15962 do_fpop: 15963 gen_farith(ctx, mips32_op, rt, rs, rd, 0); 15964 break; 15965 default: 15966 pool32f_invalid: 15967 MIPS_INVAL("pool32f"); 15968 gen_reserved_instruction(ctx); 15969 break; 15970 } 15971 } else { 15972 generate_exception_err(ctx, EXCP_CpU, 1); 15973 } 15974 break; 15975 case POOL32I: 15976 minor = (ctx->opcode >> 21) & 0x1f; 15977 switch (minor) { 15978 case BLTZ: 15979 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15980 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4); 15981 break; 15982 case BLTZAL: 15983 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15984 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4); 15985 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 15986 break; 15987 case BLTZALS: 15988 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15989 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2); 15990 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 15991 break; 15992 case BGEZ: 15993 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15994 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4); 15995 break; 15996 case BGEZAL: 15997 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15998 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4); 15999 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 16000 break; 16001 case BGEZALS: 16002 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16003 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2); 16004 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 16005 break; 16006 case BLEZ: 16007 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16008 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4); 16009 break; 16010 case BGTZ: 16011 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16012 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4); 16013 break; 16014 16015 /* Traps */ 16016 case TLTI: /* BC1EQZC */ 16017 if (ctx->insn_flags & ISA_MIPS_R6) { 16018 /* BC1EQZC */ 16019 check_cp1_enabled(ctx); 16020 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0); 16021 } else { 16022 /* TLTI */ 16023 mips32_op = OPC_TLTI; 16024 goto do_trapi; 16025 } 16026 break; 16027 case TGEI: /* BC1NEZC */ 16028 if (ctx->insn_flags & ISA_MIPS_R6) { 16029 /* BC1NEZC */ 16030 check_cp1_enabled(ctx); 16031 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0); 16032 } else { 16033 /* TGEI */ 16034 mips32_op = OPC_TGEI; 16035 goto do_trapi; 16036 } 16037 break; 16038 case TLTIU: 16039 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16040 mips32_op = OPC_TLTIU; 16041 goto do_trapi; 16042 case TGEIU: 16043 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16044 mips32_op = OPC_TGEIU; 16045 goto do_trapi; 16046 case TNEI: /* SYNCI */ 16047 if (ctx->insn_flags & ISA_MIPS_R6) { 16048 /* SYNCI */ 16049 /* 16050 * Break the TB to be able to sync copied instructions 16051 * immediately. 16052 */ 16053 ctx->base.is_jmp = DISAS_STOP; 16054 } else { 16055 /* TNEI */ 16056 mips32_op = OPC_TNEI; 16057 goto do_trapi; 16058 } 16059 break; 16060 case TEQI: 16061 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16062 mips32_op = OPC_TEQI; 16063 do_trapi: 16064 gen_trap(ctx, mips32_op, rs, -1, imm); 16065 break; 16066 16067 case BNEZC: 16068 case BEQZC: 16069 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16070 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ, 16071 4, rs, 0, imm << 1, 0); 16072 /* 16073 * Compact branches don't have a delay slot, so just let 16074 * the normal delay slot handling take us to the branch 16075 * target. 16076 */ 16077 break; 16078 case LUI: 16079 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16080 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm); 16081 break; 16082 case SYNCI: 16083 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16084 /* 16085 * Break the TB to be able to sync copied instructions 16086 * immediately. 16087 */ 16088 ctx->base.is_jmp = DISAS_STOP; 16089 break; 16090 case BC2F: 16091 case BC2T: 16092 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16093 /* COP2: Not implemented. */ 16094 generate_exception_err(ctx, EXCP_CpU, 2); 16095 break; 16096 case BC1F: 16097 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16098 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F; 16099 goto do_cp1branch; 16100 case BC1T: 16101 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16102 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T; 16103 goto do_cp1branch; 16104 case BC1ANY4F: 16105 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16106 mips32_op = OPC_BC1FANY4; 16107 goto do_cp1mips3d; 16108 case BC1ANY4T: 16109 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16110 mips32_op = OPC_BC1TANY4; 16111 do_cp1mips3d: 16112 check_cop1x(ctx); 16113 check_insn(ctx, ASE_MIPS3D); 16114 /* Fall through */ 16115 do_cp1branch: 16116 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 16117 check_cp1_enabled(ctx); 16118 gen_compute_branch1(ctx, mips32_op, 16119 (ctx->opcode >> 18) & 0x7, imm << 1); 16120 } else { 16121 generate_exception_err(ctx, EXCP_CpU, 1); 16122 } 16123 break; 16124 case BPOSGE64: 16125 case BPOSGE32: 16126 /* MIPS DSP: not implemented */ 16127 /* Fall through */ 16128 default: 16129 MIPS_INVAL("pool32i"); 16130 gen_reserved_instruction(ctx); 16131 break; 16132 } 16133 break; 16134 case POOL32C: 16135 minor = (ctx->opcode >> 12) & 0xf; 16136 offset = sextract32(ctx->opcode, 0, 16137 (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12); 16138 switch (minor) { 16139 case LWL: 16140 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16141 mips32_op = OPC_LWL; 16142 goto do_ld_lr; 16143 case SWL: 16144 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16145 mips32_op = OPC_SWL; 16146 goto do_st_lr; 16147 case LWR: 16148 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16149 mips32_op = OPC_LWR; 16150 goto do_ld_lr; 16151 case SWR: 16152 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16153 mips32_op = OPC_SWR; 16154 goto do_st_lr; 16155 #if defined(TARGET_MIPS64) 16156 case LDL: 16157 check_insn(ctx, ISA_MIPS3); 16158 check_mips_64(ctx); 16159 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16160 mips32_op = OPC_LDL; 16161 goto do_ld_lr; 16162 case SDL: 16163 check_insn(ctx, ISA_MIPS3); 16164 check_mips_64(ctx); 16165 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16166 mips32_op = OPC_SDL; 16167 goto do_st_lr; 16168 case LDR: 16169 check_insn(ctx, ISA_MIPS3); 16170 check_mips_64(ctx); 16171 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16172 mips32_op = OPC_LDR; 16173 goto do_ld_lr; 16174 case SDR: 16175 check_insn(ctx, ISA_MIPS3); 16176 check_mips_64(ctx); 16177 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16178 mips32_op = OPC_SDR; 16179 goto do_st_lr; 16180 case LWU: 16181 check_insn(ctx, ISA_MIPS3); 16182 check_mips_64(ctx); 16183 mips32_op = OPC_LWU; 16184 goto do_ld_lr; 16185 case LLD: 16186 check_insn(ctx, ISA_MIPS3); 16187 check_mips_64(ctx); 16188 mips32_op = OPC_LLD; 16189 goto do_ld_lr; 16190 #endif 16191 case LL: 16192 mips32_op = OPC_LL; 16193 goto do_ld_lr; 16194 do_ld_lr: 16195 gen_ld(ctx, mips32_op, rt, rs, offset); 16196 break; 16197 do_st_lr: 16198 gen_st(ctx, mips32_op, rt, rs, offset); 16199 break; 16200 case SC: 16201 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false); 16202 break; 16203 #if defined(TARGET_MIPS64) 16204 case SCD: 16205 check_insn(ctx, ISA_MIPS3); 16206 check_mips_64(ctx); 16207 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false); 16208 break; 16209 #endif 16210 case LD_EVA: 16211 if (!ctx->eva) { 16212 MIPS_INVAL("pool32c ld-eva"); 16213 gen_reserved_instruction(ctx); 16214 break; 16215 } 16216 check_cp0_enabled(ctx); 16217 16218 minor2 = (ctx->opcode >> 9) & 0x7; 16219 offset = sextract32(ctx->opcode, 0, 9); 16220 switch (minor2) { 16221 case LBUE: 16222 mips32_op = OPC_LBUE; 16223 goto do_ld_lr; 16224 case LHUE: 16225 mips32_op = OPC_LHUE; 16226 goto do_ld_lr; 16227 case LWLE: 16228 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16229 mips32_op = OPC_LWLE; 16230 goto do_ld_lr; 16231 case LWRE: 16232 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16233 mips32_op = OPC_LWRE; 16234 goto do_ld_lr; 16235 case LBE: 16236 mips32_op = OPC_LBE; 16237 goto do_ld_lr; 16238 case LHE: 16239 mips32_op = OPC_LHE; 16240 goto do_ld_lr; 16241 case LLE: 16242 mips32_op = OPC_LLE; 16243 goto do_ld_lr; 16244 case LWE: 16245 mips32_op = OPC_LWE; 16246 goto do_ld_lr; 16247 }; 16248 break; 16249 case ST_EVA: 16250 if (!ctx->eva) { 16251 MIPS_INVAL("pool32c st-eva"); 16252 gen_reserved_instruction(ctx); 16253 break; 16254 } 16255 check_cp0_enabled(ctx); 16256 16257 minor2 = (ctx->opcode >> 9) & 0x7; 16258 offset = sextract32(ctx->opcode, 0, 9); 16259 switch (minor2) { 16260 case SWLE: 16261 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16262 mips32_op = OPC_SWLE; 16263 goto do_st_lr; 16264 case SWRE: 16265 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16266 mips32_op = OPC_SWRE; 16267 goto do_st_lr; 16268 case PREFE: 16269 /* Treat as no-op */ 16270 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) { 16271 /* hint codes 24-31 are reserved and signal RI */ 16272 generate_exception(ctx, EXCP_RI); 16273 } 16274 break; 16275 case CACHEE: 16276 /* Treat as no-op */ 16277 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 16278 gen_cache_operation(ctx, rt, rs, offset); 16279 } 16280 break; 16281 case SBE: 16282 mips32_op = OPC_SBE; 16283 goto do_st_lr; 16284 case SHE: 16285 mips32_op = OPC_SHE; 16286 goto do_st_lr; 16287 case SCE: 16288 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true); 16289 break; 16290 case SWE: 16291 mips32_op = OPC_SWE; 16292 goto do_st_lr; 16293 }; 16294 break; 16295 case PREF: 16296 /* Treat as no-op */ 16297 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) { 16298 /* hint codes 24-31 are reserved and signal RI */ 16299 generate_exception(ctx, EXCP_RI); 16300 } 16301 break; 16302 default: 16303 MIPS_INVAL("pool32c"); 16304 gen_reserved_instruction(ctx); 16305 break; 16306 } 16307 break; 16308 case ADDI32: /* AUI, LUI */ 16309 if (ctx->insn_flags & ISA_MIPS_R6) { 16310 /* AUI, LUI */ 16311 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm); 16312 } else { 16313 /* ADDI32 */ 16314 mips32_op = OPC_ADDI; 16315 goto do_addi; 16316 } 16317 break; 16318 case ADDIU32: 16319 mips32_op = OPC_ADDIU; 16320 do_addi: 16321 gen_arith_imm(ctx, mips32_op, rt, rs, imm); 16322 break; 16323 16324 /* Logical operations */ 16325 case ORI32: 16326 mips32_op = OPC_ORI; 16327 goto do_logici; 16328 case XORI32: 16329 mips32_op = OPC_XORI; 16330 goto do_logici; 16331 case ANDI32: 16332 mips32_op = OPC_ANDI; 16333 do_logici: 16334 gen_logic_imm(ctx, mips32_op, rt, rs, imm); 16335 break; 16336 16337 /* Set less than immediate */ 16338 case SLTI32: 16339 mips32_op = OPC_SLTI; 16340 goto do_slti; 16341 case SLTIU32: 16342 mips32_op = OPC_SLTIU; 16343 do_slti: 16344 gen_slt_imm(ctx, mips32_op, rt, rs, imm); 16345 break; 16346 case JALX32: 16347 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16348 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 16349 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4); 16350 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 16351 break; 16352 case JALS32: /* BOVC, BEQC, BEQZALC */ 16353 if (ctx->insn_flags & ISA_MIPS_R6) { 16354 if (rs >= rt) { 16355 /* BOVC */ 16356 mips32_op = OPC_BOVC; 16357 } else if (rs < rt && rs == 0) { 16358 /* BEQZALC */ 16359 mips32_op = OPC_BEQZALC; 16360 } else { 16361 /* BEQC */ 16362 mips32_op = OPC_BEQC; 16363 } 16364 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16365 } else { 16366 /* JALS32 */ 16367 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1; 16368 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2); 16369 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 16370 } 16371 break; 16372 case BEQ32: /* BC */ 16373 if (ctx->insn_flags & ISA_MIPS_R6) { 16374 /* BC */ 16375 gen_compute_compact_branch(ctx, OPC_BC, 0, 0, 16376 sextract32(ctx->opcode << 1, 0, 27)); 16377 } else { 16378 /* BEQ32 */ 16379 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4); 16380 } 16381 break; 16382 case BNE32: /* BALC */ 16383 if (ctx->insn_flags & ISA_MIPS_R6) { 16384 /* BALC */ 16385 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0, 16386 sextract32(ctx->opcode << 1, 0, 27)); 16387 } else { 16388 /* BNE32 */ 16389 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4); 16390 } 16391 break; 16392 case J32: /* BGTZC, BLTZC, BLTC */ 16393 if (ctx->insn_flags & ISA_MIPS_R6) { 16394 if (rs == 0 && rt != 0) { 16395 /* BGTZC */ 16396 mips32_op = OPC_BGTZC; 16397 } else if (rs != 0 && rt != 0 && rs == rt) { 16398 /* BLTZC */ 16399 mips32_op = OPC_BLTZC; 16400 } else { 16401 /* BLTC */ 16402 mips32_op = OPC_BLTC; 16403 } 16404 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16405 } else { 16406 /* J32 */ 16407 gen_compute_branch(ctx, OPC_J, 4, rt, rs, 16408 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); 16409 } 16410 break; 16411 case JAL32: /* BLEZC, BGEZC, BGEC */ 16412 if (ctx->insn_flags & ISA_MIPS_R6) { 16413 if (rs == 0 && rt != 0) { 16414 /* BLEZC */ 16415 mips32_op = OPC_BLEZC; 16416 } else if (rs != 0 && rt != 0 && rs == rt) { 16417 /* BGEZC */ 16418 mips32_op = OPC_BGEZC; 16419 } else { 16420 /* BGEC */ 16421 mips32_op = OPC_BGEC; 16422 } 16423 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16424 } else { 16425 /* JAL32 */ 16426 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, 16427 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4); 16428 ctx->hflags |= MIPS_HFLAG_BDS_STRICT; 16429 } 16430 break; 16431 /* Floating point (COP1) */ 16432 case LWC132: 16433 mips32_op = OPC_LWC1; 16434 goto do_cop1; 16435 case LDC132: 16436 mips32_op = OPC_LDC1; 16437 goto do_cop1; 16438 case SWC132: 16439 mips32_op = OPC_SWC1; 16440 goto do_cop1; 16441 case SDC132: 16442 mips32_op = OPC_SDC1; 16443 do_cop1: 16444 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm); 16445 break; 16446 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ 16447 if (ctx->insn_flags & ISA_MIPS_R6) { 16448 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ 16449 switch ((ctx->opcode >> 16) & 0x1f) { 16450 case ADDIUPC_00: 16451 case ADDIUPC_01: 16452 case ADDIUPC_02: 16453 case ADDIUPC_03: 16454 case ADDIUPC_04: 16455 case ADDIUPC_05: 16456 case ADDIUPC_06: 16457 case ADDIUPC_07: 16458 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt); 16459 break; 16460 case AUIPC: 16461 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt); 16462 break; 16463 case ALUIPC: 16464 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt); 16465 break; 16466 case LWPC_08: 16467 case LWPC_09: 16468 case LWPC_0A: 16469 case LWPC_0B: 16470 case LWPC_0C: 16471 case LWPC_0D: 16472 case LWPC_0E: 16473 case LWPC_0F: 16474 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt); 16475 break; 16476 default: 16477 generate_exception(ctx, EXCP_RI); 16478 break; 16479 } 16480 } else { 16481 /* ADDIUPC */ 16482 int reg = mmreg(ZIMM(ctx->opcode, 23, 3)); 16483 offset = SIMM(ctx->opcode, 0, 23) << 2; 16484 16485 gen_addiupc(ctx, reg, offset, 0, 0); 16486 } 16487 break; 16488 case BNVC: /* BNEC, BNEZALC */ 16489 check_insn(ctx, ISA_MIPS_R6); 16490 if (rs >= rt) { 16491 /* BNVC */ 16492 mips32_op = OPC_BNVC; 16493 } else if (rs < rt && rs == 0) { 16494 /* BNEZALC */ 16495 mips32_op = OPC_BNEZALC; 16496 } else { 16497 /* BNEC */ 16498 mips32_op = OPC_BNEC; 16499 } 16500 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16501 break; 16502 case R6_BNEZC: /* JIALC */ 16503 check_insn(ctx, ISA_MIPS_R6); 16504 if (rt != 0) { 16505 /* BNEZC */ 16506 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0, 16507 sextract32(ctx->opcode << 1, 0, 22)); 16508 } else { 16509 /* JIALC */ 16510 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm); 16511 } 16512 break; 16513 case R6_BEQZC: /* JIC */ 16514 check_insn(ctx, ISA_MIPS_R6); 16515 if (rt != 0) { 16516 /* BEQZC */ 16517 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, 16518 sextract32(ctx->opcode << 1, 0, 22)); 16519 } else { 16520 /* JIC */ 16521 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm); 16522 } 16523 break; 16524 case BLEZALC: /* BGEZALC, BGEUC */ 16525 check_insn(ctx, ISA_MIPS_R6); 16526 if (rs == 0 && rt != 0) { 16527 /* BLEZALC */ 16528 mips32_op = OPC_BLEZALC; 16529 } else if (rs != 0 && rt != 0 && rs == rt) { 16530 /* BGEZALC */ 16531 mips32_op = OPC_BGEZALC; 16532 } else { 16533 /* BGEUC */ 16534 mips32_op = OPC_BGEUC; 16535 } 16536 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16537 break; 16538 case BGTZALC: /* BLTZALC, BLTUC */ 16539 check_insn(ctx, ISA_MIPS_R6); 16540 if (rs == 0 && rt != 0) { 16541 /* BGTZALC */ 16542 mips32_op = OPC_BGTZALC; 16543 } else if (rs != 0 && rt != 0 && rs == rt) { 16544 /* BLTZALC */ 16545 mips32_op = OPC_BLTZALC; 16546 } else { 16547 /* BLTUC */ 16548 mips32_op = OPC_BLTUC; 16549 } 16550 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1); 16551 break; 16552 /* Loads and stores */ 16553 case LB32: 16554 mips32_op = OPC_LB; 16555 goto do_ld; 16556 case LBU32: 16557 mips32_op = OPC_LBU; 16558 goto do_ld; 16559 case LH32: 16560 mips32_op = OPC_LH; 16561 goto do_ld; 16562 case LHU32: 16563 mips32_op = OPC_LHU; 16564 goto do_ld; 16565 case LW32: 16566 mips32_op = OPC_LW; 16567 goto do_ld; 16568 #ifdef TARGET_MIPS64 16569 case LD32: 16570 check_insn(ctx, ISA_MIPS3); 16571 check_mips_64(ctx); 16572 mips32_op = OPC_LD; 16573 goto do_ld; 16574 case SD32: 16575 check_insn(ctx, ISA_MIPS3); 16576 check_mips_64(ctx); 16577 mips32_op = OPC_SD; 16578 goto do_st; 16579 #endif 16580 case SB32: 16581 mips32_op = OPC_SB; 16582 goto do_st; 16583 case SH32: 16584 mips32_op = OPC_SH; 16585 goto do_st; 16586 case SW32: 16587 mips32_op = OPC_SW; 16588 goto do_st; 16589 do_ld: 16590 gen_ld(ctx, mips32_op, rt, rs, imm); 16591 break; 16592 do_st: 16593 gen_st(ctx, mips32_op, rt, rs, imm); 16594 break; 16595 default: 16596 gen_reserved_instruction(ctx); 16597 break; 16598 } 16599 } 16600 16601 static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx) 16602 { 16603 uint32_t op; 16604 16605 /* make sure instructions are on a halfword boundary */ 16606 if (ctx->base.pc_next & 0x1) { 16607 env->CP0_BadVAddr = ctx->base.pc_next; 16608 generate_exception_end(ctx, EXCP_AdEL); 16609 return 2; 16610 } 16611 16612 op = (ctx->opcode >> 10) & 0x3f; 16613 /* Enforce properly-sized instructions in a delay slot */ 16614 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) { 16615 switch (op & 0x7) { /* MSB-3..MSB-5 */ 16616 case 0: 16617 /* POOL32A, POOL32B, POOL32I, POOL32C */ 16618 case 4: 16619 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */ 16620 case 5: 16621 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */ 16622 case 6: 16623 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */ 16624 case 7: 16625 /* LB32, LH32, LWC132, LDC132, LW32 */ 16626 if (ctx->hflags & MIPS_HFLAG_BDS16) { 16627 gen_reserved_instruction(ctx); 16628 return 2; 16629 } 16630 break; 16631 case 1: 16632 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */ 16633 case 2: 16634 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */ 16635 case 3: 16636 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */ 16637 if (ctx->hflags & MIPS_HFLAG_BDS32) { 16638 gen_reserved_instruction(ctx); 16639 return 2; 16640 } 16641 break; 16642 } 16643 } 16644 16645 switch (op) { 16646 case POOL16A: 16647 { 16648 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16649 int rs1 = mmreg(uMIPS_RS1(ctx->opcode)); 16650 int rs2 = mmreg(uMIPS_RS2(ctx->opcode)); 16651 uint32_t opc = 0; 16652 16653 switch (ctx->opcode & 0x1) { 16654 case ADDU16: 16655 opc = OPC_ADDU; 16656 break; 16657 case SUBU16: 16658 opc = OPC_SUBU; 16659 break; 16660 } 16661 if (ctx->insn_flags & ISA_MIPS_R6) { 16662 /* 16663 * In the Release 6, the register number location in 16664 * the instruction encoding has changed. 16665 */ 16666 gen_arith(ctx, opc, rs1, rd, rs2); 16667 } else { 16668 gen_arith(ctx, opc, rd, rs1, rs2); 16669 } 16670 } 16671 break; 16672 case POOL16B: 16673 { 16674 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16675 int rs = mmreg(uMIPS_RS(ctx->opcode)); 16676 int amount = (ctx->opcode >> 1) & 0x7; 16677 uint32_t opc = 0; 16678 amount = amount == 0 ? 8 : amount; 16679 16680 switch (ctx->opcode & 0x1) { 16681 case SLL16: 16682 opc = OPC_SLL; 16683 break; 16684 case SRL16: 16685 opc = OPC_SRL; 16686 break; 16687 } 16688 16689 gen_shift_imm(ctx, opc, rd, rs, amount); 16690 } 16691 break; 16692 case POOL16C: 16693 if (ctx->insn_flags & ISA_MIPS_R6) { 16694 gen_pool16c_r6_insn(ctx); 16695 } else { 16696 gen_pool16c_insn(ctx); 16697 } 16698 break; 16699 case LWGP16: 16700 { 16701 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16702 int rb = 28; /* GP */ 16703 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2; 16704 16705 gen_ld(ctx, OPC_LW, rd, rb, offset); 16706 } 16707 break; 16708 case POOL16F: 16709 check_insn_opc_removed(ctx, ISA_MIPS_R6); 16710 if (ctx->opcode & 1) { 16711 gen_reserved_instruction(ctx); 16712 } else { 16713 /* MOVEP */ 16714 int enc_dest = uMIPS_RD(ctx->opcode); 16715 int enc_rt = uMIPS_RS2(ctx->opcode); 16716 int enc_rs = uMIPS_RS1(ctx->opcode); 16717 gen_movep(ctx, enc_dest, enc_rt, enc_rs); 16718 } 16719 break; 16720 case LBU16: 16721 { 16722 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16723 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16724 int16_t offset = ZIMM(ctx->opcode, 0, 4); 16725 offset = (offset == 0xf ? -1 : offset); 16726 16727 gen_ld(ctx, OPC_LBU, rd, rb, offset); 16728 } 16729 break; 16730 case LHU16: 16731 { 16732 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16733 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16734 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1; 16735 16736 gen_ld(ctx, OPC_LHU, rd, rb, offset); 16737 } 16738 break; 16739 case LWSP16: 16740 { 16741 int rd = (ctx->opcode >> 5) & 0x1f; 16742 int rb = 29; /* SP */ 16743 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2; 16744 16745 gen_ld(ctx, OPC_LW, rd, rb, offset); 16746 } 16747 break; 16748 case LW16: 16749 { 16750 int rd = mmreg(uMIPS_RD(ctx->opcode)); 16751 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16752 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2; 16753 16754 gen_ld(ctx, OPC_LW, rd, rb, offset); 16755 } 16756 break; 16757 case SB16: 16758 { 16759 int rd = mmreg2(uMIPS_RD(ctx->opcode)); 16760 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16761 int16_t offset = ZIMM(ctx->opcode, 0, 4); 16762 16763 gen_st(ctx, OPC_SB, rd, rb, offset); 16764 } 16765 break; 16766 case SH16: 16767 { 16768 int rd = mmreg2(uMIPS_RD(ctx->opcode)); 16769 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16770 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1; 16771 16772 gen_st(ctx, OPC_SH, rd, rb, offset); 16773 } 16774 break; 16775 case SWSP16: 16776 { 16777 int rd = (ctx->opcode >> 5) & 0x1f; 16778 int rb = 29; /* SP */ 16779 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2; 16780 16781 gen_st(ctx, OPC_SW, rd, rb, offset); 16782 } 16783 break; 16784 case SW16: 16785 { 16786 int rd = mmreg2(uMIPS_RD(ctx->opcode)); 16787 int rb = mmreg(uMIPS_RS(ctx->opcode)); 16788 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2; 16789 16790 gen_st(ctx, OPC_SW, rd, rb, offset); 16791 } 16792 break; 16793 case MOVE16: 16794 { 16795 int rd = uMIPS_RD5(ctx->opcode); 16796 int rs = uMIPS_RS5(ctx->opcode); 16797 16798 gen_arith(ctx, OPC_ADDU, rd, rs, 0); 16799 } 16800 break; 16801 case ANDI16: 16802 gen_andi16(ctx); 16803 break; 16804 case POOL16D: 16805 switch (ctx->opcode & 0x1) { 16806 case ADDIUS5: 16807 gen_addius5(ctx); 16808 break; 16809 case ADDIUSP: 16810 gen_addiusp(ctx); 16811 break; 16812 } 16813 break; 16814 case POOL16E: 16815 switch (ctx->opcode & 0x1) { 16816 case ADDIUR2: 16817 gen_addiur2(ctx); 16818 break; 16819 case ADDIUR1SP: 16820 gen_addiur1sp(ctx); 16821 break; 16822 } 16823 break; 16824 case B16: /* BC16 */ 16825 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, 16826 sextract32(ctx->opcode, 0, 10) << 1, 16827 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4); 16828 break; 16829 case BNEZ16: /* BNEZC16 */ 16830 case BEQZ16: /* BEQZC16 */ 16831 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2, 16832 mmreg(uMIPS_RD(ctx->opcode)), 16833 0, sextract32(ctx->opcode, 0, 7) << 1, 16834 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4); 16835 16836 break; 16837 case LI16: 16838 { 16839 int reg = mmreg(uMIPS_RD(ctx->opcode)); 16840 int imm = ZIMM(ctx->opcode, 0, 7); 16841 16842 imm = (imm == 0x7f ? -1 : imm); 16843 tcg_gen_movi_tl(cpu_gpr[reg], imm); 16844 } 16845 break; 16846 case RES_29: 16847 case RES_31: 16848 case RES_39: 16849 gen_reserved_instruction(ctx); 16850 break; 16851 default: 16852 decode_micromips32_opc(env, ctx); 16853 return 4; 16854 } 16855 16856 return 2; 16857 } 16858 16859 /* 16860 * 16861 * nanoMIPS opcodes 16862 * 16863 */ 16864 16865 /* MAJOR, P16, and P32 pools opcodes */ 16866 enum { 16867 NM_P_ADDIU = 0x00, 16868 NM_ADDIUPC = 0x01, 16869 NM_MOVE_BALC = 0x02, 16870 NM_P16_MV = 0x04, 16871 NM_LW16 = 0x05, 16872 NM_BC16 = 0x06, 16873 NM_P16_SR = 0x07, 16874 16875 NM_POOL32A = 0x08, 16876 NM_P_BAL = 0x0a, 16877 NM_P16_SHIFT = 0x0c, 16878 NM_LWSP16 = 0x0d, 16879 NM_BALC16 = 0x0e, 16880 NM_P16_4X4 = 0x0f, 16881 16882 NM_P_GP_W = 0x10, 16883 NM_P_GP_BH = 0x11, 16884 NM_P_J = 0x12, 16885 NM_P16C = 0x14, 16886 NM_LWGP16 = 0x15, 16887 NM_P16_LB = 0x17, 16888 16889 NM_P48I = 0x18, 16890 NM_P16_A1 = 0x1c, 16891 NM_LW4X4 = 0x1d, 16892 NM_P16_LH = 0x1f, 16893 16894 NM_P_U12 = 0x20, 16895 NM_P_LS_U12 = 0x21, 16896 NM_P_BR1 = 0x22, 16897 NM_P16_A2 = 0x24, 16898 NM_SW16 = 0x25, 16899 NM_BEQZC16 = 0x26, 16900 16901 NM_POOL32F = 0x28, 16902 NM_P_LS_S9 = 0x29, 16903 NM_P_BR2 = 0x2a, 16904 16905 NM_P16_ADDU = 0x2c, 16906 NM_SWSP16 = 0x2d, 16907 NM_BNEZC16 = 0x2e, 16908 NM_MOVEP = 0x2f, 16909 16910 NM_POOL32S = 0x30, 16911 NM_P_BRI = 0x32, 16912 NM_LI16 = 0x34, 16913 NM_SWGP16 = 0x35, 16914 NM_P16_BR = 0x36, 16915 16916 NM_P_LUI = 0x38, 16917 NM_ANDI16 = 0x3c, 16918 NM_SW4X4 = 0x3d, 16919 NM_MOVEPREV = 0x3f, 16920 }; 16921 16922 /* POOL32A instruction pool */ 16923 enum { 16924 NM_POOL32A0 = 0x00, 16925 NM_SPECIAL2 = 0x01, 16926 NM_COP2_1 = 0x02, 16927 NM_UDI = 0x03, 16928 NM_POOL32A5 = 0x05, 16929 NM_POOL32A7 = 0x07, 16930 }; 16931 16932 /* P.GP.W instruction pool */ 16933 enum { 16934 NM_ADDIUGP_W = 0x00, 16935 NM_LWGP = 0x02, 16936 NM_SWGP = 0x03, 16937 }; 16938 16939 /* P48I instruction pool */ 16940 enum { 16941 NM_LI48 = 0x00, 16942 NM_ADDIU48 = 0x01, 16943 NM_ADDIUGP48 = 0x02, 16944 NM_ADDIUPC48 = 0x03, 16945 NM_LWPC48 = 0x0b, 16946 NM_SWPC48 = 0x0f, 16947 }; 16948 16949 /* P.U12 instruction pool */ 16950 enum { 16951 NM_ORI = 0x00, 16952 NM_XORI = 0x01, 16953 NM_ANDI = 0x02, 16954 NM_P_SR = 0x03, 16955 NM_SLTI = 0x04, 16956 NM_SLTIU = 0x05, 16957 NM_SEQI = 0x06, 16958 NM_ADDIUNEG = 0x08, 16959 NM_P_SHIFT = 0x0c, 16960 NM_P_ROTX = 0x0d, 16961 NM_P_INS = 0x0e, 16962 NM_P_EXT = 0x0f, 16963 }; 16964 16965 /* POOL32F instruction pool */ 16966 enum { 16967 NM_POOL32F_0 = 0x00, 16968 NM_POOL32F_3 = 0x03, 16969 NM_POOL32F_5 = 0x05, 16970 }; 16971 16972 /* POOL32S instruction pool */ 16973 enum { 16974 NM_POOL32S_0 = 0x00, 16975 NM_POOL32S_4 = 0x04, 16976 }; 16977 16978 /* P.LUI instruction pool */ 16979 enum { 16980 NM_LUI = 0x00, 16981 NM_ALUIPC = 0x01, 16982 }; 16983 16984 /* P.GP.BH instruction pool */ 16985 enum { 16986 NM_LBGP = 0x00, 16987 NM_SBGP = 0x01, 16988 NM_LBUGP = 0x02, 16989 NM_ADDIUGP_B = 0x03, 16990 NM_P_GP_LH = 0x04, 16991 NM_P_GP_SH = 0x05, 16992 NM_P_GP_CP1 = 0x06, 16993 }; 16994 16995 /* P.LS.U12 instruction pool */ 16996 enum { 16997 NM_LB = 0x00, 16998 NM_SB = 0x01, 16999 NM_LBU = 0x02, 17000 NM_P_PREFU12 = 0x03, 17001 NM_LH = 0x04, 17002 NM_SH = 0x05, 17003 NM_LHU = 0x06, 17004 NM_LWU = 0x07, 17005 NM_LW = 0x08, 17006 NM_SW = 0x09, 17007 NM_LWC1 = 0x0a, 17008 NM_SWC1 = 0x0b, 17009 NM_LDC1 = 0x0e, 17010 NM_SDC1 = 0x0f, 17011 }; 17012 17013 /* P.LS.S9 instruction pool */ 17014 enum { 17015 NM_P_LS_S0 = 0x00, 17016 NM_P_LS_S1 = 0x01, 17017 NM_P_LS_E0 = 0x02, 17018 NM_P_LS_WM = 0x04, 17019 NM_P_LS_UAWM = 0x05, 17020 }; 17021 17022 /* P.BAL instruction pool */ 17023 enum { 17024 NM_BC = 0x00, 17025 NM_BALC = 0x01, 17026 }; 17027 17028 /* P.J instruction pool */ 17029 enum { 17030 NM_JALRC = 0x00, 17031 NM_JALRC_HB = 0x01, 17032 NM_P_BALRSC = 0x08, 17033 }; 17034 17035 /* P.BR1 instruction pool */ 17036 enum { 17037 NM_BEQC = 0x00, 17038 NM_P_BR3A = 0x01, 17039 NM_BGEC = 0x02, 17040 NM_BGEUC = 0x03, 17041 }; 17042 17043 /* P.BR2 instruction pool */ 17044 enum { 17045 NM_BNEC = 0x00, 17046 NM_BLTC = 0x02, 17047 NM_BLTUC = 0x03, 17048 }; 17049 17050 /* P.BRI instruction pool */ 17051 enum { 17052 NM_BEQIC = 0x00, 17053 NM_BBEQZC = 0x01, 17054 NM_BGEIC = 0x02, 17055 NM_BGEIUC = 0x03, 17056 NM_BNEIC = 0x04, 17057 NM_BBNEZC = 0x05, 17058 NM_BLTIC = 0x06, 17059 NM_BLTIUC = 0x07, 17060 }; 17061 17062 /* P16.SHIFT instruction pool */ 17063 enum { 17064 NM_SLL16 = 0x00, 17065 NM_SRL16 = 0x01, 17066 }; 17067 17068 /* POOL16C instruction pool */ 17069 enum { 17070 NM_POOL16C_0 = 0x00, 17071 NM_LWXS16 = 0x01, 17072 }; 17073 17074 /* P16.A1 instruction pool */ 17075 enum { 17076 NM_ADDIUR1SP = 0x01, 17077 }; 17078 17079 /* P16.A2 instruction pool */ 17080 enum { 17081 NM_ADDIUR2 = 0x00, 17082 NM_P_ADDIURS5 = 0x01, 17083 }; 17084 17085 /* P16.ADDU instruction pool */ 17086 enum { 17087 NM_ADDU16 = 0x00, 17088 NM_SUBU16 = 0x01, 17089 }; 17090 17091 /* P16.SR instruction pool */ 17092 enum { 17093 NM_SAVE16 = 0x00, 17094 NM_RESTORE_JRC16 = 0x01, 17095 }; 17096 17097 /* P16.4X4 instruction pool */ 17098 enum { 17099 NM_ADDU4X4 = 0x00, 17100 NM_MUL4X4 = 0x01, 17101 }; 17102 17103 /* P16.LB instruction pool */ 17104 enum { 17105 NM_LB16 = 0x00, 17106 NM_SB16 = 0x01, 17107 NM_LBU16 = 0x02, 17108 }; 17109 17110 /* P16.LH instruction pool */ 17111 enum { 17112 NM_LH16 = 0x00, 17113 NM_SH16 = 0x01, 17114 NM_LHU16 = 0x02, 17115 }; 17116 17117 /* P.RI instruction pool */ 17118 enum { 17119 NM_SIGRIE = 0x00, 17120 NM_P_SYSCALL = 0x01, 17121 NM_BREAK = 0x02, 17122 NM_SDBBP = 0x03, 17123 }; 17124 17125 /* POOL32A0 instruction pool */ 17126 enum { 17127 NM_P_TRAP = 0x00, 17128 NM_SEB = 0x01, 17129 NM_SLLV = 0x02, 17130 NM_MUL = 0x03, 17131 NM_MFC0 = 0x06, 17132 NM_MFHC0 = 0x07, 17133 NM_SEH = 0x09, 17134 NM_SRLV = 0x0a, 17135 NM_MUH = 0x0b, 17136 NM_MTC0 = 0x0e, 17137 NM_MTHC0 = 0x0f, 17138 NM_SRAV = 0x12, 17139 NM_MULU = 0x13, 17140 NM_ROTRV = 0x1a, 17141 NM_MUHU = 0x1b, 17142 NM_ADD = 0x22, 17143 NM_DIV = 0x23, 17144 NM_ADDU = 0x2a, 17145 NM_MOD = 0x2b, 17146 NM_SUB = 0x32, 17147 NM_DIVU = 0x33, 17148 NM_RDHWR = 0x38, 17149 NM_SUBU = 0x3a, 17150 NM_MODU = 0x3b, 17151 NM_P_CMOVE = 0x42, 17152 NM_FORK = 0x45, 17153 NM_MFTR = 0x46, 17154 NM_MFHTR = 0x47, 17155 NM_AND = 0x4a, 17156 NM_YIELD = 0x4d, 17157 NM_MTTR = 0x4e, 17158 NM_MTHTR = 0x4f, 17159 NM_OR = 0x52, 17160 NM_D_E_MT_VPE = 0x56, 17161 NM_NOR = 0x5a, 17162 NM_XOR = 0x62, 17163 NM_SLT = 0x6a, 17164 NM_P_SLTU = 0x72, 17165 NM_SOV = 0x7a, 17166 }; 17167 17168 /* CRC32 instruction pool */ 17169 enum { 17170 NM_CRC32B = 0x00, 17171 NM_CRC32H = 0x01, 17172 NM_CRC32W = 0x02, 17173 NM_CRC32CB = 0x04, 17174 NM_CRC32CH = 0x05, 17175 NM_CRC32CW = 0x06, 17176 }; 17177 17178 /* POOL32A5 instruction pool */ 17179 enum { 17180 NM_CMP_EQ_PH = 0x00, 17181 NM_CMP_LT_PH = 0x08, 17182 NM_CMP_LE_PH = 0x10, 17183 NM_CMPGU_EQ_QB = 0x18, 17184 NM_CMPGU_LT_QB = 0x20, 17185 NM_CMPGU_LE_QB = 0x28, 17186 NM_CMPGDU_EQ_QB = 0x30, 17187 NM_CMPGDU_LT_QB = 0x38, 17188 NM_CMPGDU_LE_QB = 0x40, 17189 NM_CMPU_EQ_QB = 0x48, 17190 NM_CMPU_LT_QB = 0x50, 17191 NM_CMPU_LE_QB = 0x58, 17192 NM_ADDQ_S_W = 0x60, 17193 NM_SUBQ_S_W = 0x68, 17194 NM_ADDSC = 0x70, 17195 NM_ADDWC = 0x78, 17196 17197 NM_ADDQ_S_PH = 0x01, 17198 NM_ADDQH_R_PH = 0x09, 17199 NM_ADDQH_R_W = 0x11, 17200 NM_ADDU_S_QB = 0x19, 17201 NM_ADDU_S_PH = 0x21, 17202 NM_ADDUH_R_QB = 0x29, 17203 NM_SHRAV_R_PH = 0x31, 17204 NM_SHRAV_R_QB = 0x39, 17205 NM_SUBQ_S_PH = 0x41, 17206 NM_SUBQH_R_PH = 0x49, 17207 NM_SUBQH_R_W = 0x51, 17208 NM_SUBU_S_QB = 0x59, 17209 NM_SUBU_S_PH = 0x61, 17210 NM_SUBUH_R_QB = 0x69, 17211 NM_SHLLV_S_PH = 0x71, 17212 NM_PRECR_SRA_R_PH_W = 0x79, 17213 17214 NM_MULEU_S_PH_QBL = 0x12, 17215 NM_MULEU_S_PH_QBR = 0x1a, 17216 NM_MULQ_RS_PH = 0x22, 17217 NM_MULQ_S_PH = 0x2a, 17218 NM_MULQ_RS_W = 0x32, 17219 NM_MULQ_S_W = 0x3a, 17220 NM_APPEND = 0x42, 17221 NM_MODSUB = 0x52, 17222 NM_SHRAV_R_W = 0x5a, 17223 NM_SHRLV_PH = 0x62, 17224 NM_SHRLV_QB = 0x6a, 17225 NM_SHLLV_QB = 0x72, 17226 NM_SHLLV_S_W = 0x7a, 17227 17228 NM_SHILO = 0x03, 17229 17230 NM_MULEQ_S_W_PHL = 0x04, 17231 NM_MULEQ_S_W_PHR = 0x0c, 17232 17233 NM_MUL_S_PH = 0x05, 17234 NM_PRECR_QB_PH = 0x0d, 17235 NM_PRECRQ_QB_PH = 0x15, 17236 NM_PRECRQ_PH_W = 0x1d, 17237 NM_PRECRQ_RS_PH_W = 0x25, 17238 NM_PRECRQU_S_QB_PH = 0x2d, 17239 NM_PACKRL_PH = 0x35, 17240 NM_PICK_QB = 0x3d, 17241 NM_PICK_PH = 0x45, 17242 17243 NM_SHRA_R_W = 0x5e, 17244 NM_SHRA_R_PH = 0x66, 17245 NM_SHLL_S_PH = 0x76, 17246 NM_SHLL_S_W = 0x7e, 17247 17248 NM_REPL_PH = 0x07 17249 }; 17250 17251 /* POOL32A7 instruction pool */ 17252 enum { 17253 NM_P_LSX = 0x00, 17254 NM_LSA = 0x01, 17255 NM_EXTW = 0x03, 17256 NM_POOL32AXF = 0x07, 17257 }; 17258 17259 /* P.SR instruction pool */ 17260 enum { 17261 NM_PP_SR = 0x00, 17262 NM_P_SR_F = 0x01, 17263 }; 17264 17265 /* P.SHIFT instruction pool */ 17266 enum { 17267 NM_P_SLL = 0x00, 17268 NM_SRL = 0x02, 17269 NM_SRA = 0x04, 17270 NM_ROTR = 0x06, 17271 }; 17272 17273 /* P.ROTX instruction pool */ 17274 enum { 17275 NM_ROTX = 0x00, 17276 }; 17277 17278 /* P.INS instruction pool */ 17279 enum { 17280 NM_INS = 0x00, 17281 }; 17282 17283 /* P.EXT instruction pool */ 17284 enum { 17285 NM_EXT = 0x00, 17286 }; 17287 17288 /* POOL32F_0 (fmt) instruction pool */ 17289 enum { 17290 NM_RINT_S = 0x04, 17291 NM_RINT_D = 0x44, 17292 NM_ADD_S = 0x06, 17293 NM_SELEQZ_S = 0x07, 17294 NM_SELEQZ_D = 0x47, 17295 NM_CLASS_S = 0x0c, 17296 NM_CLASS_D = 0x4c, 17297 NM_SUB_S = 0x0e, 17298 NM_SELNEZ_S = 0x0f, 17299 NM_SELNEZ_D = 0x4f, 17300 NM_MUL_S = 0x16, 17301 NM_SEL_S = 0x17, 17302 NM_SEL_D = 0x57, 17303 NM_DIV_S = 0x1e, 17304 NM_ADD_D = 0x26, 17305 NM_SUB_D = 0x2e, 17306 NM_MUL_D = 0x36, 17307 NM_MADDF_S = 0x37, 17308 NM_MADDF_D = 0x77, 17309 NM_DIV_D = 0x3e, 17310 NM_MSUBF_S = 0x3f, 17311 NM_MSUBF_D = 0x7f, 17312 }; 17313 17314 /* POOL32F_3 instruction pool */ 17315 enum { 17316 NM_MIN_FMT = 0x00, 17317 NM_MAX_FMT = 0x01, 17318 NM_MINA_FMT = 0x04, 17319 NM_MAXA_FMT = 0x05, 17320 NM_POOL32FXF = 0x07, 17321 }; 17322 17323 /* POOL32F_5 instruction pool */ 17324 enum { 17325 NM_CMP_CONDN_S = 0x00, 17326 NM_CMP_CONDN_D = 0x02, 17327 }; 17328 17329 /* P.GP.LH instruction pool */ 17330 enum { 17331 NM_LHGP = 0x00, 17332 NM_LHUGP = 0x01, 17333 }; 17334 17335 /* P.GP.SH instruction pool */ 17336 enum { 17337 NM_SHGP = 0x00, 17338 }; 17339 17340 /* P.GP.CP1 instruction pool */ 17341 enum { 17342 NM_LWC1GP = 0x00, 17343 NM_SWC1GP = 0x01, 17344 NM_LDC1GP = 0x02, 17345 NM_SDC1GP = 0x03, 17346 }; 17347 17348 /* P.LS.S0 instruction pool */ 17349 enum { 17350 NM_LBS9 = 0x00, 17351 NM_LHS9 = 0x04, 17352 NM_LWS9 = 0x08, 17353 NM_LDS9 = 0x0c, 17354 17355 NM_SBS9 = 0x01, 17356 NM_SHS9 = 0x05, 17357 NM_SWS9 = 0x09, 17358 NM_SDS9 = 0x0d, 17359 17360 NM_LBUS9 = 0x02, 17361 NM_LHUS9 = 0x06, 17362 NM_LWC1S9 = 0x0a, 17363 NM_LDC1S9 = 0x0e, 17364 17365 NM_P_PREFS9 = 0x03, 17366 NM_LWUS9 = 0x07, 17367 NM_SWC1S9 = 0x0b, 17368 NM_SDC1S9 = 0x0f, 17369 }; 17370 17371 /* P.LS.S1 instruction pool */ 17372 enum { 17373 NM_ASET_ACLR = 0x02, 17374 NM_UALH = 0x04, 17375 NM_UASH = 0x05, 17376 NM_CACHE = 0x07, 17377 NM_P_LL = 0x0a, 17378 NM_P_SC = 0x0b, 17379 }; 17380 17381 /* P.LS.E0 instruction pool */ 17382 enum { 17383 NM_LBE = 0x00, 17384 NM_SBE = 0x01, 17385 NM_LBUE = 0x02, 17386 NM_P_PREFE = 0x03, 17387 NM_LHE = 0x04, 17388 NM_SHE = 0x05, 17389 NM_LHUE = 0x06, 17390 NM_CACHEE = 0x07, 17391 NM_LWE = 0x08, 17392 NM_SWE = 0x09, 17393 NM_P_LLE = 0x0a, 17394 NM_P_SCE = 0x0b, 17395 }; 17396 17397 /* P.PREFE instruction pool */ 17398 enum { 17399 NM_SYNCIE = 0x00, 17400 NM_PREFE = 0x01, 17401 }; 17402 17403 /* P.LLE instruction pool */ 17404 enum { 17405 NM_LLE = 0x00, 17406 NM_LLWPE = 0x01, 17407 }; 17408 17409 /* P.SCE instruction pool */ 17410 enum { 17411 NM_SCE = 0x00, 17412 NM_SCWPE = 0x01, 17413 }; 17414 17415 /* P.LS.WM instruction pool */ 17416 enum { 17417 NM_LWM = 0x00, 17418 NM_SWM = 0x01, 17419 }; 17420 17421 /* P.LS.UAWM instruction pool */ 17422 enum { 17423 NM_UALWM = 0x00, 17424 NM_UASWM = 0x01, 17425 }; 17426 17427 /* P.BR3A instruction pool */ 17428 enum { 17429 NM_BC1EQZC = 0x00, 17430 NM_BC1NEZC = 0x01, 17431 NM_BC2EQZC = 0x02, 17432 NM_BC2NEZC = 0x03, 17433 NM_BPOSGE32C = 0x04, 17434 }; 17435 17436 /* P16.RI instruction pool */ 17437 enum { 17438 NM_P16_SYSCALL = 0x01, 17439 NM_BREAK16 = 0x02, 17440 NM_SDBBP16 = 0x03, 17441 }; 17442 17443 /* POOL16C_0 instruction pool */ 17444 enum { 17445 NM_POOL16C_00 = 0x00, 17446 }; 17447 17448 /* P16.JRC instruction pool */ 17449 enum { 17450 NM_JRC = 0x00, 17451 NM_JALRC16 = 0x01, 17452 }; 17453 17454 /* P.SYSCALL instruction pool */ 17455 enum { 17456 NM_SYSCALL = 0x00, 17457 NM_HYPCALL = 0x01, 17458 }; 17459 17460 /* P.TRAP instruction pool */ 17461 enum { 17462 NM_TEQ = 0x00, 17463 NM_TNE = 0x01, 17464 }; 17465 17466 /* P.CMOVE instruction pool */ 17467 enum { 17468 NM_MOVZ = 0x00, 17469 NM_MOVN = 0x01, 17470 }; 17471 17472 /* POOL32Axf instruction pool */ 17473 enum { 17474 NM_POOL32AXF_1 = 0x01, 17475 NM_POOL32AXF_2 = 0x02, 17476 NM_POOL32AXF_4 = 0x04, 17477 NM_POOL32AXF_5 = 0x05, 17478 NM_POOL32AXF_7 = 0x07, 17479 }; 17480 17481 /* POOL32Axf_1 instruction pool */ 17482 enum { 17483 NM_POOL32AXF_1_0 = 0x00, 17484 NM_POOL32AXF_1_1 = 0x01, 17485 NM_POOL32AXF_1_3 = 0x03, 17486 NM_POOL32AXF_1_4 = 0x04, 17487 NM_POOL32AXF_1_5 = 0x05, 17488 NM_POOL32AXF_1_7 = 0x07, 17489 }; 17490 17491 /* POOL32Axf_2 instruction pool */ 17492 enum { 17493 NM_POOL32AXF_2_0_7 = 0x00, 17494 NM_POOL32AXF_2_8_15 = 0x01, 17495 NM_POOL32AXF_2_16_23 = 0x02, 17496 NM_POOL32AXF_2_24_31 = 0x03, 17497 }; 17498 17499 /* POOL32Axf_7 instruction pool */ 17500 enum { 17501 NM_SHRA_R_QB = 0x0, 17502 NM_SHRL_PH = 0x1, 17503 NM_REPL_QB = 0x2, 17504 }; 17505 17506 /* POOL32Axf_1_0 instruction pool */ 17507 enum { 17508 NM_MFHI = 0x0, 17509 NM_MFLO = 0x1, 17510 NM_MTHI = 0x2, 17511 NM_MTLO = 0x3, 17512 }; 17513 17514 /* POOL32Axf_1_1 instruction pool */ 17515 enum { 17516 NM_MTHLIP = 0x0, 17517 NM_SHILOV = 0x1, 17518 }; 17519 17520 /* POOL32Axf_1_3 instruction pool */ 17521 enum { 17522 NM_RDDSP = 0x0, 17523 NM_WRDSP = 0x1, 17524 NM_EXTP = 0x2, 17525 NM_EXTPDP = 0x3, 17526 }; 17527 17528 /* POOL32Axf_1_4 instruction pool */ 17529 enum { 17530 NM_SHLL_QB = 0x0, 17531 NM_SHRL_QB = 0x1, 17532 }; 17533 17534 /* POOL32Axf_1_5 instruction pool */ 17535 enum { 17536 NM_MAQ_S_W_PHR = 0x0, 17537 NM_MAQ_S_W_PHL = 0x1, 17538 NM_MAQ_SA_W_PHR = 0x2, 17539 NM_MAQ_SA_W_PHL = 0x3, 17540 }; 17541 17542 /* POOL32Axf_1_7 instruction pool */ 17543 enum { 17544 NM_EXTR_W = 0x0, 17545 NM_EXTR_R_W = 0x1, 17546 NM_EXTR_RS_W = 0x2, 17547 NM_EXTR_S_H = 0x3, 17548 }; 17549 17550 /* POOL32Axf_2_0_7 instruction pool */ 17551 enum { 17552 NM_DPA_W_PH = 0x0, 17553 NM_DPAQ_S_W_PH = 0x1, 17554 NM_DPS_W_PH = 0x2, 17555 NM_DPSQ_S_W_PH = 0x3, 17556 NM_BALIGN = 0x4, 17557 NM_MADD = 0x5, 17558 NM_MULT = 0x6, 17559 NM_EXTRV_W = 0x7, 17560 }; 17561 17562 /* POOL32Axf_2_8_15 instruction pool */ 17563 enum { 17564 NM_DPAX_W_PH = 0x0, 17565 NM_DPAQ_SA_L_W = 0x1, 17566 NM_DPSX_W_PH = 0x2, 17567 NM_DPSQ_SA_L_W = 0x3, 17568 NM_MADDU = 0x5, 17569 NM_MULTU = 0x6, 17570 NM_EXTRV_R_W = 0x7, 17571 }; 17572 17573 /* POOL32Axf_2_16_23 instruction pool */ 17574 enum { 17575 NM_DPAU_H_QBL = 0x0, 17576 NM_DPAQX_S_W_PH = 0x1, 17577 NM_DPSU_H_QBL = 0x2, 17578 NM_DPSQX_S_W_PH = 0x3, 17579 NM_EXTPV = 0x4, 17580 NM_MSUB = 0x5, 17581 NM_MULSA_W_PH = 0x6, 17582 NM_EXTRV_RS_W = 0x7, 17583 }; 17584 17585 /* POOL32Axf_2_24_31 instruction pool */ 17586 enum { 17587 NM_DPAU_H_QBR = 0x0, 17588 NM_DPAQX_SA_W_PH = 0x1, 17589 NM_DPSU_H_QBR = 0x2, 17590 NM_DPSQX_SA_W_PH = 0x3, 17591 NM_EXTPDPV = 0x4, 17592 NM_MSUBU = 0x5, 17593 NM_MULSAQ_S_W_PH = 0x6, 17594 NM_EXTRV_S_H = 0x7, 17595 }; 17596 17597 /* POOL32Axf_{4, 5} instruction pool */ 17598 enum { 17599 NM_CLO = 0x25, 17600 NM_CLZ = 0x2d, 17601 17602 NM_TLBP = 0x01, 17603 NM_TLBR = 0x09, 17604 NM_TLBWI = 0x11, 17605 NM_TLBWR = 0x19, 17606 NM_TLBINV = 0x03, 17607 NM_TLBINVF = 0x0b, 17608 NM_DI = 0x23, 17609 NM_EI = 0x2b, 17610 NM_RDPGPR = 0x70, 17611 NM_WRPGPR = 0x78, 17612 NM_WAIT = 0x61, 17613 NM_DERET = 0x71, 17614 NM_ERETX = 0x79, 17615 17616 /* nanoMIPS DSP instructions */ 17617 NM_ABSQ_S_QB = 0x00, 17618 NM_ABSQ_S_PH = 0x08, 17619 NM_ABSQ_S_W = 0x10, 17620 NM_PRECEQ_W_PHL = 0x28, 17621 NM_PRECEQ_W_PHR = 0x30, 17622 NM_PRECEQU_PH_QBL = 0x38, 17623 NM_PRECEQU_PH_QBR = 0x48, 17624 NM_PRECEU_PH_QBL = 0x58, 17625 NM_PRECEU_PH_QBR = 0x68, 17626 NM_PRECEQU_PH_QBLA = 0x39, 17627 NM_PRECEQU_PH_QBRA = 0x49, 17628 NM_PRECEU_PH_QBLA = 0x59, 17629 NM_PRECEU_PH_QBRA = 0x69, 17630 NM_REPLV_PH = 0x01, 17631 NM_REPLV_QB = 0x09, 17632 NM_BITREV = 0x18, 17633 NM_INSV = 0x20, 17634 NM_RADDU_W_QB = 0x78, 17635 17636 NM_BITSWAP = 0x05, 17637 NM_WSBH = 0x3d, 17638 }; 17639 17640 /* PP.SR instruction pool */ 17641 enum { 17642 NM_SAVE = 0x00, 17643 NM_RESTORE = 0x02, 17644 NM_RESTORE_JRC = 0x03, 17645 }; 17646 17647 /* P.SR.F instruction pool */ 17648 enum { 17649 NM_SAVEF = 0x00, 17650 NM_RESTOREF = 0x01, 17651 }; 17652 17653 /* P16.SYSCALL instruction pool */ 17654 enum { 17655 NM_SYSCALL16 = 0x00, 17656 NM_HYPCALL16 = 0x01, 17657 }; 17658 17659 /* POOL16C_00 instruction pool */ 17660 enum { 17661 NM_NOT16 = 0x00, 17662 NM_XOR16 = 0x01, 17663 NM_AND16 = 0x02, 17664 NM_OR16 = 0x03, 17665 }; 17666 17667 /* PP.LSX and PP.LSXS instruction pool */ 17668 enum { 17669 NM_LBX = 0x00, 17670 NM_LHX = 0x04, 17671 NM_LWX = 0x08, 17672 NM_LDX = 0x0c, 17673 17674 NM_SBX = 0x01, 17675 NM_SHX = 0x05, 17676 NM_SWX = 0x09, 17677 NM_SDX = 0x0d, 17678 17679 NM_LBUX = 0x02, 17680 NM_LHUX = 0x06, 17681 NM_LWC1X = 0x0a, 17682 NM_LDC1X = 0x0e, 17683 17684 NM_LWUX = 0x07, 17685 NM_SWC1X = 0x0b, 17686 NM_SDC1X = 0x0f, 17687 17688 NM_LHXS = 0x04, 17689 NM_LWXS = 0x08, 17690 NM_LDXS = 0x0c, 17691 17692 NM_SHXS = 0x05, 17693 NM_SWXS = 0x09, 17694 NM_SDXS = 0x0d, 17695 17696 NM_LHUXS = 0x06, 17697 NM_LWC1XS = 0x0a, 17698 NM_LDC1XS = 0x0e, 17699 17700 NM_LWUXS = 0x07, 17701 NM_SWC1XS = 0x0b, 17702 NM_SDC1XS = 0x0f, 17703 }; 17704 17705 /* ERETx instruction pool */ 17706 enum { 17707 NM_ERET = 0x00, 17708 NM_ERETNC = 0x01, 17709 }; 17710 17711 /* POOL32FxF_{0, 1} insturction pool */ 17712 enum { 17713 NM_CFC1 = 0x40, 17714 NM_CTC1 = 0x60, 17715 NM_MFC1 = 0x80, 17716 NM_MTC1 = 0xa0, 17717 NM_MFHC1 = 0xc0, 17718 NM_MTHC1 = 0xe0, 17719 17720 NM_CVT_S_PL = 0x84, 17721 NM_CVT_S_PU = 0xa4, 17722 17723 NM_CVT_L_S = 0x004, 17724 NM_CVT_L_D = 0x104, 17725 NM_CVT_W_S = 0x024, 17726 NM_CVT_W_D = 0x124, 17727 17728 NM_RSQRT_S = 0x008, 17729 NM_RSQRT_D = 0x108, 17730 17731 NM_SQRT_S = 0x028, 17732 NM_SQRT_D = 0x128, 17733 17734 NM_RECIP_S = 0x048, 17735 NM_RECIP_D = 0x148, 17736 17737 NM_FLOOR_L_S = 0x00c, 17738 NM_FLOOR_L_D = 0x10c, 17739 17740 NM_FLOOR_W_S = 0x02c, 17741 NM_FLOOR_W_D = 0x12c, 17742 17743 NM_CEIL_L_S = 0x04c, 17744 NM_CEIL_L_D = 0x14c, 17745 NM_CEIL_W_S = 0x06c, 17746 NM_CEIL_W_D = 0x16c, 17747 NM_TRUNC_L_S = 0x08c, 17748 NM_TRUNC_L_D = 0x18c, 17749 NM_TRUNC_W_S = 0x0ac, 17750 NM_TRUNC_W_D = 0x1ac, 17751 NM_ROUND_L_S = 0x0cc, 17752 NM_ROUND_L_D = 0x1cc, 17753 NM_ROUND_W_S = 0x0ec, 17754 NM_ROUND_W_D = 0x1ec, 17755 17756 NM_MOV_S = 0x01, 17757 NM_MOV_D = 0x81, 17758 NM_ABS_S = 0x0d, 17759 NM_ABS_D = 0x8d, 17760 NM_NEG_S = 0x2d, 17761 NM_NEG_D = 0xad, 17762 NM_CVT_D_S = 0x04d, 17763 NM_CVT_D_W = 0x0cd, 17764 NM_CVT_D_L = 0x14d, 17765 NM_CVT_S_D = 0x06d, 17766 NM_CVT_S_W = 0x0ed, 17767 NM_CVT_S_L = 0x16d, 17768 }; 17769 17770 /* P.LL instruction pool */ 17771 enum { 17772 NM_LL = 0x00, 17773 NM_LLWP = 0x01, 17774 }; 17775 17776 /* P.SC instruction pool */ 17777 enum { 17778 NM_SC = 0x00, 17779 NM_SCWP = 0x01, 17780 }; 17781 17782 /* P.DVP instruction pool */ 17783 enum { 17784 NM_DVP = 0x00, 17785 NM_EVP = 0x01, 17786 }; 17787 17788 17789 /* 17790 * 17791 * nanoMIPS decoding engine 17792 * 17793 */ 17794 17795 17796 /* extraction utilities */ 17797 17798 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7) 17799 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7) 17800 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7) 17801 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f) 17802 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f) 17803 17804 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */ 17805 static inline int decode_gpr_gpr3(int r) 17806 { 17807 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 }; 17808 17809 return map[r & 0x7]; 17810 } 17811 17812 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */ 17813 static inline int decode_gpr_gpr3_src_store(int r) 17814 { 17815 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 }; 17816 17817 return map[r & 0x7]; 17818 } 17819 17820 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */ 17821 static inline int decode_gpr_gpr4(int r) 17822 { 17823 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7, 17824 16, 17, 18, 19, 20, 21, 22, 23 }; 17825 17826 return map[r & 0xf]; 17827 } 17828 17829 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */ 17830 static inline int decode_gpr_gpr4_zero(int r) 17831 { 17832 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7, 17833 16, 17, 18, 19, 20, 21, 22, 23 }; 17834 17835 return map[r & 0xf]; 17836 } 17837 17838 17839 static void gen_adjust_sp(DisasContext *ctx, int u) 17840 { 17841 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u); 17842 } 17843 17844 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count, 17845 uint8_t gp, uint16_t u) 17846 { 17847 int counter = 0; 17848 TCGv va = tcg_temp_new(); 17849 TCGv t0 = tcg_temp_new(); 17850 17851 while (counter != count) { 17852 bool use_gp = gp && (counter == count - 1); 17853 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 17854 int this_offset = -((counter + 1) << 2); 17855 gen_base_offset_addr(ctx, va, 29, this_offset); 17856 gen_load_gpr(t0, this_rt); 17857 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx, 17858 (MO_TEUL | ctx->default_tcg_memop_mask)); 17859 counter++; 17860 } 17861 17862 /* adjust stack pointer */ 17863 gen_adjust_sp(ctx, -u); 17864 17865 tcg_temp_free(t0); 17866 tcg_temp_free(va); 17867 } 17868 17869 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count, 17870 uint8_t gp, uint16_t u) 17871 { 17872 int counter = 0; 17873 TCGv va = tcg_temp_new(); 17874 TCGv t0 = tcg_temp_new(); 17875 17876 while (counter != count) { 17877 bool use_gp = gp && (counter == count - 1); 17878 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 17879 int this_offset = u - ((counter + 1) << 2); 17880 gen_base_offset_addr(ctx, va, 29, this_offset); 17881 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL | 17882 ctx->default_tcg_memop_mask); 17883 tcg_gen_ext32s_tl(t0, t0); 17884 gen_store_gpr(t0, this_rt); 17885 counter++; 17886 } 17887 17888 /* adjust stack pointer */ 17889 gen_adjust_sp(ctx, u); 17890 17891 tcg_temp_free(t0); 17892 tcg_temp_free(va); 17893 } 17894 17895 static void gen_pool16c_nanomips_insn(DisasContext *ctx) 17896 { 17897 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 17898 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 17899 17900 switch (extract32(ctx->opcode, 2, 2)) { 17901 case NM_NOT16: 17902 gen_logic(ctx, OPC_NOR, rt, rs, 0); 17903 break; 17904 case NM_AND16: 17905 gen_logic(ctx, OPC_AND, rt, rt, rs); 17906 break; 17907 case NM_XOR16: 17908 gen_logic(ctx, OPC_XOR, rt, rt, rs); 17909 break; 17910 case NM_OR16: 17911 gen_logic(ctx, OPC_OR, rt, rt, rs); 17912 break; 17913 } 17914 } 17915 17916 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 17917 { 17918 int rt = extract32(ctx->opcode, 21, 5); 17919 int rs = extract32(ctx->opcode, 16, 5); 17920 int rd = extract32(ctx->opcode, 11, 5); 17921 17922 switch (extract32(ctx->opcode, 3, 7)) { 17923 case NM_P_TRAP: 17924 switch (extract32(ctx->opcode, 10, 1)) { 17925 case NM_TEQ: 17926 check_nms(ctx); 17927 gen_trap(ctx, OPC_TEQ, rs, rt, -1); 17928 break; 17929 case NM_TNE: 17930 check_nms(ctx); 17931 gen_trap(ctx, OPC_TNE, rs, rt, -1); 17932 break; 17933 } 17934 break; 17935 case NM_RDHWR: 17936 check_nms(ctx); 17937 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); 17938 break; 17939 case NM_SEB: 17940 check_nms(ctx); 17941 gen_bshfl(ctx, OPC_SEB, rs, rt); 17942 break; 17943 case NM_SEH: 17944 gen_bshfl(ctx, OPC_SEH, rs, rt); 17945 break; 17946 case NM_SLLV: 17947 gen_shift(ctx, OPC_SLLV, rd, rt, rs); 17948 break; 17949 case NM_SRLV: 17950 gen_shift(ctx, OPC_SRLV, rd, rt, rs); 17951 break; 17952 case NM_SRAV: 17953 gen_shift(ctx, OPC_SRAV, rd, rt, rs); 17954 break; 17955 case NM_ROTRV: 17956 gen_shift(ctx, OPC_ROTRV, rd, rt, rs); 17957 break; 17958 case NM_ADD: 17959 gen_arith(ctx, OPC_ADD, rd, rs, rt); 17960 break; 17961 case NM_ADDU: 17962 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 17963 break; 17964 case NM_SUB: 17965 check_nms(ctx); 17966 gen_arith(ctx, OPC_SUB, rd, rs, rt); 17967 break; 17968 case NM_SUBU: 17969 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 17970 break; 17971 case NM_P_CMOVE: 17972 switch (extract32(ctx->opcode, 10, 1)) { 17973 case NM_MOVZ: 17974 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); 17975 break; 17976 case NM_MOVN: 17977 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); 17978 break; 17979 } 17980 break; 17981 case NM_AND: 17982 gen_logic(ctx, OPC_AND, rd, rs, rt); 17983 break; 17984 case NM_OR: 17985 gen_logic(ctx, OPC_OR, rd, rs, rt); 17986 break; 17987 case NM_NOR: 17988 gen_logic(ctx, OPC_NOR, rd, rs, rt); 17989 break; 17990 case NM_XOR: 17991 gen_logic(ctx, OPC_XOR, rd, rs, rt); 17992 break; 17993 case NM_SLT: 17994 gen_slt(ctx, OPC_SLT, rd, rs, rt); 17995 break; 17996 case NM_P_SLTU: 17997 if (rd == 0) { 17998 /* P_DVP */ 17999 #ifndef CONFIG_USER_ONLY 18000 TCGv t0 = tcg_temp_new(); 18001 switch (extract32(ctx->opcode, 10, 1)) { 18002 case NM_DVP: 18003 if (ctx->vp) { 18004 check_cp0_enabled(ctx); 18005 gen_helper_dvp(t0, cpu_env); 18006 gen_store_gpr(t0, rt); 18007 } 18008 break; 18009 case NM_EVP: 18010 if (ctx->vp) { 18011 check_cp0_enabled(ctx); 18012 gen_helper_evp(t0, cpu_env); 18013 gen_store_gpr(t0, rt); 18014 } 18015 break; 18016 } 18017 tcg_temp_free(t0); 18018 #endif 18019 } else { 18020 gen_slt(ctx, OPC_SLTU, rd, rs, rt); 18021 } 18022 break; 18023 case NM_SOV: 18024 { 18025 TCGv t0 = tcg_temp_new(); 18026 TCGv t1 = tcg_temp_new(); 18027 TCGv t2 = tcg_temp_new(); 18028 18029 gen_load_gpr(t1, rs); 18030 gen_load_gpr(t2, rt); 18031 tcg_gen_add_tl(t0, t1, t2); 18032 tcg_gen_ext32s_tl(t0, t0); 18033 tcg_gen_xor_tl(t1, t1, t2); 18034 tcg_gen_xor_tl(t2, t0, t2); 18035 tcg_gen_andc_tl(t1, t2, t1); 18036 18037 /* operands of same sign, result different sign */ 18038 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0); 18039 gen_store_gpr(t0, rd); 18040 18041 tcg_temp_free(t0); 18042 tcg_temp_free(t1); 18043 tcg_temp_free(t2); 18044 } 18045 break; 18046 case NM_MUL: 18047 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); 18048 break; 18049 case NM_MUH: 18050 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); 18051 break; 18052 case NM_MULU: 18053 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); 18054 break; 18055 case NM_MUHU: 18056 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); 18057 break; 18058 case NM_DIV: 18059 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); 18060 break; 18061 case NM_MOD: 18062 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); 18063 break; 18064 case NM_DIVU: 18065 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); 18066 break; 18067 case NM_MODU: 18068 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); 18069 break; 18070 #ifndef CONFIG_USER_ONLY 18071 case NM_MFC0: 18072 check_cp0_enabled(ctx); 18073 if (rt == 0) { 18074 /* Treat as NOP. */ 18075 break; 18076 } 18077 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3)); 18078 break; 18079 case NM_MTC0: 18080 check_cp0_enabled(ctx); 18081 { 18082 TCGv t0 = tcg_temp_new(); 18083 18084 gen_load_gpr(t0, rt); 18085 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3)); 18086 tcg_temp_free(t0); 18087 } 18088 break; 18089 case NM_D_E_MT_VPE: 18090 { 18091 uint8_t sc = extract32(ctx->opcode, 10, 1); 18092 TCGv t0 = tcg_temp_new(); 18093 18094 switch (sc) { 18095 case 0: 18096 if (rs == 1) { 18097 /* DMT */ 18098 check_cp0_mt(ctx); 18099 gen_helper_dmt(t0); 18100 gen_store_gpr(t0, rt); 18101 } else if (rs == 0) { 18102 /* DVPE */ 18103 check_cp0_mt(ctx); 18104 gen_helper_dvpe(t0, cpu_env); 18105 gen_store_gpr(t0, rt); 18106 } else { 18107 gen_reserved_instruction(ctx); 18108 } 18109 break; 18110 case 1: 18111 if (rs == 1) { 18112 /* EMT */ 18113 check_cp0_mt(ctx); 18114 gen_helper_emt(t0); 18115 gen_store_gpr(t0, rt); 18116 } else if (rs == 0) { 18117 /* EVPE */ 18118 check_cp0_mt(ctx); 18119 gen_helper_evpe(t0, cpu_env); 18120 gen_store_gpr(t0, rt); 18121 } else { 18122 gen_reserved_instruction(ctx); 18123 } 18124 break; 18125 } 18126 18127 tcg_temp_free(t0); 18128 } 18129 break; 18130 case NM_FORK: 18131 check_mt(ctx); 18132 { 18133 TCGv t0 = tcg_temp_new(); 18134 TCGv t1 = tcg_temp_new(); 18135 18136 gen_load_gpr(t0, rt); 18137 gen_load_gpr(t1, rs); 18138 gen_helper_fork(t0, t1); 18139 tcg_temp_free(t0); 18140 tcg_temp_free(t1); 18141 } 18142 break; 18143 case NM_MFTR: 18144 case NM_MFHTR: 18145 check_cp0_enabled(ctx); 18146 if (rd == 0) { 18147 /* Treat as NOP. */ 18148 return; 18149 } 18150 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 18151 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 18152 break; 18153 case NM_MTTR: 18154 case NM_MTHTR: 18155 check_cp0_enabled(ctx); 18156 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 18157 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 18158 break; 18159 case NM_YIELD: 18160 check_mt(ctx); 18161 { 18162 TCGv t0 = tcg_temp_new(); 18163 18164 gen_load_gpr(t0, rs); 18165 gen_helper_yield(t0, cpu_env, t0); 18166 gen_store_gpr(t0, rt); 18167 tcg_temp_free(t0); 18168 } 18169 break; 18170 #endif 18171 default: 18172 gen_reserved_instruction(ctx); 18173 break; 18174 } 18175 } 18176 18177 /* dsp */ 18178 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc, 18179 int ret, int v1, int v2) 18180 { 18181 TCGv_i32 t0; 18182 TCGv v0_t; 18183 TCGv v1_t; 18184 18185 t0 = tcg_temp_new_i32(); 18186 18187 v0_t = tcg_temp_new(); 18188 v1_t = tcg_temp_new(); 18189 18190 tcg_gen_movi_i32(t0, v2 >> 3); 18191 18192 gen_load_gpr(v0_t, ret); 18193 gen_load_gpr(v1_t, v1); 18194 18195 switch (opc) { 18196 case NM_MAQ_S_W_PHR: 18197 check_dsp(ctx); 18198 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env); 18199 break; 18200 case NM_MAQ_S_W_PHL: 18201 check_dsp(ctx); 18202 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env); 18203 break; 18204 case NM_MAQ_SA_W_PHR: 18205 check_dsp(ctx); 18206 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env); 18207 break; 18208 case NM_MAQ_SA_W_PHL: 18209 check_dsp(ctx); 18210 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); 18211 break; 18212 default: 18213 gen_reserved_instruction(ctx); 18214 break; 18215 } 18216 18217 tcg_temp_free_i32(t0); 18218 18219 tcg_temp_free(v0_t); 18220 tcg_temp_free(v1_t); 18221 } 18222 18223 18224 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, 18225 int ret, int v1, int v2) 18226 { 18227 int16_t imm; 18228 TCGv t0 = tcg_temp_new(); 18229 TCGv t1 = tcg_temp_new(); 18230 TCGv v0_t = tcg_temp_new(); 18231 18232 gen_load_gpr(v0_t, v1); 18233 18234 switch (opc) { 18235 case NM_POOL32AXF_1_0: 18236 check_dsp(ctx); 18237 switch (extract32(ctx->opcode, 12, 2)) { 18238 case NM_MFHI: 18239 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret); 18240 break; 18241 case NM_MFLO: 18242 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret); 18243 break; 18244 case NM_MTHI: 18245 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1); 18246 break; 18247 case NM_MTLO: 18248 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1); 18249 break; 18250 } 18251 break; 18252 case NM_POOL32AXF_1_1: 18253 check_dsp(ctx); 18254 switch (extract32(ctx->opcode, 12, 2)) { 18255 case NM_MTHLIP: 18256 tcg_gen_movi_tl(t0, v2); 18257 gen_helper_mthlip(t0, v0_t, cpu_env); 18258 break; 18259 case NM_SHILOV: 18260 tcg_gen_movi_tl(t0, v2 >> 3); 18261 gen_helper_shilo(t0, v0_t, cpu_env); 18262 break; 18263 default: 18264 gen_reserved_instruction(ctx); 18265 break; 18266 } 18267 break; 18268 case NM_POOL32AXF_1_3: 18269 check_dsp(ctx); 18270 imm = extract32(ctx->opcode, 14, 7); 18271 switch (extract32(ctx->opcode, 12, 2)) { 18272 case NM_RDDSP: 18273 tcg_gen_movi_tl(t0, imm); 18274 gen_helper_rddsp(t0, t0, cpu_env); 18275 gen_store_gpr(t0, ret); 18276 break; 18277 case NM_WRDSP: 18278 gen_load_gpr(t0, ret); 18279 tcg_gen_movi_tl(t1, imm); 18280 gen_helper_wrdsp(t0, t1, cpu_env); 18281 break; 18282 case NM_EXTP: 18283 tcg_gen_movi_tl(t0, v2 >> 3); 18284 tcg_gen_movi_tl(t1, v1); 18285 gen_helper_extp(t0, t0, t1, cpu_env); 18286 gen_store_gpr(t0, ret); 18287 break; 18288 case NM_EXTPDP: 18289 tcg_gen_movi_tl(t0, v2 >> 3); 18290 tcg_gen_movi_tl(t1, v1); 18291 gen_helper_extpdp(t0, t0, t1, cpu_env); 18292 gen_store_gpr(t0, ret); 18293 break; 18294 } 18295 break; 18296 case NM_POOL32AXF_1_4: 18297 check_dsp(ctx); 18298 tcg_gen_movi_tl(t0, v2 >> 2); 18299 switch (extract32(ctx->opcode, 12, 1)) { 18300 case NM_SHLL_QB: 18301 gen_helper_shll_qb(t0, t0, v0_t, cpu_env); 18302 gen_store_gpr(t0, ret); 18303 break; 18304 case NM_SHRL_QB: 18305 gen_helper_shrl_qb(t0, t0, v0_t); 18306 gen_store_gpr(t0, ret); 18307 break; 18308 } 18309 break; 18310 case NM_POOL32AXF_1_5: 18311 opc = extract32(ctx->opcode, 12, 2); 18312 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); 18313 break; 18314 case NM_POOL32AXF_1_7: 18315 check_dsp(ctx); 18316 tcg_gen_movi_tl(t0, v2 >> 3); 18317 tcg_gen_movi_tl(t1, v1); 18318 switch (extract32(ctx->opcode, 12, 2)) { 18319 case NM_EXTR_W: 18320 gen_helper_extr_w(t0, t0, t1, cpu_env); 18321 gen_store_gpr(t0, ret); 18322 break; 18323 case NM_EXTR_R_W: 18324 gen_helper_extr_r_w(t0, t0, t1, cpu_env); 18325 gen_store_gpr(t0, ret); 18326 break; 18327 case NM_EXTR_RS_W: 18328 gen_helper_extr_rs_w(t0, t0, t1, cpu_env); 18329 gen_store_gpr(t0, ret); 18330 break; 18331 case NM_EXTR_S_H: 18332 gen_helper_extr_s_h(t0, t0, t1, cpu_env); 18333 gen_store_gpr(t0, ret); 18334 break; 18335 } 18336 break; 18337 default: 18338 gen_reserved_instruction(ctx); 18339 break; 18340 } 18341 18342 tcg_temp_free(t0); 18343 tcg_temp_free(t1); 18344 tcg_temp_free(v0_t); 18345 } 18346 18347 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, 18348 TCGv v0, TCGv v1, int rd) 18349 { 18350 TCGv_i32 t0; 18351 18352 t0 = tcg_temp_new_i32(); 18353 18354 tcg_gen_movi_i32(t0, rd >> 3); 18355 18356 switch (opc) { 18357 case NM_POOL32AXF_2_0_7: 18358 switch (extract32(ctx->opcode, 9, 3)) { 18359 case NM_DPA_W_PH: 18360 check_dsp_r2(ctx); 18361 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env); 18362 break; 18363 case NM_DPAQ_S_W_PH: 18364 check_dsp(ctx); 18365 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env); 18366 break; 18367 case NM_DPS_W_PH: 18368 check_dsp_r2(ctx); 18369 gen_helper_dps_w_ph(t0, v1, v0, cpu_env); 18370 break; 18371 case NM_DPSQ_S_W_PH: 18372 check_dsp(ctx); 18373 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); 18374 break; 18375 default: 18376 gen_reserved_instruction(ctx); 18377 break; 18378 } 18379 break; 18380 case NM_POOL32AXF_2_8_15: 18381 switch (extract32(ctx->opcode, 9, 3)) { 18382 case NM_DPAX_W_PH: 18383 check_dsp_r2(ctx); 18384 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env); 18385 break; 18386 case NM_DPAQ_SA_L_W: 18387 check_dsp(ctx); 18388 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env); 18389 break; 18390 case NM_DPSX_W_PH: 18391 check_dsp_r2(ctx); 18392 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env); 18393 break; 18394 case NM_DPSQ_SA_L_W: 18395 check_dsp(ctx); 18396 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); 18397 break; 18398 default: 18399 gen_reserved_instruction(ctx); 18400 break; 18401 } 18402 break; 18403 case NM_POOL32AXF_2_16_23: 18404 switch (extract32(ctx->opcode, 9, 3)) { 18405 case NM_DPAU_H_QBL: 18406 check_dsp(ctx); 18407 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env); 18408 break; 18409 case NM_DPAQX_S_W_PH: 18410 check_dsp_r2(ctx); 18411 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env); 18412 break; 18413 case NM_DPSU_H_QBL: 18414 check_dsp(ctx); 18415 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env); 18416 break; 18417 case NM_DPSQX_S_W_PH: 18418 check_dsp_r2(ctx); 18419 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env); 18420 break; 18421 case NM_MULSA_W_PH: 18422 check_dsp_r2(ctx); 18423 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); 18424 break; 18425 default: 18426 gen_reserved_instruction(ctx); 18427 break; 18428 } 18429 break; 18430 case NM_POOL32AXF_2_24_31: 18431 switch (extract32(ctx->opcode, 9, 3)) { 18432 case NM_DPAU_H_QBR: 18433 check_dsp(ctx); 18434 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env); 18435 break; 18436 case NM_DPAQX_SA_W_PH: 18437 check_dsp_r2(ctx); 18438 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env); 18439 break; 18440 case NM_DPSU_H_QBR: 18441 check_dsp(ctx); 18442 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env); 18443 break; 18444 case NM_DPSQX_SA_W_PH: 18445 check_dsp_r2(ctx); 18446 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env); 18447 break; 18448 case NM_MULSAQ_S_W_PH: 18449 check_dsp(ctx); 18450 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); 18451 break; 18452 default: 18453 gen_reserved_instruction(ctx); 18454 break; 18455 } 18456 break; 18457 default: 18458 gen_reserved_instruction(ctx); 18459 break; 18460 } 18461 18462 tcg_temp_free_i32(t0); 18463 } 18464 18465 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, 18466 int rt, int rs, int rd) 18467 { 18468 int ret = rt; 18469 TCGv t0 = tcg_temp_new(); 18470 TCGv t1 = tcg_temp_new(); 18471 TCGv v0_t = tcg_temp_new(); 18472 TCGv v1_t = tcg_temp_new(); 18473 18474 gen_load_gpr(v0_t, rt); 18475 gen_load_gpr(v1_t, rs); 18476 18477 switch (opc) { 18478 case NM_POOL32AXF_2_0_7: 18479 switch (extract32(ctx->opcode, 9, 3)) { 18480 case NM_DPA_W_PH: 18481 case NM_DPAQ_S_W_PH: 18482 case NM_DPS_W_PH: 18483 case NM_DPSQ_S_W_PH: 18484 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 18485 break; 18486 case NM_BALIGN: 18487 check_dsp_r2(ctx); 18488 if (rt != 0) { 18489 gen_load_gpr(t0, rs); 18490 rd &= 3; 18491 if (rd != 0 && rd != 2) { 18492 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd); 18493 tcg_gen_ext32u_tl(t0, t0); 18494 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd)); 18495 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 18496 } 18497 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 18498 } 18499 break; 18500 case NM_MADD: 18501 check_dsp(ctx); 18502 { 18503 int acc = extract32(ctx->opcode, 14, 2); 18504 TCGv_i64 t2 = tcg_temp_new_i64(); 18505 TCGv_i64 t3 = tcg_temp_new_i64(); 18506 18507 gen_load_gpr(t0, rt); 18508 gen_load_gpr(t1, rs); 18509 tcg_gen_ext_tl_i64(t2, t0); 18510 tcg_gen_ext_tl_i64(t3, t1); 18511 tcg_gen_mul_i64(t2, t2, t3); 18512 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 18513 tcg_gen_add_i64(t2, t2, t3); 18514 tcg_temp_free_i64(t3); 18515 gen_move_low32(cpu_LO[acc], t2); 18516 gen_move_high32(cpu_HI[acc], t2); 18517 tcg_temp_free_i64(t2); 18518 } 18519 break; 18520 case NM_MULT: 18521 check_dsp(ctx); 18522 { 18523 int acc = extract32(ctx->opcode, 14, 2); 18524 TCGv_i32 t2 = tcg_temp_new_i32(); 18525 TCGv_i32 t3 = tcg_temp_new_i32(); 18526 18527 gen_load_gpr(t0, rs); 18528 gen_load_gpr(t1, rt); 18529 tcg_gen_trunc_tl_i32(t2, t0); 18530 tcg_gen_trunc_tl_i32(t3, t1); 18531 tcg_gen_muls2_i32(t2, t3, t2, t3); 18532 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 18533 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 18534 tcg_temp_free_i32(t2); 18535 tcg_temp_free_i32(t3); 18536 } 18537 break; 18538 case NM_EXTRV_W: 18539 check_dsp(ctx); 18540 gen_load_gpr(v1_t, rs); 18541 tcg_gen_movi_tl(t0, rd >> 3); 18542 gen_helper_extr_w(t0, t0, v1_t, cpu_env); 18543 gen_store_gpr(t0, ret); 18544 break; 18545 } 18546 break; 18547 case NM_POOL32AXF_2_8_15: 18548 switch (extract32(ctx->opcode, 9, 3)) { 18549 case NM_DPAX_W_PH: 18550 case NM_DPAQ_SA_L_W: 18551 case NM_DPSX_W_PH: 18552 case NM_DPSQ_SA_L_W: 18553 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 18554 break; 18555 case NM_MADDU: 18556 check_dsp(ctx); 18557 { 18558 int acc = extract32(ctx->opcode, 14, 2); 18559 TCGv_i64 t2 = tcg_temp_new_i64(); 18560 TCGv_i64 t3 = tcg_temp_new_i64(); 18561 18562 gen_load_gpr(t0, rs); 18563 gen_load_gpr(t1, rt); 18564 tcg_gen_ext32u_tl(t0, t0); 18565 tcg_gen_ext32u_tl(t1, t1); 18566 tcg_gen_extu_tl_i64(t2, t0); 18567 tcg_gen_extu_tl_i64(t3, t1); 18568 tcg_gen_mul_i64(t2, t2, t3); 18569 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 18570 tcg_gen_add_i64(t2, t2, t3); 18571 tcg_temp_free_i64(t3); 18572 gen_move_low32(cpu_LO[acc], t2); 18573 gen_move_high32(cpu_HI[acc], t2); 18574 tcg_temp_free_i64(t2); 18575 } 18576 break; 18577 case NM_MULTU: 18578 check_dsp(ctx); 18579 { 18580 int acc = extract32(ctx->opcode, 14, 2); 18581 TCGv_i32 t2 = tcg_temp_new_i32(); 18582 TCGv_i32 t3 = tcg_temp_new_i32(); 18583 18584 gen_load_gpr(t0, rs); 18585 gen_load_gpr(t1, rt); 18586 tcg_gen_trunc_tl_i32(t2, t0); 18587 tcg_gen_trunc_tl_i32(t3, t1); 18588 tcg_gen_mulu2_i32(t2, t3, t2, t3); 18589 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 18590 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 18591 tcg_temp_free_i32(t2); 18592 tcg_temp_free_i32(t3); 18593 } 18594 break; 18595 case NM_EXTRV_R_W: 18596 check_dsp(ctx); 18597 tcg_gen_movi_tl(t0, rd >> 3); 18598 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env); 18599 gen_store_gpr(t0, ret); 18600 break; 18601 default: 18602 gen_reserved_instruction(ctx); 18603 break; 18604 } 18605 break; 18606 case NM_POOL32AXF_2_16_23: 18607 switch (extract32(ctx->opcode, 9, 3)) { 18608 case NM_DPAU_H_QBL: 18609 case NM_DPAQX_S_W_PH: 18610 case NM_DPSU_H_QBL: 18611 case NM_DPSQX_S_W_PH: 18612 case NM_MULSA_W_PH: 18613 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 18614 break; 18615 case NM_EXTPV: 18616 check_dsp(ctx); 18617 tcg_gen_movi_tl(t0, rd >> 3); 18618 gen_helper_extp(t0, t0, v1_t, cpu_env); 18619 gen_store_gpr(t0, ret); 18620 break; 18621 case NM_MSUB: 18622 check_dsp(ctx); 18623 { 18624 int acc = extract32(ctx->opcode, 14, 2); 18625 TCGv_i64 t2 = tcg_temp_new_i64(); 18626 TCGv_i64 t3 = tcg_temp_new_i64(); 18627 18628 gen_load_gpr(t0, rs); 18629 gen_load_gpr(t1, rt); 18630 tcg_gen_ext_tl_i64(t2, t0); 18631 tcg_gen_ext_tl_i64(t3, t1); 18632 tcg_gen_mul_i64(t2, t2, t3); 18633 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 18634 tcg_gen_sub_i64(t2, t3, t2); 18635 tcg_temp_free_i64(t3); 18636 gen_move_low32(cpu_LO[acc], t2); 18637 gen_move_high32(cpu_HI[acc], t2); 18638 tcg_temp_free_i64(t2); 18639 } 18640 break; 18641 case NM_EXTRV_RS_W: 18642 check_dsp(ctx); 18643 tcg_gen_movi_tl(t0, rd >> 3); 18644 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env); 18645 gen_store_gpr(t0, ret); 18646 break; 18647 } 18648 break; 18649 case NM_POOL32AXF_2_24_31: 18650 switch (extract32(ctx->opcode, 9, 3)) { 18651 case NM_DPAU_H_QBR: 18652 case NM_DPAQX_SA_W_PH: 18653 case NM_DPSU_H_QBR: 18654 case NM_DPSQX_SA_W_PH: 18655 case NM_MULSAQ_S_W_PH: 18656 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 18657 break; 18658 case NM_EXTPDPV: 18659 check_dsp(ctx); 18660 tcg_gen_movi_tl(t0, rd >> 3); 18661 gen_helper_extpdp(t0, t0, v1_t, cpu_env); 18662 gen_store_gpr(t0, ret); 18663 break; 18664 case NM_MSUBU: 18665 check_dsp(ctx); 18666 { 18667 int acc = extract32(ctx->opcode, 14, 2); 18668 TCGv_i64 t2 = tcg_temp_new_i64(); 18669 TCGv_i64 t3 = tcg_temp_new_i64(); 18670 18671 gen_load_gpr(t0, rs); 18672 gen_load_gpr(t1, rt); 18673 tcg_gen_ext32u_tl(t0, t0); 18674 tcg_gen_ext32u_tl(t1, t1); 18675 tcg_gen_extu_tl_i64(t2, t0); 18676 tcg_gen_extu_tl_i64(t3, t1); 18677 tcg_gen_mul_i64(t2, t2, t3); 18678 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 18679 tcg_gen_sub_i64(t2, t3, t2); 18680 tcg_temp_free_i64(t3); 18681 gen_move_low32(cpu_LO[acc], t2); 18682 gen_move_high32(cpu_HI[acc], t2); 18683 tcg_temp_free_i64(t2); 18684 } 18685 break; 18686 case NM_EXTRV_S_H: 18687 check_dsp(ctx); 18688 tcg_gen_movi_tl(t0, rd >> 3); 18689 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env); 18690 gen_store_gpr(t0, ret); 18691 break; 18692 } 18693 break; 18694 default: 18695 gen_reserved_instruction(ctx); 18696 break; 18697 } 18698 18699 tcg_temp_free(t0); 18700 tcg_temp_free(t1); 18701 18702 tcg_temp_free(v0_t); 18703 tcg_temp_free(v1_t); 18704 } 18705 18706 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, 18707 int rt, int rs) 18708 { 18709 int ret = rt; 18710 TCGv t0 = tcg_temp_new(); 18711 TCGv v0_t = tcg_temp_new(); 18712 18713 gen_load_gpr(v0_t, rs); 18714 18715 switch (opc) { 18716 case NM_ABSQ_S_QB: 18717 check_dsp_r2(ctx); 18718 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env); 18719 gen_store_gpr(v0_t, ret); 18720 break; 18721 case NM_ABSQ_S_PH: 18722 check_dsp(ctx); 18723 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env); 18724 gen_store_gpr(v0_t, ret); 18725 break; 18726 case NM_ABSQ_S_W: 18727 check_dsp(ctx); 18728 gen_helper_absq_s_w(v0_t, v0_t, cpu_env); 18729 gen_store_gpr(v0_t, ret); 18730 break; 18731 case NM_PRECEQ_W_PHL: 18732 check_dsp(ctx); 18733 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000); 18734 tcg_gen_ext32s_tl(v0_t, v0_t); 18735 gen_store_gpr(v0_t, ret); 18736 break; 18737 case NM_PRECEQ_W_PHR: 18738 check_dsp(ctx); 18739 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF); 18740 tcg_gen_shli_tl(v0_t, v0_t, 16); 18741 tcg_gen_ext32s_tl(v0_t, v0_t); 18742 gen_store_gpr(v0_t, ret); 18743 break; 18744 case NM_PRECEQU_PH_QBL: 18745 check_dsp(ctx); 18746 gen_helper_precequ_ph_qbl(v0_t, v0_t); 18747 gen_store_gpr(v0_t, ret); 18748 break; 18749 case NM_PRECEQU_PH_QBR: 18750 check_dsp(ctx); 18751 gen_helper_precequ_ph_qbr(v0_t, v0_t); 18752 gen_store_gpr(v0_t, ret); 18753 break; 18754 case NM_PRECEQU_PH_QBLA: 18755 check_dsp(ctx); 18756 gen_helper_precequ_ph_qbla(v0_t, v0_t); 18757 gen_store_gpr(v0_t, ret); 18758 break; 18759 case NM_PRECEQU_PH_QBRA: 18760 check_dsp(ctx); 18761 gen_helper_precequ_ph_qbra(v0_t, v0_t); 18762 gen_store_gpr(v0_t, ret); 18763 break; 18764 case NM_PRECEU_PH_QBL: 18765 check_dsp(ctx); 18766 gen_helper_preceu_ph_qbl(v0_t, v0_t); 18767 gen_store_gpr(v0_t, ret); 18768 break; 18769 case NM_PRECEU_PH_QBR: 18770 check_dsp(ctx); 18771 gen_helper_preceu_ph_qbr(v0_t, v0_t); 18772 gen_store_gpr(v0_t, ret); 18773 break; 18774 case NM_PRECEU_PH_QBLA: 18775 check_dsp(ctx); 18776 gen_helper_preceu_ph_qbla(v0_t, v0_t); 18777 gen_store_gpr(v0_t, ret); 18778 break; 18779 case NM_PRECEU_PH_QBRA: 18780 check_dsp(ctx); 18781 gen_helper_preceu_ph_qbra(v0_t, v0_t); 18782 gen_store_gpr(v0_t, ret); 18783 break; 18784 case NM_REPLV_PH: 18785 check_dsp(ctx); 18786 tcg_gen_ext16u_tl(v0_t, v0_t); 18787 tcg_gen_shli_tl(t0, v0_t, 16); 18788 tcg_gen_or_tl(v0_t, v0_t, t0); 18789 tcg_gen_ext32s_tl(v0_t, v0_t); 18790 gen_store_gpr(v0_t, ret); 18791 break; 18792 case NM_REPLV_QB: 18793 check_dsp(ctx); 18794 tcg_gen_ext8u_tl(v0_t, v0_t); 18795 tcg_gen_shli_tl(t0, v0_t, 8); 18796 tcg_gen_or_tl(v0_t, v0_t, t0); 18797 tcg_gen_shli_tl(t0, v0_t, 16); 18798 tcg_gen_or_tl(v0_t, v0_t, t0); 18799 tcg_gen_ext32s_tl(v0_t, v0_t); 18800 gen_store_gpr(v0_t, ret); 18801 break; 18802 case NM_BITREV: 18803 check_dsp(ctx); 18804 gen_helper_bitrev(v0_t, v0_t); 18805 gen_store_gpr(v0_t, ret); 18806 break; 18807 case NM_INSV: 18808 check_dsp(ctx); 18809 { 18810 TCGv tv0 = tcg_temp_new(); 18811 18812 gen_load_gpr(tv0, rt); 18813 gen_helper_insv(v0_t, cpu_env, v0_t, tv0); 18814 gen_store_gpr(v0_t, ret); 18815 tcg_temp_free(tv0); 18816 } 18817 break; 18818 case NM_RADDU_W_QB: 18819 check_dsp(ctx); 18820 gen_helper_raddu_w_qb(v0_t, v0_t); 18821 gen_store_gpr(v0_t, ret); 18822 break; 18823 case NM_BITSWAP: 18824 gen_bitswap(ctx, OPC_BITSWAP, ret, rs); 18825 break; 18826 case NM_CLO: 18827 check_nms(ctx); 18828 gen_cl(ctx, OPC_CLO, ret, rs); 18829 break; 18830 case NM_CLZ: 18831 check_nms(ctx); 18832 gen_cl(ctx, OPC_CLZ, ret, rs); 18833 break; 18834 case NM_WSBH: 18835 gen_bshfl(ctx, OPC_WSBH, ret, rs); 18836 break; 18837 default: 18838 gen_reserved_instruction(ctx); 18839 break; 18840 } 18841 18842 tcg_temp_free(v0_t); 18843 tcg_temp_free(t0); 18844 } 18845 18846 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, 18847 int rt, int rs, int rd) 18848 { 18849 TCGv t0 = tcg_temp_new(); 18850 TCGv rs_t = tcg_temp_new(); 18851 18852 gen_load_gpr(rs_t, rs); 18853 18854 switch (opc) { 18855 case NM_SHRA_R_QB: 18856 check_dsp_r2(ctx); 18857 tcg_gen_movi_tl(t0, rd >> 2); 18858 switch (extract32(ctx->opcode, 12, 1)) { 18859 case 0: 18860 /* NM_SHRA_QB */ 18861 gen_helper_shra_qb(t0, t0, rs_t); 18862 gen_store_gpr(t0, rt); 18863 break; 18864 case 1: 18865 /* NM_SHRA_R_QB */ 18866 gen_helper_shra_r_qb(t0, t0, rs_t); 18867 gen_store_gpr(t0, rt); 18868 break; 18869 } 18870 break; 18871 case NM_SHRL_PH: 18872 check_dsp_r2(ctx); 18873 tcg_gen_movi_tl(t0, rd >> 1); 18874 gen_helper_shrl_ph(t0, t0, rs_t); 18875 gen_store_gpr(t0, rt); 18876 break; 18877 case NM_REPL_QB: 18878 check_dsp(ctx); 18879 { 18880 int16_t imm; 18881 target_long result; 18882 imm = extract32(ctx->opcode, 13, 8); 18883 result = (uint32_t)imm << 24 | 18884 (uint32_t)imm << 16 | 18885 (uint32_t)imm << 8 | 18886 (uint32_t)imm; 18887 result = (int32_t)result; 18888 tcg_gen_movi_tl(t0, result); 18889 gen_store_gpr(t0, rt); 18890 } 18891 break; 18892 default: 18893 gen_reserved_instruction(ctx); 18894 break; 18895 } 18896 tcg_temp_free(t0); 18897 tcg_temp_free(rs_t); 18898 } 18899 18900 18901 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 18902 { 18903 int rt = extract32(ctx->opcode, 21, 5); 18904 int rs = extract32(ctx->opcode, 16, 5); 18905 int rd = extract32(ctx->opcode, 11, 5); 18906 18907 switch (extract32(ctx->opcode, 6, 3)) { 18908 case NM_POOL32AXF_1: 18909 { 18910 int32_t op1 = extract32(ctx->opcode, 9, 3); 18911 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd); 18912 } 18913 break; 18914 case NM_POOL32AXF_2: 18915 { 18916 int32_t op1 = extract32(ctx->opcode, 12, 2); 18917 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd); 18918 } 18919 break; 18920 case NM_POOL32AXF_4: 18921 { 18922 int32_t op1 = extract32(ctx->opcode, 9, 7); 18923 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); 18924 } 18925 break; 18926 case NM_POOL32AXF_5: 18927 switch (extract32(ctx->opcode, 9, 7)) { 18928 #ifndef CONFIG_USER_ONLY 18929 case NM_TLBP: 18930 gen_cp0(env, ctx, OPC_TLBP, 0, 0); 18931 break; 18932 case NM_TLBR: 18933 gen_cp0(env, ctx, OPC_TLBR, 0, 0); 18934 break; 18935 case NM_TLBWI: 18936 gen_cp0(env, ctx, OPC_TLBWI, 0, 0); 18937 break; 18938 case NM_TLBWR: 18939 gen_cp0(env, ctx, OPC_TLBWR, 0, 0); 18940 break; 18941 case NM_TLBINV: 18942 gen_cp0(env, ctx, OPC_TLBINV, 0, 0); 18943 break; 18944 case NM_TLBINVF: 18945 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); 18946 break; 18947 case NM_DI: 18948 check_cp0_enabled(ctx); 18949 { 18950 TCGv t0 = tcg_temp_new(); 18951 18952 save_cpu_state(ctx, 1); 18953 gen_helper_di(t0, cpu_env); 18954 gen_store_gpr(t0, rt); 18955 /* Stop translation as we may have switched the execution mode */ 18956 ctx->base.is_jmp = DISAS_STOP; 18957 tcg_temp_free(t0); 18958 } 18959 break; 18960 case NM_EI: 18961 check_cp0_enabled(ctx); 18962 { 18963 TCGv t0 = tcg_temp_new(); 18964 18965 save_cpu_state(ctx, 1); 18966 gen_helper_ei(t0, cpu_env); 18967 gen_store_gpr(t0, rt); 18968 /* Stop translation as we may have switched the execution mode */ 18969 ctx->base.is_jmp = DISAS_STOP; 18970 tcg_temp_free(t0); 18971 } 18972 break; 18973 case NM_RDPGPR: 18974 check_cp0_enabled(ctx); 18975 gen_load_srsgpr(rs, rt); 18976 break; 18977 case NM_WRPGPR: 18978 check_cp0_enabled(ctx); 18979 gen_store_srsgpr(rs, rt); 18980 break; 18981 case NM_WAIT: 18982 gen_cp0(env, ctx, OPC_WAIT, 0, 0); 18983 break; 18984 case NM_DERET: 18985 gen_cp0(env, ctx, OPC_DERET, 0, 0); 18986 break; 18987 case NM_ERETX: 18988 gen_cp0(env, ctx, OPC_ERET, 0, 0); 18989 break; 18990 #endif 18991 default: 18992 gen_reserved_instruction(ctx); 18993 break; 18994 } 18995 break; 18996 case NM_POOL32AXF_7: 18997 { 18998 int32_t op1 = extract32(ctx->opcode, 9, 3); 18999 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); 19000 } 19001 break; 19002 default: 19003 gen_reserved_instruction(ctx); 19004 break; 19005 } 19006 } 19007 19008 /* Immediate Value Compact Branches */ 19009 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, 19010 int rt, int32_t imm, int32_t offset) 19011 { 19012 TCGCond cond = TCG_COND_ALWAYS; 19013 TCGv t0 = tcg_temp_new(); 19014 TCGv t1 = tcg_temp_new(); 19015 19016 gen_load_gpr(t0, rt); 19017 tcg_gen_movi_tl(t1, imm); 19018 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19019 19020 /* Load needed operands and calculate btarget */ 19021 switch (opc) { 19022 case NM_BEQIC: 19023 if (rt == 0 && imm == 0) { 19024 /* Unconditional branch */ 19025 } else if (rt == 0 && imm != 0) { 19026 /* Treat as NOP */ 19027 goto out; 19028 } else { 19029 cond = TCG_COND_EQ; 19030 } 19031 break; 19032 case NM_BBEQZC: 19033 case NM_BBNEZC: 19034 check_nms(ctx); 19035 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { 19036 gen_reserved_instruction(ctx); 19037 goto out; 19038 } else if (rt == 0 && opc == NM_BBEQZC) { 19039 /* Unconditional branch */ 19040 } else if (rt == 0 && opc == NM_BBNEZC) { 19041 /* Treat as NOP */ 19042 goto out; 19043 } else { 19044 tcg_gen_shri_tl(t0, t0, imm); 19045 tcg_gen_andi_tl(t0, t0, 1); 19046 tcg_gen_movi_tl(t1, 0); 19047 if (opc == NM_BBEQZC) { 19048 cond = TCG_COND_EQ; 19049 } else { 19050 cond = TCG_COND_NE; 19051 } 19052 } 19053 break; 19054 case NM_BNEIC: 19055 if (rt == 0 && imm == 0) { 19056 /* Treat as NOP */ 19057 goto out; 19058 } else if (rt == 0 && imm != 0) { 19059 /* Unconditional branch */ 19060 } else { 19061 cond = TCG_COND_NE; 19062 } 19063 break; 19064 case NM_BGEIC: 19065 if (rt == 0 && imm == 0) { 19066 /* Unconditional branch */ 19067 } else { 19068 cond = TCG_COND_GE; 19069 } 19070 break; 19071 case NM_BLTIC: 19072 cond = TCG_COND_LT; 19073 break; 19074 case NM_BGEIUC: 19075 if (rt == 0 && imm == 0) { 19076 /* Unconditional branch */ 19077 } else { 19078 cond = TCG_COND_GEU; 19079 } 19080 break; 19081 case NM_BLTIUC: 19082 cond = TCG_COND_LTU; 19083 break; 19084 default: 19085 MIPS_INVAL("Immediate Value Compact branch"); 19086 gen_reserved_instruction(ctx); 19087 goto out; 19088 } 19089 19090 /* branch completion */ 19091 clear_branch_hflags(ctx); 19092 ctx->base.is_jmp = DISAS_NORETURN; 19093 19094 if (cond == TCG_COND_ALWAYS) { 19095 /* Uncoditional compact branch */ 19096 gen_goto_tb(ctx, 0, ctx->btarget); 19097 } else { 19098 /* Conditional compact branch */ 19099 TCGLabel *fs = gen_new_label(); 19100 19101 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs); 19102 19103 gen_goto_tb(ctx, 1, ctx->btarget); 19104 gen_set_label(fs); 19105 19106 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 19107 } 19108 19109 out: 19110 tcg_temp_free(t0); 19111 tcg_temp_free(t1); 19112 } 19113 19114 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ 19115 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, 19116 int rt) 19117 { 19118 TCGv t0 = tcg_temp_new(); 19119 TCGv t1 = tcg_temp_new(); 19120 19121 /* load rs */ 19122 gen_load_gpr(t0, rs); 19123 19124 /* link */ 19125 if (rt != 0) { 19126 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); 19127 } 19128 19129 /* calculate btarget */ 19130 tcg_gen_shli_tl(t0, t0, 1); 19131 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4); 19132 gen_op_addr_add(ctx, btarget, t1, t0); 19133 19134 /* branch completion */ 19135 clear_branch_hflags(ctx); 19136 ctx->base.is_jmp = DISAS_NORETURN; 19137 19138 /* unconditional branch to register */ 19139 tcg_gen_mov_tl(cpu_PC, btarget); 19140 tcg_gen_lookup_and_goto_ptr(); 19141 19142 tcg_temp_free(t0); 19143 tcg_temp_free(t1); 19144 } 19145 19146 /* nanoMIPS Branches */ 19147 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, 19148 int rs, int rt, int32_t offset) 19149 { 19150 int bcond_compute = 0; 19151 TCGv t0 = tcg_temp_new(); 19152 TCGv t1 = tcg_temp_new(); 19153 19154 /* Load needed operands and calculate btarget */ 19155 switch (opc) { 19156 /* compact branch */ 19157 case OPC_BGEC: 19158 case OPC_BLTC: 19159 gen_load_gpr(t0, rs); 19160 gen_load_gpr(t1, rt); 19161 bcond_compute = 1; 19162 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19163 break; 19164 case OPC_BGEUC: 19165 case OPC_BLTUC: 19166 if (rs == 0 || rs == rt) { 19167 /* OPC_BLEZALC, OPC_BGEZALC */ 19168 /* OPC_BGTZALC, OPC_BLTZALC */ 19169 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4); 19170 } 19171 gen_load_gpr(t0, rs); 19172 gen_load_gpr(t1, rt); 19173 bcond_compute = 1; 19174 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19175 break; 19176 case OPC_BC: 19177 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19178 break; 19179 case OPC_BEQZC: 19180 if (rs != 0) { 19181 /* OPC_BEQZC, OPC_BNEZC */ 19182 gen_load_gpr(t0, rs); 19183 bcond_compute = 1; 19184 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19185 } else { 19186 /* OPC_JIC, OPC_JIALC */ 19187 TCGv tbase = tcg_temp_new(); 19188 TCGv toffset = tcg_temp_new(); 19189 19190 gen_load_gpr(tbase, rt); 19191 tcg_gen_movi_tl(toffset, offset); 19192 gen_op_addr_add(ctx, btarget, tbase, toffset); 19193 tcg_temp_free(tbase); 19194 tcg_temp_free(toffset); 19195 } 19196 break; 19197 default: 19198 MIPS_INVAL("Compact branch/jump"); 19199 gen_reserved_instruction(ctx); 19200 goto out; 19201 } 19202 19203 if (bcond_compute == 0) { 19204 /* Uncoditional compact branch */ 19205 switch (opc) { 19206 case OPC_BC: 19207 gen_goto_tb(ctx, 0, ctx->btarget); 19208 break; 19209 default: 19210 MIPS_INVAL("Compact branch/jump"); 19211 gen_reserved_instruction(ctx); 19212 goto out; 19213 } 19214 } else { 19215 /* Conditional compact branch */ 19216 TCGLabel *fs = gen_new_label(); 19217 19218 switch (opc) { 19219 case OPC_BGEUC: 19220 if (rs == 0 && rt != 0) { 19221 /* OPC_BLEZALC */ 19222 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 19223 } else if (rs != 0 && rt != 0 && rs == rt) { 19224 /* OPC_BGEZALC */ 19225 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 19226 } else { 19227 /* OPC_BGEUC */ 19228 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 19229 } 19230 break; 19231 case OPC_BLTUC: 19232 if (rs == 0 && rt != 0) { 19233 /* OPC_BGTZALC */ 19234 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 19235 } else if (rs != 0 && rt != 0 && rs == rt) { 19236 /* OPC_BLTZALC */ 19237 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 19238 } else { 19239 /* OPC_BLTUC */ 19240 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 19241 } 19242 break; 19243 case OPC_BGEC: 19244 if (rs == 0 && rt != 0) { 19245 /* OPC_BLEZC */ 19246 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 19247 } else if (rs != 0 && rt != 0 && rs == rt) { 19248 /* OPC_BGEZC */ 19249 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 19250 } else { 19251 /* OPC_BGEC */ 19252 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 19253 } 19254 break; 19255 case OPC_BLTC: 19256 if (rs == 0 && rt != 0) { 19257 /* OPC_BGTZC */ 19258 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 19259 } else if (rs != 0 && rt != 0 && rs == rt) { 19260 /* OPC_BLTZC */ 19261 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 19262 } else { 19263 /* OPC_BLTC */ 19264 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 19265 } 19266 break; 19267 case OPC_BEQZC: 19268 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 19269 break; 19270 default: 19271 MIPS_INVAL("Compact conditional branch/jump"); 19272 gen_reserved_instruction(ctx); 19273 goto out; 19274 } 19275 19276 /* branch completion */ 19277 clear_branch_hflags(ctx); 19278 ctx->base.is_jmp = DISAS_NORETURN; 19279 19280 /* Generating branch here as compact branches don't have delay slot */ 19281 gen_goto_tb(ctx, 1, ctx->btarget); 19282 gen_set_label(fs); 19283 19284 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 19285 } 19286 19287 out: 19288 tcg_temp_free(t0); 19289 tcg_temp_free(t1); 19290 } 19291 19292 19293 /* nanoMIPS CP1 Branches */ 19294 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, 19295 int32_t ft, int32_t offset) 19296 { 19297 target_ulong btarget; 19298 TCGv_i64 t0 = tcg_temp_new_i64(); 19299 19300 gen_load_fpr64(ctx, t0, ft); 19301 tcg_gen_andi_i64(t0, t0, 1); 19302 19303 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 19304 19305 switch (op) { 19306 case NM_BC1EQZC: 19307 tcg_gen_xori_i64(t0, t0, 1); 19308 ctx->hflags |= MIPS_HFLAG_BC; 19309 break; 19310 case NM_BC1NEZC: 19311 /* t0 already set */ 19312 ctx->hflags |= MIPS_HFLAG_BC; 19313 break; 19314 default: 19315 MIPS_INVAL("cp1 cond branch"); 19316 gen_reserved_instruction(ctx); 19317 goto out; 19318 } 19319 19320 tcg_gen_trunc_i64_tl(bcond, t0); 19321 19322 ctx->btarget = btarget; 19323 19324 out: 19325 tcg_temp_free_i64(t0); 19326 } 19327 19328 19329 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) 19330 { 19331 TCGv t0, t1; 19332 t0 = tcg_temp_new(); 19333 t1 = tcg_temp_new(); 19334 19335 gen_load_gpr(t0, rs); 19336 gen_load_gpr(t1, rt); 19337 19338 if ((extract32(ctx->opcode, 6, 1)) == 1) { 19339 /* PP.LSXS instructions require shifting */ 19340 switch (extract32(ctx->opcode, 7, 4)) { 19341 case NM_SHXS: 19342 check_nms(ctx); 19343 /* fall through */ 19344 case NM_LHXS: 19345 case NM_LHUXS: 19346 tcg_gen_shli_tl(t0, t0, 1); 19347 break; 19348 case NM_SWXS: 19349 check_nms(ctx); 19350 /* fall through */ 19351 case NM_LWXS: 19352 case NM_LWC1XS: 19353 case NM_SWC1XS: 19354 tcg_gen_shli_tl(t0, t0, 2); 19355 break; 19356 case NM_LDC1XS: 19357 case NM_SDC1XS: 19358 tcg_gen_shli_tl(t0, t0, 3); 19359 break; 19360 } 19361 } 19362 gen_op_addr_add(ctx, t0, t0, t1); 19363 19364 switch (extract32(ctx->opcode, 7, 4)) { 19365 case NM_LBX: 19366 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 19367 MO_SB); 19368 gen_store_gpr(t0, rd); 19369 break; 19370 case NM_LHX: 19371 /*case NM_LHXS:*/ 19372 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 19373 MO_TESW); 19374 gen_store_gpr(t0, rd); 19375 break; 19376 case NM_LWX: 19377 /*case NM_LWXS:*/ 19378 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 19379 MO_TESL); 19380 gen_store_gpr(t0, rd); 19381 break; 19382 case NM_LBUX: 19383 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 19384 MO_UB); 19385 gen_store_gpr(t0, rd); 19386 break; 19387 case NM_LHUX: 19388 /*case NM_LHUXS:*/ 19389 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 19390 MO_TEUW); 19391 gen_store_gpr(t0, rd); 19392 break; 19393 case NM_SBX: 19394 check_nms(ctx); 19395 gen_load_gpr(t1, rd); 19396 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 19397 MO_8); 19398 break; 19399 case NM_SHX: 19400 /*case NM_SHXS:*/ 19401 check_nms(ctx); 19402 gen_load_gpr(t1, rd); 19403 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 19404 MO_TEUW); 19405 break; 19406 case NM_SWX: 19407 /*case NM_SWXS:*/ 19408 check_nms(ctx); 19409 gen_load_gpr(t1, rd); 19410 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 19411 MO_TEUL); 19412 break; 19413 case NM_LWC1X: 19414 /*case NM_LWC1XS:*/ 19415 case NM_LDC1X: 19416 /*case NM_LDC1XS:*/ 19417 case NM_SWC1X: 19418 /*case NM_SWC1XS:*/ 19419 case NM_SDC1X: 19420 /*case NM_SDC1XS:*/ 19421 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 19422 check_cp1_enabled(ctx); 19423 switch (extract32(ctx->opcode, 7, 4)) { 19424 case NM_LWC1X: 19425 /*case NM_LWC1XS:*/ 19426 gen_flt_ldst(ctx, OPC_LWC1, rd, t0); 19427 break; 19428 case NM_LDC1X: 19429 /*case NM_LDC1XS:*/ 19430 gen_flt_ldst(ctx, OPC_LDC1, rd, t0); 19431 break; 19432 case NM_SWC1X: 19433 /*case NM_SWC1XS:*/ 19434 gen_flt_ldst(ctx, OPC_SWC1, rd, t0); 19435 break; 19436 case NM_SDC1X: 19437 /*case NM_SDC1XS:*/ 19438 gen_flt_ldst(ctx, OPC_SDC1, rd, t0); 19439 break; 19440 } 19441 } else { 19442 generate_exception_err(ctx, EXCP_CpU, 1); 19443 } 19444 break; 19445 default: 19446 gen_reserved_instruction(ctx); 19447 break; 19448 } 19449 19450 tcg_temp_free(t0); 19451 tcg_temp_free(t1); 19452 } 19453 19454 static void gen_pool32f_nanomips_insn(DisasContext *ctx) 19455 { 19456 int rt, rs, rd; 19457 19458 rt = extract32(ctx->opcode, 21, 5); 19459 rs = extract32(ctx->opcode, 16, 5); 19460 rd = extract32(ctx->opcode, 11, 5); 19461 19462 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { 19463 gen_reserved_instruction(ctx); 19464 return; 19465 } 19466 check_cp1_enabled(ctx); 19467 switch (extract32(ctx->opcode, 0, 3)) { 19468 case NM_POOL32F_0: 19469 switch (extract32(ctx->opcode, 3, 7)) { 19470 case NM_RINT_S: 19471 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); 19472 break; 19473 case NM_RINT_D: 19474 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); 19475 break; 19476 case NM_CLASS_S: 19477 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); 19478 break; 19479 case NM_CLASS_D: 19480 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); 19481 break; 19482 case NM_ADD_S: 19483 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); 19484 break; 19485 case NM_ADD_D: 19486 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); 19487 break; 19488 case NM_SUB_S: 19489 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); 19490 break; 19491 case NM_SUB_D: 19492 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); 19493 break; 19494 case NM_MUL_S: 19495 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); 19496 break; 19497 case NM_MUL_D: 19498 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); 19499 break; 19500 case NM_DIV_S: 19501 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); 19502 break; 19503 case NM_DIV_D: 19504 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); 19505 break; 19506 case NM_SELEQZ_S: 19507 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); 19508 break; 19509 case NM_SELEQZ_D: 19510 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); 19511 break; 19512 case NM_SELNEZ_S: 19513 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); 19514 break; 19515 case NM_SELNEZ_D: 19516 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); 19517 break; 19518 case NM_SEL_S: 19519 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); 19520 break; 19521 case NM_SEL_D: 19522 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); 19523 break; 19524 case NM_MADDF_S: 19525 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); 19526 break; 19527 case NM_MADDF_D: 19528 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); 19529 break; 19530 case NM_MSUBF_S: 19531 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); 19532 break; 19533 case NM_MSUBF_D: 19534 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); 19535 break; 19536 default: 19537 gen_reserved_instruction(ctx); 19538 break; 19539 } 19540 break; 19541 case NM_POOL32F_3: 19542 switch (extract32(ctx->opcode, 3, 3)) { 19543 case NM_MIN_FMT: 19544 switch (extract32(ctx->opcode, 9, 1)) { 19545 case FMT_SDPS_S: 19546 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); 19547 break; 19548 case FMT_SDPS_D: 19549 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); 19550 break; 19551 } 19552 break; 19553 case NM_MAX_FMT: 19554 switch (extract32(ctx->opcode, 9, 1)) { 19555 case FMT_SDPS_S: 19556 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); 19557 break; 19558 case FMT_SDPS_D: 19559 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); 19560 break; 19561 } 19562 break; 19563 case NM_MINA_FMT: 19564 switch (extract32(ctx->opcode, 9, 1)) { 19565 case FMT_SDPS_S: 19566 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); 19567 break; 19568 case FMT_SDPS_D: 19569 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); 19570 break; 19571 } 19572 break; 19573 case NM_MAXA_FMT: 19574 switch (extract32(ctx->opcode, 9, 1)) { 19575 case FMT_SDPS_S: 19576 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); 19577 break; 19578 case FMT_SDPS_D: 19579 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); 19580 break; 19581 } 19582 break; 19583 case NM_POOL32FXF: 19584 switch (extract32(ctx->opcode, 6, 8)) { 19585 case NM_CFC1: 19586 gen_cp1(ctx, OPC_CFC1, rt, rs); 19587 break; 19588 case NM_CTC1: 19589 gen_cp1(ctx, OPC_CTC1, rt, rs); 19590 break; 19591 case NM_MFC1: 19592 gen_cp1(ctx, OPC_MFC1, rt, rs); 19593 break; 19594 case NM_MTC1: 19595 gen_cp1(ctx, OPC_MTC1, rt, rs); 19596 break; 19597 case NM_MFHC1: 19598 gen_cp1(ctx, OPC_MFHC1, rt, rs); 19599 break; 19600 case NM_MTHC1: 19601 gen_cp1(ctx, OPC_MTHC1, rt, rs); 19602 break; 19603 case NM_CVT_S_PL: 19604 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0); 19605 break; 19606 case NM_CVT_S_PU: 19607 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0); 19608 break; 19609 default: 19610 switch (extract32(ctx->opcode, 6, 9)) { 19611 case NM_CVT_L_S: 19612 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0); 19613 break; 19614 case NM_CVT_L_D: 19615 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0); 19616 break; 19617 case NM_CVT_W_S: 19618 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0); 19619 break; 19620 case NM_CVT_W_D: 19621 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0); 19622 break; 19623 case NM_RSQRT_S: 19624 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0); 19625 break; 19626 case NM_RSQRT_D: 19627 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0); 19628 break; 19629 case NM_SQRT_S: 19630 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0); 19631 break; 19632 case NM_SQRT_D: 19633 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0); 19634 break; 19635 case NM_RECIP_S: 19636 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0); 19637 break; 19638 case NM_RECIP_D: 19639 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0); 19640 break; 19641 case NM_FLOOR_L_S: 19642 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0); 19643 break; 19644 case NM_FLOOR_L_D: 19645 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0); 19646 break; 19647 case NM_FLOOR_W_S: 19648 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0); 19649 break; 19650 case NM_FLOOR_W_D: 19651 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0); 19652 break; 19653 case NM_CEIL_L_S: 19654 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0); 19655 break; 19656 case NM_CEIL_L_D: 19657 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0); 19658 break; 19659 case NM_CEIL_W_S: 19660 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0); 19661 break; 19662 case NM_CEIL_W_D: 19663 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0); 19664 break; 19665 case NM_TRUNC_L_S: 19666 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0); 19667 break; 19668 case NM_TRUNC_L_D: 19669 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0); 19670 break; 19671 case NM_TRUNC_W_S: 19672 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0); 19673 break; 19674 case NM_TRUNC_W_D: 19675 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0); 19676 break; 19677 case NM_ROUND_L_S: 19678 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0); 19679 break; 19680 case NM_ROUND_L_D: 19681 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0); 19682 break; 19683 case NM_ROUND_W_S: 19684 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0); 19685 break; 19686 case NM_ROUND_W_D: 19687 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0); 19688 break; 19689 case NM_MOV_S: 19690 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0); 19691 break; 19692 case NM_MOV_D: 19693 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0); 19694 break; 19695 case NM_ABS_S: 19696 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0); 19697 break; 19698 case NM_ABS_D: 19699 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0); 19700 break; 19701 case NM_NEG_S: 19702 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0); 19703 break; 19704 case NM_NEG_D: 19705 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0); 19706 break; 19707 case NM_CVT_D_S: 19708 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0); 19709 break; 19710 case NM_CVT_D_W: 19711 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0); 19712 break; 19713 case NM_CVT_D_L: 19714 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0); 19715 break; 19716 case NM_CVT_S_D: 19717 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0); 19718 break; 19719 case NM_CVT_S_W: 19720 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0); 19721 break; 19722 case NM_CVT_S_L: 19723 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); 19724 break; 19725 default: 19726 gen_reserved_instruction(ctx); 19727 break; 19728 } 19729 break; 19730 } 19731 break; 19732 } 19733 break; 19734 case NM_POOL32F_5: 19735 switch (extract32(ctx->opcode, 3, 3)) { 19736 case NM_CMP_CONDN_S: 19737 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 19738 break; 19739 case NM_CMP_CONDN_D: 19740 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 19741 break; 19742 default: 19743 gen_reserved_instruction(ctx); 19744 break; 19745 } 19746 break; 19747 default: 19748 gen_reserved_instruction(ctx); 19749 break; 19750 } 19751 } 19752 19753 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, 19754 int rd, int rs, int rt) 19755 { 19756 int ret = rd; 19757 TCGv t0 = tcg_temp_new(); 19758 TCGv v1_t = tcg_temp_new(); 19759 TCGv v2_t = tcg_temp_new(); 19760 19761 gen_load_gpr(v1_t, rs); 19762 gen_load_gpr(v2_t, rt); 19763 19764 switch (opc) { 19765 case NM_CMP_EQ_PH: 19766 check_dsp(ctx); 19767 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 19768 break; 19769 case NM_CMP_LT_PH: 19770 check_dsp(ctx); 19771 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 19772 break; 19773 case NM_CMP_LE_PH: 19774 check_dsp(ctx); 19775 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 19776 break; 19777 case NM_CMPU_EQ_QB: 19778 check_dsp(ctx); 19779 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 19780 break; 19781 case NM_CMPU_LT_QB: 19782 check_dsp(ctx); 19783 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 19784 break; 19785 case NM_CMPU_LE_QB: 19786 check_dsp(ctx); 19787 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 19788 break; 19789 case NM_CMPGU_EQ_QB: 19790 check_dsp(ctx); 19791 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 19792 gen_store_gpr(v1_t, ret); 19793 break; 19794 case NM_CMPGU_LT_QB: 19795 check_dsp(ctx); 19796 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 19797 gen_store_gpr(v1_t, ret); 19798 break; 19799 case NM_CMPGU_LE_QB: 19800 check_dsp(ctx); 19801 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 19802 gen_store_gpr(v1_t, ret); 19803 break; 19804 case NM_CMPGDU_EQ_QB: 19805 check_dsp_r2(ctx); 19806 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 19807 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 19808 gen_store_gpr(v1_t, ret); 19809 break; 19810 case NM_CMPGDU_LT_QB: 19811 check_dsp_r2(ctx); 19812 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 19813 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 19814 gen_store_gpr(v1_t, ret); 19815 break; 19816 case NM_CMPGDU_LE_QB: 19817 check_dsp_r2(ctx); 19818 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 19819 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 19820 gen_store_gpr(v1_t, ret); 19821 break; 19822 case NM_PACKRL_PH: 19823 check_dsp(ctx); 19824 gen_helper_packrl_ph(v1_t, v1_t, v2_t); 19825 gen_store_gpr(v1_t, ret); 19826 break; 19827 case NM_PICK_QB: 19828 check_dsp(ctx); 19829 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env); 19830 gen_store_gpr(v1_t, ret); 19831 break; 19832 case NM_PICK_PH: 19833 check_dsp(ctx); 19834 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env); 19835 gen_store_gpr(v1_t, ret); 19836 break; 19837 case NM_ADDQ_S_W: 19838 check_dsp(ctx); 19839 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env); 19840 gen_store_gpr(v1_t, ret); 19841 break; 19842 case NM_SUBQ_S_W: 19843 check_dsp(ctx); 19844 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env); 19845 gen_store_gpr(v1_t, ret); 19846 break; 19847 case NM_ADDSC: 19848 check_dsp(ctx); 19849 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env); 19850 gen_store_gpr(v1_t, ret); 19851 break; 19852 case NM_ADDWC: 19853 check_dsp(ctx); 19854 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env); 19855 gen_store_gpr(v1_t, ret); 19856 break; 19857 case NM_ADDQ_S_PH: 19858 check_dsp(ctx); 19859 switch (extract32(ctx->opcode, 10, 1)) { 19860 case 0: 19861 /* ADDQ_PH */ 19862 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env); 19863 gen_store_gpr(v1_t, ret); 19864 break; 19865 case 1: 19866 /* ADDQ_S_PH */ 19867 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env); 19868 gen_store_gpr(v1_t, ret); 19869 break; 19870 } 19871 break; 19872 case NM_ADDQH_R_PH: 19873 check_dsp_r2(ctx); 19874 switch (extract32(ctx->opcode, 10, 1)) { 19875 case 0: 19876 /* ADDQH_PH */ 19877 gen_helper_addqh_ph(v1_t, v1_t, v2_t); 19878 gen_store_gpr(v1_t, ret); 19879 break; 19880 case 1: 19881 /* ADDQH_R_PH */ 19882 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); 19883 gen_store_gpr(v1_t, ret); 19884 break; 19885 } 19886 break; 19887 case NM_ADDQH_R_W: 19888 check_dsp_r2(ctx); 19889 switch (extract32(ctx->opcode, 10, 1)) { 19890 case 0: 19891 /* ADDQH_W */ 19892 gen_helper_addqh_w(v1_t, v1_t, v2_t); 19893 gen_store_gpr(v1_t, ret); 19894 break; 19895 case 1: 19896 /* ADDQH_R_W */ 19897 gen_helper_addqh_r_w(v1_t, v1_t, v2_t); 19898 gen_store_gpr(v1_t, ret); 19899 break; 19900 } 19901 break; 19902 case NM_ADDU_S_QB: 19903 check_dsp(ctx); 19904 switch (extract32(ctx->opcode, 10, 1)) { 19905 case 0: 19906 /* ADDU_QB */ 19907 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env); 19908 gen_store_gpr(v1_t, ret); 19909 break; 19910 case 1: 19911 /* ADDU_S_QB */ 19912 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env); 19913 gen_store_gpr(v1_t, ret); 19914 break; 19915 } 19916 break; 19917 case NM_ADDU_S_PH: 19918 check_dsp_r2(ctx); 19919 switch (extract32(ctx->opcode, 10, 1)) { 19920 case 0: 19921 /* ADDU_PH */ 19922 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env); 19923 gen_store_gpr(v1_t, ret); 19924 break; 19925 case 1: 19926 /* ADDU_S_PH */ 19927 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env); 19928 gen_store_gpr(v1_t, ret); 19929 break; 19930 } 19931 break; 19932 case NM_ADDUH_R_QB: 19933 check_dsp_r2(ctx); 19934 switch (extract32(ctx->opcode, 10, 1)) { 19935 case 0: 19936 /* ADDUH_QB */ 19937 gen_helper_adduh_qb(v1_t, v1_t, v2_t); 19938 gen_store_gpr(v1_t, ret); 19939 break; 19940 case 1: 19941 /* ADDUH_R_QB */ 19942 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t); 19943 gen_store_gpr(v1_t, ret); 19944 break; 19945 } 19946 break; 19947 case NM_SHRAV_R_PH: 19948 check_dsp(ctx); 19949 switch (extract32(ctx->opcode, 10, 1)) { 19950 case 0: 19951 /* SHRAV_PH */ 19952 gen_helper_shra_ph(v1_t, v1_t, v2_t); 19953 gen_store_gpr(v1_t, ret); 19954 break; 19955 case 1: 19956 /* SHRAV_R_PH */ 19957 gen_helper_shra_r_ph(v1_t, v1_t, v2_t); 19958 gen_store_gpr(v1_t, ret); 19959 break; 19960 } 19961 break; 19962 case NM_SHRAV_R_QB: 19963 check_dsp_r2(ctx); 19964 switch (extract32(ctx->opcode, 10, 1)) { 19965 case 0: 19966 /* SHRAV_QB */ 19967 gen_helper_shra_qb(v1_t, v1_t, v2_t); 19968 gen_store_gpr(v1_t, ret); 19969 break; 19970 case 1: 19971 /* SHRAV_R_QB */ 19972 gen_helper_shra_r_qb(v1_t, v1_t, v2_t); 19973 gen_store_gpr(v1_t, ret); 19974 break; 19975 } 19976 break; 19977 case NM_SUBQ_S_PH: 19978 check_dsp(ctx); 19979 switch (extract32(ctx->opcode, 10, 1)) { 19980 case 0: 19981 /* SUBQ_PH */ 19982 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env); 19983 gen_store_gpr(v1_t, ret); 19984 break; 19985 case 1: 19986 /* SUBQ_S_PH */ 19987 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env); 19988 gen_store_gpr(v1_t, ret); 19989 break; 19990 } 19991 break; 19992 case NM_SUBQH_R_PH: 19993 check_dsp_r2(ctx); 19994 switch (extract32(ctx->opcode, 10, 1)) { 19995 case 0: 19996 /* SUBQH_PH */ 19997 gen_helper_subqh_ph(v1_t, v1_t, v2_t); 19998 gen_store_gpr(v1_t, ret); 19999 break; 20000 case 1: 20001 /* SUBQH_R_PH */ 20002 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t); 20003 gen_store_gpr(v1_t, ret); 20004 break; 20005 } 20006 break; 20007 case NM_SUBQH_R_W: 20008 check_dsp_r2(ctx); 20009 switch (extract32(ctx->opcode, 10, 1)) { 20010 case 0: 20011 /* SUBQH_W */ 20012 gen_helper_subqh_w(v1_t, v1_t, v2_t); 20013 gen_store_gpr(v1_t, ret); 20014 break; 20015 case 1: 20016 /* SUBQH_R_W */ 20017 gen_helper_subqh_r_w(v1_t, v1_t, v2_t); 20018 gen_store_gpr(v1_t, ret); 20019 break; 20020 } 20021 break; 20022 case NM_SUBU_S_QB: 20023 check_dsp(ctx); 20024 switch (extract32(ctx->opcode, 10, 1)) { 20025 case 0: 20026 /* SUBU_QB */ 20027 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env); 20028 gen_store_gpr(v1_t, ret); 20029 break; 20030 case 1: 20031 /* SUBU_S_QB */ 20032 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env); 20033 gen_store_gpr(v1_t, ret); 20034 break; 20035 } 20036 break; 20037 case NM_SUBU_S_PH: 20038 check_dsp_r2(ctx); 20039 switch (extract32(ctx->opcode, 10, 1)) { 20040 case 0: 20041 /* SUBU_PH */ 20042 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env); 20043 gen_store_gpr(v1_t, ret); 20044 break; 20045 case 1: 20046 /* SUBU_S_PH */ 20047 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env); 20048 gen_store_gpr(v1_t, ret); 20049 break; 20050 } 20051 break; 20052 case NM_SUBUH_R_QB: 20053 check_dsp_r2(ctx); 20054 switch (extract32(ctx->opcode, 10, 1)) { 20055 case 0: 20056 /* SUBUH_QB */ 20057 gen_helper_subuh_qb(v1_t, v1_t, v2_t); 20058 gen_store_gpr(v1_t, ret); 20059 break; 20060 case 1: 20061 /* SUBUH_R_QB */ 20062 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t); 20063 gen_store_gpr(v1_t, ret); 20064 break; 20065 } 20066 break; 20067 case NM_SHLLV_S_PH: 20068 check_dsp(ctx); 20069 switch (extract32(ctx->opcode, 10, 1)) { 20070 case 0: 20071 /* SHLLV_PH */ 20072 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env); 20073 gen_store_gpr(v1_t, ret); 20074 break; 20075 case 1: 20076 /* SHLLV_S_PH */ 20077 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env); 20078 gen_store_gpr(v1_t, ret); 20079 break; 20080 } 20081 break; 20082 case NM_PRECR_SRA_R_PH_W: 20083 check_dsp_r2(ctx); 20084 switch (extract32(ctx->opcode, 10, 1)) { 20085 case 0: 20086 /* PRECR_SRA_PH_W */ 20087 { 20088 TCGv_i32 sa_t = tcg_const_i32(rd); 20089 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t, 20090 cpu_gpr[rt]); 20091 gen_store_gpr(v1_t, rt); 20092 tcg_temp_free_i32(sa_t); 20093 } 20094 break; 20095 case 1: 20096 /* PRECR_SRA_R_PH_W */ 20097 { 20098 TCGv_i32 sa_t = tcg_const_i32(rd); 20099 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t, 20100 cpu_gpr[rt]); 20101 gen_store_gpr(v1_t, rt); 20102 tcg_temp_free_i32(sa_t); 20103 } 20104 break; 20105 } 20106 break; 20107 case NM_MULEU_S_PH_QBL: 20108 check_dsp(ctx); 20109 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env); 20110 gen_store_gpr(v1_t, ret); 20111 break; 20112 case NM_MULEU_S_PH_QBR: 20113 check_dsp(ctx); 20114 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env); 20115 gen_store_gpr(v1_t, ret); 20116 break; 20117 case NM_MULQ_RS_PH: 20118 check_dsp(ctx); 20119 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env); 20120 gen_store_gpr(v1_t, ret); 20121 break; 20122 case NM_MULQ_S_PH: 20123 check_dsp_r2(ctx); 20124 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env); 20125 gen_store_gpr(v1_t, ret); 20126 break; 20127 case NM_MULQ_RS_W: 20128 check_dsp_r2(ctx); 20129 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env); 20130 gen_store_gpr(v1_t, ret); 20131 break; 20132 case NM_MULQ_S_W: 20133 check_dsp_r2(ctx); 20134 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env); 20135 gen_store_gpr(v1_t, ret); 20136 break; 20137 case NM_APPEND: 20138 check_dsp_r2(ctx); 20139 gen_load_gpr(t0, rs); 20140 if (rd != 0) { 20141 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd); 20142 } 20143 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 20144 break; 20145 case NM_MODSUB: 20146 check_dsp(ctx); 20147 gen_helper_modsub(v1_t, v1_t, v2_t); 20148 gen_store_gpr(v1_t, ret); 20149 break; 20150 case NM_SHRAV_R_W: 20151 check_dsp(ctx); 20152 gen_helper_shra_r_w(v1_t, v1_t, v2_t); 20153 gen_store_gpr(v1_t, ret); 20154 break; 20155 case NM_SHRLV_PH: 20156 check_dsp_r2(ctx); 20157 gen_helper_shrl_ph(v1_t, v1_t, v2_t); 20158 gen_store_gpr(v1_t, ret); 20159 break; 20160 case NM_SHRLV_QB: 20161 check_dsp(ctx); 20162 gen_helper_shrl_qb(v1_t, v1_t, v2_t); 20163 gen_store_gpr(v1_t, ret); 20164 break; 20165 case NM_SHLLV_QB: 20166 check_dsp(ctx); 20167 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env); 20168 gen_store_gpr(v1_t, ret); 20169 break; 20170 case NM_SHLLV_S_W: 20171 check_dsp(ctx); 20172 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env); 20173 gen_store_gpr(v1_t, ret); 20174 break; 20175 case NM_SHILO: 20176 check_dsp(ctx); 20177 { 20178 TCGv tv0 = tcg_temp_new(); 20179 TCGv tv1 = tcg_temp_new(); 20180 int16_t imm = extract32(ctx->opcode, 16, 7); 20181 20182 tcg_gen_movi_tl(tv0, rd >> 3); 20183 tcg_gen_movi_tl(tv1, imm); 20184 gen_helper_shilo(tv0, tv1, cpu_env); 20185 } 20186 break; 20187 case NM_MULEQ_S_W_PHL: 20188 check_dsp(ctx); 20189 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env); 20190 gen_store_gpr(v1_t, ret); 20191 break; 20192 case NM_MULEQ_S_W_PHR: 20193 check_dsp(ctx); 20194 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env); 20195 gen_store_gpr(v1_t, ret); 20196 break; 20197 case NM_MUL_S_PH: 20198 check_dsp_r2(ctx); 20199 switch (extract32(ctx->opcode, 10, 1)) { 20200 case 0: 20201 /* MUL_PH */ 20202 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env); 20203 gen_store_gpr(v1_t, ret); 20204 break; 20205 case 1: 20206 /* MUL_S_PH */ 20207 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env); 20208 gen_store_gpr(v1_t, ret); 20209 break; 20210 } 20211 break; 20212 case NM_PRECR_QB_PH: 20213 check_dsp_r2(ctx); 20214 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t); 20215 gen_store_gpr(v1_t, ret); 20216 break; 20217 case NM_PRECRQ_QB_PH: 20218 check_dsp(ctx); 20219 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t); 20220 gen_store_gpr(v1_t, ret); 20221 break; 20222 case NM_PRECRQ_PH_W: 20223 check_dsp(ctx); 20224 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t); 20225 gen_store_gpr(v1_t, ret); 20226 break; 20227 case NM_PRECRQ_RS_PH_W: 20228 check_dsp(ctx); 20229 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env); 20230 gen_store_gpr(v1_t, ret); 20231 break; 20232 case NM_PRECRQU_S_QB_PH: 20233 check_dsp(ctx); 20234 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env); 20235 gen_store_gpr(v1_t, ret); 20236 break; 20237 case NM_SHRA_R_W: 20238 check_dsp(ctx); 20239 tcg_gen_movi_tl(t0, rd); 20240 gen_helper_shra_r_w(v1_t, t0, v1_t); 20241 gen_store_gpr(v1_t, rt); 20242 break; 20243 case NM_SHRA_R_PH: 20244 check_dsp(ctx); 20245 tcg_gen_movi_tl(t0, rd >> 1); 20246 switch (extract32(ctx->opcode, 10, 1)) { 20247 case 0: 20248 /* SHRA_PH */ 20249 gen_helper_shra_ph(v1_t, t0, v1_t); 20250 gen_store_gpr(v1_t, rt); 20251 break; 20252 case 1: 20253 /* SHRA_R_PH */ 20254 gen_helper_shra_r_ph(v1_t, t0, v1_t); 20255 gen_store_gpr(v1_t, rt); 20256 break; 20257 } 20258 break; 20259 case NM_SHLL_S_PH: 20260 check_dsp(ctx); 20261 tcg_gen_movi_tl(t0, rd >> 1); 20262 switch (extract32(ctx->opcode, 10, 2)) { 20263 case 0: 20264 /* SHLL_PH */ 20265 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env); 20266 gen_store_gpr(v1_t, rt); 20267 break; 20268 case 2: 20269 /* SHLL_S_PH */ 20270 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env); 20271 gen_store_gpr(v1_t, rt); 20272 break; 20273 default: 20274 gen_reserved_instruction(ctx); 20275 break; 20276 } 20277 break; 20278 case NM_SHLL_S_W: 20279 check_dsp(ctx); 20280 tcg_gen_movi_tl(t0, rd); 20281 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env); 20282 gen_store_gpr(v1_t, rt); 20283 break; 20284 case NM_REPL_PH: 20285 check_dsp(ctx); 20286 { 20287 int16_t imm; 20288 imm = sextract32(ctx->opcode, 11, 11); 20289 imm = (int16_t)(imm << 6) >> 6; 20290 if (rt != 0) { 20291 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm)); 20292 } 20293 } 20294 break; 20295 default: 20296 gen_reserved_instruction(ctx); 20297 break; 20298 } 20299 } 20300 20301 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) 20302 { 20303 uint16_t insn; 20304 uint32_t op; 20305 int rt, rs, rd; 20306 int offset; 20307 int imm; 20308 20309 insn = translator_lduw(env, ctx->base.pc_next + 2); 20310 ctx->opcode = (ctx->opcode << 16) | insn; 20311 20312 rt = extract32(ctx->opcode, 21, 5); 20313 rs = extract32(ctx->opcode, 16, 5); 20314 rd = extract32(ctx->opcode, 11, 5); 20315 20316 op = extract32(ctx->opcode, 26, 6); 20317 switch (op) { 20318 case NM_P_ADDIU: 20319 if (rt == 0) { 20320 /* P.RI */ 20321 switch (extract32(ctx->opcode, 19, 2)) { 20322 case NM_SIGRIE: 20323 default: 20324 gen_reserved_instruction(ctx); 20325 break; 20326 case NM_P_SYSCALL: 20327 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) { 20328 generate_exception_end(ctx, EXCP_SYSCALL); 20329 } else { 20330 gen_reserved_instruction(ctx); 20331 } 20332 break; 20333 case NM_BREAK: 20334 generate_exception_end(ctx, EXCP_BREAK); 20335 break; 20336 case NM_SDBBP: 20337 if (is_uhi(extract32(ctx->opcode, 0, 19))) { 20338 gen_helper_do_semihosting(cpu_env); 20339 } else { 20340 if (ctx->hflags & MIPS_HFLAG_SBRI) { 20341 gen_reserved_instruction(ctx); 20342 } else { 20343 generate_exception_end(ctx, EXCP_DBp); 20344 } 20345 } 20346 break; 20347 } 20348 } else { 20349 /* NM_ADDIU */ 20350 imm = extract32(ctx->opcode, 0, 16); 20351 if (rs != 0) { 20352 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); 20353 } else { 20354 tcg_gen_movi_tl(cpu_gpr[rt], imm); 20355 } 20356 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 20357 } 20358 break; 20359 case NM_ADDIUPC: 20360 if (rt != 0) { 20361 offset = sextract32(ctx->opcode, 0, 1) << 21 | 20362 extract32(ctx->opcode, 1, 20) << 1; 20363 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset); 20364 tcg_gen_movi_tl(cpu_gpr[rt], addr); 20365 } 20366 break; 20367 case NM_POOL32A: 20368 switch (ctx->opcode & 0x07) { 20369 case NM_POOL32A0: 20370 gen_pool32a0_nanomips_insn(env, ctx); 20371 break; 20372 case NM_POOL32A5: 20373 { 20374 int32_t op1 = extract32(ctx->opcode, 3, 7); 20375 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt); 20376 } 20377 break; 20378 case NM_POOL32A7: 20379 switch (extract32(ctx->opcode, 3, 3)) { 20380 case NM_P_LSX: 20381 gen_p_lsx(ctx, rd, rs, rt); 20382 break; 20383 case NM_LSA: 20384 /* 20385 * In nanoMIPS, the shift field directly encodes the shift 20386 * amount, meaning that the supported shift values are in 20387 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). 20388 */ 20389 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1); 20390 break; 20391 case NM_EXTW: 20392 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); 20393 break; 20394 case NM_POOL32AXF: 20395 gen_pool32axf_nanomips_insn(env, ctx); 20396 break; 20397 default: 20398 gen_reserved_instruction(ctx); 20399 break; 20400 } 20401 break; 20402 default: 20403 gen_reserved_instruction(ctx); 20404 break; 20405 } 20406 break; 20407 case NM_P_GP_W: 20408 switch (ctx->opcode & 0x03) { 20409 case NM_ADDIUGP_W: 20410 if (rt != 0) { 20411 offset = extract32(ctx->opcode, 0, 21); 20412 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); 20413 } 20414 break; 20415 case NM_LWGP: 20416 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 20417 break; 20418 case NM_SWGP: 20419 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 20420 break; 20421 default: 20422 gen_reserved_instruction(ctx); 20423 break; 20424 } 20425 break; 20426 case NM_P48I: 20427 { 20428 insn = translator_lduw(env, ctx->base.pc_next + 4); 20429 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16; 20430 switch (extract32(ctx->opcode, 16, 5)) { 20431 case NM_LI48: 20432 check_nms(ctx); 20433 if (rt != 0) { 20434 tcg_gen_movi_tl(cpu_gpr[rt], addr_off); 20435 } 20436 break; 20437 case NM_ADDIU48: 20438 check_nms(ctx); 20439 if (rt != 0) { 20440 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off); 20441 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 20442 } 20443 break; 20444 case NM_ADDIUGP48: 20445 check_nms(ctx); 20446 if (rt != 0) { 20447 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off); 20448 } 20449 break; 20450 case NM_ADDIUPC48: 20451 check_nms(ctx); 20452 if (rt != 0) { 20453 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 20454 addr_off); 20455 20456 tcg_gen_movi_tl(cpu_gpr[rt], addr); 20457 } 20458 break; 20459 case NM_LWPC48: 20460 check_nms(ctx); 20461 if (rt != 0) { 20462 TCGv t0; 20463 t0 = tcg_temp_new(); 20464 20465 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 20466 addr_off); 20467 20468 tcg_gen_movi_tl(t0, addr); 20469 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL); 20470 tcg_temp_free(t0); 20471 } 20472 break; 20473 case NM_SWPC48: 20474 check_nms(ctx); 20475 { 20476 TCGv t0, t1; 20477 t0 = tcg_temp_new(); 20478 t1 = tcg_temp_new(); 20479 20480 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 20481 addr_off); 20482 20483 tcg_gen_movi_tl(t0, addr); 20484 gen_load_gpr(t1, rt); 20485 20486 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 20487 20488 tcg_temp_free(t0); 20489 tcg_temp_free(t1); 20490 } 20491 break; 20492 default: 20493 gen_reserved_instruction(ctx); 20494 break; 20495 } 20496 return 6; 20497 } 20498 case NM_P_U12: 20499 switch (extract32(ctx->opcode, 12, 4)) { 20500 case NM_ORI: 20501 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12)); 20502 break; 20503 case NM_XORI: 20504 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12)); 20505 break; 20506 case NM_ANDI: 20507 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12)); 20508 break; 20509 case NM_P_SR: 20510 switch (extract32(ctx->opcode, 20, 1)) { 20511 case NM_PP_SR: 20512 switch (ctx->opcode & 3) { 20513 case NM_SAVE: 20514 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), 20515 extract32(ctx->opcode, 2, 1), 20516 extract32(ctx->opcode, 3, 9) << 3); 20517 break; 20518 case NM_RESTORE: 20519 case NM_RESTORE_JRC: 20520 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), 20521 extract32(ctx->opcode, 2, 1), 20522 extract32(ctx->opcode, 3, 9) << 3); 20523 if ((ctx->opcode & 3) == NM_RESTORE_JRC) { 20524 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 20525 } 20526 break; 20527 default: 20528 gen_reserved_instruction(ctx); 20529 break; 20530 } 20531 break; 20532 case NM_P_SR_F: 20533 gen_reserved_instruction(ctx); 20534 break; 20535 } 20536 break; 20537 case NM_SLTI: 20538 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12)); 20539 break; 20540 case NM_SLTIU: 20541 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12)); 20542 break; 20543 case NM_SEQI: 20544 { 20545 TCGv t0 = tcg_temp_new(); 20546 20547 imm = extract32(ctx->opcode, 0, 12); 20548 gen_load_gpr(t0, rs); 20549 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm); 20550 gen_store_gpr(t0, rt); 20551 20552 tcg_temp_free(t0); 20553 } 20554 break; 20555 case NM_ADDIUNEG: 20556 imm = (int16_t) extract32(ctx->opcode, 0, 12); 20557 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm); 20558 break; 20559 case NM_P_SHIFT: 20560 { 20561 int shift = extract32(ctx->opcode, 0, 5); 20562 switch (extract32(ctx->opcode, 5, 4)) { 20563 case NM_P_SLL: 20564 if (rt == 0 && shift == 0) { 20565 /* NOP */ 20566 } else if (rt == 0 && shift == 3) { 20567 /* EHB - treat as NOP */ 20568 } else if (rt == 0 && shift == 5) { 20569 /* PAUSE - treat as NOP */ 20570 } else if (rt == 0 && shift == 6) { 20571 /* SYNC */ 20572 gen_sync(extract32(ctx->opcode, 16, 5)); 20573 } else { 20574 /* SLL */ 20575 gen_shift_imm(ctx, OPC_SLL, rt, rs, 20576 extract32(ctx->opcode, 0, 5)); 20577 } 20578 break; 20579 case NM_SRL: 20580 gen_shift_imm(ctx, OPC_SRL, rt, rs, 20581 extract32(ctx->opcode, 0, 5)); 20582 break; 20583 case NM_SRA: 20584 gen_shift_imm(ctx, OPC_SRA, rt, rs, 20585 extract32(ctx->opcode, 0, 5)); 20586 break; 20587 case NM_ROTR: 20588 gen_shift_imm(ctx, OPC_ROTR, rt, rs, 20589 extract32(ctx->opcode, 0, 5)); 20590 break; 20591 } 20592 } 20593 break; 20594 case NM_P_ROTX: 20595 check_nms(ctx); 20596 if (rt != 0) { 20597 TCGv t0 = tcg_temp_new(); 20598 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5)); 20599 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4) 20600 << 1); 20601 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1)); 20602 20603 gen_load_gpr(t0, rs); 20604 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); 20605 tcg_temp_free(t0); 20606 20607 tcg_temp_free_i32(shift); 20608 tcg_temp_free_i32(shiftx); 20609 tcg_temp_free_i32(stripe); 20610 } 20611 break; 20612 case NM_P_INS: 20613 switch (((ctx->opcode >> 10) & 2) | 20614 (extract32(ctx->opcode, 5, 1))) { 20615 case NM_INS: 20616 check_nms(ctx); 20617 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5), 20618 extract32(ctx->opcode, 6, 5)); 20619 break; 20620 default: 20621 gen_reserved_instruction(ctx); 20622 break; 20623 } 20624 break; 20625 case NM_P_EXT: 20626 switch (((ctx->opcode >> 10) & 2) | 20627 (extract32(ctx->opcode, 5, 1))) { 20628 case NM_EXT: 20629 check_nms(ctx); 20630 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5), 20631 extract32(ctx->opcode, 6, 5)); 20632 break; 20633 default: 20634 gen_reserved_instruction(ctx); 20635 break; 20636 } 20637 break; 20638 default: 20639 gen_reserved_instruction(ctx); 20640 break; 20641 } 20642 break; 20643 case NM_POOL32F: 20644 gen_pool32f_nanomips_insn(ctx); 20645 break; 20646 case NM_POOL32S: 20647 break; 20648 case NM_P_LUI: 20649 switch (extract32(ctx->opcode, 1, 1)) { 20650 case NM_LUI: 20651 if (rt != 0) { 20652 tcg_gen_movi_tl(cpu_gpr[rt], 20653 sextract32(ctx->opcode, 0, 1) << 31 | 20654 extract32(ctx->opcode, 2, 10) << 21 | 20655 extract32(ctx->opcode, 12, 9) << 12); 20656 } 20657 break; 20658 case NM_ALUIPC: 20659 if (rt != 0) { 20660 offset = sextract32(ctx->opcode, 0, 1) << 31 | 20661 extract32(ctx->opcode, 2, 10) << 21 | 20662 extract32(ctx->opcode, 12, 9) << 12; 20663 target_long addr; 20664 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset); 20665 tcg_gen_movi_tl(cpu_gpr[rt], addr); 20666 } 20667 break; 20668 } 20669 break; 20670 case NM_P_GP_BH: 20671 { 20672 uint32_t u = extract32(ctx->opcode, 0, 18); 20673 20674 switch (extract32(ctx->opcode, 18, 3)) { 20675 case NM_LBGP: 20676 gen_ld(ctx, OPC_LB, rt, 28, u); 20677 break; 20678 case NM_SBGP: 20679 gen_st(ctx, OPC_SB, rt, 28, u); 20680 break; 20681 case NM_LBUGP: 20682 gen_ld(ctx, OPC_LBU, rt, 28, u); 20683 break; 20684 case NM_ADDIUGP_B: 20685 if (rt != 0) { 20686 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); 20687 } 20688 break; 20689 case NM_P_GP_LH: 20690 u &= ~1; 20691 switch (ctx->opcode & 1) { 20692 case NM_LHGP: 20693 gen_ld(ctx, OPC_LH, rt, 28, u); 20694 break; 20695 case NM_LHUGP: 20696 gen_ld(ctx, OPC_LHU, rt, 28, u); 20697 break; 20698 } 20699 break; 20700 case NM_P_GP_SH: 20701 u &= ~1; 20702 switch (ctx->opcode & 1) { 20703 case NM_SHGP: 20704 gen_st(ctx, OPC_SH, rt, 28, u); 20705 break; 20706 default: 20707 gen_reserved_instruction(ctx); 20708 break; 20709 } 20710 break; 20711 case NM_P_GP_CP1: 20712 u &= ~0x3; 20713 switch (ctx->opcode & 0x3) { 20714 case NM_LWC1GP: 20715 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); 20716 break; 20717 case NM_LDC1GP: 20718 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); 20719 break; 20720 case NM_SWC1GP: 20721 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); 20722 break; 20723 case NM_SDC1GP: 20724 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); 20725 break; 20726 } 20727 break; 20728 default: 20729 gen_reserved_instruction(ctx); 20730 break; 20731 } 20732 } 20733 break; 20734 case NM_P_LS_U12: 20735 { 20736 uint32_t u = extract32(ctx->opcode, 0, 12); 20737 20738 switch (extract32(ctx->opcode, 12, 4)) { 20739 case NM_P_PREFU12: 20740 if (rt == 31) { 20741 /* SYNCI */ 20742 /* 20743 * Break the TB to be able to sync copied instructions 20744 * immediately. 20745 */ 20746 ctx->base.is_jmp = DISAS_STOP; 20747 } else { 20748 /* PREF */ 20749 /* Treat as NOP. */ 20750 } 20751 break; 20752 case NM_LB: 20753 gen_ld(ctx, OPC_LB, rt, rs, u); 20754 break; 20755 case NM_LH: 20756 gen_ld(ctx, OPC_LH, rt, rs, u); 20757 break; 20758 case NM_LW: 20759 gen_ld(ctx, OPC_LW, rt, rs, u); 20760 break; 20761 case NM_LBU: 20762 gen_ld(ctx, OPC_LBU, rt, rs, u); 20763 break; 20764 case NM_LHU: 20765 gen_ld(ctx, OPC_LHU, rt, rs, u); 20766 break; 20767 case NM_SB: 20768 gen_st(ctx, OPC_SB, rt, rs, u); 20769 break; 20770 case NM_SH: 20771 gen_st(ctx, OPC_SH, rt, rs, u); 20772 break; 20773 case NM_SW: 20774 gen_st(ctx, OPC_SW, rt, rs, u); 20775 break; 20776 case NM_LWC1: 20777 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); 20778 break; 20779 case NM_LDC1: 20780 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); 20781 break; 20782 case NM_SWC1: 20783 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); 20784 break; 20785 case NM_SDC1: 20786 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); 20787 break; 20788 default: 20789 gen_reserved_instruction(ctx); 20790 break; 20791 } 20792 } 20793 break; 20794 case NM_P_LS_S9: 20795 { 20796 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) | 20797 extract32(ctx->opcode, 0, 8); 20798 20799 switch (extract32(ctx->opcode, 8, 3)) { 20800 case NM_P_LS_S0: 20801 switch (extract32(ctx->opcode, 11, 4)) { 20802 case NM_LBS9: 20803 gen_ld(ctx, OPC_LB, rt, rs, s); 20804 break; 20805 case NM_LHS9: 20806 gen_ld(ctx, OPC_LH, rt, rs, s); 20807 break; 20808 case NM_LWS9: 20809 gen_ld(ctx, OPC_LW, rt, rs, s); 20810 break; 20811 case NM_LBUS9: 20812 gen_ld(ctx, OPC_LBU, rt, rs, s); 20813 break; 20814 case NM_LHUS9: 20815 gen_ld(ctx, OPC_LHU, rt, rs, s); 20816 break; 20817 case NM_SBS9: 20818 gen_st(ctx, OPC_SB, rt, rs, s); 20819 break; 20820 case NM_SHS9: 20821 gen_st(ctx, OPC_SH, rt, rs, s); 20822 break; 20823 case NM_SWS9: 20824 gen_st(ctx, OPC_SW, rt, rs, s); 20825 break; 20826 case NM_LWC1S9: 20827 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s); 20828 break; 20829 case NM_LDC1S9: 20830 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s); 20831 break; 20832 case NM_SWC1S9: 20833 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s); 20834 break; 20835 case NM_SDC1S9: 20836 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s); 20837 break; 20838 case NM_P_PREFS9: 20839 if (rt == 31) { 20840 /* SYNCI */ 20841 /* 20842 * Break the TB to be able to sync copied instructions 20843 * immediately. 20844 */ 20845 ctx->base.is_jmp = DISAS_STOP; 20846 } else { 20847 /* PREF */ 20848 /* Treat as NOP. */ 20849 } 20850 break; 20851 default: 20852 gen_reserved_instruction(ctx); 20853 break; 20854 } 20855 break; 20856 case NM_P_LS_S1: 20857 switch (extract32(ctx->opcode, 11, 4)) { 20858 case NM_UALH: 20859 case NM_UASH: 20860 check_nms(ctx); 20861 { 20862 TCGv t0 = tcg_temp_new(); 20863 TCGv t1 = tcg_temp_new(); 20864 20865 gen_base_offset_addr(ctx, t0, rs, s); 20866 20867 switch (extract32(ctx->opcode, 11, 4)) { 20868 case NM_UALH: 20869 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 20870 MO_UNALN); 20871 gen_store_gpr(t0, rt); 20872 break; 20873 case NM_UASH: 20874 gen_load_gpr(t1, rt); 20875 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 20876 MO_UNALN); 20877 break; 20878 } 20879 tcg_temp_free(t0); 20880 tcg_temp_free(t1); 20881 } 20882 break; 20883 case NM_P_LL: 20884 switch (ctx->opcode & 0x03) { 20885 case NM_LL: 20886 gen_ld(ctx, OPC_LL, rt, rs, s); 20887 break; 20888 case NM_LLWP: 20889 check_xnp(ctx); 20890 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 20891 break; 20892 } 20893 break; 20894 case NM_P_SC: 20895 switch (ctx->opcode & 0x03) { 20896 case NM_SC: 20897 gen_st_cond(ctx, rt, rs, s, MO_TESL, false); 20898 break; 20899 case NM_SCWP: 20900 check_xnp(ctx); 20901 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 20902 false); 20903 break; 20904 } 20905 break; 20906 case NM_CACHE: 20907 check_cp0_enabled(ctx); 20908 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 20909 gen_cache_operation(ctx, rt, rs, s); 20910 } 20911 break; 20912 } 20913 break; 20914 case NM_P_LS_E0: 20915 switch (extract32(ctx->opcode, 11, 4)) { 20916 case NM_LBE: 20917 check_eva(ctx); 20918 check_cp0_enabled(ctx); 20919 gen_ld(ctx, OPC_LBE, rt, rs, s); 20920 break; 20921 case NM_SBE: 20922 check_eva(ctx); 20923 check_cp0_enabled(ctx); 20924 gen_st(ctx, OPC_SBE, rt, rs, s); 20925 break; 20926 case NM_LBUE: 20927 check_eva(ctx); 20928 check_cp0_enabled(ctx); 20929 gen_ld(ctx, OPC_LBUE, rt, rs, s); 20930 break; 20931 case NM_P_PREFE: 20932 if (rt == 31) { 20933 /* case NM_SYNCIE */ 20934 check_eva(ctx); 20935 check_cp0_enabled(ctx); 20936 /* 20937 * Break the TB to be able to sync copied instructions 20938 * immediately. 20939 */ 20940 ctx->base.is_jmp = DISAS_STOP; 20941 } else { 20942 /* case NM_PREFE */ 20943 check_eva(ctx); 20944 check_cp0_enabled(ctx); 20945 /* Treat as NOP. */ 20946 } 20947 break; 20948 case NM_LHE: 20949 check_eva(ctx); 20950 check_cp0_enabled(ctx); 20951 gen_ld(ctx, OPC_LHE, rt, rs, s); 20952 break; 20953 case NM_SHE: 20954 check_eva(ctx); 20955 check_cp0_enabled(ctx); 20956 gen_st(ctx, OPC_SHE, rt, rs, s); 20957 break; 20958 case NM_LHUE: 20959 check_eva(ctx); 20960 check_cp0_enabled(ctx); 20961 gen_ld(ctx, OPC_LHUE, rt, rs, s); 20962 break; 20963 case NM_CACHEE: 20964 check_eva(ctx); 20965 check_cp0_enabled(ctx); 20966 check_nms_dl_il_sl_tl_l2c(ctx); 20967 gen_cache_operation(ctx, rt, rs, s); 20968 break; 20969 case NM_LWE: 20970 check_eva(ctx); 20971 check_cp0_enabled(ctx); 20972 gen_ld(ctx, OPC_LWE, rt, rs, s); 20973 break; 20974 case NM_SWE: 20975 check_eva(ctx); 20976 check_cp0_enabled(ctx); 20977 gen_st(ctx, OPC_SWE, rt, rs, s); 20978 break; 20979 case NM_P_LLE: 20980 switch (extract32(ctx->opcode, 2, 2)) { 20981 case NM_LLE: 20982 check_xnp(ctx); 20983 check_eva(ctx); 20984 check_cp0_enabled(ctx); 20985 gen_ld(ctx, OPC_LLE, rt, rs, s); 20986 break; 20987 case NM_LLWPE: 20988 check_xnp(ctx); 20989 check_eva(ctx); 20990 check_cp0_enabled(ctx); 20991 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 20992 break; 20993 default: 20994 gen_reserved_instruction(ctx); 20995 break; 20996 } 20997 break; 20998 case NM_P_SCE: 20999 switch (extract32(ctx->opcode, 2, 2)) { 21000 case NM_SCE: 21001 check_xnp(ctx); 21002 check_eva(ctx); 21003 check_cp0_enabled(ctx); 21004 gen_st_cond(ctx, rt, rs, s, MO_TESL, true); 21005 break; 21006 case NM_SCWPE: 21007 check_xnp(ctx); 21008 check_eva(ctx); 21009 check_cp0_enabled(ctx); 21010 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 21011 true); 21012 break; 21013 default: 21014 gen_reserved_instruction(ctx); 21015 break; 21016 } 21017 break; 21018 } 21019 break; 21020 case NM_P_LS_WM: 21021 case NM_P_LS_UAWM: 21022 check_nms(ctx); 21023 { 21024 int count = extract32(ctx->opcode, 12, 3); 21025 int counter = 0; 21026 21027 offset = sextract32(ctx->opcode, 15, 1) << 8 | 21028 extract32(ctx->opcode, 0, 8); 21029 TCGv va = tcg_temp_new(); 21030 TCGv t1 = tcg_temp_new(); 21031 MemOp memop = (extract32(ctx->opcode, 8, 3)) == 21032 NM_P_LS_UAWM ? MO_UNALN : 0; 21033 21034 count = (count == 0) ? 8 : count; 21035 while (counter != count) { 21036 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10); 21037 int this_offset = offset + (counter << 2); 21038 21039 gen_base_offset_addr(ctx, va, rs, this_offset); 21040 21041 switch (extract32(ctx->opcode, 11, 1)) { 21042 case NM_LWM: 21043 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx, 21044 memop | MO_TESL); 21045 gen_store_gpr(t1, this_rt); 21046 if ((this_rt == rs) && 21047 (counter != (count - 1))) { 21048 /* UNPREDICTABLE */ 21049 } 21050 break; 21051 case NM_SWM: 21052 this_rt = (rt == 0) ? 0 : this_rt; 21053 gen_load_gpr(t1, this_rt); 21054 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx, 21055 memop | MO_TEUL); 21056 break; 21057 } 21058 counter++; 21059 } 21060 tcg_temp_free(va); 21061 tcg_temp_free(t1); 21062 } 21063 break; 21064 default: 21065 gen_reserved_instruction(ctx); 21066 break; 21067 } 21068 } 21069 break; 21070 case NM_MOVE_BALC: 21071 check_nms(ctx); 21072 { 21073 TCGv t0 = tcg_temp_new(); 21074 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 | 21075 extract32(ctx->opcode, 1, 20) << 1; 21076 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5; 21077 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 | 21078 extract32(ctx->opcode, 21, 3)); 21079 gen_load_gpr(t0, rt); 21080 tcg_gen_mov_tl(cpu_gpr[rd], t0); 21081 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 21082 tcg_temp_free(t0); 21083 } 21084 break; 21085 case NM_P_BAL: 21086 { 21087 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 | 21088 extract32(ctx->opcode, 1, 24) << 1; 21089 21090 if ((extract32(ctx->opcode, 25, 1)) == 0) { 21091 /* BC */ 21092 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s); 21093 } else { 21094 /* BALC */ 21095 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 21096 } 21097 } 21098 break; 21099 case NM_P_J: 21100 switch (extract32(ctx->opcode, 12, 4)) { 21101 case NM_JALRC: 21102 case NM_JALRC_HB: 21103 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0); 21104 break; 21105 case NM_P_BALRSC: 21106 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); 21107 break; 21108 default: 21109 gen_reserved_instruction(ctx); 21110 break; 21111 } 21112 break; 21113 case NM_P_BR1: 21114 { 21115 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 21116 extract32(ctx->opcode, 1, 13) << 1; 21117 switch (extract32(ctx->opcode, 14, 2)) { 21118 case NM_BEQC: 21119 check_nms(ctx); 21120 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s); 21121 break; 21122 case NM_P_BR3A: 21123 s = sextract32(ctx->opcode, 0, 1) << 14 | 21124 extract32(ctx->opcode, 1, 13) << 1; 21125 check_cp1_enabled(ctx); 21126 switch (extract32(ctx->opcode, 16, 5)) { 21127 case NM_BC1EQZC: 21128 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s); 21129 break; 21130 case NM_BC1NEZC: 21131 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); 21132 break; 21133 case NM_BPOSGE32C: 21134 check_dsp_r3(ctx); 21135 { 21136 int32_t imm = extract32(ctx->opcode, 1, 13) | 21137 extract32(ctx->opcode, 0, 1) << 13; 21138 21139 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2, 21140 imm); 21141 } 21142 break; 21143 default: 21144 gen_reserved_instruction(ctx); 21145 break; 21146 } 21147 break; 21148 case NM_BGEC: 21149 if (rs == rt) { 21150 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s); 21151 } else { 21152 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s); 21153 } 21154 break; 21155 case NM_BGEUC: 21156 if (rs == rt || rt == 0) { 21157 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s); 21158 } else if (rs == 0) { 21159 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s); 21160 } else { 21161 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s); 21162 } 21163 break; 21164 } 21165 } 21166 break; 21167 case NM_P_BR2: 21168 { 21169 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 21170 extract32(ctx->opcode, 1, 13) << 1; 21171 switch (extract32(ctx->opcode, 14, 2)) { 21172 case NM_BNEC: 21173 check_nms(ctx); 21174 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s); 21175 break; 21176 case NM_BLTC: 21177 if (rs != 0 && rt != 0 && rs == rt) { 21178 /* NOP */ 21179 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 21180 } else { 21181 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s); 21182 } 21183 break; 21184 case NM_BLTUC: 21185 if (rs == 0 || rs == rt) { 21186 /* NOP */ 21187 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 21188 } else { 21189 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s); 21190 } 21191 break; 21192 default: 21193 gen_reserved_instruction(ctx); 21194 break; 21195 } 21196 } 21197 break; 21198 case NM_P_BRI: 21199 { 21200 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 | 21201 extract32(ctx->opcode, 1, 10) << 1; 21202 uint32_t u = extract32(ctx->opcode, 11, 7); 21203 21204 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3), 21205 rt, u, s); 21206 } 21207 break; 21208 default: 21209 gen_reserved_instruction(ctx); 21210 break; 21211 } 21212 return 4; 21213 } 21214 21215 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx) 21216 { 21217 uint32_t op; 21218 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 21219 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 21220 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode)); 21221 int offset; 21222 int imm; 21223 21224 /* make sure instructions are on a halfword boundary */ 21225 if (ctx->base.pc_next & 0x1) { 21226 TCGv tmp = tcg_const_tl(ctx->base.pc_next); 21227 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 21228 tcg_temp_free(tmp); 21229 generate_exception_end(ctx, EXCP_AdEL); 21230 return 2; 21231 } 21232 21233 op = extract32(ctx->opcode, 10, 6); 21234 switch (op) { 21235 case NM_P16_MV: 21236 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 21237 if (rt != 0) { 21238 /* MOVE */ 21239 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode); 21240 gen_arith(ctx, OPC_ADDU, rt, rs, 0); 21241 } else { 21242 /* P16.RI */ 21243 switch (extract32(ctx->opcode, 3, 2)) { 21244 case NM_P16_SYSCALL: 21245 if (extract32(ctx->opcode, 2, 1) == 0) { 21246 generate_exception_end(ctx, EXCP_SYSCALL); 21247 } else { 21248 gen_reserved_instruction(ctx); 21249 } 21250 break; 21251 case NM_BREAK16: 21252 generate_exception_end(ctx, EXCP_BREAK); 21253 break; 21254 case NM_SDBBP16: 21255 if (is_uhi(extract32(ctx->opcode, 0, 3))) { 21256 gen_helper_do_semihosting(cpu_env); 21257 } else { 21258 if (ctx->hflags & MIPS_HFLAG_SBRI) { 21259 gen_reserved_instruction(ctx); 21260 } else { 21261 generate_exception_end(ctx, EXCP_DBp); 21262 } 21263 } 21264 break; 21265 default: 21266 gen_reserved_instruction(ctx); 21267 break; 21268 } 21269 } 21270 break; 21271 case NM_P16_SHIFT: 21272 { 21273 int shift = extract32(ctx->opcode, 0, 3); 21274 uint32_t opc = 0; 21275 shift = (shift == 0) ? 8 : shift; 21276 21277 switch (extract32(ctx->opcode, 3, 1)) { 21278 case NM_SLL16: 21279 opc = OPC_SLL; 21280 break; 21281 case NM_SRL16: 21282 opc = OPC_SRL; 21283 break; 21284 } 21285 gen_shift_imm(ctx, opc, rt, rs, shift); 21286 } 21287 break; 21288 case NM_P16C: 21289 switch (ctx->opcode & 1) { 21290 case NM_POOL16C_0: 21291 gen_pool16c_nanomips_insn(ctx); 21292 break; 21293 case NM_LWXS16: 21294 gen_ldxs(ctx, rt, rs, rd); 21295 break; 21296 } 21297 break; 21298 case NM_P16_A1: 21299 switch (extract32(ctx->opcode, 6, 1)) { 21300 case NM_ADDIUR1SP: 21301 imm = extract32(ctx->opcode, 0, 6) << 2; 21302 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); 21303 break; 21304 default: 21305 gen_reserved_instruction(ctx); 21306 break; 21307 } 21308 break; 21309 case NM_P16_A2: 21310 switch (extract32(ctx->opcode, 3, 1)) { 21311 case NM_ADDIUR2: 21312 imm = extract32(ctx->opcode, 0, 3) << 2; 21313 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm); 21314 break; 21315 case NM_P_ADDIURS5: 21316 rt = extract32(ctx->opcode, 5, 5); 21317 if (rt != 0) { 21318 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */ 21319 imm = (sextract32(ctx->opcode, 4, 1) << 3) | 21320 (extract32(ctx->opcode, 0, 3)); 21321 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm); 21322 } 21323 break; 21324 } 21325 break; 21326 case NM_P16_ADDU: 21327 switch (ctx->opcode & 0x1) { 21328 case NM_ADDU16: 21329 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 21330 break; 21331 case NM_SUBU16: 21332 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 21333 break; 21334 } 21335 break; 21336 case NM_P16_4X4: 21337 rt = (extract32(ctx->opcode, 9, 1) << 3) | 21338 extract32(ctx->opcode, 5, 3); 21339 rs = (extract32(ctx->opcode, 4, 1) << 3) | 21340 extract32(ctx->opcode, 0, 3); 21341 rt = decode_gpr_gpr4(rt); 21342 rs = decode_gpr_gpr4(rs); 21343 switch ((extract32(ctx->opcode, 7, 2) & 0x2) | 21344 (extract32(ctx->opcode, 3, 1))) { 21345 case NM_ADDU4X4: 21346 check_nms(ctx); 21347 gen_arith(ctx, OPC_ADDU, rt, rs, rt); 21348 break; 21349 case NM_MUL4X4: 21350 check_nms(ctx); 21351 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); 21352 break; 21353 default: 21354 gen_reserved_instruction(ctx); 21355 break; 21356 } 21357 break; 21358 case NM_LI16: 21359 { 21360 int imm = extract32(ctx->opcode, 0, 7); 21361 imm = (imm == 0x7f ? -1 : imm); 21362 if (rt != 0) { 21363 tcg_gen_movi_tl(cpu_gpr[rt], imm); 21364 } 21365 } 21366 break; 21367 case NM_ANDI16: 21368 { 21369 uint32_t u = extract32(ctx->opcode, 0, 4); 21370 u = (u == 12) ? 0xff : 21371 (u == 13) ? 0xffff : u; 21372 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u); 21373 } 21374 break; 21375 case NM_P16_LB: 21376 offset = extract32(ctx->opcode, 0, 2); 21377 switch (extract32(ctx->opcode, 2, 2)) { 21378 case NM_LB16: 21379 gen_ld(ctx, OPC_LB, rt, rs, offset); 21380 break; 21381 case NM_SB16: 21382 rt = decode_gpr_gpr3_src_store( 21383 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 21384 gen_st(ctx, OPC_SB, rt, rs, offset); 21385 break; 21386 case NM_LBU16: 21387 gen_ld(ctx, OPC_LBU, rt, rs, offset); 21388 break; 21389 default: 21390 gen_reserved_instruction(ctx); 21391 break; 21392 } 21393 break; 21394 case NM_P16_LH: 21395 offset = extract32(ctx->opcode, 1, 2) << 1; 21396 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) { 21397 case NM_LH16: 21398 gen_ld(ctx, OPC_LH, rt, rs, offset); 21399 break; 21400 case NM_SH16: 21401 rt = decode_gpr_gpr3_src_store( 21402 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 21403 gen_st(ctx, OPC_SH, rt, rs, offset); 21404 break; 21405 case NM_LHU16: 21406 gen_ld(ctx, OPC_LHU, rt, rs, offset); 21407 break; 21408 default: 21409 gen_reserved_instruction(ctx); 21410 break; 21411 } 21412 break; 21413 case NM_LW16: 21414 offset = extract32(ctx->opcode, 0, 4) << 2; 21415 gen_ld(ctx, OPC_LW, rt, rs, offset); 21416 break; 21417 case NM_LWSP16: 21418 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 21419 offset = extract32(ctx->opcode, 0, 5) << 2; 21420 gen_ld(ctx, OPC_LW, rt, 29, offset); 21421 break; 21422 case NM_LW4X4: 21423 check_nms(ctx); 21424 rt = (extract32(ctx->opcode, 9, 1) << 3) | 21425 extract32(ctx->opcode, 5, 3); 21426 rs = (extract32(ctx->opcode, 4, 1) << 3) | 21427 extract32(ctx->opcode, 0, 3); 21428 offset = (extract32(ctx->opcode, 3, 1) << 3) | 21429 (extract32(ctx->opcode, 8, 1) << 2); 21430 rt = decode_gpr_gpr4(rt); 21431 rs = decode_gpr_gpr4(rs); 21432 gen_ld(ctx, OPC_LW, rt, rs, offset); 21433 break; 21434 case NM_SW4X4: 21435 check_nms(ctx); 21436 rt = (extract32(ctx->opcode, 9, 1) << 3) | 21437 extract32(ctx->opcode, 5, 3); 21438 rs = (extract32(ctx->opcode, 4, 1) << 3) | 21439 extract32(ctx->opcode, 0, 3); 21440 offset = (extract32(ctx->opcode, 3, 1) << 3) | 21441 (extract32(ctx->opcode, 8, 1) << 2); 21442 rt = decode_gpr_gpr4_zero(rt); 21443 rs = decode_gpr_gpr4(rs); 21444 gen_st(ctx, OPC_SW, rt, rs, offset); 21445 break; 21446 case NM_LWGP16: 21447 offset = extract32(ctx->opcode, 0, 7) << 2; 21448 gen_ld(ctx, OPC_LW, rt, 28, offset); 21449 break; 21450 case NM_SWSP16: 21451 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 21452 offset = extract32(ctx->opcode, 0, 5) << 2; 21453 gen_st(ctx, OPC_SW, rt, 29, offset); 21454 break; 21455 case NM_SW16: 21456 rt = decode_gpr_gpr3_src_store( 21457 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 21458 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 21459 offset = extract32(ctx->opcode, 0, 4) << 2; 21460 gen_st(ctx, OPC_SW, rt, rs, offset); 21461 break; 21462 case NM_SWGP16: 21463 rt = decode_gpr_gpr3_src_store( 21464 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 21465 offset = extract32(ctx->opcode, 0, 7) << 2; 21466 gen_st(ctx, OPC_SW, rt, 28, offset); 21467 break; 21468 case NM_BC16: 21469 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0, 21470 (sextract32(ctx->opcode, 0, 1) << 10) | 21471 (extract32(ctx->opcode, 1, 9) << 1)); 21472 break; 21473 case NM_BALC16: 21474 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0, 21475 (sextract32(ctx->opcode, 0, 1) << 10) | 21476 (extract32(ctx->opcode, 1, 9) << 1)); 21477 break; 21478 case NM_BEQZC16: 21479 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0, 21480 (sextract32(ctx->opcode, 0, 1) << 7) | 21481 (extract32(ctx->opcode, 1, 6) << 1)); 21482 break; 21483 case NM_BNEZC16: 21484 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0, 21485 (sextract32(ctx->opcode, 0, 1) << 7) | 21486 (extract32(ctx->opcode, 1, 6) << 1)); 21487 break; 21488 case NM_P16_BR: 21489 switch (ctx->opcode & 0xf) { 21490 case 0: 21491 /* P16.JRC */ 21492 switch (extract32(ctx->opcode, 4, 1)) { 21493 case NM_JRC: 21494 gen_compute_branch_nm(ctx, OPC_JR, 2, 21495 extract32(ctx->opcode, 5, 5), 0, 0); 21496 break; 21497 case NM_JALRC16: 21498 gen_compute_branch_nm(ctx, OPC_JALR, 2, 21499 extract32(ctx->opcode, 5, 5), 31, 0); 21500 break; 21501 } 21502 break; 21503 default: 21504 { 21505 /* P16.BRI */ 21506 uint32_t opc = extract32(ctx->opcode, 4, 3) < 21507 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE; 21508 gen_compute_branch_nm(ctx, opc, 2, rs, rt, 21509 extract32(ctx->opcode, 0, 4) << 1); 21510 } 21511 break; 21512 } 21513 break; 21514 case NM_P16_SR: 21515 { 21516 int count = extract32(ctx->opcode, 0, 4); 21517 int u = extract32(ctx->opcode, 4, 4) << 4; 21518 21519 rt = 30 + extract32(ctx->opcode, 9, 1); 21520 switch (extract32(ctx->opcode, 8, 1)) { 21521 case NM_SAVE16: 21522 gen_save(ctx, rt, count, 0, u); 21523 break; 21524 case NM_RESTORE_JRC16: 21525 gen_restore(ctx, rt, count, 0, u); 21526 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 21527 break; 21528 } 21529 } 21530 break; 21531 case NM_MOVEP: 21532 case NM_MOVEPREV: 21533 check_nms(ctx); 21534 { 21535 static const int gpr2reg1[] = {4, 5, 6, 7}; 21536 static const int gpr2reg2[] = {5, 6, 7, 8}; 21537 int re; 21538 int rd2 = extract32(ctx->opcode, 3, 1) << 1 | 21539 extract32(ctx->opcode, 8, 1); 21540 int r1 = gpr2reg1[rd2]; 21541 int r2 = gpr2reg2[rd2]; 21542 int r3 = extract32(ctx->opcode, 4, 1) << 3 | 21543 extract32(ctx->opcode, 0, 3); 21544 int r4 = extract32(ctx->opcode, 9, 1) << 3 | 21545 extract32(ctx->opcode, 5, 3); 21546 TCGv t0 = tcg_temp_new(); 21547 TCGv t1 = tcg_temp_new(); 21548 if (op == NM_MOVEP) { 21549 rd = r1; 21550 re = r2; 21551 rs = decode_gpr_gpr4_zero(r3); 21552 rt = decode_gpr_gpr4_zero(r4); 21553 } else { 21554 rd = decode_gpr_gpr4(r3); 21555 re = decode_gpr_gpr4(r4); 21556 rs = r1; 21557 rt = r2; 21558 } 21559 gen_load_gpr(t0, rs); 21560 gen_load_gpr(t1, rt); 21561 tcg_gen_mov_tl(cpu_gpr[rd], t0); 21562 tcg_gen_mov_tl(cpu_gpr[re], t1); 21563 tcg_temp_free(t0); 21564 tcg_temp_free(t1); 21565 } 21566 break; 21567 default: 21568 return decode_nanomips_32_48_opc(env, ctx); 21569 } 21570 21571 return 2; 21572 } 21573 21574 21575 /* SmartMIPS extension to MIPS32 */ 21576 21577 #if defined(TARGET_MIPS64) 21578 21579 /* MDMX extension to MIPS64 */ 21580 21581 #endif 21582 21583 /* MIPSDSP functions. */ 21584 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, 21585 int rd, int base, int offset) 21586 { 21587 TCGv t0; 21588 21589 check_dsp(ctx); 21590 t0 = tcg_temp_new(); 21591 21592 if (base == 0) { 21593 gen_load_gpr(t0, offset); 21594 } else if (offset == 0) { 21595 gen_load_gpr(t0, base); 21596 } else { 21597 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 21598 } 21599 21600 switch (opc) { 21601 case OPC_LBUX: 21602 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 21603 gen_store_gpr(t0, rd); 21604 break; 21605 case OPC_LHX: 21606 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 21607 gen_store_gpr(t0, rd); 21608 break; 21609 case OPC_LWX: 21610 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 21611 gen_store_gpr(t0, rd); 21612 break; 21613 #if defined(TARGET_MIPS64) 21614 case OPC_LDX: 21615 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 21616 gen_store_gpr(t0, rd); 21617 break; 21618 #endif 21619 } 21620 tcg_temp_free(t0); 21621 } 21622 21623 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 21624 int ret, int v1, int v2) 21625 { 21626 TCGv v1_t; 21627 TCGv v2_t; 21628 21629 if (ret == 0) { 21630 /* Treat as NOP. */ 21631 return; 21632 } 21633 21634 v1_t = tcg_temp_new(); 21635 v2_t = tcg_temp_new(); 21636 21637 gen_load_gpr(v1_t, v1); 21638 gen_load_gpr(v2_t, v2); 21639 21640 switch (op1) { 21641 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 21642 case OPC_MULT_G_2E: 21643 check_dsp_r2(ctx); 21644 switch (op2) { 21645 case OPC_ADDUH_QB: 21646 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 21647 break; 21648 case OPC_ADDUH_R_QB: 21649 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 21650 break; 21651 case OPC_ADDQH_PH: 21652 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 21653 break; 21654 case OPC_ADDQH_R_PH: 21655 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 21656 break; 21657 case OPC_ADDQH_W: 21658 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 21659 break; 21660 case OPC_ADDQH_R_W: 21661 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 21662 break; 21663 case OPC_SUBUH_QB: 21664 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 21665 break; 21666 case OPC_SUBUH_R_QB: 21667 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 21668 break; 21669 case OPC_SUBQH_PH: 21670 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 21671 break; 21672 case OPC_SUBQH_R_PH: 21673 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 21674 break; 21675 case OPC_SUBQH_W: 21676 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 21677 break; 21678 case OPC_SUBQH_R_W: 21679 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 21680 break; 21681 } 21682 break; 21683 case OPC_ABSQ_S_PH_DSP: 21684 switch (op2) { 21685 case OPC_ABSQ_S_QB: 21686 check_dsp_r2(ctx); 21687 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 21688 break; 21689 case OPC_ABSQ_S_PH: 21690 check_dsp(ctx); 21691 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 21692 break; 21693 case OPC_ABSQ_S_W: 21694 check_dsp(ctx); 21695 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 21696 break; 21697 case OPC_PRECEQ_W_PHL: 21698 check_dsp(ctx); 21699 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 21700 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 21701 break; 21702 case OPC_PRECEQ_W_PHR: 21703 check_dsp(ctx); 21704 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 21705 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 21706 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 21707 break; 21708 case OPC_PRECEQU_PH_QBL: 21709 check_dsp(ctx); 21710 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 21711 break; 21712 case OPC_PRECEQU_PH_QBR: 21713 check_dsp(ctx); 21714 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 21715 break; 21716 case OPC_PRECEQU_PH_QBLA: 21717 check_dsp(ctx); 21718 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 21719 break; 21720 case OPC_PRECEQU_PH_QBRA: 21721 check_dsp(ctx); 21722 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 21723 break; 21724 case OPC_PRECEU_PH_QBL: 21725 check_dsp(ctx); 21726 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 21727 break; 21728 case OPC_PRECEU_PH_QBR: 21729 check_dsp(ctx); 21730 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 21731 break; 21732 case OPC_PRECEU_PH_QBLA: 21733 check_dsp(ctx); 21734 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 21735 break; 21736 case OPC_PRECEU_PH_QBRA: 21737 check_dsp(ctx); 21738 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 21739 break; 21740 } 21741 break; 21742 case OPC_ADDU_QB_DSP: 21743 switch (op2) { 21744 case OPC_ADDQ_PH: 21745 check_dsp(ctx); 21746 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21747 break; 21748 case OPC_ADDQ_S_PH: 21749 check_dsp(ctx); 21750 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21751 break; 21752 case OPC_ADDQ_S_W: 21753 check_dsp(ctx); 21754 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21755 break; 21756 case OPC_ADDU_QB: 21757 check_dsp(ctx); 21758 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21759 break; 21760 case OPC_ADDU_S_QB: 21761 check_dsp(ctx); 21762 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21763 break; 21764 case OPC_ADDU_PH: 21765 check_dsp_r2(ctx); 21766 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21767 break; 21768 case OPC_ADDU_S_PH: 21769 check_dsp_r2(ctx); 21770 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21771 break; 21772 case OPC_SUBQ_PH: 21773 check_dsp(ctx); 21774 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21775 break; 21776 case OPC_SUBQ_S_PH: 21777 check_dsp(ctx); 21778 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21779 break; 21780 case OPC_SUBQ_S_W: 21781 check_dsp(ctx); 21782 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21783 break; 21784 case OPC_SUBU_QB: 21785 check_dsp(ctx); 21786 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21787 break; 21788 case OPC_SUBU_S_QB: 21789 check_dsp(ctx); 21790 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21791 break; 21792 case OPC_SUBU_PH: 21793 check_dsp_r2(ctx); 21794 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21795 break; 21796 case OPC_SUBU_S_PH: 21797 check_dsp_r2(ctx); 21798 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21799 break; 21800 case OPC_ADDSC: 21801 check_dsp(ctx); 21802 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21803 break; 21804 case OPC_ADDWC: 21805 check_dsp(ctx); 21806 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21807 break; 21808 case OPC_MODSUB: 21809 check_dsp(ctx); 21810 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 21811 break; 21812 case OPC_RADDU_W_QB: 21813 check_dsp(ctx); 21814 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 21815 break; 21816 } 21817 break; 21818 case OPC_CMPU_EQ_QB_DSP: 21819 switch (op2) { 21820 case OPC_PRECR_QB_PH: 21821 check_dsp_r2(ctx); 21822 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 21823 break; 21824 case OPC_PRECRQ_QB_PH: 21825 check_dsp(ctx); 21826 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 21827 break; 21828 case OPC_PRECR_SRA_PH_W: 21829 check_dsp_r2(ctx); 21830 { 21831 TCGv_i32 sa_t = tcg_const_i32(v2); 21832 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 21833 cpu_gpr[ret]); 21834 tcg_temp_free_i32(sa_t); 21835 break; 21836 } 21837 case OPC_PRECR_SRA_R_PH_W: 21838 check_dsp_r2(ctx); 21839 { 21840 TCGv_i32 sa_t = tcg_const_i32(v2); 21841 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 21842 cpu_gpr[ret]); 21843 tcg_temp_free_i32(sa_t); 21844 break; 21845 } 21846 case OPC_PRECRQ_PH_W: 21847 check_dsp(ctx); 21848 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 21849 break; 21850 case OPC_PRECRQ_RS_PH_W: 21851 check_dsp(ctx); 21852 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21853 break; 21854 case OPC_PRECRQU_S_QB_PH: 21855 check_dsp(ctx); 21856 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21857 break; 21858 } 21859 break; 21860 #ifdef TARGET_MIPS64 21861 case OPC_ABSQ_S_QH_DSP: 21862 switch (op2) { 21863 case OPC_PRECEQ_L_PWL: 21864 check_dsp(ctx); 21865 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 21866 break; 21867 case OPC_PRECEQ_L_PWR: 21868 check_dsp(ctx); 21869 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 21870 break; 21871 case OPC_PRECEQ_PW_QHL: 21872 check_dsp(ctx); 21873 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 21874 break; 21875 case OPC_PRECEQ_PW_QHR: 21876 check_dsp(ctx); 21877 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 21878 break; 21879 case OPC_PRECEQ_PW_QHLA: 21880 check_dsp(ctx); 21881 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 21882 break; 21883 case OPC_PRECEQ_PW_QHRA: 21884 check_dsp(ctx); 21885 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 21886 break; 21887 case OPC_PRECEQU_QH_OBL: 21888 check_dsp(ctx); 21889 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 21890 break; 21891 case OPC_PRECEQU_QH_OBR: 21892 check_dsp(ctx); 21893 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 21894 break; 21895 case OPC_PRECEQU_QH_OBLA: 21896 check_dsp(ctx); 21897 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 21898 break; 21899 case OPC_PRECEQU_QH_OBRA: 21900 check_dsp(ctx); 21901 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 21902 break; 21903 case OPC_PRECEU_QH_OBL: 21904 check_dsp(ctx); 21905 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 21906 break; 21907 case OPC_PRECEU_QH_OBR: 21908 check_dsp(ctx); 21909 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 21910 break; 21911 case OPC_PRECEU_QH_OBLA: 21912 check_dsp(ctx); 21913 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 21914 break; 21915 case OPC_PRECEU_QH_OBRA: 21916 check_dsp(ctx); 21917 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 21918 break; 21919 case OPC_ABSQ_S_OB: 21920 check_dsp_r2(ctx); 21921 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 21922 break; 21923 case OPC_ABSQ_S_PW: 21924 check_dsp(ctx); 21925 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 21926 break; 21927 case OPC_ABSQ_S_QH: 21928 check_dsp(ctx); 21929 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 21930 break; 21931 } 21932 break; 21933 case OPC_ADDU_OB_DSP: 21934 switch (op2) { 21935 case OPC_RADDU_L_OB: 21936 check_dsp(ctx); 21937 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 21938 break; 21939 case OPC_SUBQ_PW: 21940 check_dsp(ctx); 21941 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21942 break; 21943 case OPC_SUBQ_S_PW: 21944 check_dsp(ctx); 21945 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21946 break; 21947 case OPC_SUBQ_QH: 21948 check_dsp(ctx); 21949 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21950 break; 21951 case OPC_SUBQ_S_QH: 21952 check_dsp(ctx); 21953 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21954 break; 21955 case OPC_SUBU_OB: 21956 check_dsp(ctx); 21957 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21958 break; 21959 case OPC_SUBU_S_OB: 21960 check_dsp(ctx); 21961 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21962 break; 21963 case OPC_SUBU_QH: 21964 check_dsp_r2(ctx); 21965 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21966 break; 21967 case OPC_SUBU_S_QH: 21968 check_dsp_r2(ctx); 21969 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21970 break; 21971 case OPC_SUBUH_OB: 21972 check_dsp_r2(ctx); 21973 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 21974 break; 21975 case OPC_SUBUH_R_OB: 21976 check_dsp_r2(ctx); 21977 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 21978 break; 21979 case OPC_ADDQ_PW: 21980 check_dsp(ctx); 21981 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21982 break; 21983 case OPC_ADDQ_S_PW: 21984 check_dsp(ctx); 21985 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21986 break; 21987 case OPC_ADDQ_QH: 21988 check_dsp(ctx); 21989 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21990 break; 21991 case OPC_ADDQ_S_QH: 21992 check_dsp(ctx); 21993 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21994 break; 21995 case OPC_ADDU_OB: 21996 check_dsp(ctx); 21997 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 21998 break; 21999 case OPC_ADDU_S_OB: 22000 check_dsp(ctx); 22001 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22002 break; 22003 case OPC_ADDU_QH: 22004 check_dsp_r2(ctx); 22005 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22006 break; 22007 case OPC_ADDU_S_QH: 22008 check_dsp_r2(ctx); 22009 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22010 break; 22011 case OPC_ADDUH_OB: 22012 check_dsp_r2(ctx); 22013 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 22014 break; 22015 case OPC_ADDUH_R_OB: 22016 check_dsp_r2(ctx); 22017 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 22018 break; 22019 } 22020 break; 22021 case OPC_CMPU_EQ_OB_DSP: 22022 switch (op2) { 22023 case OPC_PRECR_OB_QH: 22024 check_dsp_r2(ctx); 22025 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 22026 break; 22027 case OPC_PRECR_SRA_QH_PW: 22028 check_dsp_r2(ctx); 22029 { 22030 TCGv_i32 ret_t = tcg_const_i32(ret); 22031 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 22032 tcg_temp_free_i32(ret_t); 22033 break; 22034 } 22035 case OPC_PRECR_SRA_R_QH_PW: 22036 check_dsp_r2(ctx); 22037 { 22038 TCGv_i32 sa_v = tcg_const_i32(ret); 22039 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 22040 tcg_temp_free_i32(sa_v); 22041 break; 22042 } 22043 case OPC_PRECRQ_OB_QH: 22044 check_dsp(ctx); 22045 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 22046 break; 22047 case OPC_PRECRQ_PW_L: 22048 check_dsp(ctx); 22049 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 22050 break; 22051 case OPC_PRECRQ_QH_PW: 22052 check_dsp(ctx); 22053 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 22054 break; 22055 case OPC_PRECRQ_RS_QH_PW: 22056 check_dsp(ctx); 22057 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22058 break; 22059 case OPC_PRECRQU_S_OB_QH: 22060 check_dsp(ctx); 22061 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22062 break; 22063 } 22064 break; 22065 #endif 22066 } 22067 22068 tcg_temp_free(v1_t); 22069 tcg_temp_free(v2_t); 22070 } 22071 22072 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 22073 int ret, int v1, int v2) 22074 { 22075 uint32_t op2; 22076 TCGv t0; 22077 TCGv v1_t; 22078 TCGv v2_t; 22079 22080 if (ret == 0) { 22081 /* Treat as NOP. */ 22082 return; 22083 } 22084 22085 t0 = tcg_temp_new(); 22086 v1_t = tcg_temp_new(); 22087 v2_t = tcg_temp_new(); 22088 22089 tcg_gen_movi_tl(t0, v1); 22090 gen_load_gpr(v1_t, v1); 22091 gen_load_gpr(v2_t, v2); 22092 22093 switch (opc) { 22094 case OPC_SHLL_QB_DSP: 22095 { 22096 op2 = MASK_SHLL_QB(ctx->opcode); 22097 switch (op2) { 22098 case OPC_SHLL_QB: 22099 check_dsp(ctx); 22100 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 22101 break; 22102 case OPC_SHLLV_QB: 22103 check_dsp(ctx); 22104 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22105 break; 22106 case OPC_SHLL_PH: 22107 check_dsp(ctx); 22108 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 22109 break; 22110 case OPC_SHLLV_PH: 22111 check_dsp(ctx); 22112 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22113 break; 22114 case OPC_SHLL_S_PH: 22115 check_dsp(ctx); 22116 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 22117 break; 22118 case OPC_SHLLV_S_PH: 22119 check_dsp(ctx); 22120 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22121 break; 22122 case OPC_SHLL_S_W: 22123 check_dsp(ctx); 22124 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 22125 break; 22126 case OPC_SHLLV_S_W: 22127 check_dsp(ctx); 22128 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22129 break; 22130 case OPC_SHRL_QB: 22131 check_dsp(ctx); 22132 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 22133 break; 22134 case OPC_SHRLV_QB: 22135 check_dsp(ctx); 22136 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 22137 break; 22138 case OPC_SHRL_PH: 22139 check_dsp_r2(ctx); 22140 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 22141 break; 22142 case OPC_SHRLV_PH: 22143 check_dsp_r2(ctx); 22144 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 22145 break; 22146 case OPC_SHRA_QB: 22147 check_dsp_r2(ctx); 22148 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 22149 break; 22150 case OPC_SHRA_R_QB: 22151 check_dsp_r2(ctx); 22152 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 22153 break; 22154 case OPC_SHRAV_QB: 22155 check_dsp_r2(ctx); 22156 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 22157 break; 22158 case OPC_SHRAV_R_QB: 22159 check_dsp_r2(ctx); 22160 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 22161 break; 22162 case OPC_SHRA_PH: 22163 check_dsp(ctx); 22164 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 22165 break; 22166 case OPC_SHRA_R_PH: 22167 check_dsp(ctx); 22168 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 22169 break; 22170 case OPC_SHRAV_PH: 22171 check_dsp(ctx); 22172 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 22173 break; 22174 case OPC_SHRAV_R_PH: 22175 check_dsp(ctx); 22176 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 22177 break; 22178 case OPC_SHRA_R_W: 22179 check_dsp(ctx); 22180 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 22181 break; 22182 case OPC_SHRAV_R_W: 22183 check_dsp(ctx); 22184 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 22185 break; 22186 default: /* Invalid */ 22187 MIPS_INVAL("MASK SHLL.QB"); 22188 gen_reserved_instruction(ctx); 22189 break; 22190 } 22191 break; 22192 } 22193 #ifdef TARGET_MIPS64 22194 case OPC_SHLL_OB_DSP: 22195 op2 = MASK_SHLL_OB(ctx->opcode); 22196 switch (op2) { 22197 case OPC_SHLL_PW: 22198 check_dsp(ctx); 22199 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 22200 break; 22201 case OPC_SHLLV_PW: 22202 check_dsp(ctx); 22203 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 22204 break; 22205 case OPC_SHLL_S_PW: 22206 check_dsp(ctx); 22207 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 22208 break; 22209 case OPC_SHLLV_S_PW: 22210 check_dsp(ctx); 22211 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 22212 break; 22213 case OPC_SHLL_OB: 22214 check_dsp(ctx); 22215 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 22216 break; 22217 case OPC_SHLLV_OB: 22218 check_dsp(ctx); 22219 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 22220 break; 22221 case OPC_SHLL_QH: 22222 check_dsp(ctx); 22223 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 22224 break; 22225 case OPC_SHLLV_QH: 22226 check_dsp(ctx); 22227 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 22228 break; 22229 case OPC_SHLL_S_QH: 22230 check_dsp(ctx); 22231 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 22232 break; 22233 case OPC_SHLLV_S_QH: 22234 check_dsp(ctx); 22235 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 22236 break; 22237 case OPC_SHRA_OB: 22238 check_dsp_r2(ctx); 22239 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 22240 break; 22241 case OPC_SHRAV_OB: 22242 check_dsp_r2(ctx); 22243 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 22244 break; 22245 case OPC_SHRA_R_OB: 22246 check_dsp_r2(ctx); 22247 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 22248 break; 22249 case OPC_SHRAV_R_OB: 22250 check_dsp_r2(ctx); 22251 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 22252 break; 22253 case OPC_SHRA_PW: 22254 check_dsp(ctx); 22255 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 22256 break; 22257 case OPC_SHRAV_PW: 22258 check_dsp(ctx); 22259 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 22260 break; 22261 case OPC_SHRA_R_PW: 22262 check_dsp(ctx); 22263 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 22264 break; 22265 case OPC_SHRAV_R_PW: 22266 check_dsp(ctx); 22267 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 22268 break; 22269 case OPC_SHRA_QH: 22270 check_dsp(ctx); 22271 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 22272 break; 22273 case OPC_SHRAV_QH: 22274 check_dsp(ctx); 22275 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 22276 break; 22277 case OPC_SHRA_R_QH: 22278 check_dsp(ctx); 22279 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 22280 break; 22281 case OPC_SHRAV_R_QH: 22282 check_dsp(ctx); 22283 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 22284 break; 22285 case OPC_SHRL_OB: 22286 check_dsp(ctx); 22287 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 22288 break; 22289 case OPC_SHRLV_OB: 22290 check_dsp(ctx); 22291 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 22292 break; 22293 case OPC_SHRL_QH: 22294 check_dsp_r2(ctx); 22295 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 22296 break; 22297 case OPC_SHRLV_QH: 22298 check_dsp_r2(ctx); 22299 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 22300 break; 22301 default: /* Invalid */ 22302 MIPS_INVAL("MASK SHLL.OB"); 22303 gen_reserved_instruction(ctx); 22304 break; 22305 } 22306 break; 22307 #endif 22308 } 22309 22310 tcg_temp_free(t0); 22311 tcg_temp_free(v1_t); 22312 tcg_temp_free(v2_t); 22313 } 22314 22315 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 22316 int ret, int v1, int v2, int check_ret) 22317 { 22318 TCGv_i32 t0; 22319 TCGv v1_t; 22320 TCGv v2_t; 22321 22322 if ((ret == 0) && (check_ret == 1)) { 22323 /* Treat as NOP. */ 22324 return; 22325 } 22326 22327 t0 = tcg_temp_new_i32(); 22328 v1_t = tcg_temp_new(); 22329 v2_t = tcg_temp_new(); 22330 22331 tcg_gen_movi_i32(t0, ret); 22332 gen_load_gpr(v1_t, v1); 22333 gen_load_gpr(v2_t, v2); 22334 22335 switch (op1) { 22336 /* 22337 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 22338 * the same mask and op1. 22339 */ 22340 case OPC_MULT_G_2E: 22341 check_dsp_r2(ctx); 22342 switch (op2) { 22343 case OPC_MUL_PH: 22344 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22345 break; 22346 case OPC_MUL_S_PH: 22347 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22348 break; 22349 case OPC_MULQ_S_W: 22350 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22351 break; 22352 case OPC_MULQ_RS_W: 22353 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22354 break; 22355 } 22356 break; 22357 case OPC_DPA_W_PH_DSP: 22358 switch (op2) { 22359 case OPC_DPAU_H_QBL: 22360 check_dsp(ctx); 22361 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 22362 break; 22363 case OPC_DPAU_H_QBR: 22364 check_dsp(ctx); 22365 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 22366 break; 22367 case OPC_DPSU_H_QBL: 22368 check_dsp(ctx); 22369 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 22370 break; 22371 case OPC_DPSU_H_QBR: 22372 check_dsp(ctx); 22373 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 22374 break; 22375 case OPC_DPA_W_PH: 22376 check_dsp_r2(ctx); 22377 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 22378 break; 22379 case OPC_DPAX_W_PH: 22380 check_dsp_r2(ctx); 22381 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 22382 break; 22383 case OPC_DPAQ_S_W_PH: 22384 check_dsp(ctx); 22385 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 22386 break; 22387 case OPC_DPAQX_S_W_PH: 22388 check_dsp_r2(ctx); 22389 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 22390 break; 22391 case OPC_DPAQX_SA_W_PH: 22392 check_dsp_r2(ctx); 22393 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 22394 break; 22395 case OPC_DPS_W_PH: 22396 check_dsp_r2(ctx); 22397 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 22398 break; 22399 case OPC_DPSX_W_PH: 22400 check_dsp_r2(ctx); 22401 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 22402 break; 22403 case OPC_DPSQ_S_W_PH: 22404 check_dsp(ctx); 22405 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 22406 break; 22407 case OPC_DPSQX_S_W_PH: 22408 check_dsp_r2(ctx); 22409 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 22410 break; 22411 case OPC_DPSQX_SA_W_PH: 22412 check_dsp_r2(ctx); 22413 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 22414 break; 22415 case OPC_MULSAQ_S_W_PH: 22416 check_dsp(ctx); 22417 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 22418 break; 22419 case OPC_DPAQ_SA_L_W: 22420 check_dsp(ctx); 22421 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 22422 break; 22423 case OPC_DPSQ_SA_L_W: 22424 check_dsp(ctx); 22425 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 22426 break; 22427 case OPC_MAQ_S_W_PHL: 22428 check_dsp(ctx); 22429 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 22430 break; 22431 case OPC_MAQ_S_W_PHR: 22432 check_dsp(ctx); 22433 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 22434 break; 22435 case OPC_MAQ_SA_W_PHL: 22436 check_dsp(ctx); 22437 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 22438 break; 22439 case OPC_MAQ_SA_W_PHR: 22440 check_dsp(ctx); 22441 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 22442 break; 22443 case OPC_MULSA_W_PH: 22444 check_dsp_r2(ctx); 22445 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 22446 break; 22447 } 22448 break; 22449 #ifdef TARGET_MIPS64 22450 case OPC_DPAQ_W_QH_DSP: 22451 { 22452 int ac = ret & 0x03; 22453 tcg_gen_movi_i32(t0, ac); 22454 22455 switch (op2) { 22456 case OPC_DMADD: 22457 check_dsp(ctx); 22458 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 22459 break; 22460 case OPC_DMADDU: 22461 check_dsp(ctx); 22462 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 22463 break; 22464 case OPC_DMSUB: 22465 check_dsp(ctx); 22466 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 22467 break; 22468 case OPC_DMSUBU: 22469 check_dsp(ctx); 22470 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 22471 break; 22472 case OPC_DPA_W_QH: 22473 check_dsp_r2(ctx); 22474 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 22475 break; 22476 case OPC_DPAQ_S_W_QH: 22477 check_dsp(ctx); 22478 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 22479 break; 22480 case OPC_DPAQ_SA_L_PW: 22481 check_dsp(ctx); 22482 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 22483 break; 22484 case OPC_DPAU_H_OBL: 22485 check_dsp(ctx); 22486 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 22487 break; 22488 case OPC_DPAU_H_OBR: 22489 check_dsp(ctx); 22490 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 22491 break; 22492 case OPC_DPS_W_QH: 22493 check_dsp_r2(ctx); 22494 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 22495 break; 22496 case OPC_DPSQ_S_W_QH: 22497 check_dsp(ctx); 22498 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 22499 break; 22500 case OPC_DPSQ_SA_L_PW: 22501 check_dsp(ctx); 22502 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 22503 break; 22504 case OPC_DPSU_H_OBL: 22505 check_dsp(ctx); 22506 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 22507 break; 22508 case OPC_DPSU_H_OBR: 22509 check_dsp(ctx); 22510 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 22511 break; 22512 case OPC_MAQ_S_L_PWL: 22513 check_dsp(ctx); 22514 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 22515 break; 22516 case OPC_MAQ_S_L_PWR: 22517 check_dsp(ctx); 22518 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 22519 break; 22520 case OPC_MAQ_S_W_QHLL: 22521 check_dsp(ctx); 22522 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 22523 break; 22524 case OPC_MAQ_SA_W_QHLL: 22525 check_dsp(ctx); 22526 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 22527 break; 22528 case OPC_MAQ_S_W_QHLR: 22529 check_dsp(ctx); 22530 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 22531 break; 22532 case OPC_MAQ_SA_W_QHLR: 22533 check_dsp(ctx); 22534 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 22535 break; 22536 case OPC_MAQ_S_W_QHRL: 22537 check_dsp(ctx); 22538 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 22539 break; 22540 case OPC_MAQ_SA_W_QHRL: 22541 check_dsp(ctx); 22542 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 22543 break; 22544 case OPC_MAQ_S_W_QHRR: 22545 check_dsp(ctx); 22546 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 22547 break; 22548 case OPC_MAQ_SA_W_QHRR: 22549 check_dsp(ctx); 22550 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 22551 break; 22552 case OPC_MULSAQ_S_L_PW: 22553 check_dsp(ctx); 22554 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 22555 break; 22556 case OPC_MULSAQ_S_W_QH: 22557 check_dsp(ctx); 22558 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 22559 break; 22560 } 22561 } 22562 break; 22563 #endif 22564 case OPC_ADDU_QB_DSP: 22565 switch (op2) { 22566 case OPC_MULEU_S_PH_QBL: 22567 check_dsp(ctx); 22568 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22569 break; 22570 case OPC_MULEU_S_PH_QBR: 22571 check_dsp(ctx); 22572 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22573 break; 22574 case OPC_MULQ_RS_PH: 22575 check_dsp(ctx); 22576 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22577 break; 22578 case OPC_MULEQ_S_W_PHL: 22579 check_dsp(ctx); 22580 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22581 break; 22582 case OPC_MULEQ_S_W_PHR: 22583 check_dsp(ctx); 22584 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22585 break; 22586 case OPC_MULQ_S_PH: 22587 check_dsp_r2(ctx); 22588 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22589 break; 22590 } 22591 break; 22592 #ifdef TARGET_MIPS64 22593 case OPC_ADDU_OB_DSP: 22594 switch (op2) { 22595 case OPC_MULEQ_S_PW_QHL: 22596 check_dsp(ctx); 22597 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22598 break; 22599 case OPC_MULEQ_S_PW_QHR: 22600 check_dsp(ctx); 22601 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22602 break; 22603 case OPC_MULEU_S_QH_OBL: 22604 check_dsp(ctx); 22605 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22606 break; 22607 case OPC_MULEU_S_QH_OBR: 22608 check_dsp(ctx); 22609 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22610 break; 22611 case OPC_MULQ_RS_QH: 22612 check_dsp(ctx); 22613 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22614 break; 22615 } 22616 break; 22617 #endif 22618 } 22619 22620 tcg_temp_free_i32(t0); 22621 tcg_temp_free(v1_t); 22622 tcg_temp_free(v2_t); 22623 } 22624 22625 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 22626 int ret, int val) 22627 { 22628 int16_t imm; 22629 TCGv t0; 22630 TCGv val_t; 22631 22632 if (ret == 0) { 22633 /* Treat as NOP. */ 22634 return; 22635 } 22636 22637 t0 = tcg_temp_new(); 22638 val_t = tcg_temp_new(); 22639 gen_load_gpr(val_t, val); 22640 22641 switch (op1) { 22642 case OPC_ABSQ_S_PH_DSP: 22643 switch (op2) { 22644 case OPC_BITREV: 22645 check_dsp(ctx); 22646 gen_helper_bitrev(cpu_gpr[ret], val_t); 22647 break; 22648 case OPC_REPL_QB: 22649 check_dsp(ctx); 22650 { 22651 target_long result; 22652 imm = (ctx->opcode >> 16) & 0xFF; 22653 result = (uint32_t)imm << 24 | 22654 (uint32_t)imm << 16 | 22655 (uint32_t)imm << 8 | 22656 (uint32_t)imm; 22657 result = (int32_t)result; 22658 tcg_gen_movi_tl(cpu_gpr[ret], result); 22659 } 22660 break; 22661 case OPC_REPLV_QB: 22662 check_dsp(ctx); 22663 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 22664 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 22665 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22666 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 22667 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22668 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 22669 break; 22670 case OPC_REPL_PH: 22671 check_dsp(ctx); 22672 { 22673 imm = (ctx->opcode >> 16) & 0x03FF; 22674 imm = (int16_t)(imm << 6) >> 6; 22675 tcg_gen_movi_tl(cpu_gpr[ret], \ 22676 (target_long)((int32_t)imm << 16 | \ 22677 (uint16_t)imm)); 22678 } 22679 break; 22680 case OPC_REPLV_PH: 22681 check_dsp(ctx); 22682 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 22683 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 22684 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22685 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 22686 break; 22687 } 22688 break; 22689 #ifdef TARGET_MIPS64 22690 case OPC_ABSQ_S_QH_DSP: 22691 switch (op2) { 22692 case OPC_REPL_OB: 22693 check_dsp(ctx); 22694 { 22695 target_long temp; 22696 22697 imm = (ctx->opcode >> 16) & 0xFF; 22698 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 22699 temp = (temp << 16) | temp; 22700 temp = (temp << 32) | temp; 22701 tcg_gen_movi_tl(cpu_gpr[ret], temp); 22702 break; 22703 } 22704 case OPC_REPL_PW: 22705 check_dsp(ctx); 22706 { 22707 target_long temp; 22708 22709 imm = (ctx->opcode >> 16) & 0x03FF; 22710 imm = (int16_t)(imm << 6) >> 6; 22711 temp = ((target_long)imm << 32) \ 22712 | ((target_long)imm & 0xFFFFFFFF); 22713 tcg_gen_movi_tl(cpu_gpr[ret], temp); 22714 break; 22715 } 22716 case OPC_REPL_QH: 22717 check_dsp(ctx); 22718 { 22719 target_long temp; 22720 22721 imm = (ctx->opcode >> 16) & 0x03FF; 22722 imm = (int16_t)(imm << 6) >> 6; 22723 22724 temp = ((uint64_t)(uint16_t)imm << 48) | 22725 ((uint64_t)(uint16_t)imm << 32) | 22726 ((uint64_t)(uint16_t)imm << 16) | 22727 (uint64_t)(uint16_t)imm; 22728 tcg_gen_movi_tl(cpu_gpr[ret], temp); 22729 break; 22730 } 22731 case OPC_REPLV_OB: 22732 check_dsp(ctx); 22733 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 22734 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 22735 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22736 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 22737 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22738 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 22739 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22740 break; 22741 case OPC_REPLV_PW: 22742 check_dsp(ctx); 22743 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 22744 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 22745 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22746 break; 22747 case OPC_REPLV_QH: 22748 check_dsp(ctx); 22749 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 22750 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 22751 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22752 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 22753 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 22754 break; 22755 } 22756 break; 22757 #endif 22758 } 22759 tcg_temp_free(t0); 22760 tcg_temp_free(val_t); 22761 } 22762 22763 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 22764 uint32_t op1, uint32_t op2, 22765 int ret, int v1, int v2, int check_ret) 22766 { 22767 TCGv t1; 22768 TCGv v1_t; 22769 TCGv v2_t; 22770 22771 if ((ret == 0) && (check_ret == 1)) { 22772 /* Treat as NOP. */ 22773 return; 22774 } 22775 22776 t1 = tcg_temp_new(); 22777 v1_t = tcg_temp_new(); 22778 v2_t = tcg_temp_new(); 22779 22780 gen_load_gpr(v1_t, v1); 22781 gen_load_gpr(v2_t, v2); 22782 22783 switch (op1) { 22784 case OPC_CMPU_EQ_QB_DSP: 22785 switch (op2) { 22786 case OPC_CMPU_EQ_QB: 22787 check_dsp(ctx); 22788 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 22789 break; 22790 case OPC_CMPU_LT_QB: 22791 check_dsp(ctx); 22792 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 22793 break; 22794 case OPC_CMPU_LE_QB: 22795 check_dsp(ctx); 22796 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 22797 break; 22798 case OPC_CMPGU_EQ_QB: 22799 check_dsp(ctx); 22800 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 22801 break; 22802 case OPC_CMPGU_LT_QB: 22803 check_dsp(ctx); 22804 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 22805 break; 22806 case OPC_CMPGU_LE_QB: 22807 check_dsp(ctx); 22808 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 22809 break; 22810 case OPC_CMPGDU_EQ_QB: 22811 check_dsp_r2(ctx); 22812 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 22813 tcg_gen_mov_tl(cpu_gpr[ret], t1); 22814 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 22815 tcg_gen_shli_tl(t1, t1, 24); 22816 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 22817 break; 22818 case OPC_CMPGDU_LT_QB: 22819 check_dsp_r2(ctx); 22820 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 22821 tcg_gen_mov_tl(cpu_gpr[ret], t1); 22822 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 22823 tcg_gen_shli_tl(t1, t1, 24); 22824 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 22825 break; 22826 case OPC_CMPGDU_LE_QB: 22827 check_dsp_r2(ctx); 22828 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 22829 tcg_gen_mov_tl(cpu_gpr[ret], t1); 22830 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 22831 tcg_gen_shli_tl(t1, t1, 24); 22832 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 22833 break; 22834 case OPC_CMP_EQ_PH: 22835 check_dsp(ctx); 22836 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 22837 break; 22838 case OPC_CMP_LT_PH: 22839 check_dsp(ctx); 22840 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 22841 break; 22842 case OPC_CMP_LE_PH: 22843 check_dsp(ctx); 22844 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 22845 break; 22846 case OPC_PICK_QB: 22847 check_dsp(ctx); 22848 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22849 break; 22850 case OPC_PICK_PH: 22851 check_dsp(ctx); 22852 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22853 break; 22854 case OPC_PACKRL_PH: 22855 check_dsp(ctx); 22856 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 22857 break; 22858 } 22859 break; 22860 #ifdef TARGET_MIPS64 22861 case OPC_CMPU_EQ_OB_DSP: 22862 switch (op2) { 22863 case OPC_CMP_EQ_PW: 22864 check_dsp(ctx); 22865 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 22866 break; 22867 case OPC_CMP_LT_PW: 22868 check_dsp(ctx); 22869 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 22870 break; 22871 case OPC_CMP_LE_PW: 22872 check_dsp(ctx); 22873 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 22874 break; 22875 case OPC_CMP_EQ_QH: 22876 check_dsp(ctx); 22877 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 22878 break; 22879 case OPC_CMP_LT_QH: 22880 check_dsp(ctx); 22881 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 22882 break; 22883 case OPC_CMP_LE_QH: 22884 check_dsp(ctx); 22885 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 22886 break; 22887 case OPC_CMPGDU_EQ_OB: 22888 check_dsp_r2(ctx); 22889 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22890 break; 22891 case OPC_CMPGDU_LT_OB: 22892 check_dsp_r2(ctx); 22893 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22894 break; 22895 case OPC_CMPGDU_LE_OB: 22896 check_dsp_r2(ctx); 22897 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22898 break; 22899 case OPC_CMPGU_EQ_OB: 22900 check_dsp(ctx); 22901 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 22902 break; 22903 case OPC_CMPGU_LT_OB: 22904 check_dsp(ctx); 22905 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 22906 break; 22907 case OPC_CMPGU_LE_OB: 22908 check_dsp(ctx); 22909 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 22910 break; 22911 case OPC_CMPU_EQ_OB: 22912 check_dsp(ctx); 22913 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 22914 break; 22915 case OPC_CMPU_LT_OB: 22916 check_dsp(ctx); 22917 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 22918 break; 22919 case OPC_CMPU_LE_OB: 22920 check_dsp(ctx); 22921 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 22922 break; 22923 case OPC_PACKRL_PW: 22924 check_dsp(ctx); 22925 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 22926 break; 22927 case OPC_PICK_OB: 22928 check_dsp(ctx); 22929 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22930 break; 22931 case OPC_PICK_PW: 22932 check_dsp(ctx); 22933 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22934 break; 22935 case OPC_PICK_QH: 22936 check_dsp(ctx); 22937 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 22938 break; 22939 } 22940 break; 22941 #endif 22942 } 22943 22944 tcg_temp_free(t1); 22945 tcg_temp_free(v1_t); 22946 tcg_temp_free(v2_t); 22947 } 22948 22949 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 22950 uint32_t op1, int rt, int rs, int sa) 22951 { 22952 TCGv t0; 22953 22954 check_dsp_r2(ctx); 22955 22956 if (rt == 0) { 22957 /* Treat as NOP. */ 22958 return; 22959 } 22960 22961 t0 = tcg_temp_new(); 22962 gen_load_gpr(t0, rs); 22963 22964 switch (op1) { 22965 case OPC_APPEND_DSP: 22966 switch (MASK_APPEND(ctx->opcode)) { 22967 case OPC_APPEND: 22968 if (sa != 0) { 22969 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 22970 } 22971 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 22972 break; 22973 case OPC_PREPEND: 22974 if (sa != 0) { 22975 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 22976 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 22977 tcg_gen_shli_tl(t0, t0, 32 - sa); 22978 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 22979 } 22980 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 22981 break; 22982 case OPC_BALIGN: 22983 sa &= 3; 22984 if (sa != 0 && sa != 2) { 22985 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 22986 tcg_gen_ext32u_tl(t0, t0); 22987 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 22988 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 22989 } 22990 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 22991 break; 22992 default: /* Invalid */ 22993 MIPS_INVAL("MASK APPEND"); 22994 gen_reserved_instruction(ctx); 22995 break; 22996 } 22997 break; 22998 #ifdef TARGET_MIPS64 22999 case OPC_DAPPEND_DSP: 23000 switch (MASK_DAPPEND(ctx->opcode)) { 23001 case OPC_DAPPEND: 23002 if (sa != 0) { 23003 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 23004 } 23005 break; 23006 case OPC_PREPENDD: 23007 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 23008 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 23009 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 23010 break; 23011 case OPC_PREPENDW: 23012 if (sa != 0) { 23013 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 23014 tcg_gen_shli_tl(t0, t0, 64 - sa); 23015 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 23016 } 23017 break; 23018 case OPC_DBALIGN: 23019 sa &= 7; 23020 if (sa != 0 && sa != 2 && sa != 4) { 23021 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 23022 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 23023 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 23024 } 23025 break; 23026 default: /* Invalid */ 23027 MIPS_INVAL("MASK DAPPEND"); 23028 gen_reserved_instruction(ctx); 23029 break; 23030 } 23031 break; 23032 #endif 23033 } 23034 tcg_temp_free(t0); 23035 } 23036 23037 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 23038 int ret, int v1, int v2, int check_ret) 23039 23040 { 23041 TCGv t0; 23042 TCGv t1; 23043 TCGv v1_t; 23044 TCGv v2_t; 23045 int16_t imm; 23046 23047 if ((ret == 0) && (check_ret == 1)) { 23048 /* Treat as NOP. */ 23049 return; 23050 } 23051 23052 t0 = tcg_temp_new(); 23053 t1 = tcg_temp_new(); 23054 v1_t = tcg_temp_new(); 23055 v2_t = tcg_temp_new(); 23056 23057 gen_load_gpr(v1_t, v1); 23058 gen_load_gpr(v2_t, v2); 23059 23060 switch (op1) { 23061 case OPC_EXTR_W_DSP: 23062 check_dsp(ctx); 23063 switch (op2) { 23064 case OPC_EXTR_W: 23065 tcg_gen_movi_tl(t0, v2); 23066 tcg_gen_movi_tl(t1, v1); 23067 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 23068 break; 23069 case OPC_EXTR_R_W: 23070 tcg_gen_movi_tl(t0, v2); 23071 tcg_gen_movi_tl(t1, v1); 23072 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 23073 break; 23074 case OPC_EXTR_RS_W: 23075 tcg_gen_movi_tl(t0, v2); 23076 tcg_gen_movi_tl(t1, v1); 23077 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 23078 break; 23079 case OPC_EXTR_S_H: 23080 tcg_gen_movi_tl(t0, v2); 23081 tcg_gen_movi_tl(t1, v1); 23082 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 23083 break; 23084 case OPC_EXTRV_S_H: 23085 tcg_gen_movi_tl(t0, v2); 23086 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 23087 break; 23088 case OPC_EXTRV_W: 23089 tcg_gen_movi_tl(t0, v2); 23090 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23091 break; 23092 case OPC_EXTRV_R_W: 23093 tcg_gen_movi_tl(t0, v2); 23094 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23095 break; 23096 case OPC_EXTRV_RS_W: 23097 tcg_gen_movi_tl(t0, v2); 23098 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23099 break; 23100 case OPC_EXTP: 23101 tcg_gen_movi_tl(t0, v2); 23102 tcg_gen_movi_tl(t1, v1); 23103 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 23104 break; 23105 case OPC_EXTPV: 23106 tcg_gen_movi_tl(t0, v2); 23107 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 23108 break; 23109 case OPC_EXTPDP: 23110 tcg_gen_movi_tl(t0, v2); 23111 tcg_gen_movi_tl(t1, v1); 23112 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 23113 break; 23114 case OPC_EXTPDPV: 23115 tcg_gen_movi_tl(t0, v2); 23116 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 23117 break; 23118 case OPC_SHILO: 23119 imm = (ctx->opcode >> 20) & 0x3F; 23120 tcg_gen_movi_tl(t0, ret); 23121 tcg_gen_movi_tl(t1, imm); 23122 gen_helper_shilo(t0, t1, cpu_env); 23123 break; 23124 case OPC_SHILOV: 23125 tcg_gen_movi_tl(t0, ret); 23126 gen_helper_shilo(t0, v1_t, cpu_env); 23127 break; 23128 case OPC_MTHLIP: 23129 tcg_gen_movi_tl(t0, ret); 23130 gen_helper_mthlip(t0, v1_t, cpu_env); 23131 break; 23132 case OPC_WRDSP: 23133 imm = (ctx->opcode >> 11) & 0x3FF; 23134 tcg_gen_movi_tl(t0, imm); 23135 gen_helper_wrdsp(v1_t, t0, cpu_env); 23136 break; 23137 case OPC_RDDSP: 23138 imm = (ctx->opcode >> 16) & 0x03FF; 23139 tcg_gen_movi_tl(t0, imm); 23140 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 23141 break; 23142 } 23143 break; 23144 #ifdef TARGET_MIPS64 23145 case OPC_DEXTR_W_DSP: 23146 check_dsp(ctx); 23147 switch (op2) { 23148 case OPC_DMTHLIP: 23149 tcg_gen_movi_tl(t0, ret); 23150 gen_helper_dmthlip(v1_t, t0, cpu_env); 23151 break; 23152 case OPC_DSHILO: 23153 { 23154 int shift = (ctx->opcode >> 19) & 0x7F; 23155 int ac = (ctx->opcode >> 11) & 0x03; 23156 tcg_gen_movi_tl(t0, shift); 23157 tcg_gen_movi_tl(t1, ac); 23158 gen_helper_dshilo(t0, t1, cpu_env); 23159 break; 23160 } 23161 case OPC_DSHILOV: 23162 { 23163 int ac = (ctx->opcode >> 11) & 0x03; 23164 tcg_gen_movi_tl(t0, ac); 23165 gen_helper_dshilo(v1_t, t0, cpu_env); 23166 break; 23167 } 23168 case OPC_DEXTP: 23169 tcg_gen_movi_tl(t0, v2); 23170 tcg_gen_movi_tl(t1, v1); 23171 23172 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 23173 break; 23174 case OPC_DEXTPV: 23175 tcg_gen_movi_tl(t0, v2); 23176 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 23177 break; 23178 case OPC_DEXTPDP: 23179 tcg_gen_movi_tl(t0, v2); 23180 tcg_gen_movi_tl(t1, v1); 23181 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 23182 break; 23183 case OPC_DEXTPDPV: 23184 tcg_gen_movi_tl(t0, v2); 23185 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 23186 break; 23187 case OPC_DEXTR_L: 23188 tcg_gen_movi_tl(t0, v2); 23189 tcg_gen_movi_tl(t1, v1); 23190 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 23191 break; 23192 case OPC_DEXTR_R_L: 23193 tcg_gen_movi_tl(t0, v2); 23194 tcg_gen_movi_tl(t1, v1); 23195 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 23196 break; 23197 case OPC_DEXTR_RS_L: 23198 tcg_gen_movi_tl(t0, v2); 23199 tcg_gen_movi_tl(t1, v1); 23200 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 23201 break; 23202 case OPC_DEXTR_W: 23203 tcg_gen_movi_tl(t0, v2); 23204 tcg_gen_movi_tl(t1, v1); 23205 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 23206 break; 23207 case OPC_DEXTR_R_W: 23208 tcg_gen_movi_tl(t0, v2); 23209 tcg_gen_movi_tl(t1, v1); 23210 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 23211 break; 23212 case OPC_DEXTR_RS_W: 23213 tcg_gen_movi_tl(t0, v2); 23214 tcg_gen_movi_tl(t1, v1); 23215 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 23216 break; 23217 case OPC_DEXTR_S_H: 23218 tcg_gen_movi_tl(t0, v2); 23219 tcg_gen_movi_tl(t1, v1); 23220 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 23221 break; 23222 case OPC_DEXTRV_S_H: 23223 tcg_gen_movi_tl(t0, v2); 23224 tcg_gen_movi_tl(t1, v1); 23225 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 23226 break; 23227 case OPC_DEXTRV_L: 23228 tcg_gen_movi_tl(t0, v2); 23229 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 23230 break; 23231 case OPC_DEXTRV_R_L: 23232 tcg_gen_movi_tl(t0, v2); 23233 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 23234 break; 23235 case OPC_DEXTRV_RS_L: 23236 tcg_gen_movi_tl(t0, v2); 23237 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 23238 break; 23239 case OPC_DEXTRV_W: 23240 tcg_gen_movi_tl(t0, v2); 23241 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23242 break; 23243 case OPC_DEXTRV_R_W: 23244 tcg_gen_movi_tl(t0, v2); 23245 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23246 break; 23247 case OPC_DEXTRV_RS_W: 23248 tcg_gen_movi_tl(t0, v2); 23249 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 23250 break; 23251 } 23252 break; 23253 #endif 23254 } 23255 23256 tcg_temp_free(t0); 23257 tcg_temp_free(t1); 23258 tcg_temp_free(v1_t); 23259 tcg_temp_free(v2_t); 23260 } 23261 23262 /* End MIPSDSP functions. */ 23263 23264 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 23265 { 23266 int rs, rt, rd, sa; 23267 uint32_t op1, op2; 23268 23269 rs = (ctx->opcode >> 21) & 0x1f; 23270 rt = (ctx->opcode >> 16) & 0x1f; 23271 rd = (ctx->opcode >> 11) & 0x1f; 23272 sa = (ctx->opcode >> 6) & 0x1f; 23273 23274 op1 = MASK_SPECIAL(ctx->opcode); 23275 switch (op1) { 23276 case OPC_MULT: 23277 case OPC_MULTU: 23278 case OPC_DIV: 23279 case OPC_DIVU: 23280 op2 = MASK_R6_MULDIV(ctx->opcode); 23281 switch (op2) { 23282 case R6_OPC_MUL: 23283 case R6_OPC_MUH: 23284 case R6_OPC_MULU: 23285 case R6_OPC_MUHU: 23286 case R6_OPC_DIV: 23287 case R6_OPC_MOD: 23288 case R6_OPC_DIVU: 23289 case R6_OPC_MODU: 23290 gen_r6_muldiv(ctx, op2, rd, rs, rt); 23291 break; 23292 default: 23293 MIPS_INVAL("special_r6 muldiv"); 23294 gen_reserved_instruction(ctx); 23295 break; 23296 } 23297 break; 23298 case OPC_SELEQZ: 23299 case OPC_SELNEZ: 23300 gen_cond_move(ctx, op1, rd, rs, rt); 23301 break; 23302 case R6_OPC_CLO: 23303 case R6_OPC_CLZ: 23304 if (rt == 0 && sa == 1) { 23305 /* 23306 * Major opcode and function field is shared with preR6 MFHI/MTHI. 23307 * We need additionally to check other fields. 23308 */ 23309 gen_cl(ctx, op1, rd, rs); 23310 } else { 23311 gen_reserved_instruction(ctx); 23312 } 23313 break; 23314 case R6_OPC_SDBBP: 23315 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 23316 gen_helper_do_semihosting(cpu_env); 23317 } else { 23318 if (ctx->hflags & MIPS_HFLAG_SBRI) { 23319 gen_reserved_instruction(ctx); 23320 } else { 23321 generate_exception_end(ctx, EXCP_DBp); 23322 } 23323 } 23324 break; 23325 #if defined(TARGET_MIPS64) 23326 case R6_OPC_DCLO: 23327 case R6_OPC_DCLZ: 23328 if (rt == 0 && sa == 1) { 23329 /* 23330 * Major opcode and function field is shared with preR6 MFHI/MTHI. 23331 * We need additionally to check other fields. 23332 */ 23333 check_mips_64(ctx); 23334 gen_cl(ctx, op1, rd, rs); 23335 } else { 23336 gen_reserved_instruction(ctx); 23337 } 23338 break; 23339 case OPC_DMULT: 23340 case OPC_DMULTU: 23341 case OPC_DDIV: 23342 case OPC_DDIVU: 23343 23344 op2 = MASK_R6_MULDIV(ctx->opcode); 23345 switch (op2) { 23346 case R6_OPC_DMUL: 23347 case R6_OPC_DMUH: 23348 case R6_OPC_DMULU: 23349 case R6_OPC_DMUHU: 23350 case R6_OPC_DDIV: 23351 case R6_OPC_DMOD: 23352 case R6_OPC_DDIVU: 23353 case R6_OPC_DMODU: 23354 check_mips_64(ctx); 23355 gen_r6_muldiv(ctx, op2, rd, rs, rt); 23356 break; 23357 default: 23358 MIPS_INVAL("special_r6 muldiv"); 23359 gen_reserved_instruction(ctx); 23360 break; 23361 } 23362 break; 23363 #endif 23364 default: /* Invalid */ 23365 MIPS_INVAL("special_r6"); 23366 gen_reserved_instruction(ctx); 23367 break; 23368 } 23369 } 23370 23371 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 23372 { 23373 int rs = extract32(ctx->opcode, 21, 5); 23374 int rt = extract32(ctx->opcode, 16, 5); 23375 int rd = extract32(ctx->opcode, 11, 5); 23376 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 23377 23378 switch (op1) { 23379 case OPC_MOVN: /* Conditional move */ 23380 case OPC_MOVZ: 23381 gen_cond_move(ctx, op1, rd, rs, rt); 23382 break; 23383 case OPC_MFHI: /* Move from HI/LO */ 23384 case OPC_MFLO: 23385 gen_HILO(ctx, op1, 0, rd); 23386 break; 23387 case OPC_MTHI: 23388 case OPC_MTLO: /* Move to HI/LO */ 23389 gen_HILO(ctx, op1, 0, rs); 23390 break; 23391 case OPC_MULT: 23392 case OPC_MULTU: 23393 gen_mul_txx9(ctx, op1, rd, rs, rt); 23394 break; 23395 case OPC_DIV: 23396 case OPC_DIVU: 23397 gen_muldiv(ctx, op1, 0, rs, rt); 23398 break; 23399 #if defined(TARGET_MIPS64) 23400 case OPC_DMULT: 23401 case OPC_DMULTU: 23402 case OPC_DDIV: 23403 case OPC_DDIVU: 23404 check_insn_opc_user_only(ctx, INSN_R5900); 23405 gen_muldiv(ctx, op1, 0, rs, rt); 23406 break; 23407 #endif 23408 case OPC_JR: 23409 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 23410 break; 23411 default: /* Invalid */ 23412 MIPS_INVAL("special_tx79"); 23413 gen_reserved_instruction(ctx); 23414 break; 23415 } 23416 } 23417 23418 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 23419 { 23420 int rs, rt, rd, sa; 23421 uint32_t op1; 23422 23423 rs = (ctx->opcode >> 21) & 0x1f; 23424 rt = (ctx->opcode >> 16) & 0x1f; 23425 rd = (ctx->opcode >> 11) & 0x1f; 23426 sa = (ctx->opcode >> 6) & 0x1f; 23427 23428 op1 = MASK_SPECIAL(ctx->opcode); 23429 switch (op1) { 23430 case OPC_MOVN: /* Conditional move */ 23431 case OPC_MOVZ: 23432 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 23433 INSN_LOONGSON2E | INSN_LOONGSON2F); 23434 gen_cond_move(ctx, op1, rd, rs, rt); 23435 break; 23436 case OPC_MFHI: /* Move from HI/LO */ 23437 case OPC_MFLO: 23438 gen_HILO(ctx, op1, rs & 3, rd); 23439 break; 23440 case OPC_MTHI: 23441 case OPC_MTLO: /* Move to HI/LO */ 23442 gen_HILO(ctx, op1, rd & 3, rs); 23443 break; 23444 case OPC_MOVCI: 23445 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 23446 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 23447 check_cp1_enabled(ctx); 23448 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 23449 (ctx->opcode >> 16) & 1); 23450 } else { 23451 generate_exception_err(ctx, EXCP_CpU, 1); 23452 } 23453 break; 23454 case OPC_MULT: 23455 case OPC_MULTU: 23456 if (sa) { 23457 check_insn(ctx, INSN_VR54XX); 23458 op1 = MASK_MUL_VR54XX(ctx->opcode); 23459 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 23460 } else { 23461 gen_muldiv(ctx, op1, rd & 3, rs, rt); 23462 } 23463 break; 23464 case OPC_DIV: 23465 case OPC_DIVU: 23466 gen_muldiv(ctx, op1, 0, rs, rt); 23467 break; 23468 #if defined(TARGET_MIPS64) 23469 case OPC_DMULT: 23470 case OPC_DMULTU: 23471 case OPC_DDIV: 23472 case OPC_DDIVU: 23473 check_insn(ctx, ISA_MIPS3); 23474 check_mips_64(ctx); 23475 gen_muldiv(ctx, op1, 0, rs, rt); 23476 break; 23477 #endif 23478 case OPC_JR: 23479 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 23480 break; 23481 case OPC_SPIM: 23482 #ifdef MIPS_STRICT_STANDARD 23483 MIPS_INVAL("SPIM"); 23484 gen_reserved_instruction(ctx); 23485 #else 23486 /* Implemented as RI exception for now. */ 23487 MIPS_INVAL("spim (unofficial)"); 23488 gen_reserved_instruction(ctx); 23489 #endif 23490 break; 23491 default: /* Invalid */ 23492 MIPS_INVAL("special_legacy"); 23493 gen_reserved_instruction(ctx); 23494 break; 23495 } 23496 } 23497 23498 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 23499 { 23500 int rs, rt, rd, sa; 23501 uint32_t op1; 23502 23503 rs = (ctx->opcode >> 21) & 0x1f; 23504 rt = (ctx->opcode >> 16) & 0x1f; 23505 rd = (ctx->opcode >> 11) & 0x1f; 23506 sa = (ctx->opcode >> 6) & 0x1f; 23507 23508 op1 = MASK_SPECIAL(ctx->opcode); 23509 switch (op1) { 23510 case OPC_SLL: /* Shift with immediate */ 23511 if (sa == 5 && rd == 0 && 23512 rs == 0 && rt == 0) { /* PAUSE */ 23513 if ((ctx->insn_flags & ISA_MIPS_R6) && 23514 (ctx->hflags & MIPS_HFLAG_BMASK)) { 23515 gen_reserved_instruction(ctx); 23516 break; 23517 } 23518 } 23519 /* Fallthrough */ 23520 case OPC_SRA: 23521 gen_shift_imm(ctx, op1, rd, rt, sa); 23522 break; 23523 case OPC_SRL: 23524 switch ((ctx->opcode >> 21) & 0x1f) { 23525 case 1: 23526 /* rotr is decoded as srl on non-R2 CPUs */ 23527 if (ctx->insn_flags & ISA_MIPS_R2) { 23528 op1 = OPC_ROTR; 23529 } 23530 /* Fallthrough */ 23531 case 0: 23532 gen_shift_imm(ctx, op1, rd, rt, sa); 23533 break; 23534 default: 23535 gen_reserved_instruction(ctx); 23536 break; 23537 } 23538 break; 23539 case OPC_ADD: 23540 case OPC_ADDU: 23541 case OPC_SUB: 23542 case OPC_SUBU: 23543 gen_arith(ctx, op1, rd, rs, rt); 23544 break; 23545 case OPC_SLLV: /* Shifts */ 23546 case OPC_SRAV: 23547 gen_shift(ctx, op1, rd, rs, rt); 23548 break; 23549 case OPC_SRLV: 23550 switch ((ctx->opcode >> 6) & 0x1f) { 23551 case 1: 23552 /* rotrv is decoded as srlv on non-R2 CPUs */ 23553 if (ctx->insn_flags & ISA_MIPS_R2) { 23554 op1 = OPC_ROTRV; 23555 } 23556 /* Fallthrough */ 23557 case 0: 23558 gen_shift(ctx, op1, rd, rs, rt); 23559 break; 23560 default: 23561 gen_reserved_instruction(ctx); 23562 break; 23563 } 23564 break; 23565 case OPC_SLT: /* Set on less than */ 23566 case OPC_SLTU: 23567 gen_slt(ctx, op1, rd, rs, rt); 23568 break; 23569 case OPC_AND: /* Logic*/ 23570 case OPC_OR: 23571 case OPC_NOR: 23572 case OPC_XOR: 23573 gen_logic(ctx, op1, rd, rs, rt); 23574 break; 23575 case OPC_JALR: 23576 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 23577 break; 23578 case OPC_TGE: /* Traps */ 23579 case OPC_TGEU: 23580 case OPC_TLT: 23581 case OPC_TLTU: 23582 case OPC_TEQ: 23583 case OPC_TNE: 23584 check_insn(ctx, ISA_MIPS2); 23585 gen_trap(ctx, op1, rs, rt, -1); 23586 break; 23587 case OPC_PMON: 23588 /* Pmon entry point, also R4010 selsl */ 23589 #ifdef MIPS_STRICT_STANDARD 23590 MIPS_INVAL("PMON / selsl"); 23591 gen_reserved_instruction(ctx); 23592 #else 23593 gen_helper_0e0i(pmon, sa); 23594 #endif 23595 break; 23596 case OPC_SYSCALL: 23597 generate_exception_end(ctx, EXCP_SYSCALL); 23598 break; 23599 case OPC_BREAK: 23600 generate_exception_end(ctx, EXCP_BREAK); 23601 break; 23602 case OPC_SYNC: 23603 check_insn(ctx, ISA_MIPS2); 23604 gen_sync(extract32(ctx->opcode, 6, 5)); 23605 break; 23606 23607 #if defined(TARGET_MIPS64) 23608 /* MIPS64 specific opcodes */ 23609 case OPC_DSLL: 23610 case OPC_DSRA: 23611 case OPC_DSLL32: 23612 case OPC_DSRA32: 23613 check_insn(ctx, ISA_MIPS3); 23614 check_mips_64(ctx); 23615 gen_shift_imm(ctx, op1, rd, rt, sa); 23616 break; 23617 case OPC_DSRL: 23618 switch ((ctx->opcode >> 21) & 0x1f) { 23619 case 1: 23620 /* drotr is decoded as dsrl on non-R2 CPUs */ 23621 if (ctx->insn_flags & ISA_MIPS_R2) { 23622 op1 = OPC_DROTR; 23623 } 23624 /* Fallthrough */ 23625 case 0: 23626 check_insn(ctx, ISA_MIPS3); 23627 check_mips_64(ctx); 23628 gen_shift_imm(ctx, op1, rd, rt, sa); 23629 break; 23630 default: 23631 gen_reserved_instruction(ctx); 23632 break; 23633 } 23634 break; 23635 case OPC_DSRL32: 23636 switch ((ctx->opcode >> 21) & 0x1f) { 23637 case 1: 23638 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 23639 if (ctx->insn_flags & ISA_MIPS_R2) { 23640 op1 = OPC_DROTR32; 23641 } 23642 /* Fallthrough */ 23643 case 0: 23644 check_insn(ctx, ISA_MIPS3); 23645 check_mips_64(ctx); 23646 gen_shift_imm(ctx, op1, rd, rt, sa); 23647 break; 23648 default: 23649 gen_reserved_instruction(ctx); 23650 break; 23651 } 23652 break; 23653 case OPC_DADD: 23654 case OPC_DADDU: 23655 case OPC_DSUB: 23656 case OPC_DSUBU: 23657 check_insn(ctx, ISA_MIPS3); 23658 check_mips_64(ctx); 23659 gen_arith(ctx, op1, rd, rs, rt); 23660 break; 23661 case OPC_DSLLV: 23662 case OPC_DSRAV: 23663 check_insn(ctx, ISA_MIPS3); 23664 check_mips_64(ctx); 23665 gen_shift(ctx, op1, rd, rs, rt); 23666 break; 23667 case OPC_DSRLV: 23668 switch ((ctx->opcode >> 6) & 0x1f) { 23669 case 1: 23670 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 23671 if (ctx->insn_flags & ISA_MIPS_R2) { 23672 op1 = OPC_DROTRV; 23673 } 23674 /* Fallthrough */ 23675 case 0: 23676 check_insn(ctx, ISA_MIPS3); 23677 check_mips_64(ctx); 23678 gen_shift(ctx, op1, rd, rs, rt); 23679 break; 23680 default: 23681 gen_reserved_instruction(ctx); 23682 break; 23683 } 23684 break; 23685 #endif 23686 default: 23687 if (ctx->insn_flags & ISA_MIPS_R6) { 23688 decode_opc_special_r6(env, ctx); 23689 } else if (ctx->insn_flags & INSN_R5900) { 23690 decode_opc_special_tx79(env, ctx); 23691 } else { 23692 decode_opc_special_legacy(env, ctx); 23693 } 23694 } 23695 } 23696 23697 23698 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 23699 { 23700 int rs, rt, rd; 23701 uint32_t op1; 23702 23703 rs = (ctx->opcode >> 21) & 0x1f; 23704 rt = (ctx->opcode >> 16) & 0x1f; 23705 rd = (ctx->opcode >> 11) & 0x1f; 23706 23707 op1 = MASK_SPECIAL2(ctx->opcode); 23708 switch (op1) { 23709 case OPC_MADD: /* Multiply and add/sub */ 23710 case OPC_MADDU: 23711 case OPC_MSUB: 23712 case OPC_MSUBU: 23713 check_insn(ctx, ISA_MIPS_R1); 23714 gen_muldiv(ctx, op1, rd & 3, rs, rt); 23715 break; 23716 case OPC_MUL: 23717 gen_arith(ctx, op1, rd, rs, rt); 23718 break; 23719 case OPC_DIV_G_2F: 23720 case OPC_DIVU_G_2F: 23721 case OPC_MULT_G_2F: 23722 case OPC_MULTU_G_2F: 23723 case OPC_MOD_G_2F: 23724 case OPC_MODU_G_2F: 23725 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 23726 gen_loongson_integer(ctx, op1, rd, rs, rt); 23727 break; 23728 case OPC_CLO: 23729 case OPC_CLZ: 23730 check_insn(ctx, ISA_MIPS_R1); 23731 gen_cl(ctx, op1, rd, rs); 23732 break; 23733 case OPC_SDBBP: 23734 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 23735 gen_helper_do_semihosting(cpu_env); 23736 } else { 23737 /* 23738 * XXX: not clear which exception should be raised 23739 * when in debug mode... 23740 */ 23741 check_insn(ctx, ISA_MIPS_R1); 23742 generate_exception_end(ctx, EXCP_DBp); 23743 } 23744 break; 23745 #if defined(TARGET_MIPS64) 23746 case OPC_DCLO: 23747 case OPC_DCLZ: 23748 check_insn(ctx, ISA_MIPS_R1); 23749 check_mips_64(ctx); 23750 gen_cl(ctx, op1, rd, rs); 23751 break; 23752 case OPC_DMULT_G_2F: 23753 case OPC_DMULTU_G_2F: 23754 case OPC_DDIV_G_2F: 23755 case OPC_DDIVU_G_2F: 23756 case OPC_DMOD_G_2F: 23757 case OPC_DMODU_G_2F: 23758 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 23759 gen_loongson_integer(ctx, op1, rd, rs, rt); 23760 break; 23761 #endif 23762 default: /* Invalid */ 23763 MIPS_INVAL("special2_legacy"); 23764 gen_reserved_instruction(ctx); 23765 break; 23766 } 23767 } 23768 23769 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 23770 { 23771 int rs, rt, rd, sa; 23772 uint32_t op1, op2; 23773 int16_t imm; 23774 23775 rs = (ctx->opcode >> 21) & 0x1f; 23776 rt = (ctx->opcode >> 16) & 0x1f; 23777 rd = (ctx->opcode >> 11) & 0x1f; 23778 sa = (ctx->opcode >> 6) & 0x1f; 23779 imm = (int16_t)ctx->opcode >> 7; 23780 23781 op1 = MASK_SPECIAL3(ctx->opcode); 23782 switch (op1) { 23783 case R6_OPC_PREF: 23784 if (rt >= 24) { 23785 /* hint codes 24-31 are reserved and signal RI */ 23786 gen_reserved_instruction(ctx); 23787 } 23788 /* Treat as NOP. */ 23789 break; 23790 case R6_OPC_CACHE: 23791 check_cp0_enabled(ctx); 23792 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 23793 gen_cache_operation(ctx, rt, rs, imm); 23794 } 23795 break; 23796 case R6_OPC_SC: 23797 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 23798 break; 23799 case R6_OPC_LL: 23800 gen_ld(ctx, op1, rt, rs, imm); 23801 break; 23802 case OPC_BSHFL: 23803 { 23804 if (rd == 0) { 23805 /* Treat as NOP. */ 23806 break; 23807 } 23808 op2 = MASK_BSHFL(ctx->opcode); 23809 switch (op2) { 23810 case OPC_ALIGN: 23811 case OPC_ALIGN_1: 23812 case OPC_ALIGN_2: 23813 case OPC_ALIGN_3: 23814 gen_align(ctx, 32, rd, rs, rt, sa & 3); 23815 break; 23816 case OPC_BITSWAP: 23817 gen_bitswap(ctx, op2, rd, rt); 23818 break; 23819 } 23820 } 23821 break; 23822 #ifndef CONFIG_USER_ONLY 23823 case OPC_GINV: 23824 if (unlikely(ctx->gi <= 1)) { 23825 gen_reserved_instruction(ctx); 23826 } 23827 check_cp0_enabled(ctx); 23828 switch ((ctx->opcode >> 6) & 3) { 23829 case 0: /* GINVI */ 23830 /* Treat as NOP. */ 23831 break; 23832 case 2: /* GINVT */ 23833 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 23834 break; 23835 default: 23836 gen_reserved_instruction(ctx); 23837 break; 23838 } 23839 break; 23840 #endif 23841 #if defined(TARGET_MIPS64) 23842 case R6_OPC_SCD: 23843 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 23844 break; 23845 case R6_OPC_LLD: 23846 gen_ld(ctx, op1, rt, rs, imm); 23847 break; 23848 case OPC_DBSHFL: 23849 check_mips_64(ctx); 23850 { 23851 if (rd == 0) { 23852 /* Treat as NOP. */ 23853 break; 23854 } 23855 op2 = MASK_DBSHFL(ctx->opcode); 23856 switch (op2) { 23857 case OPC_DALIGN: 23858 case OPC_DALIGN_1: 23859 case OPC_DALIGN_2: 23860 case OPC_DALIGN_3: 23861 case OPC_DALIGN_4: 23862 case OPC_DALIGN_5: 23863 case OPC_DALIGN_6: 23864 case OPC_DALIGN_7: 23865 gen_align(ctx, 64, rd, rs, rt, sa & 7); 23866 break; 23867 case OPC_DBITSWAP: 23868 gen_bitswap(ctx, op2, rd, rt); 23869 break; 23870 } 23871 23872 } 23873 break; 23874 #endif 23875 default: /* Invalid */ 23876 MIPS_INVAL("special3_r6"); 23877 gen_reserved_instruction(ctx); 23878 break; 23879 } 23880 } 23881 23882 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 23883 { 23884 int rs, rt, rd; 23885 uint32_t op1, op2; 23886 23887 rs = (ctx->opcode >> 21) & 0x1f; 23888 rt = (ctx->opcode >> 16) & 0x1f; 23889 rd = (ctx->opcode >> 11) & 0x1f; 23890 23891 op1 = MASK_SPECIAL3(ctx->opcode); 23892 switch (op1) { 23893 case OPC_DIV_G_2E: 23894 case OPC_DIVU_G_2E: 23895 case OPC_MOD_G_2E: 23896 case OPC_MODU_G_2E: 23897 case OPC_MULT_G_2E: 23898 case OPC_MULTU_G_2E: 23899 /* 23900 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 23901 * the same mask and op1. 23902 */ 23903 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 23904 op2 = MASK_ADDUH_QB(ctx->opcode); 23905 switch (op2) { 23906 case OPC_ADDUH_QB: 23907 case OPC_ADDUH_R_QB: 23908 case OPC_ADDQH_PH: 23909 case OPC_ADDQH_R_PH: 23910 case OPC_ADDQH_W: 23911 case OPC_ADDQH_R_W: 23912 case OPC_SUBUH_QB: 23913 case OPC_SUBUH_R_QB: 23914 case OPC_SUBQH_PH: 23915 case OPC_SUBQH_R_PH: 23916 case OPC_SUBQH_W: 23917 case OPC_SUBQH_R_W: 23918 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 23919 break; 23920 case OPC_MUL_PH: 23921 case OPC_MUL_S_PH: 23922 case OPC_MULQ_S_W: 23923 case OPC_MULQ_RS_W: 23924 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 23925 break; 23926 default: 23927 MIPS_INVAL("MASK ADDUH.QB"); 23928 gen_reserved_instruction(ctx); 23929 break; 23930 } 23931 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 23932 gen_loongson_integer(ctx, op1, rd, rs, rt); 23933 } else { 23934 gen_reserved_instruction(ctx); 23935 } 23936 break; 23937 case OPC_LX_DSP: 23938 op2 = MASK_LX(ctx->opcode); 23939 switch (op2) { 23940 #if defined(TARGET_MIPS64) 23941 case OPC_LDX: 23942 #endif 23943 case OPC_LBUX: 23944 case OPC_LHX: 23945 case OPC_LWX: 23946 gen_mipsdsp_ld(ctx, op2, rd, rs, rt); 23947 break; 23948 default: /* Invalid */ 23949 MIPS_INVAL("MASK LX"); 23950 gen_reserved_instruction(ctx); 23951 break; 23952 } 23953 break; 23954 case OPC_ABSQ_S_PH_DSP: 23955 op2 = MASK_ABSQ_S_PH(ctx->opcode); 23956 switch (op2) { 23957 case OPC_ABSQ_S_QB: 23958 case OPC_ABSQ_S_PH: 23959 case OPC_ABSQ_S_W: 23960 case OPC_PRECEQ_W_PHL: 23961 case OPC_PRECEQ_W_PHR: 23962 case OPC_PRECEQU_PH_QBL: 23963 case OPC_PRECEQU_PH_QBR: 23964 case OPC_PRECEQU_PH_QBLA: 23965 case OPC_PRECEQU_PH_QBRA: 23966 case OPC_PRECEU_PH_QBL: 23967 case OPC_PRECEU_PH_QBR: 23968 case OPC_PRECEU_PH_QBLA: 23969 case OPC_PRECEU_PH_QBRA: 23970 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 23971 break; 23972 case OPC_BITREV: 23973 case OPC_REPL_QB: 23974 case OPC_REPLV_QB: 23975 case OPC_REPL_PH: 23976 case OPC_REPLV_PH: 23977 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 23978 break; 23979 default: 23980 MIPS_INVAL("MASK ABSQ_S.PH"); 23981 gen_reserved_instruction(ctx); 23982 break; 23983 } 23984 break; 23985 case OPC_ADDU_QB_DSP: 23986 op2 = MASK_ADDU_QB(ctx->opcode); 23987 switch (op2) { 23988 case OPC_ADDQ_PH: 23989 case OPC_ADDQ_S_PH: 23990 case OPC_ADDQ_S_W: 23991 case OPC_ADDU_QB: 23992 case OPC_ADDU_S_QB: 23993 case OPC_ADDU_PH: 23994 case OPC_ADDU_S_PH: 23995 case OPC_SUBQ_PH: 23996 case OPC_SUBQ_S_PH: 23997 case OPC_SUBQ_S_W: 23998 case OPC_SUBU_QB: 23999 case OPC_SUBU_S_QB: 24000 case OPC_SUBU_PH: 24001 case OPC_SUBU_S_PH: 24002 case OPC_ADDSC: 24003 case OPC_ADDWC: 24004 case OPC_MODSUB: 24005 case OPC_RADDU_W_QB: 24006 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 24007 break; 24008 case OPC_MULEU_S_PH_QBL: 24009 case OPC_MULEU_S_PH_QBR: 24010 case OPC_MULQ_RS_PH: 24011 case OPC_MULEQ_S_W_PHL: 24012 case OPC_MULEQ_S_W_PHR: 24013 case OPC_MULQ_S_PH: 24014 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 24015 break; 24016 default: /* Invalid */ 24017 MIPS_INVAL("MASK ADDU.QB"); 24018 gen_reserved_instruction(ctx); 24019 break; 24020 24021 } 24022 break; 24023 case OPC_CMPU_EQ_QB_DSP: 24024 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 24025 switch (op2) { 24026 case OPC_PRECR_SRA_PH_W: 24027 case OPC_PRECR_SRA_R_PH_W: 24028 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 24029 break; 24030 case OPC_PRECR_QB_PH: 24031 case OPC_PRECRQ_QB_PH: 24032 case OPC_PRECRQ_PH_W: 24033 case OPC_PRECRQ_RS_PH_W: 24034 case OPC_PRECRQU_S_QB_PH: 24035 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 24036 break; 24037 case OPC_CMPU_EQ_QB: 24038 case OPC_CMPU_LT_QB: 24039 case OPC_CMPU_LE_QB: 24040 case OPC_CMP_EQ_PH: 24041 case OPC_CMP_LT_PH: 24042 case OPC_CMP_LE_PH: 24043 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 24044 break; 24045 case OPC_CMPGU_EQ_QB: 24046 case OPC_CMPGU_LT_QB: 24047 case OPC_CMPGU_LE_QB: 24048 case OPC_CMPGDU_EQ_QB: 24049 case OPC_CMPGDU_LT_QB: 24050 case OPC_CMPGDU_LE_QB: 24051 case OPC_PICK_QB: 24052 case OPC_PICK_PH: 24053 case OPC_PACKRL_PH: 24054 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 24055 break; 24056 default: /* Invalid */ 24057 MIPS_INVAL("MASK CMPU.EQ.QB"); 24058 gen_reserved_instruction(ctx); 24059 break; 24060 } 24061 break; 24062 case OPC_SHLL_QB_DSP: 24063 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 24064 break; 24065 case OPC_DPA_W_PH_DSP: 24066 op2 = MASK_DPA_W_PH(ctx->opcode); 24067 switch (op2) { 24068 case OPC_DPAU_H_QBL: 24069 case OPC_DPAU_H_QBR: 24070 case OPC_DPSU_H_QBL: 24071 case OPC_DPSU_H_QBR: 24072 case OPC_DPA_W_PH: 24073 case OPC_DPAX_W_PH: 24074 case OPC_DPAQ_S_W_PH: 24075 case OPC_DPAQX_S_W_PH: 24076 case OPC_DPAQX_SA_W_PH: 24077 case OPC_DPS_W_PH: 24078 case OPC_DPSX_W_PH: 24079 case OPC_DPSQ_S_W_PH: 24080 case OPC_DPSQX_S_W_PH: 24081 case OPC_DPSQX_SA_W_PH: 24082 case OPC_MULSAQ_S_W_PH: 24083 case OPC_DPAQ_SA_L_W: 24084 case OPC_DPSQ_SA_L_W: 24085 case OPC_MAQ_S_W_PHL: 24086 case OPC_MAQ_S_W_PHR: 24087 case OPC_MAQ_SA_W_PHL: 24088 case OPC_MAQ_SA_W_PHR: 24089 case OPC_MULSA_W_PH: 24090 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 24091 break; 24092 default: /* Invalid */ 24093 MIPS_INVAL("MASK DPAW.PH"); 24094 gen_reserved_instruction(ctx); 24095 break; 24096 } 24097 break; 24098 case OPC_INSV_DSP: 24099 op2 = MASK_INSV(ctx->opcode); 24100 switch (op2) { 24101 case OPC_INSV: 24102 check_dsp(ctx); 24103 { 24104 TCGv t0, t1; 24105 24106 if (rt == 0) { 24107 break; 24108 } 24109 24110 t0 = tcg_temp_new(); 24111 t1 = tcg_temp_new(); 24112 24113 gen_load_gpr(t0, rt); 24114 gen_load_gpr(t1, rs); 24115 24116 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 24117 24118 tcg_temp_free(t0); 24119 tcg_temp_free(t1); 24120 break; 24121 } 24122 default: /* Invalid */ 24123 MIPS_INVAL("MASK INSV"); 24124 gen_reserved_instruction(ctx); 24125 break; 24126 } 24127 break; 24128 case OPC_APPEND_DSP: 24129 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 24130 break; 24131 case OPC_EXTR_W_DSP: 24132 op2 = MASK_EXTR_W(ctx->opcode); 24133 switch (op2) { 24134 case OPC_EXTR_W: 24135 case OPC_EXTR_R_W: 24136 case OPC_EXTR_RS_W: 24137 case OPC_EXTR_S_H: 24138 case OPC_EXTRV_S_H: 24139 case OPC_EXTRV_W: 24140 case OPC_EXTRV_R_W: 24141 case OPC_EXTRV_RS_W: 24142 case OPC_EXTP: 24143 case OPC_EXTPV: 24144 case OPC_EXTPDP: 24145 case OPC_EXTPDPV: 24146 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 24147 break; 24148 case OPC_RDDSP: 24149 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 24150 break; 24151 case OPC_SHILO: 24152 case OPC_SHILOV: 24153 case OPC_MTHLIP: 24154 case OPC_WRDSP: 24155 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 24156 break; 24157 default: /* Invalid */ 24158 MIPS_INVAL("MASK EXTR.W"); 24159 gen_reserved_instruction(ctx); 24160 break; 24161 } 24162 break; 24163 #if defined(TARGET_MIPS64) 24164 case OPC_DDIV_G_2E: 24165 case OPC_DDIVU_G_2E: 24166 case OPC_DMULT_G_2E: 24167 case OPC_DMULTU_G_2E: 24168 case OPC_DMOD_G_2E: 24169 case OPC_DMODU_G_2E: 24170 check_insn(ctx, INSN_LOONGSON2E); 24171 gen_loongson_integer(ctx, op1, rd, rs, rt); 24172 break; 24173 case OPC_ABSQ_S_QH_DSP: 24174 op2 = MASK_ABSQ_S_QH(ctx->opcode); 24175 switch (op2) { 24176 case OPC_PRECEQ_L_PWL: 24177 case OPC_PRECEQ_L_PWR: 24178 case OPC_PRECEQ_PW_QHL: 24179 case OPC_PRECEQ_PW_QHR: 24180 case OPC_PRECEQ_PW_QHLA: 24181 case OPC_PRECEQ_PW_QHRA: 24182 case OPC_PRECEQU_QH_OBL: 24183 case OPC_PRECEQU_QH_OBR: 24184 case OPC_PRECEQU_QH_OBLA: 24185 case OPC_PRECEQU_QH_OBRA: 24186 case OPC_PRECEU_QH_OBL: 24187 case OPC_PRECEU_QH_OBR: 24188 case OPC_PRECEU_QH_OBLA: 24189 case OPC_PRECEU_QH_OBRA: 24190 case OPC_ABSQ_S_OB: 24191 case OPC_ABSQ_S_PW: 24192 case OPC_ABSQ_S_QH: 24193 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 24194 break; 24195 case OPC_REPL_OB: 24196 case OPC_REPL_PW: 24197 case OPC_REPL_QH: 24198 case OPC_REPLV_OB: 24199 case OPC_REPLV_PW: 24200 case OPC_REPLV_QH: 24201 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 24202 break; 24203 default: /* Invalid */ 24204 MIPS_INVAL("MASK ABSQ_S.QH"); 24205 gen_reserved_instruction(ctx); 24206 break; 24207 } 24208 break; 24209 case OPC_ADDU_OB_DSP: 24210 op2 = MASK_ADDU_OB(ctx->opcode); 24211 switch (op2) { 24212 case OPC_RADDU_L_OB: 24213 case OPC_SUBQ_PW: 24214 case OPC_SUBQ_S_PW: 24215 case OPC_SUBQ_QH: 24216 case OPC_SUBQ_S_QH: 24217 case OPC_SUBU_OB: 24218 case OPC_SUBU_S_OB: 24219 case OPC_SUBU_QH: 24220 case OPC_SUBU_S_QH: 24221 case OPC_SUBUH_OB: 24222 case OPC_SUBUH_R_OB: 24223 case OPC_ADDQ_PW: 24224 case OPC_ADDQ_S_PW: 24225 case OPC_ADDQ_QH: 24226 case OPC_ADDQ_S_QH: 24227 case OPC_ADDU_OB: 24228 case OPC_ADDU_S_OB: 24229 case OPC_ADDU_QH: 24230 case OPC_ADDU_S_QH: 24231 case OPC_ADDUH_OB: 24232 case OPC_ADDUH_R_OB: 24233 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 24234 break; 24235 case OPC_MULEQ_S_PW_QHL: 24236 case OPC_MULEQ_S_PW_QHR: 24237 case OPC_MULEU_S_QH_OBL: 24238 case OPC_MULEU_S_QH_OBR: 24239 case OPC_MULQ_RS_QH: 24240 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 24241 break; 24242 default: /* Invalid */ 24243 MIPS_INVAL("MASK ADDU.OB"); 24244 gen_reserved_instruction(ctx); 24245 break; 24246 } 24247 break; 24248 case OPC_CMPU_EQ_OB_DSP: 24249 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 24250 switch (op2) { 24251 case OPC_PRECR_SRA_QH_PW: 24252 case OPC_PRECR_SRA_R_QH_PW: 24253 /* Return value is rt. */ 24254 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 24255 break; 24256 case OPC_PRECR_OB_QH: 24257 case OPC_PRECRQ_OB_QH: 24258 case OPC_PRECRQ_PW_L: 24259 case OPC_PRECRQ_QH_PW: 24260 case OPC_PRECRQ_RS_QH_PW: 24261 case OPC_PRECRQU_S_OB_QH: 24262 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 24263 break; 24264 case OPC_CMPU_EQ_OB: 24265 case OPC_CMPU_LT_OB: 24266 case OPC_CMPU_LE_OB: 24267 case OPC_CMP_EQ_QH: 24268 case OPC_CMP_LT_QH: 24269 case OPC_CMP_LE_QH: 24270 case OPC_CMP_EQ_PW: 24271 case OPC_CMP_LT_PW: 24272 case OPC_CMP_LE_PW: 24273 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 24274 break; 24275 case OPC_CMPGDU_EQ_OB: 24276 case OPC_CMPGDU_LT_OB: 24277 case OPC_CMPGDU_LE_OB: 24278 case OPC_CMPGU_EQ_OB: 24279 case OPC_CMPGU_LT_OB: 24280 case OPC_CMPGU_LE_OB: 24281 case OPC_PACKRL_PW: 24282 case OPC_PICK_OB: 24283 case OPC_PICK_PW: 24284 case OPC_PICK_QH: 24285 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 24286 break; 24287 default: /* Invalid */ 24288 MIPS_INVAL("MASK CMPU_EQ.OB"); 24289 gen_reserved_instruction(ctx); 24290 break; 24291 } 24292 break; 24293 case OPC_DAPPEND_DSP: 24294 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 24295 break; 24296 case OPC_DEXTR_W_DSP: 24297 op2 = MASK_DEXTR_W(ctx->opcode); 24298 switch (op2) { 24299 case OPC_DEXTP: 24300 case OPC_DEXTPDP: 24301 case OPC_DEXTPDPV: 24302 case OPC_DEXTPV: 24303 case OPC_DEXTR_L: 24304 case OPC_DEXTR_R_L: 24305 case OPC_DEXTR_RS_L: 24306 case OPC_DEXTR_W: 24307 case OPC_DEXTR_R_W: 24308 case OPC_DEXTR_RS_W: 24309 case OPC_DEXTR_S_H: 24310 case OPC_DEXTRV_L: 24311 case OPC_DEXTRV_R_L: 24312 case OPC_DEXTRV_RS_L: 24313 case OPC_DEXTRV_S_H: 24314 case OPC_DEXTRV_W: 24315 case OPC_DEXTRV_R_W: 24316 case OPC_DEXTRV_RS_W: 24317 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 24318 break; 24319 case OPC_DMTHLIP: 24320 case OPC_DSHILO: 24321 case OPC_DSHILOV: 24322 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 24323 break; 24324 default: /* Invalid */ 24325 MIPS_INVAL("MASK EXTR.W"); 24326 gen_reserved_instruction(ctx); 24327 break; 24328 } 24329 break; 24330 case OPC_DPAQ_W_QH_DSP: 24331 op2 = MASK_DPAQ_W_QH(ctx->opcode); 24332 switch (op2) { 24333 case OPC_DPAU_H_OBL: 24334 case OPC_DPAU_H_OBR: 24335 case OPC_DPSU_H_OBL: 24336 case OPC_DPSU_H_OBR: 24337 case OPC_DPA_W_QH: 24338 case OPC_DPAQ_S_W_QH: 24339 case OPC_DPS_W_QH: 24340 case OPC_DPSQ_S_W_QH: 24341 case OPC_MULSAQ_S_W_QH: 24342 case OPC_DPAQ_SA_L_PW: 24343 case OPC_DPSQ_SA_L_PW: 24344 case OPC_MULSAQ_S_L_PW: 24345 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 24346 break; 24347 case OPC_MAQ_S_W_QHLL: 24348 case OPC_MAQ_S_W_QHLR: 24349 case OPC_MAQ_S_W_QHRL: 24350 case OPC_MAQ_S_W_QHRR: 24351 case OPC_MAQ_SA_W_QHLL: 24352 case OPC_MAQ_SA_W_QHLR: 24353 case OPC_MAQ_SA_W_QHRL: 24354 case OPC_MAQ_SA_W_QHRR: 24355 case OPC_MAQ_S_L_PWL: 24356 case OPC_MAQ_S_L_PWR: 24357 case OPC_DMADD: 24358 case OPC_DMADDU: 24359 case OPC_DMSUB: 24360 case OPC_DMSUBU: 24361 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 24362 break; 24363 default: /* Invalid */ 24364 MIPS_INVAL("MASK DPAQ.W.QH"); 24365 gen_reserved_instruction(ctx); 24366 break; 24367 } 24368 break; 24369 case OPC_DINSV_DSP: 24370 op2 = MASK_INSV(ctx->opcode); 24371 switch (op2) { 24372 case OPC_DINSV: 24373 { 24374 TCGv t0, t1; 24375 24376 if (rt == 0) { 24377 break; 24378 } 24379 check_dsp(ctx); 24380 24381 t0 = tcg_temp_new(); 24382 t1 = tcg_temp_new(); 24383 24384 gen_load_gpr(t0, rt); 24385 gen_load_gpr(t1, rs); 24386 24387 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 24388 24389 tcg_temp_free(t0); 24390 tcg_temp_free(t1); 24391 break; 24392 } 24393 default: /* Invalid */ 24394 MIPS_INVAL("MASK DINSV"); 24395 gen_reserved_instruction(ctx); 24396 break; 24397 } 24398 break; 24399 case OPC_SHLL_OB_DSP: 24400 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 24401 break; 24402 #endif 24403 default: /* Invalid */ 24404 MIPS_INVAL("special3_legacy"); 24405 gen_reserved_instruction(ctx); 24406 break; 24407 } 24408 } 24409 24410 24411 #if defined(TARGET_MIPS64) 24412 24413 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 24414 { 24415 uint32_t opc = MASK_MMI(ctx->opcode); 24416 int rs = extract32(ctx->opcode, 21, 5); 24417 int rt = extract32(ctx->opcode, 16, 5); 24418 int rd = extract32(ctx->opcode, 11, 5); 24419 24420 switch (opc) { 24421 case MMI_OPC_MULT1: 24422 case MMI_OPC_MULTU1: 24423 case MMI_OPC_MADD: 24424 case MMI_OPC_MADDU: 24425 case MMI_OPC_MADD1: 24426 case MMI_OPC_MADDU1: 24427 gen_mul_txx9(ctx, opc, rd, rs, rt); 24428 break; 24429 case MMI_OPC_DIV1: 24430 case MMI_OPC_DIVU1: 24431 gen_div1_tx79(ctx, opc, rs, rt); 24432 break; 24433 default: 24434 MIPS_INVAL("TX79 MMI class"); 24435 gen_reserved_instruction(ctx); 24436 break; 24437 } 24438 } 24439 24440 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx) 24441 { 24442 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_LQ */ 24443 } 24444 24445 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 24446 { 24447 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 24448 } 24449 24450 /* 24451 * The TX79-specific instruction Store Quadword 24452 * 24453 * +--------+-------+-------+------------------------+ 24454 * | 011111 | base | rt | offset | SQ 24455 * +--------+-------+-------+------------------------+ 24456 * 6 5 5 16 24457 * 24458 * has the same opcode as the Read Hardware Register instruction 24459 * 24460 * +--------+-------+-------+-------+-------+--------+ 24461 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 24462 * +--------+-------+-------+-------+-------+--------+ 24463 * 6 5 5 5 5 6 24464 * 24465 * that is required, trapped and emulated by the Linux kernel. However, all 24466 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 24467 * offset is odd. Therefore all valid SQ instructions can execute normally. 24468 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 24469 * between SQ and RDHWR, as the Linux kernel does. 24470 */ 24471 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 24472 { 24473 int base = extract32(ctx->opcode, 21, 5); 24474 int rt = extract32(ctx->opcode, 16, 5); 24475 int offset = extract32(ctx->opcode, 0, 16); 24476 24477 #ifdef CONFIG_USER_ONLY 24478 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 24479 uint32_t op2 = extract32(ctx->opcode, 6, 5); 24480 24481 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 24482 int rd = extract32(ctx->opcode, 11, 5); 24483 24484 gen_rdhwr(ctx, rt, rd, 0); 24485 return; 24486 } 24487 #endif 24488 24489 gen_mmi_sq(ctx, base, rt, offset); 24490 } 24491 24492 #endif 24493 24494 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 24495 { 24496 int rs, rt, rd, sa; 24497 uint32_t op1, op2; 24498 int16_t imm; 24499 24500 rs = (ctx->opcode >> 21) & 0x1f; 24501 rt = (ctx->opcode >> 16) & 0x1f; 24502 rd = (ctx->opcode >> 11) & 0x1f; 24503 sa = (ctx->opcode >> 6) & 0x1f; 24504 imm = sextract32(ctx->opcode, 7, 9); 24505 24506 op1 = MASK_SPECIAL3(ctx->opcode); 24507 24508 /* 24509 * EVA loads and stores overlap Loongson 2E instructions decoded by 24510 * decode_opc_special3_legacy(), so be careful to allow their decoding when 24511 * EVA is absent. 24512 */ 24513 if (ctx->eva) { 24514 switch (op1) { 24515 case OPC_LWLE: 24516 case OPC_LWRE: 24517 case OPC_LBUE: 24518 case OPC_LHUE: 24519 case OPC_LBE: 24520 case OPC_LHE: 24521 case OPC_LLE: 24522 case OPC_LWE: 24523 check_cp0_enabled(ctx); 24524 gen_ld(ctx, op1, rt, rs, imm); 24525 return; 24526 case OPC_SWLE: 24527 case OPC_SWRE: 24528 case OPC_SBE: 24529 case OPC_SHE: 24530 case OPC_SWE: 24531 check_cp0_enabled(ctx); 24532 gen_st(ctx, op1, rt, rs, imm); 24533 return; 24534 case OPC_SCE: 24535 check_cp0_enabled(ctx); 24536 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 24537 return; 24538 case OPC_CACHEE: 24539 check_eva(ctx); 24540 check_cp0_enabled(ctx); 24541 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 24542 gen_cache_operation(ctx, rt, rs, imm); 24543 } 24544 return; 24545 case OPC_PREFE: 24546 check_cp0_enabled(ctx); 24547 /* Treat as NOP. */ 24548 return; 24549 } 24550 } 24551 24552 switch (op1) { 24553 case OPC_EXT: 24554 case OPC_INS: 24555 check_insn(ctx, ISA_MIPS_R2); 24556 gen_bitops(ctx, op1, rt, rs, sa, rd); 24557 break; 24558 case OPC_BSHFL: 24559 op2 = MASK_BSHFL(ctx->opcode); 24560 switch (op2) { 24561 case OPC_ALIGN: 24562 case OPC_ALIGN_1: 24563 case OPC_ALIGN_2: 24564 case OPC_ALIGN_3: 24565 case OPC_BITSWAP: 24566 check_insn(ctx, ISA_MIPS_R6); 24567 decode_opc_special3_r6(env, ctx); 24568 break; 24569 default: 24570 check_insn(ctx, ISA_MIPS_R2); 24571 gen_bshfl(ctx, op2, rt, rd); 24572 break; 24573 } 24574 break; 24575 #if defined(TARGET_MIPS64) 24576 case OPC_DEXTM: 24577 case OPC_DEXTU: 24578 case OPC_DEXT: 24579 case OPC_DINSM: 24580 case OPC_DINSU: 24581 case OPC_DINS: 24582 check_insn(ctx, ISA_MIPS_R2); 24583 check_mips_64(ctx); 24584 gen_bitops(ctx, op1, rt, rs, sa, rd); 24585 break; 24586 case OPC_DBSHFL: 24587 op2 = MASK_DBSHFL(ctx->opcode); 24588 switch (op2) { 24589 case OPC_DALIGN: 24590 case OPC_DALIGN_1: 24591 case OPC_DALIGN_2: 24592 case OPC_DALIGN_3: 24593 case OPC_DALIGN_4: 24594 case OPC_DALIGN_5: 24595 case OPC_DALIGN_6: 24596 case OPC_DALIGN_7: 24597 case OPC_DBITSWAP: 24598 check_insn(ctx, ISA_MIPS_R6); 24599 decode_opc_special3_r6(env, ctx); 24600 break; 24601 default: 24602 check_insn(ctx, ISA_MIPS_R2); 24603 check_mips_64(ctx); 24604 op2 = MASK_DBSHFL(ctx->opcode); 24605 gen_bshfl(ctx, op2, rt, rd); 24606 break; 24607 } 24608 break; 24609 #endif 24610 case OPC_RDHWR: 24611 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 24612 break; 24613 case OPC_FORK: 24614 check_mt(ctx); 24615 { 24616 TCGv t0 = tcg_temp_new(); 24617 TCGv t1 = tcg_temp_new(); 24618 24619 gen_load_gpr(t0, rt); 24620 gen_load_gpr(t1, rs); 24621 gen_helper_fork(t0, t1); 24622 tcg_temp_free(t0); 24623 tcg_temp_free(t1); 24624 } 24625 break; 24626 case OPC_YIELD: 24627 check_mt(ctx); 24628 { 24629 TCGv t0 = tcg_temp_new(); 24630 24631 gen_load_gpr(t0, rs); 24632 gen_helper_yield(t0, cpu_env, t0); 24633 gen_store_gpr(t0, rd); 24634 tcg_temp_free(t0); 24635 } 24636 break; 24637 default: 24638 if (ctx->insn_flags & ISA_MIPS_R6) { 24639 decode_opc_special3_r6(env, ctx); 24640 } else { 24641 decode_opc_special3_legacy(env, ctx); 24642 } 24643 } 24644 } 24645 24646 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 24647 { 24648 int32_t offset; 24649 int rs, rt, rd, sa; 24650 uint32_t op, op1; 24651 int16_t imm; 24652 24653 op = MASK_OP_MAJOR(ctx->opcode); 24654 rs = (ctx->opcode >> 21) & 0x1f; 24655 rt = (ctx->opcode >> 16) & 0x1f; 24656 rd = (ctx->opcode >> 11) & 0x1f; 24657 sa = (ctx->opcode >> 6) & 0x1f; 24658 imm = (int16_t)ctx->opcode; 24659 switch (op) { 24660 case OPC_SPECIAL: 24661 decode_opc_special(env, ctx); 24662 break; 24663 case OPC_SPECIAL2: 24664 #if defined(TARGET_MIPS64) 24665 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 24666 decode_mmi(env, ctx); 24667 break; 24668 } 24669 #endif 24670 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 24671 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 24672 gen_arith(ctx, OPC_MUL, rd, rs, rt); 24673 } else { 24674 decode_ase_mxu(ctx, ctx->opcode); 24675 } 24676 break; 24677 } 24678 decode_opc_special2_legacy(env, ctx); 24679 break; 24680 case OPC_SPECIAL3: 24681 #if defined(TARGET_MIPS64) 24682 if (ctx->insn_flags & INSN_R5900) { 24683 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 24684 } else { 24685 decode_opc_special3(env, ctx); 24686 } 24687 #else 24688 decode_opc_special3(env, ctx); 24689 #endif 24690 break; 24691 case OPC_REGIMM: 24692 op1 = MASK_REGIMM(ctx->opcode); 24693 switch (op1) { 24694 case OPC_BLTZL: /* REGIMM branches */ 24695 case OPC_BGEZL: 24696 case OPC_BLTZALL: 24697 case OPC_BGEZALL: 24698 check_insn(ctx, ISA_MIPS2); 24699 check_insn_opc_removed(ctx, ISA_MIPS_R6); 24700 /* Fallthrough */ 24701 case OPC_BLTZ: 24702 case OPC_BGEZ: 24703 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 24704 break; 24705 case OPC_BLTZAL: 24706 case OPC_BGEZAL: 24707 if (ctx->insn_flags & ISA_MIPS_R6) { 24708 if (rs == 0) { 24709 /* OPC_NAL, OPC_BAL */ 24710 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 24711 } else { 24712 gen_reserved_instruction(ctx); 24713 } 24714 } else { 24715 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 24716 } 24717 break; 24718 case OPC_TGEI: /* REGIMM traps */ 24719 case OPC_TGEIU: 24720 case OPC_TLTI: 24721 case OPC_TLTIU: 24722 case OPC_TEQI: 24723 24724 case OPC_TNEI: 24725 check_insn(ctx, ISA_MIPS2); 24726 check_insn_opc_removed(ctx, ISA_MIPS_R6); 24727 gen_trap(ctx, op1, rs, -1, imm); 24728 break; 24729 case OPC_SIGRIE: 24730 check_insn(ctx, ISA_MIPS_R6); 24731 gen_reserved_instruction(ctx); 24732 break; 24733 case OPC_SYNCI: 24734 check_insn(ctx, ISA_MIPS_R2); 24735 /* 24736 * Break the TB to be able to sync copied instructions 24737 * immediately. 24738 */ 24739 ctx->base.is_jmp = DISAS_STOP; 24740 break; 24741 case OPC_BPOSGE32: /* MIPS DSP branch */ 24742 #if defined(TARGET_MIPS64) 24743 case OPC_BPOSGE64: 24744 #endif 24745 check_dsp(ctx); 24746 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 24747 break; 24748 #if defined(TARGET_MIPS64) 24749 case OPC_DAHI: 24750 check_insn(ctx, ISA_MIPS_R6); 24751 check_mips_64(ctx); 24752 if (rs != 0) { 24753 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 24754 } 24755 break; 24756 case OPC_DATI: 24757 check_insn(ctx, ISA_MIPS_R6); 24758 check_mips_64(ctx); 24759 if (rs != 0) { 24760 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 24761 } 24762 break; 24763 #endif 24764 default: /* Invalid */ 24765 MIPS_INVAL("regimm"); 24766 gen_reserved_instruction(ctx); 24767 break; 24768 } 24769 break; 24770 case OPC_CP0: 24771 check_cp0_enabled(ctx); 24772 op1 = MASK_CP0(ctx->opcode); 24773 switch (op1) { 24774 case OPC_MFC0: 24775 case OPC_MTC0: 24776 case OPC_MFTR: 24777 case OPC_MTTR: 24778 case OPC_MFHC0: 24779 case OPC_MTHC0: 24780 #if defined(TARGET_MIPS64) 24781 case OPC_DMFC0: 24782 case OPC_DMTC0: 24783 #endif 24784 #ifndef CONFIG_USER_ONLY 24785 gen_cp0(env, ctx, op1, rt, rd); 24786 #endif /* !CONFIG_USER_ONLY */ 24787 break; 24788 case OPC_C0: 24789 case OPC_C0_1: 24790 case OPC_C0_2: 24791 case OPC_C0_3: 24792 case OPC_C0_4: 24793 case OPC_C0_5: 24794 case OPC_C0_6: 24795 case OPC_C0_7: 24796 case OPC_C0_8: 24797 case OPC_C0_9: 24798 case OPC_C0_A: 24799 case OPC_C0_B: 24800 case OPC_C0_C: 24801 case OPC_C0_D: 24802 case OPC_C0_E: 24803 case OPC_C0_F: 24804 #ifndef CONFIG_USER_ONLY 24805 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 24806 #endif /* !CONFIG_USER_ONLY */ 24807 break; 24808 case OPC_MFMC0: 24809 #ifndef CONFIG_USER_ONLY 24810 { 24811 uint32_t op2; 24812 TCGv t0 = tcg_temp_new(); 24813 24814 op2 = MASK_MFMC0(ctx->opcode); 24815 switch (op2) { 24816 case OPC_DMT: 24817 check_cp0_mt(ctx); 24818 gen_helper_dmt(t0); 24819 gen_store_gpr(t0, rt); 24820 break; 24821 case OPC_EMT: 24822 check_cp0_mt(ctx); 24823 gen_helper_emt(t0); 24824 gen_store_gpr(t0, rt); 24825 break; 24826 case OPC_DVPE: 24827 check_cp0_mt(ctx); 24828 gen_helper_dvpe(t0, cpu_env); 24829 gen_store_gpr(t0, rt); 24830 break; 24831 case OPC_EVPE: 24832 check_cp0_mt(ctx); 24833 gen_helper_evpe(t0, cpu_env); 24834 gen_store_gpr(t0, rt); 24835 break; 24836 case OPC_DVP: 24837 check_insn(ctx, ISA_MIPS_R6); 24838 if (ctx->vp) { 24839 gen_helper_dvp(t0, cpu_env); 24840 gen_store_gpr(t0, rt); 24841 } 24842 break; 24843 case OPC_EVP: 24844 check_insn(ctx, ISA_MIPS_R6); 24845 if (ctx->vp) { 24846 gen_helper_evp(t0, cpu_env); 24847 gen_store_gpr(t0, rt); 24848 } 24849 break; 24850 case OPC_DI: 24851 check_insn(ctx, ISA_MIPS_R2); 24852 save_cpu_state(ctx, 1); 24853 gen_helper_di(t0, cpu_env); 24854 gen_store_gpr(t0, rt); 24855 /* 24856 * Stop translation as we may have switched 24857 * the execution mode. 24858 */ 24859 ctx->base.is_jmp = DISAS_STOP; 24860 break; 24861 case OPC_EI: 24862 check_insn(ctx, ISA_MIPS_R2); 24863 save_cpu_state(ctx, 1); 24864 gen_helper_ei(t0, cpu_env); 24865 gen_store_gpr(t0, rt); 24866 /* 24867 * DISAS_STOP isn't sufficient, we need to ensure we break 24868 * out of translated code to check for pending interrupts. 24869 */ 24870 gen_save_pc(ctx->base.pc_next + 4); 24871 ctx->base.is_jmp = DISAS_EXIT; 24872 break; 24873 default: /* Invalid */ 24874 MIPS_INVAL("mfmc0"); 24875 gen_reserved_instruction(ctx); 24876 break; 24877 } 24878 tcg_temp_free(t0); 24879 } 24880 #endif /* !CONFIG_USER_ONLY */ 24881 break; 24882 case OPC_RDPGPR: 24883 check_insn(ctx, ISA_MIPS_R2); 24884 gen_load_srsgpr(rt, rd); 24885 break; 24886 case OPC_WRPGPR: 24887 check_insn(ctx, ISA_MIPS_R2); 24888 gen_store_srsgpr(rt, rd); 24889 break; 24890 default: 24891 MIPS_INVAL("cp0"); 24892 gen_reserved_instruction(ctx); 24893 break; 24894 } 24895 break; 24896 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 24897 if (ctx->insn_flags & ISA_MIPS_R6) { 24898 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 24899 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 24900 } else { 24901 /* OPC_ADDI */ 24902 /* Arithmetic with immediate opcode */ 24903 gen_arith_imm(ctx, op, rt, rs, imm); 24904 } 24905 break; 24906 case OPC_ADDIU: 24907 gen_arith_imm(ctx, op, rt, rs, imm); 24908 break; 24909 case OPC_SLTI: /* Set on less than with immediate opcode */ 24910 case OPC_SLTIU: 24911 gen_slt_imm(ctx, op, rt, rs, imm); 24912 break; 24913 case OPC_ANDI: /* Arithmetic with immediate opcode */ 24914 case OPC_LUI: /* OPC_AUI */ 24915 case OPC_ORI: 24916 case OPC_XORI: 24917 gen_logic_imm(ctx, op, rt, rs, imm); 24918 break; 24919 case OPC_J: /* Jump */ 24920 case OPC_JAL: 24921 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 24922 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 24923 break; 24924 /* Branch */ 24925 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 24926 if (ctx->insn_flags & ISA_MIPS_R6) { 24927 if (rt == 0) { 24928 gen_reserved_instruction(ctx); 24929 break; 24930 } 24931 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 24932 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 24933 } else { 24934 /* OPC_BLEZL */ 24935 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 24936 } 24937 break; 24938 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 24939 if (ctx->insn_flags & ISA_MIPS_R6) { 24940 if (rt == 0) { 24941 gen_reserved_instruction(ctx); 24942 break; 24943 } 24944 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 24945 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 24946 } else { 24947 /* OPC_BGTZL */ 24948 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 24949 } 24950 break; 24951 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 24952 if (rt == 0) { 24953 /* OPC_BLEZ */ 24954 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 24955 } else { 24956 check_insn(ctx, ISA_MIPS_R6); 24957 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 24958 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 24959 } 24960 break; 24961 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 24962 if (rt == 0) { 24963 /* OPC_BGTZ */ 24964 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 24965 } else { 24966 check_insn(ctx, ISA_MIPS_R6); 24967 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 24968 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 24969 } 24970 break; 24971 case OPC_BEQL: 24972 case OPC_BNEL: 24973 check_insn(ctx, ISA_MIPS2); 24974 check_insn_opc_removed(ctx, ISA_MIPS_R6); 24975 /* Fallthrough */ 24976 case OPC_BEQ: 24977 case OPC_BNE: 24978 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 24979 break; 24980 case OPC_LL: /* Load and stores */ 24981 check_insn(ctx, ISA_MIPS2); 24982 if (ctx->insn_flags & INSN_R5900) { 24983 check_insn_opc_user_only(ctx, INSN_R5900); 24984 } 24985 /* Fallthrough */ 24986 case OPC_LWL: 24987 case OPC_LWR: 24988 case OPC_LB: 24989 case OPC_LH: 24990 case OPC_LW: 24991 case OPC_LWPC: 24992 case OPC_LBU: 24993 case OPC_LHU: 24994 gen_ld(ctx, op, rt, rs, imm); 24995 break; 24996 case OPC_SWL: 24997 case OPC_SWR: 24998 case OPC_SB: 24999 case OPC_SH: 25000 case OPC_SW: 25001 gen_st(ctx, op, rt, rs, imm); 25002 break; 25003 case OPC_SC: 25004 check_insn(ctx, ISA_MIPS2); 25005 if (ctx->insn_flags & INSN_R5900) { 25006 check_insn_opc_user_only(ctx, INSN_R5900); 25007 } 25008 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 25009 break; 25010 case OPC_CACHE: 25011 check_cp0_enabled(ctx); 25012 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 25013 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 25014 gen_cache_operation(ctx, rt, rs, imm); 25015 } 25016 /* Treat as NOP. */ 25017 break; 25018 case OPC_PREF: 25019 if (ctx->insn_flags & INSN_R5900) { 25020 /* Treat as NOP. */ 25021 } else { 25022 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 25023 /* Treat as NOP. */ 25024 } 25025 break; 25026 25027 /* Floating point (COP1). */ 25028 case OPC_LWC1: 25029 case OPC_LDC1: 25030 case OPC_SWC1: 25031 case OPC_SDC1: 25032 gen_cop1_ldst(ctx, op, rt, rs, imm); 25033 break; 25034 25035 case OPC_CP1: 25036 op1 = MASK_CP1(ctx->opcode); 25037 25038 switch (op1) { 25039 case OPC_MFHC1: 25040 case OPC_MTHC1: 25041 check_cp1_enabled(ctx); 25042 check_insn(ctx, ISA_MIPS_R2); 25043 /* fall through */ 25044 case OPC_MFC1: 25045 case OPC_CFC1: 25046 case OPC_MTC1: 25047 case OPC_CTC1: 25048 check_cp1_enabled(ctx); 25049 gen_cp1(ctx, op1, rt, rd); 25050 break; 25051 #if defined(TARGET_MIPS64) 25052 case OPC_DMFC1: 25053 case OPC_DMTC1: 25054 check_cp1_enabled(ctx); 25055 check_insn(ctx, ISA_MIPS3); 25056 check_mips_64(ctx); 25057 gen_cp1(ctx, op1, rt, rd); 25058 break; 25059 #endif 25060 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 25061 check_cp1_enabled(ctx); 25062 if (ctx->insn_flags & ISA_MIPS_R6) { 25063 /* OPC_BC1EQZ */ 25064 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 25065 rt, imm << 2, 4); 25066 } else { 25067 /* OPC_BC1ANY2 */ 25068 check_cop1x(ctx); 25069 check_insn(ctx, ASE_MIPS3D); 25070 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 25071 (rt >> 2) & 0x7, imm << 2); 25072 } 25073 break; 25074 case OPC_BC1NEZ: 25075 check_cp1_enabled(ctx); 25076 check_insn(ctx, ISA_MIPS_R6); 25077 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 25078 rt, imm << 2, 4); 25079 break; 25080 case OPC_BC1ANY4: 25081 check_cp1_enabled(ctx); 25082 check_insn_opc_removed(ctx, ISA_MIPS_R6); 25083 check_cop1x(ctx); 25084 check_insn(ctx, ASE_MIPS3D); 25085 /* fall through */ 25086 case OPC_BC1: 25087 check_cp1_enabled(ctx); 25088 check_insn_opc_removed(ctx, ISA_MIPS_R6); 25089 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 25090 (rt >> 2) & 0x7, imm << 2); 25091 break; 25092 case OPC_PS_FMT: 25093 check_ps(ctx); 25094 /* fall through */ 25095 case OPC_S_FMT: 25096 case OPC_D_FMT: 25097 check_cp1_enabled(ctx); 25098 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 25099 (imm >> 8) & 0x7); 25100 break; 25101 case OPC_W_FMT: 25102 case OPC_L_FMT: 25103 { 25104 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 25105 check_cp1_enabled(ctx); 25106 if (ctx->insn_flags & ISA_MIPS_R6) { 25107 switch (r6_op) { 25108 case R6_OPC_CMP_AF_S: 25109 case R6_OPC_CMP_UN_S: 25110 case R6_OPC_CMP_EQ_S: 25111 case R6_OPC_CMP_UEQ_S: 25112 case R6_OPC_CMP_LT_S: 25113 case R6_OPC_CMP_ULT_S: 25114 case R6_OPC_CMP_LE_S: 25115 case R6_OPC_CMP_ULE_S: 25116 case R6_OPC_CMP_SAF_S: 25117 case R6_OPC_CMP_SUN_S: 25118 case R6_OPC_CMP_SEQ_S: 25119 case R6_OPC_CMP_SEUQ_S: 25120 case R6_OPC_CMP_SLT_S: 25121 case R6_OPC_CMP_SULT_S: 25122 case R6_OPC_CMP_SLE_S: 25123 case R6_OPC_CMP_SULE_S: 25124 case R6_OPC_CMP_OR_S: 25125 case R6_OPC_CMP_UNE_S: 25126 case R6_OPC_CMP_NE_S: 25127 case R6_OPC_CMP_SOR_S: 25128 case R6_OPC_CMP_SUNE_S: 25129 case R6_OPC_CMP_SNE_S: 25130 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 25131 break; 25132 case R6_OPC_CMP_AF_D: 25133 case R6_OPC_CMP_UN_D: 25134 case R6_OPC_CMP_EQ_D: 25135 case R6_OPC_CMP_UEQ_D: 25136 case R6_OPC_CMP_LT_D: 25137 case R6_OPC_CMP_ULT_D: 25138 case R6_OPC_CMP_LE_D: 25139 case R6_OPC_CMP_ULE_D: 25140 case R6_OPC_CMP_SAF_D: 25141 case R6_OPC_CMP_SUN_D: 25142 case R6_OPC_CMP_SEQ_D: 25143 case R6_OPC_CMP_SEUQ_D: 25144 case R6_OPC_CMP_SLT_D: 25145 case R6_OPC_CMP_SULT_D: 25146 case R6_OPC_CMP_SLE_D: 25147 case R6_OPC_CMP_SULE_D: 25148 case R6_OPC_CMP_OR_D: 25149 case R6_OPC_CMP_UNE_D: 25150 case R6_OPC_CMP_NE_D: 25151 case R6_OPC_CMP_SOR_D: 25152 case R6_OPC_CMP_SUNE_D: 25153 case R6_OPC_CMP_SNE_D: 25154 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 25155 break; 25156 default: 25157 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 25158 rt, rd, sa, (imm >> 8) & 0x7); 25159 25160 break; 25161 } 25162 } else { 25163 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 25164 (imm >> 8) & 0x7); 25165 } 25166 break; 25167 } 25168 default: 25169 MIPS_INVAL("cp1"); 25170 gen_reserved_instruction(ctx); 25171 break; 25172 } 25173 break; 25174 25175 /* Compact branches [R6] and COP2 [non-R6] */ 25176 case OPC_BC: /* OPC_LWC2 */ 25177 case OPC_BALC: /* OPC_SWC2 */ 25178 if (ctx->insn_flags & ISA_MIPS_R6) { 25179 /* OPC_BC, OPC_BALC */ 25180 gen_compute_compact_branch(ctx, op, 0, 0, 25181 sextract32(ctx->opcode << 2, 0, 28)); 25182 } else if (ctx->insn_flags & ASE_LEXT) { 25183 gen_loongson_lswc2(ctx, rt, rs, rd); 25184 } else { 25185 /* OPC_LWC2, OPC_SWC2 */ 25186 /* COP2: Not implemented. */ 25187 generate_exception_err(ctx, EXCP_CpU, 2); 25188 } 25189 break; 25190 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 25191 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 25192 if (ctx->insn_flags & ISA_MIPS_R6) { 25193 if (rs != 0) { 25194 /* OPC_BEQZC, OPC_BNEZC */ 25195 gen_compute_compact_branch(ctx, op, rs, 0, 25196 sextract32(ctx->opcode << 2, 0, 23)); 25197 } else { 25198 /* OPC_JIC, OPC_JIALC */ 25199 gen_compute_compact_branch(ctx, op, 0, rt, imm); 25200 } 25201 } else if (ctx->insn_flags & ASE_LEXT) { 25202 gen_loongson_lsdc2(ctx, rt, rs, rd); 25203 } else { 25204 /* OPC_LWC2, OPC_SWC2 */ 25205 /* COP2: Not implemented. */ 25206 generate_exception_err(ctx, EXCP_CpU, 2); 25207 } 25208 break; 25209 case OPC_CP2: 25210 check_insn(ctx, ASE_LMMI); 25211 /* Note that these instructions use different fields. */ 25212 gen_loongson_multimedia(ctx, sa, rd, rt); 25213 break; 25214 25215 case OPC_CP3: 25216 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 25217 check_cp1_enabled(ctx); 25218 op1 = MASK_CP3(ctx->opcode); 25219 switch (op1) { 25220 case OPC_LUXC1: 25221 case OPC_SUXC1: 25222 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 25223 /* Fallthrough */ 25224 case OPC_LWXC1: 25225 case OPC_LDXC1: 25226 case OPC_SWXC1: 25227 case OPC_SDXC1: 25228 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 25229 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 25230 break; 25231 case OPC_PREFX: 25232 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 25233 /* Treat as NOP. */ 25234 break; 25235 case OPC_ALNV_PS: 25236 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 25237 /* Fallthrough */ 25238 case OPC_MADD_S: 25239 case OPC_MADD_D: 25240 case OPC_MADD_PS: 25241 case OPC_MSUB_S: 25242 case OPC_MSUB_D: 25243 case OPC_MSUB_PS: 25244 case OPC_NMADD_S: 25245 case OPC_NMADD_D: 25246 case OPC_NMADD_PS: 25247 case OPC_NMSUB_S: 25248 case OPC_NMSUB_D: 25249 case OPC_NMSUB_PS: 25250 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 25251 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 25252 break; 25253 default: 25254 MIPS_INVAL("cp3"); 25255 gen_reserved_instruction(ctx); 25256 break; 25257 } 25258 } else { 25259 generate_exception_err(ctx, EXCP_CpU, 1); 25260 } 25261 break; 25262 25263 #if defined(TARGET_MIPS64) 25264 /* MIPS64 opcodes */ 25265 case OPC_LLD: 25266 if (ctx->insn_flags & INSN_R5900) { 25267 check_insn_opc_user_only(ctx, INSN_R5900); 25268 } 25269 /* fall through */ 25270 case OPC_LDL: 25271 case OPC_LDR: 25272 case OPC_LWU: 25273 case OPC_LD: 25274 check_insn(ctx, ISA_MIPS3); 25275 check_mips_64(ctx); 25276 gen_ld(ctx, op, rt, rs, imm); 25277 break; 25278 case OPC_SDL: 25279 case OPC_SDR: 25280 case OPC_SD: 25281 check_insn(ctx, ISA_MIPS3); 25282 check_mips_64(ctx); 25283 gen_st(ctx, op, rt, rs, imm); 25284 break; 25285 case OPC_SCD: 25286 check_insn(ctx, ISA_MIPS3); 25287 if (ctx->insn_flags & INSN_R5900) { 25288 check_insn_opc_user_only(ctx, INSN_R5900); 25289 } 25290 check_mips_64(ctx); 25291 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 25292 break; 25293 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 25294 if (ctx->insn_flags & ISA_MIPS_R6) { 25295 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 25296 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 25297 } else { 25298 /* OPC_DADDI */ 25299 check_insn(ctx, ISA_MIPS3); 25300 check_mips_64(ctx); 25301 gen_arith_imm(ctx, op, rt, rs, imm); 25302 } 25303 break; 25304 case OPC_DADDIU: 25305 check_insn(ctx, ISA_MIPS3); 25306 check_mips_64(ctx); 25307 gen_arith_imm(ctx, op, rt, rs, imm); 25308 break; 25309 #else 25310 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 25311 if (ctx->insn_flags & ISA_MIPS_R6) { 25312 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 25313 } else { 25314 MIPS_INVAL("major opcode"); 25315 gen_reserved_instruction(ctx); 25316 } 25317 break; 25318 #endif 25319 case OPC_DAUI: /* OPC_JALX */ 25320 if (ctx->insn_flags & ISA_MIPS_R6) { 25321 #if defined(TARGET_MIPS64) 25322 /* OPC_DAUI */ 25323 check_mips_64(ctx); 25324 if (rs == 0) { 25325 generate_exception(ctx, EXCP_RI); 25326 } else if (rt != 0) { 25327 TCGv t0 = tcg_temp_new(); 25328 gen_load_gpr(t0, rs); 25329 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 25330 tcg_temp_free(t0); 25331 } 25332 #else 25333 gen_reserved_instruction(ctx); 25334 MIPS_INVAL("major opcode"); 25335 #endif 25336 } else { 25337 /* OPC_JALX */ 25338 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 25339 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 25340 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 25341 } 25342 break; 25343 case OPC_MDMX: /* MMI_OPC_LQ */ 25344 if (ctx->insn_flags & INSN_R5900) { 25345 #if defined(TARGET_MIPS64) 25346 gen_mmi_lq(env, ctx); 25347 #endif 25348 } else { 25349 /* MDMX: Not implemented. */ 25350 } 25351 break; 25352 case OPC_PCREL: 25353 check_insn(ctx, ISA_MIPS_R6); 25354 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 25355 break; 25356 default: /* Invalid */ 25357 MIPS_INVAL("major opcode"); 25358 return false; 25359 } 25360 return true; 25361 } 25362 25363 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 25364 { 25365 /* make sure instructions are on a word boundary */ 25366 if (ctx->base.pc_next & 0x3) { 25367 env->CP0_BadVAddr = ctx->base.pc_next; 25368 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 25369 return; 25370 } 25371 25372 /* Handle blikely not taken case */ 25373 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 25374 TCGLabel *l1 = gen_new_label(); 25375 25376 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 25377 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 25378 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 25379 gen_set_label(l1); 25380 } 25381 25382 /* Transition to the auto-generated decoder. */ 25383 25384 /* ISA extensions */ 25385 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 25386 return; 25387 } 25388 25389 /* ISA (from latest to oldest) */ 25390 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 25391 return; 25392 } 25393 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 25394 return; 25395 } 25396 25397 if (decode_opc_legacy(env, ctx)) { 25398 return; 25399 } 25400 25401 gen_reserved_instruction(ctx); 25402 } 25403 25404 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 25405 { 25406 DisasContext *ctx = container_of(dcbase, DisasContext, base); 25407 CPUMIPSState *env = cs->env_ptr; 25408 25409 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 25410 ctx->saved_pc = -1; 25411 ctx->insn_flags = env->insn_flags; 25412 ctx->CP0_Config1 = env->CP0_Config1; 25413 ctx->CP0_Config2 = env->CP0_Config2; 25414 ctx->CP0_Config3 = env->CP0_Config3; 25415 ctx->CP0_Config5 = env->CP0_Config5; 25416 ctx->btarget = 0; 25417 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 25418 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 25419 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 25420 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 25421 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 25422 ctx->PAMask = env->PAMask; 25423 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 25424 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 25425 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 25426 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 25427 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 25428 /* Restore delay slot state from the tb context. */ 25429 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 25430 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 25431 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 25432 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 25433 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 25434 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 25435 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 25436 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 25437 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 25438 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 25439 restore_cpu_state(env, ctx); 25440 #ifdef CONFIG_USER_ONLY 25441 ctx->mem_idx = MIPS_HFLAG_UM; 25442 #else 25443 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 25444 #endif 25445 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 | 25446 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; 25447 25448 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 25449 ctx->hflags); 25450 } 25451 25452 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 25453 { 25454 } 25455 25456 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 25457 { 25458 DisasContext *ctx = container_of(dcbase, DisasContext, base); 25459 25460 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 25461 ctx->btarget); 25462 } 25463 25464 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 25465 const CPUBreakpoint *bp) 25466 { 25467 DisasContext *ctx = container_of(dcbase, DisasContext, base); 25468 25469 save_cpu_state(ctx, 1); 25470 ctx->base.is_jmp = DISAS_NORETURN; 25471 gen_helper_raise_exception_debug(cpu_env); 25472 /* 25473 * The address covered by the breakpoint must be included in 25474 * [tb->pc, tb->pc + tb->size) in order to for it to be 25475 * properly cleared -- thus we increment the PC here so that 25476 * the logic setting tb->size below does the right thing. 25477 */ 25478 ctx->base.pc_next += 4; 25479 return true; 25480 } 25481 25482 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 25483 { 25484 CPUMIPSState *env = cs->env_ptr; 25485 DisasContext *ctx = container_of(dcbase, DisasContext, base); 25486 int insn_bytes; 25487 int is_slot; 25488 25489 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 25490 if (ctx->insn_flags & ISA_NANOMIPS32) { 25491 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 25492 insn_bytes = decode_nanomips_opc(env, ctx); 25493 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 25494 ctx->opcode = translator_ldl(env, ctx->base.pc_next); 25495 insn_bytes = 4; 25496 decode_opc(env, ctx); 25497 } else if (ctx->insn_flags & ASE_MICROMIPS) { 25498 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 25499 insn_bytes = decode_micromips_opc(env, ctx); 25500 } else if (ctx->insn_flags & ASE_MIPS16) { 25501 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 25502 insn_bytes = decode_mips16_opc(env, ctx); 25503 } else { 25504 gen_reserved_instruction(ctx); 25505 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 25506 return; 25507 } 25508 25509 if (ctx->hflags & MIPS_HFLAG_BMASK) { 25510 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 25511 MIPS_HFLAG_FBNSLOT))) { 25512 /* 25513 * Force to generate branch as there is neither delay nor 25514 * forbidden slot. 25515 */ 25516 is_slot = 1; 25517 } 25518 if ((ctx->hflags & MIPS_HFLAG_M16) && 25519 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 25520 /* 25521 * Force to generate branch as microMIPS R6 doesn't restrict 25522 * branches in the forbidden slot. 25523 */ 25524 is_slot = 1; 25525 } 25526 } 25527 if (is_slot) { 25528 gen_branch(ctx, insn_bytes); 25529 } 25530 ctx->base.pc_next += insn_bytes; 25531 25532 if (ctx->base.is_jmp != DISAS_NEXT) { 25533 return; 25534 } 25535 /* 25536 * Execute a branch and its delay slot as a single instruction. 25537 * This is what GDB expects and is consistent with what the 25538 * hardware does (e.g. if a delay slot instruction faults, the 25539 * reported PC is the PC of the branch). 25540 */ 25541 if (ctx->base.singlestep_enabled && 25542 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) { 25543 ctx->base.is_jmp = DISAS_TOO_MANY; 25544 } 25545 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) { 25546 ctx->base.is_jmp = DISAS_TOO_MANY; 25547 } 25548 } 25549 25550 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 25551 { 25552 DisasContext *ctx = container_of(dcbase, DisasContext, base); 25553 25554 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { 25555 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); 25556 gen_helper_raise_exception_debug(cpu_env); 25557 } else { 25558 switch (ctx->base.is_jmp) { 25559 case DISAS_STOP: 25560 gen_save_pc(ctx->base.pc_next); 25561 tcg_gen_lookup_and_goto_ptr(); 25562 break; 25563 case DISAS_NEXT: 25564 case DISAS_TOO_MANY: 25565 save_cpu_state(ctx, 0); 25566 gen_goto_tb(ctx, 0, ctx->base.pc_next); 25567 break; 25568 case DISAS_EXIT: 25569 tcg_gen_exit_tb(NULL, 0); 25570 break; 25571 case DISAS_NORETURN: 25572 break; 25573 default: 25574 g_assert_not_reached(); 25575 } 25576 } 25577 } 25578 25579 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 25580 { 25581 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 25582 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 25583 } 25584 25585 static const TranslatorOps mips_tr_ops = { 25586 .init_disas_context = mips_tr_init_disas_context, 25587 .tb_start = mips_tr_tb_start, 25588 .insn_start = mips_tr_insn_start, 25589 .breakpoint_check = mips_tr_breakpoint_check, 25590 .translate_insn = mips_tr_translate_insn, 25591 .tb_stop = mips_tr_tb_stop, 25592 .disas_log = mips_tr_disas_log, 25593 }; 25594 25595 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 25596 { 25597 DisasContext ctx; 25598 25599 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns); 25600 } 25601 25602 void mips_tcg_init(void) 25603 { 25604 int i; 25605 25606 cpu_gpr[0] = NULL; 25607 for (i = 1; i < 32; i++) 25608 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 25609 offsetof(CPUMIPSState, 25610 active_tc.gpr[i]), 25611 regnames[i]); 25612 #if defined(TARGET_MIPS64) 25613 cpu_gpr_hi[0] = NULL; 25614 25615 for (unsigned i = 1; i < 32; i++) { 25616 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 25617 25618 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 25619 offsetof(CPUMIPSState, 25620 active_tc.gpr_hi[i]), 25621 rname); 25622 } 25623 #endif /* !TARGET_MIPS64 */ 25624 for (i = 0; i < 32; i++) { 25625 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 25626 25627 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 25628 } 25629 msa_translate_init(); 25630 cpu_PC = tcg_global_mem_new(cpu_env, 25631 offsetof(CPUMIPSState, active_tc.PC), "PC"); 25632 for (i = 0; i < MIPS_DSP_ACC; i++) { 25633 cpu_HI[i] = tcg_global_mem_new(cpu_env, 25634 offsetof(CPUMIPSState, active_tc.HI[i]), 25635 regnames_HI[i]); 25636 cpu_LO[i] = tcg_global_mem_new(cpu_env, 25637 offsetof(CPUMIPSState, active_tc.LO[i]), 25638 regnames_LO[i]); 25639 } 25640 cpu_dspctrl = tcg_global_mem_new(cpu_env, 25641 offsetof(CPUMIPSState, 25642 active_tc.DSPControl), 25643 "DSPControl"); 25644 bcond = tcg_global_mem_new(cpu_env, 25645 offsetof(CPUMIPSState, bcond), "bcond"); 25646 btarget = tcg_global_mem_new(cpu_env, 25647 offsetof(CPUMIPSState, btarget), "btarget"); 25648 hflags = tcg_global_mem_new_i32(cpu_env, 25649 offsetof(CPUMIPSState, hflags), "hflags"); 25650 25651 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 25652 offsetof(CPUMIPSState, active_fpu.fcr0), 25653 "fcr0"); 25654 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 25655 offsetof(CPUMIPSState, active_fpu.fcr31), 25656 "fcr31"); 25657 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 25658 "lladdr"); 25659 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 25660 "llval"); 25661 25662 if (TARGET_LONG_BITS == 32) { 25663 mxu_translate_init(); 25664 } 25665 } 25666 25667 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, 25668 target_ulong *data) 25669 { 25670 env->active_tc.PC = data[0]; 25671 env->hflags &= ~MIPS_HFLAG_BMASK; 25672 env->hflags |= data[1]; 25673 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 25674 case MIPS_HFLAG_BR: 25675 break; 25676 case MIPS_HFLAG_BC: 25677 case MIPS_HFLAG_BL: 25678 case MIPS_HFLAG_B: 25679 env->btarget = data[2]; 25680 break; 25681 } 25682 } 25683