1 /* 2 * MIPS emulation for QEMU - main translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "translate.h" 27 #include "internal.h" 28 #include "exec/helper-proto.h" 29 #include "exec/translation-block.h" 30 #include "semihosting/semihost.h" 31 #include "trace.h" 32 #include "fpu_helper.h" 33 34 #define HELPER_H "helper.h" 35 #include "exec/helper-info.c.inc" 36 #undef HELPER_H 37 38 39 /* 40 * Many sysemu-only helpers are not reachable for user-only. 41 * Define stub generators here, so that we need not either sprinkle 42 * ifdefs through the translator, nor provide the helper function. 43 */ 44 #define STUB_HELPER(NAME, ...) \ 45 static inline void gen_helper_##NAME(__VA_ARGS__) \ 46 { g_assert_not_reached(); } 47 48 #ifdef CONFIG_USER_ONLY 49 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 50 #endif 51 52 enum { 53 /* indirect opcode tables */ 54 OPC_SPECIAL = (0x00 << 26), 55 OPC_REGIMM = (0x01 << 26), 56 OPC_CP0 = (0x10 << 26), 57 OPC_CP2 = (0x12 << 26), 58 OPC_CP3 = (0x13 << 26), 59 OPC_SPECIAL2 = (0x1C << 26), 60 OPC_SPECIAL3 = (0x1F << 26), 61 /* arithmetic with immediate */ 62 OPC_ADDI = (0x08 << 26), 63 OPC_ADDIU = (0x09 << 26), 64 OPC_SLTI = (0x0A << 26), 65 OPC_SLTIU = (0x0B << 26), 66 /* logic with immediate */ 67 OPC_ANDI = (0x0C << 26), 68 OPC_ORI = (0x0D << 26), 69 OPC_XORI = (0x0E << 26), 70 OPC_LUI = (0x0F << 26), 71 /* arithmetic with immediate */ 72 OPC_DADDI = (0x18 << 26), 73 OPC_DADDIU = (0x19 << 26), 74 /* Jump and branches */ 75 OPC_J = (0x02 << 26), 76 OPC_JAL = (0x03 << 26), 77 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 78 OPC_BEQL = (0x14 << 26), 79 OPC_BNE = (0x05 << 26), 80 OPC_BNEL = (0x15 << 26), 81 OPC_BLEZ = (0x06 << 26), 82 OPC_BLEZL = (0x16 << 26), 83 OPC_BGTZ = (0x07 << 26), 84 OPC_BGTZL = (0x17 << 26), 85 OPC_JALX = (0x1D << 26), 86 OPC_DAUI = (0x1D << 26), 87 /* Load and stores */ 88 OPC_LDL = (0x1A << 26), 89 OPC_LDR = (0x1B << 26), 90 OPC_LB = (0x20 << 26), 91 OPC_LH = (0x21 << 26), 92 OPC_LWL = (0x22 << 26), 93 OPC_LW = (0x23 << 26), 94 OPC_LWPC = OPC_LW | 0x5, 95 OPC_LBU = (0x24 << 26), 96 OPC_LHU = (0x25 << 26), 97 OPC_LWR = (0x26 << 26), 98 OPC_LWU = (0x27 << 26), 99 OPC_SB = (0x28 << 26), 100 OPC_SH = (0x29 << 26), 101 OPC_SWL = (0x2A << 26), 102 OPC_SW = (0x2B << 26), 103 OPC_SDL = (0x2C << 26), 104 OPC_SDR = (0x2D << 26), 105 OPC_SWR = (0x2E << 26), 106 OPC_LL = (0x30 << 26), 107 OPC_LLD = (0x34 << 26), 108 OPC_LD = (0x37 << 26), 109 OPC_LDPC = OPC_LD | 0x5, 110 OPC_SC = (0x38 << 26), 111 OPC_SCD = (0x3C << 26), 112 OPC_SD = (0x3F << 26), 113 /* Floating point load/store */ 114 OPC_LWC1 = (0x31 << 26), 115 OPC_LWC2 = (0x32 << 26), 116 OPC_LDC1 = (0x35 << 26), 117 OPC_LDC2 = (0x36 << 26), 118 OPC_SWC1 = (0x39 << 26), 119 OPC_SWC2 = (0x3A << 26), 120 OPC_SDC1 = (0x3D << 26), 121 OPC_SDC2 = (0x3E << 26), 122 /* Compact Branches */ 123 OPC_BLEZALC = (0x06 << 26), 124 OPC_BGEZALC = (0x06 << 26), 125 OPC_BGEUC = (0x06 << 26), 126 OPC_BGTZALC = (0x07 << 26), 127 OPC_BLTZALC = (0x07 << 26), 128 OPC_BLTUC = (0x07 << 26), 129 OPC_BOVC = (0x08 << 26), 130 OPC_BEQZALC = (0x08 << 26), 131 OPC_BEQC = (0x08 << 26), 132 OPC_BLEZC = (0x16 << 26), 133 OPC_BGEZC = (0x16 << 26), 134 OPC_BGEC = (0x16 << 26), 135 OPC_BGTZC = (0x17 << 26), 136 OPC_BLTZC = (0x17 << 26), 137 OPC_BLTC = (0x17 << 26), 138 OPC_BNVC = (0x18 << 26), 139 OPC_BNEZALC = (0x18 << 26), 140 OPC_BNEC = (0x18 << 26), 141 OPC_BC = (0x32 << 26), 142 OPC_BEQZC = (0x36 << 26), 143 OPC_JIC = (0x36 << 26), 144 OPC_BALC = (0x3A << 26), 145 OPC_BNEZC = (0x3E << 26), 146 OPC_JIALC = (0x3E << 26), 147 /* MDMX ASE specific */ 148 OPC_MDMX = (0x1E << 26), 149 /* Cache and prefetch */ 150 OPC_CACHE = (0x2F << 26), 151 OPC_PREF = (0x33 << 26), 152 /* PC-relative address computation / loads */ 153 OPC_PCREL = (0x3B << 26), 154 }; 155 156 /* PC-relative address computation / loads */ 157 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 158 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 159 enum { 160 /* Instructions determined by bits 19 and 20 */ 161 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 162 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 163 OPC_LWUPC = OPC_PCREL | (2 << 19), 164 165 /* Instructions determined by bits 16 ... 20 */ 166 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 167 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 168 169 /* Other */ 170 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 171 }; 172 173 /* MIPS special opcodes */ 174 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 175 176 enum { 177 /* Shifts */ 178 OPC_SLL = 0x00 | OPC_SPECIAL, 179 /* NOP is SLL r0, r0, 0 */ 180 /* SSNOP is SLL r0, r0, 1 */ 181 /* EHB is SLL r0, r0, 3 */ 182 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 183 OPC_ROTR = OPC_SRL | (1 << 21), 184 OPC_SRA = 0x03 | OPC_SPECIAL, 185 OPC_SLLV = 0x04 | OPC_SPECIAL, 186 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 187 OPC_ROTRV = OPC_SRLV | (1 << 6), 188 OPC_SRAV = 0x07 | OPC_SPECIAL, 189 OPC_DSLLV = 0x14 | OPC_SPECIAL, 190 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 191 OPC_DROTRV = OPC_DSRLV | (1 << 6), 192 OPC_DSRAV = 0x17 | OPC_SPECIAL, 193 OPC_DSLL = 0x38 | OPC_SPECIAL, 194 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 195 OPC_DROTR = OPC_DSRL | (1 << 21), 196 OPC_DSRA = 0x3B | OPC_SPECIAL, 197 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 198 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 199 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 200 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 201 /* Multiplication / division */ 202 OPC_MULT = 0x18 | OPC_SPECIAL, 203 OPC_MULTU = 0x19 | OPC_SPECIAL, 204 OPC_DIV = 0x1A | OPC_SPECIAL, 205 OPC_DIVU = 0x1B | OPC_SPECIAL, 206 OPC_DMULT = 0x1C | OPC_SPECIAL, 207 OPC_DMULTU = 0x1D | OPC_SPECIAL, 208 OPC_DDIV = 0x1E | OPC_SPECIAL, 209 OPC_DDIVU = 0x1F | OPC_SPECIAL, 210 211 /* 2 registers arithmetic / logic */ 212 OPC_ADD = 0x20 | OPC_SPECIAL, 213 OPC_ADDU = 0x21 | OPC_SPECIAL, 214 OPC_SUB = 0x22 | OPC_SPECIAL, 215 OPC_SUBU = 0x23 | OPC_SPECIAL, 216 OPC_AND = 0x24 | OPC_SPECIAL, 217 OPC_OR = 0x25 | OPC_SPECIAL, 218 OPC_XOR = 0x26 | OPC_SPECIAL, 219 OPC_NOR = 0x27 | OPC_SPECIAL, 220 OPC_SLT = 0x2A | OPC_SPECIAL, 221 OPC_SLTU = 0x2B | OPC_SPECIAL, 222 OPC_DADD = 0x2C | OPC_SPECIAL, 223 OPC_DADDU = 0x2D | OPC_SPECIAL, 224 OPC_DSUB = 0x2E | OPC_SPECIAL, 225 OPC_DSUBU = 0x2F | OPC_SPECIAL, 226 /* Jumps */ 227 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 228 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 229 /* Traps */ 230 OPC_TGE = 0x30 | OPC_SPECIAL, 231 OPC_TGEU = 0x31 | OPC_SPECIAL, 232 OPC_TLT = 0x32 | OPC_SPECIAL, 233 OPC_TLTU = 0x33 | OPC_SPECIAL, 234 OPC_TEQ = 0x34 | OPC_SPECIAL, 235 OPC_TNE = 0x36 | OPC_SPECIAL, 236 /* HI / LO registers load & stores */ 237 OPC_MFHI = 0x10 | OPC_SPECIAL, 238 OPC_MTHI = 0x11 | OPC_SPECIAL, 239 OPC_MFLO = 0x12 | OPC_SPECIAL, 240 OPC_MTLO = 0x13 | OPC_SPECIAL, 241 /* Conditional moves */ 242 OPC_MOVZ = 0x0A | OPC_SPECIAL, 243 OPC_MOVN = 0x0B | OPC_SPECIAL, 244 245 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 246 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 247 248 OPC_MOVCI = 0x01 | OPC_SPECIAL, 249 250 /* Special */ 251 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 252 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 253 OPC_BREAK = 0x0D | OPC_SPECIAL, 254 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 255 OPC_SYNC = 0x0F | OPC_SPECIAL, 256 257 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 258 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 259 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 260 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 261 }; 262 263 /* 264 * R6 Multiply and Divide instructions have the same opcode 265 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 266 */ 267 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 268 269 enum { 270 R6_OPC_MUL = OPC_MULT | (2 << 6), 271 R6_OPC_MUH = OPC_MULT | (3 << 6), 272 R6_OPC_MULU = OPC_MULTU | (2 << 6), 273 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 274 R6_OPC_DIV = OPC_DIV | (2 << 6), 275 R6_OPC_MOD = OPC_DIV | (3 << 6), 276 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 277 R6_OPC_MODU = OPC_DIVU | (3 << 6), 278 279 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 280 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 281 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 282 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 283 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 284 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 285 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 286 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 287 288 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 289 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 290 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 291 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 292 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 293 }; 294 295 /* REGIMM (rt field) opcodes */ 296 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 297 298 enum { 299 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 300 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 301 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 302 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 303 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 304 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 305 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 306 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 307 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 308 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 309 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 310 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 311 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 312 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 313 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 314 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 315 316 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 317 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 318 }; 319 320 /* Special2 opcodes */ 321 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 322 323 enum { 324 /* Multiply & xxx operations */ 325 OPC_MADD = 0x00 | OPC_SPECIAL2, 326 OPC_MADDU = 0x01 | OPC_SPECIAL2, 327 OPC_MUL = 0x02 | OPC_SPECIAL2, 328 OPC_MSUB = 0x04 | OPC_SPECIAL2, 329 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 330 /* Loongson 2F */ 331 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 332 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 333 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 334 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 335 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 336 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 337 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 338 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 339 /* Misc */ 340 OPC_CLZ = 0x20 | OPC_SPECIAL2, 341 OPC_CLO = 0x21 | OPC_SPECIAL2, 342 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 343 OPC_DCLO = 0x25 | OPC_SPECIAL2, 344 /* Special */ 345 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 346 }; 347 348 /* Special3 opcodes */ 349 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 350 351 enum { 352 OPC_EXT = 0x00 | OPC_SPECIAL3, 353 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 354 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 355 OPC_DEXT = 0x03 | OPC_SPECIAL3, 356 OPC_INS = 0x04 | OPC_SPECIAL3, 357 OPC_DINSM = 0x05 | OPC_SPECIAL3, 358 OPC_DINSU = 0x06 | OPC_SPECIAL3, 359 OPC_DINS = 0x07 | OPC_SPECIAL3, 360 OPC_FORK = 0x08 | OPC_SPECIAL3, 361 OPC_YIELD = 0x09 | OPC_SPECIAL3, 362 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 363 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 364 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 365 OPC_GINV = 0x3D | OPC_SPECIAL3, 366 367 /* Loongson 2E */ 368 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 369 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 370 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 371 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 372 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 373 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 374 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 375 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 376 377 /* MIPS DSP Load */ 378 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 379 /* MIPS DSP Arithmetic */ 380 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 381 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 382 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 383 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 384 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 385 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 386 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 387 /* MIPS DSP GPR-Based Shift Sub-class */ 388 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 389 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 390 /* MIPS DSP Multiply Sub-class insns */ 391 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 392 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 393 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 394 /* DSP Bit/Manipulation Sub-class */ 395 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 396 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 397 /* MIPS DSP Append Sub-class */ 398 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 399 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 400 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 401 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 402 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 403 404 /* EVA */ 405 OPC_LWLE = 0x19 | OPC_SPECIAL3, 406 OPC_LWRE = 0x1A | OPC_SPECIAL3, 407 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 408 OPC_SBE = 0x1C | OPC_SPECIAL3, 409 OPC_SHE = 0x1D | OPC_SPECIAL3, 410 OPC_SCE = 0x1E | OPC_SPECIAL3, 411 OPC_SWE = 0x1F | OPC_SPECIAL3, 412 OPC_SWLE = 0x21 | OPC_SPECIAL3, 413 OPC_SWRE = 0x22 | OPC_SPECIAL3, 414 OPC_PREFE = 0x23 | OPC_SPECIAL3, 415 OPC_LBUE = 0x28 | OPC_SPECIAL3, 416 OPC_LHUE = 0x29 | OPC_SPECIAL3, 417 OPC_LBE = 0x2C | OPC_SPECIAL3, 418 OPC_LHE = 0x2D | OPC_SPECIAL3, 419 OPC_LLE = 0x2E | OPC_SPECIAL3, 420 OPC_LWE = 0x2F | OPC_SPECIAL3, 421 422 /* R6 */ 423 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 424 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 425 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 426 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 427 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 428 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 429 }; 430 431 /* Loongson EXT load/store quad word opcodes */ 432 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 433 enum { 434 OPC_GSLQ = 0x0020 | OPC_LWC2, 435 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 436 OPC_GSSHFL = OPC_LWC2, 437 OPC_GSSQ = 0x0020 | OPC_SWC2, 438 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 439 OPC_GSSHFS = OPC_SWC2, 440 }; 441 442 /* Loongson EXT shifted load/store opcodes */ 443 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 444 enum { 445 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 446 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 447 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 448 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 449 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 450 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 451 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 452 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 453 }; 454 455 /* Loongson EXT LDC2/SDC2 opcodes */ 456 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 457 458 enum { 459 OPC_GSLBX = 0x0 | OPC_LDC2, 460 OPC_GSLHX = 0x1 | OPC_LDC2, 461 OPC_GSLWX = 0x2 | OPC_LDC2, 462 OPC_GSLDX = 0x3 | OPC_LDC2, 463 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 464 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 465 OPC_GSSBX = 0x0 | OPC_SDC2, 466 OPC_GSSHX = 0x1 | OPC_SDC2, 467 OPC_GSSWX = 0x2 | OPC_SDC2, 468 OPC_GSSDX = 0x3 | OPC_SDC2, 469 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 470 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 471 }; 472 473 /* BSHFL opcodes */ 474 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 475 476 enum { 477 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 478 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 479 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 480 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 481 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 482 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 483 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 484 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 485 }; 486 487 /* DBSHFL opcodes */ 488 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 489 490 enum { 491 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 492 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 493 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 494 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 495 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 496 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 497 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 498 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 499 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 500 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 501 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 502 }; 503 504 /* MIPS DSP REGIMM opcodes */ 505 enum { 506 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 507 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 508 }; 509 510 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 511 /* MIPS DSP Load */ 512 enum { 513 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 514 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 515 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 516 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 517 }; 518 519 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 520 enum { 521 /* MIPS DSP Arithmetic Sub-class */ 522 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 523 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 524 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 525 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 526 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 527 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 528 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 529 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 530 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 531 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 532 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 533 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 534 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 535 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 536 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 537 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 538 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 539 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 540 /* MIPS DSP Multiply Sub-class insns */ 541 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 542 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 543 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 544 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 545 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 546 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 547 }; 548 549 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 550 enum { 551 /* MIPS DSP Arithmetic Sub-class */ 552 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 553 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 554 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 555 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 556 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 557 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 558 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 559 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 560 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 561 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 562 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 563 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 564 /* MIPS DSP Multiply Sub-class insns */ 565 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 566 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 567 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 568 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 569 }; 570 571 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 572 enum { 573 /* MIPS DSP Arithmetic Sub-class */ 574 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 575 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 576 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 577 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 578 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 579 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 580 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 581 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 582 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 583 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 584 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 585 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 586 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 587 /* DSP Bit/Manipulation Sub-class */ 588 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 589 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 590 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 591 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 592 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 593 }; 594 595 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 596 enum { 597 /* MIPS DSP Arithmetic Sub-class */ 598 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 602 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 603 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 604 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 605 /* DSP Compare-Pick Sub-class */ 606 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 607 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 608 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 609 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 610 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 611 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 612 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 613 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 614 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 615 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 616 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 617 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 618 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 619 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 620 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 621 }; 622 623 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 624 enum { 625 /* MIPS DSP GPR-Based Shift Sub-class */ 626 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 629 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 630 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 631 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 632 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 633 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 634 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 635 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 636 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 637 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 638 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 639 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 640 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 641 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 642 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 643 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 644 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 645 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 646 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 647 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 648 }; 649 650 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 651 enum { 652 /* MIPS DSP Multiply Sub-class insns */ 653 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 654 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 656 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 657 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 658 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 659 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 660 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 661 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 662 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 663 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 664 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 665 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 666 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 667 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 668 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 669 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 670 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 671 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 672 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 673 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 674 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 675 }; 676 677 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 678 enum { 679 /* DSP Bit/Manipulation Sub-class */ 680 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 681 }; 682 683 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 684 enum { 685 /* MIPS DSP Append Sub-class */ 686 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 687 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 688 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 689 }; 690 691 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 692 enum { 693 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 694 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 695 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 696 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 697 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 698 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 699 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 700 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 701 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 702 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 703 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 704 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 705 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 706 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 707 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 708 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 709 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 710 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 711 }; 712 713 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 714 enum { 715 /* MIPS DSP Arithmetic Sub-class */ 716 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 721 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 722 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 723 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 724 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 725 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 726 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 727 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 728 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 729 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 730 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 731 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 732 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 733 /* DSP Bit/Manipulation Sub-class */ 734 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 735 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 736 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 737 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 738 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 739 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 740 }; 741 742 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 743 enum { 744 /* MIPS DSP Multiply Sub-class insns */ 745 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 746 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 747 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 748 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 749 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 750 /* MIPS DSP Arithmetic Sub-class */ 751 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 752 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 753 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 754 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 755 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 756 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 757 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 758 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 759 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 760 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 761 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 762 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 763 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 764 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 765 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 766 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 767 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 768 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 769 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 770 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 771 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 772 }; 773 774 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 775 enum { 776 /* DSP Compare-Pick Sub-class */ 777 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 778 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 779 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 786 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 787 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 788 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 789 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 790 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 791 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 792 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 793 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 794 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 795 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 796 /* MIPS DSP Arithmetic Sub-class */ 797 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 798 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 799 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 800 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 801 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 802 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 803 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 804 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 805 }; 806 807 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 808 enum { 809 /* DSP Append Sub-class */ 810 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 811 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 812 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 813 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 814 }; 815 816 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 817 enum { 818 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 819 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 820 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 821 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 822 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 823 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 824 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 825 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 826 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 827 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 828 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 829 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 830 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 831 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 832 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 833 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 834 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 835 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 836 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 837 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 838 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 839 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 840 }; 841 842 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 843 enum { 844 /* DSP Bit/Manipulation Sub-class */ 845 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 846 }; 847 848 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 849 enum { 850 /* MIPS DSP Multiply Sub-class insns */ 851 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 858 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 859 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 860 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 861 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 862 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 863 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 864 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 865 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 866 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 867 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 868 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 869 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 870 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 871 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 872 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 873 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 874 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 875 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 876 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 877 }; 878 879 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 880 enum { 881 /* MIPS DSP GPR-Based Shift Sub-class */ 882 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 889 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 890 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 891 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 892 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 893 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 894 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 895 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 896 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 897 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 898 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 899 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 900 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 901 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 902 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 903 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 904 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 905 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 906 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 907 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 908 }; 909 910 /* Coprocessor 0 (rs field) */ 911 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 912 913 enum { 914 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 915 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 916 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 917 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 918 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 919 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 920 OPC_MFTR = (0x08 << 21) | OPC_CP0, 921 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 922 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 923 OPC_MTTR = (0x0C << 21) | OPC_CP0, 924 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 925 OPC_C0 = (0x10 << 21) | OPC_CP0, 926 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 927 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 928 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 929 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 930 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 931 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 932 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 933 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 934 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 935 OPC_C0_A = (0x1A << 21) | OPC_CP0, 936 OPC_C0_B = (0x1B << 21) | OPC_CP0, 937 OPC_C0_C = (0x1C << 21) | OPC_CP0, 938 OPC_C0_D = (0x1D << 21) | OPC_CP0, 939 OPC_C0_E = (0x1E << 21) | OPC_CP0, 940 OPC_C0_F = (0x1F << 21) | OPC_CP0, 941 }; 942 943 /* MFMC0 opcodes */ 944 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 945 946 enum { 947 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 948 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 949 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 950 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 951 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 952 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 953 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 954 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 955 }; 956 957 /* Coprocessor 0 (with rs == C0) */ 958 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 959 960 enum { 961 OPC_TLBR = 0x01 | OPC_C0, 962 OPC_TLBWI = 0x02 | OPC_C0, 963 OPC_TLBINV = 0x03 | OPC_C0, 964 OPC_TLBINVF = 0x04 | OPC_C0, 965 OPC_TLBWR = 0x06 | OPC_C0, 966 OPC_TLBP = 0x08 | OPC_C0, 967 OPC_RFE = 0x10 | OPC_C0, 968 OPC_ERET = 0x18 | OPC_C0, 969 OPC_DERET = 0x1F | OPC_C0, 970 OPC_WAIT = 0x20 | OPC_C0, 971 }; 972 973 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 974 975 enum { 976 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 977 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 978 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 979 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 980 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 981 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 982 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 983 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 984 OPC_BC2 = (0x08 << 21) | OPC_CP2, 985 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 986 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 987 }; 988 989 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 990 991 enum { 992 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 993 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 994 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 995 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 996 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 997 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 998 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 999 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1000 1001 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1002 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1003 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1004 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1005 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1006 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1007 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1008 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1009 1010 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1011 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1012 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1013 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1014 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1015 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1016 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1017 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1018 1019 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1020 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1021 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1022 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1023 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1024 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1025 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1026 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1027 1028 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1029 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1030 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1031 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1032 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1033 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1034 1035 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1036 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1037 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1038 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1039 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1040 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1041 1042 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1043 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1044 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1045 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1046 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1047 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1048 1049 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1050 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1051 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1052 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1053 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1054 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1055 1056 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1057 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1058 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1059 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1060 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1061 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1062 1063 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1064 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1065 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1066 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1067 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1068 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1069 1070 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1071 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1072 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1073 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1074 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1075 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1076 1077 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1078 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1079 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1080 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1081 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1082 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1083 }; 1084 1085 1086 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1087 1088 enum { 1089 OPC_LWXC1 = 0x00 | OPC_CP3, 1090 OPC_LDXC1 = 0x01 | OPC_CP3, 1091 OPC_LUXC1 = 0x05 | OPC_CP3, 1092 OPC_SWXC1 = 0x08 | OPC_CP3, 1093 OPC_SDXC1 = 0x09 | OPC_CP3, 1094 OPC_SUXC1 = 0x0D | OPC_CP3, 1095 OPC_PREFX = 0x0F | OPC_CP3, 1096 OPC_ALNV_PS = 0x1E | OPC_CP3, 1097 OPC_MADD_S = 0x20 | OPC_CP3, 1098 OPC_MADD_D = 0x21 | OPC_CP3, 1099 OPC_MADD_PS = 0x26 | OPC_CP3, 1100 OPC_MSUB_S = 0x28 | OPC_CP3, 1101 OPC_MSUB_D = 0x29 | OPC_CP3, 1102 OPC_MSUB_PS = 0x2E | OPC_CP3, 1103 OPC_NMADD_S = 0x30 | OPC_CP3, 1104 OPC_NMADD_D = 0x31 | OPC_CP3, 1105 OPC_NMADD_PS = 0x36 | OPC_CP3, 1106 OPC_NMSUB_S = 0x38 | OPC_CP3, 1107 OPC_NMSUB_D = 0x39 | OPC_CP3, 1108 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1109 }; 1110 1111 /* 1112 * MMI (MultiMedia Instruction) encodings 1113 * ====================================== 1114 * 1115 * MMI instructions encoding table keys: 1116 * 1117 * * This code is reserved for future use. An attempt to execute it 1118 * causes a Reserved Instruction exception. 1119 * % This code indicates an instruction class. The instruction word 1120 * must be further decoded by examining additional tables that show 1121 * the values for other instruction fields. 1122 * # This code is reserved for the unsupported instructions DMULT, 1123 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1124 * to execute it causes a Reserved Instruction exception. 1125 * 1126 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1127 * 1128 * 31 26 0 1129 * +--------+----------------------------------------+ 1130 * | opcode | | 1131 * +--------+----------------------------------------+ 1132 * 1133 * opcode bits 28..26 1134 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1135 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1136 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1137 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1138 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1139 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1140 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1141 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1142 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1143 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1144 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1145 */ 1146 1147 enum { 1148 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1149 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1150 }; 1151 1152 /* 1153 * MMI instructions with opcode field = MMI: 1154 * 1155 * 31 26 5 0 1156 * +--------+-------------------------------+--------+ 1157 * | MMI | |function| 1158 * +--------+-------------------------------+--------+ 1159 * 1160 * function bits 2..0 1161 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1162 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1163 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1164 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1165 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1166 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1167 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1168 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1169 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1170 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1171 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1172 */ 1173 1174 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1175 enum { 1176 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1177 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1178 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1179 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1180 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1181 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1182 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1183 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1184 }; 1185 1186 /* global register indices */ 1187 TCGv cpu_gpr[32], cpu_PC; 1188 /* 1189 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1190 * and the upper halves in cpu_gpr_hi[]. 1191 */ 1192 TCGv_i64 cpu_gpr_hi[32]; 1193 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1194 static TCGv cpu_dspctrl, btarget; 1195 TCGv bcond; 1196 static TCGv cpu_lladdr, cpu_llval; 1197 static TCGv_i32 hflags; 1198 TCGv_i32 fpu_fcr0, fpu_fcr31; 1199 TCGv_i64 fpu_f64[32]; 1200 1201 static const char regnames_HI[][4] = { 1202 "HI0", "HI1", "HI2", "HI3", 1203 }; 1204 1205 static const char regnames_LO[][4] = { 1206 "LO0", "LO1", "LO2", "LO3", 1207 }; 1208 1209 /* General purpose registers moves. */ 1210 void gen_load_gpr(TCGv t, int reg) 1211 { 1212 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1213 if (reg == 0) { 1214 tcg_gen_movi_tl(t, 0); 1215 } else { 1216 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1217 } 1218 } 1219 1220 void gen_store_gpr(TCGv t, int reg) 1221 { 1222 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1223 if (reg != 0) { 1224 tcg_gen_mov_tl(cpu_gpr[reg], t); 1225 } 1226 } 1227 1228 #if defined(TARGET_MIPS64) 1229 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1230 { 1231 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1232 if (reg == 0) { 1233 tcg_gen_movi_i64(t, 0); 1234 } else { 1235 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1236 } 1237 } 1238 1239 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1240 { 1241 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1242 if (reg != 0) { 1243 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1244 } 1245 } 1246 #endif /* TARGET_MIPS64 */ 1247 1248 /* Moves to/from shadow registers. */ 1249 static inline void gen_load_srsgpr(int from, int to) 1250 { 1251 TCGv t0 = tcg_temp_new(); 1252 1253 if (from == 0) { 1254 tcg_gen_movi_tl(t0, 0); 1255 } else { 1256 TCGv_i32 t2 = tcg_temp_new_i32(); 1257 TCGv_ptr addr = tcg_temp_new_ptr(); 1258 1259 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1260 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1261 tcg_gen_andi_i32(t2, t2, 0xf); 1262 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1263 tcg_gen_ext_i32_ptr(addr, t2); 1264 tcg_gen_add_ptr(addr, tcg_env, addr); 1265 1266 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1267 } 1268 gen_store_gpr(t0, to); 1269 } 1270 1271 static inline void gen_store_srsgpr(int from, int to) 1272 { 1273 if (to != 0) { 1274 TCGv t0 = tcg_temp_new(); 1275 TCGv_i32 t2 = tcg_temp_new_i32(); 1276 TCGv_ptr addr = tcg_temp_new_ptr(); 1277 1278 gen_load_gpr(t0, from); 1279 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1280 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1281 tcg_gen_andi_i32(t2, t2, 0xf); 1282 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1283 tcg_gen_ext_i32_ptr(addr, t2); 1284 tcg_gen_add_ptr(addr, tcg_env, addr); 1285 1286 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1287 } 1288 } 1289 1290 /* Tests */ 1291 static inline void gen_save_pc(target_ulong pc) 1292 { 1293 tcg_gen_movi_tl(cpu_PC, pc); 1294 } 1295 1296 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1297 { 1298 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1299 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1300 gen_save_pc(ctx->base.pc_next); 1301 ctx->saved_pc = ctx->base.pc_next; 1302 } 1303 if (ctx->hflags != ctx->saved_hflags) { 1304 tcg_gen_movi_i32(hflags, ctx->hflags); 1305 ctx->saved_hflags = ctx->hflags; 1306 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1307 case MIPS_HFLAG_BR: 1308 break; 1309 case MIPS_HFLAG_BC: 1310 case MIPS_HFLAG_BL: 1311 case MIPS_HFLAG_B: 1312 tcg_gen_movi_tl(btarget, ctx->btarget); 1313 break; 1314 } 1315 } 1316 } 1317 1318 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1319 { 1320 ctx->saved_hflags = ctx->hflags; 1321 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1322 case MIPS_HFLAG_BR: 1323 break; 1324 case MIPS_HFLAG_BC: 1325 case MIPS_HFLAG_BL: 1326 case MIPS_HFLAG_B: 1327 ctx->btarget = env->btarget; 1328 break; 1329 } 1330 } 1331 1332 void generate_exception_err(DisasContext *ctx, int excp, int err) 1333 { 1334 save_cpu_state(ctx, 1); 1335 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1336 tcg_constant_i32(err)); 1337 ctx->base.is_jmp = DISAS_NORETURN; 1338 } 1339 1340 void generate_exception(DisasContext *ctx, int excp) 1341 { 1342 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1343 } 1344 1345 void generate_exception_end(DisasContext *ctx, int excp) 1346 { 1347 generate_exception_err(ctx, excp, 0); 1348 } 1349 1350 void generate_exception_break(DisasContext *ctx, int code) 1351 { 1352 #ifdef CONFIG_USER_ONLY 1353 /* Pass the break code along to cpu_loop. */ 1354 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1355 offsetof(CPUMIPSState, error_code)); 1356 #endif 1357 generate_exception_end(ctx, EXCP_BREAK); 1358 } 1359 1360 void gen_reserved_instruction(DisasContext *ctx) 1361 { 1362 generate_exception_end(ctx, EXCP_RI); 1363 } 1364 1365 /* Floating point register moves. */ 1366 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1367 { 1368 if (ctx->hflags & MIPS_HFLAG_FRE) { 1369 generate_exception(ctx, EXCP_RI); 1370 } 1371 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1372 } 1373 1374 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1375 { 1376 TCGv_i64 t64; 1377 if (ctx->hflags & MIPS_HFLAG_FRE) { 1378 generate_exception(ctx, EXCP_RI); 1379 } 1380 t64 = tcg_temp_new_i64(); 1381 tcg_gen_extu_i32_i64(t64, t); 1382 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1383 } 1384 1385 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1386 { 1387 if (ctx->hflags & MIPS_HFLAG_F64) { 1388 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1389 } else { 1390 gen_load_fpr32(ctx, t, reg | 1); 1391 } 1392 } 1393 1394 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1395 { 1396 if (ctx->hflags & MIPS_HFLAG_F64) { 1397 TCGv_i64 t64 = tcg_temp_new_i64(); 1398 tcg_gen_extu_i32_i64(t64, t); 1399 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1400 } else { 1401 gen_store_fpr32(ctx, t, reg | 1); 1402 } 1403 } 1404 1405 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1406 { 1407 if (ctx->hflags & MIPS_HFLAG_F64) { 1408 tcg_gen_mov_i64(t, fpu_f64[reg]); 1409 } else { 1410 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1411 } 1412 } 1413 1414 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1415 { 1416 if (ctx->hflags & MIPS_HFLAG_F64) { 1417 tcg_gen_mov_i64(fpu_f64[reg], t); 1418 } else { 1419 TCGv_i64 t0; 1420 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1421 t0 = tcg_temp_new_i64(); 1422 tcg_gen_shri_i64(t0, t, 32); 1423 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1424 } 1425 } 1426 1427 int get_fp_bit(int cc) 1428 { 1429 if (cc) { 1430 return 24 + cc; 1431 } else { 1432 return 23; 1433 } 1434 } 1435 1436 /* Addresses computation */ 1437 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1438 { 1439 tcg_gen_add_tl(ret, arg0, arg1); 1440 1441 #if defined(TARGET_MIPS64) 1442 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1443 tcg_gen_ext32s_i64(ret, ret); 1444 } 1445 #endif 1446 } 1447 1448 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1449 { 1450 tcg_gen_addi_tl(ret, base, ofs); 1451 1452 #if defined(TARGET_MIPS64) 1453 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1454 tcg_gen_ext32s_i64(ret, ret); 1455 } 1456 #endif 1457 } 1458 1459 /* Addresses computation (translation time) */ 1460 static target_long addr_add(DisasContext *ctx, target_long base, 1461 target_long offset) 1462 { 1463 target_long sum = base + offset; 1464 1465 #if defined(TARGET_MIPS64) 1466 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1467 sum = (int32_t)sum; 1468 } 1469 #endif 1470 return sum; 1471 } 1472 1473 /* Sign-extract the low 32-bits to a target_long. */ 1474 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1475 { 1476 #if defined(TARGET_MIPS64) 1477 tcg_gen_ext32s_i64(ret, arg); 1478 #else 1479 tcg_gen_extrl_i64_i32(ret, arg); 1480 #endif 1481 } 1482 1483 /* Sign-extract the high 32-bits to a target_long. */ 1484 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1485 { 1486 #if defined(TARGET_MIPS64) 1487 tcg_gen_sari_i64(ret, arg, 32); 1488 #else 1489 tcg_gen_extrh_i64_i32(ret, arg); 1490 #endif 1491 } 1492 1493 bool check_cp0_enabled(DisasContext *ctx) 1494 { 1495 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1496 generate_exception_end(ctx, EXCP_CpU); 1497 return false; 1498 } 1499 return true; 1500 } 1501 1502 void check_cp1_enabled(DisasContext *ctx) 1503 { 1504 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1505 generate_exception_err(ctx, EXCP_CpU, 1); 1506 } 1507 } 1508 1509 /* 1510 * Verify that the processor is running with COP1X instructions enabled. 1511 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1512 * opcode tables. 1513 */ 1514 void check_cop1x(DisasContext *ctx) 1515 { 1516 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1517 gen_reserved_instruction(ctx); 1518 } 1519 } 1520 1521 /* 1522 * Verify that the processor is running with 64-bit floating-point 1523 * operations enabled. 1524 */ 1525 void check_cp1_64bitmode(DisasContext *ctx) 1526 { 1527 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1528 gen_reserved_instruction(ctx); 1529 } 1530 } 1531 1532 /* 1533 * Verify if floating point register is valid; an operation is not defined 1534 * if bit 0 of any register specification is set and the FR bit in the 1535 * Status register equals zero, since the register numbers specify an 1536 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1537 * in the Status register equals one, both even and odd register numbers 1538 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1539 * 1540 * Multiple 64 bit wide registers can be checked by calling 1541 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1542 */ 1543 void check_cp1_registers(DisasContext *ctx, int regs) 1544 { 1545 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1546 gen_reserved_instruction(ctx); 1547 } 1548 } 1549 1550 /* 1551 * Verify that the processor is running with DSP instructions enabled. 1552 * This is enabled by CP0 Status register MX(24) bit. 1553 */ 1554 static inline void check_dsp(DisasContext *ctx) 1555 { 1556 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1557 if (ctx->insn_flags & ASE_DSP) { 1558 generate_exception_end(ctx, EXCP_DSPDIS); 1559 } else { 1560 gen_reserved_instruction(ctx); 1561 } 1562 } 1563 } 1564 1565 static inline void check_dsp_r2(DisasContext *ctx) 1566 { 1567 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1568 if (ctx->insn_flags & ASE_DSP) { 1569 generate_exception_end(ctx, EXCP_DSPDIS); 1570 } else { 1571 gen_reserved_instruction(ctx); 1572 } 1573 } 1574 } 1575 1576 static inline void check_dsp_r3(DisasContext *ctx) 1577 { 1578 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1579 if (ctx->insn_flags & ASE_DSP) { 1580 generate_exception_end(ctx, EXCP_DSPDIS); 1581 } else { 1582 gen_reserved_instruction(ctx); 1583 } 1584 } 1585 } 1586 1587 /* 1588 * This code generates a "reserved instruction" exception if the 1589 * CPU does not support the instruction set corresponding to flags. 1590 */ 1591 void check_insn(DisasContext *ctx, uint64_t flags) 1592 { 1593 if (unlikely(!(ctx->insn_flags & flags))) { 1594 gen_reserved_instruction(ctx); 1595 } 1596 } 1597 1598 /* 1599 * This code generates a "reserved instruction" exception if the 1600 * CPU has corresponding flag set which indicates that the instruction 1601 * has been removed. 1602 */ 1603 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1604 { 1605 if (unlikely(ctx->insn_flags & flags)) { 1606 gen_reserved_instruction(ctx); 1607 } 1608 } 1609 1610 /* 1611 * The Linux kernel traps certain reserved instruction exceptions to 1612 * emulate the corresponding instructions. QEMU is the kernel in user 1613 * mode, so those traps are emulated by accepting the instructions. 1614 * 1615 * A reserved instruction exception is generated for flagged CPUs if 1616 * QEMU runs in system mode. 1617 */ 1618 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1619 { 1620 #ifndef CONFIG_USER_ONLY 1621 check_insn_opc_removed(ctx, flags); 1622 #endif 1623 } 1624 1625 /* 1626 * This code generates a "reserved instruction" exception if the 1627 * CPU does not support 64-bit paired-single (PS) floating point data type. 1628 */ 1629 static inline void check_ps(DisasContext *ctx) 1630 { 1631 if (unlikely(!ctx->ps)) { 1632 generate_exception(ctx, EXCP_RI); 1633 } 1634 check_cp1_64bitmode(ctx); 1635 } 1636 1637 bool decode_64bit_enabled(DisasContext *ctx) 1638 { 1639 return ctx->hflags & MIPS_HFLAG_64; 1640 } 1641 1642 /* 1643 * This code generates a "reserved instruction" exception if cpu is not 1644 * 64-bit or 64-bit instructions are not enabled. 1645 */ 1646 void check_mips_64(DisasContext *ctx) 1647 { 1648 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1649 gen_reserved_instruction(ctx); 1650 } 1651 } 1652 1653 #ifndef CONFIG_USER_ONLY 1654 static inline void check_mvh(DisasContext *ctx) 1655 { 1656 if (unlikely(!ctx->mvh)) { 1657 generate_exception(ctx, EXCP_RI); 1658 } 1659 } 1660 #endif 1661 1662 /* 1663 * This code generates a "reserved instruction" exception if the 1664 * Config5 XNP bit is set. 1665 */ 1666 static inline void check_xnp(DisasContext *ctx) 1667 { 1668 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1669 gen_reserved_instruction(ctx); 1670 } 1671 } 1672 1673 #ifndef CONFIG_USER_ONLY 1674 /* 1675 * This code generates a "reserved instruction" exception if the 1676 * Config3 PW bit is NOT set. 1677 */ 1678 static inline void check_pw(DisasContext *ctx) 1679 { 1680 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1681 gen_reserved_instruction(ctx); 1682 } 1683 } 1684 #endif 1685 1686 /* 1687 * This code generates a "reserved instruction" exception if the 1688 * Config3 MT bit is NOT set. 1689 */ 1690 static inline void check_mt(DisasContext *ctx) 1691 { 1692 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1693 gen_reserved_instruction(ctx); 1694 } 1695 } 1696 1697 #ifndef CONFIG_USER_ONLY 1698 /* 1699 * This code generates a "coprocessor unusable" exception if CP0 is not 1700 * available, and, if that is not the case, generates a "reserved instruction" 1701 * exception if the Config5 MT bit is NOT set. This is needed for availability 1702 * control of some of MT ASE instructions. 1703 */ 1704 static inline void check_cp0_mt(DisasContext *ctx) 1705 { 1706 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1707 generate_exception_end(ctx, EXCP_CpU); 1708 } else { 1709 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1710 gen_reserved_instruction(ctx); 1711 } 1712 } 1713 } 1714 #endif 1715 1716 /* 1717 * This code generates a "reserved instruction" exception if the 1718 * Config5 NMS bit is set. 1719 */ 1720 static inline void check_nms(DisasContext *ctx) 1721 { 1722 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1723 gen_reserved_instruction(ctx); 1724 } 1725 } 1726 1727 /* 1728 * This code generates a "reserved instruction" exception if the 1729 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1730 * Config2 TL, and Config5 L2C are unset. 1731 */ 1732 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1733 { 1734 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1735 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1736 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1737 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1738 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1739 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1740 gen_reserved_instruction(ctx); 1741 } 1742 } 1743 1744 /* 1745 * This code generates a "reserved instruction" exception if the 1746 * Config5 EVA bit is NOT set. 1747 */ 1748 static inline void check_eva(DisasContext *ctx) 1749 { 1750 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1751 gen_reserved_instruction(ctx); 1752 } 1753 } 1754 1755 1756 /* 1757 * Define small wrappers for gen_load_fpr* so that we have a uniform 1758 * calling interface for 32 and 64-bit FPRs. No sense in changing 1759 * all callers for gen_load_fpr32 when we need the CTX parameter for 1760 * this one use. 1761 */ 1762 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1763 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1764 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1765 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1766 int ft, int fs, int cc) \ 1767 { \ 1768 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1769 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1770 switch (ifmt) { \ 1771 case FMT_PS: \ 1772 check_ps(ctx); \ 1773 break; \ 1774 case FMT_D: \ 1775 if (abs) { \ 1776 check_cop1x(ctx); \ 1777 } \ 1778 check_cp1_registers(ctx, fs | ft); \ 1779 break; \ 1780 case FMT_S: \ 1781 if (abs) { \ 1782 check_cop1x(ctx); \ 1783 } \ 1784 break; \ 1785 } \ 1786 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1787 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1788 switch (n) { \ 1789 case 0: \ 1790 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1791 break; \ 1792 case 1: \ 1793 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1794 break; \ 1795 case 2: \ 1796 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1797 break; \ 1798 case 3: \ 1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1800 break; \ 1801 case 4: \ 1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1803 break; \ 1804 case 5: \ 1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1806 break; \ 1807 case 6: \ 1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1809 break; \ 1810 case 7: \ 1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1812 break; \ 1813 case 8: \ 1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1815 break; \ 1816 case 9: \ 1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1818 break; \ 1819 case 10: \ 1820 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1821 break; \ 1822 case 11: \ 1823 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1824 break; \ 1825 case 12: \ 1826 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1827 break; \ 1828 case 13: \ 1829 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1830 break; \ 1831 case 14: \ 1832 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1833 break; \ 1834 case 15: \ 1835 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1836 break; \ 1837 default: \ 1838 abort(); \ 1839 } \ 1840 } 1841 1842 FOP_CONDS(, 0, d, FMT_D, 64) 1843 FOP_CONDS(abs, 1, d, FMT_D, 64) 1844 FOP_CONDS(, 0, s, FMT_S, 32) 1845 FOP_CONDS(abs, 1, s, FMT_S, 32) 1846 FOP_CONDS(, 0, ps, FMT_PS, 64) 1847 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1848 #undef FOP_CONDS 1849 1850 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1851 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1852 int ft, int fs, int fd) \ 1853 { \ 1854 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1855 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1856 if (ifmt == FMT_D) { \ 1857 check_cp1_registers(ctx, fs | ft | fd); \ 1858 } \ 1859 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1860 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1861 switch (n) { \ 1862 case 0: \ 1863 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1864 break; \ 1865 case 1: \ 1866 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1867 break; \ 1868 case 2: \ 1869 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1870 break; \ 1871 case 3: \ 1872 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1873 break; \ 1874 case 4: \ 1875 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1876 break; \ 1877 case 5: \ 1878 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1879 break; \ 1880 case 6: \ 1881 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1882 break; \ 1883 case 7: \ 1884 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1885 break; \ 1886 case 8: \ 1887 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1888 break; \ 1889 case 9: \ 1890 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1891 break; \ 1892 case 10: \ 1893 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1894 break; \ 1895 case 11: \ 1896 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1897 break; \ 1898 case 12: \ 1899 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1900 break; \ 1901 case 13: \ 1902 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1903 break; \ 1904 case 14: \ 1905 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1906 break; \ 1907 case 15: \ 1908 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1909 break; \ 1910 case 17: \ 1911 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1912 break; \ 1913 case 18: \ 1914 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1915 break; \ 1916 case 19: \ 1917 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1918 break; \ 1919 case 25: \ 1920 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1921 break; \ 1922 case 26: \ 1923 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1924 break; \ 1925 case 27: \ 1926 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1927 break; \ 1928 default: \ 1929 abort(); \ 1930 } \ 1931 STORE; \ 1932 } 1933 1934 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1935 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1936 #undef FOP_CONDNS 1937 #undef gen_ldcmp_fpr32 1938 #undef gen_ldcmp_fpr64 1939 1940 /* load/store instructions. */ 1941 #ifdef CONFIG_USER_ONLY 1942 #define OP_LD_ATOMIC(insn, memop) \ 1943 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1944 DisasContext *ctx) \ 1945 { \ 1946 TCGv t0 = tcg_temp_new(); \ 1947 tcg_gen_mov_tl(t0, arg1); \ 1948 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1949 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1950 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1951 } 1952 #else 1953 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1954 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1955 DisasContext *ctx) \ 1956 { \ 1957 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1958 } 1959 #endif 1960 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1961 #if defined(TARGET_MIPS64) 1962 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1963 #endif 1964 #undef OP_LD_ATOMIC 1965 1966 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1967 { 1968 if (base == 0) { 1969 tcg_gen_movi_tl(addr, offset); 1970 } else if (offset == 0) { 1971 gen_load_gpr(addr, base); 1972 } else { 1973 tcg_gen_movi_tl(addr, offset); 1974 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1975 } 1976 } 1977 1978 static target_ulong pc_relative_pc(DisasContext *ctx) 1979 { 1980 target_ulong pc = ctx->base.pc_next; 1981 1982 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1983 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1984 1985 pc -= branch_bytes; 1986 } 1987 1988 pc &= ~(target_ulong)3; 1989 return pc; 1990 } 1991 1992 /* LWL or LDL, depending on MemOp. */ 1993 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1994 int mem_idx, MemOp mop) 1995 { 1996 int sizem1 = memop_size(mop) - 1; 1997 TCGv t0 = tcg_temp_new(); 1998 TCGv t1 = tcg_temp_new(); 1999 2000 /* 2001 * Do a byte access to possibly trigger a page 2002 * fault with the unaligned address. 2003 */ 2004 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2005 tcg_gen_andi_tl(t1, addr, sizem1); 2006 if (!disas_is_bigendian(ctx)) { 2007 tcg_gen_xori_tl(t1, t1, sizem1); 2008 } 2009 tcg_gen_shli_tl(t1, t1, 3); 2010 tcg_gen_andi_tl(t0, addr, ~sizem1); 2011 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2012 tcg_gen_shl_tl(t0, t0, t1); 2013 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 2014 tcg_gen_andc_tl(t1, reg, t1); 2015 tcg_gen_or_tl(reg, t0, t1); 2016 } 2017 2018 /* LWR or LDR, depending on MemOp. */ 2019 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2020 int mem_idx, MemOp mop) 2021 { 2022 int size = memop_size(mop); 2023 int sizem1 = size - 1; 2024 TCGv t0 = tcg_temp_new(); 2025 TCGv t1 = tcg_temp_new(); 2026 2027 /* 2028 * Do a byte access to possibly trigger a page 2029 * fault with the unaligned address. 2030 */ 2031 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2032 tcg_gen_andi_tl(t1, addr, sizem1); 2033 if (disas_is_bigendian(ctx)) { 2034 tcg_gen_xori_tl(t1, t1, sizem1); 2035 } 2036 tcg_gen_shli_tl(t1, t1, 3); 2037 tcg_gen_andi_tl(t0, addr, ~sizem1); 2038 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2039 tcg_gen_shr_tl(t0, t0, t1); 2040 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2041 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2042 tcg_gen_and_tl(t1, reg, t1); 2043 tcg_gen_or_tl(reg, t0, t1); 2044 } 2045 2046 /* Load */ 2047 static void gen_ld(DisasContext *ctx, uint32_t opc, 2048 int rt, int base, int offset) 2049 { 2050 TCGv t0, t1; 2051 int mem_idx = ctx->mem_idx; 2052 2053 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2054 INSN_LOONGSON3A)) { 2055 /* 2056 * Loongson CPU uses a load to zero register for prefetch. 2057 * We emulate it as a NOP. On other CPU we must perform the 2058 * actual memory access. 2059 */ 2060 return; 2061 } 2062 2063 t0 = tcg_temp_new(); 2064 gen_base_offset_addr(ctx, t0, base, offset); 2065 2066 switch (opc) { 2067 #if defined(TARGET_MIPS64) 2068 case OPC_LWU: 2069 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2070 ctx->default_tcg_memop_mask); 2071 gen_store_gpr(t0, rt); 2072 break; 2073 case OPC_LD: 2074 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2075 ctx->default_tcg_memop_mask); 2076 gen_store_gpr(t0, rt); 2077 break; 2078 case OPC_LLD: 2079 case R6_OPC_LLD: 2080 op_ld_lld(t0, t0, mem_idx, ctx); 2081 gen_store_gpr(t0, rt); 2082 break; 2083 case OPC_LDL: 2084 t1 = tcg_temp_new(); 2085 gen_load_gpr(t1, rt); 2086 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2087 gen_store_gpr(t1, rt); 2088 break; 2089 case OPC_LDR: 2090 t1 = tcg_temp_new(); 2091 gen_load_gpr(t1, rt); 2092 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2093 gen_store_gpr(t1, rt); 2094 break; 2095 case OPC_LDPC: 2096 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2097 gen_op_addr_add(ctx, t0, t0, t1); 2098 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2099 gen_store_gpr(t0, rt); 2100 break; 2101 #endif 2102 case OPC_LWPC: 2103 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2104 gen_op_addr_add(ctx, t0, t0, t1); 2105 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2106 gen_store_gpr(t0, rt); 2107 break; 2108 case OPC_LWE: 2109 mem_idx = MIPS_HFLAG_UM; 2110 /* fall through */ 2111 case OPC_LW: 2112 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2113 ctx->default_tcg_memop_mask); 2114 gen_store_gpr(t0, rt); 2115 break; 2116 case OPC_LHE: 2117 mem_idx = MIPS_HFLAG_UM; 2118 /* fall through */ 2119 case OPC_LH: 2120 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2121 ctx->default_tcg_memop_mask); 2122 gen_store_gpr(t0, rt); 2123 break; 2124 case OPC_LHUE: 2125 mem_idx = MIPS_HFLAG_UM; 2126 /* fall through */ 2127 case OPC_LHU: 2128 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2129 ctx->default_tcg_memop_mask); 2130 gen_store_gpr(t0, rt); 2131 break; 2132 case OPC_LBE: 2133 mem_idx = MIPS_HFLAG_UM; 2134 /* fall through */ 2135 case OPC_LB: 2136 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2137 gen_store_gpr(t0, rt); 2138 break; 2139 case OPC_LBUE: 2140 mem_idx = MIPS_HFLAG_UM; 2141 /* fall through */ 2142 case OPC_LBU: 2143 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2144 gen_store_gpr(t0, rt); 2145 break; 2146 case OPC_LWLE: 2147 mem_idx = MIPS_HFLAG_UM; 2148 /* fall through */ 2149 case OPC_LWL: 2150 t1 = tcg_temp_new(); 2151 gen_load_gpr(t1, rt); 2152 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2153 tcg_gen_ext32s_tl(t1, t1); 2154 gen_store_gpr(t1, rt); 2155 break; 2156 case OPC_LWRE: 2157 mem_idx = MIPS_HFLAG_UM; 2158 /* fall through */ 2159 case OPC_LWR: 2160 t1 = tcg_temp_new(); 2161 gen_load_gpr(t1, rt); 2162 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2163 tcg_gen_ext32s_tl(t1, t1); 2164 gen_store_gpr(t1, rt); 2165 break; 2166 case OPC_LLE: 2167 mem_idx = MIPS_HFLAG_UM; 2168 /* fall through */ 2169 case OPC_LL: 2170 case R6_OPC_LL: 2171 op_ld_ll(t0, t0, mem_idx, ctx); 2172 gen_store_gpr(t0, rt); 2173 break; 2174 } 2175 } 2176 2177 /* Store */ 2178 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2179 int base, int offset) 2180 { 2181 TCGv t0 = tcg_temp_new(); 2182 TCGv t1 = tcg_temp_new(); 2183 int mem_idx = ctx->mem_idx; 2184 2185 gen_base_offset_addr(ctx, t0, base, offset); 2186 gen_load_gpr(t1, rt); 2187 switch (opc) { 2188 #if defined(TARGET_MIPS64) 2189 case OPC_SD: 2190 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2191 ctx->default_tcg_memop_mask); 2192 break; 2193 case OPC_SDL: 2194 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2195 break; 2196 case OPC_SDR: 2197 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2198 break; 2199 #endif 2200 case OPC_SWE: 2201 mem_idx = MIPS_HFLAG_UM; 2202 /* fall through */ 2203 case OPC_SW: 2204 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2205 ctx->default_tcg_memop_mask); 2206 break; 2207 case OPC_SHE: 2208 mem_idx = MIPS_HFLAG_UM; 2209 /* fall through */ 2210 case OPC_SH: 2211 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2212 ctx->default_tcg_memop_mask); 2213 break; 2214 case OPC_SBE: 2215 mem_idx = MIPS_HFLAG_UM; 2216 /* fall through */ 2217 case OPC_SB: 2218 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2219 break; 2220 case OPC_SWLE: 2221 mem_idx = MIPS_HFLAG_UM; 2222 /* fall through */ 2223 case OPC_SWL: 2224 gen_helper_0e2i(swl, t1, t0, mem_idx); 2225 break; 2226 case OPC_SWRE: 2227 mem_idx = MIPS_HFLAG_UM; 2228 /* fall through */ 2229 case OPC_SWR: 2230 gen_helper_0e2i(swr, t1, t0, mem_idx); 2231 break; 2232 } 2233 } 2234 2235 2236 /* Store conditional */ 2237 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2238 MemOp tcg_mo, bool eva) 2239 { 2240 TCGv addr, t0, val; 2241 TCGLabel *l1 = gen_new_label(); 2242 TCGLabel *done = gen_new_label(); 2243 2244 t0 = tcg_temp_new(); 2245 addr = tcg_temp_new(); 2246 /* compare the address against that of the preceding LL */ 2247 gen_base_offset_addr(ctx, addr, base, offset); 2248 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2249 gen_store_gpr(tcg_constant_tl(0), rt); 2250 tcg_gen_br(done); 2251 2252 gen_set_label(l1); 2253 /* generate cmpxchg */ 2254 val = tcg_temp_new(); 2255 gen_load_gpr(val, rt); 2256 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2257 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2258 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2259 gen_store_gpr(t0, rt); 2260 2261 gen_set_label(done); 2262 } 2263 2264 /* Load and store */ 2265 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2266 TCGv t0) 2267 { 2268 /* 2269 * Don't do NOP if destination is zero: we must perform the actual 2270 * memory access. 2271 */ 2272 switch (opc) { 2273 case OPC_LWC1: 2274 { 2275 TCGv_i32 fp0 = tcg_temp_new_i32(); 2276 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2277 ctx->default_tcg_memop_mask); 2278 gen_store_fpr32(ctx, fp0, ft); 2279 } 2280 break; 2281 case OPC_SWC1: 2282 { 2283 TCGv_i32 fp0 = tcg_temp_new_i32(); 2284 gen_load_fpr32(ctx, fp0, ft); 2285 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2286 ctx->default_tcg_memop_mask); 2287 } 2288 break; 2289 case OPC_LDC1: 2290 { 2291 TCGv_i64 fp0 = tcg_temp_new_i64(); 2292 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2293 ctx->default_tcg_memop_mask); 2294 gen_store_fpr64(ctx, fp0, ft); 2295 } 2296 break; 2297 case OPC_SDC1: 2298 { 2299 TCGv_i64 fp0 = tcg_temp_new_i64(); 2300 gen_load_fpr64(ctx, fp0, ft); 2301 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2302 ctx->default_tcg_memop_mask); 2303 } 2304 break; 2305 default: 2306 MIPS_INVAL("flt_ldst"); 2307 gen_reserved_instruction(ctx); 2308 break; 2309 } 2310 } 2311 2312 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2313 int rs, int16_t imm) 2314 { 2315 TCGv t0 = tcg_temp_new(); 2316 2317 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2318 check_cp1_enabled(ctx); 2319 switch (op) { 2320 case OPC_LDC1: 2321 case OPC_SDC1: 2322 check_insn(ctx, ISA_MIPS2); 2323 /* Fallthrough */ 2324 default: 2325 gen_base_offset_addr(ctx, t0, rs, imm); 2326 gen_flt_ldst(ctx, op, rt, t0); 2327 } 2328 } else { 2329 generate_exception_err(ctx, EXCP_CpU, 1); 2330 } 2331 } 2332 2333 /* Arithmetic with immediate operand */ 2334 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2335 int rt, int rs, int imm) 2336 { 2337 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2338 2339 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2340 /* 2341 * If no destination, treat it as a NOP. 2342 * For addi, we must generate the overflow exception when needed. 2343 */ 2344 return; 2345 } 2346 switch (opc) { 2347 case OPC_ADDI: 2348 { 2349 TCGv t0 = tcg_temp_new(); 2350 TCGv t1 = tcg_temp_new(); 2351 TCGv t2 = tcg_temp_new(); 2352 TCGLabel *l1 = gen_new_label(); 2353 2354 gen_load_gpr(t1, rs); 2355 tcg_gen_addi_tl(t0, t1, uimm); 2356 tcg_gen_ext32s_tl(t0, t0); 2357 2358 tcg_gen_xori_tl(t1, t1, ~uimm); 2359 tcg_gen_xori_tl(t2, t0, uimm); 2360 tcg_gen_and_tl(t1, t1, t2); 2361 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2362 /* operands of same sign, result different sign */ 2363 generate_exception(ctx, EXCP_OVERFLOW); 2364 gen_set_label(l1); 2365 tcg_gen_ext32s_tl(t0, t0); 2366 gen_store_gpr(t0, rt); 2367 } 2368 break; 2369 case OPC_ADDIU: 2370 if (rs != 0) { 2371 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2372 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2373 } else { 2374 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2375 } 2376 break; 2377 #if defined(TARGET_MIPS64) 2378 case OPC_DADDI: 2379 { 2380 TCGv t0 = tcg_temp_new(); 2381 TCGv t1 = tcg_temp_new(); 2382 TCGv t2 = tcg_temp_new(); 2383 TCGLabel *l1 = gen_new_label(); 2384 2385 gen_load_gpr(t1, rs); 2386 tcg_gen_addi_tl(t0, t1, uimm); 2387 2388 tcg_gen_xori_tl(t1, t1, ~uimm); 2389 tcg_gen_xori_tl(t2, t0, uimm); 2390 tcg_gen_and_tl(t1, t1, t2); 2391 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2392 /* operands of same sign, result different sign */ 2393 generate_exception(ctx, EXCP_OVERFLOW); 2394 gen_set_label(l1); 2395 gen_store_gpr(t0, rt); 2396 } 2397 break; 2398 case OPC_DADDIU: 2399 if (rs != 0) { 2400 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2401 } else { 2402 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2403 } 2404 break; 2405 #endif 2406 } 2407 } 2408 2409 /* Logic with immediate operand */ 2410 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2411 int rt, int rs, int16_t imm) 2412 { 2413 target_ulong uimm; 2414 2415 if (rt == 0) { 2416 /* If no destination, treat it as a NOP. */ 2417 return; 2418 } 2419 uimm = (uint16_t)imm; 2420 switch (opc) { 2421 case OPC_ANDI: 2422 if (likely(rs != 0)) { 2423 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2424 } else { 2425 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2426 } 2427 break; 2428 case OPC_ORI: 2429 if (rs != 0) { 2430 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2431 } else { 2432 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2433 } 2434 break; 2435 case OPC_XORI: 2436 if (likely(rs != 0)) { 2437 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2438 } else { 2439 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2440 } 2441 break; 2442 case OPC_LUI: 2443 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2444 /* OPC_AUI */ 2445 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2446 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2447 } else { 2448 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2449 } 2450 break; 2451 2452 default: 2453 break; 2454 } 2455 } 2456 2457 /* Set on less than with immediate operand */ 2458 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2459 int rt, int rs, int16_t imm) 2460 { 2461 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2462 TCGv t0; 2463 2464 if (rt == 0) { 2465 /* If no destination, treat it as a NOP. */ 2466 return; 2467 } 2468 t0 = tcg_temp_new(); 2469 gen_load_gpr(t0, rs); 2470 switch (opc) { 2471 case OPC_SLTI: 2472 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2473 break; 2474 case OPC_SLTIU: 2475 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2476 break; 2477 } 2478 } 2479 2480 /* Shifts with immediate operand */ 2481 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2482 int rt, int rs, int16_t imm) 2483 { 2484 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2485 TCGv t0; 2486 2487 if (rt == 0) { 2488 /* If no destination, treat it as a NOP. */ 2489 return; 2490 } 2491 2492 t0 = tcg_temp_new(); 2493 gen_load_gpr(t0, rs); 2494 switch (opc) { 2495 case OPC_SLL: 2496 tcg_gen_shli_tl(t0, t0, uimm); 2497 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2498 break; 2499 case OPC_SRA: 2500 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2501 break; 2502 case OPC_SRL: 2503 if (uimm != 0) { 2504 tcg_gen_ext32u_tl(t0, t0); 2505 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2506 } else { 2507 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2508 } 2509 break; 2510 case OPC_ROTR: 2511 if (uimm != 0) { 2512 TCGv_i32 t1 = tcg_temp_new_i32(); 2513 2514 tcg_gen_trunc_tl_i32(t1, t0); 2515 tcg_gen_rotri_i32(t1, t1, uimm); 2516 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2517 } else { 2518 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2519 } 2520 break; 2521 #if defined(TARGET_MIPS64) 2522 case OPC_DSLL: 2523 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2524 break; 2525 case OPC_DSRA: 2526 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2527 break; 2528 case OPC_DSRL: 2529 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2530 break; 2531 case OPC_DROTR: 2532 if (uimm != 0) { 2533 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2534 } else { 2535 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2536 } 2537 break; 2538 case OPC_DSLL32: 2539 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2540 break; 2541 case OPC_DSRA32: 2542 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2543 break; 2544 case OPC_DSRL32: 2545 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2546 break; 2547 case OPC_DROTR32: 2548 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2549 break; 2550 #endif 2551 } 2552 } 2553 2554 /* Arithmetic */ 2555 static void gen_arith(DisasContext *ctx, uint32_t opc, 2556 int rd, int rs, int rt) 2557 { 2558 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2559 && opc != OPC_DADD && opc != OPC_DSUB) { 2560 /* 2561 * If no destination, treat it as a NOP. 2562 * For add & sub, we must generate the overflow exception when needed. 2563 */ 2564 return; 2565 } 2566 2567 switch (opc) { 2568 case OPC_ADD: 2569 { 2570 TCGv t0 = tcg_temp_new(); 2571 TCGv t1 = tcg_temp_new(); 2572 TCGv t2 = tcg_temp_new(); 2573 TCGLabel *l1 = gen_new_label(); 2574 2575 gen_load_gpr(t1, rs); 2576 gen_load_gpr(t2, rt); 2577 tcg_gen_add_tl(t0, t1, t2); 2578 tcg_gen_ext32s_tl(t0, t0); 2579 tcg_gen_xor_tl(t1, t1, t2); 2580 tcg_gen_xor_tl(t2, t0, t2); 2581 tcg_gen_andc_tl(t1, t2, t1); 2582 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2583 /* operands of same sign, result different sign */ 2584 generate_exception(ctx, EXCP_OVERFLOW); 2585 gen_set_label(l1); 2586 gen_store_gpr(t0, rd); 2587 } 2588 break; 2589 case OPC_ADDU: 2590 if (rs != 0 && rt != 0) { 2591 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2592 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2593 } else if (rs == 0 && rt != 0) { 2594 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2595 } else if (rs != 0 && rt == 0) { 2596 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2597 } else { 2598 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2599 } 2600 break; 2601 case OPC_SUB: 2602 { 2603 TCGv t0 = tcg_temp_new(); 2604 TCGv t1 = tcg_temp_new(); 2605 TCGv t2 = tcg_temp_new(); 2606 TCGLabel *l1 = gen_new_label(); 2607 2608 gen_load_gpr(t1, rs); 2609 gen_load_gpr(t2, rt); 2610 tcg_gen_sub_tl(t0, t1, t2); 2611 tcg_gen_ext32s_tl(t0, t0); 2612 tcg_gen_xor_tl(t2, t1, t2); 2613 tcg_gen_xor_tl(t1, t0, t1); 2614 tcg_gen_and_tl(t1, t1, t2); 2615 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2616 /* 2617 * operands of different sign, first operand and the result 2618 * of different sign 2619 */ 2620 generate_exception(ctx, EXCP_OVERFLOW); 2621 gen_set_label(l1); 2622 gen_store_gpr(t0, rd); 2623 } 2624 break; 2625 case OPC_SUBU: 2626 if (rs != 0 && rt != 0) { 2627 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2628 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2629 } else if (rs == 0 && rt != 0) { 2630 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2631 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2632 } else if (rs != 0 && rt == 0) { 2633 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2634 } else { 2635 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2636 } 2637 break; 2638 #if defined(TARGET_MIPS64) 2639 case OPC_DADD: 2640 { 2641 TCGv t0 = tcg_temp_new(); 2642 TCGv t1 = tcg_temp_new(); 2643 TCGv t2 = tcg_temp_new(); 2644 TCGLabel *l1 = gen_new_label(); 2645 2646 gen_load_gpr(t1, rs); 2647 gen_load_gpr(t2, rt); 2648 tcg_gen_add_tl(t0, t1, t2); 2649 tcg_gen_xor_tl(t1, t1, t2); 2650 tcg_gen_xor_tl(t2, t0, t2); 2651 tcg_gen_andc_tl(t1, t2, t1); 2652 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2653 /* operands of same sign, result different sign */ 2654 generate_exception(ctx, EXCP_OVERFLOW); 2655 gen_set_label(l1); 2656 gen_store_gpr(t0, rd); 2657 } 2658 break; 2659 case OPC_DADDU: 2660 if (rs != 0 && rt != 0) { 2661 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2662 } else if (rs == 0 && rt != 0) { 2663 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2664 } else if (rs != 0 && rt == 0) { 2665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2666 } else { 2667 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2668 } 2669 break; 2670 case OPC_DSUB: 2671 { 2672 TCGv t0 = tcg_temp_new(); 2673 TCGv t1 = tcg_temp_new(); 2674 TCGv t2 = tcg_temp_new(); 2675 TCGLabel *l1 = gen_new_label(); 2676 2677 gen_load_gpr(t1, rs); 2678 gen_load_gpr(t2, rt); 2679 tcg_gen_sub_tl(t0, t1, t2); 2680 tcg_gen_xor_tl(t2, t1, t2); 2681 tcg_gen_xor_tl(t1, t0, t1); 2682 tcg_gen_and_tl(t1, t1, t2); 2683 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2684 /* 2685 * Operands of different sign, first operand and result different 2686 * sign. 2687 */ 2688 generate_exception(ctx, EXCP_OVERFLOW); 2689 gen_set_label(l1); 2690 gen_store_gpr(t0, rd); 2691 } 2692 break; 2693 case OPC_DSUBU: 2694 if (rs != 0 && rt != 0) { 2695 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2696 } else if (rs == 0 && rt != 0) { 2697 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2698 } else if (rs != 0 && rt == 0) { 2699 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2700 } else { 2701 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2702 } 2703 break; 2704 #endif 2705 case OPC_MUL: 2706 if (likely(rs != 0 && rt != 0)) { 2707 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2708 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2709 } else { 2710 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2711 } 2712 break; 2713 } 2714 } 2715 2716 /* Conditional move */ 2717 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2718 int rd, int rs, int rt) 2719 { 2720 TCGv t0, t1, t2; 2721 2722 if (rd == 0) { 2723 /* If no destination, treat it as a NOP. */ 2724 return; 2725 } 2726 2727 t0 = tcg_temp_new(); 2728 gen_load_gpr(t0, rt); 2729 t1 = tcg_constant_tl(0); 2730 t2 = tcg_temp_new(); 2731 gen_load_gpr(t2, rs); 2732 switch (opc) { 2733 case OPC_MOVN: 2734 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2735 break; 2736 case OPC_MOVZ: 2737 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2738 break; 2739 case OPC_SELNEZ: 2740 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2741 break; 2742 case OPC_SELEQZ: 2743 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2744 break; 2745 } 2746 } 2747 2748 /* Logic */ 2749 static void gen_logic(DisasContext *ctx, uint32_t opc, 2750 int rd, int rs, int rt) 2751 { 2752 if (rd == 0) { 2753 /* If no destination, treat it as a NOP. */ 2754 return; 2755 } 2756 2757 switch (opc) { 2758 case OPC_AND: 2759 if (likely(rs != 0 && rt != 0)) { 2760 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2761 } else { 2762 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2763 } 2764 break; 2765 case OPC_NOR: 2766 if (rs != 0 && rt != 0) { 2767 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2768 } else if (rs == 0 && rt != 0) { 2769 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2770 } else if (rs != 0 && rt == 0) { 2771 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2772 } else { 2773 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2774 } 2775 break; 2776 case OPC_OR: 2777 if (likely(rs != 0 && rt != 0)) { 2778 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2779 } else if (rs == 0 && rt != 0) { 2780 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2781 } else if (rs != 0 && rt == 0) { 2782 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2783 } else { 2784 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2785 } 2786 break; 2787 case OPC_XOR: 2788 if (likely(rs != 0 && rt != 0)) { 2789 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2790 } else if (rs == 0 && rt != 0) { 2791 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2792 } else if (rs != 0 && rt == 0) { 2793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2794 } else { 2795 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2796 } 2797 break; 2798 } 2799 } 2800 2801 /* Set on lower than */ 2802 static void gen_slt(DisasContext *ctx, uint32_t opc, 2803 int rd, int rs, int rt) 2804 { 2805 TCGv t0, t1; 2806 2807 if (rd == 0) { 2808 /* If no destination, treat it as a NOP. */ 2809 return; 2810 } 2811 2812 t0 = tcg_temp_new(); 2813 t1 = tcg_temp_new(); 2814 gen_load_gpr(t0, rs); 2815 gen_load_gpr(t1, rt); 2816 switch (opc) { 2817 case OPC_SLT: 2818 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2819 break; 2820 case OPC_SLTU: 2821 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2822 break; 2823 } 2824 } 2825 2826 /* Shifts */ 2827 static void gen_shift(DisasContext *ctx, uint32_t opc, 2828 int rd, int rs, int rt) 2829 { 2830 TCGv t0, t1; 2831 2832 if (rd == 0) { 2833 /* 2834 * If no destination, treat it as a NOP. 2835 * For add & sub, we must generate the overflow exception when needed. 2836 */ 2837 return; 2838 } 2839 2840 t0 = tcg_temp_new(); 2841 t1 = tcg_temp_new(); 2842 gen_load_gpr(t0, rs); 2843 gen_load_gpr(t1, rt); 2844 switch (opc) { 2845 case OPC_SLLV: 2846 tcg_gen_andi_tl(t0, t0, 0x1f); 2847 tcg_gen_shl_tl(t0, t1, t0); 2848 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2849 break; 2850 case OPC_SRAV: 2851 tcg_gen_andi_tl(t0, t0, 0x1f); 2852 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2853 break; 2854 case OPC_SRLV: 2855 tcg_gen_ext32u_tl(t1, t1); 2856 tcg_gen_andi_tl(t0, t0, 0x1f); 2857 tcg_gen_shr_tl(t0, t1, t0); 2858 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2859 break; 2860 case OPC_ROTRV: 2861 { 2862 TCGv_i32 t2 = tcg_temp_new_i32(); 2863 TCGv_i32 t3 = tcg_temp_new_i32(); 2864 2865 tcg_gen_trunc_tl_i32(t2, t0); 2866 tcg_gen_trunc_tl_i32(t3, t1); 2867 tcg_gen_andi_i32(t2, t2, 0x1f); 2868 tcg_gen_rotr_i32(t2, t3, t2); 2869 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2870 } 2871 break; 2872 #if defined(TARGET_MIPS64) 2873 case OPC_DSLLV: 2874 tcg_gen_andi_tl(t0, t0, 0x3f); 2875 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2876 break; 2877 case OPC_DSRAV: 2878 tcg_gen_andi_tl(t0, t0, 0x3f); 2879 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2880 break; 2881 case OPC_DSRLV: 2882 tcg_gen_andi_tl(t0, t0, 0x3f); 2883 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2884 break; 2885 case OPC_DROTRV: 2886 tcg_gen_andi_tl(t0, t0, 0x3f); 2887 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2888 break; 2889 #endif 2890 } 2891 } 2892 2893 /* Arithmetic on HI/LO registers */ 2894 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2895 { 2896 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2897 /* Treat as NOP. */ 2898 return; 2899 } 2900 2901 if (acc != 0) { 2902 check_dsp(ctx); 2903 } 2904 2905 switch (opc) { 2906 case OPC_MFHI: 2907 #if defined(TARGET_MIPS64) 2908 if (acc != 0) { 2909 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2910 } else 2911 #endif 2912 { 2913 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2914 } 2915 break; 2916 case OPC_MFLO: 2917 #if defined(TARGET_MIPS64) 2918 if (acc != 0) { 2919 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2920 } else 2921 #endif 2922 { 2923 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2924 } 2925 break; 2926 case OPC_MTHI: 2927 if (reg != 0) { 2928 #if defined(TARGET_MIPS64) 2929 if (acc != 0) { 2930 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2931 } else 2932 #endif 2933 { 2934 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2935 } 2936 } else { 2937 tcg_gen_movi_tl(cpu_HI[acc], 0); 2938 } 2939 break; 2940 case OPC_MTLO: 2941 if (reg != 0) { 2942 #if defined(TARGET_MIPS64) 2943 if (acc != 0) { 2944 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2945 } else 2946 #endif 2947 { 2948 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2949 } 2950 } else { 2951 tcg_gen_movi_tl(cpu_LO[acc], 0); 2952 } 2953 break; 2954 } 2955 } 2956 2957 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2958 MemOp memop) 2959 { 2960 TCGv t0 = tcg_temp_new(); 2961 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2962 gen_store_gpr(t0, reg); 2963 } 2964 2965 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2966 int rs) 2967 { 2968 target_long offset; 2969 target_long addr; 2970 2971 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2972 case OPC_ADDIUPC: 2973 if (rs != 0) { 2974 offset = sextract32(ctx->opcode << 2, 0, 21); 2975 addr = addr_add(ctx, pc, offset); 2976 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2977 } 2978 break; 2979 case R6_OPC_LWPC: 2980 offset = sextract32(ctx->opcode << 2, 0, 21); 2981 addr = addr_add(ctx, pc, offset); 2982 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2983 break; 2984 #if defined(TARGET_MIPS64) 2985 case OPC_LWUPC: 2986 check_mips_64(ctx); 2987 offset = sextract32(ctx->opcode << 2, 0, 21); 2988 addr = addr_add(ctx, pc, offset); 2989 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2990 break; 2991 #endif 2992 default: 2993 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2994 case OPC_AUIPC: 2995 if (rs != 0) { 2996 offset = sextract32(ctx->opcode, 0, 16) << 16; 2997 addr = addr_add(ctx, pc, offset); 2998 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2999 } 3000 break; 3001 case OPC_ALUIPC: 3002 if (rs != 0) { 3003 offset = sextract32(ctx->opcode, 0, 16) << 16; 3004 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3005 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3006 } 3007 break; 3008 #if defined(TARGET_MIPS64) 3009 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3010 case R6_OPC_LDPC + (1 << 16): 3011 case R6_OPC_LDPC + (2 << 16): 3012 case R6_OPC_LDPC + (3 << 16): 3013 check_mips_64(ctx); 3014 offset = sextract32(ctx->opcode << 3, 0, 21); 3015 addr = addr_add(ctx, (pc & ~0x7), offset); 3016 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 3017 break; 3018 #endif 3019 default: 3020 MIPS_INVAL("OPC_PCREL"); 3021 gen_reserved_instruction(ctx); 3022 break; 3023 } 3024 break; 3025 } 3026 } 3027 3028 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3029 { 3030 TCGv t0, t1; 3031 3032 if (rd == 0) { 3033 /* Treat as NOP. */ 3034 return; 3035 } 3036 3037 t0 = tcg_temp_new(); 3038 t1 = tcg_temp_new(); 3039 3040 gen_load_gpr(t0, rs); 3041 gen_load_gpr(t1, rt); 3042 3043 switch (opc) { 3044 case R6_OPC_DIV: 3045 { 3046 TCGv t2 = tcg_temp_new(); 3047 TCGv t3 = tcg_temp_new(); 3048 tcg_gen_ext32s_tl(t0, t0); 3049 tcg_gen_ext32s_tl(t1, t1); 3050 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3051 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3052 tcg_gen_and_tl(t2, t2, t3); 3053 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3054 tcg_gen_or_tl(t2, t2, t3); 3055 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3056 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3057 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3058 } 3059 break; 3060 case R6_OPC_MOD: 3061 { 3062 TCGv t2 = tcg_temp_new(); 3063 TCGv t3 = tcg_temp_new(); 3064 tcg_gen_ext32s_tl(t0, t0); 3065 tcg_gen_ext32s_tl(t1, t1); 3066 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3067 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3068 tcg_gen_and_tl(t2, t2, t3); 3069 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3070 tcg_gen_or_tl(t2, t2, t3); 3071 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3072 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3074 } 3075 break; 3076 case R6_OPC_DIVU: 3077 { 3078 tcg_gen_ext32u_tl(t0, t0); 3079 tcg_gen_ext32u_tl(t1, t1); 3080 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3081 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3082 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3083 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3084 } 3085 break; 3086 case R6_OPC_MODU: 3087 { 3088 tcg_gen_ext32u_tl(t0, t0); 3089 tcg_gen_ext32u_tl(t1, t1); 3090 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3091 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3092 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3093 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3094 } 3095 break; 3096 case R6_OPC_MUL: 3097 { 3098 TCGv_i32 t2 = tcg_temp_new_i32(); 3099 TCGv_i32 t3 = tcg_temp_new_i32(); 3100 tcg_gen_trunc_tl_i32(t2, t0); 3101 tcg_gen_trunc_tl_i32(t3, t1); 3102 tcg_gen_mul_i32(t2, t2, t3); 3103 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3104 } 3105 break; 3106 case R6_OPC_MUH: 3107 { 3108 TCGv_i32 t2 = tcg_temp_new_i32(); 3109 TCGv_i32 t3 = tcg_temp_new_i32(); 3110 tcg_gen_trunc_tl_i32(t2, t0); 3111 tcg_gen_trunc_tl_i32(t3, t1); 3112 tcg_gen_muls2_i32(t2, t3, t2, t3); 3113 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3114 } 3115 break; 3116 case R6_OPC_MULU: 3117 { 3118 TCGv_i32 t2 = tcg_temp_new_i32(); 3119 TCGv_i32 t3 = tcg_temp_new_i32(); 3120 tcg_gen_trunc_tl_i32(t2, t0); 3121 tcg_gen_trunc_tl_i32(t3, t1); 3122 tcg_gen_mul_i32(t2, t2, t3); 3123 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3124 } 3125 break; 3126 case R6_OPC_MUHU: 3127 { 3128 TCGv_i32 t2 = tcg_temp_new_i32(); 3129 TCGv_i32 t3 = tcg_temp_new_i32(); 3130 tcg_gen_trunc_tl_i32(t2, t0); 3131 tcg_gen_trunc_tl_i32(t3, t1); 3132 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3133 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3134 } 3135 break; 3136 #if defined(TARGET_MIPS64) 3137 case R6_OPC_DDIV: 3138 { 3139 TCGv t2 = tcg_temp_new(); 3140 TCGv t3 = tcg_temp_new(); 3141 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3142 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3143 tcg_gen_and_tl(t2, t2, t3); 3144 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3145 tcg_gen_or_tl(t2, t2, t3); 3146 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3147 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3148 } 3149 break; 3150 case R6_OPC_DMOD: 3151 { 3152 TCGv t2 = tcg_temp_new(); 3153 TCGv t3 = tcg_temp_new(); 3154 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3155 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3156 tcg_gen_and_tl(t2, t2, t3); 3157 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3158 tcg_gen_or_tl(t2, t2, t3); 3159 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3160 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3161 } 3162 break; 3163 case R6_OPC_DDIVU: 3164 { 3165 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3166 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3167 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3168 } 3169 break; 3170 case R6_OPC_DMODU: 3171 { 3172 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3173 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3174 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3175 } 3176 break; 3177 case R6_OPC_DMUL: 3178 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3179 break; 3180 case R6_OPC_DMUH: 3181 { 3182 TCGv t2 = tcg_temp_new(); 3183 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3184 } 3185 break; 3186 case R6_OPC_DMULU: 3187 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3188 break; 3189 case R6_OPC_DMUHU: 3190 { 3191 TCGv t2 = tcg_temp_new(); 3192 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3193 } 3194 break; 3195 #endif 3196 default: 3197 MIPS_INVAL("r6 mul/div"); 3198 gen_reserved_instruction(ctx); 3199 break; 3200 } 3201 } 3202 3203 #if defined(TARGET_MIPS64) 3204 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3205 { 3206 TCGv t0, t1; 3207 3208 t0 = tcg_temp_new(); 3209 t1 = tcg_temp_new(); 3210 3211 gen_load_gpr(t0, rs); 3212 gen_load_gpr(t1, rt); 3213 3214 switch (opc) { 3215 case MMI_OPC_DIV1: 3216 { 3217 TCGv t2 = tcg_temp_new(); 3218 TCGv t3 = tcg_temp_new(); 3219 tcg_gen_ext32s_tl(t0, t0); 3220 tcg_gen_ext32s_tl(t1, t1); 3221 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3222 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3223 tcg_gen_and_tl(t2, t2, t3); 3224 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3225 tcg_gen_or_tl(t2, t2, t3); 3226 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3227 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3228 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3229 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3230 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3231 } 3232 break; 3233 case MMI_OPC_DIVU1: 3234 { 3235 TCGv t2 = tcg_constant_tl(0); 3236 TCGv t3 = tcg_constant_tl(1); 3237 tcg_gen_ext32u_tl(t0, t0); 3238 tcg_gen_ext32u_tl(t1, t1); 3239 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3240 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3241 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3242 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3243 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3244 } 3245 break; 3246 default: 3247 MIPS_INVAL("div1 TX79"); 3248 gen_reserved_instruction(ctx); 3249 break; 3250 } 3251 } 3252 #endif 3253 3254 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3255 int acc, int rs, int rt) 3256 { 3257 TCGv t0, t1; 3258 3259 t0 = tcg_temp_new(); 3260 t1 = tcg_temp_new(); 3261 3262 gen_load_gpr(t0, rs); 3263 gen_load_gpr(t1, rt); 3264 3265 if (acc != 0) { 3266 check_dsp(ctx); 3267 } 3268 3269 switch (opc) { 3270 case OPC_DIV: 3271 { 3272 TCGv t2 = tcg_temp_new(); 3273 TCGv t3 = tcg_temp_new(); 3274 tcg_gen_ext32s_tl(t0, t0); 3275 tcg_gen_ext32s_tl(t1, t1); 3276 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3277 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3278 tcg_gen_and_tl(t2, t2, t3); 3279 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3280 tcg_gen_or_tl(t2, t2, t3); 3281 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3282 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3283 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3284 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3285 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3286 } 3287 break; 3288 case OPC_DIVU: 3289 { 3290 TCGv t2 = tcg_constant_tl(0); 3291 TCGv t3 = tcg_constant_tl(1); 3292 tcg_gen_ext32u_tl(t0, t0); 3293 tcg_gen_ext32u_tl(t1, t1); 3294 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3295 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3296 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3297 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3298 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3299 } 3300 break; 3301 case OPC_MULT: 3302 { 3303 TCGv_i32 t2 = tcg_temp_new_i32(); 3304 TCGv_i32 t3 = tcg_temp_new_i32(); 3305 tcg_gen_trunc_tl_i32(t2, t0); 3306 tcg_gen_trunc_tl_i32(t3, t1); 3307 tcg_gen_muls2_i32(t2, t3, t2, t3); 3308 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3309 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3310 } 3311 break; 3312 case OPC_MULTU: 3313 { 3314 TCGv_i32 t2 = tcg_temp_new_i32(); 3315 TCGv_i32 t3 = tcg_temp_new_i32(); 3316 tcg_gen_trunc_tl_i32(t2, t0); 3317 tcg_gen_trunc_tl_i32(t3, t1); 3318 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3319 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3320 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3321 } 3322 break; 3323 #if defined(TARGET_MIPS64) 3324 case OPC_DDIV: 3325 { 3326 TCGv t2 = tcg_temp_new(); 3327 TCGv t3 = tcg_temp_new(); 3328 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3329 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3330 tcg_gen_and_tl(t2, t2, t3); 3331 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3332 tcg_gen_or_tl(t2, t2, t3); 3333 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3334 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3335 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3336 } 3337 break; 3338 case OPC_DDIVU: 3339 { 3340 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3341 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3342 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3343 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3344 } 3345 break; 3346 case OPC_DMULT: 3347 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3348 break; 3349 case OPC_DMULTU: 3350 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3351 break; 3352 #endif 3353 case OPC_MADD: 3354 { 3355 TCGv_i64 t2 = tcg_temp_new_i64(); 3356 TCGv_i64 t3 = tcg_temp_new_i64(); 3357 3358 tcg_gen_ext_tl_i64(t2, t0); 3359 tcg_gen_ext_tl_i64(t3, t1); 3360 tcg_gen_mul_i64(t2, t2, t3); 3361 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3362 tcg_gen_add_i64(t2, t2, t3); 3363 gen_move_low32(cpu_LO[acc], t2); 3364 gen_move_high32(cpu_HI[acc], t2); 3365 } 3366 break; 3367 case OPC_MADDU: 3368 { 3369 TCGv_i64 t2 = tcg_temp_new_i64(); 3370 TCGv_i64 t3 = tcg_temp_new_i64(); 3371 3372 tcg_gen_ext32u_tl(t0, t0); 3373 tcg_gen_ext32u_tl(t1, t1); 3374 tcg_gen_extu_tl_i64(t2, t0); 3375 tcg_gen_extu_tl_i64(t3, t1); 3376 tcg_gen_mul_i64(t2, t2, t3); 3377 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3378 tcg_gen_add_i64(t2, t2, t3); 3379 gen_move_low32(cpu_LO[acc], t2); 3380 gen_move_high32(cpu_HI[acc], t2); 3381 } 3382 break; 3383 case OPC_MSUB: 3384 { 3385 TCGv_i64 t2 = tcg_temp_new_i64(); 3386 TCGv_i64 t3 = tcg_temp_new_i64(); 3387 3388 tcg_gen_ext_tl_i64(t2, t0); 3389 tcg_gen_ext_tl_i64(t3, t1); 3390 tcg_gen_mul_i64(t2, t2, t3); 3391 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3392 tcg_gen_sub_i64(t2, t3, t2); 3393 gen_move_low32(cpu_LO[acc], t2); 3394 gen_move_high32(cpu_HI[acc], t2); 3395 } 3396 break; 3397 case OPC_MSUBU: 3398 { 3399 TCGv_i64 t2 = tcg_temp_new_i64(); 3400 TCGv_i64 t3 = tcg_temp_new_i64(); 3401 3402 tcg_gen_ext32u_tl(t0, t0); 3403 tcg_gen_ext32u_tl(t1, t1); 3404 tcg_gen_extu_tl_i64(t2, t0); 3405 tcg_gen_extu_tl_i64(t3, t1); 3406 tcg_gen_mul_i64(t2, t2, t3); 3407 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3408 tcg_gen_sub_i64(t2, t3, t2); 3409 gen_move_low32(cpu_LO[acc], t2); 3410 gen_move_high32(cpu_HI[acc], t2); 3411 } 3412 break; 3413 default: 3414 MIPS_INVAL("mul/div"); 3415 gen_reserved_instruction(ctx); 3416 break; 3417 } 3418 } 3419 3420 /* 3421 * These MULT[U] and MADD[U] instructions implemented in for example 3422 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3423 * architectures are special three-operand variants with the syntax 3424 * 3425 * MULT[U][1] rd, rs, rt 3426 * 3427 * such that 3428 * 3429 * (rd, LO, HI) <- rs * rt 3430 * 3431 * and 3432 * 3433 * MADD[U][1] rd, rs, rt 3434 * 3435 * such that 3436 * 3437 * (rd, LO, HI) <- (LO, HI) + rs * rt 3438 * 3439 * where the low-order 32-bits of the result is placed into both the 3440 * GPR rd and the special register LO. The high-order 32-bits of the 3441 * result is placed into the special register HI. 3442 * 3443 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3444 * which is the zero register that always reads as 0. 3445 */ 3446 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3447 int rd, int rs, int rt) 3448 { 3449 TCGv t0 = tcg_temp_new(); 3450 TCGv t1 = tcg_temp_new(); 3451 int acc = 0; 3452 3453 gen_load_gpr(t0, rs); 3454 gen_load_gpr(t1, rt); 3455 3456 switch (opc) { 3457 case MMI_OPC_MULT1: 3458 acc = 1; 3459 /* Fall through */ 3460 case OPC_MULT: 3461 { 3462 TCGv_i32 t2 = tcg_temp_new_i32(); 3463 TCGv_i32 t3 = tcg_temp_new_i32(); 3464 tcg_gen_trunc_tl_i32(t2, t0); 3465 tcg_gen_trunc_tl_i32(t3, t1); 3466 tcg_gen_muls2_i32(t2, t3, t2, t3); 3467 if (rd) { 3468 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3469 } 3470 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3471 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3472 } 3473 break; 3474 case MMI_OPC_MULTU1: 3475 acc = 1; 3476 /* Fall through */ 3477 case OPC_MULTU: 3478 { 3479 TCGv_i32 t2 = tcg_temp_new_i32(); 3480 TCGv_i32 t3 = tcg_temp_new_i32(); 3481 tcg_gen_trunc_tl_i32(t2, t0); 3482 tcg_gen_trunc_tl_i32(t3, t1); 3483 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3484 if (rd) { 3485 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3486 } 3487 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3488 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3489 } 3490 break; 3491 case MMI_OPC_MADD1: 3492 acc = 1; 3493 /* Fall through */ 3494 case MMI_OPC_MADD: 3495 { 3496 TCGv_i64 t2 = tcg_temp_new_i64(); 3497 TCGv_i64 t3 = tcg_temp_new_i64(); 3498 3499 tcg_gen_ext_tl_i64(t2, t0); 3500 tcg_gen_ext_tl_i64(t3, t1); 3501 tcg_gen_mul_i64(t2, t2, t3); 3502 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3503 tcg_gen_add_i64(t2, t2, t3); 3504 gen_move_low32(cpu_LO[acc], t2); 3505 gen_move_high32(cpu_HI[acc], t2); 3506 if (rd) { 3507 gen_move_low32(cpu_gpr[rd], t2); 3508 } 3509 } 3510 break; 3511 case MMI_OPC_MADDU1: 3512 acc = 1; 3513 /* Fall through */ 3514 case MMI_OPC_MADDU: 3515 { 3516 TCGv_i64 t2 = tcg_temp_new_i64(); 3517 TCGv_i64 t3 = tcg_temp_new_i64(); 3518 3519 tcg_gen_ext32u_tl(t0, t0); 3520 tcg_gen_ext32u_tl(t1, t1); 3521 tcg_gen_extu_tl_i64(t2, t0); 3522 tcg_gen_extu_tl_i64(t3, t1); 3523 tcg_gen_mul_i64(t2, t2, t3); 3524 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3525 tcg_gen_add_i64(t2, t2, t3); 3526 gen_move_low32(cpu_LO[acc], t2); 3527 gen_move_high32(cpu_HI[acc], t2); 3528 if (rd) { 3529 gen_move_low32(cpu_gpr[rd], t2); 3530 } 3531 } 3532 break; 3533 default: 3534 MIPS_INVAL("mul/madd TXx9"); 3535 gen_reserved_instruction(ctx); 3536 break; 3537 } 3538 } 3539 3540 static void gen_cl(DisasContext *ctx, uint32_t opc, 3541 int rd, int rs) 3542 { 3543 TCGv t0; 3544 3545 if (rd == 0) { 3546 /* Treat as NOP. */ 3547 return; 3548 } 3549 t0 = cpu_gpr[rd]; 3550 gen_load_gpr(t0, rs); 3551 3552 switch (opc) { 3553 case OPC_CLO: 3554 case R6_OPC_CLO: 3555 #if defined(TARGET_MIPS64) 3556 case OPC_DCLO: 3557 case R6_OPC_DCLO: 3558 #endif 3559 tcg_gen_not_tl(t0, t0); 3560 break; 3561 } 3562 3563 switch (opc) { 3564 case OPC_CLO: 3565 case R6_OPC_CLO: 3566 case OPC_CLZ: 3567 case R6_OPC_CLZ: 3568 tcg_gen_ext32u_tl(t0, t0); 3569 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3570 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3571 break; 3572 #if defined(TARGET_MIPS64) 3573 case OPC_DCLO: 3574 case R6_OPC_DCLO: 3575 case OPC_DCLZ: 3576 case R6_OPC_DCLZ: 3577 tcg_gen_clzi_i64(t0, t0, 64); 3578 break; 3579 #endif 3580 } 3581 } 3582 3583 /* Godson integer instructions */ 3584 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3585 int rd, int rs, int rt) 3586 { 3587 TCGv t0, t1; 3588 3589 if (rd == 0) { 3590 /* Treat as NOP. */ 3591 return; 3592 } 3593 3594 t0 = tcg_temp_new(); 3595 t1 = tcg_temp_new(); 3596 gen_load_gpr(t0, rs); 3597 gen_load_gpr(t1, rt); 3598 3599 switch (opc) { 3600 case OPC_MULT_G_2E: 3601 case OPC_MULT_G_2F: 3602 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3603 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3604 break; 3605 case OPC_MULTU_G_2E: 3606 case OPC_MULTU_G_2F: 3607 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3608 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3609 break; 3610 case OPC_MOD_G_2E: 3611 case OPC_MOD_G_2F: 3612 { 3613 TCGLabel *l1 = gen_new_label(); 3614 TCGLabel *l2 = gen_new_label(); 3615 TCGLabel *l3 = gen_new_label(); 3616 tcg_gen_ext32u_tl(t0, t0); 3617 tcg_gen_ext32u_tl(t1, t1); 3618 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3619 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3620 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3621 gen_set_label(l1); 3622 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3623 tcg_gen_br(l3); 3624 gen_set_label(l2); 3625 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3626 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3627 gen_set_label(l3); 3628 } 3629 break; 3630 case OPC_MODU_G_2E: 3631 case OPC_MODU_G_2F: 3632 { 3633 TCGLabel *l1 = gen_new_label(); 3634 TCGLabel *l2 = gen_new_label(); 3635 tcg_gen_ext32u_tl(t0, t0); 3636 tcg_gen_ext32u_tl(t1, t1); 3637 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3638 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3639 tcg_gen_br(l2); 3640 gen_set_label(l1); 3641 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3642 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3643 gen_set_label(l2); 3644 } 3645 break; 3646 #if defined(TARGET_MIPS64) 3647 case OPC_DMULT_G_2E: 3648 case OPC_DMULT_G_2F: 3649 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3650 break; 3651 case OPC_DMULTU_G_2E: 3652 case OPC_DMULTU_G_2F: 3653 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3654 break; 3655 case OPC_DMOD_G_2E: 3656 case OPC_DMOD_G_2F: 3657 { 3658 TCGLabel *l1 = gen_new_label(); 3659 TCGLabel *l2 = gen_new_label(); 3660 TCGLabel *l3 = gen_new_label(); 3661 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3662 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3663 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3664 gen_set_label(l1); 3665 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3666 tcg_gen_br(l3); 3667 gen_set_label(l2); 3668 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3669 gen_set_label(l3); 3670 } 3671 break; 3672 case OPC_DMODU_G_2E: 3673 case OPC_DMODU_G_2F: 3674 { 3675 TCGLabel *l1 = gen_new_label(); 3676 TCGLabel *l2 = gen_new_label(); 3677 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3678 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3679 tcg_gen_br(l2); 3680 gen_set_label(l1); 3681 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3682 gen_set_label(l2); 3683 } 3684 break; 3685 #endif 3686 } 3687 } 3688 3689 /* Loongson multimedia instructions */ 3690 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3691 { 3692 uint32_t opc, shift_max; 3693 TCGv_i64 t0, t1; 3694 TCGCond cond; 3695 3696 opc = MASK_LMMI(ctx->opcode); 3697 check_cp1_enabled(ctx); 3698 3699 t0 = tcg_temp_new_i64(); 3700 t1 = tcg_temp_new_i64(); 3701 gen_load_fpr64(ctx, t0, rs); 3702 gen_load_fpr64(ctx, t1, rt); 3703 3704 switch (opc) { 3705 case OPC_PADDSH: 3706 gen_helper_paddsh(t0, t0, t1); 3707 break; 3708 case OPC_PADDUSH: 3709 gen_helper_paddush(t0, t0, t1); 3710 break; 3711 case OPC_PADDH: 3712 gen_helper_paddh(t0, t0, t1); 3713 break; 3714 case OPC_PADDW: 3715 gen_helper_paddw(t0, t0, t1); 3716 break; 3717 case OPC_PADDSB: 3718 gen_helper_paddsb(t0, t0, t1); 3719 break; 3720 case OPC_PADDUSB: 3721 gen_helper_paddusb(t0, t0, t1); 3722 break; 3723 case OPC_PADDB: 3724 gen_helper_paddb(t0, t0, t1); 3725 break; 3726 3727 case OPC_PSUBSH: 3728 gen_helper_psubsh(t0, t0, t1); 3729 break; 3730 case OPC_PSUBUSH: 3731 gen_helper_psubush(t0, t0, t1); 3732 break; 3733 case OPC_PSUBH: 3734 gen_helper_psubh(t0, t0, t1); 3735 break; 3736 case OPC_PSUBW: 3737 gen_helper_psubw(t0, t0, t1); 3738 break; 3739 case OPC_PSUBSB: 3740 gen_helper_psubsb(t0, t0, t1); 3741 break; 3742 case OPC_PSUBUSB: 3743 gen_helper_psubusb(t0, t0, t1); 3744 break; 3745 case OPC_PSUBB: 3746 gen_helper_psubb(t0, t0, t1); 3747 break; 3748 3749 case OPC_PSHUFH: 3750 gen_helper_pshufh(t0, t0, t1); 3751 break; 3752 case OPC_PACKSSWH: 3753 gen_helper_packsswh(t0, t0, t1); 3754 break; 3755 case OPC_PACKSSHB: 3756 gen_helper_packsshb(t0, t0, t1); 3757 break; 3758 case OPC_PACKUSHB: 3759 gen_helper_packushb(t0, t0, t1); 3760 break; 3761 3762 case OPC_PUNPCKLHW: 3763 gen_helper_punpcklhw(t0, t0, t1); 3764 break; 3765 case OPC_PUNPCKHHW: 3766 gen_helper_punpckhhw(t0, t0, t1); 3767 break; 3768 case OPC_PUNPCKLBH: 3769 gen_helper_punpcklbh(t0, t0, t1); 3770 break; 3771 case OPC_PUNPCKHBH: 3772 gen_helper_punpckhbh(t0, t0, t1); 3773 break; 3774 case OPC_PUNPCKLWD: 3775 gen_helper_punpcklwd(t0, t0, t1); 3776 break; 3777 case OPC_PUNPCKHWD: 3778 gen_helper_punpckhwd(t0, t0, t1); 3779 break; 3780 3781 case OPC_PAVGH: 3782 gen_helper_pavgh(t0, t0, t1); 3783 break; 3784 case OPC_PAVGB: 3785 gen_helper_pavgb(t0, t0, t1); 3786 break; 3787 case OPC_PMAXSH: 3788 gen_helper_pmaxsh(t0, t0, t1); 3789 break; 3790 case OPC_PMINSH: 3791 gen_helper_pminsh(t0, t0, t1); 3792 break; 3793 case OPC_PMAXUB: 3794 gen_helper_pmaxub(t0, t0, t1); 3795 break; 3796 case OPC_PMINUB: 3797 gen_helper_pminub(t0, t0, t1); 3798 break; 3799 3800 case OPC_PCMPEQW: 3801 gen_helper_pcmpeqw(t0, t0, t1); 3802 break; 3803 case OPC_PCMPGTW: 3804 gen_helper_pcmpgtw(t0, t0, t1); 3805 break; 3806 case OPC_PCMPEQH: 3807 gen_helper_pcmpeqh(t0, t0, t1); 3808 break; 3809 case OPC_PCMPGTH: 3810 gen_helper_pcmpgth(t0, t0, t1); 3811 break; 3812 case OPC_PCMPEQB: 3813 gen_helper_pcmpeqb(t0, t0, t1); 3814 break; 3815 case OPC_PCMPGTB: 3816 gen_helper_pcmpgtb(t0, t0, t1); 3817 break; 3818 3819 case OPC_PSLLW: 3820 gen_helper_psllw(t0, t0, t1); 3821 break; 3822 case OPC_PSLLH: 3823 gen_helper_psllh(t0, t0, t1); 3824 break; 3825 case OPC_PSRLW: 3826 gen_helper_psrlw(t0, t0, t1); 3827 break; 3828 case OPC_PSRLH: 3829 gen_helper_psrlh(t0, t0, t1); 3830 break; 3831 case OPC_PSRAW: 3832 gen_helper_psraw(t0, t0, t1); 3833 break; 3834 case OPC_PSRAH: 3835 gen_helper_psrah(t0, t0, t1); 3836 break; 3837 3838 case OPC_PMULLH: 3839 gen_helper_pmullh(t0, t0, t1); 3840 break; 3841 case OPC_PMULHH: 3842 gen_helper_pmulhh(t0, t0, t1); 3843 break; 3844 case OPC_PMULHUH: 3845 gen_helper_pmulhuh(t0, t0, t1); 3846 break; 3847 case OPC_PMADDHW: 3848 gen_helper_pmaddhw(t0, t0, t1); 3849 break; 3850 3851 case OPC_PASUBUB: 3852 gen_helper_pasubub(t0, t0, t1); 3853 break; 3854 case OPC_BIADD: 3855 gen_helper_biadd(t0, t0); 3856 break; 3857 case OPC_PMOVMSKB: 3858 gen_helper_pmovmskb(t0, t0); 3859 break; 3860 3861 case OPC_PADDD: 3862 tcg_gen_add_i64(t0, t0, t1); 3863 break; 3864 case OPC_PSUBD: 3865 tcg_gen_sub_i64(t0, t0, t1); 3866 break; 3867 case OPC_XOR_CP2: 3868 tcg_gen_xor_i64(t0, t0, t1); 3869 break; 3870 case OPC_NOR_CP2: 3871 tcg_gen_nor_i64(t0, t0, t1); 3872 break; 3873 case OPC_AND_CP2: 3874 tcg_gen_and_i64(t0, t0, t1); 3875 break; 3876 case OPC_OR_CP2: 3877 tcg_gen_or_i64(t0, t0, t1); 3878 break; 3879 3880 case OPC_PANDN: 3881 tcg_gen_andc_i64(t0, t1, t0); 3882 break; 3883 3884 case OPC_PINSRH_0: 3885 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3886 break; 3887 case OPC_PINSRH_1: 3888 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3889 break; 3890 case OPC_PINSRH_2: 3891 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3892 break; 3893 case OPC_PINSRH_3: 3894 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3895 break; 3896 3897 case OPC_PEXTRH: 3898 tcg_gen_andi_i64(t1, t1, 3); 3899 tcg_gen_shli_i64(t1, t1, 4); 3900 tcg_gen_shr_i64(t0, t0, t1); 3901 tcg_gen_ext16u_i64(t0, t0); 3902 break; 3903 3904 case OPC_ADDU_CP2: 3905 tcg_gen_add_i64(t0, t0, t1); 3906 tcg_gen_ext32s_i64(t0, t0); 3907 break; 3908 case OPC_SUBU_CP2: 3909 tcg_gen_sub_i64(t0, t0, t1); 3910 tcg_gen_ext32s_i64(t0, t0); 3911 break; 3912 3913 case OPC_SLL_CP2: 3914 shift_max = 32; 3915 goto do_shift; 3916 case OPC_SRL_CP2: 3917 shift_max = 32; 3918 goto do_shift; 3919 case OPC_SRA_CP2: 3920 shift_max = 32; 3921 goto do_shift; 3922 case OPC_DSLL_CP2: 3923 shift_max = 64; 3924 goto do_shift; 3925 case OPC_DSRL_CP2: 3926 shift_max = 64; 3927 goto do_shift; 3928 case OPC_DSRA_CP2: 3929 shift_max = 64; 3930 goto do_shift; 3931 do_shift: 3932 /* Make sure shift count isn't TCG undefined behaviour. */ 3933 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3934 3935 switch (opc) { 3936 case OPC_SLL_CP2: 3937 case OPC_DSLL_CP2: 3938 tcg_gen_shl_i64(t0, t0, t1); 3939 break; 3940 case OPC_SRA_CP2: 3941 case OPC_DSRA_CP2: 3942 /* 3943 * Since SRA is UndefinedResult without sign-extended inputs, 3944 * we can treat SRA and DSRA the same. 3945 */ 3946 tcg_gen_sar_i64(t0, t0, t1); 3947 break; 3948 case OPC_SRL_CP2: 3949 /* We want to shift in zeros for SRL; zero-extend first. */ 3950 tcg_gen_ext32u_i64(t0, t0); 3951 /* FALLTHRU */ 3952 case OPC_DSRL_CP2: 3953 tcg_gen_shr_i64(t0, t0, t1); 3954 break; 3955 } 3956 3957 if (shift_max == 32) { 3958 tcg_gen_ext32s_i64(t0, t0); 3959 } 3960 3961 /* Shifts larger than MAX produce zero. */ 3962 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3963 tcg_gen_neg_i64(t1, t1); 3964 tcg_gen_and_i64(t0, t0, t1); 3965 break; 3966 3967 case OPC_ADD_CP2: 3968 case OPC_DADD_CP2: 3969 { 3970 TCGv_i64 t2 = tcg_temp_new_i64(); 3971 TCGLabel *lab = gen_new_label(); 3972 3973 tcg_gen_mov_i64(t2, t0); 3974 tcg_gen_add_i64(t0, t1, t2); 3975 if (opc == OPC_ADD_CP2) { 3976 tcg_gen_ext32s_i64(t0, t0); 3977 } 3978 tcg_gen_xor_i64(t1, t1, t2); 3979 tcg_gen_xor_i64(t2, t2, t0); 3980 tcg_gen_andc_i64(t1, t2, t1); 3981 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3982 generate_exception(ctx, EXCP_OVERFLOW); 3983 gen_set_label(lab); 3984 break; 3985 } 3986 3987 case OPC_SUB_CP2: 3988 case OPC_DSUB_CP2: 3989 { 3990 TCGv_i64 t2 = tcg_temp_new_i64(); 3991 TCGLabel *lab = gen_new_label(); 3992 3993 tcg_gen_mov_i64(t2, t0); 3994 tcg_gen_sub_i64(t0, t1, t2); 3995 if (opc == OPC_SUB_CP2) { 3996 tcg_gen_ext32s_i64(t0, t0); 3997 } 3998 tcg_gen_xor_i64(t1, t1, t2); 3999 tcg_gen_xor_i64(t2, t2, t0); 4000 tcg_gen_and_i64(t1, t1, t2); 4001 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4002 generate_exception(ctx, EXCP_OVERFLOW); 4003 gen_set_label(lab); 4004 break; 4005 } 4006 4007 case OPC_PMULUW: 4008 tcg_gen_ext32u_i64(t0, t0); 4009 tcg_gen_ext32u_i64(t1, t1); 4010 tcg_gen_mul_i64(t0, t0, t1); 4011 break; 4012 4013 case OPC_SEQU_CP2: 4014 case OPC_SEQ_CP2: 4015 cond = TCG_COND_EQ; 4016 goto do_cc_cond; 4017 break; 4018 case OPC_SLTU_CP2: 4019 cond = TCG_COND_LTU; 4020 goto do_cc_cond; 4021 break; 4022 case OPC_SLT_CP2: 4023 cond = TCG_COND_LT; 4024 goto do_cc_cond; 4025 break; 4026 case OPC_SLEU_CP2: 4027 cond = TCG_COND_LEU; 4028 goto do_cc_cond; 4029 break; 4030 case OPC_SLE_CP2: 4031 cond = TCG_COND_LE; 4032 do_cc_cond: 4033 { 4034 int cc = (ctx->opcode >> 8) & 0x7; 4035 TCGv_i64 t64 = tcg_temp_new_i64(); 4036 TCGv_i32 t32 = tcg_temp_new_i32(); 4037 4038 tcg_gen_setcond_i64(cond, t64, t0, t1); 4039 tcg_gen_extrl_i64_i32(t32, t64); 4040 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4041 get_fp_bit(cc), 1); 4042 } 4043 return; 4044 default: 4045 MIPS_INVAL("loongson_cp2"); 4046 gen_reserved_instruction(ctx); 4047 return; 4048 } 4049 4050 gen_store_fpr64(ctx, t0, rd); 4051 } 4052 4053 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4054 int rs, int rd) 4055 { 4056 TCGv t0, t1; 4057 TCGv_i32 fp0; 4058 #if defined(TARGET_MIPS64) 4059 int lsq_rt1 = ctx->opcode & 0x1f; 4060 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4061 #endif 4062 int shf_offset = sextract32(ctx->opcode, 6, 8); 4063 4064 t0 = tcg_temp_new(); 4065 4066 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4067 #if defined(TARGET_MIPS64) 4068 case OPC_GSLQ: 4069 t1 = tcg_temp_new(); 4070 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4071 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4072 ctx->default_tcg_memop_mask); 4073 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4074 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4075 ctx->default_tcg_memop_mask); 4076 gen_store_gpr(t1, rt); 4077 gen_store_gpr(t0, lsq_rt1); 4078 break; 4079 case OPC_GSLQC1: 4080 check_cp1_enabled(ctx); 4081 t1 = tcg_temp_new(); 4082 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4083 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4084 ctx->default_tcg_memop_mask); 4085 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4086 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4087 ctx->default_tcg_memop_mask); 4088 gen_store_fpr64(ctx, t1, rt); 4089 gen_store_fpr64(ctx, t0, lsq_rt1); 4090 break; 4091 case OPC_GSSQ: 4092 t1 = tcg_temp_new(); 4093 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4094 gen_load_gpr(t1, rt); 4095 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4096 ctx->default_tcg_memop_mask); 4097 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4098 gen_load_gpr(t1, lsq_rt1); 4099 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4100 ctx->default_tcg_memop_mask); 4101 break; 4102 case OPC_GSSQC1: 4103 check_cp1_enabled(ctx); 4104 t1 = tcg_temp_new(); 4105 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4106 gen_load_fpr64(ctx, t1, rt); 4107 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4108 ctx->default_tcg_memop_mask); 4109 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4110 gen_load_fpr64(ctx, t1, lsq_rt1); 4111 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4112 ctx->default_tcg_memop_mask); 4113 break; 4114 #endif 4115 case OPC_GSSHFL: 4116 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4117 case OPC_GSLWLC1: 4118 check_cp1_enabled(ctx); 4119 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4120 fp0 = tcg_temp_new_i32(); 4121 gen_load_fpr32(ctx, fp0, rt); 4122 t1 = tcg_temp_new(); 4123 tcg_gen_ext_i32_tl(t1, fp0); 4124 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4125 tcg_gen_trunc_tl_i32(fp0, t1); 4126 gen_store_fpr32(ctx, fp0, rt); 4127 break; 4128 case OPC_GSLWRC1: 4129 check_cp1_enabled(ctx); 4130 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4131 fp0 = tcg_temp_new_i32(); 4132 gen_load_fpr32(ctx, fp0, rt); 4133 t1 = tcg_temp_new(); 4134 tcg_gen_ext_i32_tl(t1, fp0); 4135 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4136 tcg_gen_trunc_tl_i32(fp0, t1); 4137 gen_store_fpr32(ctx, fp0, rt); 4138 break; 4139 #if defined(TARGET_MIPS64) 4140 case OPC_GSLDLC1: 4141 check_cp1_enabled(ctx); 4142 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4143 t1 = tcg_temp_new(); 4144 gen_load_fpr64(ctx, t1, rt); 4145 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4146 gen_store_fpr64(ctx, t1, rt); 4147 break; 4148 case OPC_GSLDRC1: 4149 check_cp1_enabled(ctx); 4150 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4151 t1 = tcg_temp_new(); 4152 gen_load_fpr64(ctx, t1, rt); 4153 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4154 gen_store_fpr64(ctx, t1, rt); 4155 break; 4156 #endif 4157 default: 4158 MIPS_INVAL("loongson_gsshfl"); 4159 gen_reserved_instruction(ctx); 4160 break; 4161 } 4162 break; 4163 case OPC_GSSHFS: 4164 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4165 case OPC_GSSWLC1: 4166 check_cp1_enabled(ctx); 4167 t1 = tcg_temp_new(); 4168 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4169 fp0 = tcg_temp_new_i32(); 4170 gen_load_fpr32(ctx, fp0, rt); 4171 tcg_gen_ext_i32_tl(t1, fp0); 4172 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4173 break; 4174 case OPC_GSSWRC1: 4175 check_cp1_enabled(ctx); 4176 t1 = tcg_temp_new(); 4177 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4178 fp0 = tcg_temp_new_i32(); 4179 gen_load_fpr32(ctx, fp0, rt); 4180 tcg_gen_ext_i32_tl(t1, fp0); 4181 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4182 break; 4183 #if defined(TARGET_MIPS64) 4184 case OPC_GSSDLC1: 4185 check_cp1_enabled(ctx); 4186 t1 = tcg_temp_new(); 4187 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4188 gen_load_fpr64(ctx, t1, rt); 4189 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4190 break; 4191 case OPC_GSSDRC1: 4192 check_cp1_enabled(ctx); 4193 t1 = tcg_temp_new(); 4194 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4195 gen_load_fpr64(ctx, t1, rt); 4196 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4197 break; 4198 #endif 4199 default: 4200 MIPS_INVAL("loongson_gsshfs"); 4201 gen_reserved_instruction(ctx); 4202 break; 4203 } 4204 break; 4205 default: 4206 MIPS_INVAL("loongson_gslsq"); 4207 gen_reserved_instruction(ctx); 4208 break; 4209 } 4210 } 4211 4212 /* Loongson EXT LDC2/SDC2 */ 4213 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4214 int rs, int rd) 4215 { 4216 int offset = sextract32(ctx->opcode, 3, 8); 4217 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4218 TCGv t0, t1; 4219 TCGv_i32 fp0; 4220 4221 /* Pre-conditions */ 4222 switch (opc) { 4223 case OPC_GSLBX: 4224 case OPC_GSLHX: 4225 case OPC_GSLWX: 4226 case OPC_GSLDX: 4227 /* prefetch, implement as NOP */ 4228 if (rt == 0) { 4229 return; 4230 } 4231 break; 4232 case OPC_GSSBX: 4233 case OPC_GSSHX: 4234 case OPC_GSSWX: 4235 case OPC_GSSDX: 4236 break; 4237 case OPC_GSLWXC1: 4238 #if defined(TARGET_MIPS64) 4239 case OPC_GSLDXC1: 4240 #endif 4241 check_cp1_enabled(ctx); 4242 /* prefetch, implement as NOP */ 4243 if (rt == 0) { 4244 return; 4245 } 4246 break; 4247 case OPC_GSSWXC1: 4248 #if defined(TARGET_MIPS64) 4249 case OPC_GSSDXC1: 4250 #endif 4251 check_cp1_enabled(ctx); 4252 break; 4253 default: 4254 MIPS_INVAL("loongson_lsdc2"); 4255 gen_reserved_instruction(ctx); 4256 return; 4257 break; 4258 } 4259 4260 t0 = tcg_temp_new(); 4261 4262 gen_base_offset_addr(ctx, t0, rs, offset); 4263 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4264 4265 switch (opc) { 4266 case OPC_GSLBX: 4267 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4268 gen_store_gpr(t0, rt); 4269 break; 4270 case OPC_GSLHX: 4271 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4272 ctx->default_tcg_memop_mask); 4273 gen_store_gpr(t0, rt); 4274 break; 4275 case OPC_GSLWX: 4276 gen_base_offset_addr(ctx, t0, rs, offset); 4277 if (rd) { 4278 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4279 } 4280 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4281 ctx->default_tcg_memop_mask); 4282 gen_store_gpr(t0, rt); 4283 break; 4284 #if defined(TARGET_MIPS64) 4285 case OPC_GSLDX: 4286 gen_base_offset_addr(ctx, t0, rs, offset); 4287 if (rd) { 4288 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4289 } 4290 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4291 ctx->default_tcg_memop_mask); 4292 gen_store_gpr(t0, rt); 4293 break; 4294 #endif 4295 case OPC_GSLWXC1: 4296 gen_base_offset_addr(ctx, t0, rs, offset); 4297 if (rd) { 4298 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4299 } 4300 fp0 = tcg_temp_new_i32(); 4301 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4302 ctx->default_tcg_memop_mask); 4303 gen_store_fpr32(ctx, fp0, rt); 4304 break; 4305 #if defined(TARGET_MIPS64) 4306 case OPC_GSLDXC1: 4307 gen_base_offset_addr(ctx, t0, rs, offset); 4308 if (rd) { 4309 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4310 } 4311 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4312 ctx->default_tcg_memop_mask); 4313 gen_store_fpr64(ctx, t0, rt); 4314 break; 4315 #endif 4316 case OPC_GSSBX: 4317 t1 = tcg_temp_new(); 4318 gen_load_gpr(t1, rt); 4319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4320 break; 4321 case OPC_GSSHX: 4322 t1 = tcg_temp_new(); 4323 gen_load_gpr(t1, rt); 4324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4325 ctx->default_tcg_memop_mask); 4326 break; 4327 case OPC_GSSWX: 4328 t1 = tcg_temp_new(); 4329 gen_load_gpr(t1, rt); 4330 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4331 ctx->default_tcg_memop_mask); 4332 break; 4333 #if defined(TARGET_MIPS64) 4334 case OPC_GSSDX: 4335 t1 = tcg_temp_new(); 4336 gen_load_gpr(t1, rt); 4337 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4338 ctx->default_tcg_memop_mask); 4339 break; 4340 #endif 4341 case OPC_GSSWXC1: 4342 fp0 = tcg_temp_new_i32(); 4343 gen_load_fpr32(ctx, fp0, rt); 4344 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4345 ctx->default_tcg_memop_mask); 4346 break; 4347 #if defined(TARGET_MIPS64) 4348 case OPC_GSSDXC1: 4349 t1 = tcg_temp_new(); 4350 gen_load_fpr64(ctx, t1, rt); 4351 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4352 ctx->default_tcg_memop_mask); 4353 break; 4354 #endif 4355 default: 4356 break; 4357 } 4358 } 4359 4360 /* Traps */ 4361 static void gen_trap(DisasContext *ctx, uint32_t opc, 4362 int rs, int rt, int16_t imm, int code) 4363 { 4364 int cond; 4365 TCGv t0 = tcg_temp_new(); 4366 TCGv t1 = tcg_temp_new(); 4367 4368 cond = 0; 4369 /* Load needed operands */ 4370 switch (opc) { 4371 case OPC_TEQ: 4372 case OPC_TGE: 4373 case OPC_TGEU: 4374 case OPC_TLT: 4375 case OPC_TLTU: 4376 case OPC_TNE: 4377 /* Compare two registers */ 4378 if (rs != rt) { 4379 gen_load_gpr(t0, rs); 4380 gen_load_gpr(t1, rt); 4381 cond = 1; 4382 } 4383 break; 4384 case OPC_TEQI: 4385 case OPC_TGEI: 4386 case OPC_TGEIU: 4387 case OPC_TLTI: 4388 case OPC_TLTIU: 4389 case OPC_TNEI: 4390 /* Compare register to immediate */ 4391 if (rs != 0 || imm != 0) { 4392 gen_load_gpr(t0, rs); 4393 tcg_gen_movi_tl(t1, (int32_t)imm); 4394 cond = 1; 4395 } 4396 break; 4397 } 4398 if (cond == 0) { 4399 switch (opc) { 4400 case OPC_TEQ: /* rs == rs */ 4401 case OPC_TEQI: /* r0 == 0 */ 4402 case OPC_TGE: /* rs >= rs */ 4403 case OPC_TGEI: /* r0 >= 0 */ 4404 case OPC_TGEU: /* rs >= rs unsigned */ 4405 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4406 /* Always trap */ 4407 #ifdef CONFIG_USER_ONLY 4408 /* Pass the break code along to cpu_loop. */ 4409 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4410 offsetof(CPUMIPSState, error_code)); 4411 #endif 4412 generate_exception_end(ctx, EXCP_TRAP); 4413 break; 4414 case OPC_TLT: /* rs < rs */ 4415 case OPC_TLTI: /* r0 < 0 */ 4416 case OPC_TLTU: /* rs < rs unsigned */ 4417 case OPC_TLTIU: /* r0 < 0 unsigned */ 4418 case OPC_TNE: /* rs != rs */ 4419 case OPC_TNEI: /* r0 != 0 */ 4420 /* Never trap: treat as NOP. */ 4421 break; 4422 } 4423 } else { 4424 TCGLabel *l1 = gen_new_label(); 4425 4426 switch (opc) { 4427 case OPC_TEQ: 4428 case OPC_TEQI: 4429 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4430 break; 4431 case OPC_TGE: 4432 case OPC_TGEI: 4433 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4434 break; 4435 case OPC_TGEU: 4436 case OPC_TGEIU: 4437 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4438 break; 4439 case OPC_TLT: 4440 case OPC_TLTI: 4441 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4442 break; 4443 case OPC_TLTU: 4444 case OPC_TLTIU: 4445 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4446 break; 4447 case OPC_TNE: 4448 case OPC_TNEI: 4449 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4450 break; 4451 } 4452 #ifdef CONFIG_USER_ONLY 4453 /* Pass the break code along to cpu_loop. */ 4454 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4455 offsetof(CPUMIPSState, error_code)); 4456 #endif 4457 /* Like save_cpu_state, only don't update saved values. */ 4458 if (ctx->base.pc_next != ctx->saved_pc) { 4459 gen_save_pc(ctx->base.pc_next); 4460 } 4461 if (ctx->hflags != ctx->saved_hflags) { 4462 tcg_gen_movi_i32(hflags, ctx->hflags); 4463 } 4464 generate_exception(ctx, EXCP_TRAP); 4465 gen_set_label(l1); 4466 } 4467 } 4468 4469 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4470 { 4471 if (translator_use_goto_tb(&ctx->base, dest)) { 4472 tcg_gen_goto_tb(n); 4473 gen_save_pc(dest); 4474 tcg_gen_exit_tb(ctx->base.tb, n); 4475 } else { 4476 gen_save_pc(dest); 4477 tcg_gen_lookup_and_goto_ptr(); 4478 } 4479 } 4480 4481 /* Branches (before delay slot) */ 4482 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4483 int insn_bytes, 4484 int rs, int rt, int32_t offset, 4485 int delayslot_size) 4486 { 4487 target_ulong btgt = -1; 4488 int blink = 0; 4489 int bcond_compute = 0; 4490 TCGv t0 = tcg_temp_new(); 4491 TCGv t1 = tcg_temp_new(); 4492 4493 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4494 #ifdef MIPS_DEBUG_DISAS 4495 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4496 VADDR_PRIx "\n", ctx->base.pc_next); 4497 #endif 4498 gen_reserved_instruction(ctx); 4499 goto out; 4500 } 4501 4502 /* Load needed operands */ 4503 switch (opc) { 4504 case OPC_BEQ: 4505 case OPC_BEQL: 4506 case OPC_BNE: 4507 case OPC_BNEL: 4508 /* Compare two registers */ 4509 if (rs != rt) { 4510 gen_load_gpr(t0, rs); 4511 gen_load_gpr(t1, rt); 4512 bcond_compute = 1; 4513 } 4514 btgt = ctx->base.pc_next + insn_bytes + offset; 4515 break; 4516 case OPC_BGEZ: 4517 case OPC_BGEZAL: 4518 case OPC_BGEZALL: 4519 case OPC_BGEZL: 4520 case OPC_BGTZ: 4521 case OPC_BGTZL: 4522 case OPC_BLEZ: 4523 case OPC_BLEZL: 4524 case OPC_BLTZ: 4525 case OPC_BLTZAL: 4526 case OPC_BLTZALL: 4527 case OPC_BLTZL: 4528 /* Compare to zero */ 4529 if (rs != 0) { 4530 gen_load_gpr(t0, rs); 4531 bcond_compute = 1; 4532 } 4533 btgt = ctx->base.pc_next + insn_bytes + offset; 4534 break; 4535 case OPC_BPOSGE32: 4536 #if defined(TARGET_MIPS64) 4537 case OPC_BPOSGE64: 4538 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4539 #else 4540 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4541 #endif 4542 bcond_compute = 1; 4543 btgt = ctx->base.pc_next + insn_bytes + offset; 4544 break; 4545 case OPC_J: 4546 case OPC_JAL: 4547 { 4548 /* Jump to immediate */ 4549 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4550 : 0xF0000000; 4551 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4552 | (uint32_t)offset; 4553 break; 4554 } 4555 case OPC_JALX: 4556 /* Jump to immediate */ 4557 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4558 (uint32_t)offset; 4559 break; 4560 case OPC_JR: 4561 case OPC_JALR: 4562 /* Jump to register */ 4563 if (offset != 0 && offset != 16) { 4564 /* 4565 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4566 * others are reserved. 4567 */ 4568 MIPS_INVAL("jump hint"); 4569 gen_reserved_instruction(ctx); 4570 goto out; 4571 } 4572 gen_load_gpr(btarget, rs); 4573 break; 4574 default: 4575 MIPS_INVAL("branch/jump"); 4576 gen_reserved_instruction(ctx); 4577 goto out; 4578 } 4579 if (bcond_compute == 0) { 4580 /* No condition to be computed */ 4581 switch (opc) { 4582 case OPC_BEQ: /* rx == rx */ 4583 case OPC_BEQL: /* rx == rx likely */ 4584 case OPC_BGEZ: /* 0 >= 0 */ 4585 case OPC_BGEZL: /* 0 >= 0 likely */ 4586 case OPC_BLEZ: /* 0 <= 0 */ 4587 case OPC_BLEZL: /* 0 <= 0 likely */ 4588 /* Always take */ 4589 ctx->hflags |= MIPS_HFLAG_B; 4590 break; 4591 case OPC_BGEZAL: /* 0 >= 0 */ 4592 case OPC_BGEZALL: /* 0 >= 0 likely */ 4593 /* Always take and link */ 4594 blink = 31; 4595 ctx->hflags |= MIPS_HFLAG_B; 4596 break; 4597 case OPC_BNE: /* rx != rx */ 4598 case OPC_BGTZ: /* 0 > 0 */ 4599 case OPC_BLTZ: /* 0 < 0 */ 4600 /* Treat as NOP. */ 4601 goto out; 4602 case OPC_BLTZAL: /* 0 < 0 */ 4603 /* 4604 * Handle as an unconditional branch to get correct delay 4605 * slot checking. 4606 */ 4607 blink = 31; 4608 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4609 ctx->hflags |= MIPS_HFLAG_B; 4610 break; 4611 case OPC_BLTZALL: /* 0 < 0 likely */ 4612 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4613 /* Skip the instruction in the delay slot */ 4614 ctx->base.pc_next += 4; 4615 goto out; 4616 case OPC_BNEL: /* rx != rx likely */ 4617 case OPC_BGTZL: /* 0 > 0 likely */ 4618 case OPC_BLTZL: /* 0 < 0 likely */ 4619 /* Skip the instruction in the delay slot */ 4620 ctx->base.pc_next += 4; 4621 goto out; 4622 case OPC_J: 4623 ctx->hflags |= MIPS_HFLAG_B; 4624 break; 4625 case OPC_JALX: 4626 ctx->hflags |= MIPS_HFLAG_BX; 4627 /* Fallthrough */ 4628 case OPC_JAL: 4629 blink = 31; 4630 ctx->hflags |= MIPS_HFLAG_B; 4631 break; 4632 case OPC_JR: 4633 ctx->hflags |= MIPS_HFLAG_BR; 4634 break; 4635 case OPC_JALR: 4636 blink = rt; 4637 ctx->hflags |= MIPS_HFLAG_BR; 4638 break; 4639 default: 4640 MIPS_INVAL("branch/jump"); 4641 gen_reserved_instruction(ctx); 4642 goto out; 4643 } 4644 } else { 4645 switch (opc) { 4646 case OPC_BEQ: 4647 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4648 goto not_likely; 4649 case OPC_BEQL: 4650 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4651 goto likely; 4652 case OPC_BNE: 4653 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4654 goto not_likely; 4655 case OPC_BNEL: 4656 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4657 goto likely; 4658 case OPC_BGEZ: 4659 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4660 goto not_likely; 4661 case OPC_BGEZL: 4662 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4663 goto likely; 4664 case OPC_BGEZAL: 4665 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4666 blink = 31; 4667 goto not_likely; 4668 case OPC_BGEZALL: 4669 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4670 blink = 31; 4671 goto likely; 4672 case OPC_BGTZ: 4673 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4674 goto not_likely; 4675 case OPC_BGTZL: 4676 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4677 goto likely; 4678 case OPC_BLEZ: 4679 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4680 goto not_likely; 4681 case OPC_BLEZL: 4682 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4683 goto likely; 4684 case OPC_BLTZ: 4685 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4686 goto not_likely; 4687 case OPC_BLTZL: 4688 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4689 goto likely; 4690 case OPC_BPOSGE32: 4691 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4692 goto not_likely; 4693 #if defined(TARGET_MIPS64) 4694 case OPC_BPOSGE64: 4695 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4696 goto not_likely; 4697 #endif 4698 case OPC_BLTZAL: 4699 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4700 blink = 31; 4701 not_likely: 4702 ctx->hflags |= MIPS_HFLAG_BC; 4703 break; 4704 case OPC_BLTZALL: 4705 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4706 blink = 31; 4707 likely: 4708 ctx->hflags |= MIPS_HFLAG_BL; 4709 break; 4710 default: 4711 MIPS_INVAL("conditional branch/jump"); 4712 gen_reserved_instruction(ctx); 4713 goto out; 4714 } 4715 } 4716 4717 ctx->btarget = btgt; 4718 4719 switch (delayslot_size) { 4720 case 2: 4721 ctx->hflags |= MIPS_HFLAG_BDS16; 4722 break; 4723 case 4: 4724 ctx->hflags |= MIPS_HFLAG_BDS32; 4725 break; 4726 } 4727 4728 if (blink > 0) { 4729 int post_delay = insn_bytes + delayslot_size; 4730 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4731 4732 tcg_gen_movi_tl(cpu_gpr[blink], 4733 ctx->base.pc_next + post_delay + lowbit); 4734 } 4735 4736 out: 4737 if (insn_bytes == 2) { 4738 ctx->hflags |= MIPS_HFLAG_B16; 4739 } 4740 } 4741 4742 4743 /* special3 bitfield operations */ 4744 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4745 int rs, int lsb, int msb) 4746 { 4747 TCGv t0 = tcg_temp_new(); 4748 TCGv t1 = tcg_temp_new(); 4749 4750 gen_load_gpr(t1, rs); 4751 switch (opc) { 4752 case OPC_EXT: 4753 if (lsb + msb > 31) { 4754 goto fail; 4755 } 4756 if (msb != 31) { 4757 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4758 } else { 4759 /* 4760 * The two checks together imply that lsb == 0, 4761 * so this is a simple sign-extension. 4762 */ 4763 tcg_gen_ext32s_tl(t0, t1); 4764 } 4765 break; 4766 #if defined(TARGET_MIPS64) 4767 case OPC_DEXTU: 4768 lsb += 32; 4769 goto do_dext; 4770 case OPC_DEXTM: 4771 msb += 32; 4772 goto do_dext; 4773 case OPC_DEXT: 4774 do_dext: 4775 if (lsb + msb > 63) { 4776 goto fail; 4777 } 4778 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4779 break; 4780 #endif 4781 case OPC_INS: 4782 if (lsb > msb) { 4783 goto fail; 4784 } 4785 gen_load_gpr(t0, rt); 4786 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4787 tcg_gen_ext32s_tl(t0, t0); 4788 break; 4789 #if defined(TARGET_MIPS64) 4790 case OPC_DINSU: 4791 lsb += 32; 4792 /* FALLTHRU */ 4793 case OPC_DINSM: 4794 msb += 32; 4795 /* FALLTHRU */ 4796 case OPC_DINS: 4797 if (lsb > msb) { 4798 goto fail; 4799 } 4800 gen_load_gpr(t0, rt); 4801 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4802 break; 4803 #endif 4804 default: 4805 fail: 4806 MIPS_INVAL("bitops"); 4807 gen_reserved_instruction(ctx); 4808 return; 4809 } 4810 gen_store_gpr(t0, rt); 4811 } 4812 4813 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4814 { 4815 TCGv t0; 4816 4817 if (rd == 0) { 4818 /* If no destination, treat it as a NOP. */ 4819 return; 4820 } 4821 4822 t0 = tcg_temp_new(); 4823 gen_load_gpr(t0, rt); 4824 switch (op2) { 4825 case OPC_WSBH: 4826 { 4827 TCGv t1 = tcg_temp_new(); 4828 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4829 4830 tcg_gen_shri_tl(t1, t0, 8); 4831 tcg_gen_and_tl(t1, t1, t2); 4832 tcg_gen_and_tl(t0, t0, t2); 4833 tcg_gen_shli_tl(t0, t0, 8); 4834 tcg_gen_or_tl(t0, t0, t1); 4835 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4836 } 4837 break; 4838 case OPC_SEB: 4839 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4840 break; 4841 case OPC_SEH: 4842 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4843 break; 4844 #if defined(TARGET_MIPS64) 4845 case OPC_DSBH: 4846 { 4847 TCGv t1 = tcg_temp_new(); 4848 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4849 4850 tcg_gen_shri_tl(t1, t0, 8); 4851 tcg_gen_and_tl(t1, t1, t2); 4852 tcg_gen_and_tl(t0, t0, t2); 4853 tcg_gen_shli_tl(t0, t0, 8); 4854 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4855 } 4856 break; 4857 case OPC_DSHD: 4858 { 4859 TCGv t1 = tcg_temp_new(); 4860 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4861 4862 tcg_gen_shri_tl(t1, t0, 16); 4863 tcg_gen_and_tl(t1, t1, t2); 4864 tcg_gen_and_tl(t0, t0, t2); 4865 tcg_gen_shli_tl(t0, t0, 16); 4866 tcg_gen_or_tl(t0, t0, t1); 4867 tcg_gen_shri_tl(t1, t0, 32); 4868 tcg_gen_shli_tl(t0, t0, 32); 4869 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4870 } 4871 break; 4872 #endif 4873 default: 4874 MIPS_INVAL("bsfhl"); 4875 gen_reserved_instruction(ctx); 4876 return; 4877 } 4878 } 4879 4880 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4881 int rt, int bits) 4882 { 4883 TCGv t0; 4884 if (rd == 0) { 4885 /* Treat as NOP. */ 4886 return; 4887 } 4888 t0 = tcg_temp_new(); 4889 if (bits == 0 || bits == wordsz) { 4890 if (bits == 0) { 4891 gen_load_gpr(t0, rt); 4892 } else { 4893 gen_load_gpr(t0, rs); 4894 } 4895 switch (wordsz) { 4896 case 32: 4897 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4898 break; 4899 #if defined(TARGET_MIPS64) 4900 case 64: 4901 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4902 break; 4903 #endif 4904 } 4905 } else { 4906 TCGv t1 = tcg_temp_new(); 4907 gen_load_gpr(t0, rt); 4908 gen_load_gpr(t1, rs); 4909 switch (wordsz) { 4910 case 32: 4911 { 4912 TCGv_i64 t2 = tcg_temp_new_i64(); 4913 tcg_gen_concat_tl_i64(t2, t1, t0); 4914 tcg_gen_shri_i64(t2, t2, 32 - bits); 4915 gen_move_low32(cpu_gpr[rd], t2); 4916 } 4917 break; 4918 #if defined(TARGET_MIPS64) 4919 case 64: 4920 tcg_gen_shli_tl(t0, t0, bits); 4921 tcg_gen_shri_tl(t1, t1, 64 - bits); 4922 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4923 break; 4924 #endif 4925 } 4926 } 4927 } 4928 4929 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4930 { 4931 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4932 } 4933 4934 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4935 { 4936 TCGv t0; 4937 if (rd == 0) { 4938 /* Treat as NOP. */ 4939 return; 4940 } 4941 t0 = tcg_temp_new(); 4942 gen_load_gpr(t0, rt); 4943 switch (opc) { 4944 case OPC_BITSWAP: 4945 gen_helper_bitswap(cpu_gpr[rd], t0); 4946 break; 4947 #if defined(TARGET_MIPS64) 4948 case OPC_DBITSWAP: 4949 gen_helper_dbitswap(cpu_gpr[rd], t0); 4950 break; 4951 #endif 4952 } 4953 } 4954 4955 #ifndef CONFIG_USER_ONLY 4956 /* CP0 (MMU and control) */ 4957 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4958 { 4959 TCGv_i64 t0 = tcg_temp_new_i64(); 4960 TCGv_i64 t1 = tcg_temp_new_i64(); 4961 4962 tcg_gen_ext_tl_i64(t0, arg); 4963 tcg_gen_ld_i64(t1, tcg_env, off); 4964 #if defined(TARGET_MIPS64) 4965 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4966 #else 4967 tcg_gen_concat32_i64(t1, t1, t0); 4968 #endif 4969 tcg_gen_st_i64(t1, tcg_env, off); 4970 } 4971 4972 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4973 { 4974 TCGv_i64 t0 = tcg_temp_new_i64(); 4975 TCGv_i64 t1 = tcg_temp_new_i64(); 4976 4977 tcg_gen_ext_tl_i64(t0, arg); 4978 tcg_gen_ld_i64(t1, tcg_env, off); 4979 tcg_gen_concat32_i64(t1, t1, t0); 4980 tcg_gen_st_i64(t1, tcg_env, off); 4981 } 4982 4983 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4984 { 4985 TCGv_i64 t0 = tcg_temp_new_i64(); 4986 4987 tcg_gen_ld_i64(t0, tcg_env, off); 4988 #if defined(TARGET_MIPS64) 4989 tcg_gen_shri_i64(t0, t0, 30); 4990 #else 4991 tcg_gen_shri_i64(t0, t0, 32); 4992 #endif 4993 gen_move_low32(arg, t0); 4994 } 4995 4996 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4997 { 4998 TCGv_i64 t0 = tcg_temp_new_i64(); 4999 5000 tcg_gen_ld_i64(t0, tcg_env, off); 5001 tcg_gen_shri_i64(t0, t0, 32 + shift); 5002 gen_move_low32(arg, t0); 5003 } 5004 5005 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5006 { 5007 TCGv_i32 t0 = tcg_temp_new_i32(); 5008 5009 tcg_gen_ld_i32(t0, tcg_env, off); 5010 tcg_gen_ext_i32_tl(arg, t0); 5011 } 5012 5013 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5014 { 5015 tcg_gen_ld_tl(arg, tcg_env, off); 5016 tcg_gen_ext32s_tl(arg, arg); 5017 } 5018 5019 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5020 { 5021 TCGv_i32 t0 = tcg_temp_new_i32(); 5022 5023 tcg_gen_trunc_tl_i32(t0, arg); 5024 tcg_gen_st_i32(t0, tcg_env, off); 5025 } 5026 5027 #define CP0_CHECK(c) \ 5028 do { \ 5029 if (!(c)) { \ 5030 goto cp0_unimplemented; \ 5031 } \ 5032 } while (0) 5033 5034 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5035 { 5036 const char *register_name = "invalid"; 5037 5038 switch (reg) { 5039 case CP0_REGISTER_02: 5040 switch (sel) { 5041 case 0: 5042 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5043 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5044 register_name = "EntryLo0"; 5045 break; 5046 default: 5047 goto cp0_unimplemented; 5048 } 5049 break; 5050 case CP0_REGISTER_03: 5051 switch (sel) { 5052 case CP0_REG03__ENTRYLO1: 5053 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5054 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5055 register_name = "EntryLo1"; 5056 break; 5057 default: 5058 goto cp0_unimplemented; 5059 } 5060 break; 5061 case CP0_REGISTER_17: 5062 switch (sel) { 5063 case CP0_REG17__LLADDR: 5064 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5065 ctx->CP0_LLAddr_shift); 5066 register_name = "LLAddr"; 5067 break; 5068 case CP0_REG17__MAAR: 5069 CP0_CHECK(ctx->mrp); 5070 gen_helper_mfhc0_maar(arg, tcg_env); 5071 register_name = "MAAR"; 5072 break; 5073 default: 5074 goto cp0_unimplemented; 5075 } 5076 break; 5077 case CP0_REGISTER_19: 5078 switch (sel) { 5079 case CP0_REG19__WATCHHI0: 5080 case CP0_REG19__WATCHHI1: 5081 case CP0_REG19__WATCHHI2: 5082 case CP0_REG19__WATCHHI3: 5083 case CP0_REG19__WATCHHI4: 5084 case CP0_REG19__WATCHHI5: 5085 case CP0_REG19__WATCHHI6: 5086 case CP0_REG19__WATCHHI7: 5087 /* upper 32 bits are only available when Config5MI != 0 */ 5088 CP0_CHECK(ctx->mi); 5089 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5090 register_name = "WatchHi"; 5091 break; 5092 default: 5093 goto cp0_unimplemented; 5094 } 5095 break; 5096 case CP0_REGISTER_28: 5097 switch (sel) { 5098 case 0: 5099 case 2: 5100 case 4: 5101 case 6: 5102 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5103 register_name = "TagLo"; 5104 break; 5105 default: 5106 goto cp0_unimplemented; 5107 } 5108 break; 5109 default: 5110 goto cp0_unimplemented; 5111 } 5112 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5113 return; 5114 5115 cp0_unimplemented: 5116 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5117 register_name, reg, sel); 5118 tcg_gen_movi_tl(arg, 0); 5119 } 5120 5121 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5122 { 5123 const char *register_name = "invalid"; 5124 uint64_t mask = ctx->PAMask >> 36; 5125 5126 switch (reg) { 5127 case CP0_REGISTER_02: 5128 switch (sel) { 5129 case 0: 5130 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5131 tcg_gen_andi_tl(arg, arg, mask); 5132 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5133 register_name = "EntryLo0"; 5134 break; 5135 default: 5136 goto cp0_unimplemented; 5137 } 5138 break; 5139 case CP0_REGISTER_03: 5140 switch (sel) { 5141 case CP0_REG03__ENTRYLO1: 5142 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5143 tcg_gen_andi_tl(arg, arg, mask); 5144 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5145 register_name = "EntryLo1"; 5146 break; 5147 default: 5148 goto cp0_unimplemented; 5149 } 5150 break; 5151 case CP0_REGISTER_17: 5152 switch (sel) { 5153 case CP0_REG17__LLADDR: 5154 /* 5155 * LLAddr is read-only (the only exception is bit 0 if LLB is 5156 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5157 * relevant for modern MIPS cores supporting MTHC0, therefore 5158 * treating MTHC0 to LLAddr as NOP. 5159 */ 5160 register_name = "LLAddr"; 5161 break; 5162 case CP0_REG17__MAAR: 5163 CP0_CHECK(ctx->mrp); 5164 gen_helper_mthc0_maar(tcg_env, arg); 5165 register_name = "MAAR"; 5166 break; 5167 default: 5168 goto cp0_unimplemented; 5169 } 5170 break; 5171 case CP0_REGISTER_19: 5172 switch (sel) { 5173 case CP0_REG19__WATCHHI0: 5174 case CP0_REG19__WATCHHI1: 5175 case CP0_REG19__WATCHHI2: 5176 case CP0_REG19__WATCHHI3: 5177 case CP0_REG19__WATCHHI4: 5178 case CP0_REG19__WATCHHI5: 5179 case CP0_REG19__WATCHHI6: 5180 case CP0_REG19__WATCHHI7: 5181 /* upper 32 bits are only available when Config5MI != 0 */ 5182 CP0_CHECK(ctx->mi); 5183 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5184 register_name = "WatchHi"; 5185 break; 5186 default: 5187 goto cp0_unimplemented; 5188 } 5189 break; 5190 case CP0_REGISTER_28: 5191 switch (sel) { 5192 case 0: 5193 case 2: 5194 case 4: 5195 case 6: 5196 tcg_gen_andi_tl(arg, arg, mask); 5197 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5198 register_name = "TagLo"; 5199 break; 5200 default: 5201 goto cp0_unimplemented; 5202 } 5203 break; 5204 default: 5205 goto cp0_unimplemented; 5206 } 5207 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5208 return; 5209 5210 cp0_unimplemented: 5211 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5212 register_name, reg, sel); 5213 } 5214 5215 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5216 { 5217 if (ctx->insn_flags & ISA_MIPS_R6) { 5218 tcg_gen_movi_tl(arg, 0); 5219 } else { 5220 tcg_gen_movi_tl(arg, ~0); 5221 } 5222 } 5223 5224 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5225 { 5226 const char *register_name = "invalid"; 5227 5228 if (sel != 0) { 5229 check_insn(ctx, ISA_MIPS_R1); 5230 } 5231 5232 switch (reg) { 5233 case CP0_REGISTER_00: 5234 switch (sel) { 5235 case CP0_REG00__INDEX: 5236 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5237 register_name = "Index"; 5238 break; 5239 case CP0_REG00__MVPCONTROL: 5240 CP0_CHECK(ctx->insn_flags & ASE_MT); 5241 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5242 register_name = "MVPControl"; 5243 break; 5244 case CP0_REG00__MVPCONF0: 5245 CP0_CHECK(ctx->insn_flags & ASE_MT); 5246 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5247 register_name = "MVPConf0"; 5248 break; 5249 case CP0_REG00__MVPCONF1: 5250 CP0_CHECK(ctx->insn_flags & ASE_MT); 5251 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5252 register_name = "MVPConf1"; 5253 break; 5254 case CP0_REG00__VPCONTROL: 5255 CP0_CHECK(ctx->vp); 5256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5257 register_name = "VPControl"; 5258 break; 5259 default: 5260 goto cp0_unimplemented; 5261 } 5262 break; 5263 case CP0_REGISTER_01: 5264 switch (sel) { 5265 case CP0_REG01__RANDOM: 5266 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5267 gen_helper_mfc0_random(arg, tcg_env); 5268 register_name = "Random"; 5269 break; 5270 case CP0_REG01__VPECONTROL: 5271 CP0_CHECK(ctx->insn_flags & ASE_MT); 5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5273 register_name = "VPEControl"; 5274 break; 5275 case CP0_REG01__VPECONF0: 5276 CP0_CHECK(ctx->insn_flags & ASE_MT); 5277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5278 register_name = "VPEConf0"; 5279 break; 5280 case CP0_REG01__VPECONF1: 5281 CP0_CHECK(ctx->insn_flags & ASE_MT); 5282 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5283 register_name = "VPEConf1"; 5284 break; 5285 case CP0_REG01__YQMASK: 5286 CP0_CHECK(ctx->insn_flags & ASE_MT); 5287 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5288 register_name = "YQMask"; 5289 break; 5290 case CP0_REG01__VPESCHEDULE: 5291 CP0_CHECK(ctx->insn_flags & ASE_MT); 5292 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5293 register_name = "VPESchedule"; 5294 break; 5295 case CP0_REG01__VPESCHEFBACK: 5296 CP0_CHECK(ctx->insn_flags & ASE_MT); 5297 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5298 register_name = "VPEScheFBack"; 5299 break; 5300 case CP0_REG01__VPEOPT: 5301 CP0_CHECK(ctx->insn_flags & ASE_MT); 5302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5303 register_name = "VPEOpt"; 5304 break; 5305 default: 5306 goto cp0_unimplemented; 5307 } 5308 break; 5309 case CP0_REGISTER_02: 5310 switch (sel) { 5311 case CP0_REG02__ENTRYLO0: 5312 { 5313 TCGv_i64 tmp = tcg_temp_new_i64(); 5314 tcg_gen_ld_i64(tmp, tcg_env, 5315 offsetof(CPUMIPSState, CP0_EntryLo0)); 5316 #if defined(TARGET_MIPS64) 5317 if (ctx->rxi) { 5318 /* Move RI/XI fields to bits 31:30 */ 5319 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5320 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5321 } 5322 #endif 5323 gen_move_low32(arg, tmp); 5324 } 5325 register_name = "EntryLo0"; 5326 break; 5327 case CP0_REG02__TCSTATUS: 5328 CP0_CHECK(ctx->insn_flags & ASE_MT); 5329 gen_helper_mfc0_tcstatus(arg, tcg_env); 5330 register_name = "TCStatus"; 5331 break; 5332 case CP0_REG02__TCBIND: 5333 CP0_CHECK(ctx->insn_flags & ASE_MT); 5334 gen_helper_mfc0_tcbind(arg, tcg_env); 5335 register_name = "TCBind"; 5336 break; 5337 case CP0_REG02__TCRESTART: 5338 CP0_CHECK(ctx->insn_flags & ASE_MT); 5339 gen_helper_mfc0_tcrestart(arg, tcg_env); 5340 register_name = "TCRestart"; 5341 break; 5342 case CP0_REG02__TCHALT: 5343 CP0_CHECK(ctx->insn_flags & ASE_MT); 5344 gen_helper_mfc0_tchalt(arg, tcg_env); 5345 register_name = "TCHalt"; 5346 break; 5347 case CP0_REG02__TCCONTEXT: 5348 CP0_CHECK(ctx->insn_flags & ASE_MT); 5349 gen_helper_mfc0_tccontext(arg, tcg_env); 5350 register_name = "TCContext"; 5351 break; 5352 case CP0_REG02__TCSCHEDULE: 5353 CP0_CHECK(ctx->insn_flags & ASE_MT); 5354 gen_helper_mfc0_tcschedule(arg, tcg_env); 5355 register_name = "TCSchedule"; 5356 break; 5357 case CP0_REG02__TCSCHEFBACK: 5358 CP0_CHECK(ctx->insn_flags & ASE_MT); 5359 gen_helper_mfc0_tcschefback(arg, tcg_env); 5360 register_name = "TCScheFBack"; 5361 break; 5362 default: 5363 goto cp0_unimplemented; 5364 } 5365 break; 5366 case CP0_REGISTER_03: 5367 switch (sel) { 5368 case CP0_REG03__ENTRYLO1: 5369 { 5370 TCGv_i64 tmp = tcg_temp_new_i64(); 5371 tcg_gen_ld_i64(tmp, tcg_env, 5372 offsetof(CPUMIPSState, CP0_EntryLo1)); 5373 #if defined(TARGET_MIPS64) 5374 if (ctx->rxi) { 5375 /* Move RI/XI fields to bits 31:30 */ 5376 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5377 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5378 } 5379 #endif 5380 gen_move_low32(arg, tmp); 5381 } 5382 register_name = "EntryLo1"; 5383 break; 5384 case CP0_REG03__GLOBALNUM: 5385 CP0_CHECK(ctx->vp); 5386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5387 register_name = "GlobalNumber"; 5388 break; 5389 default: 5390 goto cp0_unimplemented; 5391 } 5392 break; 5393 case CP0_REGISTER_04: 5394 switch (sel) { 5395 case CP0_REG04__CONTEXT: 5396 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5397 tcg_gen_ext32s_tl(arg, arg); 5398 register_name = "Context"; 5399 break; 5400 case CP0_REG04__CONTEXTCONFIG: 5401 /* SmartMIPS ASE */ 5402 /* gen_helper_mfc0_contextconfig(arg); */ 5403 register_name = "ContextConfig"; 5404 goto cp0_unimplemented; 5405 case CP0_REG04__USERLOCAL: 5406 CP0_CHECK(ctx->ulri); 5407 tcg_gen_ld_tl(arg, tcg_env, 5408 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5409 tcg_gen_ext32s_tl(arg, arg); 5410 register_name = "UserLocal"; 5411 break; 5412 case CP0_REG04__MMID: 5413 CP0_CHECK(ctx->mi); 5414 gen_helper_mtc0_memorymapid(tcg_env, arg); 5415 register_name = "MMID"; 5416 break; 5417 default: 5418 goto cp0_unimplemented; 5419 } 5420 break; 5421 case CP0_REGISTER_05: 5422 switch (sel) { 5423 case CP0_REG05__PAGEMASK: 5424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5425 register_name = "PageMask"; 5426 break; 5427 case CP0_REG05__PAGEGRAIN: 5428 check_insn(ctx, ISA_MIPS_R2); 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5430 register_name = "PageGrain"; 5431 break; 5432 case CP0_REG05__SEGCTL0: 5433 CP0_CHECK(ctx->sc); 5434 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5435 tcg_gen_ext32s_tl(arg, arg); 5436 register_name = "SegCtl0"; 5437 break; 5438 case CP0_REG05__SEGCTL1: 5439 CP0_CHECK(ctx->sc); 5440 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5441 tcg_gen_ext32s_tl(arg, arg); 5442 register_name = "SegCtl1"; 5443 break; 5444 case CP0_REG05__SEGCTL2: 5445 CP0_CHECK(ctx->sc); 5446 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5447 tcg_gen_ext32s_tl(arg, arg); 5448 register_name = "SegCtl2"; 5449 break; 5450 case CP0_REG05__PWBASE: 5451 check_pw(ctx); 5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5453 register_name = "PWBase"; 5454 break; 5455 case CP0_REG05__PWFIELD: 5456 check_pw(ctx); 5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5458 register_name = "PWField"; 5459 break; 5460 case CP0_REG05__PWSIZE: 5461 check_pw(ctx); 5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5463 register_name = "PWSize"; 5464 break; 5465 default: 5466 goto cp0_unimplemented; 5467 } 5468 break; 5469 case CP0_REGISTER_06: 5470 switch (sel) { 5471 case CP0_REG06__WIRED: 5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5473 register_name = "Wired"; 5474 break; 5475 case CP0_REG06__SRSCONF0: 5476 check_insn(ctx, ISA_MIPS_R2); 5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5478 register_name = "SRSConf0"; 5479 break; 5480 case CP0_REG06__SRSCONF1: 5481 check_insn(ctx, ISA_MIPS_R2); 5482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5483 register_name = "SRSConf1"; 5484 break; 5485 case CP0_REG06__SRSCONF2: 5486 check_insn(ctx, ISA_MIPS_R2); 5487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5488 register_name = "SRSConf2"; 5489 break; 5490 case CP0_REG06__SRSCONF3: 5491 check_insn(ctx, ISA_MIPS_R2); 5492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5493 register_name = "SRSConf3"; 5494 break; 5495 case CP0_REG06__SRSCONF4: 5496 check_insn(ctx, ISA_MIPS_R2); 5497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5498 register_name = "SRSConf4"; 5499 break; 5500 case CP0_REG06__PWCTL: 5501 check_pw(ctx); 5502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5503 register_name = "PWCtl"; 5504 break; 5505 default: 5506 goto cp0_unimplemented; 5507 } 5508 break; 5509 case CP0_REGISTER_07: 5510 switch (sel) { 5511 case CP0_REG07__HWRENA: 5512 check_insn(ctx, ISA_MIPS_R2); 5513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5514 register_name = "HWREna"; 5515 break; 5516 default: 5517 goto cp0_unimplemented; 5518 } 5519 break; 5520 case CP0_REGISTER_08: 5521 switch (sel) { 5522 case CP0_REG08__BADVADDR: 5523 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5524 tcg_gen_ext32s_tl(arg, arg); 5525 register_name = "BadVAddr"; 5526 break; 5527 case CP0_REG08__BADINSTR: 5528 CP0_CHECK(ctx->bi); 5529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5530 register_name = "BadInstr"; 5531 break; 5532 case CP0_REG08__BADINSTRP: 5533 CP0_CHECK(ctx->bp); 5534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5535 register_name = "BadInstrP"; 5536 break; 5537 case CP0_REG08__BADINSTRX: 5538 CP0_CHECK(ctx->bi); 5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5540 tcg_gen_andi_tl(arg, arg, ~0xffff); 5541 register_name = "BadInstrX"; 5542 break; 5543 default: 5544 goto cp0_unimplemented; 5545 } 5546 break; 5547 case CP0_REGISTER_09: 5548 switch (sel) { 5549 case CP0_REG09__COUNT: 5550 /* Mark as an IO operation because we read the time. */ 5551 translator_io_start(&ctx->base); 5552 5553 gen_helper_mfc0_count(arg, tcg_env); 5554 /* 5555 * Break the TB to be able to take timer interrupts immediately 5556 * after reading count. DISAS_STOP isn't sufficient, we need to 5557 * ensure we break completely out of translated code. 5558 */ 5559 gen_save_pc(ctx->base.pc_next + 4); 5560 ctx->base.is_jmp = DISAS_EXIT; 5561 register_name = "Count"; 5562 break; 5563 default: 5564 goto cp0_unimplemented; 5565 } 5566 break; 5567 case CP0_REGISTER_10: 5568 switch (sel) { 5569 case CP0_REG10__ENTRYHI: 5570 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5571 tcg_gen_ext32s_tl(arg, arg); 5572 register_name = "EntryHi"; 5573 break; 5574 default: 5575 goto cp0_unimplemented; 5576 } 5577 break; 5578 case CP0_REGISTER_11: 5579 switch (sel) { 5580 case CP0_REG11__COMPARE: 5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5582 register_name = "Compare"; 5583 break; 5584 /* 6,7 are implementation dependent */ 5585 default: 5586 goto cp0_unimplemented; 5587 } 5588 break; 5589 case CP0_REGISTER_12: 5590 switch (sel) { 5591 case CP0_REG12__STATUS: 5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5593 register_name = "Status"; 5594 break; 5595 case CP0_REG12__INTCTL: 5596 check_insn(ctx, ISA_MIPS_R2); 5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5598 register_name = "IntCtl"; 5599 break; 5600 case CP0_REG12__SRSCTL: 5601 check_insn(ctx, ISA_MIPS_R2); 5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5603 register_name = "SRSCtl"; 5604 break; 5605 case CP0_REG12__SRSMAP: 5606 check_insn(ctx, ISA_MIPS_R2); 5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5608 register_name = "SRSMap"; 5609 break; 5610 default: 5611 goto cp0_unimplemented; 5612 } 5613 break; 5614 case CP0_REGISTER_13: 5615 switch (sel) { 5616 case CP0_REG13__CAUSE: 5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5618 register_name = "Cause"; 5619 break; 5620 default: 5621 goto cp0_unimplemented; 5622 } 5623 break; 5624 case CP0_REGISTER_14: 5625 switch (sel) { 5626 case CP0_REG14__EPC: 5627 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5628 tcg_gen_ext32s_tl(arg, arg); 5629 register_name = "EPC"; 5630 break; 5631 default: 5632 goto cp0_unimplemented; 5633 } 5634 break; 5635 case CP0_REGISTER_15: 5636 switch (sel) { 5637 case CP0_REG15__PRID: 5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5639 register_name = "PRid"; 5640 break; 5641 case CP0_REG15__EBASE: 5642 check_insn(ctx, ISA_MIPS_R2); 5643 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5644 tcg_gen_ext32s_tl(arg, arg); 5645 register_name = "EBase"; 5646 break; 5647 case CP0_REG15__CMGCRBASE: 5648 check_insn(ctx, ISA_MIPS_R2); 5649 CP0_CHECK(ctx->cmgcr); 5650 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5651 tcg_gen_ext32s_tl(arg, arg); 5652 register_name = "CMGCRBase"; 5653 break; 5654 default: 5655 goto cp0_unimplemented; 5656 } 5657 break; 5658 case CP0_REGISTER_16: 5659 switch (sel) { 5660 case CP0_REG16__CONFIG: 5661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5662 register_name = "Config"; 5663 break; 5664 case CP0_REG16__CONFIG1: 5665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5666 register_name = "Config1"; 5667 break; 5668 case CP0_REG16__CONFIG2: 5669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5670 register_name = "Config2"; 5671 break; 5672 case CP0_REG16__CONFIG3: 5673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5674 register_name = "Config3"; 5675 break; 5676 case CP0_REG16__CONFIG4: 5677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5678 register_name = "Config4"; 5679 break; 5680 case CP0_REG16__CONFIG5: 5681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5682 register_name = "Config5"; 5683 break; 5684 /* 6,7 are implementation dependent */ 5685 case CP0_REG16__CONFIG6: 5686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5687 register_name = "Config6"; 5688 break; 5689 case CP0_REG16__CONFIG7: 5690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5691 register_name = "Config7"; 5692 break; 5693 default: 5694 goto cp0_unimplemented; 5695 } 5696 break; 5697 case CP0_REGISTER_17: 5698 switch (sel) { 5699 case CP0_REG17__LLADDR: 5700 gen_helper_mfc0_lladdr(arg, tcg_env); 5701 register_name = "LLAddr"; 5702 break; 5703 case CP0_REG17__MAAR: 5704 CP0_CHECK(ctx->mrp); 5705 gen_helper_mfc0_maar(arg, tcg_env); 5706 register_name = "MAAR"; 5707 break; 5708 case CP0_REG17__MAARI: 5709 CP0_CHECK(ctx->mrp); 5710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5711 register_name = "MAARI"; 5712 break; 5713 default: 5714 goto cp0_unimplemented; 5715 } 5716 break; 5717 case CP0_REGISTER_18: 5718 switch (sel) { 5719 case CP0_REG18__WATCHLO0: 5720 case CP0_REG18__WATCHLO1: 5721 case CP0_REG18__WATCHLO2: 5722 case CP0_REG18__WATCHLO3: 5723 case CP0_REG18__WATCHLO4: 5724 case CP0_REG18__WATCHLO5: 5725 case CP0_REG18__WATCHLO6: 5726 case CP0_REG18__WATCHLO7: 5727 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5728 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5729 register_name = "WatchLo"; 5730 break; 5731 default: 5732 goto cp0_unimplemented; 5733 } 5734 break; 5735 case CP0_REGISTER_19: 5736 switch (sel) { 5737 case CP0_REG19__WATCHHI0: 5738 case CP0_REG19__WATCHHI1: 5739 case CP0_REG19__WATCHHI2: 5740 case CP0_REG19__WATCHHI3: 5741 case CP0_REG19__WATCHHI4: 5742 case CP0_REG19__WATCHHI5: 5743 case CP0_REG19__WATCHHI6: 5744 case CP0_REG19__WATCHHI7: 5745 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5746 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5747 register_name = "WatchHi"; 5748 break; 5749 default: 5750 goto cp0_unimplemented; 5751 } 5752 break; 5753 case CP0_REGISTER_20: 5754 switch (sel) { 5755 case CP0_REG20__XCONTEXT: 5756 #if defined(TARGET_MIPS64) 5757 check_insn(ctx, ISA_MIPS3); 5758 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5759 tcg_gen_ext32s_tl(arg, arg); 5760 register_name = "XContext"; 5761 break; 5762 #endif 5763 default: 5764 goto cp0_unimplemented; 5765 } 5766 break; 5767 case CP0_REGISTER_21: 5768 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5769 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5770 switch (sel) { 5771 case 0: 5772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5773 register_name = "Framemask"; 5774 break; 5775 default: 5776 goto cp0_unimplemented; 5777 } 5778 break; 5779 case CP0_REGISTER_22: 5780 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5781 register_name = "'Diagnostic"; /* implementation dependent */ 5782 break; 5783 case CP0_REGISTER_23: 5784 switch (sel) { 5785 case CP0_REG23__DEBUG: 5786 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5787 register_name = "Debug"; 5788 break; 5789 case CP0_REG23__TRACECONTROL: 5790 /* PDtrace support */ 5791 /* gen_helper_mfc0_tracecontrol(arg); */ 5792 register_name = "TraceControl"; 5793 goto cp0_unimplemented; 5794 case CP0_REG23__TRACECONTROL2: 5795 /* PDtrace support */ 5796 /* gen_helper_mfc0_tracecontrol2(arg); */ 5797 register_name = "TraceControl2"; 5798 goto cp0_unimplemented; 5799 case CP0_REG23__USERTRACEDATA1: 5800 /* PDtrace support */ 5801 /* gen_helper_mfc0_usertracedata1(arg);*/ 5802 register_name = "UserTraceData1"; 5803 goto cp0_unimplemented; 5804 case CP0_REG23__TRACEIBPC: 5805 /* PDtrace support */ 5806 /* gen_helper_mfc0_traceibpc(arg); */ 5807 register_name = "TraceIBPC"; 5808 goto cp0_unimplemented; 5809 case CP0_REG23__TRACEDBPC: 5810 /* PDtrace support */ 5811 /* gen_helper_mfc0_tracedbpc(arg); */ 5812 register_name = "TraceDBPC"; 5813 goto cp0_unimplemented; 5814 default: 5815 goto cp0_unimplemented; 5816 } 5817 break; 5818 case CP0_REGISTER_24: 5819 switch (sel) { 5820 case CP0_REG24__DEPC: 5821 /* EJTAG support */ 5822 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5823 tcg_gen_ext32s_tl(arg, arg); 5824 register_name = "DEPC"; 5825 break; 5826 default: 5827 goto cp0_unimplemented; 5828 } 5829 break; 5830 case CP0_REGISTER_25: 5831 switch (sel) { 5832 case CP0_REG25__PERFCTL0: 5833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5834 register_name = "Performance0"; 5835 break; 5836 case CP0_REG25__PERFCNT0: 5837 /* gen_helper_mfc0_performance1(arg); */ 5838 register_name = "Performance1"; 5839 goto cp0_unimplemented; 5840 case CP0_REG25__PERFCTL1: 5841 /* gen_helper_mfc0_performance2(arg); */ 5842 register_name = "Performance2"; 5843 goto cp0_unimplemented; 5844 case CP0_REG25__PERFCNT1: 5845 /* gen_helper_mfc0_performance3(arg); */ 5846 register_name = "Performance3"; 5847 goto cp0_unimplemented; 5848 case CP0_REG25__PERFCTL2: 5849 /* gen_helper_mfc0_performance4(arg); */ 5850 register_name = "Performance4"; 5851 goto cp0_unimplemented; 5852 case CP0_REG25__PERFCNT2: 5853 /* gen_helper_mfc0_performance5(arg); */ 5854 register_name = "Performance5"; 5855 goto cp0_unimplemented; 5856 case CP0_REG25__PERFCTL3: 5857 /* gen_helper_mfc0_performance6(arg); */ 5858 register_name = "Performance6"; 5859 goto cp0_unimplemented; 5860 case CP0_REG25__PERFCNT3: 5861 /* gen_helper_mfc0_performance7(arg); */ 5862 register_name = "Performance7"; 5863 goto cp0_unimplemented; 5864 default: 5865 goto cp0_unimplemented; 5866 } 5867 break; 5868 case CP0_REGISTER_26: 5869 switch (sel) { 5870 case CP0_REG26__ERRCTL: 5871 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5872 register_name = "ErrCtl"; 5873 break; 5874 default: 5875 goto cp0_unimplemented; 5876 } 5877 break; 5878 case CP0_REGISTER_27: 5879 switch (sel) { 5880 case CP0_REG27__CACHERR: 5881 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5882 register_name = "CacheErr"; 5883 break; 5884 default: 5885 goto cp0_unimplemented; 5886 } 5887 break; 5888 case CP0_REGISTER_28: 5889 switch (sel) { 5890 case CP0_REG28__TAGLO: 5891 case CP0_REG28__TAGLO1: 5892 case CP0_REG28__TAGLO2: 5893 case CP0_REG28__TAGLO3: 5894 { 5895 TCGv_i64 tmp = tcg_temp_new_i64(); 5896 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5897 gen_move_low32(arg, tmp); 5898 } 5899 register_name = "TagLo"; 5900 break; 5901 case CP0_REG28__DATALO: 5902 case CP0_REG28__DATALO1: 5903 case CP0_REG28__DATALO2: 5904 case CP0_REG28__DATALO3: 5905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5906 register_name = "DataLo"; 5907 break; 5908 default: 5909 goto cp0_unimplemented; 5910 } 5911 break; 5912 case CP0_REGISTER_29: 5913 switch (sel) { 5914 case CP0_REG29__TAGHI: 5915 case CP0_REG29__TAGHI1: 5916 case CP0_REG29__TAGHI2: 5917 case CP0_REG29__TAGHI3: 5918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5919 register_name = "TagHi"; 5920 break; 5921 case CP0_REG29__DATAHI: 5922 case CP0_REG29__DATAHI1: 5923 case CP0_REG29__DATAHI2: 5924 case CP0_REG29__DATAHI3: 5925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5926 register_name = "DataHi"; 5927 break; 5928 default: 5929 goto cp0_unimplemented; 5930 } 5931 break; 5932 case CP0_REGISTER_30: 5933 switch (sel) { 5934 case CP0_REG30__ERROREPC: 5935 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5936 tcg_gen_ext32s_tl(arg, arg); 5937 register_name = "ErrorEPC"; 5938 break; 5939 default: 5940 goto cp0_unimplemented; 5941 } 5942 break; 5943 case CP0_REGISTER_31: 5944 switch (sel) { 5945 case CP0_REG31__DESAVE: 5946 /* EJTAG support */ 5947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5948 register_name = "DESAVE"; 5949 break; 5950 case CP0_REG31__KSCRATCH1: 5951 case CP0_REG31__KSCRATCH2: 5952 case CP0_REG31__KSCRATCH3: 5953 case CP0_REG31__KSCRATCH4: 5954 case CP0_REG31__KSCRATCH5: 5955 case CP0_REG31__KSCRATCH6: 5956 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5957 tcg_gen_ld_tl(arg, tcg_env, 5958 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5959 tcg_gen_ext32s_tl(arg, arg); 5960 register_name = "KScratch"; 5961 break; 5962 default: 5963 goto cp0_unimplemented; 5964 } 5965 break; 5966 default: 5967 goto cp0_unimplemented; 5968 } 5969 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5970 return; 5971 5972 cp0_unimplemented: 5973 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5974 register_name, reg, sel); 5975 gen_mfc0_unimplemented(ctx, arg); 5976 } 5977 5978 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5979 { 5980 const char *register_name = "invalid"; 5981 bool icount; 5982 5983 if (sel != 0) { 5984 check_insn(ctx, ISA_MIPS_R1); 5985 } 5986 5987 icount = translator_io_start(&ctx->base); 5988 5989 switch (reg) { 5990 case CP0_REGISTER_00: 5991 switch (sel) { 5992 case CP0_REG00__INDEX: 5993 gen_helper_mtc0_index(tcg_env, arg); 5994 register_name = "Index"; 5995 break; 5996 case CP0_REG00__MVPCONTROL: 5997 CP0_CHECK(ctx->insn_flags & ASE_MT); 5998 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5999 register_name = "MVPControl"; 6000 break; 6001 case CP0_REG00__MVPCONF0: 6002 CP0_CHECK(ctx->insn_flags & ASE_MT); 6003 /* ignored */ 6004 register_name = "MVPConf0"; 6005 break; 6006 case CP0_REG00__MVPCONF1: 6007 CP0_CHECK(ctx->insn_flags & ASE_MT); 6008 /* ignored */ 6009 register_name = "MVPConf1"; 6010 break; 6011 case CP0_REG00__VPCONTROL: 6012 CP0_CHECK(ctx->vp); 6013 /* ignored */ 6014 register_name = "VPControl"; 6015 break; 6016 default: 6017 goto cp0_unimplemented; 6018 } 6019 break; 6020 case CP0_REGISTER_01: 6021 switch (sel) { 6022 case CP0_REG01__RANDOM: 6023 /* ignored */ 6024 register_name = "Random"; 6025 break; 6026 case CP0_REG01__VPECONTROL: 6027 CP0_CHECK(ctx->insn_flags & ASE_MT); 6028 gen_helper_mtc0_vpecontrol(tcg_env, arg); 6029 register_name = "VPEControl"; 6030 break; 6031 case CP0_REG01__VPECONF0: 6032 CP0_CHECK(ctx->insn_flags & ASE_MT); 6033 gen_helper_mtc0_vpeconf0(tcg_env, arg); 6034 register_name = "VPEConf0"; 6035 break; 6036 case CP0_REG01__VPECONF1: 6037 CP0_CHECK(ctx->insn_flags & ASE_MT); 6038 gen_helper_mtc0_vpeconf1(tcg_env, arg); 6039 register_name = "VPEConf1"; 6040 break; 6041 case CP0_REG01__YQMASK: 6042 CP0_CHECK(ctx->insn_flags & ASE_MT); 6043 gen_helper_mtc0_yqmask(tcg_env, arg); 6044 register_name = "YQMask"; 6045 break; 6046 case CP0_REG01__VPESCHEDULE: 6047 CP0_CHECK(ctx->insn_flags & ASE_MT); 6048 tcg_gen_st_tl(arg, tcg_env, 6049 offsetof(CPUMIPSState, CP0_VPESchedule)); 6050 register_name = "VPESchedule"; 6051 break; 6052 case CP0_REG01__VPESCHEFBACK: 6053 CP0_CHECK(ctx->insn_flags & ASE_MT); 6054 tcg_gen_st_tl(arg, tcg_env, 6055 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6056 register_name = "VPEScheFBack"; 6057 break; 6058 case CP0_REG01__VPEOPT: 6059 CP0_CHECK(ctx->insn_flags & ASE_MT); 6060 gen_helper_mtc0_vpeopt(tcg_env, arg); 6061 register_name = "VPEOpt"; 6062 break; 6063 default: 6064 goto cp0_unimplemented; 6065 } 6066 break; 6067 case CP0_REGISTER_02: 6068 switch (sel) { 6069 case CP0_REG02__ENTRYLO0: 6070 gen_helper_mtc0_entrylo0(tcg_env, arg); 6071 register_name = "EntryLo0"; 6072 break; 6073 case CP0_REG02__TCSTATUS: 6074 CP0_CHECK(ctx->insn_flags & ASE_MT); 6075 gen_helper_mtc0_tcstatus(tcg_env, arg); 6076 register_name = "TCStatus"; 6077 break; 6078 case CP0_REG02__TCBIND: 6079 CP0_CHECK(ctx->insn_flags & ASE_MT); 6080 gen_helper_mtc0_tcbind(tcg_env, arg); 6081 register_name = "TCBind"; 6082 break; 6083 case CP0_REG02__TCRESTART: 6084 CP0_CHECK(ctx->insn_flags & ASE_MT); 6085 gen_helper_mtc0_tcrestart(tcg_env, arg); 6086 register_name = "TCRestart"; 6087 break; 6088 case CP0_REG02__TCHALT: 6089 CP0_CHECK(ctx->insn_flags & ASE_MT); 6090 gen_helper_mtc0_tchalt(tcg_env, arg); 6091 register_name = "TCHalt"; 6092 break; 6093 case CP0_REG02__TCCONTEXT: 6094 CP0_CHECK(ctx->insn_flags & ASE_MT); 6095 gen_helper_mtc0_tccontext(tcg_env, arg); 6096 register_name = "TCContext"; 6097 break; 6098 case CP0_REG02__TCSCHEDULE: 6099 CP0_CHECK(ctx->insn_flags & ASE_MT); 6100 gen_helper_mtc0_tcschedule(tcg_env, arg); 6101 register_name = "TCSchedule"; 6102 break; 6103 case CP0_REG02__TCSCHEFBACK: 6104 CP0_CHECK(ctx->insn_flags & ASE_MT); 6105 gen_helper_mtc0_tcschefback(tcg_env, arg); 6106 register_name = "TCScheFBack"; 6107 break; 6108 default: 6109 goto cp0_unimplemented; 6110 } 6111 break; 6112 case CP0_REGISTER_03: 6113 switch (sel) { 6114 case CP0_REG03__ENTRYLO1: 6115 gen_helper_mtc0_entrylo1(tcg_env, arg); 6116 register_name = "EntryLo1"; 6117 break; 6118 case CP0_REG03__GLOBALNUM: 6119 CP0_CHECK(ctx->vp); 6120 /* ignored */ 6121 register_name = "GlobalNumber"; 6122 break; 6123 default: 6124 goto cp0_unimplemented; 6125 } 6126 break; 6127 case CP0_REGISTER_04: 6128 switch (sel) { 6129 case CP0_REG04__CONTEXT: 6130 gen_helper_mtc0_context(tcg_env, arg); 6131 register_name = "Context"; 6132 break; 6133 case CP0_REG04__CONTEXTCONFIG: 6134 /* SmartMIPS ASE */ 6135 /* gen_helper_mtc0_contextconfig(arg); */ 6136 register_name = "ContextConfig"; 6137 goto cp0_unimplemented; 6138 case CP0_REG04__USERLOCAL: 6139 CP0_CHECK(ctx->ulri); 6140 tcg_gen_st_tl(arg, tcg_env, 6141 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6142 register_name = "UserLocal"; 6143 break; 6144 case CP0_REG04__MMID: 6145 CP0_CHECK(ctx->mi); 6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6147 register_name = "MMID"; 6148 break; 6149 default: 6150 goto cp0_unimplemented; 6151 } 6152 break; 6153 case CP0_REGISTER_05: 6154 switch (sel) { 6155 case CP0_REG05__PAGEMASK: 6156 gen_helper_mtc0_pagemask(tcg_env, arg); 6157 register_name = "PageMask"; 6158 break; 6159 case CP0_REG05__PAGEGRAIN: 6160 check_insn(ctx, ISA_MIPS_R2); 6161 gen_helper_mtc0_pagegrain(tcg_env, arg); 6162 register_name = "PageGrain"; 6163 ctx->base.is_jmp = DISAS_STOP; 6164 break; 6165 case CP0_REG05__SEGCTL0: 6166 CP0_CHECK(ctx->sc); 6167 gen_helper_mtc0_segctl0(tcg_env, arg); 6168 register_name = "SegCtl0"; 6169 break; 6170 case CP0_REG05__SEGCTL1: 6171 CP0_CHECK(ctx->sc); 6172 gen_helper_mtc0_segctl1(tcg_env, arg); 6173 register_name = "SegCtl1"; 6174 break; 6175 case CP0_REG05__SEGCTL2: 6176 CP0_CHECK(ctx->sc); 6177 gen_helper_mtc0_segctl2(tcg_env, arg); 6178 register_name = "SegCtl2"; 6179 break; 6180 case CP0_REG05__PWBASE: 6181 check_pw(ctx); 6182 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6183 register_name = "PWBase"; 6184 break; 6185 case CP0_REG05__PWFIELD: 6186 check_pw(ctx); 6187 gen_helper_mtc0_pwfield(tcg_env, arg); 6188 register_name = "PWField"; 6189 break; 6190 case CP0_REG05__PWSIZE: 6191 check_pw(ctx); 6192 gen_helper_mtc0_pwsize(tcg_env, arg); 6193 register_name = "PWSize"; 6194 break; 6195 default: 6196 goto cp0_unimplemented; 6197 } 6198 break; 6199 case CP0_REGISTER_06: 6200 switch (sel) { 6201 case CP0_REG06__WIRED: 6202 gen_helper_mtc0_wired(tcg_env, arg); 6203 register_name = "Wired"; 6204 break; 6205 case CP0_REG06__SRSCONF0: 6206 check_insn(ctx, ISA_MIPS_R2); 6207 gen_helper_mtc0_srsconf0(tcg_env, arg); 6208 register_name = "SRSConf0"; 6209 break; 6210 case CP0_REG06__SRSCONF1: 6211 check_insn(ctx, ISA_MIPS_R2); 6212 gen_helper_mtc0_srsconf1(tcg_env, arg); 6213 register_name = "SRSConf1"; 6214 break; 6215 case CP0_REG06__SRSCONF2: 6216 check_insn(ctx, ISA_MIPS_R2); 6217 gen_helper_mtc0_srsconf2(tcg_env, arg); 6218 register_name = "SRSConf2"; 6219 break; 6220 case CP0_REG06__SRSCONF3: 6221 check_insn(ctx, ISA_MIPS_R2); 6222 gen_helper_mtc0_srsconf3(tcg_env, arg); 6223 register_name = "SRSConf3"; 6224 break; 6225 case CP0_REG06__SRSCONF4: 6226 check_insn(ctx, ISA_MIPS_R2); 6227 gen_helper_mtc0_srsconf4(tcg_env, arg); 6228 register_name = "SRSConf4"; 6229 break; 6230 case CP0_REG06__PWCTL: 6231 check_pw(ctx); 6232 gen_helper_mtc0_pwctl(tcg_env, arg); 6233 register_name = "PWCtl"; 6234 break; 6235 default: 6236 goto cp0_unimplemented; 6237 } 6238 break; 6239 case CP0_REGISTER_07: 6240 switch (sel) { 6241 case CP0_REG07__HWRENA: 6242 check_insn(ctx, ISA_MIPS_R2); 6243 gen_helper_mtc0_hwrena(tcg_env, arg); 6244 ctx->base.is_jmp = DISAS_STOP; 6245 register_name = "HWREna"; 6246 break; 6247 default: 6248 goto cp0_unimplemented; 6249 } 6250 break; 6251 case CP0_REGISTER_08: 6252 switch (sel) { 6253 case CP0_REG08__BADVADDR: 6254 /* ignored */ 6255 register_name = "BadVAddr"; 6256 break; 6257 case CP0_REG08__BADINSTR: 6258 /* ignored */ 6259 register_name = "BadInstr"; 6260 break; 6261 case CP0_REG08__BADINSTRP: 6262 /* ignored */ 6263 register_name = "BadInstrP"; 6264 break; 6265 case CP0_REG08__BADINSTRX: 6266 /* ignored */ 6267 register_name = "BadInstrX"; 6268 break; 6269 default: 6270 goto cp0_unimplemented; 6271 } 6272 break; 6273 case CP0_REGISTER_09: 6274 switch (sel) { 6275 case CP0_REG09__COUNT: 6276 gen_helper_mtc0_count(tcg_env, arg); 6277 register_name = "Count"; 6278 break; 6279 default: 6280 goto cp0_unimplemented; 6281 } 6282 break; 6283 case CP0_REGISTER_10: 6284 switch (sel) { 6285 case CP0_REG10__ENTRYHI: 6286 gen_helper_mtc0_entryhi(tcg_env, arg); 6287 register_name = "EntryHi"; 6288 break; 6289 default: 6290 goto cp0_unimplemented; 6291 } 6292 break; 6293 case CP0_REGISTER_11: 6294 switch (sel) { 6295 case CP0_REG11__COMPARE: 6296 gen_helper_mtc0_compare(tcg_env, arg); 6297 register_name = "Compare"; 6298 break; 6299 /* 6,7 are implementation dependent */ 6300 default: 6301 goto cp0_unimplemented; 6302 } 6303 break; 6304 case CP0_REGISTER_12: 6305 switch (sel) { 6306 case CP0_REG12__STATUS: 6307 save_cpu_state(ctx, 1); 6308 gen_helper_mtc0_status(tcg_env, arg); 6309 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6310 gen_save_pc(ctx->base.pc_next + 4); 6311 ctx->base.is_jmp = DISAS_EXIT; 6312 register_name = "Status"; 6313 break; 6314 case CP0_REG12__INTCTL: 6315 check_insn(ctx, ISA_MIPS_R2); 6316 gen_helper_mtc0_intctl(tcg_env, arg); 6317 /* Stop translation as we may have switched the execution mode */ 6318 ctx->base.is_jmp = DISAS_STOP; 6319 register_name = "IntCtl"; 6320 break; 6321 case CP0_REG12__SRSCTL: 6322 check_insn(ctx, ISA_MIPS_R2); 6323 gen_helper_mtc0_srsctl(tcg_env, arg); 6324 /* Stop translation as we may have switched the execution mode */ 6325 ctx->base.is_jmp = DISAS_STOP; 6326 register_name = "SRSCtl"; 6327 break; 6328 case CP0_REG12__SRSMAP: 6329 check_insn(ctx, ISA_MIPS_R2); 6330 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6331 /* Stop translation as we may have switched the execution mode */ 6332 ctx->base.is_jmp = DISAS_STOP; 6333 register_name = "SRSMap"; 6334 break; 6335 default: 6336 goto cp0_unimplemented; 6337 } 6338 break; 6339 case CP0_REGISTER_13: 6340 switch (sel) { 6341 case CP0_REG13__CAUSE: 6342 save_cpu_state(ctx, 1); 6343 gen_helper_mtc0_cause(tcg_env, arg); 6344 /* 6345 * Stop translation as we may have triggered an interrupt. 6346 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6347 * translated code to check for pending interrupts. 6348 */ 6349 gen_save_pc(ctx->base.pc_next + 4); 6350 ctx->base.is_jmp = DISAS_EXIT; 6351 register_name = "Cause"; 6352 break; 6353 default: 6354 goto cp0_unimplemented; 6355 } 6356 break; 6357 case CP0_REGISTER_14: 6358 switch (sel) { 6359 case CP0_REG14__EPC: 6360 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6361 register_name = "EPC"; 6362 break; 6363 default: 6364 goto cp0_unimplemented; 6365 } 6366 break; 6367 case CP0_REGISTER_15: 6368 switch (sel) { 6369 case CP0_REG15__PRID: 6370 /* ignored */ 6371 register_name = "PRid"; 6372 break; 6373 case CP0_REG15__EBASE: 6374 check_insn(ctx, ISA_MIPS_R2); 6375 gen_helper_mtc0_ebase(tcg_env, arg); 6376 register_name = "EBase"; 6377 break; 6378 default: 6379 goto cp0_unimplemented; 6380 } 6381 break; 6382 case CP0_REGISTER_16: 6383 switch (sel) { 6384 case CP0_REG16__CONFIG: 6385 gen_helper_mtc0_config0(tcg_env, arg); 6386 register_name = "Config"; 6387 /* Stop translation as we may have switched the execution mode */ 6388 ctx->base.is_jmp = DISAS_STOP; 6389 break; 6390 case CP0_REG16__CONFIG1: 6391 /* ignored, read only */ 6392 register_name = "Config1"; 6393 break; 6394 case CP0_REG16__CONFIG2: 6395 gen_helper_mtc0_config2(tcg_env, arg); 6396 register_name = "Config2"; 6397 /* Stop translation as we may have switched the execution mode */ 6398 ctx->base.is_jmp = DISAS_STOP; 6399 break; 6400 case CP0_REG16__CONFIG3: 6401 gen_helper_mtc0_config3(tcg_env, arg); 6402 register_name = "Config3"; 6403 /* Stop translation as we may have switched the execution mode */ 6404 ctx->base.is_jmp = DISAS_STOP; 6405 break; 6406 case CP0_REG16__CONFIG4: 6407 gen_helper_mtc0_config4(tcg_env, arg); 6408 register_name = "Config4"; 6409 ctx->base.is_jmp = DISAS_STOP; 6410 break; 6411 case CP0_REG16__CONFIG5: 6412 gen_helper_mtc0_config5(tcg_env, arg); 6413 register_name = "Config5"; 6414 /* Stop translation as we may have switched the execution mode */ 6415 ctx->base.is_jmp = DISAS_STOP; 6416 break; 6417 /* 6,7 are implementation dependent */ 6418 case CP0_REG16__CONFIG6: 6419 /* ignored */ 6420 register_name = "Config6"; 6421 break; 6422 case CP0_REG16__CONFIG7: 6423 /* ignored */ 6424 register_name = "Config7"; 6425 break; 6426 default: 6427 register_name = "Invalid config selector"; 6428 goto cp0_unimplemented; 6429 } 6430 break; 6431 case CP0_REGISTER_17: 6432 switch (sel) { 6433 case CP0_REG17__LLADDR: 6434 gen_helper_mtc0_lladdr(tcg_env, arg); 6435 register_name = "LLAddr"; 6436 break; 6437 case CP0_REG17__MAAR: 6438 CP0_CHECK(ctx->mrp); 6439 gen_helper_mtc0_maar(tcg_env, arg); 6440 register_name = "MAAR"; 6441 break; 6442 case CP0_REG17__MAARI: 6443 CP0_CHECK(ctx->mrp); 6444 gen_helper_mtc0_maari(tcg_env, arg); 6445 register_name = "MAARI"; 6446 break; 6447 default: 6448 goto cp0_unimplemented; 6449 } 6450 break; 6451 case CP0_REGISTER_18: 6452 switch (sel) { 6453 case CP0_REG18__WATCHLO0: 6454 case CP0_REG18__WATCHLO1: 6455 case CP0_REG18__WATCHLO2: 6456 case CP0_REG18__WATCHLO3: 6457 case CP0_REG18__WATCHLO4: 6458 case CP0_REG18__WATCHLO5: 6459 case CP0_REG18__WATCHLO6: 6460 case CP0_REG18__WATCHLO7: 6461 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6462 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6463 register_name = "WatchLo"; 6464 break; 6465 default: 6466 goto cp0_unimplemented; 6467 } 6468 break; 6469 case CP0_REGISTER_19: 6470 switch (sel) { 6471 case CP0_REG19__WATCHHI0: 6472 case CP0_REG19__WATCHHI1: 6473 case CP0_REG19__WATCHHI2: 6474 case CP0_REG19__WATCHHI3: 6475 case CP0_REG19__WATCHHI4: 6476 case CP0_REG19__WATCHHI5: 6477 case CP0_REG19__WATCHHI6: 6478 case CP0_REG19__WATCHHI7: 6479 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6480 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6481 register_name = "WatchHi"; 6482 break; 6483 default: 6484 goto cp0_unimplemented; 6485 } 6486 break; 6487 case CP0_REGISTER_20: 6488 switch (sel) { 6489 case CP0_REG20__XCONTEXT: 6490 #if defined(TARGET_MIPS64) 6491 check_insn(ctx, ISA_MIPS3); 6492 gen_helper_mtc0_xcontext(tcg_env, arg); 6493 register_name = "XContext"; 6494 break; 6495 #endif 6496 default: 6497 goto cp0_unimplemented; 6498 } 6499 break; 6500 case CP0_REGISTER_21: 6501 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6502 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6503 switch (sel) { 6504 case 0: 6505 gen_helper_mtc0_framemask(tcg_env, arg); 6506 register_name = "Framemask"; 6507 break; 6508 default: 6509 goto cp0_unimplemented; 6510 } 6511 break; 6512 case CP0_REGISTER_22: 6513 /* ignored */ 6514 register_name = "Diagnostic"; /* implementation dependent */ 6515 break; 6516 case CP0_REGISTER_23: 6517 switch (sel) { 6518 case CP0_REG23__DEBUG: 6519 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6520 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6521 gen_save_pc(ctx->base.pc_next + 4); 6522 ctx->base.is_jmp = DISAS_EXIT; 6523 register_name = "Debug"; 6524 break; 6525 case CP0_REG23__TRACECONTROL: 6526 /* PDtrace support */ 6527 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6528 register_name = "TraceControl"; 6529 /* Stop translation as we may have switched the execution mode */ 6530 ctx->base.is_jmp = DISAS_STOP; 6531 goto cp0_unimplemented; 6532 case CP0_REG23__TRACECONTROL2: 6533 /* PDtrace support */ 6534 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6535 register_name = "TraceControl2"; 6536 /* Stop translation as we may have switched the execution mode */ 6537 ctx->base.is_jmp = DISAS_STOP; 6538 goto cp0_unimplemented; 6539 case CP0_REG23__USERTRACEDATA1: 6540 /* Stop translation as we may have switched the execution mode */ 6541 ctx->base.is_jmp = DISAS_STOP; 6542 /* PDtrace support */ 6543 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6544 register_name = "UserTraceData"; 6545 /* Stop translation as we may have switched the execution mode */ 6546 ctx->base.is_jmp = DISAS_STOP; 6547 goto cp0_unimplemented; 6548 case CP0_REG23__TRACEIBPC: 6549 /* PDtrace support */ 6550 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6551 /* Stop translation as we may have switched the execution mode */ 6552 ctx->base.is_jmp = DISAS_STOP; 6553 register_name = "TraceIBPC"; 6554 goto cp0_unimplemented; 6555 case CP0_REG23__TRACEDBPC: 6556 /* PDtrace support */ 6557 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6558 /* Stop translation as we may have switched the execution mode */ 6559 ctx->base.is_jmp = DISAS_STOP; 6560 register_name = "TraceDBPC"; 6561 goto cp0_unimplemented; 6562 default: 6563 goto cp0_unimplemented; 6564 } 6565 break; 6566 case CP0_REGISTER_24: 6567 switch (sel) { 6568 case CP0_REG24__DEPC: 6569 /* EJTAG support */ 6570 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6571 register_name = "DEPC"; 6572 break; 6573 default: 6574 goto cp0_unimplemented; 6575 } 6576 break; 6577 case CP0_REGISTER_25: 6578 switch (sel) { 6579 case CP0_REG25__PERFCTL0: 6580 gen_helper_mtc0_performance0(tcg_env, arg); 6581 register_name = "Performance0"; 6582 break; 6583 case CP0_REG25__PERFCNT0: 6584 /* gen_helper_mtc0_performance1(arg); */ 6585 register_name = "Performance1"; 6586 goto cp0_unimplemented; 6587 case CP0_REG25__PERFCTL1: 6588 /* gen_helper_mtc0_performance2(arg); */ 6589 register_name = "Performance2"; 6590 goto cp0_unimplemented; 6591 case CP0_REG25__PERFCNT1: 6592 /* gen_helper_mtc0_performance3(arg); */ 6593 register_name = "Performance3"; 6594 goto cp0_unimplemented; 6595 case CP0_REG25__PERFCTL2: 6596 /* gen_helper_mtc0_performance4(arg); */ 6597 register_name = "Performance4"; 6598 goto cp0_unimplemented; 6599 case CP0_REG25__PERFCNT2: 6600 /* gen_helper_mtc0_performance5(arg); */ 6601 register_name = "Performance5"; 6602 goto cp0_unimplemented; 6603 case CP0_REG25__PERFCTL3: 6604 /* gen_helper_mtc0_performance6(arg); */ 6605 register_name = "Performance6"; 6606 goto cp0_unimplemented; 6607 case CP0_REG25__PERFCNT3: 6608 /* gen_helper_mtc0_performance7(arg); */ 6609 register_name = "Performance7"; 6610 goto cp0_unimplemented; 6611 default: 6612 goto cp0_unimplemented; 6613 } 6614 break; 6615 case CP0_REGISTER_26: 6616 switch (sel) { 6617 case CP0_REG26__ERRCTL: 6618 gen_helper_mtc0_errctl(tcg_env, arg); 6619 ctx->base.is_jmp = DISAS_STOP; 6620 register_name = "ErrCtl"; 6621 break; 6622 default: 6623 goto cp0_unimplemented; 6624 } 6625 break; 6626 case CP0_REGISTER_27: 6627 switch (sel) { 6628 case CP0_REG27__CACHERR: 6629 /* ignored */ 6630 register_name = "CacheErr"; 6631 break; 6632 default: 6633 goto cp0_unimplemented; 6634 } 6635 break; 6636 case CP0_REGISTER_28: 6637 switch (sel) { 6638 case CP0_REG28__TAGLO: 6639 case CP0_REG28__TAGLO1: 6640 case CP0_REG28__TAGLO2: 6641 case CP0_REG28__TAGLO3: 6642 gen_helper_mtc0_taglo(tcg_env, arg); 6643 register_name = "TagLo"; 6644 break; 6645 case CP0_REG28__DATALO: 6646 case CP0_REG28__DATALO1: 6647 case CP0_REG28__DATALO2: 6648 case CP0_REG28__DATALO3: 6649 gen_helper_mtc0_datalo(tcg_env, arg); 6650 register_name = "DataLo"; 6651 break; 6652 default: 6653 goto cp0_unimplemented; 6654 } 6655 break; 6656 case CP0_REGISTER_29: 6657 switch (sel) { 6658 case CP0_REG29__TAGHI: 6659 case CP0_REG29__TAGHI1: 6660 case CP0_REG29__TAGHI2: 6661 case CP0_REG29__TAGHI3: 6662 gen_helper_mtc0_taghi(tcg_env, arg); 6663 register_name = "TagHi"; 6664 break; 6665 case CP0_REG29__DATAHI: 6666 case CP0_REG29__DATAHI1: 6667 case CP0_REG29__DATAHI2: 6668 case CP0_REG29__DATAHI3: 6669 gen_helper_mtc0_datahi(tcg_env, arg); 6670 register_name = "DataHi"; 6671 break; 6672 default: 6673 register_name = "invalid sel"; 6674 goto cp0_unimplemented; 6675 } 6676 break; 6677 case CP0_REGISTER_30: 6678 switch (sel) { 6679 case CP0_REG30__ERROREPC: 6680 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6681 register_name = "ErrorEPC"; 6682 break; 6683 default: 6684 goto cp0_unimplemented; 6685 } 6686 break; 6687 case CP0_REGISTER_31: 6688 switch (sel) { 6689 case CP0_REG31__DESAVE: 6690 /* EJTAG support */ 6691 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6692 register_name = "DESAVE"; 6693 break; 6694 case CP0_REG31__KSCRATCH1: 6695 case CP0_REG31__KSCRATCH2: 6696 case CP0_REG31__KSCRATCH3: 6697 case CP0_REG31__KSCRATCH4: 6698 case CP0_REG31__KSCRATCH5: 6699 case CP0_REG31__KSCRATCH6: 6700 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6701 tcg_gen_st_tl(arg, tcg_env, 6702 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6703 register_name = "KScratch"; 6704 break; 6705 default: 6706 goto cp0_unimplemented; 6707 } 6708 break; 6709 default: 6710 goto cp0_unimplemented; 6711 } 6712 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6713 6714 /* For simplicity assume that all writes can cause interrupts. */ 6715 if (icount) { 6716 /* 6717 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6718 * translated code to check for pending interrupts. 6719 */ 6720 gen_save_pc(ctx->base.pc_next + 4); 6721 ctx->base.is_jmp = DISAS_EXIT; 6722 } 6723 return; 6724 6725 cp0_unimplemented: 6726 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6727 register_name, reg, sel); 6728 } 6729 6730 #if defined(TARGET_MIPS64) 6731 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6732 { 6733 const char *register_name = "invalid"; 6734 6735 if (sel != 0) { 6736 check_insn(ctx, ISA_MIPS_R1); 6737 } 6738 6739 switch (reg) { 6740 case CP0_REGISTER_00: 6741 switch (sel) { 6742 case CP0_REG00__INDEX: 6743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6744 register_name = "Index"; 6745 break; 6746 case CP0_REG00__MVPCONTROL: 6747 CP0_CHECK(ctx->insn_flags & ASE_MT); 6748 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6749 register_name = "MVPControl"; 6750 break; 6751 case CP0_REG00__MVPCONF0: 6752 CP0_CHECK(ctx->insn_flags & ASE_MT); 6753 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6754 register_name = "MVPConf0"; 6755 break; 6756 case CP0_REG00__MVPCONF1: 6757 CP0_CHECK(ctx->insn_flags & ASE_MT); 6758 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6759 register_name = "MVPConf1"; 6760 break; 6761 case CP0_REG00__VPCONTROL: 6762 CP0_CHECK(ctx->vp); 6763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6764 register_name = "VPControl"; 6765 break; 6766 default: 6767 goto cp0_unimplemented; 6768 } 6769 break; 6770 case CP0_REGISTER_01: 6771 switch (sel) { 6772 case CP0_REG01__RANDOM: 6773 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6774 gen_helper_mfc0_random(arg, tcg_env); 6775 register_name = "Random"; 6776 break; 6777 case CP0_REG01__VPECONTROL: 6778 CP0_CHECK(ctx->insn_flags & ASE_MT); 6779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6780 register_name = "VPEControl"; 6781 break; 6782 case CP0_REG01__VPECONF0: 6783 CP0_CHECK(ctx->insn_flags & ASE_MT); 6784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6785 register_name = "VPEConf0"; 6786 break; 6787 case CP0_REG01__VPECONF1: 6788 CP0_CHECK(ctx->insn_flags & ASE_MT); 6789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6790 register_name = "VPEConf1"; 6791 break; 6792 case CP0_REG01__YQMASK: 6793 CP0_CHECK(ctx->insn_flags & ASE_MT); 6794 tcg_gen_ld_tl(arg, tcg_env, 6795 offsetof(CPUMIPSState, CP0_YQMask)); 6796 register_name = "YQMask"; 6797 break; 6798 case CP0_REG01__VPESCHEDULE: 6799 CP0_CHECK(ctx->insn_flags & ASE_MT); 6800 tcg_gen_ld_tl(arg, tcg_env, 6801 offsetof(CPUMIPSState, CP0_VPESchedule)); 6802 register_name = "VPESchedule"; 6803 break; 6804 case CP0_REG01__VPESCHEFBACK: 6805 CP0_CHECK(ctx->insn_flags & ASE_MT); 6806 tcg_gen_ld_tl(arg, tcg_env, 6807 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6808 register_name = "VPEScheFBack"; 6809 break; 6810 case CP0_REG01__VPEOPT: 6811 CP0_CHECK(ctx->insn_flags & ASE_MT); 6812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6813 register_name = "VPEOpt"; 6814 break; 6815 default: 6816 goto cp0_unimplemented; 6817 } 6818 break; 6819 case CP0_REGISTER_02: 6820 switch (sel) { 6821 case CP0_REG02__ENTRYLO0: 6822 tcg_gen_ld_tl(arg, tcg_env, 6823 offsetof(CPUMIPSState, CP0_EntryLo0)); 6824 register_name = "EntryLo0"; 6825 break; 6826 case CP0_REG02__TCSTATUS: 6827 CP0_CHECK(ctx->insn_flags & ASE_MT); 6828 gen_helper_mfc0_tcstatus(arg, tcg_env); 6829 register_name = "TCStatus"; 6830 break; 6831 case CP0_REG02__TCBIND: 6832 CP0_CHECK(ctx->insn_flags & ASE_MT); 6833 gen_helper_mfc0_tcbind(arg, tcg_env); 6834 register_name = "TCBind"; 6835 break; 6836 case CP0_REG02__TCRESTART: 6837 CP0_CHECK(ctx->insn_flags & ASE_MT); 6838 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6839 register_name = "TCRestart"; 6840 break; 6841 case CP0_REG02__TCHALT: 6842 CP0_CHECK(ctx->insn_flags & ASE_MT); 6843 gen_helper_dmfc0_tchalt(arg, tcg_env); 6844 register_name = "TCHalt"; 6845 break; 6846 case CP0_REG02__TCCONTEXT: 6847 CP0_CHECK(ctx->insn_flags & ASE_MT); 6848 gen_helper_dmfc0_tccontext(arg, tcg_env); 6849 register_name = "TCContext"; 6850 break; 6851 case CP0_REG02__TCSCHEDULE: 6852 CP0_CHECK(ctx->insn_flags & ASE_MT); 6853 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6854 register_name = "TCSchedule"; 6855 break; 6856 case CP0_REG02__TCSCHEFBACK: 6857 CP0_CHECK(ctx->insn_flags & ASE_MT); 6858 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6859 register_name = "TCScheFBack"; 6860 break; 6861 default: 6862 goto cp0_unimplemented; 6863 } 6864 break; 6865 case CP0_REGISTER_03: 6866 switch (sel) { 6867 case CP0_REG03__ENTRYLO1: 6868 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6869 register_name = "EntryLo1"; 6870 break; 6871 case CP0_REG03__GLOBALNUM: 6872 CP0_CHECK(ctx->vp); 6873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6874 register_name = "GlobalNumber"; 6875 break; 6876 default: 6877 goto cp0_unimplemented; 6878 } 6879 break; 6880 case CP0_REGISTER_04: 6881 switch (sel) { 6882 case CP0_REG04__CONTEXT: 6883 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6884 register_name = "Context"; 6885 break; 6886 case CP0_REG04__CONTEXTCONFIG: 6887 /* SmartMIPS ASE */ 6888 /* gen_helper_dmfc0_contextconfig(arg); */ 6889 register_name = "ContextConfig"; 6890 goto cp0_unimplemented; 6891 case CP0_REG04__USERLOCAL: 6892 CP0_CHECK(ctx->ulri); 6893 tcg_gen_ld_tl(arg, tcg_env, 6894 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6895 register_name = "UserLocal"; 6896 break; 6897 case CP0_REG04__MMID: 6898 CP0_CHECK(ctx->mi); 6899 gen_helper_mtc0_memorymapid(tcg_env, arg); 6900 register_name = "MMID"; 6901 break; 6902 default: 6903 goto cp0_unimplemented; 6904 } 6905 break; 6906 case CP0_REGISTER_05: 6907 switch (sel) { 6908 case CP0_REG05__PAGEMASK: 6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6910 register_name = "PageMask"; 6911 break; 6912 case CP0_REG05__PAGEGRAIN: 6913 check_insn(ctx, ISA_MIPS_R2); 6914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6915 register_name = "PageGrain"; 6916 break; 6917 case CP0_REG05__SEGCTL0: 6918 CP0_CHECK(ctx->sc); 6919 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6920 register_name = "SegCtl0"; 6921 break; 6922 case CP0_REG05__SEGCTL1: 6923 CP0_CHECK(ctx->sc); 6924 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6925 register_name = "SegCtl1"; 6926 break; 6927 case CP0_REG05__SEGCTL2: 6928 CP0_CHECK(ctx->sc); 6929 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6930 register_name = "SegCtl2"; 6931 break; 6932 case CP0_REG05__PWBASE: 6933 check_pw(ctx); 6934 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6935 register_name = "PWBase"; 6936 break; 6937 case CP0_REG05__PWFIELD: 6938 check_pw(ctx); 6939 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6940 register_name = "PWField"; 6941 break; 6942 case CP0_REG05__PWSIZE: 6943 check_pw(ctx); 6944 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6945 register_name = "PWSize"; 6946 break; 6947 default: 6948 goto cp0_unimplemented; 6949 } 6950 break; 6951 case CP0_REGISTER_06: 6952 switch (sel) { 6953 case CP0_REG06__WIRED: 6954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6955 register_name = "Wired"; 6956 break; 6957 case CP0_REG06__SRSCONF0: 6958 check_insn(ctx, ISA_MIPS_R2); 6959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6960 register_name = "SRSConf0"; 6961 break; 6962 case CP0_REG06__SRSCONF1: 6963 check_insn(ctx, ISA_MIPS_R2); 6964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6965 register_name = "SRSConf1"; 6966 break; 6967 case CP0_REG06__SRSCONF2: 6968 check_insn(ctx, ISA_MIPS_R2); 6969 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6970 register_name = "SRSConf2"; 6971 break; 6972 case CP0_REG06__SRSCONF3: 6973 check_insn(ctx, ISA_MIPS_R2); 6974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6975 register_name = "SRSConf3"; 6976 break; 6977 case CP0_REG06__SRSCONF4: 6978 check_insn(ctx, ISA_MIPS_R2); 6979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6980 register_name = "SRSConf4"; 6981 break; 6982 case CP0_REG06__PWCTL: 6983 check_pw(ctx); 6984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6985 register_name = "PWCtl"; 6986 break; 6987 default: 6988 goto cp0_unimplemented; 6989 } 6990 break; 6991 case CP0_REGISTER_07: 6992 switch (sel) { 6993 case CP0_REG07__HWRENA: 6994 check_insn(ctx, ISA_MIPS_R2); 6995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6996 register_name = "HWREna"; 6997 break; 6998 default: 6999 goto cp0_unimplemented; 7000 } 7001 break; 7002 case CP0_REGISTER_08: 7003 switch (sel) { 7004 case CP0_REG08__BADVADDR: 7005 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7006 register_name = "BadVAddr"; 7007 break; 7008 case CP0_REG08__BADINSTR: 7009 CP0_CHECK(ctx->bi); 7010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7011 register_name = "BadInstr"; 7012 break; 7013 case CP0_REG08__BADINSTRP: 7014 CP0_CHECK(ctx->bp); 7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7016 register_name = "BadInstrP"; 7017 break; 7018 case CP0_REG08__BADINSTRX: 7019 CP0_CHECK(ctx->bi); 7020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7021 tcg_gen_andi_tl(arg, arg, ~0xffff); 7022 register_name = "BadInstrX"; 7023 break; 7024 default: 7025 goto cp0_unimplemented; 7026 } 7027 break; 7028 case CP0_REGISTER_09: 7029 switch (sel) { 7030 case CP0_REG09__COUNT: 7031 /* Mark as an IO operation because we read the time. */ 7032 translator_io_start(&ctx->base); 7033 gen_helper_mfc0_count(arg, tcg_env); 7034 /* 7035 * Break the TB to be able to take timer interrupts immediately 7036 * after reading count. DISAS_STOP isn't sufficient, we need to 7037 * ensure we break completely out of translated code. 7038 */ 7039 gen_save_pc(ctx->base.pc_next + 4); 7040 ctx->base.is_jmp = DISAS_EXIT; 7041 register_name = "Count"; 7042 break; 7043 default: 7044 goto cp0_unimplemented; 7045 } 7046 break; 7047 case CP0_REGISTER_10: 7048 switch (sel) { 7049 case CP0_REG10__ENTRYHI: 7050 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7051 register_name = "EntryHi"; 7052 break; 7053 default: 7054 goto cp0_unimplemented; 7055 } 7056 break; 7057 case CP0_REGISTER_11: 7058 switch (sel) { 7059 case CP0_REG11__COMPARE: 7060 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7061 register_name = "Compare"; 7062 break; 7063 /* 6,7 are implementation dependent */ 7064 default: 7065 goto cp0_unimplemented; 7066 } 7067 break; 7068 case CP0_REGISTER_12: 7069 switch (sel) { 7070 case CP0_REG12__STATUS: 7071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7072 register_name = "Status"; 7073 break; 7074 case CP0_REG12__INTCTL: 7075 check_insn(ctx, ISA_MIPS_R2); 7076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7077 register_name = "IntCtl"; 7078 break; 7079 case CP0_REG12__SRSCTL: 7080 check_insn(ctx, ISA_MIPS_R2); 7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7082 register_name = "SRSCtl"; 7083 break; 7084 case CP0_REG12__SRSMAP: 7085 check_insn(ctx, ISA_MIPS_R2); 7086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7087 register_name = "SRSMap"; 7088 break; 7089 default: 7090 goto cp0_unimplemented; 7091 } 7092 break; 7093 case CP0_REGISTER_13: 7094 switch (sel) { 7095 case CP0_REG13__CAUSE: 7096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7097 register_name = "Cause"; 7098 break; 7099 default: 7100 goto cp0_unimplemented; 7101 } 7102 break; 7103 case CP0_REGISTER_14: 7104 switch (sel) { 7105 case CP0_REG14__EPC: 7106 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7107 register_name = "EPC"; 7108 break; 7109 default: 7110 goto cp0_unimplemented; 7111 } 7112 break; 7113 case CP0_REGISTER_15: 7114 switch (sel) { 7115 case CP0_REG15__PRID: 7116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7117 register_name = "PRid"; 7118 break; 7119 case CP0_REG15__EBASE: 7120 check_insn(ctx, ISA_MIPS_R2); 7121 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 7122 register_name = "EBase"; 7123 break; 7124 case CP0_REG15__CMGCRBASE: 7125 check_insn(ctx, ISA_MIPS_R2); 7126 CP0_CHECK(ctx->cmgcr); 7127 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7128 register_name = "CMGCRBase"; 7129 break; 7130 default: 7131 goto cp0_unimplemented; 7132 } 7133 break; 7134 case CP0_REGISTER_16: 7135 switch (sel) { 7136 case CP0_REG16__CONFIG: 7137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7138 register_name = "Config"; 7139 break; 7140 case CP0_REG16__CONFIG1: 7141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7142 register_name = "Config1"; 7143 break; 7144 case CP0_REG16__CONFIG2: 7145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7146 register_name = "Config2"; 7147 break; 7148 case CP0_REG16__CONFIG3: 7149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7150 register_name = "Config3"; 7151 break; 7152 case CP0_REG16__CONFIG4: 7153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7154 register_name = "Config4"; 7155 break; 7156 case CP0_REG16__CONFIG5: 7157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7158 register_name = "Config5"; 7159 break; 7160 /* 6,7 are implementation dependent */ 7161 case CP0_REG16__CONFIG6: 7162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7163 register_name = "Config6"; 7164 break; 7165 case CP0_REG16__CONFIG7: 7166 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7167 register_name = "Config7"; 7168 break; 7169 default: 7170 goto cp0_unimplemented; 7171 } 7172 break; 7173 case CP0_REGISTER_17: 7174 switch (sel) { 7175 case CP0_REG17__LLADDR: 7176 gen_helper_dmfc0_lladdr(arg, tcg_env); 7177 register_name = "LLAddr"; 7178 break; 7179 case CP0_REG17__MAAR: 7180 CP0_CHECK(ctx->mrp); 7181 gen_helper_dmfc0_maar(arg, tcg_env); 7182 register_name = "MAAR"; 7183 break; 7184 case CP0_REG17__MAARI: 7185 CP0_CHECK(ctx->mrp); 7186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7187 register_name = "MAARI"; 7188 break; 7189 default: 7190 goto cp0_unimplemented; 7191 } 7192 break; 7193 case CP0_REGISTER_18: 7194 switch (sel) { 7195 case CP0_REG18__WATCHLO0: 7196 case CP0_REG18__WATCHLO1: 7197 case CP0_REG18__WATCHLO2: 7198 case CP0_REG18__WATCHLO3: 7199 case CP0_REG18__WATCHLO4: 7200 case CP0_REG18__WATCHLO5: 7201 case CP0_REG18__WATCHLO6: 7202 case CP0_REG18__WATCHLO7: 7203 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7204 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7205 register_name = "WatchLo"; 7206 break; 7207 default: 7208 goto cp0_unimplemented; 7209 } 7210 break; 7211 case CP0_REGISTER_19: 7212 switch (sel) { 7213 case CP0_REG19__WATCHHI0: 7214 case CP0_REG19__WATCHHI1: 7215 case CP0_REG19__WATCHHI2: 7216 case CP0_REG19__WATCHHI3: 7217 case CP0_REG19__WATCHHI4: 7218 case CP0_REG19__WATCHHI5: 7219 case CP0_REG19__WATCHHI6: 7220 case CP0_REG19__WATCHHI7: 7221 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7222 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7223 register_name = "WatchHi"; 7224 break; 7225 default: 7226 goto cp0_unimplemented; 7227 } 7228 break; 7229 case CP0_REGISTER_20: 7230 switch (sel) { 7231 case CP0_REG20__XCONTEXT: 7232 check_insn(ctx, ISA_MIPS3); 7233 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7234 register_name = "XContext"; 7235 break; 7236 default: 7237 goto cp0_unimplemented; 7238 } 7239 break; 7240 case CP0_REGISTER_21: 7241 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7242 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7243 switch (sel) { 7244 case 0: 7245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7246 register_name = "Framemask"; 7247 break; 7248 default: 7249 goto cp0_unimplemented; 7250 } 7251 break; 7252 case CP0_REGISTER_22: 7253 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7254 register_name = "'Diagnostic"; /* implementation dependent */ 7255 break; 7256 case CP0_REGISTER_23: 7257 switch (sel) { 7258 case CP0_REG23__DEBUG: 7259 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7260 register_name = "Debug"; 7261 break; 7262 case CP0_REG23__TRACECONTROL: 7263 /* PDtrace support */ 7264 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7265 register_name = "TraceControl"; 7266 goto cp0_unimplemented; 7267 case CP0_REG23__TRACECONTROL2: 7268 /* PDtrace support */ 7269 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7270 register_name = "TraceControl2"; 7271 goto cp0_unimplemented; 7272 case CP0_REG23__USERTRACEDATA1: 7273 /* PDtrace support */ 7274 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7275 register_name = "UserTraceData1"; 7276 goto cp0_unimplemented; 7277 case CP0_REG23__TRACEIBPC: 7278 /* PDtrace support */ 7279 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7280 register_name = "TraceIBPC"; 7281 goto cp0_unimplemented; 7282 case CP0_REG23__TRACEDBPC: 7283 /* PDtrace support */ 7284 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7285 register_name = "TraceDBPC"; 7286 goto cp0_unimplemented; 7287 default: 7288 goto cp0_unimplemented; 7289 } 7290 break; 7291 case CP0_REGISTER_24: 7292 switch (sel) { 7293 case CP0_REG24__DEPC: 7294 /* EJTAG support */ 7295 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7296 register_name = "DEPC"; 7297 break; 7298 default: 7299 goto cp0_unimplemented; 7300 } 7301 break; 7302 case CP0_REGISTER_25: 7303 switch (sel) { 7304 case CP0_REG25__PERFCTL0: 7305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7306 register_name = "Performance0"; 7307 break; 7308 case CP0_REG25__PERFCNT0: 7309 /* gen_helper_dmfc0_performance1(arg); */ 7310 register_name = "Performance1"; 7311 goto cp0_unimplemented; 7312 case CP0_REG25__PERFCTL1: 7313 /* gen_helper_dmfc0_performance2(arg); */ 7314 register_name = "Performance2"; 7315 goto cp0_unimplemented; 7316 case CP0_REG25__PERFCNT1: 7317 /* gen_helper_dmfc0_performance3(arg); */ 7318 register_name = "Performance3"; 7319 goto cp0_unimplemented; 7320 case CP0_REG25__PERFCTL2: 7321 /* gen_helper_dmfc0_performance4(arg); */ 7322 register_name = "Performance4"; 7323 goto cp0_unimplemented; 7324 case CP0_REG25__PERFCNT2: 7325 /* gen_helper_dmfc0_performance5(arg); */ 7326 register_name = "Performance5"; 7327 goto cp0_unimplemented; 7328 case CP0_REG25__PERFCTL3: 7329 /* gen_helper_dmfc0_performance6(arg); */ 7330 register_name = "Performance6"; 7331 goto cp0_unimplemented; 7332 case CP0_REG25__PERFCNT3: 7333 /* gen_helper_dmfc0_performance7(arg); */ 7334 register_name = "Performance7"; 7335 goto cp0_unimplemented; 7336 default: 7337 goto cp0_unimplemented; 7338 } 7339 break; 7340 case CP0_REGISTER_26: 7341 switch (sel) { 7342 case CP0_REG26__ERRCTL: 7343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7344 register_name = "ErrCtl"; 7345 break; 7346 default: 7347 goto cp0_unimplemented; 7348 } 7349 break; 7350 case CP0_REGISTER_27: 7351 switch (sel) { 7352 /* ignored */ 7353 case CP0_REG27__CACHERR: 7354 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7355 register_name = "CacheErr"; 7356 break; 7357 default: 7358 goto cp0_unimplemented; 7359 } 7360 break; 7361 case CP0_REGISTER_28: 7362 switch (sel) { 7363 case CP0_REG28__TAGLO: 7364 case CP0_REG28__TAGLO1: 7365 case CP0_REG28__TAGLO2: 7366 case CP0_REG28__TAGLO3: 7367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7368 register_name = "TagLo"; 7369 break; 7370 case CP0_REG28__DATALO: 7371 case CP0_REG28__DATALO1: 7372 case CP0_REG28__DATALO2: 7373 case CP0_REG28__DATALO3: 7374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7375 register_name = "DataLo"; 7376 break; 7377 default: 7378 goto cp0_unimplemented; 7379 } 7380 break; 7381 case CP0_REGISTER_29: 7382 switch (sel) { 7383 case CP0_REG29__TAGHI: 7384 case CP0_REG29__TAGHI1: 7385 case CP0_REG29__TAGHI2: 7386 case CP0_REG29__TAGHI3: 7387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7388 register_name = "TagHi"; 7389 break; 7390 case CP0_REG29__DATAHI: 7391 case CP0_REG29__DATAHI1: 7392 case CP0_REG29__DATAHI2: 7393 case CP0_REG29__DATAHI3: 7394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7395 register_name = "DataHi"; 7396 break; 7397 default: 7398 goto cp0_unimplemented; 7399 } 7400 break; 7401 case CP0_REGISTER_30: 7402 switch (sel) { 7403 case CP0_REG30__ERROREPC: 7404 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7405 register_name = "ErrorEPC"; 7406 break; 7407 default: 7408 goto cp0_unimplemented; 7409 } 7410 break; 7411 case CP0_REGISTER_31: 7412 switch (sel) { 7413 case CP0_REG31__DESAVE: 7414 /* EJTAG support */ 7415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7416 register_name = "DESAVE"; 7417 break; 7418 case CP0_REG31__KSCRATCH1: 7419 case CP0_REG31__KSCRATCH2: 7420 case CP0_REG31__KSCRATCH3: 7421 case CP0_REG31__KSCRATCH4: 7422 case CP0_REG31__KSCRATCH5: 7423 case CP0_REG31__KSCRATCH6: 7424 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7425 tcg_gen_ld_tl(arg, tcg_env, 7426 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7427 register_name = "KScratch"; 7428 break; 7429 default: 7430 goto cp0_unimplemented; 7431 } 7432 break; 7433 default: 7434 goto cp0_unimplemented; 7435 } 7436 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7437 return; 7438 7439 cp0_unimplemented: 7440 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7441 register_name, reg, sel); 7442 gen_mfc0_unimplemented(ctx, arg); 7443 } 7444 7445 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7446 { 7447 const char *register_name = "invalid"; 7448 bool icount; 7449 7450 if (sel != 0) { 7451 check_insn(ctx, ISA_MIPS_R1); 7452 } 7453 7454 icount = translator_io_start(&ctx->base); 7455 7456 switch (reg) { 7457 case CP0_REGISTER_00: 7458 switch (sel) { 7459 case CP0_REG00__INDEX: 7460 gen_helper_mtc0_index(tcg_env, arg); 7461 register_name = "Index"; 7462 break; 7463 case CP0_REG00__MVPCONTROL: 7464 CP0_CHECK(ctx->insn_flags & ASE_MT); 7465 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7466 register_name = "MVPControl"; 7467 break; 7468 case CP0_REG00__MVPCONF0: 7469 CP0_CHECK(ctx->insn_flags & ASE_MT); 7470 /* ignored */ 7471 register_name = "MVPConf0"; 7472 break; 7473 case CP0_REG00__MVPCONF1: 7474 CP0_CHECK(ctx->insn_flags & ASE_MT); 7475 /* ignored */ 7476 register_name = "MVPConf1"; 7477 break; 7478 case CP0_REG00__VPCONTROL: 7479 CP0_CHECK(ctx->vp); 7480 /* ignored */ 7481 register_name = "VPControl"; 7482 break; 7483 default: 7484 goto cp0_unimplemented; 7485 } 7486 break; 7487 case CP0_REGISTER_01: 7488 switch (sel) { 7489 case CP0_REG01__RANDOM: 7490 /* ignored */ 7491 register_name = "Random"; 7492 break; 7493 case CP0_REG01__VPECONTROL: 7494 CP0_CHECK(ctx->insn_flags & ASE_MT); 7495 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7496 register_name = "VPEControl"; 7497 break; 7498 case CP0_REG01__VPECONF0: 7499 CP0_CHECK(ctx->insn_flags & ASE_MT); 7500 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7501 register_name = "VPEConf0"; 7502 break; 7503 case CP0_REG01__VPECONF1: 7504 CP0_CHECK(ctx->insn_flags & ASE_MT); 7505 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7506 register_name = "VPEConf1"; 7507 break; 7508 case CP0_REG01__YQMASK: 7509 CP0_CHECK(ctx->insn_flags & ASE_MT); 7510 gen_helper_mtc0_yqmask(tcg_env, arg); 7511 register_name = "YQMask"; 7512 break; 7513 case CP0_REG01__VPESCHEDULE: 7514 CP0_CHECK(ctx->insn_flags & ASE_MT); 7515 tcg_gen_st_tl(arg, tcg_env, 7516 offsetof(CPUMIPSState, CP0_VPESchedule)); 7517 register_name = "VPESchedule"; 7518 break; 7519 case CP0_REG01__VPESCHEFBACK: 7520 CP0_CHECK(ctx->insn_flags & ASE_MT); 7521 tcg_gen_st_tl(arg, tcg_env, 7522 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7523 register_name = "VPEScheFBack"; 7524 break; 7525 case CP0_REG01__VPEOPT: 7526 CP0_CHECK(ctx->insn_flags & ASE_MT); 7527 gen_helper_mtc0_vpeopt(tcg_env, arg); 7528 register_name = "VPEOpt"; 7529 break; 7530 default: 7531 goto cp0_unimplemented; 7532 } 7533 break; 7534 case CP0_REGISTER_02: 7535 switch (sel) { 7536 case CP0_REG02__ENTRYLO0: 7537 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7538 register_name = "EntryLo0"; 7539 break; 7540 case CP0_REG02__TCSTATUS: 7541 CP0_CHECK(ctx->insn_flags & ASE_MT); 7542 gen_helper_mtc0_tcstatus(tcg_env, arg); 7543 register_name = "TCStatus"; 7544 break; 7545 case CP0_REG02__TCBIND: 7546 CP0_CHECK(ctx->insn_flags & ASE_MT); 7547 gen_helper_mtc0_tcbind(tcg_env, arg); 7548 register_name = "TCBind"; 7549 break; 7550 case CP0_REG02__TCRESTART: 7551 CP0_CHECK(ctx->insn_flags & ASE_MT); 7552 gen_helper_mtc0_tcrestart(tcg_env, arg); 7553 register_name = "TCRestart"; 7554 break; 7555 case CP0_REG02__TCHALT: 7556 CP0_CHECK(ctx->insn_flags & ASE_MT); 7557 gen_helper_mtc0_tchalt(tcg_env, arg); 7558 register_name = "TCHalt"; 7559 break; 7560 case CP0_REG02__TCCONTEXT: 7561 CP0_CHECK(ctx->insn_flags & ASE_MT); 7562 gen_helper_mtc0_tccontext(tcg_env, arg); 7563 register_name = "TCContext"; 7564 break; 7565 case CP0_REG02__TCSCHEDULE: 7566 CP0_CHECK(ctx->insn_flags & ASE_MT); 7567 gen_helper_mtc0_tcschedule(tcg_env, arg); 7568 register_name = "TCSchedule"; 7569 break; 7570 case CP0_REG02__TCSCHEFBACK: 7571 CP0_CHECK(ctx->insn_flags & ASE_MT); 7572 gen_helper_mtc0_tcschefback(tcg_env, arg); 7573 register_name = "TCScheFBack"; 7574 break; 7575 default: 7576 goto cp0_unimplemented; 7577 } 7578 break; 7579 case CP0_REGISTER_03: 7580 switch (sel) { 7581 case CP0_REG03__ENTRYLO1: 7582 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7583 register_name = "EntryLo1"; 7584 break; 7585 case CP0_REG03__GLOBALNUM: 7586 CP0_CHECK(ctx->vp); 7587 /* ignored */ 7588 register_name = "GlobalNumber"; 7589 break; 7590 default: 7591 goto cp0_unimplemented; 7592 } 7593 break; 7594 case CP0_REGISTER_04: 7595 switch (sel) { 7596 case CP0_REG04__CONTEXT: 7597 gen_helper_mtc0_context(tcg_env, arg); 7598 register_name = "Context"; 7599 break; 7600 case CP0_REG04__CONTEXTCONFIG: 7601 /* SmartMIPS ASE */ 7602 /* gen_helper_dmtc0_contextconfig(arg); */ 7603 register_name = "ContextConfig"; 7604 goto cp0_unimplemented; 7605 case CP0_REG04__USERLOCAL: 7606 CP0_CHECK(ctx->ulri); 7607 tcg_gen_st_tl(arg, tcg_env, 7608 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7609 register_name = "UserLocal"; 7610 break; 7611 case CP0_REG04__MMID: 7612 CP0_CHECK(ctx->mi); 7613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7614 register_name = "MMID"; 7615 break; 7616 default: 7617 goto cp0_unimplemented; 7618 } 7619 break; 7620 case CP0_REGISTER_05: 7621 switch (sel) { 7622 case CP0_REG05__PAGEMASK: 7623 gen_helper_mtc0_pagemask(tcg_env, arg); 7624 register_name = "PageMask"; 7625 break; 7626 case CP0_REG05__PAGEGRAIN: 7627 check_insn(ctx, ISA_MIPS_R2); 7628 gen_helper_mtc0_pagegrain(tcg_env, arg); 7629 register_name = "PageGrain"; 7630 break; 7631 case CP0_REG05__SEGCTL0: 7632 CP0_CHECK(ctx->sc); 7633 gen_helper_mtc0_segctl0(tcg_env, arg); 7634 register_name = "SegCtl0"; 7635 break; 7636 case CP0_REG05__SEGCTL1: 7637 CP0_CHECK(ctx->sc); 7638 gen_helper_mtc0_segctl1(tcg_env, arg); 7639 register_name = "SegCtl1"; 7640 break; 7641 case CP0_REG05__SEGCTL2: 7642 CP0_CHECK(ctx->sc); 7643 gen_helper_mtc0_segctl2(tcg_env, arg); 7644 register_name = "SegCtl2"; 7645 break; 7646 case CP0_REG05__PWBASE: 7647 check_pw(ctx); 7648 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7649 register_name = "PWBase"; 7650 break; 7651 case CP0_REG05__PWFIELD: 7652 check_pw(ctx); 7653 gen_helper_mtc0_pwfield(tcg_env, arg); 7654 register_name = "PWField"; 7655 break; 7656 case CP0_REG05__PWSIZE: 7657 check_pw(ctx); 7658 gen_helper_mtc0_pwsize(tcg_env, arg); 7659 register_name = "PWSize"; 7660 break; 7661 default: 7662 goto cp0_unimplemented; 7663 } 7664 break; 7665 case CP0_REGISTER_06: 7666 switch (sel) { 7667 case CP0_REG06__WIRED: 7668 gen_helper_mtc0_wired(tcg_env, arg); 7669 register_name = "Wired"; 7670 break; 7671 case CP0_REG06__SRSCONF0: 7672 check_insn(ctx, ISA_MIPS_R2); 7673 gen_helper_mtc0_srsconf0(tcg_env, arg); 7674 register_name = "SRSConf0"; 7675 break; 7676 case CP0_REG06__SRSCONF1: 7677 check_insn(ctx, ISA_MIPS_R2); 7678 gen_helper_mtc0_srsconf1(tcg_env, arg); 7679 register_name = "SRSConf1"; 7680 break; 7681 case CP0_REG06__SRSCONF2: 7682 check_insn(ctx, ISA_MIPS_R2); 7683 gen_helper_mtc0_srsconf2(tcg_env, arg); 7684 register_name = "SRSConf2"; 7685 break; 7686 case CP0_REG06__SRSCONF3: 7687 check_insn(ctx, ISA_MIPS_R2); 7688 gen_helper_mtc0_srsconf3(tcg_env, arg); 7689 register_name = "SRSConf3"; 7690 break; 7691 case CP0_REG06__SRSCONF4: 7692 check_insn(ctx, ISA_MIPS_R2); 7693 gen_helper_mtc0_srsconf4(tcg_env, arg); 7694 register_name = "SRSConf4"; 7695 break; 7696 case CP0_REG06__PWCTL: 7697 check_pw(ctx); 7698 gen_helper_mtc0_pwctl(tcg_env, arg); 7699 register_name = "PWCtl"; 7700 break; 7701 default: 7702 goto cp0_unimplemented; 7703 } 7704 break; 7705 case CP0_REGISTER_07: 7706 switch (sel) { 7707 case CP0_REG07__HWRENA: 7708 check_insn(ctx, ISA_MIPS_R2); 7709 gen_helper_mtc0_hwrena(tcg_env, arg); 7710 ctx->base.is_jmp = DISAS_STOP; 7711 register_name = "HWREna"; 7712 break; 7713 default: 7714 goto cp0_unimplemented; 7715 } 7716 break; 7717 case CP0_REGISTER_08: 7718 switch (sel) { 7719 case CP0_REG08__BADVADDR: 7720 /* ignored */ 7721 register_name = "BadVAddr"; 7722 break; 7723 case CP0_REG08__BADINSTR: 7724 /* ignored */ 7725 register_name = "BadInstr"; 7726 break; 7727 case CP0_REG08__BADINSTRP: 7728 /* ignored */ 7729 register_name = "BadInstrP"; 7730 break; 7731 case CP0_REG08__BADINSTRX: 7732 /* ignored */ 7733 register_name = "BadInstrX"; 7734 break; 7735 default: 7736 goto cp0_unimplemented; 7737 } 7738 break; 7739 case CP0_REGISTER_09: 7740 switch (sel) { 7741 case CP0_REG09__COUNT: 7742 gen_helper_mtc0_count(tcg_env, arg); 7743 register_name = "Count"; 7744 break; 7745 default: 7746 goto cp0_unimplemented; 7747 } 7748 /* Stop translation as we may have switched the execution mode */ 7749 ctx->base.is_jmp = DISAS_STOP; 7750 break; 7751 case CP0_REGISTER_10: 7752 switch (sel) { 7753 case CP0_REG10__ENTRYHI: 7754 gen_helper_mtc0_entryhi(tcg_env, arg); 7755 register_name = "EntryHi"; 7756 break; 7757 default: 7758 goto cp0_unimplemented; 7759 } 7760 break; 7761 case CP0_REGISTER_11: 7762 switch (sel) { 7763 case CP0_REG11__COMPARE: 7764 gen_helper_mtc0_compare(tcg_env, arg); 7765 register_name = "Compare"; 7766 break; 7767 /* 6,7 are implementation dependent */ 7768 default: 7769 goto cp0_unimplemented; 7770 } 7771 /* Stop translation as we may have switched the execution mode */ 7772 ctx->base.is_jmp = DISAS_STOP; 7773 break; 7774 case CP0_REGISTER_12: 7775 switch (sel) { 7776 case CP0_REG12__STATUS: 7777 save_cpu_state(ctx, 1); 7778 gen_helper_mtc0_status(tcg_env, arg); 7779 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7780 gen_save_pc(ctx->base.pc_next + 4); 7781 ctx->base.is_jmp = DISAS_EXIT; 7782 register_name = "Status"; 7783 break; 7784 case CP0_REG12__INTCTL: 7785 check_insn(ctx, ISA_MIPS_R2); 7786 gen_helper_mtc0_intctl(tcg_env, arg); 7787 /* Stop translation as we may have switched the execution mode */ 7788 ctx->base.is_jmp = DISAS_STOP; 7789 register_name = "IntCtl"; 7790 break; 7791 case CP0_REG12__SRSCTL: 7792 check_insn(ctx, ISA_MIPS_R2); 7793 gen_helper_mtc0_srsctl(tcg_env, arg); 7794 /* Stop translation as we may have switched the execution mode */ 7795 ctx->base.is_jmp = DISAS_STOP; 7796 register_name = "SRSCtl"; 7797 break; 7798 case CP0_REG12__SRSMAP: 7799 check_insn(ctx, ISA_MIPS_R2); 7800 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7801 /* Stop translation as we may have switched the execution mode */ 7802 ctx->base.is_jmp = DISAS_STOP; 7803 register_name = "SRSMap"; 7804 break; 7805 default: 7806 goto cp0_unimplemented; 7807 } 7808 break; 7809 case CP0_REGISTER_13: 7810 switch (sel) { 7811 case CP0_REG13__CAUSE: 7812 save_cpu_state(ctx, 1); 7813 gen_helper_mtc0_cause(tcg_env, arg); 7814 /* 7815 * Stop translation as we may have triggered an interrupt. 7816 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7817 * translated code to check for pending interrupts. 7818 */ 7819 gen_save_pc(ctx->base.pc_next + 4); 7820 ctx->base.is_jmp = DISAS_EXIT; 7821 register_name = "Cause"; 7822 break; 7823 default: 7824 goto cp0_unimplemented; 7825 } 7826 break; 7827 case CP0_REGISTER_14: 7828 switch (sel) { 7829 case CP0_REG14__EPC: 7830 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7831 register_name = "EPC"; 7832 break; 7833 default: 7834 goto cp0_unimplemented; 7835 } 7836 break; 7837 case CP0_REGISTER_15: 7838 switch (sel) { 7839 case CP0_REG15__PRID: 7840 /* ignored */ 7841 register_name = "PRid"; 7842 break; 7843 case CP0_REG15__EBASE: 7844 check_insn(ctx, ISA_MIPS_R2); 7845 gen_helper_mtc0_ebase(tcg_env, arg); 7846 register_name = "EBase"; 7847 break; 7848 default: 7849 goto cp0_unimplemented; 7850 } 7851 break; 7852 case CP0_REGISTER_16: 7853 switch (sel) { 7854 case CP0_REG16__CONFIG: 7855 gen_helper_mtc0_config0(tcg_env, arg); 7856 register_name = "Config"; 7857 /* Stop translation as we may have switched the execution mode */ 7858 ctx->base.is_jmp = DISAS_STOP; 7859 break; 7860 case CP0_REG16__CONFIG1: 7861 /* ignored, read only */ 7862 register_name = "Config1"; 7863 break; 7864 case CP0_REG16__CONFIG2: 7865 gen_helper_mtc0_config2(tcg_env, arg); 7866 register_name = "Config2"; 7867 /* Stop translation as we may have switched the execution mode */ 7868 ctx->base.is_jmp = DISAS_STOP; 7869 break; 7870 case CP0_REG16__CONFIG3: 7871 gen_helper_mtc0_config3(tcg_env, arg); 7872 register_name = "Config3"; 7873 /* Stop translation as we may have switched the execution mode */ 7874 ctx->base.is_jmp = DISAS_STOP; 7875 break; 7876 case CP0_REG16__CONFIG4: 7877 /* currently ignored */ 7878 register_name = "Config4"; 7879 break; 7880 case CP0_REG16__CONFIG5: 7881 gen_helper_mtc0_config5(tcg_env, arg); 7882 register_name = "Config5"; 7883 /* Stop translation as we may have switched the execution mode */ 7884 ctx->base.is_jmp = DISAS_STOP; 7885 break; 7886 /* 6,7 are implementation dependent */ 7887 default: 7888 register_name = "Invalid config selector"; 7889 goto cp0_unimplemented; 7890 } 7891 break; 7892 case CP0_REGISTER_17: 7893 switch (sel) { 7894 case CP0_REG17__LLADDR: 7895 gen_helper_mtc0_lladdr(tcg_env, arg); 7896 register_name = "LLAddr"; 7897 break; 7898 case CP0_REG17__MAAR: 7899 CP0_CHECK(ctx->mrp); 7900 gen_helper_mtc0_maar(tcg_env, arg); 7901 register_name = "MAAR"; 7902 break; 7903 case CP0_REG17__MAARI: 7904 CP0_CHECK(ctx->mrp); 7905 gen_helper_mtc0_maari(tcg_env, arg); 7906 register_name = "MAARI"; 7907 break; 7908 default: 7909 goto cp0_unimplemented; 7910 } 7911 break; 7912 case CP0_REGISTER_18: 7913 switch (sel) { 7914 case CP0_REG18__WATCHLO0: 7915 case CP0_REG18__WATCHLO1: 7916 case CP0_REG18__WATCHLO2: 7917 case CP0_REG18__WATCHLO3: 7918 case CP0_REG18__WATCHLO4: 7919 case CP0_REG18__WATCHLO5: 7920 case CP0_REG18__WATCHLO6: 7921 case CP0_REG18__WATCHLO7: 7922 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7923 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7924 register_name = "WatchLo"; 7925 break; 7926 default: 7927 goto cp0_unimplemented; 7928 } 7929 break; 7930 case CP0_REGISTER_19: 7931 switch (sel) { 7932 case CP0_REG19__WATCHHI0: 7933 case CP0_REG19__WATCHHI1: 7934 case CP0_REG19__WATCHHI2: 7935 case CP0_REG19__WATCHHI3: 7936 case CP0_REG19__WATCHHI4: 7937 case CP0_REG19__WATCHHI5: 7938 case CP0_REG19__WATCHHI6: 7939 case CP0_REG19__WATCHHI7: 7940 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7941 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7942 register_name = "WatchHi"; 7943 break; 7944 default: 7945 goto cp0_unimplemented; 7946 } 7947 break; 7948 case CP0_REGISTER_20: 7949 switch (sel) { 7950 case CP0_REG20__XCONTEXT: 7951 check_insn(ctx, ISA_MIPS3); 7952 gen_helper_mtc0_xcontext(tcg_env, arg); 7953 register_name = "XContext"; 7954 break; 7955 default: 7956 goto cp0_unimplemented; 7957 } 7958 break; 7959 case CP0_REGISTER_21: 7960 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7961 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7962 switch (sel) { 7963 case 0: 7964 gen_helper_mtc0_framemask(tcg_env, arg); 7965 register_name = "Framemask"; 7966 break; 7967 default: 7968 goto cp0_unimplemented; 7969 } 7970 break; 7971 case CP0_REGISTER_22: 7972 /* ignored */ 7973 register_name = "Diagnostic"; /* implementation dependent */ 7974 break; 7975 case CP0_REGISTER_23: 7976 switch (sel) { 7977 case CP0_REG23__DEBUG: 7978 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7979 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7980 gen_save_pc(ctx->base.pc_next + 4); 7981 ctx->base.is_jmp = DISAS_EXIT; 7982 register_name = "Debug"; 7983 break; 7984 case CP0_REG23__TRACECONTROL: 7985 /* PDtrace support */ 7986 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7987 /* Stop translation as we may have switched the execution mode */ 7988 ctx->base.is_jmp = DISAS_STOP; 7989 register_name = "TraceControl"; 7990 goto cp0_unimplemented; 7991 case CP0_REG23__TRACECONTROL2: 7992 /* PDtrace support */ 7993 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7994 /* Stop translation as we may have switched the execution mode */ 7995 ctx->base.is_jmp = DISAS_STOP; 7996 register_name = "TraceControl2"; 7997 goto cp0_unimplemented; 7998 case CP0_REG23__USERTRACEDATA1: 7999 /* PDtrace support */ 8000 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 8001 /* Stop translation as we may have switched the execution mode */ 8002 ctx->base.is_jmp = DISAS_STOP; 8003 register_name = "UserTraceData1"; 8004 goto cp0_unimplemented; 8005 case CP0_REG23__TRACEIBPC: 8006 /* PDtrace support */ 8007 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 8008 /* Stop translation as we may have switched the execution mode */ 8009 ctx->base.is_jmp = DISAS_STOP; 8010 register_name = "TraceIBPC"; 8011 goto cp0_unimplemented; 8012 case CP0_REG23__TRACEDBPC: 8013 /* PDtrace support */ 8014 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 8015 /* Stop translation as we may have switched the execution mode */ 8016 ctx->base.is_jmp = DISAS_STOP; 8017 register_name = "TraceDBPC"; 8018 goto cp0_unimplemented; 8019 default: 8020 goto cp0_unimplemented; 8021 } 8022 break; 8023 case CP0_REGISTER_24: 8024 switch (sel) { 8025 case CP0_REG24__DEPC: 8026 /* EJTAG support */ 8027 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 8028 register_name = "DEPC"; 8029 break; 8030 default: 8031 goto cp0_unimplemented; 8032 } 8033 break; 8034 case CP0_REGISTER_25: 8035 switch (sel) { 8036 case CP0_REG25__PERFCTL0: 8037 gen_helper_mtc0_performance0(tcg_env, arg); 8038 register_name = "Performance0"; 8039 break; 8040 case CP0_REG25__PERFCNT0: 8041 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 8042 register_name = "Performance1"; 8043 goto cp0_unimplemented; 8044 case CP0_REG25__PERFCTL1: 8045 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 8046 register_name = "Performance2"; 8047 goto cp0_unimplemented; 8048 case CP0_REG25__PERFCNT1: 8049 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 8050 register_name = "Performance3"; 8051 goto cp0_unimplemented; 8052 case CP0_REG25__PERFCTL2: 8053 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 8054 register_name = "Performance4"; 8055 goto cp0_unimplemented; 8056 case CP0_REG25__PERFCNT2: 8057 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 8058 register_name = "Performance5"; 8059 goto cp0_unimplemented; 8060 case CP0_REG25__PERFCTL3: 8061 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 8062 register_name = "Performance6"; 8063 goto cp0_unimplemented; 8064 case CP0_REG25__PERFCNT3: 8065 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 8066 register_name = "Performance7"; 8067 goto cp0_unimplemented; 8068 default: 8069 goto cp0_unimplemented; 8070 } 8071 break; 8072 case CP0_REGISTER_26: 8073 switch (sel) { 8074 case CP0_REG26__ERRCTL: 8075 gen_helper_mtc0_errctl(tcg_env, arg); 8076 ctx->base.is_jmp = DISAS_STOP; 8077 register_name = "ErrCtl"; 8078 break; 8079 default: 8080 goto cp0_unimplemented; 8081 } 8082 break; 8083 case CP0_REGISTER_27: 8084 switch (sel) { 8085 case CP0_REG27__CACHERR: 8086 /* ignored */ 8087 register_name = "CacheErr"; 8088 break; 8089 default: 8090 goto cp0_unimplemented; 8091 } 8092 break; 8093 case CP0_REGISTER_28: 8094 switch (sel) { 8095 case CP0_REG28__TAGLO: 8096 case CP0_REG28__TAGLO1: 8097 case CP0_REG28__TAGLO2: 8098 case CP0_REG28__TAGLO3: 8099 gen_helper_mtc0_taglo(tcg_env, arg); 8100 register_name = "TagLo"; 8101 break; 8102 case CP0_REG28__DATALO: 8103 case CP0_REG28__DATALO1: 8104 case CP0_REG28__DATALO2: 8105 case CP0_REG28__DATALO3: 8106 gen_helper_mtc0_datalo(tcg_env, arg); 8107 register_name = "DataLo"; 8108 break; 8109 default: 8110 goto cp0_unimplemented; 8111 } 8112 break; 8113 case CP0_REGISTER_29: 8114 switch (sel) { 8115 case CP0_REG29__TAGHI: 8116 case CP0_REG29__TAGHI1: 8117 case CP0_REG29__TAGHI2: 8118 case CP0_REG29__TAGHI3: 8119 gen_helper_mtc0_taghi(tcg_env, arg); 8120 register_name = "TagHi"; 8121 break; 8122 case CP0_REG29__DATAHI: 8123 case CP0_REG29__DATAHI1: 8124 case CP0_REG29__DATAHI2: 8125 case CP0_REG29__DATAHI3: 8126 gen_helper_mtc0_datahi(tcg_env, arg); 8127 register_name = "DataHi"; 8128 break; 8129 default: 8130 register_name = "invalid sel"; 8131 goto cp0_unimplemented; 8132 } 8133 break; 8134 case CP0_REGISTER_30: 8135 switch (sel) { 8136 case CP0_REG30__ERROREPC: 8137 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8138 register_name = "ErrorEPC"; 8139 break; 8140 default: 8141 goto cp0_unimplemented; 8142 } 8143 break; 8144 case CP0_REGISTER_31: 8145 switch (sel) { 8146 case CP0_REG31__DESAVE: 8147 /* EJTAG support */ 8148 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8149 register_name = "DESAVE"; 8150 break; 8151 case CP0_REG31__KSCRATCH1: 8152 case CP0_REG31__KSCRATCH2: 8153 case CP0_REG31__KSCRATCH3: 8154 case CP0_REG31__KSCRATCH4: 8155 case CP0_REG31__KSCRATCH5: 8156 case CP0_REG31__KSCRATCH6: 8157 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8158 tcg_gen_st_tl(arg, tcg_env, 8159 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8160 register_name = "KScratch"; 8161 break; 8162 default: 8163 goto cp0_unimplemented; 8164 } 8165 break; 8166 default: 8167 goto cp0_unimplemented; 8168 } 8169 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8170 8171 /* For simplicity assume that all writes can cause interrupts. */ 8172 if (icount) { 8173 /* 8174 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8175 * translated code to check for pending interrupts. 8176 */ 8177 gen_save_pc(ctx->base.pc_next + 4); 8178 ctx->base.is_jmp = DISAS_EXIT; 8179 } 8180 return; 8181 8182 cp0_unimplemented: 8183 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8184 register_name, reg, sel); 8185 } 8186 #endif /* TARGET_MIPS64 */ 8187 8188 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8189 int u, int sel, int h) 8190 { 8191 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8192 TCGv t0 = tcg_temp_new(); 8193 8194 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8195 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8196 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8197 tcg_gen_movi_tl(t0, -1); 8198 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8199 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8200 tcg_gen_movi_tl(t0, -1); 8201 } else if (u == 0) { 8202 switch (rt) { 8203 case 1: 8204 switch (sel) { 8205 case 1: 8206 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8207 break; 8208 case 2: 8209 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8210 break; 8211 default: 8212 goto die; 8213 break; 8214 } 8215 break; 8216 case 2: 8217 switch (sel) { 8218 case 1: 8219 gen_helper_mftc0_tcstatus(t0, tcg_env); 8220 break; 8221 case 2: 8222 gen_helper_mftc0_tcbind(t0, tcg_env); 8223 break; 8224 case 3: 8225 gen_helper_mftc0_tcrestart(t0, tcg_env); 8226 break; 8227 case 4: 8228 gen_helper_mftc0_tchalt(t0, tcg_env); 8229 break; 8230 case 5: 8231 gen_helper_mftc0_tccontext(t0, tcg_env); 8232 break; 8233 case 6: 8234 gen_helper_mftc0_tcschedule(t0, tcg_env); 8235 break; 8236 case 7: 8237 gen_helper_mftc0_tcschefback(t0, tcg_env); 8238 break; 8239 default: 8240 gen_mfc0(ctx, t0, rt, sel); 8241 break; 8242 } 8243 break; 8244 case 10: 8245 switch (sel) { 8246 case 0: 8247 gen_helper_mftc0_entryhi(t0, tcg_env); 8248 break; 8249 default: 8250 gen_mfc0(ctx, t0, rt, sel); 8251 break; 8252 } 8253 break; 8254 case 12: 8255 switch (sel) { 8256 case 0: 8257 gen_helper_mftc0_status(t0, tcg_env); 8258 break; 8259 default: 8260 gen_mfc0(ctx, t0, rt, sel); 8261 break; 8262 } 8263 break; 8264 case 13: 8265 switch (sel) { 8266 case 0: 8267 gen_helper_mftc0_cause(t0, tcg_env); 8268 break; 8269 default: 8270 goto die; 8271 break; 8272 } 8273 break; 8274 case 14: 8275 switch (sel) { 8276 case 0: 8277 gen_helper_mftc0_epc(t0, tcg_env); 8278 break; 8279 default: 8280 goto die; 8281 break; 8282 } 8283 break; 8284 case 15: 8285 switch (sel) { 8286 case 1: 8287 gen_helper_mftc0_ebase(t0, tcg_env); 8288 break; 8289 default: 8290 goto die; 8291 break; 8292 } 8293 break; 8294 case 16: 8295 switch (sel) { 8296 case 0: 8297 case 1: 8298 case 2: 8299 case 3: 8300 case 4: 8301 case 5: 8302 case 6: 8303 case 7: 8304 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8305 break; 8306 default: 8307 goto die; 8308 break; 8309 } 8310 break; 8311 case 23: 8312 switch (sel) { 8313 case 0: 8314 gen_helper_mftc0_debug(t0, tcg_env); 8315 break; 8316 default: 8317 gen_mfc0(ctx, t0, rt, sel); 8318 break; 8319 } 8320 break; 8321 default: 8322 gen_mfc0(ctx, t0, rt, sel); 8323 } 8324 } else { 8325 switch (sel) { 8326 /* GPR registers. */ 8327 case 0: 8328 gen_helper_1e0i(mftgpr, t0, rt); 8329 break; 8330 /* Auxiliary CPU registers */ 8331 case 1: 8332 switch (rt) { 8333 case 0: 8334 gen_helper_1e0i(mftlo, t0, 0); 8335 break; 8336 case 1: 8337 gen_helper_1e0i(mfthi, t0, 0); 8338 break; 8339 case 2: 8340 gen_helper_1e0i(mftacx, t0, 0); 8341 break; 8342 case 4: 8343 gen_helper_1e0i(mftlo, t0, 1); 8344 break; 8345 case 5: 8346 gen_helper_1e0i(mfthi, t0, 1); 8347 break; 8348 case 6: 8349 gen_helper_1e0i(mftacx, t0, 1); 8350 break; 8351 case 8: 8352 gen_helper_1e0i(mftlo, t0, 2); 8353 break; 8354 case 9: 8355 gen_helper_1e0i(mfthi, t0, 2); 8356 break; 8357 case 10: 8358 gen_helper_1e0i(mftacx, t0, 2); 8359 break; 8360 case 12: 8361 gen_helper_1e0i(mftlo, t0, 3); 8362 break; 8363 case 13: 8364 gen_helper_1e0i(mfthi, t0, 3); 8365 break; 8366 case 14: 8367 gen_helper_1e0i(mftacx, t0, 3); 8368 break; 8369 case 16: 8370 gen_helper_mftdsp(t0, tcg_env); 8371 break; 8372 default: 8373 goto die; 8374 } 8375 break; 8376 /* Floating point (COP1). */ 8377 case 2: 8378 /* XXX: For now we support only a single FPU context. */ 8379 if (h == 0) { 8380 TCGv_i32 fp0 = tcg_temp_new_i32(); 8381 8382 gen_load_fpr32(ctx, fp0, rt); 8383 tcg_gen_ext_i32_tl(t0, fp0); 8384 } else { 8385 TCGv_i32 fp0 = tcg_temp_new_i32(); 8386 8387 gen_load_fpr32h(ctx, fp0, rt); 8388 tcg_gen_ext_i32_tl(t0, fp0); 8389 } 8390 break; 8391 case 3: 8392 /* XXX: For now we support only a single FPU context. */ 8393 gen_helper_1e0i(cfc1, t0, rt); 8394 break; 8395 /* COP2: Not implemented. */ 8396 case 4: 8397 case 5: 8398 /* fall through */ 8399 default: 8400 goto die; 8401 } 8402 } 8403 trace_mips_translate_tr("mftr", rt, u, sel, h); 8404 gen_store_gpr(t0, rd); 8405 return; 8406 8407 die: 8408 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8409 gen_reserved_instruction(ctx); 8410 } 8411 8412 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8413 int u, int sel, int h) 8414 { 8415 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8416 TCGv t0 = tcg_temp_new(); 8417 8418 gen_load_gpr(t0, rt); 8419 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8420 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8421 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8422 /* NOP */ 8423 ; 8424 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8425 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8426 /* NOP */ 8427 ; 8428 } else if (u == 0) { 8429 switch (rd) { 8430 case 1: 8431 switch (sel) { 8432 case 1: 8433 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8434 break; 8435 case 2: 8436 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8437 break; 8438 default: 8439 goto die; 8440 break; 8441 } 8442 break; 8443 case 2: 8444 switch (sel) { 8445 case 1: 8446 gen_helper_mttc0_tcstatus(tcg_env, t0); 8447 break; 8448 case 2: 8449 gen_helper_mttc0_tcbind(tcg_env, t0); 8450 break; 8451 case 3: 8452 gen_helper_mttc0_tcrestart(tcg_env, t0); 8453 break; 8454 case 4: 8455 gen_helper_mttc0_tchalt(tcg_env, t0); 8456 break; 8457 case 5: 8458 gen_helper_mttc0_tccontext(tcg_env, t0); 8459 break; 8460 case 6: 8461 gen_helper_mttc0_tcschedule(tcg_env, t0); 8462 break; 8463 case 7: 8464 gen_helper_mttc0_tcschefback(tcg_env, t0); 8465 break; 8466 default: 8467 gen_mtc0(ctx, t0, rd, sel); 8468 break; 8469 } 8470 break; 8471 case 10: 8472 switch (sel) { 8473 case 0: 8474 gen_helper_mttc0_entryhi(tcg_env, t0); 8475 break; 8476 default: 8477 gen_mtc0(ctx, t0, rd, sel); 8478 break; 8479 } 8480 break; 8481 case 12: 8482 switch (sel) { 8483 case 0: 8484 gen_helper_mttc0_status(tcg_env, t0); 8485 break; 8486 default: 8487 gen_mtc0(ctx, t0, rd, sel); 8488 break; 8489 } 8490 break; 8491 case 13: 8492 switch (sel) { 8493 case 0: 8494 gen_helper_mttc0_cause(tcg_env, t0); 8495 break; 8496 default: 8497 goto die; 8498 break; 8499 } 8500 break; 8501 case 15: 8502 switch (sel) { 8503 case 1: 8504 gen_helper_mttc0_ebase(tcg_env, t0); 8505 break; 8506 default: 8507 goto die; 8508 break; 8509 } 8510 break; 8511 case 23: 8512 switch (sel) { 8513 case 0: 8514 gen_helper_mttc0_debug(tcg_env, t0); 8515 break; 8516 default: 8517 gen_mtc0(ctx, t0, rd, sel); 8518 break; 8519 } 8520 break; 8521 default: 8522 gen_mtc0(ctx, t0, rd, sel); 8523 } 8524 } else { 8525 switch (sel) { 8526 /* GPR registers. */ 8527 case 0: 8528 gen_helper_0e1i(mttgpr, t0, rd); 8529 break; 8530 /* Auxiliary CPU registers */ 8531 case 1: 8532 switch (rd) { 8533 case 0: 8534 gen_helper_0e1i(mttlo, t0, 0); 8535 break; 8536 case 1: 8537 gen_helper_0e1i(mtthi, t0, 0); 8538 break; 8539 case 2: 8540 gen_helper_0e1i(mttacx, t0, 0); 8541 break; 8542 case 4: 8543 gen_helper_0e1i(mttlo, t0, 1); 8544 break; 8545 case 5: 8546 gen_helper_0e1i(mtthi, t0, 1); 8547 break; 8548 case 6: 8549 gen_helper_0e1i(mttacx, t0, 1); 8550 break; 8551 case 8: 8552 gen_helper_0e1i(mttlo, t0, 2); 8553 break; 8554 case 9: 8555 gen_helper_0e1i(mtthi, t0, 2); 8556 break; 8557 case 10: 8558 gen_helper_0e1i(mttacx, t0, 2); 8559 break; 8560 case 12: 8561 gen_helper_0e1i(mttlo, t0, 3); 8562 break; 8563 case 13: 8564 gen_helper_0e1i(mtthi, t0, 3); 8565 break; 8566 case 14: 8567 gen_helper_0e1i(mttacx, t0, 3); 8568 break; 8569 case 16: 8570 gen_helper_mttdsp(tcg_env, t0); 8571 break; 8572 default: 8573 goto die; 8574 } 8575 break; 8576 /* Floating point (COP1). */ 8577 case 2: 8578 /* XXX: For now we support only a single FPU context. */ 8579 if (h == 0) { 8580 TCGv_i32 fp0 = tcg_temp_new_i32(); 8581 8582 tcg_gen_trunc_tl_i32(fp0, t0); 8583 gen_store_fpr32(ctx, fp0, rd); 8584 } else { 8585 TCGv_i32 fp0 = tcg_temp_new_i32(); 8586 8587 tcg_gen_trunc_tl_i32(fp0, t0); 8588 gen_store_fpr32h(ctx, fp0, rd); 8589 } 8590 break; 8591 case 3: 8592 /* XXX: For now we support only a single FPU context. */ 8593 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8594 /* Stop translation as we may have changed hflags */ 8595 ctx->base.is_jmp = DISAS_STOP; 8596 break; 8597 /* COP2: Not implemented. */ 8598 case 4: 8599 case 5: 8600 /* fall through */ 8601 default: 8602 goto die; 8603 } 8604 } 8605 trace_mips_translate_tr("mttr", rd, u, sel, h); 8606 return; 8607 8608 die: 8609 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8610 gen_reserved_instruction(ctx); 8611 } 8612 8613 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8614 int rt, int rd) 8615 { 8616 const char *opn = "ldst"; 8617 8618 check_cp0_enabled(ctx); 8619 switch (opc) { 8620 case OPC_MFC0: 8621 if (rt == 0) { 8622 /* Treat as NOP. */ 8623 return; 8624 } 8625 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8626 opn = "mfc0"; 8627 break; 8628 case OPC_MTC0: 8629 { 8630 TCGv t0 = tcg_temp_new(); 8631 8632 gen_load_gpr(t0, rt); 8633 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8634 } 8635 opn = "mtc0"; 8636 break; 8637 #if defined(TARGET_MIPS64) 8638 case OPC_DMFC0: 8639 check_insn(ctx, ISA_MIPS3); 8640 if (rt == 0) { 8641 /* Treat as NOP. */ 8642 return; 8643 } 8644 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8645 opn = "dmfc0"; 8646 break; 8647 case OPC_DMTC0: 8648 check_insn(ctx, ISA_MIPS3); 8649 { 8650 TCGv t0 = tcg_temp_new(); 8651 8652 gen_load_gpr(t0, rt); 8653 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8654 } 8655 opn = "dmtc0"; 8656 break; 8657 #endif 8658 case OPC_MFHC0: 8659 check_mvh(ctx); 8660 if (rt == 0) { 8661 /* Treat as NOP. */ 8662 return; 8663 } 8664 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8665 opn = "mfhc0"; 8666 break; 8667 case OPC_MTHC0: 8668 check_mvh(ctx); 8669 { 8670 TCGv t0 = tcg_temp_new(); 8671 gen_load_gpr(t0, rt); 8672 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8673 } 8674 opn = "mthc0"; 8675 break; 8676 case OPC_MFTR: 8677 check_cp0_enabled(ctx); 8678 if (rd == 0) { 8679 /* Treat as NOP. */ 8680 return; 8681 } 8682 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8683 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8684 opn = "mftr"; 8685 break; 8686 case OPC_MTTR: 8687 check_cp0_enabled(ctx); 8688 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8689 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8690 opn = "mttr"; 8691 break; 8692 case OPC_TLBWI: 8693 opn = "tlbwi"; 8694 if (!env->tlb->helper_tlbwi) { 8695 goto die; 8696 } 8697 gen_helper_tlbwi(tcg_env); 8698 break; 8699 case OPC_TLBINV: 8700 opn = "tlbinv"; 8701 if (ctx->ie >= 2) { 8702 if (!env->tlb->helper_tlbinv) { 8703 goto die; 8704 } 8705 gen_helper_tlbinv(tcg_env); 8706 } /* treat as nop if TLBINV not supported */ 8707 break; 8708 case OPC_TLBINVF: 8709 opn = "tlbinvf"; 8710 if (ctx->ie >= 2) { 8711 if (!env->tlb->helper_tlbinvf) { 8712 goto die; 8713 } 8714 gen_helper_tlbinvf(tcg_env); 8715 } /* treat as nop if TLBINV not supported */ 8716 break; 8717 case OPC_TLBWR: 8718 opn = "tlbwr"; 8719 if (!env->tlb->helper_tlbwr) { 8720 goto die; 8721 } 8722 gen_helper_tlbwr(tcg_env); 8723 break; 8724 case OPC_TLBP: 8725 opn = "tlbp"; 8726 if (!env->tlb->helper_tlbp) { 8727 goto die; 8728 } 8729 gen_helper_tlbp(tcg_env); 8730 break; 8731 case OPC_TLBR: 8732 opn = "tlbr"; 8733 if (!env->tlb->helper_tlbr) { 8734 goto die; 8735 } 8736 gen_helper_tlbr(tcg_env); 8737 break; 8738 case OPC_ERET: /* OPC_ERETNC */ 8739 if ((ctx->insn_flags & ISA_MIPS_R6) && 8740 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8741 goto die; 8742 } else { 8743 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8744 if (ctx->opcode & (1 << bit_shift)) { 8745 /* OPC_ERETNC */ 8746 opn = "eretnc"; 8747 check_insn(ctx, ISA_MIPS_R5); 8748 gen_helper_eretnc(tcg_env); 8749 } else { 8750 /* OPC_ERET */ 8751 opn = "eret"; 8752 check_insn(ctx, ISA_MIPS2); 8753 gen_helper_eret(tcg_env); 8754 } 8755 ctx->base.is_jmp = DISAS_EXIT; 8756 } 8757 break; 8758 case OPC_DERET: 8759 opn = "deret"; 8760 check_insn(ctx, ISA_MIPS_R1); 8761 if ((ctx->insn_flags & ISA_MIPS_R6) && 8762 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8763 goto die; 8764 } 8765 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8766 MIPS_INVAL(opn); 8767 gen_reserved_instruction(ctx); 8768 } else { 8769 gen_helper_deret(tcg_env); 8770 ctx->base.is_jmp = DISAS_EXIT; 8771 } 8772 break; 8773 case OPC_WAIT: 8774 opn = "wait"; 8775 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8776 if ((ctx->insn_flags & ISA_MIPS_R6) && 8777 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8778 goto die; 8779 } 8780 /* If we get an exception, we want to restart at next instruction */ 8781 ctx->base.pc_next += 4; 8782 save_cpu_state(ctx, 1); 8783 ctx->base.pc_next -= 4; 8784 gen_helper_wait(tcg_env); 8785 ctx->base.is_jmp = DISAS_NORETURN; 8786 break; 8787 default: 8788 die: 8789 MIPS_INVAL(opn); 8790 gen_reserved_instruction(ctx); 8791 return; 8792 } 8793 (void)opn; /* avoid a compiler warning */ 8794 } 8795 #endif /* !CONFIG_USER_ONLY */ 8796 8797 /* CP1 Branches (before delay slot) */ 8798 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8799 int32_t cc, int32_t offset) 8800 { 8801 target_ulong btarget; 8802 TCGv_i32 t0 = tcg_temp_new_i32(); 8803 8804 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8805 gen_reserved_instruction(ctx); 8806 return; 8807 } 8808 8809 if (cc != 0) { 8810 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8811 } 8812 8813 btarget = ctx->base.pc_next + 4 + offset; 8814 8815 switch (op) { 8816 case OPC_BC1F: 8817 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8818 tcg_gen_not_i32(t0, t0); 8819 tcg_gen_andi_i32(t0, t0, 1); 8820 tcg_gen_extu_i32_tl(bcond, t0); 8821 goto not_likely; 8822 case OPC_BC1FL: 8823 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8824 tcg_gen_not_i32(t0, t0); 8825 tcg_gen_andi_i32(t0, t0, 1); 8826 tcg_gen_extu_i32_tl(bcond, t0); 8827 goto likely; 8828 case OPC_BC1T: 8829 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8830 tcg_gen_andi_i32(t0, t0, 1); 8831 tcg_gen_extu_i32_tl(bcond, t0); 8832 goto not_likely; 8833 case OPC_BC1TL: 8834 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8835 tcg_gen_andi_i32(t0, t0, 1); 8836 tcg_gen_extu_i32_tl(bcond, t0); 8837 likely: 8838 ctx->hflags |= MIPS_HFLAG_BL; 8839 break; 8840 case OPC_BC1FANY2: 8841 { 8842 TCGv_i32 t1 = tcg_temp_new_i32(); 8843 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8844 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8845 tcg_gen_nand_i32(t0, t0, t1); 8846 tcg_gen_andi_i32(t0, t0, 1); 8847 tcg_gen_extu_i32_tl(bcond, t0); 8848 } 8849 goto not_likely; 8850 case OPC_BC1TANY2: 8851 { 8852 TCGv_i32 t1 = tcg_temp_new_i32(); 8853 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8854 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8855 tcg_gen_or_i32(t0, t0, t1); 8856 tcg_gen_andi_i32(t0, t0, 1); 8857 tcg_gen_extu_i32_tl(bcond, t0); 8858 } 8859 goto not_likely; 8860 case OPC_BC1FANY4: 8861 { 8862 TCGv_i32 t1 = tcg_temp_new_i32(); 8863 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8864 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8865 tcg_gen_and_i32(t0, t0, t1); 8866 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8867 tcg_gen_and_i32(t0, t0, t1); 8868 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8869 tcg_gen_nand_i32(t0, t0, t1); 8870 tcg_gen_andi_i32(t0, t0, 1); 8871 tcg_gen_extu_i32_tl(bcond, t0); 8872 } 8873 goto not_likely; 8874 case OPC_BC1TANY4: 8875 { 8876 TCGv_i32 t1 = tcg_temp_new_i32(); 8877 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8878 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8879 tcg_gen_or_i32(t0, t0, t1); 8880 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8881 tcg_gen_or_i32(t0, t0, t1); 8882 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8883 tcg_gen_or_i32(t0, t0, t1); 8884 tcg_gen_andi_i32(t0, t0, 1); 8885 tcg_gen_extu_i32_tl(bcond, t0); 8886 } 8887 not_likely: 8888 ctx->hflags |= MIPS_HFLAG_BC; 8889 break; 8890 default: 8891 MIPS_INVAL("cp1 cond branch"); 8892 gen_reserved_instruction(ctx); 8893 return; 8894 } 8895 ctx->btarget = btarget; 8896 ctx->hflags |= MIPS_HFLAG_BDS32; 8897 } 8898 8899 /* R6 CP1 Branches */ 8900 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8901 int32_t ft, int32_t offset, 8902 int delayslot_size) 8903 { 8904 target_ulong btarget; 8905 TCGv_i64 t0 = tcg_temp_new_i64(); 8906 8907 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8908 #ifdef MIPS_DEBUG_DISAS 8909 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8910 VADDR_PRIx "\n", ctx->base.pc_next); 8911 #endif 8912 gen_reserved_instruction(ctx); 8913 return; 8914 } 8915 8916 gen_load_fpr64(ctx, t0, ft); 8917 tcg_gen_andi_i64(t0, t0, 1); 8918 8919 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8920 8921 switch (op) { 8922 case OPC_BC1EQZ: 8923 tcg_gen_xori_i64(t0, t0, 1); 8924 ctx->hflags |= MIPS_HFLAG_BC; 8925 break; 8926 case OPC_BC1NEZ: 8927 /* t0 already set */ 8928 ctx->hflags |= MIPS_HFLAG_BC; 8929 break; 8930 default: 8931 MIPS_INVAL("cp1 cond branch"); 8932 gen_reserved_instruction(ctx); 8933 return; 8934 } 8935 8936 tcg_gen_trunc_i64_tl(bcond, t0); 8937 8938 ctx->btarget = btarget; 8939 8940 switch (delayslot_size) { 8941 case 2: 8942 ctx->hflags |= MIPS_HFLAG_BDS16; 8943 break; 8944 case 4: 8945 ctx->hflags |= MIPS_HFLAG_BDS32; 8946 break; 8947 } 8948 } 8949 8950 /* Coprocessor 1 (FPU) */ 8951 8952 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8953 8954 enum fopcode { 8955 OPC_ADD_S = FOP(0, FMT_S), 8956 OPC_SUB_S = FOP(1, FMT_S), 8957 OPC_MUL_S = FOP(2, FMT_S), 8958 OPC_DIV_S = FOP(3, FMT_S), 8959 OPC_SQRT_S = FOP(4, FMT_S), 8960 OPC_ABS_S = FOP(5, FMT_S), 8961 OPC_MOV_S = FOP(6, FMT_S), 8962 OPC_NEG_S = FOP(7, FMT_S), 8963 OPC_ROUND_L_S = FOP(8, FMT_S), 8964 OPC_TRUNC_L_S = FOP(9, FMT_S), 8965 OPC_CEIL_L_S = FOP(10, FMT_S), 8966 OPC_FLOOR_L_S = FOP(11, FMT_S), 8967 OPC_ROUND_W_S = FOP(12, FMT_S), 8968 OPC_TRUNC_W_S = FOP(13, FMT_S), 8969 OPC_CEIL_W_S = FOP(14, FMT_S), 8970 OPC_FLOOR_W_S = FOP(15, FMT_S), 8971 OPC_SEL_S = FOP(16, FMT_S), 8972 OPC_MOVCF_S = FOP(17, FMT_S), 8973 OPC_MOVZ_S = FOP(18, FMT_S), 8974 OPC_MOVN_S = FOP(19, FMT_S), 8975 OPC_SELEQZ_S = FOP(20, FMT_S), 8976 OPC_RECIP_S = FOP(21, FMT_S), 8977 OPC_RSQRT_S = FOP(22, FMT_S), 8978 OPC_SELNEZ_S = FOP(23, FMT_S), 8979 OPC_MADDF_S = FOP(24, FMT_S), 8980 OPC_MSUBF_S = FOP(25, FMT_S), 8981 OPC_RINT_S = FOP(26, FMT_S), 8982 OPC_CLASS_S = FOP(27, FMT_S), 8983 OPC_MIN_S = FOP(28, FMT_S), 8984 OPC_RECIP2_S = FOP(28, FMT_S), 8985 OPC_MINA_S = FOP(29, FMT_S), 8986 OPC_RECIP1_S = FOP(29, FMT_S), 8987 OPC_MAX_S = FOP(30, FMT_S), 8988 OPC_RSQRT1_S = FOP(30, FMT_S), 8989 OPC_MAXA_S = FOP(31, FMT_S), 8990 OPC_RSQRT2_S = FOP(31, FMT_S), 8991 OPC_CVT_D_S = FOP(33, FMT_S), 8992 OPC_CVT_W_S = FOP(36, FMT_S), 8993 OPC_CVT_L_S = FOP(37, FMT_S), 8994 OPC_CVT_PS_S = FOP(38, FMT_S), 8995 OPC_CMP_F_S = FOP(48, FMT_S), 8996 OPC_CMP_UN_S = FOP(49, FMT_S), 8997 OPC_CMP_EQ_S = FOP(50, FMT_S), 8998 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8999 OPC_CMP_OLT_S = FOP(52, FMT_S), 9000 OPC_CMP_ULT_S = FOP(53, FMT_S), 9001 OPC_CMP_OLE_S = FOP(54, FMT_S), 9002 OPC_CMP_ULE_S = FOP(55, FMT_S), 9003 OPC_CMP_SF_S = FOP(56, FMT_S), 9004 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9005 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9006 OPC_CMP_NGL_S = FOP(59, FMT_S), 9007 OPC_CMP_LT_S = FOP(60, FMT_S), 9008 OPC_CMP_NGE_S = FOP(61, FMT_S), 9009 OPC_CMP_LE_S = FOP(62, FMT_S), 9010 OPC_CMP_NGT_S = FOP(63, FMT_S), 9011 9012 OPC_ADD_D = FOP(0, FMT_D), 9013 OPC_SUB_D = FOP(1, FMT_D), 9014 OPC_MUL_D = FOP(2, FMT_D), 9015 OPC_DIV_D = FOP(3, FMT_D), 9016 OPC_SQRT_D = FOP(4, FMT_D), 9017 OPC_ABS_D = FOP(5, FMT_D), 9018 OPC_MOV_D = FOP(6, FMT_D), 9019 OPC_NEG_D = FOP(7, FMT_D), 9020 OPC_ROUND_L_D = FOP(8, FMT_D), 9021 OPC_TRUNC_L_D = FOP(9, FMT_D), 9022 OPC_CEIL_L_D = FOP(10, FMT_D), 9023 OPC_FLOOR_L_D = FOP(11, FMT_D), 9024 OPC_ROUND_W_D = FOP(12, FMT_D), 9025 OPC_TRUNC_W_D = FOP(13, FMT_D), 9026 OPC_CEIL_W_D = FOP(14, FMT_D), 9027 OPC_FLOOR_W_D = FOP(15, FMT_D), 9028 OPC_SEL_D = FOP(16, FMT_D), 9029 OPC_MOVCF_D = FOP(17, FMT_D), 9030 OPC_MOVZ_D = FOP(18, FMT_D), 9031 OPC_MOVN_D = FOP(19, FMT_D), 9032 OPC_SELEQZ_D = FOP(20, FMT_D), 9033 OPC_RECIP_D = FOP(21, FMT_D), 9034 OPC_RSQRT_D = FOP(22, FMT_D), 9035 OPC_SELNEZ_D = FOP(23, FMT_D), 9036 OPC_MADDF_D = FOP(24, FMT_D), 9037 OPC_MSUBF_D = FOP(25, FMT_D), 9038 OPC_RINT_D = FOP(26, FMT_D), 9039 OPC_CLASS_D = FOP(27, FMT_D), 9040 OPC_MIN_D = FOP(28, FMT_D), 9041 OPC_RECIP2_D = FOP(28, FMT_D), 9042 OPC_MINA_D = FOP(29, FMT_D), 9043 OPC_RECIP1_D = FOP(29, FMT_D), 9044 OPC_MAX_D = FOP(30, FMT_D), 9045 OPC_RSQRT1_D = FOP(30, FMT_D), 9046 OPC_MAXA_D = FOP(31, FMT_D), 9047 OPC_RSQRT2_D = FOP(31, FMT_D), 9048 OPC_CVT_S_D = FOP(32, FMT_D), 9049 OPC_CVT_W_D = FOP(36, FMT_D), 9050 OPC_CVT_L_D = FOP(37, FMT_D), 9051 OPC_CMP_F_D = FOP(48, FMT_D), 9052 OPC_CMP_UN_D = FOP(49, FMT_D), 9053 OPC_CMP_EQ_D = FOP(50, FMT_D), 9054 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9055 OPC_CMP_OLT_D = FOP(52, FMT_D), 9056 OPC_CMP_ULT_D = FOP(53, FMT_D), 9057 OPC_CMP_OLE_D = FOP(54, FMT_D), 9058 OPC_CMP_ULE_D = FOP(55, FMT_D), 9059 OPC_CMP_SF_D = FOP(56, FMT_D), 9060 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9061 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9062 OPC_CMP_NGL_D = FOP(59, FMT_D), 9063 OPC_CMP_LT_D = FOP(60, FMT_D), 9064 OPC_CMP_NGE_D = FOP(61, FMT_D), 9065 OPC_CMP_LE_D = FOP(62, FMT_D), 9066 OPC_CMP_NGT_D = FOP(63, FMT_D), 9067 9068 OPC_CVT_S_W = FOP(32, FMT_W), 9069 OPC_CVT_D_W = FOP(33, FMT_W), 9070 OPC_CVT_S_L = FOP(32, FMT_L), 9071 OPC_CVT_D_L = FOP(33, FMT_L), 9072 OPC_CVT_PS_PW = FOP(38, FMT_W), 9073 9074 OPC_ADD_PS = FOP(0, FMT_PS), 9075 OPC_SUB_PS = FOP(1, FMT_PS), 9076 OPC_MUL_PS = FOP(2, FMT_PS), 9077 OPC_DIV_PS = FOP(3, FMT_PS), 9078 OPC_ABS_PS = FOP(5, FMT_PS), 9079 OPC_MOV_PS = FOP(6, FMT_PS), 9080 OPC_NEG_PS = FOP(7, FMT_PS), 9081 OPC_MOVCF_PS = FOP(17, FMT_PS), 9082 OPC_MOVZ_PS = FOP(18, FMT_PS), 9083 OPC_MOVN_PS = FOP(19, FMT_PS), 9084 OPC_ADDR_PS = FOP(24, FMT_PS), 9085 OPC_MULR_PS = FOP(26, FMT_PS), 9086 OPC_RECIP2_PS = FOP(28, FMT_PS), 9087 OPC_RECIP1_PS = FOP(29, FMT_PS), 9088 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9089 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9090 9091 OPC_CVT_S_PU = FOP(32, FMT_PS), 9092 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9093 OPC_CVT_S_PL = FOP(40, FMT_PS), 9094 OPC_PLL_PS = FOP(44, FMT_PS), 9095 OPC_PLU_PS = FOP(45, FMT_PS), 9096 OPC_PUL_PS = FOP(46, FMT_PS), 9097 OPC_PUU_PS = FOP(47, FMT_PS), 9098 OPC_CMP_F_PS = FOP(48, FMT_PS), 9099 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9100 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9101 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9102 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9103 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9104 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9105 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9106 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9107 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9108 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9109 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9110 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9111 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9112 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9113 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9114 }; 9115 9116 enum r6_f_cmp_op { 9117 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9118 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9119 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9120 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9121 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9122 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9123 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9124 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9125 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9126 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9127 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9128 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9129 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9130 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9131 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9132 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9133 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9134 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9135 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9136 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9137 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9138 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9139 9140 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9141 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9142 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9143 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9144 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9145 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9146 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9147 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9148 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9149 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9150 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9151 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9152 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9153 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9154 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9155 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9156 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9157 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9158 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9159 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9160 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9161 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9162 }; 9163 9164 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9165 { 9166 TCGv t0 = tcg_temp_new(); 9167 9168 switch (opc) { 9169 case OPC_MFC1: 9170 { 9171 TCGv_i32 fp0 = tcg_temp_new_i32(); 9172 9173 gen_load_fpr32(ctx, fp0, fs); 9174 tcg_gen_ext_i32_tl(t0, fp0); 9175 } 9176 gen_store_gpr(t0, rt); 9177 break; 9178 case OPC_MTC1: 9179 gen_load_gpr(t0, rt); 9180 { 9181 TCGv_i32 fp0 = tcg_temp_new_i32(); 9182 9183 tcg_gen_trunc_tl_i32(fp0, t0); 9184 gen_store_fpr32(ctx, fp0, fs); 9185 } 9186 break; 9187 case OPC_CFC1: 9188 gen_helper_1e0i(cfc1, t0, fs); 9189 gen_store_gpr(t0, rt); 9190 break; 9191 case OPC_CTC1: 9192 gen_load_gpr(t0, rt); 9193 save_cpu_state(ctx, 0); 9194 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9195 /* Stop translation as we may have changed hflags */ 9196 ctx->base.is_jmp = DISAS_STOP; 9197 break; 9198 #if defined(TARGET_MIPS64) 9199 case OPC_DMFC1: 9200 gen_load_fpr64(ctx, t0, fs); 9201 gen_store_gpr(t0, rt); 9202 break; 9203 case OPC_DMTC1: 9204 gen_load_gpr(t0, rt); 9205 gen_store_fpr64(ctx, t0, fs); 9206 break; 9207 #endif 9208 case OPC_MFHC1: 9209 { 9210 TCGv_i32 fp0 = tcg_temp_new_i32(); 9211 9212 gen_load_fpr32h(ctx, fp0, fs); 9213 tcg_gen_ext_i32_tl(t0, fp0); 9214 } 9215 gen_store_gpr(t0, rt); 9216 break; 9217 case OPC_MTHC1: 9218 gen_load_gpr(t0, rt); 9219 { 9220 TCGv_i32 fp0 = tcg_temp_new_i32(); 9221 9222 tcg_gen_trunc_tl_i32(fp0, t0); 9223 gen_store_fpr32h(ctx, fp0, fs); 9224 } 9225 break; 9226 default: 9227 MIPS_INVAL("cp1 move"); 9228 gen_reserved_instruction(ctx); 9229 return; 9230 } 9231 } 9232 9233 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9234 { 9235 TCGLabel *l1; 9236 TCGCond cond; 9237 TCGv_i32 t0; 9238 9239 if (rd == 0) { 9240 /* Treat as NOP. */ 9241 return; 9242 } 9243 9244 if (tf) { 9245 cond = TCG_COND_EQ; 9246 } else { 9247 cond = TCG_COND_NE; 9248 } 9249 9250 l1 = gen_new_label(); 9251 t0 = tcg_temp_new_i32(); 9252 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9253 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9254 gen_load_gpr(cpu_gpr[rd], rs); 9255 gen_set_label(l1); 9256 } 9257 9258 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9259 int tf) 9260 { 9261 int cond; 9262 TCGv_i32 t0 = tcg_temp_new_i32(); 9263 TCGLabel *l1 = gen_new_label(); 9264 9265 if (tf) { 9266 cond = TCG_COND_EQ; 9267 } else { 9268 cond = TCG_COND_NE; 9269 } 9270 9271 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9272 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9273 gen_load_fpr32(ctx, t0, fs); 9274 gen_store_fpr32(ctx, t0, fd); 9275 gen_set_label(l1); 9276 } 9277 9278 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9279 int tf) 9280 { 9281 int cond; 9282 TCGv_i32 t0 = tcg_temp_new_i32(); 9283 TCGv_i64 fp0; 9284 TCGLabel *l1 = gen_new_label(); 9285 9286 if (tf) { 9287 cond = TCG_COND_EQ; 9288 } else { 9289 cond = TCG_COND_NE; 9290 } 9291 9292 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9293 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9294 fp0 = tcg_temp_new_i64(); 9295 gen_load_fpr64(ctx, fp0, fs); 9296 gen_store_fpr64(ctx, fp0, fd); 9297 gen_set_label(l1); 9298 } 9299 9300 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9301 int cc, int tf) 9302 { 9303 int cond; 9304 TCGv_i32 t0 = tcg_temp_new_i32(); 9305 TCGLabel *l1 = gen_new_label(); 9306 TCGLabel *l2 = gen_new_label(); 9307 9308 if (tf) { 9309 cond = TCG_COND_EQ; 9310 } else { 9311 cond = TCG_COND_NE; 9312 } 9313 9314 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9315 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9316 gen_load_fpr32(ctx, t0, fs); 9317 gen_store_fpr32(ctx, t0, fd); 9318 gen_set_label(l1); 9319 9320 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9321 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9322 gen_load_fpr32h(ctx, t0, fs); 9323 gen_store_fpr32h(ctx, t0, fd); 9324 gen_set_label(l2); 9325 } 9326 9327 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9328 int fs) 9329 { 9330 TCGv_i32 t1 = tcg_constant_i32(0); 9331 TCGv_i32 fp0 = tcg_temp_new_i32(); 9332 TCGv_i32 fp1 = tcg_temp_new_i32(); 9333 TCGv_i32 fp2 = tcg_temp_new_i32(); 9334 gen_load_fpr32(ctx, fp0, fd); 9335 gen_load_fpr32(ctx, fp1, ft); 9336 gen_load_fpr32(ctx, fp2, fs); 9337 9338 switch (op1) { 9339 case OPC_SEL_S: 9340 tcg_gen_andi_i32(fp0, fp0, 1); 9341 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9342 break; 9343 case OPC_SELEQZ_S: 9344 tcg_gen_andi_i32(fp1, fp1, 1); 9345 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9346 break; 9347 case OPC_SELNEZ_S: 9348 tcg_gen_andi_i32(fp1, fp1, 1); 9349 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9350 break; 9351 default: 9352 MIPS_INVAL("gen_sel_s"); 9353 gen_reserved_instruction(ctx); 9354 break; 9355 } 9356 9357 gen_store_fpr32(ctx, fp0, fd); 9358 } 9359 9360 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9361 int fs) 9362 { 9363 TCGv_i64 t1 = tcg_constant_i64(0); 9364 TCGv_i64 fp0 = tcg_temp_new_i64(); 9365 TCGv_i64 fp1 = tcg_temp_new_i64(); 9366 TCGv_i64 fp2 = tcg_temp_new_i64(); 9367 gen_load_fpr64(ctx, fp0, fd); 9368 gen_load_fpr64(ctx, fp1, ft); 9369 gen_load_fpr64(ctx, fp2, fs); 9370 9371 switch (op1) { 9372 case OPC_SEL_D: 9373 tcg_gen_andi_i64(fp0, fp0, 1); 9374 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9375 break; 9376 case OPC_SELEQZ_D: 9377 tcg_gen_andi_i64(fp1, fp1, 1); 9378 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9379 break; 9380 case OPC_SELNEZ_D: 9381 tcg_gen_andi_i64(fp1, fp1, 1); 9382 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9383 break; 9384 default: 9385 MIPS_INVAL("gen_sel_d"); 9386 gen_reserved_instruction(ctx); 9387 break; 9388 } 9389 9390 gen_store_fpr64(ctx, fp0, fd); 9391 } 9392 9393 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9394 int ft, int fs, int fd, int cc) 9395 { 9396 uint32_t func = ctx->opcode & 0x3f; 9397 switch (op1) { 9398 case OPC_ADD_S: 9399 { 9400 TCGv_i32 fp0 = tcg_temp_new_i32(); 9401 TCGv_i32 fp1 = tcg_temp_new_i32(); 9402 9403 gen_load_fpr32(ctx, fp0, fs); 9404 gen_load_fpr32(ctx, fp1, ft); 9405 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9406 gen_store_fpr32(ctx, fp0, fd); 9407 } 9408 break; 9409 case OPC_SUB_S: 9410 { 9411 TCGv_i32 fp0 = tcg_temp_new_i32(); 9412 TCGv_i32 fp1 = tcg_temp_new_i32(); 9413 9414 gen_load_fpr32(ctx, fp0, fs); 9415 gen_load_fpr32(ctx, fp1, ft); 9416 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9417 gen_store_fpr32(ctx, fp0, fd); 9418 } 9419 break; 9420 case OPC_MUL_S: 9421 { 9422 TCGv_i32 fp0 = tcg_temp_new_i32(); 9423 TCGv_i32 fp1 = tcg_temp_new_i32(); 9424 9425 gen_load_fpr32(ctx, fp0, fs); 9426 gen_load_fpr32(ctx, fp1, ft); 9427 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9428 gen_store_fpr32(ctx, fp0, fd); 9429 } 9430 break; 9431 case OPC_DIV_S: 9432 { 9433 TCGv_i32 fp0 = tcg_temp_new_i32(); 9434 TCGv_i32 fp1 = tcg_temp_new_i32(); 9435 9436 gen_load_fpr32(ctx, fp0, fs); 9437 gen_load_fpr32(ctx, fp1, ft); 9438 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9439 gen_store_fpr32(ctx, fp0, fd); 9440 } 9441 break; 9442 case OPC_SQRT_S: 9443 { 9444 TCGv_i32 fp0 = tcg_temp_new_i32(); 9445 9446 gen_load_fpr32(ctx, fp0, fs); 9447 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9448 gen_store_fpr32(ctx, fp0, fd); 9449 } 9450 break; 9451 case OPC_ABS_S: 9452 { 9453 TCGv_i32 fp0 = tcg_temp_new_i32(); 9454 9455 gen_load_fpr32(ctx, fp0, fs); 9456 if (ctx->abs2008) { 9457 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9458 } else { 9459 gen_helper_float_abs_s(fp0, fp0); 9460 } 9461 gen_store_fpr32(ctx, fp0, fd); 9462 } 9463 break; 9464 case OPC_MOV_S: 9465 { 9466 TCGv_i32 fp0 = tcg_temp_new_i32(); 9467 9468 gen_load_fpr32(ctx, fp0, fs); 9469 gen_store_fpr32(ctx, fp0, fd); 9470 } 9471 break; 9472 case OPC_NEG_S: 9473 { 9474 TCGv_i32 fp0 = tcg_temp_new_i32(); 9475 9476 gen_load_fpr32(ctx, fp0, fs); 9477 if (ctx->abs2008) { 9478 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9479 } else { 9480 gen_helper_float_chs_s(fp0, fp0); 9481 } 9482 gen_store_fpr32(ctx, fp0, fd); 9483 } 9484 break; 9485 case OPC_ROUND_L_S: 9486 check_cp1_64bitmode(ctx); 9487 { 9488 TCGv_i32 fp32 = tcg_temp_new_i32(); 9489 TCGv_i64 fp64 = tcg_temp_new_i64(); 9490 9491 gen_load_fpr32(ctx, fp32, fs); 9492 if (ctx->nan2008) { 9493 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9494 } else { 9495 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9496 } 9497 gen_store_fpr64(ctx, fp64, fd); 9498 } 9499 break; 9500 case OPC_TRUNC_L_S: 9501 check_cp1_64bitmode(ctx); 9502 { 9503 TCGv_i32 fp32 = tcg_temp_new_i32(); 9504 TCGv_i64 fp64 = tcg_temp_new_i64(); 9505 9506 gen_load_fpr32(ctx, fp32, fs); 9507 if (ctx->nan2008) { 9508 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9509 } else { 9510 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9511 } 9512 gen_store_fpr64(ctx, fp64, fd); 9513 } 9514 break; 9515 case OPC_CEIL_L_S: 9516 check_cp1_64bitmode(ctx); 9517 { 9518 TCGv_i32 fp32 = tcg_temp_new_i32(); 9519 TCGv_i64 fp64 = tcg_temp_new_i64(); 9520 9521 gen_load_fpr32(ctx, fp32, fs); 9522 if (ctx->nan2008) { 9523 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9524 } else { 9525 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9526 } 9527 gen_store_fpr64(ctx, fp64, fd); 9528 } 9529 break; 9530 case OPC_FLOOR_L_S: 9531 check_cp1_64bitmode(ctx); 9532 { 9533 TCGv_i32 fp32 = tcg_temp_new_i32(); 9534 TCGv_i64 fp64 = tcg_temp_new_i64(); 9535 9536 gen_load_fpr32(ctx, fp32, fs); 9537 if (ctx->nan2008) { 9538 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9539 } else { 9540 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9541 } 9542 gen_store_fpr64(ctx, fp64, fd); 9543 } 9544 break; 9545 case OPC_ROUND_W_S: 9546 { 9547 TCGv_i32 fp0 = tcg_temp_new_i32(); 9548 9549 gen_load_fpr32(ctx, fp0, fs); 9550 if (ctx->nan2008) { 9551 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9552 } else { 9553 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9554 } 9555 gen_store_fpr32(ctx, fp0, fd); 9556 } 9557 break; 9558 case OPC_TRUNC_W_S: 9559 { 9560 TCGv_i32 fp0 = tcg_temp_new_i32(); 9561 9562 gen_load_fpr32(ctx, fp0, fs); 9563 if (ctx->nan2008) { 9564 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9565 } else { 9566 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9567 } 9568 gen_store_fpr32(ctx, fp0, fd); 9569 } 9570 break; 9571 case OPC_CEIL_W_S: 9572 { 9573 TCGv_i32 fp0 = tcg_temp_new_i32(); 9574 9575 gen_load_fpr32(ctx, fp0, fs); 9576 if (ctx->nan2008) { 9577 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9578 } else { 9579 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9580 } 9581 gen_store_fpr32(ctx, fp0, fd); 9582 } 9583 break; 9584 case OPC_FLOOR_W_S: 9585 { 9586 TCGv_i32 fp0 = tcg_temp_new_i32(); 9587 9588 gen_load_fpr32(ctx, fp0, fs); 9589 if (ctx->nan2008) { 9590 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9591 } else { 9592 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9593 } 9594 gen_store_fpr32(ctx, fp0, fd); 9595 } 9596 break; 9597 case OPC_SEL_S: 9598 check_insn(ctx, ISA_MIPS_R6); 9599 gen_sel_s(ctx, op1, fd, ft, fs); 9600 break; 9601 case OPC_SELEQZ_S: 9602 check_insn(ctx, ISA_MIPS_R6); 9603 gen_sel_s(ctx, op1, fd, ft, fs); 9604 break; 9605 case OPC_SELNEZ_S: 9606 check_insn(ctx, ISA_MIPS_R6); 9607 gen_sel_s(ctx, op1, fd, ft, fs); 9608 break; 9609 case OPC_MOVCF_S: 9610 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9611 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9612 break; 9613 case OPC_MOVZ_S: 9614 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9615 { 9616 TCGLabel *l1 = gen_new_label(); 9617 TCGv_i32 fp0; 9618 9619 if (ft != 0) { 9620 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9621 } 9622 fp0 = tcg_temp_new_i32(); 9623 gen_load_fpr32(ctx, fp0, fs); 9624 gen_store_fpr32(ctx, fp0, fd); 9625 gen_set_label(l1); 9626 } 9627 break; 9628 case OPC_MOVN_S: 9629 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9630 { 9631 TCGLabel *l1 = gen_new_label(); 9632 TCGv_i32 fp0; 9633 9634 if (ft != 0) { 9635 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9636 fp0 = tcg_temp_new_i32(); 9637 gen_load_fpr32(ctx, fp0, fs); 9638 gen_store_fpr32(ctx, fp0, fd); 9639 gen_set_label(l1); 9640 } 9641 } 9642 break; 9643 case OPC_RECIP_S: 9644 { 9645 TCGv_i32 fp0 = tcg_temp_new_i32(); 9646 9647 gen_load_fpr32(ctx, fp0, fs); 9648 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9649 gen_store_fpr32(ctx, fp0, fd); 9650 } 9651 break; 9652 case OPC_RSQRT_S: 9653 { 9654 TCGv_i32 fp0 = tcg_temp_new_i32(); 9655 9656 gen_load_fpr32(ctx, fp0, fs); 9657 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9658 gen_store_fpr32(ctx, fp0, fd); 9659 } 9660 break; 9661 case OPC_MADDF_S: 9662 check_insn(ctx, ISA_MIPS_R6); 9663 { 9664 TCGv_i32 fp0 = tcg_temp_new_i32(); 9665 TCGv_i32 fp1 = tcg_temp_new_i32(); 9666 TCGv_i32 fp2 = tcg_temp_new_i32(); 9667 gen_load_fpr32(ctx, fp0, fs); 9668 gen_load_fpr32(ctx, fp1, ft); 9669 gen_load_fpr32(ctx, fp2, fd); 9670 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9671 gen_store_fpr32(ctx, fp2, fd); 9672 } 9673 break; 9674 case OPC_MSUBF_S: 9675 check_insn(ctx, ISA_MIPS_R6); 9676 { 9677 TCGv_i32 fp0 = tcg_temp_new_i32(); 9678 TCGv_i32 fp1 = tcg_temp_new_i32(); 9679 TCGv_i32 fp2 = tcg_temp_new_i32(); 9680 gen_load_fpr32(ctx, fp0, fs); 9681 gen_load_fpr32(ctx, fp1, ft); 9682 gen_load_fpr32(ctx, fp2, fd); 9683 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9684 gen_store_fpr32(ctx, fp2, fd); 9685 } 9686 break; 9687 case OPC_RINT_S: 9688 check_insn(ctx, ISA_MIPS_R6); 9689 { 9690 TCGv_i32 fp0 = tcg_temp_new_i32(); 9691 gen_load_fpr32(ctx, fp0, fs); 9692 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9693 gen_store_fpr32(ctx, fp0, fd); 9694 } 9695 break; 9696 case OPC_CLASS_S: 9697 check_insn(ctx, ISA_MIPS_R6); 9698 { 9699 TCGv_i32 fp0 = tcg_temp_new_i32(); 9700 gen_load_fpr32(ctx, fp0, fs); 9701 gen_helper_float_class_s(fp0, tcg_env, fp0); 9702 gen_store_fpr32(ctx, fp0, fd); 9703 } 9704 break; 9705 case OPC_MIN_S: /* OPC_RECIP2_S */ 9706 if (ctx->insn_flags & ISA_MIPS_R6) { 9707 /* OPC_MIN_S */ 9708 TCGv_i32 fp0 = tcg_temp_new_i32(); 9709 TCGv_i32 fp1 = tcg_temp_new_i32(); 9710 TCGv_i32 fp2 = tcg_temp_new_i32(); 9711 gen_load_fpr32(ctx, fp0, fs); 9712 gen_load_fpr32(ctx, fp1, ft); 9713 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9714 gen_store_fpr32(ctx, fp2, fd); 9715 } else { 9716 /* OPC_RECIP2_S */ 9717 check_cp1_64bitmode(ctx); 9718 { 9719 TCGv_i32 fp0 = tcg_temp_new_i32(); 9720 TCGv_i32 fp1 = tcg_temp_new_i32(); 9721 9722 gen_load_fpr32(ctx, fp0, fs); 9723 gen_load_fpr32(ctx, fp1, ft); 9724 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9725 gen_store_fpr32(ctx, fp0, fd); 9726 } 9727 } 9728 break; 9729 case OPC_MINA_S: /* OPC_RECIP1_S */ 9730 if (ctx->insn_flags & ISA_MIPS_R6) { 9731 /* OPC_MINA_S */ 9732 TCGv_i32 fp0 = tcg_temp_new_i32(); 9733 TCGv_i32 fp1 = tcg_temp_new_i32(); 9734 TCGv_i32 fp2 = tcg_temp_new_i32(); 9735 gen_load_fpr32(ctx, fp0, fs); 9736 gen_load_fpr32(ctx, fp1, ft); 9737 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9738 gen_store_fpr32(ctx, fp2, fd); 9739 } else { 9740 /* OPC_RECIP1_S */ 9741 check_cp1_64bitmode(ctx); 9742 { 9743 TCGv_i32 fp0 = tcg_temp_new_i32(); 9744 9745 gen_load_fpr32(ctx, fp0, fs); 9746 gen_helper_float_recip1_s(fp0, tcg_env, fp0); 9747 gen_store_fpr32(ctx, fp0, fd); 9748 } 9749 } 9750 break; 9751 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9752 if (ctx->insn_flags & ISA_MIPS_R6) { 9753 /* OPC_MAX_S */ 9754 TCGv_i32 fp0 = tcg_temp_new_i32(); 9755 TCGv_i32 fp1 = tcg_temp_new_i32(); 9756 gen_load_fpr32(ctx, fp0, fs); 9757 gen_load_fpr32(ctx, fp1, ft); 9758 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1); 9759 gen_store_fpr32(ctx, fp1, fd); 9760 } else { 9761 /* OPC_RSQRT1_S */ 9762 check_cp1_64bitmode(ctx); 9763 { 9764 TCGv_i32 fp0 = tcg_temp_new_i32(); 9765 9766 gen_load_fpr32(ctx, fp0, fs); 9767 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0); 9768 gen_store_fpr32(ctx, fp0, fd); 9769 } 9770 } 9771 break; 9772 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9773 if (ctx->insn_flags & ISA_MIPS_R6) { 9774 /* OPC_MAXA_S */ 9775 TCGv_i32 fp0 = tcg_temp_new_i32(); 9776 TCGv_i32 fp1 = tcg_temp_new_i32(); 9777 gen_load_fpr32(ctx, fp0, fs); 9778 gen_load_fpr32(ctx, fp1, ft); 9779 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1); 9780 gen_store_fpr32(ctx, fp1, fd); 9781 } else { 9782 /* OPC_RSQRT2_S */ 9783 check_cp1_64bitmode(ctx); 9784 { 9785 TCGv_i32 fp0 = tcg_temp_new_i32(); 9786 TCGv_i32 fp1 = tcg_temp_new_i32(); 9787 9788 gen_load_fpr32(ctx, fp0, fs); 9789 gen_load_fpr32(ctx, fp1, ft); 9790 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9791 gen_store_fpr32(ctx, fp0, fd); 9792 } 9793 } 9794 break; 9795 case OPC_CVT_D_S: 9796 check_cp1_registers(ctx, fd); 9797 { 9798 TCGv_i32 fp32 = tcg_temp_new_i32(); 9799 TCGv_i64 fp64 = tcg_temp_new_i64(); 9800 9801 gen_load_fpr32(ctx, fp32, fs); 9802 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9803 gen_store_fpr64(ctx, fp64, fd); 9804 } 9805 break; 9806 case OPC_CVT_W_S: 9807 { 9808 TCGv_i32 fp0 = tcg_temp_new_i32(); 9809 9810 gen_load_fpr32(ctx, fp0, fs); 9811 if (ctx->nan2008) { 9812 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9813 } else { 9814 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9815 } 9816 gen_store_fpr32(ctx, fp0, fd); 9817 } 9818 break; 9819 case OPC_CVT_L_S: 9820 check_cp1_64bitmode(ctx); 9821 { 9822 TCGv_i32 fp32 = tcg_temp_new_i32(); 9823 TCGv_i64 fp64 = tcg_temp_new_i64(); 9824 9825 gen_load_fpr32(ctx, fp32, fs); 9826 if (ctx->nan2008) { 9827 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9828 } else { 9829 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9830 } 9831 gen_store_fpr64(ctx, fp64, fd); 9832 } 9833 break; 9834 case OPC_CVT_PS_S: 9835 check_ps(ctx); 9836 { 9837 TCGv_i64 fp64 = tcg_temp_new_i64(); 9838 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9839 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9840 9841 gen_load_fpr32(ctx, fp32_0, fs); 9842 gen_load_fpr32(ctx, fp32_1, ft); 9843 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9844 gen_store_fpr64(ctx, fp64, fd); 9845 } 9846 break; 9847 case OPC_CMP_F_S: 9848 case OPC_CMP_UN_S: 9849 case OPC_CMP_EQ_S: 9850 case OPC_CMP_UEQ_S: 9851 case OPC_CMP_OLT_S: 9852 case OPC_CMP_ULT_S: 9853 case OPC_CMP_OLE_S: 9854 case OPC_CMP_ULE_S: 9855 case OPC_CMP_SF_S: 9856 case OPC_CMP_NGLE_S: 9857 case OPC_CMP_SEQ_S: 9858 case OPC_CMP_NGL_S: 9859 case OPC_CMP_LT_S: 9860 case OPC_CMP_NGE_S: 9861 case OPC_CMP_LE_S: 9862 case OPC_CMP_NGT_S: 9863 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9864 if (ctx->opcode & (1 << 6)) { 9865 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9866 } else { 9867 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9868 } 9869 break; 9870 case OPC_ADD_D: 9871 check_cp1_registers(ctx, fs | ft | fd); 9872 { 9873 TCGv_i64 fp0 = tcg_temp_new_i64(); 9874 TCGv_i64 fp1 = tcg_temp_new_i64(); 9875 9876 gen_load_fpr64(ctx, fp0, fs); 9877 gen_load_fpr64(ctx, fp1, ft); 9878 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9879 gen_store_fpr64(ctx, fp0, fd); 9880 } 9881 break; 9882 case OPC_SUB_D: 9883 check_cp1_registers(ctx, fs | ft | fd); 9884 { 9885 TCGv_i64 fp0 = tcg_temp_new_i64(); 9886 TCGv_i64 fp1 = tcg_temp_new_i64(); 9887 9888 gen_load_fpr64(ctx, fp0, fs); 9889 gen_load_fpr64(ctx, fp1, ft); 9890 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9891 gen_store_fpr64(ctx, fp0, fd); 9892 } 9893 break; 9894 case OPC_MUL_D: 9895 check_cp1_registers(ctx, fs | ft | fd); 9896 { 9897 TCGv_i64 fp0 = tcg_temp_new_i64(); 9898 TCGv_i64 fp1 = tcg_temp_new_i64(); 9899 9900 gen_load_fpr64(ctx, fp0, fs); 9901 gen_load_fpr64(ctx, fp1, ft); 9902 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9903 gen_store_fpr64(ctx, fp0, fd); 9904 } 9905 break; 9906 case OPC_DIV_D: 9907 check_cp1_registers(ctx, fs | ft | fd); 9908 { 9909 TCGv_i64 fp0 = tcg_temp_new_i64(); 9910 TCGv_i64 fp1 = tcg_temp_new_i64(); 9911 9912 gen_load_fpr64(ctx, fp0, fs); 9913 gen_load_fpr64(ctx, fp1, ft); 9914 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9915 gen_store_fpr64(ctx, fp0, fd); 9916 } 9917 break; 9918 case OPC_SQRT_D: 9919 check_cp1_registers(ctx, fs | fd); 9920 { 9921 TCGv_i64 fp0 = tcg_temp_new_i64(); 9922 9923 gen_load_fpr64(ctx, fp0, fs); 9924 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9925 gen_store_fpr64(ctx, fp0, fd); 9926 } 9927 break; 9928 case OPC_ABS_D: 9929 check_cp1_registers(ctx, fs | fd); 9930 { 9931 TCGv_i64 fp0 = tcg_temp_new_i64(); 9932 9933 gen_load_fpr64(ctx, fp0, fs); 9934 if (ctx->abs2008) { 9935 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9936 } else { 9937 gen_helper_float_abs_d(fp0, fp0); 9938 } 9939 gen_store_fpr64(ctx, fp0, fd); 9940 } 9941 break; 9942 case OPC_MOV_D: 9943 check_cp1_registers(ctx, fs | fd); 9944 { 9945 TCGv_i64 fp0 = tcg_temp_new_i64(); 9946 9947 gen_load_fpr64(ctx, fp0, fs); 9948 gen_store_fpr64(ctx, fp0, fd); 9949 } 9950 break; 9951 case OPC_NEG_D: 9952 check_cp1_registers(ctx, fs | fd); 9953 { 9954 TCGv_i64 fp0 = tcg_temp_new_i64(); 9955 9956 gen_load_fpr64(ctx, fp0, fs); 9957 if (ctx->abs2008) { 9958 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9959 } else { 9960 gen_helper_float_chs_d(fp0, fp0); 9961 } 9962 gen_store_fpr64(ctx, fp0, fd); 9963 } 9964 break; 9965 case OPC_ROUND_L_D: 9966 check_cp1_64bitmode(ctx); 9967 { 9968 TCGv_i64 fp0 = tcg_temp_new_i64(); 9969 9970 gen_load_fpr64(ctx, fp0, fs); 9971 if (ctx->nan2008) { 9972 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9973 } else { 9974 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9975 } 9976 gen_store_fpr64(ctx, fp0, fd); 9977 } 9978 break; 9979 case OPC_TRUNC_L_D: 9980 check_cp1_64bitmode(ctx); 9981 { 9982 TCGv_i64 fp0 = tcg_temp_new_i64(); 9983 9984 gen_load_fpr64(ctx, fp0, fs); 9985 if (ctx->nan2008) { 9986 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9987 } else { 9988 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9989 } 9990 gen_store_fpr64(ctx, fp0, fd); 9991 } 9992 break; 9993 case OPC_CEIL_L_D: 9994 check_cp1_64bitmode(ctx); 9995 { 9996 TCGv_i64 fp0 = tcg_temp_new_i64(); 9997 9998 gen_load_fpr64(ctx, fp0, fs); 9999 if (ctx->nan2008) { 10000 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 10001 } else { 10002 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 10003 } 10004 gen_store_fpr64(ctx, fp0, fd); 10005 } 10006 break; 10007 case OPC_FLOOR_L_D: 10008 check_cp1_64bitmode(ctx); 10009 { 10010 TCGv_i64 fp0 = tcg_temp_new_i64(); 10011 10012 gen_load_fpr64(ctx, fp0, fs); 10013 if (ctx->nan2008) { 10014 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 10015 } else { 10016 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 10017 } 10018 gen_store_fpr64(ctx, fp0, fd); 10019 } 10020 break; 10021 case OPC_ROUND_W_D: 10022 check_cp1_registers(ctx, fs); 10023 { 10024 TCGv_i32 fp32 = tcg_temp_new_i32(); 10025 TCGv_i64 fp64 = tcg_temp_new_i64(); 10026 10027 gen_load_fpr64(ctx, fp64, fs); 10028 if (ctx->nan2008) { 10029 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 10030 } else { 10031 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 10032 } 10033 gen_store_fpr32(ctx, fp32, fd); 10034 } 10035 break; 10036 case OPC_TRUNC_W_D: 10037 check_cp1_registers(ctx, fs); 10038 { 10039 TCGv_i32 fp32 = tcg_temp_new_i32(); 10040 TCGv_i64 fp64 = tcg_temp_new_i64(); 10041 10042 gen_load_fpr64(ctx, fp64, fs); 10043 if (ctx->nan2008) { 10044 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 10045 } else { 10046 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 10047 } 10048 gen_store_fpr32(ctx, fp32, fd); 10049 } 10050 break; 10051 case OPC_CEIL_W_D: 10052 check_cp1_registers(ctx, fs); 10053 { 10054 TCGv_i32 fp32 = tcg_temp_new_i32(); 10055 TCGv_i64 fp64 = tcg_temp_new_i64(); 10056 10057 gen_load_fpr64(ctx, fp64, fs); 10058 if (ctx->nan2008) { 10059 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 10060 } else { 10061 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 10062 } 10063 gen_store_fpr32(ctx, fp32, fd); 10064 } 10065 break; 10066 case OPC_FLOOR_W_D: 10067 check_cp1_registers(ctx, fs); 10068 { 10069 TCGv_i32 fp32 = tcg_temp_new_i32(); 10070 TCGv_i64 fp64 = tcg_temp_new_i64(); 10071 10072 gen_load_fpr64(ctx, fp64, fs); 10073 if (ctx->nan2008) { 10074 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 10075 } else { 10076 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 10077 } 10078 gen_store_fpr32(ctx, fp32, fd); 10079 } 10080 break; 10081 case OPC_SEL_D: 10082 check_insn(ctx, ISA_MIPS_R6); 10083 gen_sel_d(ctx, op1, fd, ft, fs); 10084 break; 10085 case OPC_SELEQZ_D: 10086 check_insn(ctx, ISA_MIPS_R6); 10087 gen_sel_d(ctx, op1, fd, ft, fs); 10088 break; 10089 case OPC_SELNEZ_D: 10090 check_insn(ctx, ISA_MIPS_R6); 10091 gen_sel_d(ctx, op1, fd, ft, fs); 10092 break; 10093 case OPC_MOVCF_D: 10094 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10095 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10096 break; 10097 case OPC_MOVZ_D: 10098 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10099 { 10100 TCGLabel *l1 = gen_new_label(); 10101 TCGv_i64 fp0; 10102 10103 if (ft != 0) { 10104 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10105 } 10106 fp0 = tcg_temp_new_i64(); 10107 gen_load_fpr64(ctx, fp0, fs); 10108 gen_store_fpr64(ctx, fp0, fd); 10109 gen_set_label(l1); 10110 } 10111 break; 10112 case OPC_MOVN_D: 10113 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10114 { 10115 TCGLabel *l1 = gen_new_label(); 10116 TCGv_i64 fp0; 10117 10118 if (ft != 0) { 10119 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10120 fp0 = tcg_temp_new_i64(); 10121 gen_load_fpr64(ctx, fp0, fs); 10122 gen_store_fpr64(ctx, fp0, fd); 10123 gen_set_label(l1); 10124 } 10125 } 10126 break; 10127 case OPC_RECIP_D: 10128 check_cp1_registers(ctx, fs | fd); 10129 { 10130 TCGv_i64 fp0 = tcg_temp_new_i64(); 10131 10132 gen_load_fpr64(ctx, fp0, fs); 10133 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10134 gen_store_fpr64(ctx, fp0, fd); 10135 } 10136 break; 10137 case OPC_RSQRT_D: 10138 check_cp1_registers(ctx, fs | fd); 10139 { 10140 TCGv_i64 fp0 = tcg_temp_new_i64(); 10141 10142 gen_load_fpr64(ctx, fp0, fs); 10143 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10144 gen_store_fpr64(ctx, fp0, fd); 10145 } 10146 break; 10147 case OPC_MADDF_D: 10148 check_insn(ctx, ISA_MIPS_R6); 10149 { 10150 TCGv_i64 fp0 = tcg_temp_new_i64(); 10151 TCGv_i64 fp1 = tcg_temp_new_i64(); 10152 TCGv_i64 fp2 = tcg_temp_new_i64(); 10153 gen_load_fpr64(ctx, fp0, fs); 10154 gen_load_fpr64(ctx, fp1, ft); 10155 gen_load_fpr64(ctx, fp2, fd); 10156 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10157 gen_store_fpr64(ctx, fp2, fd); 10158 } 10159 break; 10160 case OPC_MSUBF_D: 10161 check_insn(ctx, ISA_MIPS_R6); 10162 { 10163 TCGv_i64 fp0 = tcg_temp_new_i64(); 10164 TCGv_i64 fp1 = tcg_temp_new_i64(); 10165 TCGv_i64 fp2 = tcg_temp_new_i64(); 10166 gen_load_fpr64(ctx, fp0, fs); 10167 gen_load_fpr64(ctx, fp1, ft); 10168 gen_load_fpr64(ctx, fp2, fd); 10169 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10170 gen_store_fpr64(ctx, fp2, fd); 10171 } 10172 break; 10173 case OPC_RINT_D: 10174 check_insn(ctx, ISA_MIPS_R6); 10175 { 10176 TCGv_i64 fp0 = tcg_temp_new_i64(); 10177 gen_load_fpr64(ctx, fp0, fs); 10178 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10179 gen_store_fpr64(ctx, fp0, fd); 10180 } 10181 break; 10182 case OPC_CLASS_D: 10183 check_insn(ctx, ISA_MIPS_R6); 10184 { 10185 TCGv_i64 fp0 = tcg_temp_new_i64(); 10186 gen_load_fpr64(ctx, fp0, fs); 10187 gen_helper_float_class_d(fp0, tcg_env, fp0); 10188 gen_store_fpr64(ctx, fp0, fd); 10189 } 10190 break; 10191 case OPC_MIN_D: /* OPC_RECIP2_D */ 10192 if (ctx->insn_flags & ISA_MIPS_R6) { 10193 /* OPC_MIN_D */ 10194 TCGv_i64 fp0 = tcg_temp_new_i64(); 10195 TCGv_i64 fp1 = tcg_temp_new_i64(); 10196 gen_load_fpr64(ctx, fp0, fs); 10197 gen_load_fpr64(ctx, fp1, ft); 10198 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10199 gen_store_fpr64(ctx, fp1, fd); 10200 } else { 10201 /* OPC_RECIP2_D */ 10202 check_cp1_64bitmode(ctx); 10203 { 10204 TCGv_i64 fp0 = tcg_temp_new_i64(); 10205 TCGv_i64 fp1 = tcg_temp_new_i64(); 10206 10207 gen_load_fpr64(ctx, fp0, fs); 10208 gen_load_fpr64(ctx, fp1, ft); 10209 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10210 gen_store_fpr64(ctx, fp0, fd); 10211 } 10212 } 10213 break; 10214 case OPC_MINA_D: /* OPC_RECIP1_D */ 10215 if (ctx->insn_flags & ISA_MIPS_R6) { 10216 /* OPC_MINA_D */ 10217 TCGv_i64 fp0 = tcg_temp_new_i64(); 10218 TCGv_i64 fp1 = tcg_temp_new_i64(); 10219 gen_load_fpr64(ctx, fp0, fs); 10220 gen_load_fpr64(ctx, fp1, ft); 10221 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1); 10222 gen_store_fpr64(ctx, fp1, fd); 10223 } else { 10224 /* OPC_RECIP1_D */ 10225 check_cp1_64bitmode(ctx); 10226 { 10227 TCGv_i64 fp0 = tcg_temp_new_i64(); 10228 10229 gen_load_fpr64(ctx, fp0, fs); 10230 gen_helper_float_recip1_d(fp0, tcg_env, fp0); 10231 gen_store_fpr64(ctx, fp0, fd); 10232 } 10233 } 10234 break; 10235 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10236 if (ctx->insn_flags & ISA_MIPS_R6) { 10237 /* OPC_MAX_D */ 10238 TCGv_i64 fp0 = tcg_temp_new_i64(); 10239 TCGv_i64 fp1 = tcg_temp_new_i64(); 10240 gen_load_fpr64(ctx, fp0, fs); 10241 gen_load_fpr64(ctx, fp1, ft); 10242 gen_helper_float_max_d(fp1, tcg_env, fp0, fp1); 10243 gen_store_fpr64(ctx, fp1, fd); 10244 } else { 10245 /* OPC_RSQRT1_D */ 10246 check_cp1_64bitmode(ctx); 10247 { 10248 TCGv_i64 fp0 = tcg_temp_new_i64(); 10249 10250 gen_load_fpr64(ctx, fp0, fs); 10251 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0); 10252 gen_store_fpr64(ctx, fp0, fd); 10253 } 10254 } 10255 break; 10256 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10257 if (ctx->insn_flags & ISA_MIPS_R6) { 10258 /* OPC_MAXA_D */ 10259 TCGv_i64 fp0 = tcg_temp_new_i64(); 10260 TCGv_i64 fp1 = tcg_temp_new_i64(); 10261 gen_load_fpr64(ctx, fp0, fs); 10262 gen_load_fpr64(ctx, fp1, ft); 10263 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1); 10264 gen_store_fpr64(ctx, fp1, fd); 10265 } else { 10266 /* OPC_RSQRT2_D */ 10267 check_cp1_64bitmode(ctx); 10268 { 10269 TCGv_i64 fp0 = tcg_temp_new_i64(); 10270 TCGv_i64 fp1 = tcg_temp_new_i64(); 10271 10272 gen_load_fpr64(ctx, fp0, fs); 10273 gen_load_fpr64(ctx, fp1, ft); 10274 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10275 gen_store_fpr64(ctx, fp0, fd); 10276 } 10277 } 10278 break; 10279 case OPC_CMP_F_D: 10280 case OPC_CMP_UN_D: 10281 case OPC_CMP_EQ_D: 10282 case OPC_CMP_UEQ_D: 10283 case OPC_CMP_OLT_D: 10284 case OPC_CMP_ULT_D: 10285 case OPC_CMP_OLE_D: 10286 case OPC_CMP_ULE_D: 10287 case OPC_CMP_SF_D: 10288 case OPC_CMP_NGLE_D: 10289 case OPC_CMP_SEQ_D: 10290 case OPC_CMP_NGL_D: 10291 case OPC_CMP_LT_D: 10292 case OPC_CMP_NGE_D: 10293 case OPC_CMP_LE_D: 10294 case OPC_CMP_NGT_D: 10295 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10296 if (ctx->opcode & (1 << 6)) { 10297 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10298 } else { 10299 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10300 } 10301 break; 10302 case OPC_CVT_S_D: 10303 check_cp1_registers(ctx, fs); 10304 { 10305 TCGv_i32 fp32 = tcg_temp_new_i32(); 10306 TCGv_i64 fp64 = tcg_temp_new_i64(); 10307 10308 gen_load_fpr64(ctx, fp64, fs); 10309 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10310 gen_store_fpr32(ctx, fp32, fd); 10311 } 10312 break; 10313 case OPC_CVT_W_D: 10314 check_cp1_registers(ctx, fs); 10315 { 10316 TCGv_i32 fp32 = tcg_temp_new_i32(); 10317 TCGv_i64 fp64 = tcg_temp_new_i64(); 10318 10319 gen_load_fpr64(ctx, fp64, fs); 10320 if (ctx->nan2008) { 10321 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10322 } else { 10323 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10324 } 10325 gen_store_fpr32(ctx, fp32, fd); 10326 } 10327 break; 10328 case OPC_CVT_L_D: 10329 check_cp1_64bitmode(ctx); 10330 { 10331 TCGv_i64 fp0 = tcg_temp_new_i64(); 10332 10333 gen_load_fpr64(ctx, fp0, fs); 10334 if (ctx->nan2008) { 10335 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10336 } else { 10337 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10338 } 10339 gen_store_fpr64(ctx, fp0, fd); 10340 } 10341 break; 10342 case OPC_CVT_S_W: 10343 { 10344 TCGv_i32 fp0 = tcg_temp_new_i32(); 10345 10346 gen_load_fpr32(ctx, fp0, fs); 10347 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10348 gen_store_fpr32(ctx, fp0, fd); 10349 } 10350 break; 10351 case OPC_CVT_D_W: 10352 check_cp1_registers(ctx, fd); 10353 { 10354 TCGv_i32 fp32 = tcg_temp_new_i32(); 10355 TCGv_i64 fp64 = tcg_temp_new_i64(); 10356 10357 gen_load_fpr32(ctx, fp32, fs); 10358 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10359 gen_store_fpr64(ctx, fp64, fd); 10360 } 10361 break; 10362 case OPC_CVT_S_L: 10363 check_cp1_64bitmode(ctx); 10364 { 10365 TCGv_i32 fp32 = tcg_temp_new_i32(); 10366 TCGv_i64 fp64 = tcg_temp_new_i64(); 10367 10368 gen_load_fpr64(ctx, fp64, fs); 10369 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10370 gen_store_fpr32(ctx, fp32, fd); 10371 } 10372 break; 10373 case OPC_CVT_D_L: 10374 check_cp1_64bitmode(ctx); 10375 { 10376 TCGv_i64 fp0 = tcg_temp_new_i64(); 10377 10378 gen_load_fpr64(ctx, fp0, fs); 10379 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10380 gen_store_fpr64(ctx, fp0, fd); 10381 } 10382 break; 10383 case OPC_CVT_PS_PW: 10384 check_ps(ctx); 10385 { 10386 TCGv_i64 fp0 = tcg_temp_new_i64(); 10387 10388 gen_load_fpr64(ctx, fp0, fs); 10389 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10390 gen_store_fpr64(ctx, fp0, fd); 10391 } 10392 break; 10393 case OPC_ADD_PS: 10394 check_ps(ctx); 10395 { 10396 TCGv_i64 fp0 = tcg_temp_new_i64(); 10397 TCGv_i64 fp1 = tcg_temp_new_i64(); 10398 10399 gen_load_fpr64(ctx, fp0, fs); 10400 gen_load_fpr64(ctx, fp1, ft); 10401 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10402 gen_store_fpr64(ctx, fp0, fd); 10403 } 10404 break; 10405 case OPC_SUB_PS: 10406 check_ps(ctx); 10407 { 10408 TCGv_i64 fp0 = tcg_temp_new_i64(); 10409 TCGv_i64 fp1 = tcg_temp_new_i64(); 10410 10411 gen_load_fpr64(ctx, fp0, fs); 10412 gen_load_fpr64(ctx, fp1, ft); 10413 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10414 gen_store_fpr64(ctx, fp0, fd); 10415 } 10416 break; 10417 case OPC_MUL_PS: 10418 check_ps(ctx); 10419 { 10420 TCGv_i64 fp0 = tcg_temp_new_i64(); 10421 TCGv_i64 fp1 = tcg_temp_new_i64(); 10422 10423 gen_load_fpr64(ctx, fp0, fs); 10424 gen_load_fpr64(ctx, fp1, ft); 10425 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10426 gen_store_fpr64(ctx, fp0, fd); 10427 } 10428 break; 10429 case OPC_ABS_PS: 10430 check_ps(ctx); 10431 { 10432 TCGv_i64 fp0 = tcg_temp_new_i64(); 10433 10434 gen_load_fpr64(ctx, fp0, fs); 10435 gen_helper_float_abs_ps(fp0, fp0); 10436 gen_store_fpr64(ctx, fp0, fd); 10437 } 10438 break; 10439 case OPC_MOV_PS: 10440 check_ps(ctx); 10441 { 10442 TCGv_i64 fp0 = tcg_temp_new_i64(); 10443 10444 gen_load_fpr64(ctx, fp0, fs); 10445 gen_store_fpr64(ctx, fp0, fd); 10446 } 10447 break; 10448 case OPC_NEG_PS: 10449 check_ps(ctx); 10450 { 10451 TCGv_i64 fp0 = tcg_temp_new_i64(); 10452 10453 gen_load_fpr64(ctx, fp0, fs); 10454 gen_helper_float_chs_ps(fp0, fp0); 10455 gen_store_fpr64(ctx, fp0, fd); 10456 } 10457 break; 10458 case OPC_MOVCF_PS: 10459 check_ps(ctx); 10460 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10461 break; 10462 case OPC_MOVZ_PS: 10463 check_ps(ctx); 10464 { 10465 TCGLabel *l1 = gen_new_label(); 10466 TCGv_i64 fp0; 10467 10468 if (ft != 0) { 10469 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10470 } 10471 fp0 = tcg_temp_new_i64(); 10472 gen_load_fpr64(ctx, fp0, fs); 10473 gen_store_fpr64(ctx, fp0, fd); 10474 gen_set_label(l1); 10475 } 10476 break; 10477 case OPC_MOVN_PS: 10478 check_ps(ctx); 10479 { 10480 TCGLabel *l1 = gen_new_label(); 10481 TCGv_i64 fp0; 10482 10483 if (ft != 0) { 10484 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10485 fp0 = tcg_temp_new_i64(); 10486 gen_load_fpr64(ctx, fp0, fs); 10487 gen_store_fpr64(ctx, fp0, fd); 10488 gen_set_label(l1); 10489 } 10490 } 10491 break; 10492 case OPC_ADDR_PS: 10493 check_ps(ctx); 10494 { 10495 TCGv_i64 fp0 = tcg_temp_new_i64(); 10496 TCGv_i64 fp1 = tcg_temp_new_i64(); 10497 10498 gen_load_fpr64(ctx, fp0, ft); 10499 gen_load_fpr64(ctx, fp1, fs); 10500 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10501 gen_store_fpr64(ctx, fp0, fd); 10502 } 10503 break; 10504 case OPC_MULR_PS: 10505 check_ps(ctx); 10506 { 10507 TCGv_i64 fp0 = tcg_temp_new_i64(); 10508 TCGv_i64 fp1 = tcg_temp_new_i64(); 10509 10510 gen_load_fpr64(ctx, fp0, ft); 10511 gen_load_fpr64(ctx, fp1, fs); 10512 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10513 gen_store_fpr64(ctx, fp0, fd); 10514 } 10515 break; 10516 case OPC_RECIP2_PS: 10517 check_ps(ctx); 10518 { 10519 TCGv_i64 fp0 = tcg_temp_new_i64(); 10520 TCGv_i64 fp1 = tcg_temp_new_i64(); 10521 10522 gen_load_fpr64(ctx, fp0, fs); 10523 gen_load_fpr64(ctx, fp1, ft); 10524 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10525 gen_store_fpr64(ctx, fp0, fd); 10526 } 10527 break; 10528 case OPC_RECIP1_PS: 10529 check_ps(ctx); 10530 { 10531 TCGv_i64 fp0 = tcg_temp_new_i64(); 10532 10533 gen_load_fpr64(ctx, fp0, fs); 10534 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10535 gen_store_fpr64(ctx, fp0, fd); 10536 } 10537 break; 10538 case OPC_RSQRT1_PS: 10539 check_ps(ctx); 10540 { 10541 TCGv_i64 fp0 = tcg_temp_new_i64(); 10542 10543 gen_load_fpr64(ctx, fp0, fs); 10544 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10545 gen_store_fpr64(ctx, fp0, fd); 10546 } 10547 break; 10548 case OPC_RSQRT2_PS: 10549 check_ps(ctx); 10550 { 10551 TCGv_i64 fp0 = tcg_temp_new_i64(); 10552 TCGv_i64 fp1 = tcg_temp_new_i64(); 10553 10554 gen_load_fpr64(ctx, fp0, fs); 10555 gen_load_fpr64(ctx, fp1, ft); 10556 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10557 gen_store_fpr64(ctx, fp0, fd); 10558 } 10559 break; 10560 case OPC_CVT_S_PU: 10561 check_cp1_64bitmode(ctx); 10562 { 10563 TCGv_i32 fp0 = tcg_temp_new_i32(); 10564 10565 gen_load_fpr32h(ctx, fp0, fs); 10566 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10567 gen_store_fpr32(ctx, fp0, fd); 10568 } 10569 break; 10570 case OPC_CVT_PW_PS: 10571 check_ps(ctx); 10572 { 10573 TCGv_i64 fp0 = tcg_temp_new_i64(); 10574 10575 gen_load_fpr64(ctx, fp0, fs); 10576 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10577 gen_store_fpr64(ctx, fp0, fd); 10578 } 10579 break; 10580 case OPC_CVT_S_PL: 10581 check_cp1_64bitmode(ctx); 10582 { 10583 TCGv_i32 fp0 = tcg_temp_new_i32(); 10584 10585 gen_load_fpr32(ctx, fp0, fs); 10586 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10587 gen_store_fpr32(ctx, fp0, fd); 10588 } 10589 break; 10590 case OPC_PLL_PS: 10591 check_ps(ctx); 10592 { 10593 TCGv_i32 fp0 = tcg_temp_new_i32(); 10594 TCGv_i32 fp1 = tcg_temp_new_i32(); 10595 10596 gen_load_fpr32(ctx, fp0, fs); 10597 gen_load_fpr32(ctx, fp1, ft); 10598 gen_store_fpr32h(ctx, fp0, fd); 10599 gen_store_fpr32(ctx, fp1, fd); 10600 } 10601 break; 10602 case OPC_PLU_PS: 10603 check_ps(ctx); 10604 { 10605 TCGv_i32 fp0 = tcg_temp_new_i32(); 10606 TCGv_i32 fp1 = tcg_temp_new_i32(); 10607 10608 gen_load_fpr32(ctx, fp0, fs); 10609 gen_load_fpr32h(ctx, fp1, ft); 10610 gen_store_fpr32(ctx, fp1, fd); 10611 gen_store_fpr32h(ctx, fp0, fd); 10612 } 10613 break; 10614 case OPC_PUL_PS: 10615 check_ps(ctx); 10616 { 10617 TCGv_i32 fp0 = tcg_temp_new_i32(); 10618 TCGv_i32 fp1 = tcg_temp_new_i32(); 10619 10620 gen_load_fpr32h(ctx, fp0, fs); 10621 gen_load_fpr32(ctx, fp1, ft); 10622 gen_store_fpr32(ctx, fp1, fd); 10623 gen_store_fpr32h(ctx, fp0, fd); 10624 } 10625 break; 10626 case OPC_PUU_PS: 10627 check_ps(ctx); 10628 { 10629 TCGv_i32 fp0 = tcg_temp_new_i32(); 10630 TCGv_i32 fp1 = tcg_temp_new_i32(); 10631 10632 gen_load_fpr32h(ctx, fp0, fs); 10633 gen_load_fpr32h(ctx, fp1, ft); 10634 gen_store_fpr32(ctx, fp1, fd); 10635 gen_store_fpr32h(ctx, fp0, fd); 10636 } 10637 break; 10638 case OPC_CMP_F_PS: 10639 case OPC_CMP_UN_PS: 10640 case OPC_CMP_EQ_PS: 10641 case OPC_CMP_UEQ_PS: 10642 case OPC_CMP_OLT_PS: 10643 case OPC_CMP_ULT_PS: 10644 case OPC_CMP_OLE_PS: 10645 case OPC_CMP_ULE_PS: 10646 case OPC_CMP_SF_PS: 10647 case OPC_CMP_NGLE_PS: 10648 case OPC_CMP_SEQ_PS: 10649 case OPC_CMP_NGL_PS: 10650 case OPC_CMP_LT_PS: 10651 case OPC_CMP_NGE_PS: 10652 case OPC_CMP_LE_PS: 10653 case OPC_CMP_NGT_PS: 10654 if (ctx->opcode & (1 << 6)) { 10655 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10656 } else { 10657 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10658 } 10659 break; 10660 default: 10661 MIPS_INVAL("farith"); 10662 gen_reserved_instruction(ctx); 10663 return; 10664 } 10665 } 10666 10667 /* Coprocessor 3 (FPU) */ 10668 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10669 int fd, int fs, int base, int index) 10670 { 10671 TCGv t0 = tcg_temp_new(); 10672 10673 if (base == 0) { 10674 gen_load_gpr(t0, index); 10675 } else if (index == 0) { 10676 gen_load_gpr(t0, base); 10677 } else { 10678 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 10679 } 10680 /* 10681 * Don't do NOP if destination is zero: we must perform the actual 10682 * memory access. 10683 */ 10684 switch (opc) { 10685 case OPC_LWXC1: 10686 check_cop1x(ctx); 10687 { 10688 TCGv_i32 fp0 = tcg_temp_new_i32(); 10689 10690 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10691 tcg_gen_trunc_tl_i32(fp0, t0); 10692 gen_store_fpr32(ctx, fp0, fd); 10693 } 10694 break; 10695 case OPC_LDXC1: 10696 check_cop1x(ctx); 10697 check_cp1_registers(ctx, fd); 10698 { 10699 TCGv_i64 fp0 = tcg_temp_new_i64(); 10700 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10701 gen_store_fpr64(ctx, fp0, fd); 10702 } 10703 break; 10704 case OPC_LUXC1: 10705 check_cp1_64bitmode(ctx); 10706 tcg_gen_andi_tl(t0, t0, ~0x7); 10707 { 10708 TCGv_i64 fp0 = tcg_temp_new_i64(); 10709 10710 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10711 gen_store_fpr64(ctx, fp0, fd); 10712 } 10713 break; 10714 case OPC_SWXC1: 10715 check_cop1x(ctx); 10716 { 10717 TCGv_i32 fp0 = tcg_temp_new_i32(); 10718 gen_load_fpr32(ctx, fp0, fs); 10719 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10720 } 10721 break; 10722 case OPC_SDXC1: 10723 check_cop1x(ctx); 10724 check_cp1_registers(ctx, fs); 10725 { 10726 TCGv_i64 fp0 = tcg_temp_new_i64(); 10727 gen_load_fpr64(ctx, fp0, fs); 10728 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10729 } 10730 break; 10731 case OPC_SUXC1: 10732 check_cp1_64bitmode(ctx); 10733 tcg_gen_andi_tl(t0, t0, ~0x7); 10734 { 10735 TCGv_i64 fp0 = tcg_temp_new_i64(); 10736 gen_load_fpr64(ctx, fp0, fs); 10737 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10738 } 10739 break; 10740 } 10741 } 10742 10743 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10744 int fd, int fr, int fs, int ft) 10745 { 10746 switch (opc) { 10747 case OPC_ALNV_PS: 10748 check_ps(ctx); 10749 { 10750 TCGv t0 = tcg_temp_new(); 10751 TCGv_i32 fp = tcg_temp_new_i32(); 10752 TCGv_i32 fph = tcg_temp_new_i32(); 10753 TCGLabel *l1 = gen_new_label(); 10754 TCGLabel *l2 = gen_new_label(); 10755 10756 gen_load_gpr(t0, fr); 10757 tcg_gen_andi_tl(t0, t0, 0x7); 10758 10759 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10760 gen_load_fpr32(ctx, fp, fs); 10761 gen_load_fpr32h(ctx, fph, fs); 10762 gen_store_fpr32(ctx, fp, fd); 10763 gen_store_fpr32h(ctx, fph, fd); 10764 tcg_gen_br(l2); 10765 gen_set_label(l1); 10766 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10767 if (disas_is_bigendian(ctx)) { 10768 gen_load_fpr32(ctx, fp, fs); 10769 gen_load_fpr32h(ctx, fph, ft); 10770 gen_store_fpr32h(ctx, fp, fd); 10771 gen_store_fpr32(ctx, fph, fd); 10772 } else { 10773 gen_load_fpr32h(ctx, fph, fs); 10774 gen_load_fpr32(ctx, fp, ft); 10775 gen_store_fpr32(ctx, fph, fd); 10776 gen_store_fpr32h(ctx, fp, fd); 10777 } 10778 gen_set_label(l2); 10779 } 10780 break; 10781 case OPC_MADD_S: 10782 check_cop1x(ctx); 10783 { 10784 TCGv_i32 fp0 = tcg_temp_new_i32(); 10785 TCGv_i32 fp1 = tcg_temp_new_i32(); 10786 TCGv_i32 fp2 = tcg_temp_new_i32(); 10787 10788 gen_load_fpr32(ctx, fp0, fs); 10789 gen_load_fpr32(ctx, fp1, ft); 10790 gen_load_fpr32(ctx, fp2, fr); 10791 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10792 gen_store_fpr32(ctx, fp2, fd); 10793 } 10794 break; 10795 case OPC_MADD_D: 10796 check_cop1x(ctx); 10797 check_cp1_registers(ctx, fd | fs | ft | fr); 10798 { 10799 TCGv_i64 fp0 = tcg_temp_new_i64(); 10800 TCGv_i64 fp1 = tcg_temp_new_i64(); 10801 TCGv_i64 fp2 = tcg_temp_new_i64(); 10802 10803 gen_load_fpr64(ctx, fp0, fs); 10804 gen_load_fpr64(ctx, fp1, ft); 10805 gen_load_fpr64(ctx, fp2, fr); 10806 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10807 gen_store_fpr64(ctx, fp2, fd); 10808 } 10809 break; 10810 case OPC_MADD_PS: 10811 check_ps(ctx); 10812 { 10813 TCGv_i64 fp0 = tcg_temp_new_i64(); 10814 TCGv_i64 fp1 = tcg_temp_new_i64(); 10815 TCGv_i64 fp2 = tcg_temp_new_i64(); 10816 10817 gen_load_fpr64(ctx, fp0, fs); 10818 gen_load_fpr64(ctx, fp1, ft); 10819 gen_load_fpr64(ctx, fp2, fr); 10820 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10821 gen_store_fpr64(ctx, fp2, fd); 10822 } 10823 break; 10824 case OPC_MSUB_S: 10825 check_cop1x(ctx); 10826 { 10827 TCGv_i32 fp0 = tcg_temp_new_i32(); 10828 TCGv_i32 fp1 = tcg_temp_new_i32(); 10829 TCGv_i32 fp2 = tcg_temp_new_i32(); 10830 10831 gen_load_fpr32(ctx, fp0, fs); 10832 gen_load_fpr32(ctx, fp1, ft); 10833 gen_load_fpr32(ctx, fp2, fr); 10834 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10835 gen_store_fpr32(ctx, fp2, fd); 10836 } 10837 break; 10838 case OPC_MSUB_D: 10839 check_cop1x(ctx); 10840 check_cp1_registers(ctx, fd | fs | ft | fr); 10841 { 10842 TCGv_i64 fp0 = tcg_temp_new_i64(); 10843 TCGv_i64 fp1 = tcg_temp_new_i64(); 10844 TCGv_i64 fp2 = tcg_temp_new_i64(); 10845 10846 gen_load_fpr64(ctx, fp0, fs); 10847 gen_load_fpr64(ctx, fp1, ft); 10848 gen_load_fpr64(ctx, fp2, fr); 10849 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10850 gen_store_fpr64(ctx, fp2, fd); 10851 } 10852 break; 10853 case OPC_MSUB_PS: 10854 check_ps(ctx); 10855 { 10856 TCGv_i64 fp0 = tcg_temp_new_i64(); 10857 TCGv_i64 fp1 = tcg_temp_new_i64(); 10858 TCGv_i64 fp2 = tcg_temp_new_i64(); 10859 10860 gen_load_fpr64(ctx, fp0, fs); 10861 gen_load_fpr64(ctx, fp1, ft); 10862 gen_load_fpr64(ctx, fp2, fr); 10863 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10864 gen_store_fpr64(ctx, fp2, fd); 10865 } 10866 break; 10867 case OPC_NMADD_S: 10868 check_cop1x(ctx); 10869 { 10870 TCGv_i32 fp0 = tcg_temp_new_i32(); 10871 TCGv_i32 fp1 = tcg_temp_new_i32(); 10872 TCGv_i32 fp2 = tcg_temp_new_i32(); 10873 10874 gen_load_fpr32(ctx, fp0, fs); 10875 gen_load_fpr32(ctx, fp1, ft); 10876 gen_load_fpr32(ctx, fp2, fr); 10877 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10878 gen_store_fpr32(ctx, fp2, fd); 10879 } 10880 break; 10881 case OPC_NMADD_D: 10882 check_cop1x(ctx); 10883 check_cp1_registers(ctx, fd | fs | ft | fr); 10884 { 10885 TCGv_i64 fp0 = tcg_temp_new_i64(); 10886 TCGv_i64 fp1 = tcg_temp_new_i64(); 10887 TCGv_i64 fp2 = tcg_temp_new_i64(); 10888 10889 gen_load_fpr64(ctx, fp0, fs); 10890 gen_load_fpr64(ctx, fp1, ft); 10891 gen_load_fpr64(ctx, fp2, fr); 10892 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10893 gen_store_fpr64(ctx, fp2, fd); 10894 } 10895 break; 10896 case OPC_NMADD_PS: 10897 check_ps(ctx); 10898 { 10899 TCGv_i64 fp0 = tcg_temp_new_i64(); 10900 TCGv_i64 fp1 = tcg_temp_new_i64(); 10901 TCGv_i64 fp2 = tcg_temp_new_i64(); 10902 10903 gen_load_fpr64(ctx, fp0, fs); 10904 gen_load_fpr64(ctx, fp1, ft); 10905 gen_load_fpr64(ctx, fp2, fr); 10906 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10907 gen_store_fpr64(ctx, fp2, fd); 10908 } 10909 break; 10910 case OPC_NMSUB_S: 10911 check_cop1x(ctx); 10912 { 10913 TCGv_i32 fp0 = tcg_temp_new_i32(); 10914 TCGv_i32 fp1 = tcg_temp_new_i32(); 10915 TCGv_i32 fp2 = tcg_temp_new_i32(); 10916 10917 gen_load_fpr32(ctx, fp0, fs); 10918 gen_load_fpr32(ctx, fp1, ft); 10919 gen_load_fpr32(ctx, fp2, fr); 10920 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10921 gen_store_fpr32(ctx, fp2, fd); 10922 } 10923 break; 10924 case OPC_NMSUB_D: 10925 check_cop1x(ctx); 10926 check_cp1_registers(ctx, fd | fs | ft | fr); 10927 { 10928 TCGv_i64 fp0 = tcg_temp_new_i64(); 10929 TCGv_i64 fp1 = tcg_temp_new_i64(); 10930 TCGv_i64 fp2 = tcg_temp_new_i64(); 10931 10932 gen_load_fpr64(ctx, fp0, fs); 10933 gen_load_fpr64(ctx, fp1, ft); 10934 gen_load_fpr64(ctx, fp2, fr); 10935 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10936 gen_store_fpr64(ctx, fp2, fd); 10937 } 10938 break; 10939 case OPC_NMSUB_PS: 10940 check_ps(ctx); 10941 { 10942 TCGv_i64 fp0 = tcg_temp_new_i64(); 10943 TCGv_i64 fp1 = tcg_temp_new_i64(); 10944 TCGv_i64 fp2 = tcg_temp_new_i64(); 10945 10946 gen_load_fpr64(ctx, fp0, fs); 10947 gen_load_fpr64(ctx, fp1, ft); 10948 gen_load_fpr64(ctx, fp2, fr); 10949 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10950 gen_store_fpr64(ctx, fp2, fd); 10951 } 10952 break; 10953 default: 10954 MIPS_INVAL("flt3_arith"); 10955 gen_reserved_instruction(ctx); 10956 return; 10957 } 10958 } 10959 10960 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10961 { 10962 TCGv t0; 10963 10964 #if !defined(CONFIG_USER_ONLY) 10965 /* 10966 * The Linux kernel will emulate rdhwr if it's not supported natively. 10967 * Therefore only check the ISA in system mode. 10968 */ 10969 check_insn(ctx, ISA_MIPS_R2); 10970 #endif 10971 t0 = tcg_temp_new(); 10972 10973 switch (rd) { 10974 case 0: 10975 gen_helper_rdhwr_cpunum(t0, tcg_env); 10976 gen_store_gpr(t0, rt); 10977 break; 10978 case 1: 10979 gen_helper_rdhwr_synci_step(t0, tcg_env); 10980 gen_store_gpr(t0, rt); 10981 break; 10982 case 2: 10983 translator_io_start(&ctx->base); 10984 gen_helper_rdhwr_cc(t0, tcg_env); 10985 gen_store_gpr(t0, rt); 10986 /* 10987 * Break the TB to be able to take timer interrupts immediately 10988 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10989 * we break completely out of translated code. 10990 */ 10991 gen_save_pc(ctx->base.pc_next + 4); 10992 ctx->base.is_jmp = DISAS_EXIT; 10993 break; 10994 case 3: 10995 gen_helper_rdhwr_ccres(t0, tcg_env); 10996 gen_store_gpr(t0, rt); 10997 break; 10998 case 4: 10999 check_insn(ctx, ISA_MIPS_R6); 11000 if (sel != 0) { 11001 /* 11002 * Performance counter registers are not implemented other than 11003 * control register 0. 11004 */ 11005 generate_exception(ctx, EXCP_RI); 11006 } 11007 gen_helper_rdhwr_performance(t0, tcg_env); 11008 gen_store_gpr(t0, rt); 11009 break; 11010 case 5: 11011 check_insn(ctx, ISA_MIPS_R6); 11012 gen_helper_rdhwr_xnp(t0, tcg_env); 11013 gen_store_gpr(t0, rt); 11014 break; 11015 case 29: 11016 #if defined(CONFIG_USER_ONLY) 11017 tcg_gen_ld_tl(t0, tcg_env, 11018 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11019 gen_store_gpr(t0, rt); 11020 break; 11021 #else 11022 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11023 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11024 tcg_gen_ld_tl(t0, tcg_env, 11025 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11026 gen_store_gpr(t0, rt); 11027 } else { 11028 gen_reserved_instruction(ctx); 11029 } 11030 break; 11031 #endif 11032 default: /* Invalid */ 11033 MIPS_INVAL("rdhwr"); 11034 gen_reserved_instruction(ctx); 11035 break; 11036 } 11037 } 11038 11039 static inline void clear_branch_hflags(DisasContext *ctx) 11040 { 11041 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11042 if (ctx->base.is_jmp == DISAS_NEXT) { 11043 save_cpu_state(ctx, 0); 11044 } else { 11045 /* 11046 * It is not safe to save ctx->hflags as hflags may be changed 11047 * in execution time by the instruction in delay / forbidden slot. 11048 */ 11049 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11050 } 11051 } 11052 11053 static void gen_branch(DisasContext *ctx, int insn_bytes) 11054 { 11055 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11056 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11057 /* Branches completion */ 11058 clear_branch_hflags(ctx); 11059 ctx->base.is_jmp = DISAS_NORETURN; 11060 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11061 case MIPS_HFLAG_FBNSLOT: 11062 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11063 break; 11064 case MIPS_HFLAG_B: 11065 /* unconditional branch */ 11066 if (proc_hflags & MIPS_HFLAG_BX) { 11067 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11068 } 11069 gen_goto_tb(ctx, 0, ctx->btarget); 11070 break; 11071 case MIPS_HFLAG_BL: 11072 /* blikely taken case */ 11073 gen_goto_tb(ctx, 0, ctx->btarget); 11074 break; 11075 case MIPS_HFLAG_BC: 11076 /* Conditional branch */ 11077 { 11078 TCGLabel *l1 = gen_new_label(); 11079 11080 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11081 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11082 gen_set_label(l1); 11083 gen_goto_tb(ctx, 0, ctx->btarget); 11084 } 11085 break; 11086 case MIPS_HFLAG_BR: 11087 /* unconditional branch to register */ 11088 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11089 TCGv t0 = tcg_temp_new(); 11090 TCGv_i32 t1 = tcg_temp_new_i32(); 11091 11092 tcg_gen_andi_tl(t0, btarget, 0x1); 11093 tcg_gen_trunc_tl_i32(t1, t0); 11094 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11095 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11096 tcg_gen_or_i32(hflags, hflags, t1); 11097 11098 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11099 } else { 11100 tcg_gen_mov_tl(cpu_PC, btarget); 11101 } 11102 tcg_gen_lookup_and_goto_ptr(); 11103 break; 11104 default: 11105 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11106 gen_reserved_instruction(ctx); 11107 } 11108 } 11109 } 11110 11111 /* Compact Branches */ 11112 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11113 int rs, int rt, int32_t offset) 11114 { 11115 int bcond_compute = 0; 11116 TCGv t0 = tcg_temp_new(); 11117 TCGv t1 = tcg_temp_new(); 11118 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11119 11120 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11121 #ifdef MIPS_DEBUG_DISAS 11122 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 11123 VADDR_PRIx "\n", ctx->base.pc_next); 11124 #endif 11125 gen_reserved_instruction(ctx); 11126 return; 11127 } 11128 11129 /* Load needed operands and calculate btarget */ 11130 switch (opc) { 11131 /* compact branch */ 11132 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11133 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11134 gen_load_gpr(t0, rs); 11135 gen_load_gpr(t1, rt); 11136 bcond_compute = 1; 11137 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11138 if (rs <= rt && rs == 0) { 11139 /* OPC_BEQZALC, OPC_BNEZALC */ 11140 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11141 } 11142 break; 11143 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11144 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11145 gen_load_gpr(t0, rs); 11146 gen_load_gpr(t1, rt); 11147 bcond_compute = 1; 11148 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11149 break; 11150 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11151 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11152 if (rs == 0 || rs == rt) { 11153 /* OPC_BLEZALC, OPC_BGEZALC */ 11154 /* OPC_BGTZALC, OPC_BLTZALC */ 11155 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11156 } 11157 gen_load_gpr(t0, rs); 11158 gen_load_gpr(t1, rt); 11159 bcond_compute = 1; 11160 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11161 break; 11162 case OPC_BC: 11163 case OPC_BALC: 11164 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11165 break; 11166 case OPC_BEQZC: 11167 case OPC_BNEZC: 11168 if (rs != 0) { 11169 /* OPC_BEQZC, OPC_BNEZC */ 11170 gen_load_gpr(t0, rs); 11171 bcond_compute = 1; 11172 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11173 } else { 11174 /* OPC_JIC, OPC_JIALC */ 11175 TCGv tbase = tcg_temp_new(); 11176 11177 gen_load_gpr(tbase, rt); 11178 gen_op_addr_addi(ctx, btarget, tbase, offset); 11179 } 11180 break; 11181 default: 11182 MIPS_INVAL("Compact branch/jump"); 11183 gen_reserved_instruction(ctx); 11184 return; 11185 } 11186 11187 if (bcond_compute == 0) { 11188 /* Unconditional compact branch */ 11189 switch (opc) { 11190 case OPC_JIALC: 11191 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11192 /* Fallthrough */ 11193 case OPC_JIC: 11194 ctx->hflags |= MIPS_HFLAG_BR; 11195 break; 11196 case OPC_BALC: 11197 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11198 /* Fallthrough */ 11199 case OPC_BC: 11200 ctx->hflags |= MIPS_HFLAG_B; 11201 break; 11202 default: 11203 MIPS_INVAL("Compact branch/jump"); 11204 gen_reserved_instruction(ctx); 11205 return; 11206 } 11207 11208 /* Generating branch here as compact branches don't have delay slot */ 11209 gen_branch(ctx, 4); 11210 } else { 11211 /* Conditional compact branch */ 11212 TCGLabel *fs = gen_new_label(); 11213 save_cpu_state(ctx, 0); 11214 11215 switch (opc) { 11216 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11217 if (rs == 0 && rt != 0) { 11218 /* OPC_BLEZALC */ 11219 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11220 } else if (rs != 0 && rt != 0 && rs == rt) { 11221 /* OPC_BGEZALC */ 11222 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11223 } else { 11224 /* OPC_BGEUC */ 11225 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11226 } 11227 break; 11228 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11229 if (rs == 0 && rt != 0) { 11230 /* OPC_BGTZALC */ 11231 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11232 } else if (rs != 0 && rt != 0 && rs == rt) { 11233 /* OPC_BLTZALC */ 11234 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11235 } else { 11236 /* OPC_BLTUC */ 11237 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11238 } 11239 break; 11240 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11241 if (rs == 0 && rt != 0) { 11242 /* OPC_BLEZC */ 11243 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11244 } else if (rs != 0 && rt != 0 && rs == rt) { 11245 /* OPC_BGEZC */ 11246 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11247 } else { 11248 /* OPC_BGEC */ 11249 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11250 } 11251 break; 11252 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11253 if (rs == 0 && rt != 0) { 11254 /* OPC_BGTZC */ 11255 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11256 } else if (rs != 0 && rt != 0 && rs == rt) { 11257 /* OPC_BLTZC */ 11258 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11259 } else { 11260 /* OPC_BLTC */ 11261 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11262 } 11263 break; 11264 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11265 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11266 if (rs >= rt) { 11267 /* OPC_BOVC, OPC_BNVC */ 11268 TCGv t2 = tcg_temp_new(); 11269 TCGv t3 = tcg_temp_new(); 11270 TCGv t4 = tcg_temp_new(); 11271 TCGv input_overflow = tcg_temp_new(); 11272 11273 gen_load_gpr(t0, rs); 11274 gen_load_gpr(t1, rt); 11275 tcg_gen_ext32s_tl(t2, t0); 11276 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11277 tcg_gen_ext32s_tl(t3, t1); 11278 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11279 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11280 11281 tcg_gen_add_tl(t4, t2, t3); 11282 tcg_gen_ext32s_tl(t4, t4); 11283 tcg_gen_xor_tl(t2, t2, t3); 11284 tcg_gen_xor_tl(t3, t4, t3); 11285 tcg_gen_andc_tl(t2, t3, t2); 11286 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11287 tcg_gen_or_tl(t4, t4, input_overflow); 11288 if (opc == OPC_BOVC) { 11289 /* OPC_BOVC */ 11290 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11291 } else { 11292 /* OPC_BNVC */ 11293 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11294 } 11295 } else if (rs < rt && rs == 0) { 11296 /* OPC_BEQZALC, OPC_BNEZALC */ 11297 if (opc == OPC_BEQZALC) { 11298 /* OPC_BEQZALC */ 11299 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11300 } else { 11301 /* OPC_BNEZALC */ 11302 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11303 } 11304 } else { 11305 /* OPC_BEQC, OPC_BNEC */ 11306 if (opc == OPC_BEQC) { 11307 /* OPC_BEQC */ 11308 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11309 } else { 11310 /* OPC_BNEC */ 11311 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11312 } 11313 } 11314 break; 11315 case OPC_BEQZC: 11316 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11317 break; 11318 case OPC_BNEZC: 11319 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11320 break; 11321 default: 11322 MIPS_INVAL("Compact conditional branch/jump"); 11323 gen_reserved_instruction(ctx); 11324 return; 11325 } 11326 11327 /* Generating branch here as compact branches don't have delay slot */ 11328 gen_goto_tb(ctx, 1, ctx->btarget); 11329 gen_set_label(fs); 11330 11331 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11332 } 11333 } 11334 11335 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11336 int is_64_bit, int extended) 11337 { 11338 target_ulong npc; 11339 11340 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11341 gen_reserved_instruction(ctx); 11342 return; 11343 } 11344 11345 npc = pc_relative_pc(ctx) + imm; 11346 if (!is_64_bit) { 11347 npc = (int32_t)npc; 11348 } 11349 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11350 } 11351 11352 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11353 int16_t offset) 11354 { 11355 TCGv_i32 t0 = tcg_constant_i32(op); 11356 TCGv t1 = tcg_temp_new(); 11357 gen_base_offset_addr(ctx, t1, base, offset); 11358 gen_helper_cache(tcg_env, t1, t0); 11359 } 11360 11361 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11362 { 11363 #ifdef CONFIG_USER_ONLY 11364 return false; 11365 #else 11366 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11367 return semihosting_enabled(is_user) && sdbbp_code == 1; 11368 #endif 11369 } 11370 11371 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11372 { 11373 TCGv t0 = tcg_temp_new(); 11374 TCGv t1 = tcg_temp_new(); 11375 11376 gen_load_gpr(t0, base); 11377 11378 if (index != 0) { 11379 gen_load_gpr(t1, index); 11380 tcg_gen_shli_tl(t1, t1, 2); 11381 gen_op_addr_add(ctx, t0, t1, t0); 11382 } 11383 11384 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11385 gen_store_gpr(t1, rd); 11386 } 11387 11388 static void gen_sync(int stype) 11389 { 11390 TCGBar tcg_mo = TCG_BAR_SC; 11391 11392 switch (stype) { 11393 case 0x4: /* SYNC_WMB */ 11394 tcg_mo |= TCG_MO_ST_ST; 11395 break; 11396 case 0x10: /* SYNC_MB */ 11397 tcg_mo |= TCG_MO_ALL; 11398 break; 11399 case 0x11: /* SYNC_ACQUIRE */ 11400 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11401 break; 11402 case 0x12: /* SYNC_RELEASE */ 11403 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11404 break; 11405 case 0x13: /* SYNC_RMB */ 11406 tcg_mo |= TCG_MO_LD_LD; 11407 break; 11408 default: 11409 tcg_mo |= TCG_MO_ALL; 11410 break; 11411 } 11412 11413 tcg_gen_mb(tcg_mo); 11414 } 11415 11416 /* ISA extensions (ASEs) */ 11417 11418 /* MIPS16 extension to MIPS32 */ 11419 #include "mips16e_translate.c.inc" 11420 11421 /* microMIPS extension to MIPS32/MIPS64 */ 11422 11423 /* 11424 * Values for microMIPS fmt field. Variable-width, depending on which 11425 * formats the instruction supports. 11426 */ 11427 enum { 11428 FMT_SD_S = 0, 11429 FMT_SD_D = 1, 11430 11431 FMT_SDPS_S = 0, 11432 FMT_SDPS_D = 1, 11433 FMT_SDPS_PS = 2, 11434 11435 FMT_SWL_S = 0, 11436 FMT_SWL_W = 1, 11437 FMT_SWL_L = 2, 11438 11439 FMT_DWL_D = 0, 11440 FMT_DWL_W = 1, 11441 FMT_DWL_L = 2 11442 }; 11443 11444 #include "micromips_translate.c.inc" 11445 11446 #include "nanomips_translate.c.inc" 11447 11448 /* MIPSDSP functions. */ 11449 11450 /* Indexed load is not for DSP only */ 11451 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 11452 int rd, int base, int offset) 11453 { 11454 TCGv t0; 11455 11456 if (!(ctx->insn_flags & INSN_OCTEON)) { 11457 check_dsp(ctx); 11458 } 11459 t0 = tcg_temp_new(); 11460 11461 if (base == 0) { 11462 gen_load_gpr(t0, offset); 11463 } else if (offset == 0) { 11464 gen_load_gpr(t0, base); 11465 } else { 11466 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 11467 } 11468 11469 switch (opc) { 11470 case OPC_LBUX: 11471 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 11472 gen_store_gpr(t0, rd); 11473 break; 11474 case OPC_LHX: 11475 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW); 11476 gen_store_gpr(t0, rd); 11477 break; 11478 case OPC_LWX: 11479 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11480 gen_store_gpr(t0, rd); 11481 break; 11482 #if defined(TARGET_MIPS64) 11483 case OPC_LDX: 11484 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 11485 gen_store_gpr(t0, rd); 11486 break; 11487 #endif 11488 } 11489 } 11490 11491 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11492 int ret, int v1, int v2) 11493 { 11494 TCGv v1_t; 11495 TCGv v2_t; 11496 11497 if (ret == 0) { 11498 /* Treat as NOP. */ 11499 return; 11500 } 11501 11502 v1_t = tcg_temp_new(); 11503 v2_t = tcg_temp_new(); 11504 11505 gen_load_gpr(v1_t, v1); 11506 gen_load_gpr(v2_t, v2); 11507 11508 switch (op1) { 11509 case OPC_ADDUH_QB_DSP: 11510 check_dsp_r2(ctx); 11511 switch (op2) { 11512 case OPC_ADDUH_QB: 11513 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11514 break; 11515 case OPC_ADDUH_R_QB: 11516 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11517 break; 11518 case OPC_ADDQH_PH: 11519 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11520 break; 11521 case OPC_ADDQH_R_PH: 11522 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11523 break; 11524 case OPC_ADDQH_W: 11525 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11526 break; 11527 case OPC_ADDQH_R_W: 11528 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11529 break; 11530 case OPC_SUBUH_QB: 11531 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11532 break; 11533 case OPC_SUBUH_R_QB: 11534 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11535 break; 11536 case OPC_SUBQH_PH: 11537 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11538 break; 11539 case OPC_SUBQH_R_PH: 11540 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11541 break; 11542 case OPC_SUBQH_W: 11543 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11544 break; 11545 case OPC_SUBQH_R_W: 11546 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11547 break; 11548 } 11549 break; 11550 case OPC_ABSQ_S_PH_DSP: 11551 switch (op2) { 11552 case OPC_ABSQ_S_QB: 11553 check_dsp_r2(ctx); 11554 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11555 break; 11556 case OPC_ABSQ_S_PH: 11557 check_dsp(ctx); 11558 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11559 break; 11560 case OPC_ABSQ_S_W: 11561 check_dsp(ctx); 11562 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11563 break; 11564 case OPC_PRECEQ_W_PHL: 11565 check_dsp(ctx); 11566 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11567 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11568 break; 11569 case OPC_PRECEQ_W_PHR: 11570 check_dsp(ctx); 11571 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11572 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11573 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11574 break; 11575 case OPC_PRECEQU_PH_QBL: 11576 check_dsp(ctx); 11577 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11578 break; 11579 case OPC_PRECEQU_PH_QBR: 11580 check_dsp(ctx); 11581 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11582 break; 11583 case OPC_PRECEQU_PH_QBLA: 11584 check_dsp(ctx); 11585 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11586 break; 11587 case OPC_PRECEQU_PH_QBRA: 11588 check_dsp(ctx); 11589 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11590 break; 11591 case OPC_PRECEU_PH_QBL: 11592 check_dsp(ctx); 11593 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11594 break; 11595 case OPC_PRECEU_PH_QBR: 11596 check_dsp(ctx); 11597 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11598 break; 11599 case OPC_PRECEU_PH_QBLA: 11600 check_dsp(ctx); 11601 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11602 break; 11603 case OPC_PRECEU_PH_QBRA: 11604 check_dsp(ctx); 11605 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11606 break; 11607 } 11608 break; 11609 case OPC_ADDU_QB_DSP: 11610 switch (op2) { 11611 case OPC_ADDQ_PH: 11612 check_dsp(ctx); 11613 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11614 break; 11615 case OPC_ADDQ_S_PH: 11616 check_dsp(ctx); 11617 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11618 break; 11619 case OPC_ADDQ_S_W: 11620 check_dsp(ctx); 11621 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11622 break; 11623 case OPC_ADDU_QB: 11624 check_dsp(ctx); 11625 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11626 break; 11627 case OPC_ADDU_S_QB: 11628 check_dsp(ctx); 11629 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11630 break; 11631 case OPC_ADDU_PH: 11632 check_dsp_r2(ctx); 11633 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11634 break; 11635 case OPC_ADDU_S_PH: 11636 check_dsp_r2(ctx); 11637 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11638 break; 11639 case OPC_SUBQ_PH: 11640 check_dsp(ctx); 11641 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11642 break; 11643 case OPC_SUBQ_S_PH: 11644 check_dsp(ctx); 11645 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11646 break; 11647 case OPC_SUBQ_S_W: 11648 check_dsp(ctx); 11649 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11650 break; 11651 case OPC_SUBU_QB: 11652 check_dsp(ctx); 11653 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11654 break; 11655 case OPC_SUBU_S_QB: 11656 check_dsp(ctx); 11657 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11658 break; 11659 case OPC_SUBU_PH: 11660 check_dsp_r2(ctx); 11661 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11662 break; 11663 case OPC_SUBU_S_PH: 11664 check_dsp_r2(ctx); 11665 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11666 break; 11667 case OPC_ADDSC: 11668 check_dsp(ctx); 11669 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11670 break; 11671 case OPC_ADDWC: 11672 check_dsp(ctx); 11673 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11674 break; 11675 case OPC_MODSUB: 11676 check_dsp(ctx); 11677 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11678 break; 11679 case OPC_RADDU_W_QB: 11680 check_dsp(ctx); 11681 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11682 break; 11683 } 11684 break; 11685 case OPC_CMPU_EQ_QB_DSP: 11686 switch (op2) { 11687 case OPC_PRECR_QB_PH: 11688 check_dsp_r2(ctx); 11689 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11690 break; 11691 case OPC_PRECRQ_QB_PH: 11692 check_dsp(ctx); 11693 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11694 break; 11695 case OPC_PRECR_SRA_PH_W: 11696 check_dsp_r2(ctx); 11697 { 11698 TCGv_i32 sa_t = tcg_constant_i32(v2); 11699 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11700 cpu_gpr[ret]); 11701 break; 11702 } 11703 case OPC_PRECR_SRA_R_PH_W: 11704 check_dsp_r2(ctx); 11705 { 11706 TCGv_i32 sa_t = tcg_constant_i32(v2); 11707 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11708 cpu_gpr[ret]); 11709 break; 11710 } 11711 case OPC_PRECRQ_PH_W: 11712 check_dsp(ctx); 11713 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11714 break; 11715 case OPC_PRECRQ_RS_PH_W: 11716 check_dsp(ctx); 11717 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11718 break; 11719 case OPC_PRECRQU_S_QB_PH: 11720 check_dsp(ctx); 11721 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11722 break; 11723 } 11724 break; 11725 #ifdef TARGET_MIPS64 11726 case OPC_ABSQ_S_QH_DSP: 11727 switch (op2) { 11728 case OPC_PRECEQ_L_PWL: 11729 check_dsp(ctx); 11730 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11731 break; 11732 case OPC_PRECEQ_L_PWR: 11733 check_dsp(ctx); 11734 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11735 break; 11736 case OPC_PRECEQ_PW_QHL: 11737 check_dsp(ctx); 11738 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11739 break; 11740 case OPC_PRECEQ_PW_QHR: 11741 check_dsp(ctx); 11742 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11743 break; 11744 case OPC_PRECEQ_PW_QHLA: 11745 check_dsp(ctx); 11746 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11747 break; 11748 case OPC_PRECEQ_PW_QHRA: 11749 check_dsp(ctx); 11750 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11751 break; 11752 case OPC_PRECEQU_QH_OBL: 11753 check_dsp(ctx); 11754 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11755 break; 11756 case OPC_PRECEQU_QH_OBR: 11757 check_dsp(ctx); 11758 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11759 break; 11760 case OPC_PRECEQU_QH_OBLA: 11761 check_dsp(ctx); 11762 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11763 break; 11764 case OPC_PRECEQU_QH_OBRA: 11765 check_dsp(ctx); 11766 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11767 break; 11768 case OPC_PRECEU_QH_OBL: 11769 check_dsp(ctx); 11770 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11771 break; 11772 case OPC_PRECEU_QH_OBR: 11773 check_dsp(ctx); 11774 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11775 break; 11776 case OPC_PRECEU_QH_OBLA: 11777 check_dsp(ctx); 11778 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11779 break; 11780 case OPC_PRECEU_QH_OBRA: 11781 check_dsp(ctx); 11782 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11783 break; 11784 case OPC_ABSQ_S_OB: 11785 check_dsp_r2(ctx); 11786 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11787 break; 11788 case OPC_ABSQ_S_PW: 11789 check_dsp(ctx); 11790 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11791 break; 11792 case OPC_ABSQ_S_QH: 11793 check_dsp(ctx); 11794 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11795 break; 11796 } 11797 break; 11798 case OPC_ADDU_OB_DSP: 11799 switch (op2) { 11800 case OPC_RADDU_L_OB: 11801 check_dsp(ctx); 11802 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11803 break; 11804 case OPC_SUBQ_PW: 11805 check_dsp(ctx); 11806 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11807 break; 11808 case OPC_SUBQ_S_PW: 11809 check_dsp(ctx); 11810 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11811 break; 11812 case OPC_SUBQ_QH: 11813 check_dsp(ctx); 11814 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11815 break; 11816 case OPC_SUBQ_S_QH: 11817 check_dsp(ctx); 11818 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11819 break; 11820 case OPC_SUBU_OB: 11821 check_dsp(ctx); 11822 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11823 break; 11824 case OPC_SUBU_S_OB: 11825 check_dsp(ctx); 11826 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11827 break; 11828 case OPC_SUBU_QH: 11829 check_dsp_r2(ctx); 11830 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11831 break; 11832 case OPC_SUBU_S_QH: 11833 check_dsp_r2(ctx); 11834 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11835 break; 11836 case OPC_SUBUH_OB: 11837 check_dsp_r2(ctx); 11838 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11839 break; 11840 case OPC_SUBUH_R_OB: 11841 check_dsp_r2(ctx); 11842 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11843 break; 11844 case OPC_ADDQ_PW: 11845 check_dsp(ctx); 11846 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11847 break; 11848 case OPC_ADDQ_S_PW: 11849 check_dsp(ctx); 11850 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11851 break; 11852 case OPC_ADDQ_QH: 11853 check_dsp(ctx); 11854 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11855 break; 11856 case OPC_ADDQ_S_QH: 11857 check_dsp(ctx); 11858 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11859 break; 11860 case OPC_ADDU_OB: 11861 check_dsp(ctx); 11862 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11863 break; 11864 case OPC_ADDU_S_OB: 11865 check_dsp(ctx); 11866 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11867 break; 11868 case OPC_ADDU_QH: 11869 check_dsp_r2(ctx); 11870 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11871 break; 11872 case OPC_ADDU_S_QH: 11873 check_dsp_r2(ctx); 11874 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11875 break; 11876 case OPC_ADDUH_OB: 11877 check_dsp_r2(ctx); 11878 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11879 break; 11880 case OPC_ADDUH_R_OB: 11881 check_dsp_r2(ctx); 11882 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11883 break; 11884 } 11885 break; 11886 case OPC_CMPU_EQ_OB_DSP: 11887 switch (op2) { 11888 case OPC_PRECR_OB_QH: 11889 check_dsp_r2(ctx); 11890 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11891 break; 11892 case OPC_PRECR_SRA_QH_PW: 11893 check_dsp_r2(ctx); 11894 { 11895 TCGv_i32 ret_t = tcg_constant_i32(ret); 11896 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11897 break; 11898 } 11899 case OPC_PRECR_SRA_R_QH_PW: 11900 check_dsp_r2(ctx); 11901 { 11902 TCGv_i32 sa_v = tcg_constant_i32(ret); 11903 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11904 break; 11905 } 11906 case OPC_PRECRQ_OB_QH: 11907 check_dsp(ctx); 11908 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11909 break; 11910 case OPC_PRECRQ_PW_L: 11911 check_dsp(ctx); 11912 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11913 break; 11914 case OPC_PRECRQ_QH_PW: 11915 check_dsp(ctx); 11916 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11917 break; 11918 case OPC_PRECRQ_RS_QH_PW: 11919 check_dsp(ctx); 11920 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11921 break; 11922 case OPC_PRECRQU_S_OB_QH: 11923 check_dsp(ctx); 11924 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11925 break; 11926 } 11927 break; 11928 #endif 11929 } 11930 } 11931 11932 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11933 int ret, int v1, int v2) 11934 { 11935 uint32_t op2; 11936 TCGv t0; 11937 TCGv v1_t; 11938 TCGv v2_t; 11939 11940 if (ret == 0) { 11941 /* Treat as NOP. */ 11942 return; 11943 } 11944 11945 t0 = tcg_temp_new(); 11946 v1_t = tcg_temp_new(); 11947 v2_t = tcg_temp_new(); 11948 11949 tcg_gen_movi_tl(t0, v1); 11950 gen_load_gpr(v1_t, v1); 11951 gen_load_gpr(v2_t, v2); 11952 11953 switch (opc) { 11954 case OPC_SHLL_QB_DSP: 11955 { 11956 op2 = MASK_SHLL_QB(ctx->opcode); 11957 switch (op2) { 11958 case OPC_SHLL_QB: 11959 check_dsp(ctx); 11960 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11961 break; 11962 case OPC_SHLLV_QB: 11963 check_dsp(ctx); 11964 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11965 break; 11966 case OPC_SHLL_PH: 11967 check_dsp(ctx); 11968 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11969 break; 11970 case OPC_SHLLV_PH: 11971 check_dsp(ctx); 11972 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11973 break; 11974 case OPC_SHLL_S_PH: 11975 check_dsp(ctx); 11976 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11977 break; 11978 case OPC_SHLLV_S_PH: 11979 check_dsp(ctx); 11980 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11981 break; 11982 case OPC_SHLL_S_W: 11983 check_dsp(ctx); 11984 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11985 break; 11986 case OPC_SHLLV_S_W: 11987 check_dsp(ctx); 11988 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11989 break; 11990 case OPC_SHRL_QB: 11991 check_dsp(ctx); 11992 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11993 break; 11994 case OPC_SHRLV_QB: 11995 check_dsp(ctx); 11996 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11997 break; 11998 case OPC_SHRL_PH: 11999 check_dsp_r2(ctx); 12000 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12001 break; 12002 case OPC_SHRLV_PH: 12003 check_dsp_r2(ctx); 12004 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12005 break; 12006 case OPC_SHRA_QB: 12007 check_dsp_r2(ctx); 12008 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12009 break; 12010 case OPC_SHRA_R_QB: 12011 check_dsp_r2(ctx); 12012 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12013 break; 12014 case OPC_SHRAV_QB: 12015 check_dsp_r2(ctx); 12016 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12017 break; 12018 case OPC_SHRAV_R_QB: 12019 check_dsp_r2(ctx); 12020 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12021 break; 12022 case OPC_SHRA_PH: 12023 check_dsp(ctx); 12024 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12025 break; 12026 case OPC_SHRA_R_PH: 12027 check_dsp(ctx); 12028 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12029 break; 12030 case OPC_SHRAV_PH: 12031 check_dsp(ctx); 12032 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12033 break; 12034 case OPC_SHRAV_R_PH: 12035 check_dsp(ctx); 12036 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12037 break; 12038 case OPC_SHRA_R_W: 12039 check_dsp(ctx); 12040 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12041 break; 12042 case OPC_SHRAV_R_W: 12043 check_dsp(ctx); 12044 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12045 break; 12046 default: /* Invalid */ 12047 MIPS_INVAL("MASK SHLL.QB"); 12048 gen_reserved_instruction(ctx); 12049 break; 12050 } 12051 break; 12052 } 12053 #ifdef TARGET_MIPS64 12054 case OPC_SHLL_OB_DSP: 12055 op2 = MASK_SHLL_OB(ctx->opcode); 12056 switch (op2) { 12057 case OPC_SHLL_PW: 12058 check_dsp(ctx); 12059 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 12060 break; 12061 case OPC_SHLLV_PW: 12062 check_dsp(ctx); 12063 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12064 break; 12065 case OPC_SHLL_S_PW: 12066 check_dsp(ctx); 12067 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 12068 break; 12069 case OPC_SHLLV_S_PW: 12070 check_dsp(ctx); 12071 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12072 break; 12073 case OPC_SHLL_OB: 12074 check_dsp(ctx); 12075 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 12076 break; 12077 case OPC_SHLLV_OB: 12078 check_dsp(ctx); 12079 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12080 break; 12081 case OPC_SHLL_QH: 12082 check_dsp(ctx); 12083 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 12084 break; 12085 case OPC_SHLLV_QH: 12086 check_dsp(ctx); 12087 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12088 break; 12089 case OPC_SHLL_S_QH: 12090 check_dsp(ctx); 12091 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 12092 break; 12093 case OPC_SHLLV_S_QH: 12094 check_dsp(ctx); 12095 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12096 break; 12097 case OPC_SHRA_OB: 12098 check_dsp_r2(ctx); 12099 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12100 break; 12101 case OPC_SHRAV_OB: 12102 check_dsp_r2(ctx); 12103 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12104 break; 12105 case OPC_SHRA_R_OB: 12106 check_dsp_r2(ctx); 12107 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12108 break; 12109 case OPC_SHRAV_R_OB: 12110 check_dsp_r2(ctx); 12111 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12112 break; 12113 case OPC_SHRA_PW: 12114 check_dsp(ctx); 12115 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12116 break; 12117 case OPC_SHRAV_PW: 12118 check_dsp(ctx); 12119 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12120 break; 12121 case OPC_SHRA_R_PW: 12122 check_dsp(ctx); 12123 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12124 break; 12125 case OPC_SHRAV_R_PW: 12126 check_dsp(ctx); 12127 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12128 break; 12129 case OPC_SHRA_QH: 12130 check_dsp(ctx); 12131 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12132 break; 12133 case OPC_SHRAV_QH: 12134 check_dsp(ctx); 12135 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12136 break; 12137 case OPC_SHRA_R_QH: 12138 check_dsp(ctx); 12139 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12140 break; 12141 case OPC_SHRAV_R_QH: 12142 check_dsp(ctx); 12143 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12144 break; 12145 case OPC_SHRL_OB: 12146 check_dsp(ctx); 12147 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12148 break; 12149 case OPC_SHRLV_OB: 12150 check_dsp(ctx); 12151 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12152 break; 12153 case OPC_SHRL_QH: 12154 check_dsp_r2(ctx); 12155 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12156 break; 12157 case OPC_SHRLV_QH: 12158 check_dsp_r2(ctx); 12159 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12160 break; 12161 default: /* Invalid */ 12162 MIPS_INVAL("MASK SHLL.OB"); 12163 gen_reserved_instruction(ctx); 12164 break; 12165 } 12166 break; 12167 #endif 12168 } 12169 } 12170 12171 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12172 int ret, int v1, int v2, int check_ret) 12173 { 12174 TCGv_i32 t0; 12175 TCGv v1_t; 12176 TCGv v2_t; 12177 12178 if ((ret == 0) && (check_ret == 1)) { 12179 /* Treat as NOP. */ 12180 return; 12181 } 12182 12183 t0 = tcg_temp_new_i32(); 12184 v1_t = tcg_temp_new(); 12185 v2_t = tcg_temp_new(); 12186 12187 tcg_gen_movi_i32(t0, ret); 12188 gen_load_gpr(v1_t, v1); 12189 gen_load_gpr(v2_t, v2); 12190 12191 switch (op1) { 12192 case OPC_MUL_PH_DSP: 12193 check_dsp_r2(ctx); 12194 switch (op2) { 12195 case OPC_MUL_PH: 12196 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12197 break; 12198 case OPC_MUL_S_PH: 12199 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12200 break; 12201 case OPC_MULQ_S_W: 12202 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12203 break; 12204 case OPC_MULQ_RS_W: 12205 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12206 break; 12207 } 12208 break; 12209 case OPC_DPA_W_PH_DSP: 12210 switch (op2) { 12211 case OPC_DPAU_H_QBL: 12212 check_dsp(ctx); 12213 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12214 break; 12215 case OPC_DPAU_H_QBR: 12216 check_dsp(ctx); 12217 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12218 break; 12219 case OPC_DPSU_H_QBL: 12220 check_dsp(ctx); 12221 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12222 break; 12223 case OPC_DPSU_H_QBR: 12224 check_dsp(ctx); 12225 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12226 break; 12227 case OPC_DPA_W_PH: 12228 check_dsp_r2(ctx); 12229 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12230 break; 12231 case OPC_DPAX_W_PH: 12232 check_dsp_r2(ctx); 12233 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12234 break; 12235 case OPC_DPAQ_S_W_PH: 12236 check_dsp(ctx); 12237 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12238 break; 12239 case OPC_DPAQX_S_W_PH: 12240 check_dsp_r2(ctx); 12241 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12242 break; 12243 case OPC_DPAQX_SA_W_PH: 12244 check_dsp_r2(ctx); 12245 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12246 break; 12247 case OPC_DPS_W_PH: 12248 check_dsp_r2(ctx); 12249 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12250 break; 12251 case OPC_DPSX_W_PH: 12252 check_dsp_r2(ctx); 12253 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12254 break; 12255 case OPC_DPSQ_S_W_PH: 12256 check_dsp(ctx); 12257 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12258 break; 12259 case OPC_DPSQX_S_W_PH: 12260 check_dsp_r2(ctx); 12261 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12262 break; 12263 case OPC_DPSQX_SA_W_PH: 12264 check_dsp_r2(ctx); 12265 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12266 break; 12267 case OPC_MULSAQ_S_W_PH: 12268 check_dsp(ctx); 12269 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12270 break; 12271 case OPC_DPAQ_SA_L_W: 12272 check_dsp(ctx); 12273 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12274 break; 12275 case OPC_DPSQ_SA_L_W: 12276 check_dsp(ctx); 12277 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12278 break; 12279 case OPC_MAQ_S_W_PHL: 12280 check_dsp(ctx); 12281 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12282 break; 12283 case OPC_MAQ_S_W_PHR: 12284 check_dsp(ctx); 12285 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12286 break; 12287 case OPC_MAQ_SA_W_PHL: 12288 check_dsp(ctx); 12289 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12290 break; 12291 case OPC_MAQ_SA_W_PHR: 12292 check_dsp(ctx); 12293 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12294 break; 12295 case OPC_MULSA_W_PH: 12296 check_dsp_r2(ctx); 12297 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12298 break; 12299 } 12300 break; 12301 #ifdef TARGET_MIPS64 12302 case OPC_DPAQ_W_QH_DSP: 12303 { 12304 int ac = ret & 0x03; 12305 tcg_gen_movi_i32(t0, ac); 12306 12307 switch (op2) { 12308 case OPC_DMADD: 12309 check_dsp(ctx); 12310 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12311 break; 12312 case OPC_DMADDU: 12313 check_dsp(ctx); 12314 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12315 break; 12316 case OPC_DMSUB: 12317 check_dsp(ctx); 12318 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12319 break; 12320 case OPC_DMSUBU: 12321 check_dsp(ctx); 12322 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12323 break; 12324 case OPC_DPA_W_QH: 12325 check_dsp_r2(ctx); 12326 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12327 break; 12328 case OPC_DPAQ_S_W_QH: 12329 check_dsp(ctx); 12330 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12331 break; 12332 case OPC_DPAQ_SA_L_PW: 12333 check_dsp(ctx); 12334 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12335 break; 12336 case OPC_DPAU_H_OBL: 12337 check_dsp(ctx); 12338 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12339 break; 12340 case OPC_DPAU_H_OBR: 12341 check_dsp(ctx); 12342 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12343 break; 12344 case OPC_DPS_W_QH: 12345 check_dsp_r2(ctx); 12346 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12347 break; 12348 case OPC_DPSQ_S_W_QH: 12349 check_dsp(ctx); 12350 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12351 break; 12352 case OPC_DPSQ_SA_L_PW: 12353 check_dsp(ctx); 12354 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12355 break; 12356 case OPC_DPSU_H_OBL: 12357 check_dsp(ctx); 12358 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12359 break; 12360 case OPC_DPSU_H_OBR: 12361 check_dsp(ctx); 12362 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12363 break; 12364 case OPC_MAQ_S_L_PWL: 12365 check_dsp(ctx); 12366 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12367 break; 12368 case OPC_MAQ_S_L_PWR: 12369 check_dsp(ctx); 12370 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12371 break; 12372 case OPC_MAQ_S_W_QHLL: 12373 check_dsp(ctx); 12374 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12375 break; 12376 case OPC_MAQ_SA_W_QHLL: 12377 check_dsp(ctx); 12378 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12379 break; 12380 case OPC_MAQ_S_W_QHLR: 12381 check_dsp(ctx); 12382 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12383 break; 12384 case OPC_MAQ_SA_W_QHLR: 12385 check_dsp(ctx); 12386 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12387 break; 12388 case OPC_MAQ_S_W_QHRL: 12389 check_dsp(ctx); 12390 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12391 break; 12392 case OPC_MAQ_SA_W_QHRL: 12393 check_dsp(ctx); 12394 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12395 break; 12396 case OPC_MAQ_S_W_QHRR: 12397 check_dsp(ctx); 12398 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12399 break; 12400 case OPC_MAQ_SA_W_QHRR: 12401 check_dsp(ctx); 12402 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12403 break; 12404 case OPC_MULSAQ_S_L_PW: 12405 check_dsp(ctx); 12406 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12407 break; 12408 case OPC_MULSAQ_S_W_QH: 12409 check_dsp(ctx); 12410 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12411 break; 12412 } 12413 } 12414 break; 12415 #endif 12416 case OPC_ADDU_QB_DSP: 12417 switch (op2) { 12418 case OPC_MULEU_S_PH_QBL: 12419 check_dsp(ctx); 12420 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12421 break; 12422 case OPC_MULEU_S_PH_QBR: 12423 check_dsp(ctx); 12424 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12425 break; 12426 case OPC_MULQ_RS_PH: 12427 check_dsp(ctx); 12428 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12429 break; 12430 case OPC_MULEQ_S_W_PHL: 12431 check_dsp(ctx); 12432 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12433 break; 12434 case OPC_MULEQ_S_W_PHR: 12435 check_dsp(ctx); 12436 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12437 break; 12438 case OPC_MULQ_S_PH: 12439 check_dsp_r2(ctx); 12440 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12441 break; 12442 } 12443 break; 12444 #ifdef TARGET_MIPS64 12445 case OPC_ADDU_OB_DSP: 12446 switch (op2) { 12447 case OPC_MULEQ_S_PW_QHL: 12448 check_dsp(ctx); 12449 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12450 break; 12451 case OPC_MULEQ_S_PW_QHR: 12452 check_dsp(ctx); 12453 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12454 break; 12455 case OPC_MULEU_S_QH_OBL: 12456 check_dsp(ctx); 12457 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12458 break; 12459 case OPC_MULEU_S_QH_OBR: 12460 check_dsp(ctx); 12461 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12462 break; 12463 case OPC_MULQ_RS_QH: 12464 check_dsp(ctx); 12465 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12466 break; 12467 } 12468 break; 12469 #endif 12470 } 12471 } 12472 12473 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12474 int ret, int val) 12475 { 12476 int16_t imm; 12477 TCGv t0; 12478 TCGv val_t; 12479 12480 if (ret == 0) { 12481 /* Treat as NOP. */ 12482 return; 12483 } 12484 12485 t0 = tcg_temp_new(); 12486 val_t = tcg_temp_new(); 12487 gen_load_gpr(val_t, val); 12488 12489 switch (op1) { 12490 case OPC_ABSQ_S_PH_DSP: 12491 switch (op2) { 12492 case OPC_BITREV: 12493 check_dsp(ctx); 12494 gen_helper_bitrev(cpu_gpr[ret], val_t); 12495 break; 12496 case OPC_REPL_QB: 12497 check_dsp(ctx); 12498 { 12499 target_long result; 12500 imm = (ctx->opcode >> 16) & 0xFF; 12501 result = (uint32_t)imm << 24 | 12502 (uint32_t)imm << 16 | 12503 (uint32_t)imm << 8 | 12504 (uint32_t)imm; 12505 result = (int32_t)result; 12506 tcg_gen_movi_tl(cpu_gpr[ret], result); 12507 } 12508 break; 12509 case OPC_REPLV_QB: 12510 check_dsp(ctx); 12511 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12512 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12513 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12514 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12515 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12516 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12517 break; 12518 case OPC_REPL_PH: 12519 check_dsp(ctx); 12520 { 12521 imm = (ctx->opcode >> 16) & 0x03FF; 12522 imm = (int16_t)(imm << 6) >> 6; 12523 tcg_gen_movi_tl(cpu_gpr[ret], \ 12524 (target_long)((int32_t)imm << 16 | \ 12525 (uint16_t)imm)); 12526 } 12527 break; 12528 case OPC_REPLV_PH: 12529 check_dsp(ctx); 12530 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12531 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12532 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12533 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12534 break; 12535 } 12536 break; 12537 #ifdef TARGET_MIPS64 12538 case OPC_ABSQ_S_QH_DSP: 12539 switch (op2) { 12540 case OPC_REPL_OB: 12541 check_dsp(ctx); 12542 { 12543 target_long temp; 12544 12545 imm = (ctx->opcode >> 16) & 0xFF; 12546 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12547 temp = (temp << 16) | temp; 12548 temp = (temp << 32) | temp; 12549 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12550 break; 12551 } 12552 case OPC_REPL_PW: 12553 check_dsp(ctx); 12554 { 12555 target_long temp; 12556 12557 imm = (ctx->opcode >> 16) & 0x03FF; 12558 imm = (int16_t)(imm << 6) >> 6; 12559 temp = ((target_long)imm << 32) \ 12560 | ((target_long)imm & 0xFFFFFFFF); 12561 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12562 break; 12563 } 12564 case OPC_REPL_QH: 12565 check_dsp(ctx); 12566 { 12567 target_long temp; 12568 12569 imm = (ctx->opcode >> 16) & 0x03FF; 12570 imm = (int16_t)(imm << 6) >> 6; 12571 12572 temp = ((uint64_t)(uint16_t)imm << 48) | 12573 ((uint64_t)(uint16_t)imm << 32) | 12574 ((uint64_t)(uint16_t)imm << 16) | 12575 (uint64_t)(uint16_t)imm; 12576 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12577 break; 12578 } 12579 case OPC_REPLV_OB: 12580 check_dsp(ctx); 12581 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12582 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12583 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12584 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12585 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12586 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12587 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12588 break; 12589 case OPC_REPLV_PW: 12590 check_dsp(ctx); 12591 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12592 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12593 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12594 break; 12595 case OPC_REPLV_QH: 12596 check_dsp(ctx); 12597 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12598 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12599 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12600 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12601 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12602 break; 12603 } 12604 break; 12605 #endif 12606 } 12607 } 12608 12609 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12610 uint32_t op1, uint32_t op2, 12611 int ret, int v1, int v2, int check_ret) 12612 { 12613 TCGv t1; 12614 TCGv v1_t; 12615 TCGv v2_t; 12616 12617 if ((ret == 0) && (check_ret == 1)) { 12618 /* Treat as NOP. */ 12619 return; 12620 } 12621 12622 t1 = tcg_temp_new(); 12623 v1_t = tcg_temp_new(); 12624 v2_t = tcg_temp_new(); 12625 12626 gen_load_gpr(v1_t, v1); 12627 gen_load_gpr(v2_t, v2); 12628 12629 switch (op1) { 12630 case OPC_CMPU_EQ_QB_DSP: 12631 switch (op2) { 12632 case OPC_CMPU_EQ_QB: 12633 check_dsp(ctx); 12634 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12635 break; 12636 case OPC_CMPU_LT_QB: 12637 check_dsp(ctx); 12638 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12639 break; 12640 case OPC_CMPU_LE_QB: 12641 check_dsp(ctx); 12642 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12643 break; 12644 case OPC_CMPGU_EQ_QB: 12645 check_dsp(ctx); 12646 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12647 break; 12648 case OPC_CMPGU_LT_QB: 12649 check_dsp(ctx); 12650 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12651 break; 12652 case OPC_CMPGU_LE_QB: 12653 check_dsp(ctx); 12654 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12655 break; 12656 case OPC_CMPGDU_EQ_QB: 12657 check_dsp_r2(ctx); 12658 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12659 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12660 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12661 tcg_gen_shli_tl(t1, t1, 24); 12662 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12663 break; 12664 case OPC_CMPGDU_LT_QB: 12665 check_dsp_r2(ctx); 12666 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12667 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12668 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12669 tcg_gen_shli_tl(t1, t1, 24); 12670 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12671 break; 12672 case OPC_CMPGDU_LE_QB: 12673 check_dsp_r2(ctx); 12674 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12675 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12676 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12677 tcg_gen_shli_tl(t1, t1, 24); 12678 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12679 break; 12680 case OPC_CMP_EQ_PH: 12681 check_dsp(ctx); 12682 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12683 break; 12684 case OPC_CMP_LT_PH: 12685 check_dsp(ctx); 12686 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12687 break; 12688 case OPC_CMP_LE_PH: 12689 check_dsp(ctx); 12690 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12691 break; 12692 case OPC_PICK_QB: 12693 check_dsp(ctx); 12694 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12695 break; 12696 case OPC_PICK_PH: 12697 check_dsp(ctx); 12698 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12699 break; 12700 case OPC_PACKRL_PH: 12701 check_dsp(ctx); 12702 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12703 break; 12704 } 12705 break; 12706 #ifdef TARGET_MIPS64 12707 case OPC_CMPU_EQ_OB_DSP: 12708 switch (op2) { 12709 case OPC_CMP_EQ_PW: 12710 check_dsp(ctx); 12711 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12712 break; 12713 case OPC_CMP_LT_PW: 12714 check_dsp(ctx); 12715 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12716 break; 12717 case OPC_CMP_LE_PW: 12718 check_dsp(ctx); 12719 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12720 break; 12721 case OPC_CMP_EQ_QH: 12722 check_dsp(ctx); 12723 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12724 break; 12725 case OPC_CMP_LT_QH: 12726 check_dsp(ctx); 12727 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12728 break; 12729 case OPC_CMP_LE_QH: 12730 check_dsp(ctx); 12731 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12732 break; 12733 case OPC_CMPGDU_EQ_OB: 12734 check_dsp_r2(ctx); 12735 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12736 break; 12737 case OPC_CMPGDU_LT_OB: 12738 check_dsp_r2(ctx); 12739 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12740 break; 12741 case OPC_CMPGDU_LE_OB: 12742 check_dsp_r2(ctx); 12743 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12744 break; 12745 case OPC_CMPGU_EQ_OB: 12746 check_dsp(ctx); 12747 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12748 break; 12749 case OPC_CMPGU_LT_OB: 12750 check_dsp(ctx); 12751 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12752 break; 12753 case OPC_CMPGU_LE_OB: 12754 check_dsp(ctx); 12755 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12756 break; 12757 case OPC_CMPU_EQ_OB: 12758 check_dsp(ctx); 12759 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12760 break; 12761 case OPC_CMPU_LT_OB: 12762 check_dsp(ctx); 12763 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12764 break; 12765 case OPC_CMPU_LE_OB: 12766 check_dsp(ctx); 12767 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12768 break; 12769 case OPC_PACKRL_PW: 12770 check_dsp(ctx); 12771 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12772 break; 12773 case OPC_PICK_OB: 12774 check_dsp(ctx); 12775 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12776 break; 12777 case OPC_PICK_PW: 12778 check_dsp(ctx); 12779 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12780 break; 12781 case OPC_PICK_QH: 12782 check_dsp(ctx); 12783 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12784 break; 12785 } 12786 break; 12787 #endif 12788 } 12789 } 12790 12791 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12792 uint32_t op1, int rt, int rs, int sa) 12793 { 12794 TCGv t0; 12795 12796 check_dsp_r2(ctx); 12797 12798 if (rt == 0) { 12799 /* Treat as NOP. */ 12800 return; 12801 } 12802 12803 t0 = tcg_temp_new(); 12804 gen_load_gpr(t0, rs); 12805 12806 switch (op1) { 12807 case OPC_APPEND_DSP: 12808 switch (MASK_APPEND(ctx->opcode)) { 12809 case OPC_APPEND: 12810 if (sa != 0) { 12811 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12812 } 12813 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12814 break; 12815 case OPC_PREPEND: 12816 if (sa != 0) { 12817 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12818 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12819 tcg_gen_shli_tl(t0, t0, 32 - sa); 12820 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12821 } 12822 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12823 break; 12824 case OPC_BALIGN: 12825 sa &= 3; 12826 if (sa != 0 && sa != 2) { 12827 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12828 tcg_gen_ext32u_tl(t0, t0); 12829 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12830 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12831 } 12832 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12833 break; 12834 default: /* Invalid */ 12835 MIPS_INVAL("MASK APPEND"); 12836 gen_reserved_instruction(ctx); 12837 break; 12838 } 12839 break; 12840 #ifdef TARGET_MIPS64 12841 case OPC_DAPPEND_DSP: 12842 switch (MASK_DAPPEND(ctx->opcode)) { 12843 case OPC_DAPPEND: 12844 if (sa != 0) { 12845 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12846 } 12847 break; 12848 case OPC_PREPENDD: 12849 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12850 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12851 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12852 break; 12853 case OPC_PREPENDW: 12854 if (sa != 0) { 12855 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12856 tcg_gen_shli_tl(t0, t0, 64 - sa); 12857 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12858 } 12859 break; 12860 case OPC_DBALIGN: 12861 sa &= 7; 12862 if (sa != 0 && sa != 2 && sa != 4) { 12863 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12864 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12865 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12866 } 12867 break; 12868 default: /* Invalid */ 12869 MIPS_INVAL("MASK DAPPEND"); 12870 gen_reserved_instruction(ctx); 12871 break; 12872 } 12873 break; 12874 #endif 12875 } 12876 } 12877 12878 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12879 int ret, int v1, int v2, int check_ret) 12880 12881 { 12882 TCGv t0; 12883 TCGv t1; 12884 TCGv v1_t; 12885 int16_t imm; 12886 12887 if ((ret == 0) && (check_ret == 1)) { 12888 /* Treat as NOP. */ 12889 return; 12890 } 12891 12892 t0 = tcg_temp_new(); 12893 t1 = tcg_temp_new(); 12894 v1_t = tcg_temp_new(); 12895 12896 gen_load_gpr(v1_t, v1); 12897 12898 switch (op1) { 12899 case OPC_EXTR_W_DSP: 12900 check_dsp(ctx); 12901 switch (op2) { 12902 case OPC_EXTR_W: 12903 tcg_gen_movi_tl(t0, v2); 12904 tcg_gen_movi_tl(t1, v1); 12905 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12906 break; 12907 case OPC_EXTR_R_W: 12908 tcg_gen_movi_tl(t0, v2); 12909 tcg_gen_movi_tl(t1, v1); 12910 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12911 break; 12912 case OPC_EXTR_RS_W: 12913 tcg_gen_movi_tl(t0, v2); 12914 tcg_gen_movi_tl(t1, v1); 12915 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12916 break; 12917 case OPC_EXTR_S_H: 12918 tcg_gen_movi_tl(t0, v2); 12919 tcg_gen_movi_tl(t1, v1); 12920 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12921 break; 12922 case OPC_EXTRV_S_H: 12923 tcg_gen_movi_tl(t0, v2); 12924 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12925 break; 12926 case OPC_EXTRV_W: 12927 tcg_gen_movi_tl(t0, v2); 12928 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12929 break; 12930 case OPC_EXTRV_R_W: 12931 tcg_gen_movi_tl(t0, v2); 12932 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12933 break; 12934 case OPC_EXTRV_RS_W: 12935 tcg_gen_movi_tl(t0, v2); 12936 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12937 break; 12938 case OPC_EXTP: 12939 tcg_gen_movi_tl(t0, v2); 12940 tcg_gen_movi_tl(t1, v1); 12941 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12942 break; 12943 case OPC_EXTPV: 12944 tcg_gen_movi_tl(t0, v2); 12945 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12946 break; 12947 case OPC_EXTPDP: 12948 tcg_gen_movi_tl(t0, v2); 12949 tcg_gen_movi_tl(t1, v1); 12950 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12951 break; 12952 case OPC_EXTPDPV: 12953 tcg_gen_movi_tl(t0, v2); 12954 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12955 break; 12956 case OPC_SHILO: 12957 imm = (ctx->opcode >> 20) & 0x3F; 12958 tcg_gen_movi_tl(t0, ret); 12959 tcg_gen_movi_tl(t1, imm); 12960 gen_helper_shilo(t0, t1, tcg_env); 12961 break; 12962 case OPC_SHILOV: 12963 tcg_gen_movi_tl(t0, ret); 12964 gen_helper_shilo(t0, v1_t, tcg_env); 12965 break; 12966 case OPC_MTHLIP: 12967 tcg_gen_movi_tl(t0, ret); 12968 gen_helper_mthlip(t0, v1_t, tcg_env); 12969 break; 12970 case OPC_WRDSP: 12971 imm = (ctx->opcode >> 11) & 0x3FF; 12972 tcg_gen_movi_tl(t0, imm); 12973 gen_helper_wrdsp(v1_t, t0, tcg_env); 12974 break; 12975 case OPC_RDDSP: 12976 imm = (ctx->opcode >> 16) & 0x03FF; 12977 tcg_gen_movi_tl(t0, imm); 12978 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12979 break; 12980 } 12981 break; 12982 #ifdef TARGET_MIPS64 12983 case OPC_DEXTR_W_DSP: 12984 check_dsp(ctx); 12985 switch (op2) { 12986 case OPC_DMTHLIP: 12987 tcg_gen_movi_tl(t0, ret); 12988 gen_helper_dmthlip(v1_t, t0, tcg_env); 12989 break; 12990 case OPC_DSHILO: 12991 { 12992 int shift = (ctx->opcode >> 19) & 0x7F; 12993 int ac = (ctx->opcode >> 11) & 0x03; 12994 tcg_gen_movi_tl(t0, shift); 12995 tcg_gen_movi_tl(t1, ac); 12996 gen_helper_dshilo(t0, t1, tcg_env); 12997 break; 12998 } 12999 case OPC_DSHILOV: 13000 { 13001 int ac = (ctx->opcode >> 11) & 0x03; 13002 tcg_gen_movi_tl(t0, ac); 13003 gen_helper_dshilo(v1_t, t0, tcg_env); 13004 break; 13005 } 13006 case OPC_DEXTP: 13007 tcg_gen_movi_tl(t0, v2); 13008 tcg_gen_movi_tl(t1, v1); 13009 13010 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 13011 break; 13012 case OPC_DEXTPV: 13013 tcg_gen_movi_tl(t0, v2); 13014 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 13015 break; 13016 case OPC_DEXTPDP: 13017 tcg_gen_movi_tl(t0, v2); 13018 tcg_gen_movi_tl(t1, v1); 13019 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 13020 break; 13021 case OPC_DEXTPDPV: 13022 tcg_gen_movi_tl(t0, v2); 13023 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 13024 break; 13025 case OPC_DEXTR_L: 13026 tcg_gen_movi_tl(t0, v2); 13027 tcg_gen_movi_tl(t1, v1); 13028 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 13029 break; 13030 case OPC_DEXTR_R_L: 13031 tcg_gen_movi_tl(t0, v2); 13032 tcg_gen_movi_tl(t1, v1); 13033 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 13034 break; 13035 case OPC_DEXTR_RS_L: 13036 tcg_gen_movi_tl(t0, v2); 13037 tcg_gen_movi_tl(t1, v1); 13038 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 13039 break; 13040 case OPC_DEXTR_W: 13041 tcg_gen_movi_tl(t0, v2); 13042 tcg_gen_movi_tl(t1, v1); 13043 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 13044 break; 13045 case OPC_DEXTR_R_W: 13046 tcg_gen_movi_tl(t0, v2); 13047 tcg_gen_movi_tl(t1, v1); 13048 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 13049 break; 13050 case OPC_DEXTR_RS_W: 13051 tcg_gen_movi_tl(t0, v2); 13052 tcg_gen_movi_tl(t1, v1); 13053 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 13054 break; 13055 case OPC_DEXTR_S_H: 13056 tcg_gen_movi_tl(t0, v2); 13057 tcg_gen_movi_tl(t1, v1); 13058 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 13059 break; 13060 case OPC_DEXTRV_S_H: 13061 tcg_gen_movi_tl(t0, v2); 13062 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 13063 break; 13064 case OPC_DEXTRV_L: 13065 tcg_gen_movi_tl(t0, v2); 13066 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 13067 break; 13068 case OPC_DEXTRV_R_L: 13069 tcg_gen_movi_tl(t0, v2); 13070 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 13071 break; 13072 case OPC_DEXTRV_RS_L: 13073 tcg_gen_movi_tl(t0, v2); 13074 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 13075 break; 13076 case OPC_DEXTRV_W: 13077 tcg_gen_movi_tl(t0, v2); 13078 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13079 break; 13080 case OPC_DEXTRV_R_W: 13081 tcg_gen_movi_tl(t0, v2); 13082 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13083 break; 13084 case OPC_DEXTRV_RS_W: 13085 tcg_gen_movi_tl(t0, v2); 13086 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13087 break; 13088 } 13089 break; 13090 #endif 13091 } 13092 } 13093 13094 /* End MIPSDSP functions. */ 13095 13096 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13097 { 13098 int rs, rt, rd, sa; 13099 uint32_t op1, op2; 13100 13101 rs = (ctx->opcode >> 21) & 0x1f; 13102 rt = (ctx->opcode >> 16) & 0x1f; 13103 rd = (ctx->opcode >> 11) & 0x1f; 13104 sa = (ctx->opcode >> 6) & 0x1f; 13105 13106 op1 = MASK_SPECIAL(ctx->opcode); 13107 switch (op1) { 13108 case OPC_MULT: 13109 case OPC_MULTU: 13110 case OPC_DIV: 13111 case OPC_DIVU: 13112 op2 = MASK_R6_MULDIV(ctx->opcode); 13113 switch (op2) { 13114 case R6_OPC_MUL: 13115 case R6_OPC_MUH: 13116 case R6_OPC_MULU: 13117 case R6_OPC_MUHU: 13118 case R6_OPC_DIV: 13119 case R6_OPC_MOD: 13120 case R6_OPC_DIVU: 13121 case R6_OPC_MODU: 13122 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13123 break; 13124 default: 13125 MIPS_INVAL("special_r6 muldiv"); 13126 gen_reserved_instruction(ctx); 13127 break; 13128 } 13129 break; 13130 case OPC_SELEQZ: 13131 case OPC_SELNEZ: 13132 gen_cond_move(ctx, op1, rd, rs, rt); 13133 break; 13134 case R6_OPC_CLO: 13135 case R6_OPC_CLZ: 13136 if (rt == 0 && sa == 1) { 13137 /* 13138 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13139 * We need additionally to check other fields. 13140 */ 13141 gen_cl(ctx, op1, rd, rs); 13142 } else { 13143 gen_reserved_instruction(ctx); 13144 } 13145 break; 13146 case R6_OPC_SDBBP: 13147 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13148 ctx->base.is_jmp = DISAS_SEMIHOST; 13149 } else { 13150 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13151 gen_reserved_instruction(ctx); 13152 } else { 13153 generate_exception_end(ctx, EXCP_DBp); 13154 } 13155 } 13156 break; 13157 #if defined(TARGET_MIPS64) 13158 case R6_OPC_DCLO: 13159 case R6_OPC_DCLZ: 13160 if (rt == 0 && sa == 1) { 13161 /* 13162 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13163 * We need additionally to check other fields. 13164 */ 13165 check_mips_64(ctx); 13166 gen_cl(ctx, op1, rd, rs); 13167 } else { 13168 gen_reserved_instruction(ctx); 13169 } 13170 break; 13171 case OPC_DMULT: 13172 case OPC_DMULTU: 13173 case OPC_DDIV: 13174 case OPC_DDIVU: 13175 13176 op2 = MASK_R6_MULDIV(ctx->opcode); 13177 switch (op2) { 13178 case R6_OPC_DMUL: 13179 case R6_OPC_DMUH: 13180 case R6_OPC_DMULU: 13181 case R6_OPC_DMUHU: 13182 case R6_OPC_DDIV: 13183 case R6_OPC_DMOD: 13184 case R6_OPC_DDIVU: 13185 case R6_OPC_DMODU: 13186 check_mips_64(ctx); 13187 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13188 break; 13189 default: 13190 MIPS_INVAL("special_r6 muldiv"); 13191 gen_reserved_instruction(ctx); 13192 break; 13193 } 13194 break; 13195 #endif 13196 default: /* Invalid */ 13197 MIPS_INVAL("special_r6"); 13198 gen_reserved_instruction(ctx); 13199 break; 13200 } 13201 } 13202 13203 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13204 { 13205 int rs = extract32(ctx->opcode, 21, 5); 13206 int rt = extract32(ctx->opcode, 16, 5); 13207 int rd = extract32(ctx->opcode, 11, 5); 13208 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13209 13210 switch (op1) { 13211 case OPC_MOVN: /* Conditional move */ 13212 case OPC_MOVZ: 13213 gen_cond_move(ctx, op1, rd, rs, rt); 13214 break; 13215 case OPC_MFHI: /* Move from HI/LO */ 13216 case OPC_MFLO: 13217 gen_HILO(ctx, op1, 0, rd); 13218 break; 13219 case OPC_MTHI: 13220 case OPC_MTLO: /* Move to HI/LO */ 13221 gen_HILO(ctx, op1, 0, rs); 13222 break; 13223 case OPC_MULT: 13224 case OPC_MULTU: 13225 gen_mul_txx9(ctx, op1, rd, rs, rt); 13226 break; 13227 case OPC_DIV: 13228 case OPC_DIVU: 13229 gen_muldiv(ctx, op1, 0, rs, rt); 13230 break; 13231 #if defined(TARGET_MIPS64) 13232 case OPC_DMULT: 13233 case OPC_DMULTU: 13234 case OPC_DDIV: 13235 case OPC_DDIVU: 13236 check_insn_opc_user_only(ctx, INSN_R5900); 13237 gen_muldiv(ctx, op1, 0, rs, rt); 13238 break; 13239 #endif 13240 case OPC_JR: 13241 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13242 break; 13243 default: /* Invalid */ 13244 MIPS_INVAL("special_tx79"); 13245 gen_reserved_instruction(ctx); 13246 break; 13247 } 13248 } 13249 13250 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13251 { 13252 int rs, rt, rd; 13253 uint32_t op1; 13254 13255 rs = (ctx->opcode >> 21) & 0x1f; 13256 rt = (ctx->opcode >> 16) & 0x1f; 13257 rd = (ctx->opcode >> 11) & 0x1f; 13258 13259 op1 = MASK_SPECIAL(ctx->opcode); 13260 switch (op1) { 13261 case OPC_MOVN: /* Conditional move */ 13262 case OPC_MOVZ: 13263 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13264 INSN_LOONGSON2E | INSN_LOONGSON2F); 13265 gen_cond_move(ctx, op1, rd, rs, rt); 13266 break; 13267 case OPC_MFHI: /* Move from HI/LO */ 13268 case OPC_MFLO: 13269 gen_HILO(ctx, op1, rs & 3, rd); 13270 break; 13271 case OPC_MTHI: 13272 case OPC_MTLO: /* Move to HI/LO */ 13273 gen_HILO(ctx, op1, rd & 3, rs); 13274 break; 13275 case OPC_MOVCI: 13276 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13277 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13278 check_cp1_enabled(ctx); 13279 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13280 (ctx->opcode >> 16) & 1); 13281 } else { 13282 generate_exception_err(ctx, EXCP_CpU, 1); 13283 } 13284 break; 13285 case OPC_MULT: 13286 case OPC_MULTU: 13287 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13288 break; 13289 case OPC_DIV: 13290 case OPC_DIVU: 13291 gen_muldiv(ctx, op1, 0, rs, rt); 13292 break; 13293 #if defined(TARGET_MIPS64) 13294 case OPC_DMULT: 13295 case OPC_DMULTU: 13296 case OPC_DDIV: 13297 case OPC_DDIVU: 13298 check_insn(ctx, ISA_MIPS3); 13299 check_mips_64(ctx); 13300 gen_muldiv(ctx, op1, 0, rs, rt); 13301 break; 13302 #endif 13303 case OPC_JR: 13304 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13305 break; 13306 case OPC_SPIM: 13307 #ifdef MIPS_STRICT_STANDARD 13308 MIPS_INVAL("SPIM"); 13309 gen_reserved_instruction(ctx); 13310 #else 13311 /* Implemented as RI exception for now. */ 13312 MIPS_INVAL("spim (unofficial)"); 13313 gen_reserved_instruction(ctx); 13314 #endif 13315 break; 13316 default: /* Invalid */ 13317 MIPS_INVAL("special_legacy"); 13318 gen_reserved_instruction(ctx); 13319 break; 13320 } 13321 } 13322 13323 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13324 { 13325 int rs, rt, rd, sa; 13326 uint32_t op1; 13327 13328 rs = (ctx->opcode >> 21) & 0x1f; 13329 rt = (ctx->opcode >> 16) & 0x1f; 13330 rd = (ctx->opcode >> 11) & 0x1f; 13331 sa = (ctx->opcode >> 6) & 0x1f; 13332 13333 op1 = MASK_SPECIAL(ctx->opcode); 13334 switch (op1) { 13335 case OPC_SLL: /* Shift with immediate */ 13336 if (sa == 5 && rd == 0 && 13337 rs == 0 && rt == 0) { /* PAUSE */ 13338 if ((ctx->insn_flags & ISA_MIPS_R6) && 13339 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13340 gen_reserved_instruction(ctx); 13341 break; 13342 } 13343 } 13344 /* Fallthrough */ 13345 case OPC_SRA: 13346 gen_shift_imm(ctx, op1, rd, rt, sa); 13347 break; 13348 case OPC_SRL: 13349 switch ((ctx->opcode >> 21) & 0x1f) { 13350 case 1: 13351 /* rotr is decoded as srl on non-R2 CPUs */ 13352 if (ctx->insn_flags & ISA_MIPS_R2) { 13353 op1 = OPC_ROTR; 13354 } 13355 /* Fallthrough */ 13356 case 0: 13357 gen_shift_imm(ctx, op1, rd, rt, sa); 13358 break; 13359 default: 13360 gen_reserved_instruction(ctx); 13361 break; 13362 } 13363 break; 13364 case OPC_ADD: 13365 case OPC_ADDU: 13366 case OPC_SUB: 13367 case OPC_SUBU: 13368 gen_arith(ctx, op1, rd, rs, rt); 13369 break; 13370 case OPC_SLLV: /* Shifts */ 13371 case OPC_SRAV: 13372 gen_shift(ctx, op1, rd, rs, rt); 13373 break; 13374 case OPC_SRLV: 13375 switch ((ctx->opcode >> 6) & 0x1f) { 13376 case 1: 13377 /* rotrv is decoded as srlv on non-R2 CPUs */ 13378 if (ctx->insn_flags & ISA_MIPS_R2) { 13379 op1 = OPC_ROTRV; 13380 } 13381 /* Fallthrough */ 13382 case 0: 13383 gen_shift(ctx, op1, rd, rs, rt); 13384 break; 13385 default: 13386 gen_reserved_instruction(ctx); 13387 break; 13388 } 13389 break; 13390 case OPC_SLT: /* Set on less than */ 13391 case OPC_SLTU: 13392 gen_slt(ctx, op1, rd, rs, rt); 13393 break; 13394 case OPC_AND: /* Logic*/ 13395 case OPC_OR: 13396 case OPC_NOR: 13397 case OPC_XOR: 13398 gen_logic(ctx, op1, rd, rs, rt); 13399 break; 13400 case OPC_JALR: 13401 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13402 break; 13403 case OPC_TGE: /* Traps */ 13404 case OPC_TGEU: 13405 case OPC_TLT: 13406 case OPC_TLTU: 13407 case OPC_TEQ: 13408 case OPC_TNE: 13409 check_insn(ctx, ISA_MIPS2); 13410 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13411 break; 13412 case OPC_PMON: 13413 /* Pmon entry point, also R4010 selsl */ 13414 #ifdef MIPS_STRICT_STANDARD 13415 MIPS_INVAL("PMON / selsl"); 13416 gen_reserved_instruction(ctx); 13417 #else 13418 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13419 #endif 13420 break; 13421 case OPC_SYSCALL: 13422 generate_exception_end(ctx, EXCP_SYSCALL); 13423 break; 13424 case OPC_BREAK: 13425 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13426 break; 13427 case OPC_SYNC: 13428 check_insn(ctx, ISA_MIPS2); 13429 gen_sync(extract32(ctx->opcode, 6, 5)); 13430 break; 13431 13432 #if defined(TARGET_MIPS64) 13433 /* MIPS64 specific opcodes */ 13434 case OPC_DSLL: 13435 case OPC_DSRA: 13436 case OPC_DSLL32: 13437 case OPC_DSRA32: 13438 check_insn(ctx, ISA_MIPS3); 13439 check_mips_64(ctx); 13440 gen_shift_imm(ctx, op1, rd, rt, sa); 13441 break; 13442 case OPC_DSRL: 13443 switch ((ctx->opcode >> 21) & 0x1f) { 13444 case 1: 13445 /* drotr is decoded as dsrl on non-R2 CPUs */ 13446 if (ctx->insn_flags & ISA_MIPS_R2) { 13447 op1 = OPC_DROTR; 13448 } 13449 /* Fallthrough */ 13450 case 0: 13451 check_insn(ctx, ISA_MIPS3); 13452 check_mips_64(ctx); 13453 gen_shift_imm(ctx, op1, rd, rt, sa); 13454 break; 13455 default: 13456 gen_reserved_instruction(ctx); 13457 break; 13458 } 13459 break; 13460 case OPC_DSRL32: 13461 switch ((ctx->opcode >> 21) & 0x1f) { 13462 case 1: 13463 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13464 if (ctx->insn_flags & ISA_MIPS_R2) { 13465 op1 = OPC_DROTR32; 13466 } 13467 /* Fallthrough */ 13468 case 0: 13469 check_insn(ctx, ISA_MIPS3); 13470 check_mips_64(ctx); 13471 gen_shift_imm(ctx, op1, rd, rt, sa); 13472 break; 13473 default: 13474 gen_reserved_instruction(ctx); 13475 break; 13476 } 13477 break; 13478 case OPC_DADD: 13479 case OPC_DADDU: 13480 case OPC_DSUB: 13481 case OPC_DSUBU: 13482 check_insn(ctx, ISA_MIPS3); 13483 check_mips_64(ctx); 13484 gen_arith(ctx, op1, rd, rs, rt); 13485 break; 13486 case OPC_DSLLV: 13487 case OPC_DSRAV: 13488 check_insn(ctx, ISA_MIPS3); 13489 check_mips_64(ctx); 13490 gen_shift(ctx, op1, rd, rs, rt); 13491 break; 13492 case OPC_DSRLV: 13493 switch ((ctx->opcode >> 6) & 0x1f) { 13494 case 1: 13495 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13496 if (ctx->insn_flags & ISA_MIPS_R2) { 13497 op1 = OPC_DROTRV; 13498 } 13499 /* Fallthrough */ 13500 case 0: 13501 check_insn(ctx, ISA_MIPS3); 13502 check_mips_64(ctx); 13503 gen_shift(ctx, op1, rd, rs, rt); 13504 break; 13505 default: 13506 gen_reserved_instruction(ctx); 13507 break; 13508 } 13509 break; 13510 #endif 13511 default: 13512 if (ctx->insn_flags & ISA_MIPS_R6) { 13513 decode_opc_special_r6(env, ctx); 13514 } else if (ctx->insn_flags & INSN_R5900) { 13515 decode_opc_special_tx79(env, ctx); 13516 } else { 13517 decode_opc_special_legacy(env, ctx); 13518 } 13519 } 13520 } 13521 13522 13523 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13524 { 13525 int rs, rt, rd; 13526 uint32_t op1; 13527 13528 rs = (ctx->opcode >> 21) & 0x1f; 13529 rt = (ctx->opcode >> 16) & 0x1f; 13530 rd = (ctx->opcode >> 11) & 0x1f; 13531 13532 op1 = MASK_SPECIAL2(ctx->opcode); 13533 switch (op1) { 13534 case OPC_MADD: /* Multiply and add/sub */ 13535 case OPC_MADDU: 13536 case OPC_MSUB: 13537 case OPC_MSUBU: 13538 check_insn(ctx, ISA_MIPS_R1); 13539 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13540 break; 13541 case OPC_MUL: 13542 gen_arith(ctx, op1, rd, rs, rt); 13543 break; 13544 case OPC_MULT_G_2F: 13545 case OPC_MULTU_G_2F: 13546 case OPC_MOD_G_2F: 13547 case OPC_MODU_G_2F: 13548 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13549 gen_loongson_integer(ctx, op1, rd, rs, rt); 13550 break; 13551 case OPC_CLO: 13552 case OPC_CLZ: 13553 check_insn(ctx, ISA_MIPS_R1); 13554 gen_cl(ctx, op1, rd, rs); 13555 break; 13556 case OPC_SDBBP: 13557 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13558 ctx->base.is_jmp = DISAS_SEMIHOST; 13559 } else { 13560 /* 13561 * XXX: not clear which exception should be raised 13562 * when in debug mode... 13563 */ 13564 check_insn(ctx, ISA_MIPS_R1); 13565 generate_exception_end(ctx, EXCP_DBp); 13566 } 13567 break; 13568 #if defined(TARGET_MIPS64) 13569 case OPC_DCLO: 13570 case OPC_DCLZ: 13571 check_insn(ctx, ISA_MIPS_R1); 13572 check_mips_64(ctx); 13573 gen_cl(ctx, op1, rd, rs); 13574 break; 13575 case OPC_DMULT_G_2F: 13576 case OPC_DMULTU_G_2F: 13577 case OPC_DMOD_G_2F: 13578 case OPC_DMODU_G_2F: 13579 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13580 gen_loongson_integer(ctx, op1, rd, rs, rt); 13581 break; 13582 #endif 13583 default: /* Invalid */ 13584 MIPS_INVAL("special2_legacy"); 13585 gen_reserved_instruction(ctx); 13586 break; 13587 } 13588 } 13589 13590 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13591 { 13592 int rs, rt, rd, sa; 13593 uint32_t op1, op2; 13594 int16_t imm; 13595 13596 rs = (ctx->opcode >> 21) & 0x1f; 13597 rt = (ctx->opcode >> 16) & 0x1f; 13598 rd = (ctx->opcode >> 11) & 0x1f; 13599 sa = (ctx->opcode >> 6) & 0x1f; 13600 imm = (int16_t)ctx->opcode >> 7; 13601 13602 op1 = MASK_SPECIAL3(ctx->opcode); 13603 switch (op1) { 13604 case R6_OPC_PREF: 13605 if (rt >= 24) { 13606 /* hint codes 24-31 are reserved and signal RI */ 13607 gen_reserved_instruction(ctx); 13608 } 13609 /* Treat as NOP. */ 13610 break; 13611 case R6_OPC_CACHE: 13612 check_cp0_enabled(ctx); 13613 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13614 gen_cache_operation(ctx, rt, rs, imm); 13615 } 13616 break; 13617 case R6_OPC_SC: 13618 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13619 break; 13620 case R6_OPC_LL: 13621 gen_ld(ctx, op1, rt, rs, imm); 13622 break; 13623 case OPC_BSHFL: 13624 { 13625 if (rd == 0) { 13626 /* Treat as NOP. */ 13627 break; 13628 } 13629 op2 = MASK_BSHFL(ctx->opcode); 13630 switch (op2) { 13631 case OPC_ALIGN: 13632 case OPC_ALIGN_1: 13633 case OPC_ALIGN_2: 13634 case OPC_ALIGN_3: 13635 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13636 break; 13637 case OPC_BITSWAP: 13638 gen_bitswap(ctx, op2, rd, rt); 13639 break; 13640 } 13641 } 13642 break; 13643 #ifndef CONFIG_USER_ONLY 13644 case OPC_GINV: 13645 if (unlikely(ctx->gi <= 1)) { 13646 gen_reserved_instruction(ctx); 13647 } 13648 check_cp0_enabled(ctx); 13649 switch ((ctx->opcode >> 6) & 3) { 13650 case 0: /* GINVI */ 13651 /* Treat as NOP. */ 13652 break; 13653 case 2: /* GINVT */ 13654 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13655 break; 13656 default: 13657 gen_reserved_instruction(ctx); 13658 break; 13659 } 13660 break; 13661 #endif 13662 #if defined(TARGET_MIPS64) 13663 case R6_OPC_SCD: 13664 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13665 break; 13666 case R6_OPC_LLD: 13667 gen_ld(ctx, op1, rt, rs, imm); 13668 break; 13669 case OPC_DBSHFL: 13670 check_mips_64(ctx); 13671 { 13672 if (rd == 0) { 13673 /* Treat as NOP. */ 13674 break; 13675 } 13676 op2 = MASK_DBSHFL(ctx->opcode); 13677 switch (op2) { 13678 case OPC_DALIGN: 13679 case OPC_DALIGN_1: 13680 case OPC_DALIGN_2: 13681 case OPC_DALIGN_3: 13682 case OPC_DALIGN_4: 13683 case OPC_DALIGN_5: 13684 case OPC_DALIGN_6: 13685 case OPC_DALIGN_7: 13686 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13687 break; 13688 case OPC_DBITSWAP: 13689 gen_bitswap(ctx, op2, rd, rt); 13690 break; 13691 } 13692 13693 } 13694 break; 13695 #endif 13696 default: /* Invalid */ 13697 MIPS_INVAL("special3_r6"); 13698 gen_reserved_instruction(ctx); 13699 break; 13700 } 13701 } 13702 13703 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13704 { 13705 int rs, rt, rd; 13706 uint32_t op1, op2; 13707 13708 rs = (ctx->opcode >> 21) & 0x1f; 13709 rt = (ctx->opcode >> 16) & 0x1f; 13710 rd = (ctx->opcode >> 11) & 0x1f; 13711 13712 op1 = MASK_SPECIAL3(ctx->opcode); 13713 switch (op1) { 13714 case OPC_MOD_G_2E: 13715 case OPC_MODU_G_2E: 13716 case OPC_MULT_G_2E: 13717 case OPC_MULTU_G_2E: 13718 /* 13719 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13720 * the same mask and op1. 13721 */ 13722 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13723 op2 = MASK_ADDUH_QB(ctx->opcode); 13724 switch (op2) { 13725 case OPC_ADDUH_QB: 13726 case OPC_ADDUH_R_QB: 13727 case OPC_ADDQH_PH: 13728 case OPC_ADDQH_R_PH: 13729 case OPC_ADDQH_W: 13730 case OPC_ADDQH_R_W: 13731 case OPC_SUBUH_QB: 13732 case OPC_SUBUH_R_QB: 13733 case OPC_SUBQH_PH: 13734 case OPC_SUBQH_R_PH: 13735 case OPC_SUBQH_W: 13736 case OPC_SUBQH_R_W: 13737 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13738 break; 13739 case OPC_MUL_PH: 13740 case OPC_MUL_S_PH: 13741 case OPC_MULQ_S_W: 13742 case OPC_MULQ_RS_W: 13743 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13744 break; 13745 default: 13746 MIPS_INVAL("MASK ADDUH.QB"); 13747 gen_reserved_instruction(ctx); 13748 break; 13749 } 13750 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 13751 gen_loongson_integer(ctx, op1, rd, rs, rt); 13752 } else { 13753 gen_reserved_instruction(ctx); 13754 } 13755 break; 13756 case OPC_LX_DSP: 13757 op2 = MASK_LX(ctx->opcode); 13758 switch (op2) { 13759 #if defined(TARGET_MIPS64) 13760 case OPC_LDX: 13761 #endif 13762 case OPC_LBUX: 13763 case OPC_LHX: 13764 case OPC_LWX: 13765 gen_mips_lx(ctx, op2, rd, rs, rt); 13766 break; 13767 default: /* Invalid */ 13768 MIPS_INVAL("MASK LX"); 13769 gen_reserved_instruction(ctx); 13770 break; 13771 } 13772 break; 13773 case OPC_ABSQ_S_PH_DSP: 13774 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13775 switch (op2) { 13776 case OPC_ABSQ_S_QB: 13777 case OPC_ABSQ_S_PH: 13778 case OPC_ABSQ_S_W: 13779 case OPC_PRECEQ_W_PHL: 13780 case OPC_PRECEQ_W_PHR: 13781 case OPC_PRECEQU_PH_QBL: 13782 case OPC_PRECEQU_PH_QBR: 13783 case OPC_PRECEQU_PH_QBLA: 13784 case OPC_PRECEQU_PH_QBRA: 13785 case OPC_PRECEU_PH_QBL: 13786 case OPC_PRECEU_PH_QBR: 13787 case OPC_PRECEU_PH_QBLA: 13788 case OPC_PRECEU_PH_QBRA: 13789 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13790 break; 13791 case OPC_BITREV: 13792 case OPC_REPL_QB: 13793 case OPC_REPLV_QB: 13794 case OPC_REPL_PH: 13795 case OPC_REPLV_PH: 13796 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13797 break; 13798 default: 13799 MIPS_INVAL("MASK ABSQ_S.PH"); 13800 gen_reserved_instruction(ctx); 13801 break; 13802 } 13803 break; 13804 case OPC_ADDU_QB_DSP: 13805 op2 = MASK_ADDU_QB(ctx->opcode); 13806 switch (op2) { 13807 case OPC_ADDQ_PH: 13808 case OPC_ADDQ_S_PH: 13809 case OPC_ADDQ_S_W: 13810 case OPC_ADDU_QB: 13811 case OPC_ADDU_S_QB: 13812 case OPC_ADDU_PH: 13813 case OPC_ADDU_S_PH: 13814 case OPC_SUBQ_PH: 13815 case OPC_SUBQ_S_PH: 13816 case OPC_SUBQ_S_W: 13817 case OPC_SUBU_QB: 13818 case OPC_SUBU_S_QB: 13819 case OPC_SUBU_PH: 13820 case OPC_SUBU_S_PH: 13821 case OPC_ADDSC: 13822 case OPC_ADDWC: 13823 case OPC_MODSUB: 13824 case OPC_RADDU_W_QB: 13825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13826 break; 13827 case OPC_MULEU_S_PH_QBL: 13828 case OPC_MULEU_S_PH_QBR: 13829 case OPC_MULQ_RS_PH: 13830 case OPC_MULEQ_S_W_PHL: 13831 case OPC_MULEQ_S_W_PHR: 13832 case OPC_MULQ_S_PH: 13833 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13834 break; 13835 default: /* Invalid */ 13836 MIPS_INVAL("MASK ADDU.QB"); 13837 gen_reserved_instruction(ctx); 13838 break; 13839 13840 } 13841 break; 13842 case OPC_CMPU_EQ_QB_DSP: 13843 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13844 switch (op2) { 13845 case OPC_PRECR_SRA_PH_W: 13846 case OPC_PRECR_SRA_R_PH_W: 13847 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13848 break; 13849 case OPC_PRECR_QB_PH: 13850 case OPC_PRECRQ_QB_PH: 13851 case OPC_PRECRQ_PH_W: 13852 case OPC_PRECRQ_RS_PH_W: 13853 case OPC_PRECRQU_S_QB_PH: 13854 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13855 break; 13856 case OPC_CMPU_EQ_QB: 13857 case OPC_CMPU_LT_QB: 13858 case OPC_CMPU_LE_QB: 13859 case OPC_CMP_EQ_PH: 13860 case OPC_CMP_LT_PH: 13861 case OPC_CMP_LE_PH: 13862 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13863 break; 13864 case OPC_CMPGU_EQ_QB: 13865 case OPC_CMPGU_LT_QB: 13866 case OPC_CMPGU_LE_QB: 13867 case OPC_CMPGDU_EQ_QB: 13868 case OPC_CMPGDU_LT_QB: 13869 case OPC_CMPGDU_LE_QB: 13870 case OPC_PICK_QB: 13871 case OPC_PICK_PH: 13872 case OPC_PACKRL_PH: 13873 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13874 break; 13875 default: /* Invalid */ 13876 MIPS_INVAL("MASK CMPU.EQ.QB"); 13877 gen_reserved_instruction(ctx); 13878 break; 13879 } 13880 break; 13881 case OPC_SHLL_QB_DSP: 13882 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13883 break; 13884 case OPC_DPA_W_PH_DSP: 13885 op2 = MASK_DPA_W_PH(ctx->opcode); 13886 switch (op2) { 13887 case OPC_DPAU_H_QBL: 13888 case OPC_DPAU_H_QBR: 13889 case OPC_DPSU_H_QBL: 13890 case OPC_DPSU_H_QBR: 13891 case OPC_DPA_W_PH: 13892 case OPC_DPAX_W_PH: 13893 case OPC_DPAQ_S_W_PH: 13894 case OPC_DPAQX_S_W_PH: 13895 case OPC_DPAQX_SA_W_PH: 13896 case OPC_DPS_W_PH: 13897 case OPC_DPSX_W_PH: 13898 case OPC_DPSQ_S_W_PH: 13899 case OPC_DPSQX_S_W_PH: 13900 case OPC_DPSQX_SA_W_PH: 13901 case OPC_MULSAQ_S_W_PH: 13902 case OPC_DPAQ_SA_L_W: 13903 case OPC_DPSQ_SA_L_W: 13904 case OPC_MAQ_S_W_PHL: 13905 case OPC_MAQ_S_W_PHR: 13906 case OPC_MAQ_SA_W_PHL: 13907 case OPC_MAQ_SA_W_PHR: 13908 case OPC_MULSA_W_PH: 13909 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13910 break; 13911 default: /* Invalid */ 13912 MIPS_INVAL("MASK DPAW.PH"); 13913 gen_reserved_instruction(ctx); 13914 break; 13915 } 13916 break; 13917 case OPC_INSV_DSP: 13918 op2 = MASK_INSV(ctx->opcode); 13919 switch (op2) { 13920 case OPC_INSV: 13921 check_dsp(ctx); 13922 { 13923 TCGv t0, t1; 13924 13925 if (rt == 0) { 13926 break; 13927 } 13928 13929 t0 = tcg_temp_new(); 13930 t1 = tcg_temp_new(); 13931 13932 gen_load_gpr(t0, rt); 13933 gen_load_gpr(t1, rs); 13934 13935 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13936 break; 13937 } 13938 default: /* Invalid */ 13939 MIPS_INVAL("MASK INSV"); 13940 gen_reserved_instruction(ctx); 13941 break; 13942 } 13943 break; 13944 case OPC_APPEND_DSP: 13945 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13946 break; 13947 case OPC_EXTR_W_DSP: 13948 op2 = MASK_EXTR_W(ctx->opcode); 13949 switch (op2) { 13950 case OPC_EXTR_W: 13951 case OPC_EXTR_R_W: 13952 case OPC_EXTR_RS_W: 13953 case OPC_EXTR_S_H: 13954 case OPC_EXTRV_S_H: 13955 case OPC_EXTRV_W: 13956 case OPC_EXTRV_R_W: 13957 case OPC_EXTRV_RS_W: 13958 case OPC_EXTP: 13959 case OPC_EXTPV: 13960 case OPC_EXTPDP: 13961 case OPC_EXTPDPV: 13962 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13963 break; 13964 case OPC_RDDSP: 13965 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13966 break; 13967 case OPC_SHILO: 13968 case OPC_SHILOV: 13969 case OPC_MTHLIP: 13970 case OPC_WRDSP: 13971 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13972 break; 13973 default: /* Invalid */ 13974 MIPS_INVAL("MASK EXTR.W"); 13975 gen_reserved_instruction(ctx); 13976 break; 13977 } 13978 break; 13979 #if defined(TARGET_MIPS64) 13980 case OPC_DMULT_G_2E: 13981 case OPC_DMULTU_G_2E: 13982 case OPC_DMOD_G_2E: 13983 case OPC_DMODU_G_2E: 13984 check_insn(ctx, INSN_LOONGSON2E); 13985 gen_loongson_integer(ctx, op1, rd, rs, rt); 13986 break; 13987 case OPC_ABSQ_S_QH_DSP: 13988 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13989 switch (op2) { 13990 case OPC_PRECEQ_L_PWL: 13991 case OPC_PRECEQ_L_PWR: 13992 case OPC_PRECEQ_PW_QHL: 13993 case OPC_PRECEQ_PW_QHR: 13994 case OPC_PRECEQ_PW_QHLA: 13995 case OPC_PRECEQ_PW_QHRA: 13996 case OPC_PRECEQU_QH_OBL: 13997 case OPC_PRECEQU_QH_OBR: 13998 case OPC_PRECEQU_QH_OBLA: 13999 case OPC_PRECEQU_QH_OBRA: 14000 case OPC_PRECEU_QH_OBL: 14001 case OPC_PRECEU_QH_OBR: 14002 case OPC_PRECEU_QH_OBLA: 14003 case OPC_PRECEU_QH_OBRA: 14004 case OPC_ABSQ_S_OB: 14005 case OPC_ABSQ_S_PW: 14006 case OPC_ABSQ_S_QH: 14007 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14008 break; 14009 case OPC_REPL_OB: 14010 case OPC_REPL_PW: 14011 case OPC_REPL_QH: 14012 case OPC_REPLV_OB: 14013 case OPC_REPLV_PW: 14014 case OPC_REPLV_QH: 14015 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14016 break; 14017 default: /* Invalid */ 14018 MIPS_INVAL("MASK ABSQ_S.QH"); 14019 gen_reserved_instruction(ctx); 14020 break; 14021 } 14022 break; 14023 case OPC_ADDU_OB_DSP: 14024 op2 = MASK_ADDU_OB(ctx->opcode); 14025 switch (op2) { 14026 case OPC_RADDU_L_OB: 14027 case OPC_SUBQ_PW: 14028 case OPC_SUBQ_S_PW: 14029 case OPC_SUBQ_QH: 14030 case OPC_SUBQ_S_QH: 14031 case OPC_SUBU_OB: 14032 case OPC_SUBU_S_OB: 14033 case OPC_SUBU_QH: 14034 case OPC_SUBU_S_QH: 14035 case OPC_SUBUH_OB: 14036 case OPC_SUBUH_R_OB: 14037 case OPC_ADDQ_PW: 14038 case OPC_ADDQ_S_PW: 14039 case OPC_ADDQ_QH: 14040 case OPC_ADDQ_S_QH: 14041 case OPC_ADDU_OB: 14042 case OPC_ADDU_S_OB: 14043 case OPC_ADDU_QH: 14044 case OPC_ADDU_S_QH: 14045 case OPC_ADDUH_OB: 14046 case OPC_ADDUH_R_OB: 14047 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14048 break; 14049 case OPC_MULEQ_S_PW_QHL: 14050 case OPC_MULEQ_S_PW_QHR: 14051 case OPC_MULEU_S_QH_OBL: 14052 case OPC_MULEU_S_QH_OBR: 14053 case OPC_MULQ_RS_QH: 14054 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14055 break; 14056 default: /* Invalid */ 14057 MIPS_INVAL("MASK ADDU.OB"); 14058 gen_reserved_instruction(ctx); 14059 break; 14060 } 14061 break; 14062 case OPC_CMPU_EQ_OB_DSP: 14063 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14064 switch (op2) { 14065 case OPC_PRECR_SRA_QH_PW: 14066 case OPC_PRECR_SRA_R_QH_PW: 14067 /* Return value is rt. */ 14068 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14069 break; 14070 case OPC_PRECR_OB_QH: 14071 case OPC_PRECRQ_OB_QH: 14072 case OPC_PRECRQ_PW_L: 14073 case OPC_PRECRQ_QH_PW: 14074 case OPC_PRECRQ_RS_QH_PW: 14075 case OPC_PRECRQU_S_OB_QH: 14076 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14077 break; 14078 case OPC_CMPU_EQ_OB: 14079 case OPC_CMPU_LT_OB: 14080 case OPC_CMPU_LE_OB: 14081 case OPC_CMP_EQ_QH: 14082 case OPC_CMP_LT_QH: 14083 case OPC_CMP_LE_QH: 14084 case OPC_CMP_EQ_PW: 14085 case OPC_CMP_LT_PW: 14086 case OPC_CMP_LE_PW: 14087 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14088 break; 14089 case OPC_CMPGDU_EQ_OB: 14090 case OPC_CMPGDU_LT_OB: 14091 case OPC_CMPGDU_LE_OB: 14092 case OPC_CMPGU_EQ_OB: 14093 case OPC_CMPGU_LT_OB: 14094 case OPC_CMPGU_LE_OB: 14095 case OPC_PACKRL_PW: 14096 case OPC_PICK_OB: 14097 case OPC_PICK_PW: 14098 case OPC_PICK_QH: 14099 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14100 break; 14101 default: /* Invalid */ 14102 MIPS_INVAL("MASK CMPU_EQ.OB"); 14103 gen_reserved_instruction(ctx); 14104 break; 14105 } 14106 break; 14107 case OPC_DAPPEND_DSP: 14108 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14109 break; 14110 case OPC_DEXTR_W_DSP: 14111 op2 = MASK_DEXTR_W(ctx->opcode); 14112 switch (op2) { 14113 case OPC_DEXTP: 14114 case OPC_DEXTPDP: 14115 case OPC_DEXTPDPV: 14116 case OPC_DEXTPV: 14117 case OPC_DEXTR_L: 14118 case OPC_DEXTR_R_L: 14119 case OPC_DEXTR_RS_L: 14120 case OPC_DEXTR_W: 14121 case OPC_DEXTR_R_W: 14122 case OPC_DEXTR_RS_W: 14123 case OPC_DEXTR_S_H: 14124 case OPC_DEXTRV_L: 14125 case OPC_DEXTRV_R_L: 14126 case OPC_DEXTRV_RS_L: 14127 case OPC_DEXTRV_S_H: 14128 case OPC_DEXTRV_W: 14129 case OPC_DEXTRV_R_W: 14130 case OPC_DEXTRV_RS_W: 14131 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14132 break; 14133 case OPC_DMTHLIP: 14134 case OPC_DSHILO: 14135 case OPC_DSHILOV: 14136 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14137 break; 14138 default: /* Invalid */ 14139 MIPS_INVAL("MASK EXTR.W"); 14140 gen_reserved_instruction(ctx); 14141 break; 14142 } 14143 break; 14144 case OPC_DPAQ_W_QH_DSP: 14145 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14146 switch (op2) { 14147 case OPC_DPAU_H_OBL: 14148 case OPC_DPAU_H_OBR: 14149 case OPC_DPSU_H_OBL: 14150 case OPC_DPSU_H_OBR: 14151 case OPC_DPA_W_QH: 14152 case OPC_DPAQ_S_W_QH: 14153 case OPC_DPS_W_QH: 14154 case OPC_DPSQ_S_W_QH: 14155 case OPC_MULSAQ_S_W_QH: 14156 case OPC_DPAQ_SA_L_PW: 14157 case OPC_DPSQ_SA_L_PW: 14158 case OPC_MULSAQ_S_L_PW: 14159 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14160 break; 14161 case OPC_MAQ_S_W_QHLL: 14162 case OPC_MAQ_S_W_QHLR: 14163 case OPC_MAQ_S_W_QHRL: 14164 case OPC_MAQ_S_W_QHRR: 14165 case OPC_MAQ_SA_W_QHLL: 14166 case OPC_MAQ_SA_W_QHLR: 14167 case OPC_MAQ_SA_W_QHRL: 14168 case OPC_MAQ_SA_W_QHRR: 14169 case OPC_MAQ_S_L_PWL: 14170 case OPC_MAQ_S_L_PWR: 14171 case OPC_DMADD: 14172 case OPC_DMADDU: 14173 case OPC_DMSUB: 14174 case OPC_DMSUBU: 14175 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14176 break; 14177 default: /* Invalid */ 14178 MIPS_INVAL("MASK DPAQ.W.QH"); 14179 gen_reserved_instruction(ctx); 14180 break; 14181 } 14182 break; 14183 case OPC_DINSV_DSP: 14184 op2 = MASK_INSV(ctx->opcode); 14185 switch (op2) { 14186 case OPC_DINSV: 14187 { 14188 TCGv t0, t1; 14189 14190 check_dsp(ctx); 14191 14192 if (rt == 0) { 14193 break; 14194 } 14195 14196 t0 = tcg_temp_new(); 14197 t1 = tcg_temp_new(); 14198 14199 gen_load_gpr(t0, rt); 14200 gen_load_gpr(t1, rs); 14201 14202 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14203 break; 14204 } 14205 default: /* Invalid */ 14206 MIPS_INVAL("MASK DINSV"); 14207 gen_reserved_instruction(ctx); 14208 break; 14209 } 14210 break; 14211 case OPC_SHLL_OB_DSP: 14212 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14213 break; 14214 #endif 14215 default: /* Invalid */ 14216 MIPS_INVAL("special3_legacy"); 14217 gen_reserved_instruction(ctx); 14218 break; 14219 } 14220 } 14221 14222 14223 #if defined(TARGET_MIPS64) 14224 14225 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14226 { 14227 uint32_t opc = MASK_MMI(ctx->opcode); 14228 int rs = extract32(ctx->opcode, 21, 5); 14229 int rt = extract32(ctx->opcode, 16, 5); 14230 int rd = extract32(ctx->opcode, 11, 5); 14231 14232 switch (opc) { 14233 case MMI_OPC_MULT1: 14234 case MMI_OPC_MULTU1: 14235 case MMI_OPC_MADD: 14236 case MMI_OPC_MADDU: 14237 case MMI_OPC_MADD1: 14238 case MMI_OPC_MADDU1: 14239 gen_mul_txx9(ctx, opc, rd, rs, rt); 14240 break; 14241 case MMI_OPC_DIV1: 14242 case MMI_OPC_DIVU1: 14243 gen_div1_tx79(ctx, opc, rs, rt); 14244 break; 14245 default: 14246 MIPS_INVAL("TX79 MMI class"); 14247 gen_reserved_instruction(ctx); 14248 break; 14249 } 14250 } 14251 14252 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14253 { 14254 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14255 } 14256 14257 /* 14258 * The TX79-specific instruction Store Quadword 14259 * 14260 * +--------+-------+-------+------------------------+ 14261 * | 011111 | base | rt | offset | SQ 14262 * +--------+-------+-------+------------------------+ 14263 * 6 5 5 16 14264 * 14265 * has the same opcode as the Read Hardware Register instruction 14266 * 14267 * +--------+-------+-------+-------+-------+--------+ 14268 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14269 * +--------+-------+-------+-------+-------+--------+ 14270 * 6 5 5 5 5 6 14271 * 14272 * that is required, trapped and emulated by the Linux kernel. However, all 14273 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14274 * offset is odd. Therefore all valid SQ instructions can execute normally. 14275 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14276 * between SQ and RDHWR, as the Linux kernel does. 14277 */ 14278 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14279 { 14280 int base = extract32(ctx->opcode, 21, 5); 14281 int rt = extract32(ctx->opcode, 16, 5); 14282 int offset = extract32(ctx->opcode, 0, 16); 14283 14284 #ifdef CONFIG_USER_ONLY 14285 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14286 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14287 14288 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14289 int rd = extract32(ctx->opcode, 11, 5); 14290 14291 gen_rdhwr(ctx, rt, rd, 0); 14292 return; 14293 } 14294 #endif 14295 14296 gen_mmi_sq(ctx, base, rt, offset); 14297 } 14298 14299 #endif 14300 14301 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14302 { 14303 int rs, rt, rd, sa; 14304 uint32_t op1, op2; 14305 int16_t imm; 14306 14307 rs = (ctx->opcode >> 21) & 0x1f; 14308 rt = (ctx->opcode >> 16) & 0x1f; 14309 rd = (ctx->opcode >> 11) & 0x1f; 14310 sa = (ctx->opcode >> 6) & 0x1f; 14311 imm = sextract32(ctx->opcode, 7, 9); 14312 14313 op1 = MASK_SPECIAL3(ctx->opcode); 14314 14315 /* 14316 * EVA loads and stores overlap Loongson 2E instructions decoded by 14317 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14318 * EVA is absent. 14319 */ 14320 if (ctx->eva) { 14321 switch (op1) { 14322 case OPC_LWLE: 14323 case OPC_LWRE: 14324 case OPC_LBUE: 14325 case OPC_LHUE: 14326 case OPC_LBE: 14327 case OPC_LHE: 14328 case OPC_LLE: 14329 case OPC_LWE: 14330 check_cp0_enabled(ctx); 14331 gen_ld(ctx, op1, rt, rs, imm); 14332 return; 14333 case OPC_SWLE: 14334 case OPC_SWRE: 14335 case OPC_SBE: 14336 case OPC_SHE: 14337 case OPC_SWE: 14338 check_cp0_enabled(ctx); 14339 gen_st(ctx, op1, rt, rs, imm); 14340 return; 14341 case OPC_SCE: 14342 check_cp0_enabled(ctx); 14343 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14344 return; 14345 case OPC_CACHEE: 14346 check_eva(ctx); 14347 check_cp0_enabled(ctx); 14348 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14349 gen_cache_operation(ctx, rt, rs, imm); 14350 } 14351 return; 14352 case OPC_PREFE: 14353 check_cp0_enabled(ctx); 14354 /* Treat as NOP. */ 14355 return; 14356 } 14357 } 14358 14359 switch (op1) { 14360 case OPC_EXT: 14361 case OPC_INS: 14362 check_insn(ctx, ISA_MIPS_R2); 14363 gen_bitops(ctx, op1, rt, rs, sa, rd); 14364 break; 14365 case OPC_BSHFL: 14366 op2 = MASK_BSHFL(ctx->opcode); 14367 switch (op2) { 14368 case OPC_ALIGN: 14369 case OPC_ALIGN_1: 14370 case OPC_ALIGN_2: 14371 case OPC_ALIGN_3: 14372 case OPC_BITSWAP: 14373 check_insn(ctx, ISA_MIPS_R6); 14374 decode_opc_special3_r6(env, ctx); 14375 break; 14376 default: 14377 check_insn(ctx, ISA_MIPS_R2); 14378 gen_bshfl(ctx, op2, rt, rd); 14379 break; 14380 } 14381 break; 14382 #if defined(TARGET_MIPS64) 14383 case OPC_DEXTM: 14384 case OPC_DEXTU: 14385 case OPC_DEXT: 14386 case OPC_DINSM: 14387 case OPC_DINSU: 14388 case OPC_DINS: 14389 check_insn(ctx, ISA_MIPS_R2); 14390 check_mips_64(ctx); 14391 gen_bitops(ctx, op1, rt, rs, sa, rd); 14392 break; 14393 case OPC_DBSHFL: 14394 op2 = MASK_DBSHFL(ctx->opcode); 14395 switch (op2) { 14396 case OPC_DALIGN: 14397 case OPC_DALIGN_1: 14398 case OPC_DALIGN_2: 14399 case OPC_DALIGN_3: 14400 case OPC_DALIGN_4: 14401 case OPC_DALIGN_5: 14402 case OPC_DALIGN_6: 14403 case OPC_DALIGN_7: 14404 case OPC_DBITSWAP: 14405 check_insn(ctx, ISA_MIPS_R6); 14406 decode_opc_special3_r6(env, ctx); 14407 break; 14408 default: 14409 check_insn(ctx, ISA_MIPS_R2); 14410 check_mips_64(ctx); 14411 op2 = MASK_DBSHFL(ctx->opcode); 14412 gen_bshfl(ctx, op2, rt, rd); 14413 break; 14414 } 14415 break; 14416 #endif 14417 case OPC_RDHWR: 14418 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14419 break; 14420 case OPC_FORK: 14421 check_mt(ctx); 14422 { 14423 TCGv t0 = tcg_temp_new(); 14424 TCGv t1 = tcg_temp_new(); 14425 14426 gen_load_gpr(t0, rt); 14427 gen_load_gpr(t1, rs); 14428 gen_helper_fork(t0, t1); 14429 } 14430 break; 14431 case OPC_YIELD: 14432 check_mt(ctx); 14433 { 14434 TCGv t0 = tcg_temp_new(); 14435 14436 gen_load_gpr(t0, rs); 14437 gen_helper_yield(t0, tcg_env, t0); 14438 gen_store_gpr(t0, rd); 14439 } 14440 break; 14441 default: 14442 if (ctx->insn_flags & ISA_MIPS_R6) { 14443 decode_opc_special3_r6(env, ctx); 14444 } else { 14445 decode_opc_special3_legacy(env, ctx); 14446 } 14447 } 14448 } 14449 14450 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14451 { 14452 int32_t offset; 14453 int rs, rt, rd, sa; 14454 uint32_t op, op1; 14455 int16_t imm; 14456 14457 op = MASK_OP_MAJOR(ctx->opcode); 14458 rs = (ctx->opcode >> 21) & 0x1f; 14459 rt = (ctx->opcode >> 16) & 0x1f; 14460 rd = (ctx->opcode >> 11) & 0x1f; 14461 sa = (ctx->opcode >> 6) & 0x1f; 14462 imm = (int16_t)ctx->opcode; 14463 switch (op) { 14464 case OPC_SPECIAL: 14465 decode_opc_special(env, ctx); 14466 break; 14467 case OPC_SPECIAL2: 14468 #if defined(TARGET_MIPS64) 14469 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14470 decode_mmi(env, ctx); 14471 break; 14472 } 14473 #endif 14474 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14475 if (decode_ase_mxu(ctx, ctx->opcode)) { 14476 break; 14477 } 14478 } 14479 decode_opc_special2_legacy(env, ctx); 14480 break; 14481 case OPC_SPECIAL3: 14482 #if defined(TARGET_MIPS64) 14483 if (ctx->insn_flags & INSN_R5900) { 14484 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14485 } else { 14486 decode_opc_special3(env, ctx); 14487 } 14488 #else 14489 decode_opc_special3(env, ctx); 14490 #endif 14491 break; 14492 case OPC_REGIMM: 14493 op1 = MASK_REGIMM(ctx->opcode); 14494 switch (op1) { 14495 case OPC_BLTZL: /* REGIMM branches */ 14496 case OPC_BGEZL: 14497 case OPC_BLTZALL: 14498 case OPC_BGEZALL: 14499 check_insn(ctx, ISA_MIPS2); 14500 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14501 /* Fallthrough */ 14502 case OPC_BLTZ: 14503 case OPC_BGEZ: 14504 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14505 break; 14506 case OPC_BLTZAL: 14507 case OPC_BGEZAL: 14508 if (ctx->insn_flags & ISA_MIPS_R6) { 14509 if (rs == 0) { 14510 /* OPC_NAL, OPC_BAL */ 14511 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14512 } else { 14513 gen_reserved_instruction(ctx); 14514 } 14515 } else { 14516 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14517 } 14518 break; 14519 case OPC_TGEI: /* REGIMM traps */ 14520 case OPC_TGEIU: 14521 case OPC_TLTI: 14522 case OPC_TLTIU: 14523 case OPC_TEQI: 14524 case OPC_TNEI: 14525 check_insn(ctx, ISA_MIPS2); 14526 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14527 gen_trap(ctx, op1, rs, -1, imm, 0); 14528 break; 14529 case OPC_SIGRIE: 14530 check_insn(ctx, ISA_MIPS_R6); 14531 gen_reserved_instruction(ctx); 14532 break; 14533 case OPC_SYNCI: 14534 check_insn(ctx, ISA_MIPS_R2); 14535 /* 14536 * Break the TB to be able to sync copied instructions 14537 * immediately. 14538 */ 14539 ctx->base.is_jmp = DISAS_STOP; 14540 break; 14541 case OPC_BPOSGE32: /* MIPS DSP branch */ 14542 #if defined(TARGET_MIPS64) 14543 case OPC_BPOSGE64: 14544 #endif 14545 check_dsp(ctx); 14546 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14547 break; 14548 #if defined(TARGET_MIPS64) 14549 case OPC_DAHI: 14550 check_insn(ctx, ISA_MIPS_R6); 14551 check_mips_64(ctx); 14552 if (rs != 0) { 14553 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14554 } 14555 break; 14556 case OPC_DATI: 14557 check_insn(ctx, ISA_MIPS_R6); 14558 check_mips_64(ctx); 14559 if (rs != 0) { 14560 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14561 } 14562 break; 14563 #endif 14564 default: /* Invalid */ 14565 MIPS_INVAL("regimm"); 14566 gen_reserved_instruction(ctx); 14567 break; 14568 } 14569 break; 14570 case OPC_CP0: 14571 check_cp0_enabled(ctx); 14572 op1 = MASK_CP0(ctx->opcode); 14573 switch (op1) { 14574 case OPC_MFC0: 14575 case OPC_MTC0: 14576 case OPC_MFTR: 14577 case OPC_MTTR: 14578 case OPC_MFHC0: 14579 case OPC_MTHC0: 14580 #if defined(TARGET_MIPS64) 14581 case OPC_DMFC0: 14582 case OPC_DMTC0: 14583 #endif 14584 #ifndef CONFIG_USER_ONLY 14585 gen_cp0(env, ctx, op1, rt, rd); 14586 #endif /* !CONFIG_USER_ONLY */ 14587 break; 14588 case OPC_C0: 14589 case OPC_C0_1: 14590 case OPC_C0_2: 14591 case OPC_C0_3: 14592 case OPC_C0_4: 14593 case OPC_C0_5: 14594 case OPC_C0_6: 14595 case OPC_C0_7: 14596 case OPC_C0_8: 14597 case OPC_C0_9: 14598 case OPC_C0_A: 14599 case OPC_C0_B: 14600 case OPC_C0_C: 14601 case OPC_C0_D: 14602 case OPC_C0_E: 14603 case OPC_C0_F: 14604 #ifndef CONFIG_USER_ONLY 14605 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14606 #endif /* !CONFIG_USER_ONLY */ 14607 break; 14608 case OPC_MFMC0: 14609 #ifndef CONFIG_USER_ONLY 14610 { 14611 uint32_t op2; 14612 TCGv t0 = tcg_temp_new(); 14613 14614 op2 = MASK_MFMC0(ctx->opcode); 14615 switch (op2) { 14616 case OPC_DMT: 14617 check_cp0_mt(ctx); 14618 gen_helper_dmt(t0); 14619 gen_store_gpr(t0, rt); 14620 break; 14621 case OPC_EMT: 14622 check_cp0_mt(ctx); 14623 gen_helper_emt(t0); 14624 gen_store_gpr(t0, rt); 14625 break; 14626 case OPC_DVPE: 14627 check_cp0_mt(ctx); 14628 gen_helper_dvpe(t0, tcg_env); 14629 gen_store_gpr(t0, rt); 14630 break; 14631 case OPC_EVPE: 14632 check_cp0_mt(ctx); 14633 gen_helper_evpe(t0, tcg_env); 14634 gen_store_gpr(t0, rt); 14635 break; 14636 case OPC_DVP: 14637 check_insn(ctx, ISA_MIPS_R6); 14638 if (ctx->vp) { 14639 gen_helper_dvp(t0, tcg_env); 14640 gen_store_gpr(t0, rt); 14641 } 14642 break; 14643 case OPC_EVP: 14644 check_insn(ctx, ISA_MIPS_R6); 14645 if (ctx->vp) { 14646 gen_helper_evp(t0, tcg_env); 14647 gen_store_gpr(t0, rt); 14648 } 14649 break; 14650 case OPC_DI: 14651 check_insn(ctx, ISA_MIPS_R2); 14652 save_cpu_state(ctx, 1); 14653 gen_helper_di(t0, tcg_env); 14654 gen_store_gpr(t0, rt); 14655 /* 14656 * Stop translation as we may have switched 14657 * the execution mode. 14658 */ 14659 ctx->base.is_jmp = DISAS_STOP; 14660 break; 14661 case OPC_EI: 14662 check_insn(ctx, ISA_MIPS_R2); 14663 save_cpu_state(ctx, 1); 14664 gen_helper_ei(t0, tcg_env); 14665 gen_store_gpr(t0, rt); 14666 /* 14667 * DISAS_STOP isn't sufficient, we need to ensure we break 14668 * out of translated code to check for pending interrupts. 14669 */ 14670 gen_save_pc(ctx->base.pc_next + 4); 14671 ctx->base.is_jmp = DISAS_EXIT; 14672 break; 14673 default: /* Invalid */ 14674 MIPS_INVAL("mfmc0"); 14675 gen_reserved_instruction(ctx); 14676 break; 14677 } 14678 } 14679 #endif /* !CONFIG_USER_ONLY */ 14680 break; 14681 case OPC_RDPGPR: 14682 check_insn(ctx, ISA_MIPS_R2); 14683 gen_load_srsgpr(rt, rd); 14684 break; 14685 case OPC_WRPGPR: 14686 check_insn(ctx, ISA_MIPS_R2); 14687 gen_store_srsgpr(rt, rd); 14688 break; 14689 default: 14690 MIPS_INVAL("cp0"); 14691 gen_reserved_instruction(ctx); 14692 break; 14693 } 14694 break; 14695 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14696 if (ctx->insn_flags & ISA_MIPS_R6) { 14697 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14698 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14699 } else { 14700 /* OPC_ADDI */ 14701 /* Arithmetic with immediate opcode */ 14702 gen_arith_imm(ctx, op, rt, rs, imm); 14703 } 14704 break; 14705 case OPC_ADDIU: 14706 gen_arith_imm(ctx, op, rt, rs, imm); 14707 break; 14708 case OPC_SLTI: /* Set on less than with immediate opcode */ 14709 case OPC_SLTIU: 14710 gen_slt_imm(ctx, op, rt, rs, imm); 14711 break; 14712 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14713 case OPC_LUI: /* OPC_AUI */ 14714 case OPC_ORI: 14715 case OPC_XORI: 14716 gen_logic_imm(ctx, op, rt, rs, imm); 14717 break; 14718 case OPC_J: /* Jump */ 14719 case OPC_JAL: 14720 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14721 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14722 break; 14723 /* Branch */ 14724 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14725 if (ctx->insn_flags & ISA_MIPS_R6) { 14726 if (rt == 0) { 14727 gen_reserved_instruction(ctx); 14728 break; 14729 } 14730 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14731 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14732 } else { 14733 /* OPC_BLEZL */ 14734 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14735 } 14736 break; 14737 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14738 if (ctx->insn_flags & ISA_MIPS_R6) { 14739 if (rt == 0) { 14740 gen_reserved_instruction(ctx); 14741 break; 14742 } 14743 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14744 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14745 } else { 14746 /* OPC_BGTZL */ 14747 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14748 } 14749 break; 14750 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14751 if (rt == 0) { 14752 /* OPC_BLEZ */ 14753 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14754 } else { 14755 check_insn(ctx, ISA_MIPS_R6); 14756 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14757 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14758 } 14759 break; 14760 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14761 if (rt == 0) { 14762 /* OPC_BGTZ */ 14763 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14764 } else { 14765 check_insn(ctx, ISA_MIPS_R6); 14766 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14767 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14768 } 14769 break; 14770 case OPC_BEQL: 14771 case OPC_BNEL: 14772 check_insn(ctx, ISA_MIPS2); 14773 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14774 /* Fallthrough */ 14775 case OPC_BEQ: 14776 case OPC_BNE: 14777 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14778 break; 14779 case OPC_LL: /* Load and stores */ 14780 check_insn(ctx, ISA_MIPS2); 14781 if (ctx->insn_flags & INSN_R5900) { 14782 check_insn_opc_user_only(ctx, INSN_R5900); 14783 } 14784 /* Fallthrough */ 14785 case OPC_LWL: 14786 case OPC_LWR: 14787 case OPC_LB: 14788 case OPC_LH: 14789 case OPC_LW: 14790 case OPC_LWPC: 14791 case OPC_LBU: 14792 case OPC_LHU: 14793 gen_ld(ctx, op, rt, rs, imm); 14794 break; 14795 case OPC_SWL: 14796 case OPC_SWR: 14797 case OPC_SB: 14798 case OPC_SH: 14799 case OPC_SW: 14800 gen_st(ctx, op, rt, rs, imm); 14801 break; 14802 case OPC_SC: 14803 check_insn(ctx, ISA_MIPS2); 14804 if (ctx->insn_flags & INSN_R5900) { 14805 check_insn_opc_user_only(ctx, INSN_R5900); 14806 } 14807 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14808 break; 14809 case OPC_CACHE: 14810 check_cp0_enabled(ctx); 14811 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14812 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14813 gen_cache_operation(ctx, rt, rs, imm); 14814 } 14815 /* Treat as NOP. */ 14816 break; 14817 case OPC_PREF: 14818 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14819 /* Treat as NOP. */ 14820 break; 14821 14822 /* Floating point (COP1). */ 14823 case OPC_LWC1: 14824 case OPC_LDC1: 14825 case OPC_SWC1: 14826 case OPC_SDC1: 14827 gen_cop1_ldst(ctx, op, rt, rs, imm); 14828 break; 14829 14830 case OPC_CP1: 14831 op1 = MASK_CP1(ctx->opcode); 14832 14833 switch (op1) { 14834 case OPC_MFHC1: 14835 case OPC_MTHC1: 14836 check_cp1_enabled(ctx); 14837 check_insn(ctx, ISA_MIPS_R2); 14838 /* fall through */ 14839 case OPC_MFC1: 14840 case OPC_CFC1: 14841 case OPC_MTC1: 14842 case OPC_CTC1: 14843 check_cp1_enabled(ctx); 14844 gen_cp1(ctx, op1, rt, rd); 14845 break; 14846 #if defined(TARGET_MIPS64) 14847 case OPC_DMFC1: 14848 case OPC_DMTC1: 14849 check_cp1_enabled(ctx); 14850 check_insn(ctx, ISA_MIPS3); 14851 check_mips_64(ctx); 14852 gen_cp1(ctx, op1, rt, rd); 14853 break; 14854 #endif 14855 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14856 check_cp1_enabled(ctx); 14857 if (ctx->insn_flags & ISA_MIPS_R6) { 14858 /* OPC_BC1EQZ */ 14859 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14860 rt, imm << 2, 4); 14861 } else { 14862 /* OPC_BC1ANY2 */ 14863 check_cop1x(ctx); 14864 check_insn(ctx, ASE_MIPS3D); 14865 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14866 (rt >> 2) & 0x7, imm << 2); 14867 } 14868 break; 14869 case OPC_BC1NEZ: 14870 check_cp1_enabled(ctx); 14871 check_insn(ctx, ISA_MIPS_R6); 14872 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14873 rt, imm << 2, 4); 14874 break; 14875 case OPC_BC1ANY4: 14876 check_cp1_enabled(ctx); 14877 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14878 check_cop1x(ctx); 14879 check_insn(ctx, ASE_MIPS3D); 14880 /* fall through */ 14881 case OPC_BC1: 14882 check_cp1_enabled(ctx); 14883 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14884 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14885 (rt >> 2) & 0x7, imm << 2); 14886 break; 14887 case OPC_PS_FMT: 14888 check_ps(ctx); 14889 /* fall through */ 14890 case OPC_S_FMT: 14891 case OPC_D_FMT: 14892 check_cp1_enabled(ctx); 14893 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14894 (imm >> 8) & 0x7); 14895 break; 14896 case OPC_W_FMT: 14897 case OPC_L_FMT: 14898 { 14899 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14900 check_cp1_enabled(ctx); 14901 if (ctx->insn_flags & ISA_MIPS_R6) { 14902 switch (r6_op) { 14903 case R6_OPC_CMP_AF_S: 14904 case R6_OPC_CMP_UN_S: 14905 case R6_OPC_CMP_EQ_S: 14906 case R6_OPC_CMP_UEQ_S: 14907 case R6_OPC_CMP_LT_S: 14908 case R6_OPC_CMP_ULT_S: 14909 case R6_OPC_CMP_LE_S: 14910 case R6_OPC_CMP_ULE_S: 14911 case R6_OPC_CMP_SAF_S: 14912 case R6_OPC_CMP_SUN_S: 14913 case R6_OPC_CMP_SEQ_S: 14914 case R6_OPC_CMP_SEUQ_S: 14915 case R6_OPC_CMP_SLT_S: 14916 case R6_OPC_CMP_SULT_S: 14917 case R6_OPC_CMP_SLE_S: 14918 case R6_OPC_CMP_SULE_S: 14919 case R6_OPC_CMP_OR_S: 14920 case R6_OPC_CMP_UNE_S: 14921 case R6_OPC_CMP_NE_S: 14922 case R6_OPC_CMP_SOR_S: 14923 case R6_OPC_CMP_SUNE_S: 14924 case R6_OPC_CMP_SNE_S: 14925 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14926 break; 14927 case R6_OPC_CMP_AF_D: 14928 case R6_OPC_CMP_UN_D: 14929 case R6_OPC_CMP_EQ_D: 14930 case R6_OPC_CMP_UEQ_D: 14931 case R6_OPC_CMP_LT_D: 14932 case R6_OPC_CMP_ULT_D: 14933 case R6_OPC_CMP_LE_D: 14934 case R6_OPC_CMP_ULE_D: 14935 case R6_OPC_CMP_SAF_D: 14936 case R6_OPC_CMP_SUN_D: 14937 case R6_OPC_CMP_SEQ_D: 14938 case R6_OPC_CMP_SEUQ_D: 14939 case R6_OPC_CMP_SLT_D: 14940 case R6_OPC_CMP_SULT_D: 14941 case R6_OPC_CMP_SLE_D: 14942 case R6_OPC_CMP_SULE_D: 14943 case R6_OPC_CMP_OR_D: 14944 case R6_OPC_CMP_UNE_D: 14945 case R6_OPC_CMP_NE_D: 14946 case R6_OPC_CMP_SOR_D: 14947 case R6_OPC_CMP_SUNE_D: 14948 case R6_OPC_CMP_SNE_D: 14949 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14950 break; 14951 default: 14952 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14953 rt, rd, sa, (imm >> 8) & 0x7); 14954 14955 break; 14956 } 14957 } else { 14958 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14959 (imm >> 8) & 0x7); 14960 } 14961 break; 14962 } 14963 default: 14964 MIPS_INVAL("cp1"); 14965 gen_reserved_instruction(ctx); 14966 break; 14967 } 14968 break; 14969 14970 /* Compact branches [R6] and COP2 [non-R6] */ 14971 case OPC_BC: /* OPC_LWC2 */ 14972 case OPC_BALC: /* OPC_SWC2 */ 14973 if (ctx->insn_flags & ISA_MIPS_R6) { 14974 /* OPC_BC, OPC_BALC */ 14975 gen_compute_compact_branch(ctx, op, 0, 0, 14976 sextract32(ctx->opcode << 2, 0, 28)); 14977 } else if (ctx->insn_flags & ASE_LEXT) { 14978 gen_loongson_lswc2(ctx, rt, rs, rd); 14979 } else { 14980 /* OPC_LWC2, OPC_SWC2 */ 14981 /* COP2: Not implemented. */ 14982 generate_exception_err(ctx, EXCP_CpU, 2); 14983 } 14984 break; 14985 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14986 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14987 if (ctx->insn_flags & ISA_MIPS_R6) { 14988 if (rs != 0) { 14989 /* OPC_BEQZC, OPC_BNEZC */ 14990 gen_compute_compact_branch(ctx, op, rs, 0, 14991 sextract32(ctx->opcode << 2, 0, 23)); 14992 } else { 14993 /* OPC_JIC, OPC_JIALC */ 14994 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14995 } 14996 } else if (ctx->insn_flags & ASE_LEXT) { 14997 gen_loongson_lsdc2(ctx, rt, rs, rd); 14998 } else { 14999 /* OPC_LWC2, OPC_SWC2 */ 15000 /* COP2: Not implemented. */ 15001 generate_exception_err(ctx, EXCP_CpU, 2); 15002 } 15003 break; 15004 case OPC_CP2: 15005 check_insn(ctx, ASE_LMMI); 15006 /* Note that these instructions use different fields. */ 15007 gen_loongson_multimedia(ctx, sa, rd, rt); 15008 break; 15009 15010 case OPC_CP3: 15011 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15012 check_cp1_enabled(ctx); 15013 op1 = MASK_CP3(ctx->opcode); 15014 switch (op1) { 15015 case OPC_LUXC1: 15016 case OPC_SUXC1: 15017 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15018 /* Fallthrough */ 15019 case OPC_LWXC1: 15020 case OPC_LDXC1: 15021 case OPC_SWXC1: 15022 case OPC_SDXC1: 15023 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15024 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15025 break; 15026 case OPC_PREFX: 15027 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15028 /* Treat as NOP. */ 15029 break; 15030 case OPC_ALNV_PS: 15031 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15032 /* Fallthrough */ 15033 case OPC_MADD_S: 15034 case OPC_MADD_D: 15035 case OPC_MADD_PS: 15036 case OPC_MSUB_S: 15037 case OPC_MSUB_D: 15038 case OPC_MSUB_PS: 15039 case OPC_NMADD_S: 15040 case OPC_NMADD_D: 15041 case OPC_NMADD_PS: 15042 case OPC_NMSUB_S: 15043 case OPC_NMSUB_D: 15044 case OPC_NMSUB_PS: 15045 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15046 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15047 break; 15048 default: 15049 MIPS_INVAL("cp3"); 15050 gen_reserved_instruction(ctx); 15051 break; 15052 } 15053 } else { 15054 generate_exception_err(ctx, EXCP_CpU, 1); 15055 } 15056 break; 15057 15058 #if defined(TARGET_MIPS64) 15059 /* MIPS64 opcodes */ 15060 case OPC_LLD: 15061 if (ctx->insn_flags & INSN_R5900) { 15062 check_insn_opc_user_only(ctx, INSN_R5900); 15063 } 15064 /* fall through */ 15065 case OPC_LDL: 15066 case OPC_LDR: 15067 case OPC_LWU: 15068 case OPC_LD: 15069 check_insn(ctx, ISA_MIPS3); 15070 check_mips_64(ctx); 15071 gen_ld(ctx, op, rt, rs, imm); 15072 break; 15073 case OPC_SDL: 15074 case OPC_SDR: 15075 case OPC_SD: 15076 check_insn(ctx, ISA_MIPS3); 15077 check_mips_64(ctx); 15078 gen_st(ctx, op, rt, rs, imm); 15079 break; 15080 case OPC_SCD: 15081 check_insn(ctx, ISA_MIPS3); 15082 if (ctx->insn_flags & INSN_R5900) { 15083 check_insn_opc_user_only(ctx, INSN_R5900); 15084 } 15085 check_mips_64(ctx); 15086 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 15087 break; 15088 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 15089 if (ctx->insn_flags & ISA_MIPS_R6) { 15090 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 15091 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15092 } else { 15093 /* OPC_DADDI */ 15094 check_insn(ctx, ISA_MIPS3); 15095 check_mips_64(ctx); 15096 gen_arith_imm(ctx, op, rt, rs, imm); 15097 } 15098 break; 15099 case OPC_DADDIU: 15100 check_insn(ctx, ISA_MIPS3); 15101 check_mips_64(ctx); 15102 gen_arith_imm(ctx, op, rt, rs, imm); 15103 break; 15104 #else 15105 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 15106 if (ctx->insn_flags & ISA_MIPS_R6) { 15107 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15108 } else { 15109 MIPS_INVAL("major opcode"); 15110 gen_reserved_instruction(ctx); 15111 } 15112 break; 15113 #endif 15114 case OPC_DAUI: /* OPC_JALX */ 15115 if (ctx->insn_flags & ISA_MIPS_R6) { 15116 #if defined(TARGET_MIPS64) 15117 /* OPC_DAUI */ 15118 check_mips_64(ctx); 15119 if (rs == 0) { 15120 generate_exception(ctx, EXCP_RI); 15121 } else if (rt != 0) { 15122 TCGv t0 = tcg_temp_new(); 15123 gen_load_gpr(t0, rs); 15124 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 15125 } 15126 #else 15127 gen_reserved_instruction(ctx); 15128 MIPS_INVAL("major opcode"); 15129 #endif 15130 } else { 15131 /* OPC_JALX */ 15132 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 15133 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15134 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15135 } 15136 break; 15137 case OPC_MDMX: 15138 /* MDMX: Not implemented. */ 15139 break; 15140 case OPC_PCREL: 15141 check_insn(ctx, ISA_MIPS_R6); 15142 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15143 break; 15144 default: /* Invalid */ 15145 MIPS_INVAL("major opcode"); 15146 return false; 15147 } 15148 return true; 15149 } 15150 15151 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15152 { 15153 /* make sure instructions are on a word boundary */ 15154 if (ctx->base.pc_next & 0x3) { 15155 env->CP0_BadVAddr = ctx->base.pc_next; 15156 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15157 return; 15158 } 15159 15160 /* Handle blikely not taken case */ 15161 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15162 TCGLabel *l1 = gen_new_label(); 15163 15164 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15165 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15166 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15167 gen_set_label(l1); 15168 } 15169 15170 /* Transition to the auto-generated decoder. */ 15171 15172 /* Vendor specific extensions */ 15173 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15174 return; 15175 } 15176 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15177 return; 15178 } 15179 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15180 return; 15181 } 15182 #if defined(TARGET_MIPS64) 15183 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15184 return; 15185 } 15186 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15187 return; 15188 } 15189 #endif 15190 15191 /* ISA extensions */ 15192 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15193 return; 15194 } 15195 15196 /* ISA (from latest to oldest) */ 15197 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15198 return; 15199 } 15200 15201 if (decode_opc_legacy(env, ctx)) { 15202 return; 15203 } 15204 15205 gen_reserved_instruction(ctx); 15206 } 15207 15208 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15209 { 15210 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15211 CPUMIPSState *env = cpu_env(cs); 15212 15213 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15214 ctx->saved_pc = -1; 15215 ctx->insn_flags = env->insn_flags; 15216 ctx->CP0_Config0 = env->CP0_Config0; 15217 ctx->CP0_Config1 = env->CP0_Config1; 15218 ctx->CP0_Config2 = env->CP0_Config2; 15219 ctx->CP0_Config3 = env->CP0_Config3; 15220 ctx->CP0_Config5 = env->CP0_Config5; 15221 ctx->btarget = 0; 15222 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15223 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15224 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15225 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15226 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15227 ctx->PAMask = env->PAMask; 15228 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15229 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15230 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15231 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15232 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15233 /* Restore delay slot state from the tb context. */ 15234 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15235 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15236 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15237 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15238 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15239 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15240 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15241 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15242 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15243 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15244 restore_cpu_state(env, ctx); 15245 #ifdef CONFIG_USER_ONLY 15246 ctx->mem_idx = MIPS_HFLAG_UM; 15247 #else 15248 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15249 #endif 15250 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15251 (ctx->insn_flags & (ISA_MIPS_R6 | 15252 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15253 15254 /* 15255 * Execute a branch and its delay slot as a single instruction. 15256 * This is what GDB expects and is consistent with what the 15257 * hardware does (e.g. if a delay slot instruction faults, the 15258 * reported PC is the PC of the branch). 15259 */ 15260 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15261 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15262 ctx->base.max_insns = 2; 15263 } 15264 15265 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15266 ctx->hflags); 15267 } 15268 15269 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15270 { 15271 } 15272 15273 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15274 { 15275 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15276 15277 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15278 ctx->btarget); 15279 } 15280 15281 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15282 { 15283 CPUMIPSState *env = cpu_env(cs); 15284 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15285 int insn_bytes; 15286 int is_slot; 15287 15288 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15289 if (ctx->insn_flags & ISA_NANOMIPS32) { 15290 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15291 insn_bytes = decode_isa_nanomips(env, ctx); 15292 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15293 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15294 insn_bytes = 4; 15295 decode_opc(env, ctx); 15296 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15297 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15298 insn_bytes = decode_isa_micromips(env, ctx); 15299 } else if (ctx->insn_flags & ASE_MIPS16) { 15300 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15301 insn_bytes = decode_ase_mips16e(env, ctx); 15302 } else { 15303 gen_reserved_instruction(ctx); 15304 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15305 return; 15306 } 15307 15308 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15309 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15310 MIPS_HFLAG_FBNSLOT))) { 15311 /* 15312 * Force to generate branch as there is neither delay nor 15313 * forbidden slot. 15314 */ 15315 is_slot = 1; 15316 } 15317 if ((ctx->hflags & MIPS_HFLAG_M16) && 15318 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15319 /* 15320 * Force to generate branch as microMIPS R6 doesn't restrict 15321 * branches in the forbidden slot. 15322 */ 15323 is_slot = 1; 15324 } 15325 } 15326 if (is_slot) { 15327 gen_branch(ctx, insn_bytes); 15328 } 15329 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15330 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15331 } 15332 ctx->base.pc_next += insn_bytes; 15333 15334 if (ctx->base.is_jmp != DISAS_NEXT) { 15335 return; 15336 } 15337 15338 /* 15339 * End the TB on (most) page crossings. 15340 * See mips_tr_init_disas_context about single-stepping a branch 15341 * together with its delay slot. 15342 */ 15343 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15344 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15345 ctx->base.is_jmp = DISAS_TOO_MANY; 15346 } 15347 } 15348 15349 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15350 { 15351 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15352 15353 switch (ctx->base.is_jmp) { 15354 case DISAS_STOP: 15355 gen_save_pc(ctx->base.pc_next); 15356 tcg_gen_lookup_and_goto_ptr(); 15357 break; 15358 case DISAS_NEXT: 15359 case DISAS_TOO_MANY: 15360 save_cpu_state(ctx, 0); 15361 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15362 break; 15363 case DISAS_EXIT: 15364 tcg_gen_exit_tb(NULL, 0); 15365 break; 15366 case DISAS_NORETURN: 15367 break; 15368 default: 15369 g_assert_not_reached(); 15370 } 15371 } 15372 15373 static const TranslatorOps mips_tr_ops = { 15374 .init_disas_context = mips_tr_init_disas_context, 15375 .tb_start = mips_tr_tb_start, 15376 .insn_start = mips_tr_insn_start, 15377 .translate_insn = mips_tr_translate_insn, 15378 .tb_stop = mips_tr_tb_stop, 15379 }; 15380 15381 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, 15382 vaddr pc, void *host_pc) 15383 { 15384 DisasContext ctx; 15385 15386 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15387 } 15388 15389 void mips_tcg_init(void) 15390 { 15391 cpu_gpr[0] = NULL; 15392 for (unsigned i = 1; i < 32; i++) 15393 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15394 offsetof(CPUMIPSState, 15395 active_tc.gpr[i]), 15396 regnames[i]); 15397 #if defined(TARGET_MIPS64) 15398 cpu_gpr_hi[0] = NULL; 15399 15400 for (unsigned i = 1; i < 32; i++) { 15401 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15402 15403 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15404 offsetof(CPUMIPSState, 15405 active_tc.gpr_hi[i]), 15406 rname); 15407 } 15408 #endif /* !TARGET_MIPS64 */ 15409 for (unsigned i = 0; i < 32; i++) { 15410 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15411 15412 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15413 } 15414 msa_translate_init(); 15415 cpu_PC = tcg_global_mem_new(tcg_env, 15416 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15417 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15418 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15419 offsetof(CPUMIPSState, active_tc.HI[i]), 15420 regnames_HI[i]); 15421 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15422 offsetof(CPUMIPSState, active_tc.LO[i]), 15423 regnames_LO[i]); 15424 } 15425 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15426 offsetof(CPUMIPSState, 15427 active_tc.DSPControl), 15428 "DSPControl"); 15429 bcond = tcg_global_mem_new(tcg_env, 15430 offsetof(CPUMIPSState, bcond), "bcond"); 15431 btarget = tcg_global_mem_new(tcg_env, 15432 offsetof(CPUMIPSState, btarget), "btarget"); 15433 hflags = tcg_global_mem_new_i32(tcg_env, 15434 offsetof(CPUMIPSState, hflags), "hflags"); 15435 15436 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15437 offsetof(CPUMIPSState, active_fpu.fcr0), 15438 "fcr0"); 15439 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15440 offsetof(CPUMIPSState, active_fpu.fcr31), 15441 "fcr31"); 15442 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15443 "lladdr"); 15444 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15445 "llval"); 15446 15447 if (TARGET_LONG_BITS == 32) { 15448 mxu_translate_init(); 15449 } 15450 } 15451 15452 void mips_restore_state_to_opc(CPUState *cs, 15453 const TranslationBlock *tb, 15454 const uint64_t *data) 15455 { 15456 CPUMIPSState *env = cpu_env(cs); 15457 15458 env->active_tc.PC = data[0]; 15459 env->hflags &= ~MIPS_HFLAG_BMASK; 15460 env->hflags |= data[1]; 15461 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15462 case MIPS_HFLAG_BR: 15463 break; 15464 case MIPS_HFLAG_BC: 15465 case MIPS_HFLAG_BL: 15466 case MIPS_HFLAG_B: 15467 env->btarget = data[2]; 15468 break; 15469 } 15470 } 15471