1 /* 2 * MIPS emulation for QEMU - main translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "cpu.h" 27 #include "internal.h" 28 #include "tcg/tcg-op.h" 29 #include "exec/translator.h" 30 #include "exec/helper-proto.h" 31 #include "exec/helper-gen.h" 32 #include "semihosting/semihost.h" 33 34 #include "trace.h" 35 #include "exec/log.h" 36 #include "qemu/qemu-print.h" 37 #include "fpu_helper.h" 38 #include "translate.h" 39 40 /* 41 * Many sysemu-only helpers are not reachable for user-only. 42 * Define stub generators here, so that we need not either sprinkle 43 * ifdefs through the translator, nor provide the helper function. 44 */ 45 #define STUB_HELPER(NAME, ...) \ 46 static inline void gen_helper_##NAME(__VA_ARGS__) \ 47 { g_assert_not_reached(); } 48 49 #ifdef CONFIG_USER_ONLY 50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 51 #endif 52 53 enum { 54 /* indirect opcode tables */ 55 OPC_SPECIAL = (0x00 << 26), 56 OPC_REGIMM = (0x01 << 26), 57 OPC_CP0 = (0x10 << 26), 58 OPC_CP2 = (0x12 << 26), 59 OPC_CP3 = (0x13 << 26), 60 OPC_SPECIAL2 = (0x1C << 26), 61 OPC_SPECIAL3 = (0x1F << 26), 62 /* arithmetic with immediate */ 63 OPC_ADDI = (0x08 << 26), 64 OPC_ADDIU = (0x09 << 26), 65 OPC_SLTI = (0x0A << 26), 66 OPC_SLTIU = (0x0B << 26), 67 /* logic with immediate */ 68 OPC_ANDI = (0x0C << 26), 69 OPC_ORI = (0x0D << 26), 70 OPC_XORI = (0x0E << 26), 71 OPC_LUI = (0x0F << 26), 72 /* arithmetic with immediate */ 73 OPC_DADDI = (0x18 << 26), 74 OPC_DADDIU = (0x19 << 26), 75 /* Jump and branches */ 76 OPC_J = (0x02 << 26), 77 OPC_JAL = (0x03 << 26), 78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 79 OPC_BEQL = (0x14 << 26), 80 OPC_BNE = (0x05 << 26), 81 OPC_BNEL = (0x15 << 26), 82 OPC_BLEZ = (0x06 << 26), 83 OPC_BLEZL = (0x16 << 26), 84 OPC_BGTZ = (0x07 << 26), 85 OPC_BGTZL = (0x17 << 26), 86 OPC_JALX = (0x1D << 26), 87 OPC_DAUI = (0x1D << 26), 88 /* Load and stores */ 89 OPC_LDL = (0x1A << 26), 90 OPC_LDR = (0x1B << 26), 91 OPC_LB = (0x20 << 26), 92 OPC_LH = (0x21 << 26), 93 OPC_LWL = (0x22 << 26), 94 OPC_LW = (0x23 << 26), 95 OPC_LWPC = OPC_LW | 0x5, 96 OPC_LBU = (0x24 << 26), 97 OPC_LHU = (0x25 << 26), 98 OPC_LWR = (0x26 << 26), 99 OPC_LWU = (0x27 << 26), 100 OPC_SB = (0x28 << 26), 101 OPC_SH = (0x29 << 26), 102 OPC_SWL = (0x2A << 26), 103 OPC_SW = (0x2B << 26), 104 OPC_SDL = (0x2C << 26), 105 OPC_SDR = (0x2D << 26), 106 OPC_SWR = (0x2E << 26), 107 OPC_LL = (0x30 << 26), 108 OPC_LLD = (0x34 << 26), 109 OPC_LD = (0x37 << 26), 110 OPC_LDPC = OPC_LD | 0x5, 111 OPC_SC = (0x38 << 26), 112 OPC_SCD = (0x3C << 26), 113 OPC_SD = (0x3F << 26), 114 /* Floating point load/store */ 115 OPC_LWC1 = (0x31 << 26), 116 OPC_LWC2 = (0x32 << 26), 117 OPC_LDC1 = (0x35 << 26), 118 OPC_LDC2 = (0x36 << 26), 119 OPC_SWC1 = (0x39 << 26), 120 OPC_SWC2 = (0x3A << 26), 121 OPC_SDC1 = (0x3D << 26), 122 OPC_SDC2 = (0x3E << 26), 123 /* Compact Branches */ 124 OPC_BLEZALC = (0x06 << 26), 125 OPC_BGEZALC = (0x06 << 26), 126 OPC_BGEUC = (0x06 << 26), 127 OPC_BGTZALC = (0x07 << 26), 128 OPC_BLTZALC = (0x07 << 26), 129 OPC_BLTUC = (0x07 << 26), 130 OPC_BOVC = (0x08 << 26), 131 OPC_BEQZALC = (0x08 << 26), 132 OPC_BEQC = (0x08 << 26), 133 OPC_BLEZC = (0x16 << 26), 134 OPC_BGEZC = (0x16 << 26), 135 OPC_BGEC = (0x16 << 26), 136 OPC_BGTZC = (0x17 << 26), 137 OPC_BLTZC = (0x17 << 26), 138 OPC_BLTC = (0x17 << 26), 139 OPC_BNVC = (0x18 << 26), 140 OPC_BNEZALC = (0x18 << 26), 141 OPC_BNEC = (0x18 << 26), 142 OPC_BC = (0x32 << 26), 143 OPC_BEQZC = (0x36 << 26), 144 OPC_JIC = (0x36 << 26), 145 OPC_BALC = (0x3A << 26), 146 OPC_BNEZC = (0x3E << 26), 147 OPC_JIALC = (0x3E << 26), 148 /* MDMX ASE specific */ 149 OPC_MDMX = (0x1E << 26), 150 /* Cache and prefetch */ 151 OPC_CACHE = (0x2F << 26), 152 OPC_PREF = (0x33 << 26), 153 /* PC-relative address computation / loads */ 154 OPC_PCREL = (0x3B << 26), 155 }; 156 157 /* PC-relative address computation / loads */ 158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 160 enum { 161 /* Instructions determined by bits 19 and 20 */ 162 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 163 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 164 OPC_LWUPC = OPC_PCREL | (2 << 19), 165 166 /* Instructions determined by bits 16 ... 20 */ 167 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 169 170 /* Other */ 171 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 172 }; 173 174 /* MIPS special opcodes */ 175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 176 177 enum { 178 /* Shifts */ 179 OPC_SLL = 0x00 | OPC_SPECIAL, 180 /* NOP is SLL r0, r0, 0 */ 181 /* SSNOP is SLL r0, r0, 1 */ 182 /* EHB is SLL r0, r0, 3 */ 183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 184 OPC_ROTR = OPC_SRL | (1 << 21), 185 OPC_SRA = 0x03 | OPC_SPECIAL, 186 OPC_SLLV = 0x04 | OPC_SPECIAL, 187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 188 OPC_ROTRV = OPC_SRLV | (1 << 6), 189 OPC_SRAV = 0x07 | OPC_SPECIAL, 190 OPC_DSLLV = 0x14 | OPC_SPECIAL, 191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 192 OPC_DROTRV = OPC_DSRLV | (1 << 6), 193 OPC_DSRAV = 0x17 | OPC_SPECIAL, 194 OPC_DSLL = 0x38 | OPC_SPECIAL, 195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 196 OPC_DROTR = OPC_DSRL | (1 << 21), 197 OPC_DSRA = 0x3B | OPC_SPECIAL, 198 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 201 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 202 /* Multiplication / division */ 203 OPC_MULT = 0x18 | OPC_SPECIAL, 204 OPC_MULTU = 0x19 | OPC_SPECIAL, 205 OPC_DIV = 0x1A | OPC_SPECIAL, 206 OPC_DIVU = 0x1B | OPC_SPECIAL, 207 OPC_DMULT = 0x1C | OPC_SPECIAL, 208 OPC_DMULTU = 0x1D | OPC_SPECIAL, 209 OPC_DDIV = 0x1E | OPC_SPECIAL, 210 OPC_DDIVU = 0x1F | OPC_SPECIAL, 211 212 /* 2 registers arithmetic / logic */ 213 OPC_ADD = 0x20 | OPC_SPECIAL, 214 OPC_ADDU = 0x21 | OPC_SPECIAL, 215 OPC_SUB = 0x22 | OPC_SPECIAL, 216 OPC_SUBU = 0x23 | OPC_SPECIAL, 217 OPC_AND = 0x24 | OPC_SPECIAL, 218 OPC_OR = 0x25 | OPC_SPECIAL, 219 OPC_XOR = 0x26 | OPC_SPECIAL, 220 OPC_NOR = 0x27 | OPC_SPECIAL, 221 OPC_SLT = 0x2A | OPC_SPECIAL, 222 OPC_SLTU = 0x2B | OPC_SPECIAL, 223 OPC_DADD = 0x2C | OPC_SPECIAL, 224 OPC_DADDU = 0x2D | OPC_SPECIAL, 225 OPC_DSUB = 0x2E | OPC_SPECIAL, 226 OPC_DSUBU = 0x2F | OPC_SPECIAL, 227 /* Jumps */ 228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 230 /* Traps */ 231 OPC_TGE = 0x30 | OPC_SPECIAL, 232 OPC_TGEU = 0x31 | OPC_SPECIAL, 233 OPC_TLT = 0x32 | OPC_SPECIAL, 234 OPC_TLTU = 0x33 | OPC_SPECIAL, 235 OPC_TEQ = 0x34 | OPC_SPECIAL, 236 OPC_TNE = 0x36 | OPC_SPECIAL, 237 /* HI / LO registers load & stores */ 238 OPC_MFHI = 0x10 | OPC_SPECIAL, 239 OPC_MTHI = 0x11 | OPC_SPECIAL, 240 OPC_MFLO = 0x12 | OPC_SPECIAL, 241 OPC_MTLO = 0x13 | OPC_SPECIAL, 242 /* Conditional moves */ 243 OPC_MOVZ = 0x0A | OPC_SPECIAL, 244 OPC_MOVN = 0x0B | OPC_SPECIAL, 245 246 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 247 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 248 249 OPC_MOVCI = 0x01 | OPC_SPECIAL, 250 251 /* Special */ 252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 253 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 254 OPC_BREAK = 0x0D | OPC_SPECIAL, 255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 256 OPC_SYNC = 0x0F | OPC_SPECIAL, 257 258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 262 }; 263 264 /* 265 * R6 Multiply and Divide instructions have the same opcode 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 267 */ 268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 269 270 enum { 271 R6_OPC_MUL = OPC_MULT | (2 << 6), 272 R6_OPC_MUH = OPC_MULT | (3 << 6), 273 R6_OPC_MULU = OPC_MULTU | (2 << 6), 274 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 275 R6_OPC_DIV = OPC_DIV | (2 << 6), 276 R6_OPC_MOD = OPC_DIV | (3 << 6), 277 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 278 R6_OPC_MODU = OPC_DIVU | (3 << 6), 279 280 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 281 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 284 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 285 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 288 289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 290 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 294 }; 295 296 /* REGIMM (rt field) opcodes */ 297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 298 299 enum { 300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 316 317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 318 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 319 }; 320 321 /* Special2 opcodes */ 322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 323 324 enum { 325 /* Multiply & xxx operations */ 326 OPC_MADD = 0x00 | OPC_SPECIAL2, 327 OPC_MADDU = 0x01 | OPC_SPECIAL2, 328 OPC_MUL = 0x02 | OPC_SPECIAL2, 329 OPC_MSUB = 0x04 | OPC_SPECIAL2, 330 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 331 /* Loongson 2F */ 332 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 333 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 334 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 335 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 336 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 337 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 338 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 339 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 340 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 341 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 342 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 343 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 344 /* Misc */ 345 OPC_CLZ = 0x20 | OPC_SPECIAL2, 346 OPC_CLO = 0x21 | OPC_SPECIAL2, 347 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 348 OPC_DCLO = 0x25 | OPC_SPECIAL2, 349 /* Special */ 350 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 351 }; 352 353 /* Special3 opcodes */ 354 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 355 356 enum { 357 OPC_EXT = 0x00 | OPC_SPECIAL3, 358 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 359 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 360 OPC_DEXT = 0x03 | OPC_SPECIAL3, 361 OPC_INS = 0x04 | OPC_SPECIAL3, 362 OPC_DINSM = 0x05 | OPC_SPECIAL3, 363 OPC_DINSU = 0x06 | OPC_SPECIAL3, 364 OPC_DINS = 0x07 | OPC_SPECIAL3, 365 OPC_FORK = 0x08 | OPC_SPECIAL3, 366 OPC_YIELD = 0x09 | OPC_SPECIAL3, 367 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 368 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 369 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 370 OPC_GINV = 0x3D | OPC_SPECIAL3, 371 372 /* Loongson 2E */ 373 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 374 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 375 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 376 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 377 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 378 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 379 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 380 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 381 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 382 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 383 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 384 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 385 386 /* MIPS DSP Load */ 387 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 388 /* MIPS DSP Arithmetic */ 389 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 390 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 391 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 392 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 393 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 394 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 395 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 396 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 397 /* MIPS DSP GPR-Based Shift Sub-class */ 398 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 399 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 400 /* MIPS DSP Multiply Sub-class insns */ 401 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 402 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 403 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 404 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 405 /* DSP Bit/Manipulation Sub-class */ 406 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 407 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 408 /* MIPS DSP Append Sub-class */ 409 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 410 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 411 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 412 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 413 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 414 415 /* EVA */ 416 OPC_LWLE = 0x19 | OPC_SPECIAL3, 417 OPC_LWRE = 0x1A | OPC_SPECIAL3, 418 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 419 OPC_SBE = 0x1C | OPC_SPECIAL3, 420 OPC_SHE = 0x1D | OPC_SPECIAL3, 421 OPC_SCE = 0x1E | OPC_SPECIAL3, 422 OPC_SWE = 0x1F | OPC_SPECIAL3, 423 OPC_SWLE = 0x21 | OPC_SPECIAL3, 424 OPC_SWRE = 0x22 | OPC_SPECIAL3, 425 OPC_PREFE = 0x23 | OPC_SPECIAL3, 426 OPC_LBUE = 0x28 | OPC_SPECIAL3, 427 OPC_LHUE = 0x29 | OPC_SPECIAL3, 428 OPC_LBE = 0x2C | OPC_SPECIAL3, 429 OPC_LHE = 0x2D | OPC_SPECIAL3, 430 OPC_LLE = 0x2E | OPC_SPECIAL3, 431 OPC_LWE = 0x2F | OPC_SPECIAL3, 432 433 /* R6 */ 434 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 435 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 436 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 437 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 438 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 439 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 440 }; 441 442 /* Loongson EXT load/store quad word opcodes */ 443 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 444 enum { 445 OPC_GSLQ = 0x0020 | OPC_LWC2, 446 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 447 OPC_GSSHFL = OPC_LWC2, 448 OPC_GSSQ = 0x0020 | OPC_SWC2, 449 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 450 OPC_GSSHFS = OPC_SWC2, 451 }; 452 453 /* Loongson EXT shifted load/store opcodes */ 454 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 455 enum { 456 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 457 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 458 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 459 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 460 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 461 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 462 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 463 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 464 }; 465 466 /* Loongson EXT LDC2/SDC2 opcodes */ 467 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 468 469 enum { 470 OPC_GSLBX = 0x0 | OPC_LDC2, 471 OPC_GSLHX = 0x1 | OPC_LDC2, 472 OPC_GSLWX = 0x2 | OPC_LDC2, 473 OPC_GSLDX = 0x3 | OPC_LDC2, 474 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 475 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 476 OPC_GSSBX = 0x0 | OPC_SDC2, 477 OPC_GSSHX = 0x1 | OPC_SDC2, 478 OPC_GSSWX = 0x2 | OPC_SDC2, 479 OPC_GSSDX = 0x3 | OPC_SDC2, 480 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 481 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 482 }; 483 484 /* BSHFL opcodes */ 485 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 486 487 enum { 488 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 489 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 490 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 491 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 492 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 493 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 494 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 495 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 496 }; 497 498 /* DBSHFL opcodes */ 499 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 500 501 enum { 502 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 503 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 504 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 505 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 506 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 507 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 508 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 509 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 510 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 511 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 512 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 513 }; 514 515 /* MIPS DSP REGIMM opcodes */ 516 enum { 517 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 518 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 519 }; 520 521 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 522 /* MIPS DSP Load */ 523 enum { 524 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 525 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 526 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 527 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 528 }; 529 530 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 531 enum { 532 /* MIPS DSP Arithmetic Sub-class */ 533 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 534 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 535 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 536 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 537 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 538 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 539 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 540 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 541 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 542 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 543 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 544 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 545 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 546 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 547 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 548 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 549 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 550 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 551 /* MIPS DSP Multiply Sub-class insns */ 552 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 553 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 554 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 555 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 556 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 557 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 558 }; 559 560 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 561 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 562 enum { 563 /* MIPS DSP Arithmetic Sub-class */ 564 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 565 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 566 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 567 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 568 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 569 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 570 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 571 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 572 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 573 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 574 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 575 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 576 /* MIPS DSP Multiply Sub-class insns */ 577 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 578 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 579 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 580 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 581 }; 582 583 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 584 enum { 585 /* MIPS DSP Arithmetic Sub-class */ 586 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 587 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 588 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 589 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 590 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 591 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 592 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 593 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 594 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 595 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 596 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 597 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 598 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 599 /* DSP Bit/Manipulation Sub-class */ 600 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 601 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 602 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 603 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 604 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 605 }; 606 607 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 608 enum { 609 /* MIPS DSP Arithmetic Sub-class */ 610 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 611 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 612 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 613 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 614 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 615 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 616 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 617 /* DSP Compare-Pick Sub-class */ 618 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 619 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 620 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 621 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 622 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 623 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 624 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 625 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 626 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 627 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 628 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 629 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 630 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 631 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 632 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 633 }; 634 635 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 636 enum { 637 /* MIPS DSP GPR-Based Shift Sub-class */ 638 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 639 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 640 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 641 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 642 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 643 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 644 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 645 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 646 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 647 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 648 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 649 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 650 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 651 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 652 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 653 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 654 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 655 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 656 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 657 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 658 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 659 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 660 }; 661 662 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 663 enum { 664 /* MIPS DSP Multiply Sub-class insns */ 665 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 666 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 667 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 668 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 669 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 670 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 671 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 672 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 673 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 674 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 675 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 676 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 677 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 678 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 679 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 680 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 681 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 682 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 683 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 684 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 685 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 686 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 687 }; 688 689 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 690 enum { 691 /* DSP Bit/Manipulation Sub-class */ 692 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 693 }; 694 695 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 696 enum { 697 /* MIPS DSP Append Sub-class */ 698 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 699 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 700 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 701 }; 702 703 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 704 enum { 705 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 706 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 707 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 708 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 709 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 710 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 711 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 712 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 713 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 714 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 715 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 716 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 717 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 718 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 719 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 720 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 721 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 722 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 723 }; 724 725 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 726 enum { 727 /* MIPS DSP Arithmetic Sub-class */ 728 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 729 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 730 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 731 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 732 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 733 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 734 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 735 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 736 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 737 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 738 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 739 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 740 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 741 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 742 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 743 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 744 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 745 /* DSP Bit/Manipulation Sub-class */ 746 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 747 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 748 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 749 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 750 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 752 }; 753 754 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 755 enum { 756 /* MIPS DSP Multiply Sub-class insns */ 757 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 758 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 759 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 760 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 761 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 762 /* MIPS DSP Arithmetic Sub-class */ 763 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 764 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 765 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 766 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 767 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 768 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 769 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 770 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 771 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 772 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 773 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 774 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 775 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 776 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 777 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 778 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 779 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 780 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 781 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 782 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 783 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 784 }; 785 786 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 787 enum { 788 /* DSP Compare-Pick Sub-class */ 789 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 790 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 791 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 792 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 793 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 794 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 795 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 796 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 797 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 798 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 799 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 800 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 801 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 802 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 803 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 804 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 805 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 806 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 807 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 808 /* MIPS DSP Arithmetic Sub-class */ 809 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 810 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 811 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 817 }; 818 819 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 820 enum { 821 /* DSP Append Sub-class */ 822 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 823 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 824 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 825 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 826 }; 827 828 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 829 enum { 830 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 831 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 832 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 833 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 834 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 835 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 836 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 837 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 838 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 839 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 840 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 841 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 842 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 843 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 844 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 845 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 846 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 847 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 848 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 849 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 850 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 851 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 852 }; 853 854 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 855 enum { 856 /* DSP Bit/Manipulation Sub-class */ 857 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 858 }; 859 860 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 861 enum { 862 /* MIPS DSP Multiply Sub-class insns */ 863 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 864 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 865 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 866 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 867 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 868 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 869 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 870 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 871 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 872 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 873 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 874 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 875 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 876 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 877 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 878 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 879 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 880 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 881 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 882 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 883 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 884 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 885 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 889 }; 890 891 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 892 enum { 893 /* MIPS DSP GPR-Based Shift Sub-class */ 894 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 895 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 896 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 897 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 898 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 899 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 900 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 901 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 902 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 903 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 904 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 905 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 906 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 907 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 908 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 909 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 910 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 911 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 912 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 913 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 914 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 915 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 916 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 920 }; 921 922 /* Coprocessor 0 (rs field) */ 923 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 924 925 enum { 926 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 927 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 928 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 929 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 930 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 931 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 932 OPC_MFTR = (0x08 << 21) | OPC_CP0, 933 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 934 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 935 OPC_MTTR = (0x0C << 21) | OPC_CP0, 936 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 937 OPC_C0 = (0x10 << 21) | OPC_CP0, 938 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 939 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 940 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 941 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 942 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 943 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 944 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 945 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 946 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 947 OPC_C0_A = (0x1A << 21) | OPC_CP0, 948 OPC_C0_B = (0x1B << 21) | OPC_CP0, 949 OPC_C0_C = (0x1C << 21) | OPC_CP0, 950 OPC_C0_D = (0x1D << 21) | OPC_CP0, 951 OPC_C0_E = (0x1E << 21) | OPC_CP0, 952 OPC_C0_F = (0x1F << 21) | OPC_CP0, 953 }; 954 955 /* MFMC0 opcodes */ 956 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 957 958 enum { 959 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 960 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 961 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 962 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 963 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 964 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 965 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 966 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 967 }; 968 969 /* Coprocessor 0 (with rs == C0) */ 970 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 971 972 enum { 973 OPC_TLBR = 0x01 | OPC_C0, 974 OPC_TLBWI = 0x02 | OPC_C0, 975 OPC_TLBINV = 0x03 | OPC_C0, 976 OPC_TLBINVF = 0x04 | OPC_C0, 977 OPC_TLBWR = 0x06 | OPC_C0, 978 OPC_TLBP = 0x08 | OPC_C0, 979 OPC_RFE = 0x10 | OPC_C0, 980 OPC_ERET = 0x18 | OPC_C0, 981 OPC_DERET = 0x1F | OPC_C0, 982 OPC_WAIT = 0x20 | OPC_C0, 983 }; 984 985 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 986 987 enum { 988 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 989 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 990 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 991 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 992 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 993 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 994 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 995 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 996 OPC_BC2 = (0x08 << 21) | OPC_CP2, 997 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 998 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 999 }; 1000 1001 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1002 1003 enum { 1004 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1005 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1006 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1007 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1008 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1009 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1010 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1011 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1012 1013 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1014 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1015 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1016 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1017 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1018 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1019 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1020 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1021 1022 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1023 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1024 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1025 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1026 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1027 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1028 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1029 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1030 1031 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1032 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1033 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1034 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1035 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1036 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1037 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1038 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1039 1040 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1041 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1042 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1043 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1044 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1045 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1046 1047 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1048 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1049 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1050 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1051 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1052 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1053 1054 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1055 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1056 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1057 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1058 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1059 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1060 1061 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1062 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1063 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1064 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1065 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1066 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1067 1068 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1069 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1070 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1071 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1072 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1073 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1074 1075 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1076 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1077 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1078 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1079 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1080 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1081 1082 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1083 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1084 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1085 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1086 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1087 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1088 1089 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1090 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1091 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1092 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1093 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1094 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1095 }; 1096 1097 1098 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1099 1100 enum { 1101 OPC_LWXC1 = 0x00 | OPC_CP3, 1102 OPC_LDXC1 = 0x01 | OPC_CP3, 1103 OPC_LUXC1 = 0x05 | OPC_CP3, 1104 OPC_SWXC1 = 0x08 | OPC_CP3, 1105 OPC_SDXC1 = 0x09 | OPC_CP3, 1106 OPC_SUXC1 = 0x0D | OPC_CP3, 1107 OPC_PREFX = 0x0F | OPC_CP3, 1108 OPC_ALNV_PS = 0x1E | OPC_CP3, 1109 OPC_MADD_S = 0x20 | OPC_CP3, 1110 OPC_MADD_D = 0x21 | OPC_CP3, 1111 OPC_MADD_PS = 0x26 | OPC_CP3, 1112 OPC_MSUB_S = 0x28 | OPC_CP3, 1113 OPC_MSUB_D = 0x29 | OPC_CP3, 1114 OPC_MSUB_PS = 0x2E | OPC_CP3, 1115 OPC_NMADD_S = 0x30 | OPC_CP3, 1116 OPC_NMADD_D = 0x31 | OPC_CP3, 1117 OPC_NMADD_PS = 0x36 | OPC_CP3, 1118 OPC_NMSUB_S = 0x38 | OPC_CP3, 1119 OPC_NMSUB_D = 0x39 | OPC_CP3, 1120 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1121 }; 1122 1123 /* 1124 * MMI (MultiMedia Instruction) encodings 1125 * ====================================== 1126 * 1127 * MMI instructions encoding table keys: 1128 * 1129 * * This code is reserved for future use. An attempt to execute it 1130 * causes a Reserved Instruction exception. 1131 * % This code indicates an instruction class. The instruction word 1132 * must be further decoded by examining additional tables that show 1133 * the values for other instruction fields. 1134 * # This code is reserved for the unsupported instructions DMULT, 1135 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1136 * to execute it causes a Reserved Instruction exception. 1137 * 1138 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1139 * 1140 * 31 26 0 1141 * +--------+----------------------------------------+ 1142 * | opcode | | 1143 * +--------+----------------------------------------+ 1144 * 1145 * opcode bits 28..26 1146 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1147 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1148 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1149 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1150 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1151 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1152 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1153 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1154 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1155 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1156 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1157 */ 1158 1159 enum { 1160 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1161 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1162 }; 1163 1164 /* 1165 * MMI instructions with opcode field = MMI: 1166 * 1167 * 31 26 5 0 1168 * +--------+-------------------------------+--------+ 1169 * | MMI | |function| 1170 * +--------+-------------------------------+--------+ 1171 * 1172 * function bits 2..0 1173 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1174 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1175 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1176 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1177 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1178 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1179 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1180 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1181 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1182 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1183 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1184 */ 1185 1186 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1187 enum { 1188 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1189 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1190 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1191 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1192 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1193 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1194 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1195 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1196 }; 1197 1198 /* global register indices */ 1199 TCGv cpu_gpr[32], cpu_PC; 1200 /* 1201 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1202 * and the upper halves in cpu_gpr_hi[]. 1203 */ 1204 TCGv_i64 cpu_gpr_hi[32]; 1205 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1206 static TCGv cpu_dspctrl, btarget; 1207 TCGv bcond; 1208 static TCGv cpu_lladdr, cpu_llval; 1209 static TCGv_i32 hflags; 1210 TCGv_i32 fpu_fcr0, fpu_fcr31; 1211 TCGv_i64 fpu_f64[32]; 1212 1213 #include "exec/gen-icount.h" 1214 1215 static const char regnames_HI[][4] = { 1216 "HI0", "HI1", "HI2", "HI3", 1217 }; 1218 1219 static const char regnames_LO[][4] = { 1220 "LO0", "LO1", "LO2", "LO3", 1221 }; 1222 1223 /* General purpose registers moves. */ 1224 void gen_load_gpr(TCGv t, int reg) 1225 { 1226 if (reg == 0) { 1227 tcg_gen_movi_tl(t, 0); 1228 } else { 1229 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1230 } 1231 } 1232 1233 void gen_store_gpr(TCGv t, int reg) 1234 { 1235 if (reg != 0) { 1236 tcg_gen_mov_tl(cpu_gpr[reg], t); 1237 } 1238 } 1239 1240 #if defined(TARGET_MIPS64) 1241 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1242 { 1243 if (reg == 0) { 1244 tcg_gen_movi_i64(t, 0); 1245 } else { 1246 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1247 } 1248 } 1249 1250 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1251 { 1252 if (reg != 0) { 1253 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1254 } 1255 } 1256 #endif /* TARGET_MIPS64 */ 1257 1258 /* Moves to/from shadow registers. */ 1259 static inline void gen_load_srsgpr(int from, int to) 1260 { 1261 TCGv t0 = tcg_temp_new(); 1262 1263 if (from == 0) { 1264 tcg_gen_movi_tl(t0, 0); 1265 } else { 1266 TCGv_i32 t2 = tcg_temp_new_i32(); 1267 TCGv_ptr addr = tcg_temp_new_ptr(); 1268 1269 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1270 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1271 tcg_gen_andi_i32(t2, t2, 0xf); 1272 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1273 tcg_gen_ext_i32_ptr(addr, t2); 1274 tcg_gen_add_ptr(addr, cpu_env, addr); 1275 1276 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1277 tcg_temp_free_ptr(addr); 1278 tcg_temp_free_i32(t2); 1279 } 1280 gen_store_gpr(t0, to); 1281 tcg_temp_free(t0); 1282 } 1283 1284 static inline void gen_store_srsgpr(int from, int to) 1285 { 1286 if (to != 0) { 1287 TCGv t0 = tcg_temp_new(); 1288 TCGv_i32 t2 = tcg_temp_new_i32(); 1289 TCGv_ptr addr = tcg_temp_new_ptr(); 1290 1291 gen_load_gpr(t0, from); 1292 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1293 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1294 tcg_gen_andi_i32(t2, t2, 0xf); 1295 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1296 tcg_gen_ext_i32_ptr(addr, t2); 1297 tcg_gen_add_ptr(addr, cpu_env, addr); 1298 1299 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1300 tcg_temp_free_ptr(addr); 1301 tcg_temp_free_i32(t2); 1302 tcg_temp_free(t0); 1303 } 1304 } 1305 1306 /* Tests */ 1307 static inline void gen_save_pc(target_ulong pc) 1308 { 1309 tcg_gen_movi_tl(cpu_PC, pc); 1310 } 1311 1312 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1313 { 1314 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1315 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1316 gen_save_pc(ctx->base.pc_next); 1317 ctx->saved_pc = ctx->base.pc_next; 1318 } 1319 if (ctx->hflags != ctx->saved_hflags) { 1320 tcg_gen_movi_i32(hflags, ctx->hflags); 1321 ctx->saved_hflags = ctx->hflags; 1322 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1323 case MIPS_HFLAG_BR: 1324 break; 1325 case MIPS_HFLAG_BC: 1326 case MIPS_HFLAG_BL: 1327 case MIPS_HFLAG_B: 1328 tcg_gen_movi_tl(btarget, ctx->btarget); 1329 break; 1330 } 1331 } 1332 } 1333 1334 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1335 { 1336 ctx->saved_hflags = ctx->hflags; 1337 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1338 case MIPS_HFLAG_BR: 1339 break; 1340 case MIPS_HFLAG_BC: 1341 case MIPS_HFLAG_BL: 1342 case MIPS_HFLAG_B: 1343 ctx->btarget = env->btarget; 1344 break; 1345 } 1346 } 1347 1348 void generate_exception_err(DisasContext *ctx, int excp, int err) 1349 { 1350 save_cpu_state(ctx, 1); 1351 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp), 1352 tcg_constant_i32(err)); 1353 ctx->base.is_jmp = DISAS_NORETURN; 1354 } 1355 1356 void generate_exception(DisasContext *ctx, int excp) 1357 { 1358 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); 1359 } 1360 1361 void generate_exception_end(DisasContext *ctx, int excp) 1362 { 1363 generate_exception_err(ctx, excp, 0); 1364 } 1365 1366 void generate_exception_break(DisasContext *ctx, int code) 1367 { 1368 #ifdef CONFIG_USER_ONLY 1369 /* Pass the break code along to cpu_loop. */ 1370 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 1371 offsetof(CPUMIPSState, error_code)); 1372 #endif 1373 generate_exception_end(ctx, EXCP_BREAK); 1374 } 1375 1376 void gen_reserved_instruction(DisasContext *ctx) 1377 { 1378 generate_exception_end(ctx, EXCP_RI); 1379 } 1380 1381 /* Floating point register moves. */ 1382 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1383 { 1384 if (ctx->hflags & MIPS_HFLAG_FRE) { 1385 generate_exception(ctx, EXCP_RI); 1386 } 1387 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1388 } 1389 1390 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1391 { 1392 TCGv_i64 t64; 1393 if (ctx->hflags & MIPS_HFLAG_FRE) { 1394 generate_exception(ctx, EXCP_RI); 1395 } 1396 t64 = tcg_temp_new_i64(); 1397 tcg_gen_extu_i32_i64(t64, t); 1398 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1399 tcg_temp_free_i64(t64); 1400 } 1401 1402 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1403 { 1404 if (ctx->hflags & MIPS_HFLAG_F64) { 1405 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1406 } else { 1407 gen_load_fpr32(ctx, t, reg | 1); 1408 } 1409 } 1410 1411 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1412 { 1413 if (ctx->hflags & MIPS_HFLAG_F64) { 1414 TCGv_i64 t64 = tcg_temp_new_i64(); 1415 tcg_gen_extu_i32_i64(t64, t); 1416 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1417 tcg_temp_free_i64(t64); 1418 } else { 1419 gen_store_fpr32(ctx, t, reg | 1); 1420 } 1421 } 1422 1423 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1424 { 1425 if (ctx->hflags & MIPS_HFLAG_F64) { 1426 tcg_gen_mov_i64(t, fpu_f64[reg]); 1427 } else { 1428 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1429 } 1430 } 1431 1432 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1433 { 1434 if (ctx->hflags & MIPS_HFLAG_F64) { 1435 tcg_gen_mov_i64(fpu_f64[reg], t); 1436 } else { 1437 TCGv_i64 t0; 1438 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1439 t0 = tcg_temp_new_i64(); 1440 tcg_gen_shri_i64(t0, t, 32); 1441 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1442 tcg_temp_free_i64(t0); 1443 } 1444 } 1445 1446 int get_fp_bit(int cc) 1447 { 1448 if (cc) { 1449 return 24 + cc; 1450 } else { 1451 return 23; 1452 } 1453 } 1454 1455 /* Addresses computation */ 1456 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1457 { 1458 tcg_gen_add_tl(ret, arg0, arg1); 1459 1460 #if defined(TARGET_MIPS64) 1461 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1462 tcg_gen_ext32s_i64(ret, ret); 1463 } 1464 #endif 1465 } 1466 1467 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1468 target_long ofs) 1469 { 1470 tcg_gen_addi_tl(ret, base, ofs); 1471 1472 #if defined(TARGET_MIPS64) 1473 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1474 tcg_gen_ext32s_i64(ret, ret); 1475 } 1476 #endif 1477 } 1478 1479 /* Addresses computation (translation time) */ 1480 static target_long addr_add(DisasContext *ctx, target_long base, 1481 target_long offset) 1482 { 1483 target_long sum = base + offset; 1484 1485 #if defined(TARGET_MIPS64) 1486 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1487 sum = (int32_t)sum; 1488 } 1489 #endif 1490 return sum; 1491 } 1492 1493 /* Sign-extract the low 32-bits to a target_long. */ 1494 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1495 { 1496 #if defined(TARGET_MIPS64) 1497 tcg_gen_ext32s_i64(ret, arg); 1498 #else 1499 tcg_gen_extrl_i64_i32(ret, arg); 1500 #endif 1501 } 1502 1503 /* Sign-extract the high 32-bits to a target_long. */ 1504 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1505 { 1506 #if defined(TARGET_MIPS64) 1507 tcg_gen_sari_i64(ret, arg, 32); 1508 #else 1509 tcg_gen_extrh_i64_i32(ret, arg); 1510 #endif 1511 } 1512 1513 bool check_cp0_enabled(DisasContext *ctx) 1514 { 1515 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1516 generate_exception_end(ctx, EXCP_CpU); 1517 return false; 1518 } 1519 return true; 1520 } 1521 1522 void check_cp1_enabled(DisasContext *ctx) 1523 { 1524 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1525 generate_exception_err(ctx, EXCP_CpU, 1); 1526 } 1527 } 1528 1529 /* 1530 * Verify that the processor is running with COP1X instructions enabled. 1531 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1532 * opcode tables. 1533 */ 1534 void check_cop1x(DisasContext *ctx) 1535 { 1536 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1537 gen_reserved_instruction(ctx); 1538 } 1539 } 1540 1541 /* 1542 * Verify that the processor is running with 64-bit floating-point 1543 * operations enabled. 1544 */ 1545 void check_cp1_64bitmode(DisasContext *ctx) 1546 { 1547 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1548 gen_reserved_instruction(ctx); 1549 } 1550 } 1551 1552 /* 1553 * Verify if floating point register is valid; an operation is not defined 1554 * if bit 0 of any register specification is set and the FR bit in the 1555 * Status register equals zero, since the register numbers specify an 1556 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1557 * in the Status register equals one, both even and odd register numbers 1558 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1559 * 1560 * Multiple 64 bit wide registers can be checked by calling 1561 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1562 */ 1563 void check_cp1_registers(DisasContext *ctx, int regs) 1564 { 1565 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1566 gen_reserved_instruction(ctx); 1567 } 1568 } 1569 1570 /* 1571 * Verify that the processor is running with DSP instructions enabled. 1572 * This is enabled by CP0 Status register MX(24) bit. 1573 */ 1574 static inline void check_dsp(DisasContext *ctx) 1575 { 1576 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1577 if (ctx->insn_flags & ASE_DSP) { 1578 generate_exception_end(ctx, EXCP_DSPDIS); 1579 } else { 1580 gen_reserved_instruction(ctx); 1581 } 1582 } 1583 } 1584 1585 static inline void check_dsp_r2(DisasContext *ctx) 1586 { 1587 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1588 if (ctx->insn_flags & ASE_DSP) { 1589 generate_exception_end(ctx, EXCP_DSPDIS); 1590 } else { 1591 gen_reserved_instruction(ctx); 1592 } 1593 } 1594 } 1595 1596 static inline void check_dsp_r3(DisasContext *ctx) 1597 { 1598 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1599 if (ctx->insn_flags & ASE_DSP) { 1600 generate_exception_end(ctx, EXCP_DSPDIS); 1601 } else { 1602 gen_reserved_instruction(ctx); 1603 } 1604 } 1605 } 1606 1607 /* 1608 * This code generates a "reserved instruction" exception if the 1609 * CPU does not support the instruction set corresponding to flags. 1610 */ 1611 void check_insn(DisasContext *ctx, uint64_t flags) 1612 { 1613 if (unlikely(!(ctx->insn_flags & flags))) { 1614 gen_reserved_instruction(ctx); 1615 } 1616 } 1617 1618 /* 1619 * This code generates a "reserved instruction" exception if the 1620 * CPU has corresponding flag set which indicates that the instruction 1621 * has been removed. 1622 */ 1623 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1624 { 1625 if (unlikely(ctx->insn_flags & flags)) { 1626 gen_reserved_instruction(ctx); 1627 } 1628 } 1629 1630 /* 1631 * The Linux kernel traps certain reserved instruction exceptions to 1632 * emulate the corresponding instructions. QEMU is the kernel in user 1633 * mode, so those traps are emulated by accepting the instructions. 1634 * 1635 * A reserved instruction exception is generated for flagged CPUs if 1636 * QEMU runs in system mode. 1637 */ 1638 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1639 { 1640 #ifndef CONFIG_USER_ONLY 1641 check_insn_opc_removed(ctx, flags); 1642 #endif 1643 } 1644 1645 /* 1646 * This code generates a "reserved instruction" exception if the 1647 * CPU does not support 64-bit paired-single (PS) floating point data type. 1648 */ 1649 static inline void check_ps(DisasContext *ctx) 1650 { 1651 if (unlikely(!ctx->ps)) { 1652 generate_exception(ctx, EXCP_RI); 1653 } 1654 check_cp1_64bitmode(ctx); 1655 } 1656 1657 /* 1658 * This code generates a "reserved instruction" exception if cpu is not 1659 * 64-bit or 64-bit instructions are not enabled. 1660 */ 1661 void check_mips_64(DisasContext *ctx) 1662 { 1663 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1664 gen_reserved_instruction(ctx); 1665 } 1666 } 1667 1668 #ifndef CONFIG_USER_ONLY 1669 static inline void check_mvh(DisasContext *ctx) 1670 { 1671 if (unlikely(!ctx->mvh)) { 1672 generate_exception(ctx, EXCP_RI); 1673 } 1674 } 1675 #endif 1676 1677 /* 1678 * This code generates a "reserved instruction" exception if the 1679 * Config5 XNP bit is set. 1680 */ 1681 static inline void check_xnp(DisasContext *ctx) 1682 { 1683 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1684 gen_reserved_instruction(ctx); 1685 } 1686 } 1687 1688 #ifndef CONFIG_USER_ONLY 1689 /* 1690 * This code generates a "reserved instruction" exception if the 1691 * Config3 PW bit is NOT set. 1692 */ 1693 static inline void check_pw(DisasContext *ctx) 1694 { 1695 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1696 gen_reserved_instruction(ctx); 1697 } 1698 } 1699 #endif 1700 1701 /* 1702 * This code generates a "reserved instruction" exception if the 1703 * Config3 MT bit is NOT set. 1704 */ 1705 static inline void check_mt(DisasContext *ctx) 1706 { 1707 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1708 gen_reserved_instruction(ctx); 1709 } 1710 } 1711 1712 #ifndef CONFIG_USER_ONLY 1713 /* 1714 * This code generates a "coprocessor unusable" exception if CP0 is not 1715 * available, and, if that is not the case, generates a "reserved instruction" 1716 * exception if the Config5 MT bit is NOT set. This is needed for availability 1717 * control of some of MT ASE instructions. 1718 */ 1719 static inline void check_cp0_mt(DisasContext *ctx) 1720 { 1721 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1722 generate_exception_end(ctx, EXCP_CpU); 1723 } else { 1724 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1725 gen_reserved_instruction(ctx); 1726 } 1727 } 1728 } 1729 #endif 1730 1731 /* 1732 * This code generates a "reserved instruction" exception if the 1733 * Config5 NMS bit is set. 1734 */ 1735 static inline void check_nms(DisasContext *ctx) 1736 { 1737 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1738 gen_reserved_instruction(ctx); 1739 } 1740 } 1741 1742 /* 1743 * This code generates a "reserved instruction" exception if the 1744 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1745 * Config2 TL, and Config5 L2C are unset. 1746 */ 1747 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1748 { 1749 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1750 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1751 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1752 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1753 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1754 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1755 gen_reserved_instruction(ctx); 1756 } 1757 } 1758 1759 /* 1760 * This code generates a "reserved instruction" exception if the 1761 * Config5 EVA bit is NOT set. 1762 */ 1763 static inline void check_eva(DisasContext *ctx) 1764 { 1765 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1766 gen_reserved_instruction(ctx); 1767 } 1768 } 1769 1770 1771 /* 1772 * Define small wrappers for gen_load_fpr* so that we have a uniform 1773 * calling interface for 32 and 64-bit FPRs. No sense in changing 1774 * all callers for gen_load_fpr32 when we need the CTX parameter for 1775 * this one use. 1776 */ 1777 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1778 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1779 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1780 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1781 int ft, int fs, int cc) \ 1782 { \ 1783 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1784 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1785 switch (ifmt) { \ 1786 case FMT_PS: \ 1787 check_ps(ctx); \ 1788 break; \ 1789 case FMT_D: \ 1790 if (abs) { \ 1791 check_cop1x(ctx); \ 1792 } \ 1793 check_cp1_registers(ctx, fs | ft); \ 1794 break; \ 1795 case FMT_S: \ 1796 if (abs) { \ 1797 check_cop1x(ctx); \ 1798 } \ 1799 break; \ 1800 } \ 1801 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1802 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1803 switch (n) { \ 1804 case 0: \ 1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1806 break; \ 1807 case 1: \ 1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1809 break; \ 1810 case 2: \ 1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1812 break; \ 1813 case 3: \ 1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1815 break; \ 1816 case 4: \ 1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1818 break; \ 1819 case 5: \ 1820 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1821 break; \ 1822 case 6: \ 1823 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1824 break; \ 1825 case 7: \ 1826 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1827 break; \ 1828 case 8: \ 1829 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1830 break; \ 1831 case 9: \ 1832 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1833 break; \ 1834 case 10: \ 1835 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1836 break; \ 1837 case 11: \ 1838 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1839 break; \ 1840 case 12: \ 1841 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1842 break; \ 1843 case 13: \ 1844 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1845 break; \ 1846 case 14: \ 1847 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1848 break; \ 1849 case 15: \ 1850 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1851 break; \ 1852 default: \ 1853 abort(); \ 1854 } \ 1855 tcg_temp_free_i##bits(fp0); \ 1856 tcg_temp_free_i##bits(fp1); \ 1857 } 1858 1859 FOP_CONDS(, 0, d, FMT_D, 64) 1860 FOP_CONDS(abs, 1, d, FMT_D, 64) 1861 FOP_CONDS(, 0, s, FMT_S, 32) 1862 FOP_CONDS(abs, 1, s, FMT_S, 32) 1863 FOP_CONDS(, 0, ps, FMT_PS, 64) 1864 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1865 #undef FOP_CONDS 1866 1867 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1868 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1869 int ft, int fs, int fd) \ 1870 { \ 1871 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1872 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1873 if (ifmt == FMT_D) { \ 1874 check_cp1_registers(ctx, fs | ft | fd); \ 1875 } \ 1876 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1877 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1878 switch (n) { \ 1879 case 0: \ 1880 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1881 break; \ 1882 case 1: \ 1883 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1884 break; \ 1885 case 2: \ 1886 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1887 break; \ 1888 case 3: \ 1889 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1890 break; \ 1891 case 4: \ 1892 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1893 break; \ 1894 case 5: \ 1895 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1896 break; \ 1897 case 6: \ 1898 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1899 break; \ 1900 case 7: \ 1901 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1902 break; \ 1903 case 8: \ 1904 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1905 break; \ 1906 case 9: \ 1907 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1908 break; \ 1909 case 10: \ 1910 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1911 break; \ 1912 case 11: \ 1913 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1914 break; \ 1915 case 12: \ 1916 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1917 break; \ 1918 case 13: \ 1919 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1920 break; \ 1921 case 14: \ 1922 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1923 break; \ 1924 case 15: \ 1925 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1926 break; \ 1927 case 17: \ 1928 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1929 break; \ 1930 case 18: \ 1931 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1932 break; \ 1933 case 19: \ 1934 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1935 break; \ 1936 case 25: \ 1937 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1938 break; \ 1939 case 26: \ 1940 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 1941 break; \ 1942 case 27: \ 1943 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 1944 break; \ 1945 default: \ 1946 abort(); \ 1947 } \ 1948 STORE; \ 1949 tcg_temp_free_i ## bits(fp0); \ 1950 tcg_temp_free_i ## bits(fp1); \ 1951 } 1952 1953 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1954 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1955 #undef FOP_CONDNS 1956 #undef gen_ldcmp_fpr32 1957 #undef gen_ldcmp_fpr64 1958 1959 /* load/store instructions. */ 1960 #ifdef CONFIG_USER_ONLY 1961 #define OP_LD_ATOMIC(insn, fname) \ 1962 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1963 DisasContext *ctx) \ 1964 { \ 1965 TCGv t0 = tcg_temp_new(); \ 1966 tcg_gen_mov_tl(t0, arg1); \ 1967 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 1968 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 1969 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 1970 tcg_temp_free(t0); \ 1971 } 1972 #else 1973 #define OP_LD_ATOMIC(insn, fname) \ 1974 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1975 DisasContext *ctx) \ 1976 { \ 1977 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \ 1978 } 1979 #endif 1980 OP_LD_ATOMIC(ll, ld32s); 1981 #if defined(TARGET_MIPS64) 1982 OP_LD_ATOMIC(lld, ld64); 1983 #endif 1984 #undef OP_LD_ATOMIC 1985 1986 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1987 { 1988 if (base == 0) { 1989 tcg_gen_movi_tl(addr, offset); 1990 } else if (offset == 0) { 1991 gen_load_gpr(addr, base); 1992 } else { 1993 tcg_gen_movi_tl(addr, offset); 1994 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1995 } 1996 } 1997 1998 static target_ulong pc_relative_pc(DisasContext *ctx) 1999 { 2000 target_ulong pc = ctx->base.pc_next; 2001 2002 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2003 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2004 2005 pc -= branch_bytes; 2006 } 2007 2008 pc &= ~(target_ulong)3; 2009 return pc; 2010 } 2011 2012 /* Load */ 2013 static void gen_ld(DisasContext *ctx, uint32_t opc, 2014 int rt, int base, int offset) 2015 { 2016 TCGv t0, t1, t2; 2017 int mem_idx = ctx->mem_idx; 2018 2019 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2020 INSN_LOONGSON3A)) { 2021 /* 2022 * Loongson CPU uses a load to zero register for prefetch. 2023 * We emulate it as a NOP. On other CPU we must perform the 2024 * actual memory access. 2025 */ 2026 return; 2027 } 2028 2029 t0 = tcg_temp_new(); 2030 gen_base_offset_addr(ctx, t0, base, offset); 2031 2032 switch (opc) { 2033 #if defined(TARGET_MIPS64) 2034 case OPC_LWU: 2035 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2036 ctx->default_tcg_memop_mask); 2037 gen_store_gpr(t0, rt); 2038 break; 2039 case OPC_LD: 2040 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ | 2041 ctx->default_tcg_memop_mask); 2042 gen_store_gpr(t0, rt); 2043 break; 2044 case OPC_LLD: 2045 case R6_OPC_LLD: 2046 op_ld_lld(t0, t0, mem_idx, ctx); 2047 gen_store_gpr(t0, rt); 2048 break; 2049 case OPC_LDL: 2050 t1 = tcg_temp_new(); 2051 /* 2052 * Do a byte access to possibly trigger a page 2053 * fault with the unaligned address. 2054 */ 2055 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2056 tcg_gen_andi_tl(t1, t0, 7); 2057 if (!cpu_is_bigendian(ctx)) { 2058 tcg_gen_xori_tl(t1, t1, 7); 2059 } 2060 tcg_gen_shli_tl(t1, t1, 3); 2061 tcg_gen_andi_tl(t0, t0, ~7); 2062 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2063 tcg_gen_shl_tl(t0, t0, t1); 2064 t2 = tcg_const_tl(-1); 2065 tcg_gen_shl_tl(t2, t2, t1); 2066 gen_load_gpr(t1, rt); 2067 tcg_gen_andc_tl(t1, t1, t2); 2068 tcg_temp_free(t2); 2069 tcg_gen_or_tl(t0, t0, t1); 2070 tcg_temp_free(t1); 2071 gen_store_gpr(t0, rt); 2072 break; 2073 case OPC_LDR: 2074 t1 = tcg_temp_new(); 2075 /* 2076 * Do a byte access to possibly trigger a page 2077 * fault with the unaligned address. 2078 */ 2079 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2080 tcg_gen_andi_tl(t1, t0, 7); 2081 if (cpu_is_bigendian(ctx)) { 2082 tcg_gen_xori_tl(t1, t1, 7); 2083 } 2084 tcg_gen_shli_tl(t1, t1, 3); 2085 tcg_gen_andi_tl(t0, t0, ~7); 2086 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2087 tcg_gen_shr_tl(t0, t0, t1); 2088 tcg_gen_xori_tl(t1, t1, 63); 2089 t2 = tcg_const_tl(0xfffffffffffffffeull); 2090 tcg_gen_shl_tl(t2, t2, t1); 2091 gen_load_gpr(t1, rt); 2092 tcg_gen_and_tl(t1, t1, t2); 2093 tcg_temp_free(t2); 2094 tcg_gen_or_tl(t0, t0, t1); 2095 tcg_temp_free(t1); 2096 gen_store_gpr(t0, rt); 2097 break; 2098 case OPC_LDPC: 2099 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2100 gen_op_addr_add(ctx, t0, t0, t1); 2101 tcg_temp_free(t1); 2102 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2103 gen_store_gpr(t0, rt); 2104 break; 2105 #endif 2106 case OPC_LWPC: 2107 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2108 gen_op_addr_add(ctx, t0, t0, t1); 2109 tcg_temp_free(t1); 2110 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2111 gen_store_gpr(t0, rt); 2112 break; 2113 case OPC_LWE: 2114 mem_idx = MIPS_HFLAG_UM; 2115 /* fall through */ 2116 case OPC_LW: 2117 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2118 ctx->default_tcg_memop_mask); 2119 gen_store_gpr(t0, rt); 2120 break; 2121 case OPC_LHE: 2122 mem_idx = MIPS_HFLAG_UM; 2123 /* fall through */ 2124 case OPC_LH: 2125 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2126 ctx->default_tcg_memop_mask); 2127 gen_store_gpr(t0, rt); 2128 break; 2129 case OPC_LHUE: 2130 mem_idx = MIPS_HFLAG_UM; 2131 /* fall through */ 2132 case OPC_LHU: 2133 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2134 ctx->default_tcg_memop_mask); 2135 gen_store_gpr(t0, rt); 2136 break; 2137 case OPC_LBE: 2138 mem_idx = MIPS_HFLAG_UM; 2139 /* fall through */ 2140 case OPC_LB: 2141 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2142 gen_store_gpr(t0, rt); 2143 break; 2144 case OPC_LBUE: 2145 mem_idx = MIPS_HFLAG_UM; 2146 /* fall through */ 2147 case OPC_LBU: 2148 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2149 gen_store_gpr(t0, rt); 2150 break; 2151 case OPC_LWLE: 2152 mem_idx = MIPS_HFLAG_UM; 2153 /* fall through */ 2154 case OPC_LWL: 2155 t1 = tcg_temp_new(); 2156 /* 2157 * Do a byte access to possibly trigger a page 2158 * fault with the unaligned address. 2159 */ 2160 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2161 tcg_gen_andi_tl(t1, t0, 3); 2162 if (!cpu_is_bigendian(ctx)) { 2163 tcg_gen_xori_tl(t1, t1, 3); 2164 } 2165 tcg_gen_shli_tl(t1, t1, 3); 2166 tcg_gen_andi_tl(t0, t0, ~3); 2167 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2168 tcg_gen_shl_tl(t0, t0, t1); 2169 t2 = tcg_const_tl(-1); 2170 tcg_gen_shl_tl(t2, t2, t1); 2171 gen_load_gpr(t1, rt); 2172 tcg_gen_andc_tl(t1, t1, t2); 2173 tcg_temp_free(t2); 2174 tcg_gen_or_tl(t0, t0, t1); 2175 tcg_temp_free(t1); 2176 tcg_gen_ext32s_tl(t0, t0); 2177 gen_store_gpr(t0, rt); 2178 break; 2179 case OPC_LWRE: 2180 mem_idx = MIPS_HFLAG_UM; 2181 /* fall through */ 2182 case OPC_LWR: 2183 t1 = tcg_temp_new(); 2184 /* 2185 * Do a byte access to possibly trigger a page 2186 * fault with the unaligned address. 2187 */ 2188 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2189 tcg_gen_andi_tl(t1, t0, 3); 2190 if (cpu_is_bigendian(ctx)) { 2191 tcg_gen_xori_tl(t1, t1, 3); 2192 } 2193 tcg_gen_shli_tl(t1, t1, 3); 2194 tcg_gen_andi_tl(t0, t0, ~3); 2195 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2196 tcg_gen_shr_tl(t0, t0, t1); 2197 tcg_gen_xori_tl(t1, t1, 31); 2198 t2 = tcg_const_tl(0xfffffffeull); 2199 tcg_gen_shl_tl(t2, t2, t1); 2200 gen_load_gpr(t1, rt); 2201 tcg_gen_and_tl(t1, t1, t2); 2202 tcg_temp_free(t2); 2203 tcg_gen_or_tl(t0, t0, t1); 2204 tcg_temp_free(t1); 2205 tcg_gen_ext32s_tl(t0, t0); 2206 gen_store_gpr(t0, rt); 2207 break; 2208 case OPC_LLE: 2209 mem_idx = MIPS_HFLAG_UM; 2210 /* fall through */ 2211 case OPC_LL: 2212 case R6_OPC_LL: 2213 op_ld_ll(t0, t0, mem_idx, ctx); 2214 gen_store_gpr(t0, rt); 2215 break; 2216 } 2217 tcg_temp_free(t0); 2218 } 2219 2220 /* Store */ 2221 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2222 int base, int offset) 2223 { 2224 TCGv t0 = tcg_temp_new(); 2225 TCGv t1 = tcg_temp_new(); 2226 int mem_idx = ctx->mem_idx; 2227 2228 gen_base_offset_addr(ctx, t0, base, offset); 2229 gen_load_gpr(t1, rt); 2230 switch (opc) { 2231 #if defined(TARGET_MIPS64) 2232 case OPC_SD: 2233 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ | 2234 ctx->default_tcg_memop_mask); 2235 break; 2236 case OPC_SDL: 2237 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2238 break; 2239 case OPC_SDR: 2240 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2241 break; 2242 #endif 2243 case OPC_SWE: 2244 mem_idx = MIPS_HFLAG_UM; 2245 /* fall through */ 2246 case OPC_SW: 2247 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2248 ctx->default_tcg_memop_mask); 2249 break; 2250 case OPC_SHE: 2251 mem_idx = MIPS_HFLAG_UM; 2252 /* fall through */ 2253 case OPC_SH: 2254 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2255 ctx->default_tcg_memop_mask); 2256 break; 2257 case OPC_SBE: 2258 mem_idx = MIPS_HFLAG_UM; 2259 /* fall through */ 2260 case OPC_SB: 2261 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2262 break; 2263 case OPC_SWLE: 2264 mem_idx = MIPS_HFLAG_UM; 2265 /* fall through */ 2266 case OPC_SWL: 2267 gen_helper_0e2i(swl, t1, t0, mem_idx); 2268 break; 2269 case OPC_SWRE: 2270 mem_idx = MIPS_HFLAG_UM; 2271 /* fall through */ 2272 case OPC_SWR: 2273 gen_helper_0e2i(swr, t1, t0, mem_idx); 2274 break; 2275 } 2276 tcg_temp_free(t0); 2277 tcg_temp_free(t1); 2278 } 2279 2280 2281 /* Store conditional */ 2282 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2283 MemOp tcg_mo, bool eva) 2284 { 2285 TCGv addr, t0, val; 2286 TCGLabel *l1 = gen_new_label(); 2287 TCGLabel *done = gen_new_label(); 2288 2289 t0 = tcg_temp_new(); 2290 addr = tcg_temp_new(); 2291 /* compare the address against that of the preceding LL */ 2292 gen_base_offset_addr(ctx, addr, base, offset); 2293 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2294 tcg_temp_free(addr); 2295 tcg_gen_movi_tl(t0, 0); 2296 gen_store_gpr(t0, rt); 2297 tcg_gen_br(done); 2298 2299 gen_set_label(l1); 2300 /* generate cmpxchg */ 2301 val = tcg_temp_new(); 2302 gen_load_gpr(val, rt); 2303 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2304 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2305 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2306 gen_store_gpr(t0, rt); 2307 tcg_temp_free(val); 2308 2309 gen_set_label(done); 2310 tcg_temp_free(t0); 2311 } 2312 2313 /* Load and store */ 2314 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2315 TCGv t0) 2316 { 2317 /* 2318 * Don't do NOP if destination is zero: we must perform the actual 2319 * memory access. 2320 */ 2321 switch (opc) { 2322 case OPC_LWC1: 2323 { 2324 TCGv_i32 fp0 = tcg_temp_new_i32(); 2325 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2326 ctx->default_tcg_memop_mask); 2327 gen_store_fpr32(ctx, fp0, ft); 2328 tcg_temp_free_i32(fp0); 2329 } 2330 break; 2331 case OPC_SWC1: 2332 { 2333 TCGv_i32 fp0 = tcg_temp_new_i32(); 2334 gen_load_fpr32(ctx, fp0, ft); 2335 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2336 ctx->default_tcg_memop_mask); 2337 tcg_temp_free_i32(fp0); 2338 } 2339 break; 2340 case OPC_LDC1: 2341 { 2342 TCGv_i64 fp0 = tcg_temp_new_i64(); 2343 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2344 ctx->default_tcg_memop_mask); 2345 gen_store_fpr64(ctx, fp0, ft); 2346 tcg_temp_free_i64(fp0); 2347 } 2348 break; 2349 case OPC_SDC1: 2350 { 2351 TCGv_i64 fp0 = tcg_temp_new_i64(); 2352 gen_load_fpr64(ctx, fp0, ft); 2353 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2354 ctx->default_tcg_memop_mask); 2355 tcg_temp_free_i64(fp0); 2356 } 2357 break; 2358 default: 2359 MIPS_INVAL("flt_ldst"); 2360 gen_reserved_instruction(ctx); 2361 break; 2362 } 2363 } 2364 2365 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2366 int rs, int16_t imm) 2367 { 2368 TCGv t0 = tcg_temp_new(); 2369 2370 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2371 check_cp1_enabled(ctx); 2372 switch (op) { 2373 case OPC_LDC1: 2374 case OPC_SDC1: 2375 check_insn(ctx, ISA_MIPS2); 2376 /* Fallthrough */ 2377 default: 2378 gen_base_offset_addr(ctx, t0, rs, imm); 2379 gen_flt_ldst(ctx, op, rt, t0); 2380 } 2381 } else { 2382 generate_exception_err(ctx, EXCP_CpU, 1); 2383 } 2384 tcg_temp_free(t0); 2385 } 2386 2387 /* Arithmetic with immediate operand */ 2388 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2389 int rt, int rs, int imm) 2390 { 2391 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2392 2393 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2394 /* 2395 * If no destination, treat it as a NOP. 2396 * For addi, we must generate the overflow exception when needed. 2397 */ 2398 return; 2399 } 2400 switch (opc) { 2401 case OPC_ADDI: 2402 { 2403 TCGv t0 = tcg_temp_local_new(); 2404 TCGv t1 = tcg_temp_new(); 2405 TCGv t2 = tcg_temp_new(); 2406 TCGLabel *l1 = gen_new_label(); 2407 2408 gen_load_gpr(t1, rs); 2409 tcg_gen_addi_tl(t0, t1, uimm); 2410 tcg_gen_ext32s_tl(t0, t0); 2411 2412 tcg_gen_xori_tl(t1, t1, ~uimm); 2413 tcg_gen_xori_tl(t2, t0, uimm); 2414 tcg_gen_and_tl(t1, t1, t2); 2415 tcg_temp_free(t2); 2416 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2417 tcg_temp_free(t1); 2418 /* operands of same sign, result different sign */ 2419 generate_exception(ctx, EXCP_OVERFLOW); 2420 gen_set_label(l1); 2421 tcg_gen_ext32s_tl(t0, t0); 2422 gen_store_gpr(t0, rt); 2423 tcg_temp_free(t0); 2424 } 2425 break; 2426 case OPC_ADDIU: 2427 if (rs != 0) { 2428 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2429 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2430 } else { 2431 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2432 } 2433 break; 2434 #if defined(TARGET_MIPS64) 2435 case OPC_DADDI: 2436 { 2437 TCGv t0 = tcg_temp_local_new(); 2438 TCGv t1 = tcg_temp_new(); 2439 TCGv t2 = tcg_temp_new(); 2440 TCGLabel *l1 = gen_new_label(); 2441 2442 gen_load_gpr(t1, rs); 2443 tcg_gen_addi_tl(t0, t1, uimm); 2444 2445 tcg_gen_xori_tl(t1, t1, ~uimm); 2446 tcg_gen_xori_tl(t2, t0, uimm); 2447 tcg_gen_and_tl(t1, t1, t2); 2448 tcg_temp_free(t2); 2449 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2450 tcg_temp_free(t1); 2451 /* operands of same sign, result different sign */ 2452 generate_exception(ctx, EXCP_OVERFLOW); 2453 gen_set_label(l1); 2454 gen_store_gpr(t0, rt); 2455 tcg_temp_free(t0); 2456 } 2457 break; 2458 case OPC_DADDIU: 2459 if (rs != 0) { 2460 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2461 } else { 2462 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2463 } 2464 break; 2465 #endif 2466 } 2467 } 2468 2469 /* Logic with immediate operand */ 2470 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2471 int rt, int rs, int16_t imm) 2472 { 2473 target_ulong uimm; 2474 2475 if (rt == 0) { 2476 /* If no destination, treat it as a NOP. */ 2477 return; 2478 } 2479 uimm = (uint16_t)imm; 2480 switch (opc) { 2481 case OPC_ANDI: 2482 if (likely(rs != 0)) { 2483 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2484 } else { 2485 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2486 } 2487 break; 2488 case OPC_ORI: 2489 if (rs != 0) { 2490 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2491 } else { 2492 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2493 } 2494 break; 2495 case OPC_XORI: 2496 if (likely(rs != 0)) { 2497 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2498 } else { 2499 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2500 } 2501 break; 2502 case OPC_LUI: 2503 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2504 /* OPC_AUI */ 2505 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2506 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2507 } else { 2508 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2509 } 2510 break; 2511 2512 default: 2513 break; 2514 } 2515 } 2516 2517 /* Set on less than with immediate operand */ 2518 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2519 int rt, int rs, int16_t imm) 2520 { 2521 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2522 TCGv t0; 2523 2524 if (rt == 0) { 2525 /* If no destination, treat it as a NOP. */ 2526 return; 2527 } 2528 t0 = tcg_temp_new(); 2529 gen_load_gpr(t0, rs); 2530 switch (opc) { 2531 case OPC_SLTI: 2532 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2533 break; 2534 case OPC_SLTIU: 2535 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2536 break; 2537 } 2538 tcg_temp_free(t0); 2539 } 2540 2541 /* Shifts with immediate operand */ 2542 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2543 int rt, int rs, int16_t imm) 2544 { 2545 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2546 TCGv t0; 2547 2548 if (rt == 0) { 2549 /* If no destination, treat it as a NOP. */ 2550 return; 2551 } 2552 2553 t0 = tcg_temp_new(); 2554 gen_load_gpr(t0, rs); 2555 switch (opc) { 2556 case OPC_SLL: 2557 tcg_gen_shli_tl(t0, t0, uimm); 2558 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2559 break; 2560 case OPC_SRA: 2561 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2562 break; 2563 case OPC_SRL: 2564 if (uimm != 0) { 2565 tcg_gen_ext32u_tl(t0, t0); 2566 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2567 } else { 2568 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2569 } 2570 break; 2571 case OPC_ROTR: 2572 if (uimm != 0) { 2573 TCGv_i32 t1 = tcg_temp_new_i32(); 2574 2575 tcg_gen_trunc_tl_i32(t1, t0); 2576 tcg_gen_rotri_i32(t1, t1, uimm); 2577 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2578 tcg_temp_free_i32(t1); 2579 } else { 2580 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2581 } 2582 break; 2583 #if defined(TARGET_MIPS64) 2584 case OPC_DSLL: 2585 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2586 break; 2587 case OPC_DSRA: 2588 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2589 break; 2590 case OPC_DSRL: 2591 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2592 break; 2593 case OPC_DROTR: 2594 if (uimm != 0) { 2595 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2596 } else { 2597 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2598 } 2599 break; 2600 case OPC_DSLL32: 2601 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2602 break; 2603 case OPC_DSRA32: 2604 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2605 break; 2606 case OPC_DSRL32: 2607 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2608 break; 2609 case OPC_DROTR32: 2610 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2611 break; 2612 #endif 2613 } 2614 tcg_temp_free(t0); 2615 } 2616 2617 /* Arithmetic */ 2618 static void gen_arith(DisasContext *ctx, uint32_t opc, 2619 int rd, int rs, int rt) 2620 { 2621 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2622 && opc != OPC_DADD && opc != OPC_DSUB) { 2623 /* 2624 * If no destination, treat it as a NOP. 2625 * For add & sub, we must generate the overflow exception when needed. 2626 */ 2627 return; 2628 } 2629 2630 switch (opc) { 2631 case OPC_ADD: 2632 { 2633 TCGv t0 = tcg_temp_local_new(); 2634 TCGv t1 = tcg_temp_new(); 2635 TCGv t2 = tcg_temp_new(); 2636 TCGLabel *l1 = gen_new_label(); 2637 2638 gen_load_gpr(t1, rs); 2639 gen_load_gpr(t2, rt); 2640 tcg_gen_add_tl(t0, t1, t2); 2641 tcg_gen_ext32s_tl(t0, t0); 2642 tcg_gen_xor_tl(t1, t1, t2); 2643 tcg_gen_xor_tl(t2, t0, t2); 2644 tcg_gen_andc_tl(t1, t2, t1); 2645 tcg_temp_free(t2); 2646 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2647 tcg_temp_free(t1); 2648 /* operands of same sign, result different sign */ 2649 generate_exception(ctx, EXCP_OVERFLOW); 2650 gen_set_label(l1); 2651 gen_store_gpr(t0, rd); 2652 tcg_temp_free(t0); 2653 } 2654 break; 2655 case OPC_ADDU: 2656 if (rs != 0 && rt != 0) { 2657 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2658 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2659 } else if (rs == 0 && rt != 0) { 2660 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2661 } else if (rs != 0 && rt == 0) { 2662 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2663 } else { 2664 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2665 } 2666 break; 2667 case OPC_SUB: 2668 { 2669 TCGv t0 = tcg_temp_local_new(); 2670 TCGv t1 = tcg_temp_new(); 2671 TCGv t2 = tcg_temp_new(); 2672 TCGLabel *l1 = gen_new_label(); 2673 2674 gen_load_gpr(t1, rs); 2675 gen_load_gpr(t2, rt); 2676 tcg_gen_sub_tl(t0, t1, t2); 2677 tcg_gen_ext32s_tl(t0, t0); 2678 tcg_gen_xor_tl(t2, t1, t2); 2679 tcg_gen_xor_tl(t1, t0, t1); 2680 tcg_gen_and_tl(t1, t1, t2); 2681 tcg_temp_free(t2); 2682 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2683 tcg_temp_free(t1); 2684 /* 2685 * operands of different sign, first operand and the result 2686 * of different sign 2687 */ 2688 generate_exception(ctx, EXCP_OVERFLOW); 2689 gen_set_label(l1); 2690 gen_store_gpr(t0, rd); 2691 tcg_temp_free(t0); 2692 } 2693 break; 2694 case OPC_SUBU: 2695 if (rs != 0 && rt != 0) { 2696 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2697 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2698 } else if (rs == 0 && rt != 0) { 2699 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2700 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2701 } else if (rs != 0 && rt == 0) { 2702 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2703 } else { 2704 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2705 } 2706 break; 2707 #if defined(TARGET_MIPS64) 2708 case OPC_DADD: 2709 { 2710 TCGv t0 = tcg_temp_local_new(); 2711 TCGv t1 = tcg_temp_new(); 2712 TCGv t2 = tcg_temp_new(); 2713 TCGLabel *l1 = gen_new_label(); 2714 2715 gen_load_gpr(t1, rs); 2716 gen_load_gpr(t2, rt); 2717 tcg_gen_add_tl(t0, t1, t2); 2718 tcg_gen_xor_tl(t1, t1, t2); 2719 tcg_gen_xor_tl(t2, t0, t2); 2720 tcg_gen_andc_tl(t1, t2, t1); 2721 tcg_temp_free(t2); 2722 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2723 tcg_temp_free(t1); 2724 /* operands of same sign, result different sign */ 2725 generate_exception(ctx, EXCP_OVERFLOW); 2726 gen_set_label(l1); 2727 gen_store_gpr(t0, rd); 2728 tcg_temp_free(t0); 2729 } 2730 break; 2731 case OPC_DADDU: 2732 if (rs != 0 && rt != 0) { 2733 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2734 } else if (rs == 0 && rt != 0) { 2735 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2736 } else if (rs != 0 && rt == 0) { 2737 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2738 } else { 2739 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2740 } 2741 break; 2742 case OPC_DSUB: 2743 { 2744 TCGv t0 = tcg_temp_local_new(); 2745 TCGv t1 = tcg_temp_new(); 2746 TCGv t2 = tcg_temp_new(); 2747 TCGLabel *l1 = gen_new_label(); 2748 2749 gen_load_gpr(t1, rs); 2750 gen_load_gpr(t2, rt); 2751 tcg_gen_sub_tl(t0, t1, t2); 2752 tcg_gen_xor_tl(t2, t1, t2); 2753 tcg_gen_xor_tl(t1, t0, t1); 2754 tcg_gen_and_tl(t1, t1, t2); 2755 tcg_temp_free(t2); 2756 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2757 tcg_temp_free(t1); 2758 /* 2759 * Operands of different sign, first operand and result different 2760 * sign. 2761 */ 2762 generate_exception(ctx, EXCP_OVERFLOW); 2763 gen_set_label(l1); 2764 gen_store_gpr(t0, rd); 2765 tcg_temp_free(t0); 2766 } 2767 break; 2768 case OPC_DSUBU: 2769 if (rs != 0 && rt != 0) { 2770 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2771 } else if (rs == 0 && rt != 0) { 2772 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2773 } else if (rs != 0 && rt == 0) { 2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2775 } else { 2776 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2777 } 2778 break; 2779 #endif 2780 case OPC_MUL: 2781 if (likely(rs != 0 && rt != 0)) { 2782 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2783 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2784 } else { 2785 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2786 } 2787 break; 2788 } 2789 } 2790 2791 /* Conditional move */ 2792 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2793 int rd, int rs, int rt) 2794 { 2795 TCGv t0, t1, t2; 2796 2797 if (rd == 0) { 2798 /* If no destination, treat it as a NOP. */ 2799 return; 2800 } 2801 2802 t0 = tcg_temp_new(); 2803 gen_load_gpr(t0, rt); 2804 t1 = tcg_const_tl(0); 2805 t2 = tcg_temp_new(); 2806 gen_load_gpr(t2, rs); 2807 switch (opc) { 2808 case OPC_MOVN: 2809 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2810 break; 2811 case OPC_MOVZ: 2812 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2813 break; 2814 case OPC_SELNEZ: 2815 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2816 break; 2817 case OPC_SELEQZ: 2818 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2819 break; 2820 } 2821 tcg_temp_free(t2); 2822 tcg_temp_free(t1); 2823 tcg_temp_free(t0); 2824 } 2825 2826 /* Logic */ 2827 static void gen_logic(DisasContext *ctx, uint32_t opc, 2828 int rd, int rs, int rt) 2829 { 2830 if (rd == 0) { 2831 /* If no destination, treat it as a NOP. */ 2832 return; 2833 } 2834 2835 switch (opc) { 2836 case OPC_AND: 2837 if (likely(rs != 0 && rt != 0)) { 2838 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2839 } else { 2840 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2841 } 2842 break; 2843 case OPC_NOR: 2844 if (rs != 0 && rt != 0) { 2845 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2846 } else if (rs == 0 && rt != 0) { 2847 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2848 } else if (rs != 0 && rt == 0) { 2849 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2850 } else { 2851 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2852 } 2853 break; 2854 case OPC_OR: 2855 if (likely(rs != 0 && rt != 0)) { 2856 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2857 } else if (rs == 0 && rt != 0) { 2858 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2859 } else if (rs != 0 && rt == 0) { 2860 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2861 } else { 2862 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2863 } 2864 break; 2865 case OPC_XOR: 2866 if (likely(rs != 0 && rt != 0)) { 2867 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2868 } else if (rs == 0 && rt != 0) { 2869 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2870 } else if (rs != 0 && rt == 0) { 2871 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2872 } else { 2873 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2874 } 2875 break; 2876 } 2877 } 2878 2879 /* Set on lower than */ 2880 static void gen_slt(DisasContext *ctx, uint32_t opc, 2881 int rd, int rs, int rt) 2882 { 2883 TCGv t0, t1; 2884 2885 if (rd == 0) { 2886 /* If no destination, treat it as a NOP. */ 2887 return; 2888 } 2889 2890 t0 = tcg_temp_new(); 2891 t1 = tcg_temp_new(); 2892 gen_load_gpr(t0, rs); 2893 gen_load_gpr(t1, rt); 2894 switch (opc) { 2895 case OPC_SLT: 2896 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2897 break; 2898 case OPC_SLTU: 2899 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2900 break; 2901 } 2902 tcg_temp_free(t0); 2903 tcg_temp_free(t1); 2904 } 2905 2906 /* Shifts */ 2907 static void gen_shift(DisasContext *ctx, uint32_t opc, 2908 int rd, int rs, int rt) 2909 { 2910 TCGv t0, t1; 2911 2912 if (rd == 0) { 2913 /* 2914 * If no destination, treat it as a NOP. 2915 * For add & sub, we must generate the overflow exception when needed. 2916 */ 2917 return; 2918 } 2919 2920 t0 = tcg_temp_new(); 2921 t1 = tcg_temp_new(); 2922 gen_load_gpr(t0, rs); 2923 gen_load_gpr(t1, rt); 2924 switch (opc) { 2925 case OPC_SLLV: 2926 tcg_gen_andi_tl(t0, t0, 0x1f); 2927 tcg_gen_shl_tl(t0, t1, t0); 2928 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2929 break; 2930 case OPC_SRAV: 2931 tcg_gen_andi_tl(t0, t0, 0x1f); 2932 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2933 break; 2934 case OPC_SRLV: 2935 tcg_gen_ext32u_tl(t1, t1); 2936 tcg_gen_andi_tl(t0, t0, 0x1f); 2937 tcg_gen_shr_tl(t0, t1, t0); 2938 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2939 break; 2940 case OPC_ROTRV: 2941 { 2942 TCGv_i32 t2 = tcg_temp_new_i32(); 2943 TCGv_i32 t3 = tcg_temp_new_i32(); 2944 2945 tcg_gen_trunc_tl_i32(t2, t0); 2946 tcg_gen_trunc_tl_i32(t3, t1); 2947 tcg_gen_andi_i32(t2, t2, 0x1f); 2948 tcg_gen_rotr_i32(t2, t3, t2); 2949 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2950 tcg_temp_free_i32(t2); 2951 tcg_temp_free_i32(t3); 2952 } 2953 break; 2954 #if defined(TARGET_MIPS64) 2955 case OPC_DSLLV: 2956 tcg_gen_andi_tl(t0, t0, 0x3f); 2957 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2958 break; 2959 case OPC_DSRAV: 2960 tcg_gen_andi_tl(t0, t0, 0x3f); 2961 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2962 break; 2963 case OPC_DSRLV: 2964 tcg_gen_andi_tl(t0, t0, 0x3f); 2965 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2966 break; 2967 case OPC_DROTRV: 2968 tcg_gen_andi_tl(t0, t0, 0x3f); 2969 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2970 break; 2971 #endif 2972 } 2973 tcg_temp_free(t0); 2974 tcg_temp_free(t1); 2975 } 2976 2977 /* Arithmetic on HI/LO registers */ 2978 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2979 { 2980 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2981 /* Treat as NOP. */ 2982 return; 2983 } 2984 2985 if (acc != 0) { 2986 check_dsp(ctx); 2987 } 2988 2989 switch (opc) { 2990 case OPC_MFHI: 2991 #if defined(TARGET_MIPS64) 2992 if (acc != 0) { 2993 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2994 } else 2995 #endif 2996 { 2997 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2998 } 2999 break; 3000 case OPC_MFLO: 3001 #if defined(TARGET_MIPS64) 3002 if (acc != 0) { 3003 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3004 } else 3005 #endif 3006 { 3007 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3008 } 3009 break; 3010 case OPC_MTHI: 3011 if (reg != 0) { 3012 #if defined(TARGET_MIPS64) 3013 if (acc != 0) { 3014 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3015 } else 3016 #endif 3017 { 3018 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3019 } 3020 } else { 3021 tcg_gen_movi_tl(cpu_HI[acc], 0); 3022 } 3023 break; 3024 case OPC_MTLO: 3025 if (reg != 0) { 3026 #if defined(TARGET_MIPS64) 3027 if (acc != 0) { 3028 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3029 } else 3030 #endif 3031 { 3032 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3033 } 3034 } else { 3035 tcg_gen_movi_tl(cpu_LO[acc], 0); 3036 } 3037 break; 3038 } 3039 } 3040 3041 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3042 MemOp memop) 3043 { 3044 TCGv t0 = tcg_const_tl(addr); 3045 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3046 gen_store_gpr(t0, reg); 3047 tcg_temp_free(t0); 3048 } 3049 3050 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3051 int rs) 3052 { 3053 target_long offset; 3054 target_long addr; 3055 3056 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3057 case OPC_ADDIUPC: 3058 if (rs != 0) { 3059 offset = sextract32(ctx->opcode << 2, 0, 21); 3060 addr = addr_add(ctx, pc, offset); 3061 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3062 } 3063 break; 3064 case R6_OPC_LWPC: 3065 offset = sextract32(ctx->opcode << 2, 0, 21); 3066 addr = addr_add(ctx, pc, offset); 3067 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3068 break; 3069 #if defined(TARGET_MIPS64) 3070 case OPC_LWUPC: 3071 check_mips_64(ctx); 3072 offset = sextract32(ctx->opcode << 2, 0, 21); 3073 addr = addr_add(ctx, pc, offset); 3074 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3075 break; 3076 #endif 3077 default: 3078 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3079 case OPC_AUIPC: 3080 if (rs != 0) { 3081 offset = sextract32(ctx->opcode, 0, 16) << 16; 3082 addr = addr_add(ctx, pc, offset); 3083 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3084 } 3085 break; 3086 case OPC_ALUIPC: 3087 if (rs != 0) { 3088 offset = sextract32(ctx->opcode, 0, 16) << 16; 3089 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3090 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3091 } 3092 break; 3093 #if defined(TARGET_MIPS64) 3094 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3095 case R6_OPC_LDPC + (1 << 16): 3096 case R6_OPC_LDPC + (2 << 16): 3097 case R6_OPC_LDPC + (3 << 16): 3098 check_mips_64(ctx); 3099 offset = sextract32(ctx->opcode << 3, 0, 21); 3100 addr = addr_add(ctx, (pc & ~0x7), offset); 3101 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ); 3102 break; 3103 #endif 3104 default: 3105 MIPS_INVAL("OPC_PCREL"); 3106 gen_reserved_instruction(ctx); 3107 break; 3108 } 3109 break; 3110 } 3111 } 3112 3113 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3114 { 3115 TCGv t0, t1; 3116 3117 if (rd == 0) { 3118 /* Treat as NOP. */ 3119 return; 3120 } 3121 3122 t0 = tcg_temp_new(); 3123 t1 = tcg_temp_new(); 3124 3125 gen_load_gpr(t0, rs); 3126 gen_load_gpr(t1, rt); 3127 3128 switch (opc) { 3129 case R6_OPC_DIV: 3130 { 3131 TCGv t2 = tcg_temp_new(); 3132 TCGv t3 = tcg_temp_new(); 3133 tcg_gen_ext32s_tl(t0, t0); 3134 tcg_gen_ext32s_tl(t1, t1); 3135 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3137 tcg_gen_and_tl(t2, t2, t3); 3138 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3139 tcg_gen_or_tl(t2, t2, t3); 3140 tcg_gen_movi_tl(t3, 0); 3141 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3142 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3143 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3144 tcg_temp_free(t3); 3145 tcg_temp_free(t2); 3146 } 3147 break; 3148 case R6_OPC_MOD: 3149 { 3150 TCGv t2 = tcg_temp_new(); 3151 TCGv t3 = tcg_temp_new(); 3152 tcg_gen_ext32s_tl(t0, t0); 3153 tcg_gen_ext32s_tl(t1, t1); 3154 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3155 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 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_movi_tl(t3, 0); 3160 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3161 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3162 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3163 tcg_temp_free(t3); 3164 tcg_temp_free(t2); 3165 } 3166 break; 3167 case R6_OPC_DIVU: 3168 { 3169 TCGv t2 = tcg_const_tl(0); 3170 TCGv t3 = tcg_const_tl(1); 3171 tcg_gen_ext32u_tl(t0, t0); 3172 tcg_gen_ext32u_tl(t1, t1); 3173 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3174 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3175 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3176 tcg_temp_free(t3); 3177 tcg_temp_free(t2); 3178 } 3179 break; 3180 case R6_OPC_MODU: 3181 { 3182 TCGv t2 = tcg_const_tl(0); 3183 TCGv t3 = tcg_const_tl(1); 3184 tcg_gen_ext32u_tl(t0, t0); 3185 tcg_gen_ext32u_tl(t1, t1); 3186 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3187 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3188 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3189 tcg_temp_free(t3); 3190 tcg_temp_free(t2); 3191 } 3192 break; 3193 case R6_OPC_MUL: 3194 { 3195 TCGv_i32 t2 = tcg_temp_new_i32(); 3196 TCGv_i32 t3 = tcg_temp_new_i32(); 3197 tcg_gen_trunc_tl_i32(t2, t0); 3198 tcg_gen_trunc_tl_i32(t3, t1); 3199 tcg_gen_mul_i32(t2, t2, t3); 3200 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3201 tcg_temp_free_i32(t2); 3202 tcg_temp_free_i32(t3); 3203 } 3204 break; 3205 case R6_OPC_MUH: 3206 { 3207 TCGv_i32 t2 = tcg_temp_new_i32(); 3208 TCGv_i32 t3 = tcg_temp_new_i32(); 3209 tcg_gen_trunc_tl_i32(t2, t0); 3210 tcg_gen_trunc_tl_i32(t3, t1); 3211 tcg_gen_muls2_i32(t2, t3, t2, t3); 3212 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3213 tcg_temp_free_i32(t2); 3214 tcg_temp_free_i32(t3); 3215 } 3216 break; 3217 case R6_OPC_MULU: 3218 { 3219 TCGv_i32 t2 = tcg_temp_new_i32(); 3220 TCGv_i32 t3 = tcg_temp_new_i32(); 3221 tcg_gen_trunc_tl_i32(t2, t0); 3222 tcg_gen_trunc_tl_i32(t3, t1); 3223 tcg_gen_mul_i32(t2, t2, t3); 3224 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3225 tcg_temp_free_i32(t2); 3226 tcg_temp_free_i32(t3); 3227 } 3228 break; 3229 case R6_OPC_MUHU: 3230 { 3231 TCGv_i32 t2 = tcg_temp_new_i32(); 3232 TCGv_i32 t3 = tcg_temp_new_i32(); 3233 tcg_gen_trunc_tl_i32(t2, t0); 3234 tcg_gen_trunc_tl_i32(t3, t1); 3235 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3236 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3237 tcg_temp_free_i32(t2); 3238 tcg_temp_free_i32(t3); 3239 } 3240 break; 3241 #if defined(TARGET_MIPS64) 3242 case R6_OPC_DDIV: 3243 { 3244 TCGv t2 = tcg_temp_new(); 3245 TCGv t3 = tcg_temp_new(); 3246 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3248 tcg_gen_and_tl(t2, t2, t3); 3249 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3250 tcg_gen_or_tl(t2, t2, t3); 3251 tcg_gen_movi_tl(t3, 0); 3252 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3253 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3254 tcg_temp_free(t3); 3255 tcg_temp_free(t2); 3256 } 3257 break; 3258 case R6_OPC_DMOD: 3259 { 3260 TCGv t2 = tcg_temp_new(); 3261 TCGv t3 = tcg_temp_new(); 3262 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3264 tcg_gen_and_tl(t2, t2, t3); 3265 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3266 tcg_gen_or_tl(t2, t2, t3); 3267 tcg_gen_movi_tl(t3, 0); 3268 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3269 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3270 tcg_temp_free(t3); 3271 tcg_temp_free(t2); 3272 } 3273 break; 3274 case R6_OPC_DDIVU: 3275 { 3276 TCGv t2 = tcg_const_tl(0); 3277 TCGv t3 = tcg_const_tl(1); 3278 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3279 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3280 tcg_temp_free(t3); 3281 tcg_temp_free(t2); 3282 } 3283 break; 3284 case R6_OPC_DMODU: 3285 { 3286 TCGv t2 = tcg_const_tl(0); 3287 TCGv t3 = tcg_const_tl(1); 3288 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3289 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3290 tcg_temp_free(t3); 3291 tcg_temp_free(t2); 3292 } 3293 break; 3294 case R6_OPC_DMUL: 3295 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3296 break; 3297 case R6_OPC_DMUH: 3298 { 3299 TCGv t2 = tcg_temp_new(); 3300 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3301 tcg_temp_free(t2); 3302 } 3303 break; 3304 case R6_OPC_DMULU: 3305 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3306 break; 3307 case R6_OPC_DMUHU: 3308 { 3309 TCGv t2 = tcg_temp_new(); 3310 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3311 tcg_temp_free(t2); 3312 } 3313 break; 3314 #endif 3315 default: 3316 MIPS_INVAL("r6 mul/div"); 3317 gen_reserved_instruction(ctx); 3318 goto out; 3319 } 3320 out: 3321 tcg_temp_free(t0); 3322 tcg_temp_free(t1); 3323 } 3324 3325 #if defined(TARGET_MIPS64) 3326 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3327 { 3328 TCGv t0, t1; 3329 3330 t0 = tcg_temp_new(); 3331 t1 = tcg_temp_new(); 3332 3333 gen_load_gpr(t0, rs); 3334 gen_load_gpr(t1, rt); 3335 3336 switch (opc) { 3337 case MMI_OPC_DIV1: 3338 { 3339 TCGv t2 = tcg_temp_new(); 3340 TCGv t3 = tcg_temp_new(); 3341 tcg_gen_ext32s_tl(t0, t0); 3342 tcg_gen_ext32s_tl(t1, t1); 3343 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3344 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3345 tcg_gen_and_tl(t2, t2, t3); 3346 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3347 tcg_gen_or_tl(t2, t2, t3); 3348 tcg_gen_movi_tl(t3, 0); 3349 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3350 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3351 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3352 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3353 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3354 tcg_temp_free(t3); 3355 tcg_temp_free(t2); 3356 } 3357 break; 3358 case MMI_OPC_DIVU1: 3359 { 3360 TCGv t2 = tcg_const_tl(0); 3361 TCGv t3 = tcg_const_tl(1); 3362 tcg_gen_ext32u_tl(t0, t0); 3363 tcg_gen_ext32u_tl(t1, t1); 3364 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3365 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3366 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3367 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3368 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3369 tcg_temp_free(t3); 3370 tcg_temp_free(t2); 3371 } 3372 break; 3373 default: 3374 MIPS_INVAL("div1 TX79"); 3375 gen_reserved_instruction(ctx); 3376 goto out; 3377 } 3378 out: 3379 tcg_temp_free(t0); 3380 tcg_temp_free(t1); 3381 } 3382 #endif 3383 3384 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3385 int acc, int rs, int rt) 3386 { 3387 TCGv t0, t1; 3388 3389 t0 = tcg_temp_new(); 3390 t1 = tcg_temp_new(); 3391 3392 gen_load_gpr(t0, rs); 3393 gen_load_gpr(t1, rt); 3394 3395 if (acc != 0) { 3396 check_dsp(ctx); 3397 } 3398 3399 switch (opc) { 3400 case OPC_DIV: 3401 { 3402 TCGv t2 = tcg_temp_new(); 3403 TCGv t3 = tcg_temp_new(); 3404 tcg_gen_ext32s_tl(t0, t0); 3405 tcg_gen_ext32s_tl(t1, t1); 3406 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3407 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3408 tcg_gen_and_tl(t2, t2, t3); 3409 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3410 tcg_gen_or_tl(t2, t2, t3); 3411 tcg_gen_movi_tl(t3, 0); 3412 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3413 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3414 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3415 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3416 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3417 tcg_temp_free(t3); 3418 tcg_temp_free(t2); 3419 } 3420 break; 3421 case OPC_DIVU: 3422 { 3423 TCGv t2 = tcg_const_tl(0); 3424 TCGv t3 = tcg_const_tl(1); 3425 tcg_gen_ext32u_tl(t0, t0); 3426 tcg_gen_ext32u_tl(t1, t1); 3427 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3428 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3429 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3430 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3431 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3432 tcg_temp_free(t3); 3433 tcg_temp_free(t2); 3434 } 3435 break; 3436 case OPC_MULT: 3437 { 3438 TCGv_i32 t2 = tcg_temp_new_i32(); 3439 TCGv_i32 t3 = tcg_temp_new_i32(); 3440 tcg_gen_trunc_tl_i32(t2, t0); 3441 tcg_gen_trunc_tl_i32(t3, t1); 3442 tcg_gen_muls2_i32(t2, t3, t2, t3); 3443 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3444 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3445 tcg_temp_free_i32(t2); 3446 tcg_temp_free_i32(t3); 3447 } 3448 break; 3449 case OPC_MULTU: 3450 { 3451 TCGv_i32 t2 = tcg_temp_new_i32(); 3452 TCGv_i32 t3 = tcg_temp_new_i32(); 3453 tcg_gen_trunc_tl_i32(t2, t0); 3454 tcg_gen_trunc_tl_i32(t3, t1); 3455 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3456 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3457 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3458 tcg_temp_free_i32(t2); 3459 tcg_temp_free_i32(t3); 3460 } 3461 break; 3462 #if defined(TARGET_MIPS64) 3463 case OPC_DDIV: 3464 { 3465 TCGv t2 = tcg_temp_new(); 3466 TCGv t3 = tcg_temp_new(); 3467 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3469 tcg_gen_and_tl(t2, t2, t3); 3470 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3471 tcg_gen_or_tl(t2, t2, t3); 3472 tcg_gen_movi_tl(t3, 0); 3473 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3474 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3475 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3476 tcg_temp_free(t3); 3477 tcg_temp_free(t2); 3478 } 3479 break; 3480 case OPC_DDIVU: 3481 { 3482 TCGv t2 = tcg_const_tl(0); 3483 TCGv t3 = tcg_const_tl(1); 3484 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3485 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3486 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3487 tcg_temp_free(t3); 3488 tcg_temp_free(t2); 3489 } 3490 break; 3491 case OPC_DMULT: 3492 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3493 break; 3494 case OPC_DMULTU: 3495 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3496 break; 3497 #endif 3498 case OPC_MADD: 3499 { 3500 TCGv_i64 t2 = tcg_temp_new_i64(); 3501 TCGv_i64 t3 = tcg_temp_new_i64(); 3502 3503 tcg_gen_ext_tl_i64(t2, t0); 3504 tcg_gen_ext_tl_i64(t3, t1); 3505 tcg_gen_mul_i64(t2, t2, t3); 3506 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3507 tcg_gen_add_i64(t2, t2, t3); 3508 tcg_temp_free_i64(t3); 3509 gen_move_low32(cpu_LO[acc], t2); 3510 gen_move_high32(cpu_HI[acc], t2); 3511 tcg_temp_free_i64(t2); 3512 } 3513 break; 3514 case 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 tcg_temp_free_i64(t3); 3527 gen_move_low32(cpu_LO[acc], t2); 3528 gen_move_high32(cpu_HI[acc], t2); 3529 tcg_temp_free_i64(t2); 3530 } 3531 break; 3532 case OPC_MSUB: 3533 { 3534 TCGv_i64 t2 = tcg_temp_new_i64(); 3535 TCGv_i64 t3 = tcg_temp_new_i64(); 3536 3537 tcg_gen_ext_tl_i64(t2, t0); 3538 tcg_gen_ext_tl_i64(t3, t1); 3539 tcg_gen_mul_i64(t2, t2, t3); 3540 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3541 tcg_gen_sub_i64(t2, t3, t2); 3542 tcg_temp_free_i64(t3); 3543 gen_move_low32(cpu_LO[acc], t2); 3544 gen_move_high32(cpu_HI[acc], t2); 3545 tcg_temp_free_i64(t2); 3546 } 3547 break; 3548 case OPC_MSUBU: 3549 { 3550 TCGv_i64 t2 = tcg_temp_new_i64(); 3551 TCGv_i64 t3 = tcg_temp_new_i64(); 3552 3553 tcg_gen_ext32u_tl(t0, t0); 3554 tcg_gen_ext32u_tl(t1, t1); 3555 tcg_gen_extu_tl_i64(t2, t0); 3556 tcg_gen_extu_tl_i64(t3, t1); 3557 tcg_gen_mul_i64(t2, t2, t3); 3558 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3559 tcg_gen_sub_i64(t2, t3, t2); 3560 tcg_temp_free_i64(t3); 3561 gen_move_low32(cpu_LO[acc], t2); 3562 gen_move_high32(cpu_HI[acc], t2); 3563 tcg_temp_free_i64(t2); 3564 } 3565 break; 3566 default: 3567 MIPS_INVAL("mul/div"); 3568 gen_reserved_instruction(ctx); 3569 goto out; 3570 } 3571 out: 3572 tcg_temp_free(t0); 3573 tcg_temp_free(t1); 3574 } 3575 3576 /* 3577 * These MULT[U] and MADD[U] instructions implemented in for example 3578 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3579 * architectures are special three-operand variants with the syntax 3580 * 3581 * MULT[U][1] rd, rs, rt 3582 * 3583 * such that 3584 * 3585 * (rd, LO, HI) <- rs * rt 3586 * 3587 * and 3588 * 3589 * MADD[U][1] rd, rs, rt 3590 * 3591 * such that 3592 * 3593 * (rd, LO, HI) <- (LO, HI) + rs * rt 3594 * 3595 * where the low-order 32-bits of the result is placed into both the 3596 * GPR rd and the special register LO. The high-order 32-bits of the 3597 * result is placed into the special register HI. 3598 * 3599 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3600 * which is the zero register that always reads as 0. 3601 */ 3602 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3603 int rd, int rs, int rt) 3604 { 3605 TCGv t0 = tcg_temp_new(); 3606 TCGv t1 = tcg_temp_new(); 3607 int acc = 0; 3608 3609 gen_load_gpr(t0, rs); 3610 gen_load_gpr(t1, rt); 3611 3612 switch (opc) { 3613 case MMI_OPC_MULT1: 3614 acc = 1; 3615 /* Fall through */ 3616 case OPC_MULT: 3617 { 3618 TCGv_i32 t2 = tcg_temp_new_i32(); 3619 TCGv_i32 t3 = tcg_temp_new_i32(); 3620 tcg_gen_trunc_tl_i32(t2, t0); 3621 tcg_gen_trunc_tl_i32(t3, t1); 3622 tcg_gen_muls2_i32(t2, t3, t2, t3); 3623 if (rd) { 3624 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3625 } 3626 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3627 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3628 tcg_temp_free_i32(t2); 3629 tcg_temp_free_i32(t3); 3630 } 3631 break; 3632 case MMI_OPC_MULTU1: 3633 acc = 1; 3634 /* Fall through */ 3635 case OPC_MULTU: 3636 { 3637 TCGv_i32 t2 = tcg_temp_new_i32(); 3638 TCGv_i32 t3 = tcg_temp_new_i32(); 3639 tcg_gen_trunc_tl_i32(t2, t0); 3640 tcg_gen_trunc_tl_i32(t3, t1); 3641 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3642 if (rd) { 3643 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3644 } 3645 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3646 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3647 tcg_temp_free_i32(t2); 3648 tcg_temp_free_i32(t3); 3649 } 3650 break; 3651 case MMI_OPC_MADD1: 3652 acc = 1; 3653 /* Fall through */ 3654 case MMI_OPC_MADD: 3655 { 3656 TCGv_i64 t2 = tcg_temp_new_i64(); 3657 TCGv_i64 t3 = tcg_temp_new_i64(); 3658 3659 tcg_gen_ext_tl_i64(t2, t0); 3660 tcg_gen_ext_tl_i64(t3, t1); 3661 tcg_gen_mul_i64(t2, t2, t3); 3662 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3663 tcg_gen_add_i64(t2, t2, t3); 3664 tcg_temp_free_i64(t3); 3665 gen_move_low32(cpu_LO[acc], t2); 3666 gen_move_high32(cpu_HI[acc], t2); 3667 if (rd) { 3668 gen_move_low32(cpu_gpr[rd], t2); 3669 } 3670 tcg_temp_free_i64(t2); 3671 } 3672 break; 3673 case MMI_OPC_MADDU1: 3674 acc = 1; 3675 /* Fall through */ 3676 case MMI_OPC_MADDU: 3677 { 3678 TCGv_i64 t2 = tcg_temp_new_i64(); 3679 TCGv_i64 t3 = tcg_temp_new_i64(); 3680 3681 tcg_gen_ext32u_tl(t0, t0); 3682 tcg_gen_ext32u_tl(t1, t1); 3683 tcg_gen_extu_tl_i64(t2, t0); 3684 tcg_gen_extu_tl_i64(t3, t1); 3685 tcg_gen_mul_i64(t2, t2, t3); 3686 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3687 tcg_gen_add_i64(t2, t2, t3); 3688 tcg_temp_free_i64(t3); 3689 gen_move_low32(cpu_LO[acc], t2); 3690 gen_move_high32(cpu_HI[acc], t2); 3691 if (rd) { 3692 gen_move_low32(cpu_gpr[rd], t2); 3693 } 3694 tcg_temp_free_i64(t2); 3695 } 3696 break; 3697 default: 3698 MIPS_INVAL("mul/madd TXx9"); 3699 gen_reserved_instruction(ctx); 3700 goto out; 3701 } 3702 3703 out: 3704 tcg_temp_free(t0); 3705 tcg_temp_free(t1); 3706 } 3707 3708 static void gen_cl(DisasContext *ctx, uint32_t opc, 3709 int rd, int rs) 3710 { 3711 TCGv t0; 3712 3713 if (rd == 0) { 3714 /* Treat as NOP. */ 3715 return; 3716 } 3717 t0 = cpu_gpr[rd]; 3718 gen_load_gpr(t0, rs); 3719 3720 switch (opc) { 3721 case OPC_CLO: 3722 case R6_OPC_CLO: 3723 #if defined(TARGET_MIPS64) 3724 case OPC_DCLO: 3725 case R6_OPC_DCLO: 3726 #endif 3727 tcg_gen_not_tl(t0, t0); 3728 break; 3729 } 3730 3731 switch (opc) { 3732 case OPC_CLO: 3733 case R6_OPC_CLO: 3734 case OPC_CLZ: 3735 case R6_OPC_CLZ: 3736 tcg_gen_ext32u_tl(t0, t0); 3737 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3738 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3739 break; 3740 #if defined(TARGET_MIPS64) 3741 case OPC_DCLO: 3742 case R6_OPC_DCLO: 3743 case OPC_DCLZ: 3744 case R6_OPC_DCLZ: 3745 tcg_gen_clzi_i64(t0, t0, 64); 3746 break; 3747 #endif 3748 } 3749 } 3750 3751 /* Godson integer instructions */ 3752 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3753 int rd, int rs, int rt) 3754 { 3755 TCGv t0, t1; 3756 3757 if (rd == 0) { 3758 /* Treat as NOP. */ 3759 return; 3760 } 3761 3762 switch (opc) { 3763 case OPC_MULT_G_2E: 3764 case OPC_MULT_G_2F: 3765 case OPC_MULTU_G_2E: 3766 case OPC_MULTU_G_2F: 3767 #if defined(TARGET_MIPS64) 3768 case OPC_DMULT_G_2E: 3769 case OPC_DMULT_G_2F: 3770 case OPC_DMULTU_G_2E: 3771 case OPC_DMULTU_G_2F: 3772 #endif 3773 t0 = tcg_temp_new(); 3774 t1 = tcg_temp_new(); 3775 break; 3776 default: 3777 t0 = tcg_temp_local_new(); 3778 t1 = tcg_temp_local_new(); 3779 break; 3780 } 3781 3782 gen_load_gpr(t0, rs); 3783 gen_load_gpr(t1, rt); 3784 3785 switch (opc) { 3786 case OPC_MULT_G_2E: 3787 case OPC_MULT_G_2F: 3788 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3789 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3790 break; 3791 case OPC_MULTU_G_2E: 3792 case OPC_MULTU_G_2F: 3793 tcg_gen_ext32u_tl(t0, t0); 3794 tcg_gen_ext32u_tl(t1, t1); 3795 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3796 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3797 break; 3798 case OPC_DIV_G_2E: 3799 case OPC_DIV_G_2F: 3800 { 3801 TCGLabel *l1 = gen_new_label(); 3802 TCGLabel *l2 = gen_new_label(); 3803 TCGLabel *l3 = gen_new_label(); 3804 tcg_gen_ext32s_tl(t0, t0); 3805 tcg_gen_ext32s_tl(t1, t1); 3806 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3807 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3808 tcg_gen_br(l3); 3809 gen_set_label(l1); 3810 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3811 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3812 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3813 tcg_gen_br(l3); 3814 gen_set_label(l2); 3815 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3816 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3817 gen_set_label(l3); 3818 } 3819 break; 3820 case OPC_DIVU_G_2E: 3821 case OPC_DIVU_G_2F: 3822 { 3823 TCGLabel *l1 = gen_new_label(); 3824 TCGLabel *l2 = gen_new_label(); 3825 tcg_gen_ext32u_tl(t0, t0); 3826 tcg_gen_ext32u_tl(t1, t1); 3827 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3828 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3829 tcg_gen_br(l2); 3830 gen_set_label(l1); 3831 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3832 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3833 gen_set_label(l2); 3834 } 3835 break; 3836 case OPC_MOD_G_2E: 3837 case OPC_MOD_G_2F: 3838 { 3839 TCGLabel *l1 = gen_new_label(); 3840 TCGLabel *l2 = gen_new_label(); 3841 TCGLabel *l3 = gen_new_label(); 3842 tcg_gen_ext32u_tl(t0, t0); 3843 tcg_gen_ext32u_tl(t1, t1); 3844 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3845 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3846 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3847 gen_set_label(l1); 3848 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3849 tcg_gen_br(l3); 3850 gen_set_label(l2); 3851 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3852 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3853 gen_set_label(l3); 3854 } 3855 break; 3856 case OPC_MODU_G_2E: 3857 case OPC_MODU_G_2F: 3858 { 3859 TCGLabel *l1 = gen_new_label(); 3860 TCGLabel *l2 = gen_new_label(); 3861 tcg_gen_ext32u_tl(t0, t0); 3862 tcg_gen_ext32u_tl(t1, t1); 3863 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3864 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3865 tcg_gen_br(l2); 3866 gen_set_label(l1); 3867 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3868 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3869 gen_set_label(l2); 3870 } 3871 break; 3872 #if defined(TARGET_MIPS64) 3873 case OPC_DMULT_G_2E: 3874 case OPC_DMULT_G_2F: 3875 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3876 break; 3877 case OPC_DMULTU_G_2E: 3878 case OPC_DMULTU_G_2F: 3879 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3880 break; 3881 case OPC_DDIV_G_2E: 3882 case OPC_DDIV_G_2F: 3883 { 3884 TCGLabel *l1 = gen_new_label(); 3885 TCGLabel *l2 = gen_new_label(); 3886 TCGLabel *l3 = gen_new_label(); 3887 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3888 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3889 tcg_gen_br(l3); 3890 gen_set_label(l1); 3891 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3892 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3893 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3894 tcg_gen_br(l3); 3895 gen_set_label(l2); 3896 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3897 gen_set_label(l3); 3898 } 3899 break; 3900 case OPC_DDIVU_G_2E: 3901 case OPC_DDIVU_G_2F: 3902 { 3903 TCGLabel *l1 = gen_new_label(); 3904 TCGLabel *l2 = gen_new_label(); 3905 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3906 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3907 tcg_gen_br(l2); 3908 gen_set_label(l1); 3909 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3910 gen_set_label(l2); 3911 } 3912 break; 3913 case OPC_DMOD_G_2E: 3914 case OPC_DMOD_G_2F: 3915 { 3916 TCGLabel *l1 = gen_new_label(); 3917 TCGLabel *l2 = gen_new_label(); 3918 TCGLabel *l3 = gen_new_label(); 3919 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3920 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3921 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3922 gen_set_label(l1); 3923 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3924 tcg_gen_br(l3); 3925 gen_set_label(l2); 3926 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3927 gen_set_label(l3); 3928 } 3929 break; 3930 case OPC_DMODU_G_2E: 3931 case OPC_DMODU_G_2F: 3932 { 3933 TCGLabel *l1 = gen_new_label(); 3934 TCGLabel *l2 = gen_new_label(); 3935 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3936 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3937 tcg_gen_br(l2); 3938 gen_set_label(l1); 3939 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3940 gen_set_label(l2); 3941 } 3942 break; 3943 #endif 3944 } 3945 3946 tcg_temp_free(t0); 3947 tcg_temp_free(t1); 3948 } 3949 3950 /* Loongson multimedia instructions */ 3951 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3952 { 3953 uint32_t opc, shift_max; 3954 TCGv_i64 t0, t1; 3955 TCGCond cond; 3956 3957 opc = MASK_LMMI(ctx->opcode); 3958 switch (opc) { 3959 case OPC_ADD_CP2: 3960 case OPC_SUB_CP2: 3961 case OPC_DADD_CP2: 3962 case OPC_DSUB_CP2: 3963 t0 = tcg_temp_local_new_i64(); 3964 t1 = tcg_temp_local_new_i64(); 3965 break; 3966 default: 3967 t0 = tcg_temp_new_i64(); 3968 t1 = tcg_temp_new_i64(); 3969 break; 3970 } 3971 3972 check_cp1_enabled(ctx); 3973 gen_load_fpr64(ctx, t0, rs); 3974 gen_load_fpr64(ctx, t1, rt); 3975 3976 switch (opc) { 3977 case OPC_PADDSH: 3978 gen_helper_paddsh(t0, t0, t1); 3979 break; 3980 case OPC_PADDUSH: 3981 gen_helper_paddush(t0, t0, t1); 3982 break; 3983 case OPC_PADDH: 3984 gen_helper_paddh(t0, t0, t1); 3985 break; 3986 case OPC_PADDW: 3987 gen_helper_paddw(t0, t0, t1); 3988 break; 3989 case OPC_PADDSB: 3990 gen_helper_paddsb(t0, t0, t1); 3991 break; 3992 case OPC_PADDUSB: 3993 gen_helper_paddusb(t0, t0, t1); 3994 break; 3995 case OPC_PADDB: 3996 gen_helper_paddb(t0, t0, t1); 3997 break; 3998 3999 case OPC_PSUBSH: 4000 gen_helper_psubsh(t0, t0, t1); 4001 break; 4002 case OPC_PSUBUSH: 4003 gen_helper_psubush(t0, t0, t1); 4004 break; 4005 case OPC_PSUBH: 4006 gen_helper_psubh(t0, t0, t1); 4007 break; 4008 case OPC_PSUBW: 4009 gen_helper_psubw(t0, t0, t1); 4010 break; 4011 case OPC_PSUBSB: 4012 gen_helper_psubsb(t0, t0, t1); 4013 break; 4014 case OPC_PSUBUSB: 4015 gen_helper_psubusb(t0, t0, t1); 4016 break; 4017 case OPC_PSUBB: 4018 gen_helper_psubb(t0, t0, t1); 4019 break; 4020 4021 case OPC_PSHUFH: 4022 gen_helper_pshufh(t0, t0, t1); 4023 break; 4024 case OPC_PACKSSWH: 4025 gen_helper_packsswh(t0, t0, t1); 4026 break; 4027 case OPC_PACKSSHB: 4028 gen_helper_packsshb(t0, t0, t1); 4029 break; 4030 case OPC_PACKUSHB: 4031 gen_helper_packushb(t0, t0, t1); 4032 break; 4033 4034 case OPC_PUNPCKLHW: 4035 gen_helper_punpcklhw(t0, t0, t1); 4036 break; 4037 case OPC_PUNPCKHHW: 4038 gen_helper_punpckhhw(t0, t0, t1); 4039 break; 4040 case OPC_PUNPCKLBH: 4041 gen_helper_punpcklbh(t0, t0, t1); 4042 break; 4043 case OPC_PUNPCKHBH: 4044 gen_helper_punpckhbh(t0, t0, t1); 4045 break; 4046 case OPC_PUNPCKLWD: 4047 gen_helper_punpcklwd(t0, t0, t1); 4048 break; 4049 case OPC_PUNPCKHWD: 4050 gen_helper_punpckhwd(t0, t0, t1); 4051 break; 4052 4053 case OPC_PAVGH: 4054 gen_helper_pavgh(t0, t0, t1); 4055 break; 4056 case OPC_PAVGB: 4057 gen_helper_pavgb(t0, t0, t1); 4058 break; 4059 case OPC_PMAXSH: 4060 gen_helper_pmaxsh(t0, t0, t1); 4061 break; 4062 case OPC_PMINSH: 4063 gen_helper_pminsh(t0, t0, t1); 4064 break; 4065 case OPC_PMAXUB: 4066 gen_helper_pmaxub(t0, t0, t1); 4067 break; 4068 case OPC_PMINUB: 4069 gen_helper_pminub(t0, t0, t1); 4070 break; 4071 4072 case OPC_PCMPEQW: 4073 gen_helper_pcmpeqw(t0, t0, t1); 4074 break; 4075 case OPC_PCMPGTW: 4076 gen_helper_pcmpgtw(t0, t0, t1); 4077 break; 4078 case OPC_PCMPEQH: 4079 gen_helper_pcmpeqh(t0, t0, t1); 4080 break; 4081 case OPC_PCMPGTH: 4082 gen_helper_pcmpgth(t0, t0, t1); 4083 break; 4084 case OPC_PCMPEQB: 4085 gen_helper_pcmpeqb(t0, t0, t1); 4086 break; 4087 case OPC_PCMPGTB: 4088 gen_helper_pcmpgtb(t0, t0, t1); 4089 break; 4090 4091 case OPC_PSLLW: 4092 gen_helper_psllw(t0, t0, t1); 4093 break; 4094 case OPC_PSLLH: 4095 gen_helper_psllh(t0, t0, t1); 4096 break; 4097 case OPC_PSRLW: 4098 gen_helper_psrlw(t0, t0, t1); 4099 break; 4100 case OPC_PSRLH: 4101 gen_helper_psrlh(t0, t0, t1); 4102 break; 4103 case OPC_PSRAW: 4104 gen_helper_psraw(t0, t0, t1); 4105 break; 4106 case OPC_PSRAH: 4107 gen_helper_psrah(t0, t0, t1); 4108 break; 4109 4110 case OPC_PMULLH: 4111 gen_helper_pmullh(t0, t0, t1); 4112 break; 4113 case OPC_PMULHH: 4114 gen_helper_pmulhh(t0, t0, t1); 4115 break; 4116 case OPC_PMULHUH: 4117 gen_helper_pmulhuh(t0, t0, t1); 4118 break; 4119 case OPC_PMADDHW: 4120 gen_helper_pmaddhw(t0, t0, t1); 4121 break; 4122 4123 case OPC_PASUBUB: 4124 gen_helper_pasubub(t0, t0, t1); 4125 break; 4126 case OPC_BIADD: 4127 gen_helper_biadd(t0, t0); 4128 break; 4129 case OPC_PMOVMSKB: 4130 gen_helper_pmovmskb(t0, t0); 4131 break; 4132 4133 case OPC_PADDD: 4134 tcg_gen_add_i64(t0, t0, t1); 4135 break; 4136 case OPC_PSUBD: 4137 tcg_gen_sub_i64(t0, t0, t1); 4138 break; 4139 case OPC_XOR_CP2: 4140 tcg_gen_xor_i64(t0, t0, t1); 4141 break; 4142 case OPC_NOR_CP2: 4143 tcg_gen_nor_i64(t0, t0, t1); 4144 break; 4145 case OPC_AND_CP2: 4146 tcg_gen_and_i64(t0, t0, t1); 4147 break; 4148 case OPC_OR_CP2: 4149 tcg_gen_or_i64(t0, t0, t1); 4150 break; 4151 4152 case OPC_PANDN: 4153 tcg_gen_andc_i64(t0, t1, t0); 4154 break; 4155 4156 case OPC_PINSRH_0: 4157 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4158 break; 4159 case OPC_PINSRH_1: 4160 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4161 break; 4162 case OPC_PINSRH_2: 4163 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4164 break; 4165 case OPC_PINSRH_3: 4166 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4167 break; 4168 4169 case OPC_PEXTRH: 4170 tcg_gen_andi_i64(t1, t1, 3); 4171 tcg_gen_shli_i64(t1, t1, 4); 4172 tcg_gen_shr_i64(t0, t0, t1); 4173 tcg_gen_ext16u_i64(t0, t0); 4174 break; 4175 4176 case OPC_ADDU_CP2: 4177 tcg_gen_add_i64(t0, t0, t1); 4178 tcg_gen_ext32s_i64(t0, t0); 4179 break; 4180 case OPC_SUBU_CP2: 4181 tcg_gen_sub_i64(t0, t0, t1); 4182 tcg_gen_ext32s_i64(t0, t0); 4183 break; 4184 4185 case OPC_SLL_CP2: 4186 shift_max = 32; 4187 goto do_shift; 4188 case OPC_SRL_CP2: 4189 shift_max = 32; 4190 goto do_shift; 4191 case OPC_SRA_CP2: 4192 shift_max = 32; 4193 goto do_shift; 4194 case OPC_DSLL_CP2: 4195 shift_max = 64; 4196 goto do_shift; 4197 case OPC_DSRL_CP2: 4198 shift_max = 64; 4199 goto do_shift; 4200 case OPC_DSRA_CP2: 4201 shift_max = 64; 4202 goto do_shift; 4203 do_shift: 4204 /* Make sure shift count isn't TCG undefined behaviour. */ 4205 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4206 4207 switch (opc) { 4208 case OPC_SLL_CP2: 4209 case OPC_DSLL_CP2: 4210 tcg_gen_shl_i64(t0, t0, t1); 4211 break; 4212 case OPC_SRA_CP2: 4213 case OPC_DSRA_CP2: 4214 /* 4215 * Since SRA is UndefinedResult without sign-extended inputs, 4216 * we can treat SRA and DSRA the same. 4217 */ 4218 tcg_gen_sar_i64(t0, t0, t1); 4219 break; 4220 case OPC_SRL_CP2: 4221 /* We want to shift in zeros for SRL; zero-extend first. */ 4222 tcg_gen_ext32u_i64(t0, t0); 4223 /* FALLTHRU */ 4224 case OPC_DSRL_CP2: 4225 tcg_gen_shr_i64(t0, t0, t1); 4226 break; 4227 } 4228 4229 if (shift_max == 32) { 4230 tcg_gen_ext32s_i64(t0, t0); 4231 } 4232 4233 /* Shifts larger than MAX produce zero. */ 4234 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4235 tcg_gen_neg_i64(t1, t1); 4236 tcg_gen_and_i64(t0, t0, t1); 4237 break; 4238 4239 case OPC_ADD_CP2: 4240 case OPC_DADD_CP2: 4241 { 4242 TCGv_i64 t2 = tcg_temp_new_i64(); 4243 TCGLabel *lab = gen_new_label(); 4244 4245 tcg_gen_mov_i64(t2, t0); 4246 tcg_gen_add_i64(t0, t1, t2); 4247 if (opc == OPC_ADD_CP2) { 4248 tcg_gen_ext32s_i64(t0, t0); 4249 } 4250 tcg_gen_xor_i64(t1, t1, t2); 4251 tcg_gen_xor_i64(t2, t2, t0); 4252 tcg_gen_andc_i64(t1, t2, t1); 4253 tcg_temp_free_i64(t2); 4254 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4255 generate_exception(ctx, EXCP_OVERFLOW); 4256 gen_set_label(lab); 4257 break; 4258 } 4259 4260 case OPC_SUB_CP2: 4261 case OPC_DSUB_CP2: 4262 { 4263 TCGv_i64 t2 = tcg_temp_new_i64(); 4264 TCGLabel *lab = gen_new_label(); 4265 4266 tcg_gen_mov_i64(t2, t0); 4267 tcg_gen_sub_i64(t0, t1, t2); 4268 if (opc == OPC_SUB_CP2) { 4269 tcg_gen_ext32s_i64(t0, t0); 4270 } 4271 tcg_gen_xor_i64(t1, t1, t2); 4272 tcg_gen_xor_i64(t2, t2, t0); 4273 tcg_gen_and_i64(t1, t1, t2); 4274 tcg_temp_free_i64(t2); 4275 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4276 generate_exception(ctx, EXCP_OVERFLOW); 4277 gen_set_label(lab); 4278 break; 4279 } 4280 4281 case OPC_PMULUW: 4282 tcg_gen_ext32u_i64(t0, t0); 4283 tcg_gen_ext32u_i64(t1, t1); 4284 tcg_gen_mul_i64(t0, t0, t1); 4285 break; 4286 4287 case OPC_SEQU_CP2: 4288 case OPC_SEQ_CP2: 4289 cond = TCG_COND_EQ; 4290 goto do_cc_cond; 4291 break; 4292 case OPC_SLTU_CP2: 4293 cond = TCG_COND_LTU; 4294 goto do_cc_cond; 4295 break; 4296 case OPC_SLT_CP2: 4297 cond = TCG_COND_LT; 4298 goto do_cc_cond; 4299 break; 4300 case OPC_SLEU_CP2: 4301 cond = TCG_COND_LEU; 4302 goto do_cc_cond; 4303 break; 4304 case OPC_SLE_CP2: 4305 cond = TCG_COND_LE; 4306 do_cc_cond: 4307 { 4308 int cc = (ctx->opcode >> 8) & 0x7; 4309 TCGv_i64 t64 = tcg_temp_new_i64(); 4310 TCGv_i32 t32 = tcg_temp_new_i32(); 4311 4312 tcg_gen_setcond_i64(cond, t64, t0, t1); 4313 tcg_gen_extrl_i64_i32(t32, t64); 4314 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4315 get_fp_bit(cc), 1); 4316 4317 tcg_temp_free_i32(t32); 4318 tcg_temp_free_i64(t64); 4319 } 4320 goto no_rd; 4321 break; 4322 default: 4323 MIPS_INVAL("loongson_cp2"); 4324 gen_reserved_instruction(ctx); 4325 return; 4326 } 4327 4328 gen_store_fpr64(ctx, t0, rd); 4329 4330 no_rd: 4331 tcg_temp_free_i64(t0); 4332 tcg_temp_free_i64(t1); 4333 } 4334 4335 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4336 int rs, int rd) 4337 { 4338 TCGv t0, t1, t2; 4339 TCGv_i32 fp0; 4340 #if defined(TARGET_MIPS64) 4341 int lsq_rt1 = ctx->opcode & 0x1f; 4342 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4343 #endif 4344 int shf_offset = sextract32(ctx->opcode, 6, 8); 4345 4346 t0 = tcg_temp_new(); 4347 4348 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4349 #if defined(TARGET_MIPS64) 4350 case OPC_GSLQ: 4351 t1 = tcg_temp_new(); 4352 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4353 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4354 ctx->default_tcg_memop_mask); 4355 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4356 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4357 ctx->default_tcg_memop_mask); 4358 gen_store_gpr(t1, rt); 4359 gen_store_gpr(t0, lsq_rt1); 4360 tcg_temp_free(t1); 4361 break; 4362 case OPC_GSLQC1: 4363 check_cp1_enabled(ctx); 4364 t1 = tcg_temp_new(); 4365 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4366 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4367 ctx->default_tcg_memop_mask); 4368 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4369 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4370 ctx->default_tcg_memop_mask); 4371 gen_store_fpr64(ctx, t1, rt); 4372 gen_store_fpr64(ctx, t0, lsq_rt1); 4373 tcg_temp_free(t1); 4374 break; 4375 case OPC_GSSQ: 4376 t1 = tcg_temp_new(); 4377 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4378 gen_load_gpr(t1, rt); 4379 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4380 ctx->default_tcg_memop_mask); 4381 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4382 gen_load_gpr(t1, lsq_rt1); 4383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4384 ctx->default_tcg_memop_mask); 4385 tcg_temp_free(t1); 4386 break; 4387 case OPC_GSSQC1: 4388 check_cp1_enabled(ctx); 4389 t1 = tcg_temp_new(); 4390 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4391 gen_load_fpr64(ctx, t1, rt); 4392 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4393 ctx->default_tcg_memop_mask); 4394 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4395 gen_load_fpr64(ctx, t1, lsq_rt1); 4396 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4397 ctx->default_tcg_memop_mask); 4398 tcg_temp_free(t1); 4399 break; 4400 #endif 4401 case OPC_GSSHFL: 4402 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4403 case OPC_GSLWLC1: 4404 check_cp1_enabled(ctx); 4405 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4406 t1 = tcg_temp_new(); 4407 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4408 tcg_gen_andi_tl(t1, t0, 3); 4409 if (!cpu_is_bigendian(ctx)) { 4410 tcg_gen_xori_tl(t1, t1, 3); 4411 } 4412 tcg_gen_shli_tl(t1, t1, 3); 4413 tcg_gen_andi_tl(t0, t0, ~3); 4414 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4415 tcg_gen_shl_tl(t0, t0, t1); 4416 t2 = tcg_const_tl(-1); 4417 tcg_gen_shl_tl(t2, t2, t1); 4418 fp0 = tcg_temp_new_i32(); 4419 gen_load_fpr32(ctx, fp0, rt); 4420 tcg_gen_ext_i32_tl(t1, fp0); 4421 tcg_gen_andc_tl(t1, t1, t2); 4422 tcg_temp_free(t2); 4423 tcg_gen_or_tl(t0, t0, t1); 4424 tcg_temp_free(t1); 4425 #if defined(TARGET_MIPS64) 4426 tcg_gen_extrl_i64_i32(fp0, t0); 4427 #else 4428 tcg_gen_ext32s_tl(fp0, t0); 4429 #endif 4430 gen_store_fpr32(ctx, fp0, rt); 4431 tcg_temp_free_i32(fp0); 4432 break; 4433 case OPC_GSLWRC1: 4434 check_cp1_enabled(ctx); 4435 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4436 t1 = tcg_temp_new(); 4437 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4438 tcg_gen_andi_tl(t1, t0, 3); 4439 if (cpu_is_bigendian(ctx)) { 4440 tcg_gen_xori_tl(t1, t1, 3); 4441 } 4442 tcg_gen_shli_tl(t1, t1, 3); 4443 tcg_gen_andi_tl(t0, t0, ~3); 4444 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4445 tcg_gen_shr_tl(t0, t0, t1); 4446 tcg_gen_xori_tl(t1, t1, 31); 4447 t2 = tcg_const_tl(0xfffffffeull); 4448 tcg_gen_shl_tl(t2, t2, t1); 4449 fp0 = tcg_temp_new_i32(); 4450 gen_load_fpr32(ctx, fp0, rt); 4451 tcg_gen_ext_i32_tl(t1, fp0); 4452 tcg_gen_and_tl(t1, t1, t2); 4453 tcg_temp_free(t2); 4454 tcg_gen_or_tl(t0, t0, t1); 4455 tcg_temp_free(t1); 4456 #if defined(TARGET_MIPS64) 4457 tcg_gen_extrl_i64_i32(fp0, t0); 4458 #else 4459 tcg_gen_ext32s_tl(fp0, t0); 4460 #endif 4461 gen_store_fpr32(ctx, fp0, rt); 4462 tcg_temp_free_i32(fp0); 4463 break; 4464 #if defined(TARGET_MIPS64) 4465 case OPC_GSLDLC1: 4466 check_cp1_enabled(ctx); 4467 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4468 t1 = tcg_temp_new(); 4469 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4470 tcg_gen_andi_tl(t1, t0, 7); 4471 if (!cpu_is_bigendian(ctx)) { 4472 tcg_gen_xori_tl(t1, t1, 7); 4473 } 4474 tcg_gen_shli_tl(t1, t1, 3); 4475 tcg_gen_andi_tl(t0, t0, ~7); 4476 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 4477 tcg_gen_shl_tl(t0, t0, t1); 4478 t2 = tcg_const_tl(-1); 4479 tcg_gen_shl_tl(t2, t2, t1); 4480 gen_load_fpr64(ctx, t1, rt); 4481 tcg_gen_andc_tl(t1, t1, t2); 4482 tcg_temp_free(t2); 4483 tcg_gen_or_tl(t0, t0, t1); 4484 tcg_temp_free(t1); 4485 gen_store_fpr64(ctx, t0, rt); 4486 break; 4487 case OPC_GSLDRC1: 4488 check_cp1_enabled(ctx); 4489 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4490 t1 = tcg_temp_new(); 4491 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4492 tcg_gen_andi_tl(t1, t0, 7); 4493 if (cpu_is_bigendian(ctx)) { 4494 tcg_gen_xori_tl(t1, t1, 7); 4495 } 4496 tcg_gen_shli_tl(t1, t1, 3); 4497 tcg_gen_andi_tl(t0, t0, ~7); 4498 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 4499 tcg_gen_shr_tl(t0, t0, t1); 4500 tcg_gen_xori_tl(t1, t1, 63); 4501 t2 = tcg_const_tl(0xfffffffffffffffeull); 4502 tcg_gen_shl_tl(t2, t2, t1); 4503 gen_load_fpr64(ctx, t1, rt); 4504 tcg_gen_and_tl(t1, t1, t2); 4505 tcg_temp_free(t2); 4506 tcg_gen_or_tl(t0, t0, t1); 4507 tcg_temp_free(t1); 4508 gen_store_fpr64(ctx, t0, rt); 4509 break; 4510 #endif 4511 default: 4512 MIPS_INVAL("loongson_gsshfl"); 4513 gen_reserved_instruction(ctx); 4514 break; 4515 } 4516 break; 4517 case OPC_GSSHFS: 4518 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4519 case OPC_GSSWLC1: 4520 check_cp1_enabled(ctx); 4521 t1 = tcg_temp_new(); 4522 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4523 fp0 = tcg_temp_new_i32(); 4524 gen_load_fpr32(ctx, fp0, rt); 4525 tcg_gen_ext_i32_tl(t1, fp0); 4526 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4527 tcg_temp_free_i32(fp0); 4528 tcg_temp_free(t1); 4529 break; 4530 case OPC_GSSWRC1: 4531 check_cp1_enabled(ctx); 4532 t1 = tcg_temp_new(); 4533 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4534 fp0 = tcg_temp_new_i32(); 4535 gen_load_fpr32(ctx, fp0, rt); 4536 tcg_gen_ext_i32_tl(t1, fp0); 4537 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4538 tcg_temp_free_i32(fp0); 4539 tcg_temp_free(t1); 4540 break; 4541 #if defined(TARGET_MIPS64) 4542 case OPC_GSSDLC1: 4543 check_cp1_enabled(ctx); 4544 t1 = tcg_temp_new(); 4545 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4546 gen_load_fpr64(ctx, t1, rt); 4547 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4548 tcg_temp_free(t1); 4549 break; 4550 case OPC_GSSDRC1: 4551 check_cp1_enabled(ctx); 4552 t1 = tcg_temp_new(); 4553 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4554 gen_load_fpr64(ctx, t1, rt); 4555 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4556 tcg_temp_free(t1); 4557 break; 4558 #endif 4559 default: 4560 MIPS_INVAL("loongson_gsshfs"); 4561 gen_reserved_instruction(ctx); 4562 break; 4563 } 4564 break; 4565 default: 4566 MIPS_INVAL("loongson_gslsq"); 4567 gen_reserved_instruction(ctx); 4568 break; 4569 } 4570 tcg_temp_free(t0); 4571 } 4572 4573 /* Loongson EXT LDC2/SDC2 */ 4574 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4575 int rs, int rd) 4576 { 4577 int offset = sextract32(ctx->opcode, 3, 8); 4578 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4579 TCGv t0, t1; 4580 TCGv_i32 fp0; 4581 4582 /* Pre-conditions */ 4583 switch (opc) { 4584 case OPC_GSLBX: 4585 case OPC_GSLHX: 4586 case OPC_GSLWX: 4587 case OPC_GSLDX: 4588 /* prefetch, implement as NOP */ 4589 if (rt == 0) { 4590 return; 4591 } 4592 break; 4593 case OPC_GSSBX: 4594 case OPC_GSSHX: 4595 case OPC_GSSWX: 4596 case OPC_GSSDX: 4597 break; 4598 case OPC_GSLWXC1: 4599 #if defined(TARGET_MIPS64) 4600 case OPC_GSLDXC1: 4601 #endif 4602 check_cp1_enabled(ctx); 4603 /* prefetch, implement as NOP */ 4604 if (rt == 0) { 4605 return; 4606 } 4607 break; 4608 case OPC_GSSWXC1: 4609 #if defined(TARGET_MIPS64) 4610 case OPC_GSSDXC1: 4611 #endif 4612 check_cp1_enabled(ctx); 4613 break; 4614 default: 4615 MIPS_INVAL("loongson_lsdc2"); 4616 gen_reserved_instruction(ctx); 4617 return; 4618 break; 4619 } 4620 4621 t0 = tcg_temp_new(); 4622 4623 gen_base_offset_addr(ctx, t0, rs, offset); 4624 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4625 4626 switch (opc) { 4627 case OPC_GSLBX: 4628 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4629 gen_store_gpr(t0, rt); 4630 break; 4631 case OPC_GSLHX: 4632 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4633 ctx->default_tcg_memop_mask); 4634 gen_store_gpr(t0, rt); 4635 break; 4636 case OPC_GSLWX: 4637 gen_base_offset_addr(ctx, t0, rs, offset); 4638 if (rd) { 4639 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4640 } 4641 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4642 ctx->default_tcg_memop_mask); 4643 gen_store_gpr(t0, rt); 4644 break; 4645 #if defined(TARGET_MIPS64) 4646 case OPC_GSLDX: 4647 gen_base_offset_addr(ctx, t0, rs, offset); 4648 if (rd) { 4649 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4650 } 4651 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4652 ctx->default_tcg_memop_mask); 4653 gen_store_gpr(t0, rt); 4654 break; 4655 #endif 4656 case OPC_GSLWXC1: 4657 gen_base_offset_addr(ctx, t0, rs, offset); 4658 if (rd) { 4659 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4660 } 4661 fp0 = tcg_temp_new_i32(); 4662 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4663 ctx->default_tcg_memop_mask); 4664 gen_store_fpr32(ctx, fp0, rt); 4665 tcg_temp_free_i32(fp0); 4666 break; 4667 #if defined(TARGET_MIPS64) 4668 case OPC_GSLDXC1: 4669 gen_base_offset_addr(ctx, t0, rs, offset); 4670 if (rd) { 4671 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4672 } 4673 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4674 ctx->default_tcg_memop_mask); 4675 gen_store_fpr64(ctx, t0, rt); 4676 break; 4677 #endif 4678 case OPC_GSSBX: 4679 t1 = tcg_temp_new(); 4680 gen_load_gpr(t1, rt); 4681 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4682 tcg_temp_free(t1); 4683 break; 4684 case OPC_GSSHX: 4685 t1 = tcg_temp_new(); 4686 gen_load_gpr(t1, rt); 4687 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4688 ctx->default_tcg_memop_mask); 4689 tcg_temp_free(t1); 4690 break; 4691 case OPC_GSSWX: 4692 t1 = tcg_temp_new(); 4693 gen_load_gpr(t1, rt); 4694 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4695 ctx->default_tcg_memop_mask); 4696 tcg_temp_free(t1); 4697 break; 4698 #if defined(TARGET_MIPS64) 4699 case OPC_GSSDX: 4700 t1 = tcg_temp_new(); 4701 gen_load_gpr(t1, rt); 4702 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4703 ctx->default_tcg_memop_mask); 4704 tcg_temp_free(t1); 4705 break; 4706 #endif 4707 case OPC_GSSWXC1: 4708 fp0 = tcg_temp_new_i32(); 4709 gen_load_fpr32(ctx, fp0, rt); 4710 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4711 ctx->default_tcg_memop_mask); 4712 tcg_temp_free_i32(fp0); 4713 break; 4714 #if defined(TARGET_MIPS64) 4715 case OPC_GSSDXC1: 4716 t1 = tcg_temp_new(); 4717 gen_load_fpr64(ctx, t1, rt); 4718 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ | 4719 ctx->default_tcg_memop_mask); 4720 tcg_temp_free(t1); 4721 break; 4722 #endif 4723 default: 4724 break; 4725 } 4726 4727 tcg_temp_free(t0); 4728 } 4729 4730 /* Traps */ 4731 static void gen_trap(DisasContext *ctx, uint32_t opc, 4732 int rs, int rt, int16_t imm, int code) 4733 { 4734 int cond; 4735 TCGv t0 = tcg_temp_new(); 4736 TCGv t1 = tcg_temp_new(); 4737 4738 cond = 0; 4739 /* Load needed operands */ 4740 switch (opc) { 4741 case OPC_TEQ: 4742 case OPC_TGE: 4743 case OPC_TGEU: 4744 case OPC_TLT: 4745 case OPC_TLTU: 4746 case OPC_TNE: 4747 /* Compare two registers */ 4748 if (rs != rt) { 4749 gen_load_gpr(t0, rs); 4750 gen_load_gpr(t1, rt); 4751 cond = 1; 4752 } 4753 break; 4754 case OPC_TEQI: 4755 case OPC_TGEI: 4756 case OPC_TGEIU: 4757 case OPC_TLTI: 4758 case OPC_TLTIU: 4759 case OPC_TNEI: 4760 /* Compare register to immediate */ 4761 if (rs != 0 || imm != 0) { 4762 gen_load_gpr(t0, rs); 4763 tcg_gen_movi_tl(t1, (int32_t)imm); 4764 cond = 1; 4765 } 4766 break; 4767 } 4768 if (cond == 0) { 4769 switch (opc) { 4770 case OPC_TEQ: /* rs == rs */ 4771 case OPC_TEQI: /* r0 == 0 */ 4772 case OPC_TGE: /* rs >= rs */ 4773 case OPC_TGEI: /* r0 >= 0 */ 4774 case OPC_TGEU: /* rs >= rs unsigned */ 4775 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4776 /* Always trap */ 4777 #ifdef CONFIG_USER_ONLY 4778 /* Pass the break code along to cpu_loop. */ 4779 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4780 offsetof(CPUMIPSState, error_code)); 4781 #endif 4782 generate_exception_end(ctx, EXCP_TRAP); 4783 break; 4784 case OPC_TLT: /* rs < rs */ 4785 case OPC_TLTI: /* r0 < 0 */ 4786 case OPC_TLTU: /* rs < rs unsigned */ 4787 case OPC_TLTIU: /* r0 < 0 unsigned */ 4788 case OPC_TNE: /* rs != rs */ 4789 case OPC_TNEI: /* r0 != 0 */ 4790 /* Never trap: treat as NOP. */ 4791 break; 4792 } 4793 } else { 4794 TCGLabel *l1 = gen_new_label(); 4795 4796 switch (opc) { 4797 case OPC_TEQ: 4798 case OPC_TEQI: 4799 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4800 break; 4801 case OPC_TGE: 4802 case OPC_TGEI: 4803 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4804 break; 4805 case OPC_TGEU: 4806 case OPC_TGEIU: 4807 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4808 break; 4809 case OPC_TLT: 4810 case OPC_TLTI: 4811 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4812 break; 4813 case OPC_TLTU: 4814 case OPC_TLTIU: 4815 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4816 break; 4817 case OPC_TNE: 4818 case OPC_TNEI: 4819 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4820 break; 4821 } 4822 #ifdef CONFIG_USER_ONLY 4823 /* Pass the break code along to cpu_loop. */ 4824 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4825 offsetof(CPUMIPSState, error_code)); 4826 #endif 4827 /* Like save_cpu_state, only don't update saved values. */ 4828 if (ctx->base.pc_next != ctx->saved_pc) { 4829 gen_save_pc(ctx->base.pc_next); 4830 } 4831 if (ctx->hflags != ctx->saved_hflags) { 4832 tcg_gen_movi_i32(hflags, ctx->hflags); 4833 } 4834 generate_exception(ctx, EXCP_TRAP); 4835 gen_set_label(l1); 4836 } 4837 tcg_temp_free(t0); 4838 tcg_temp_free(t1); 4839 } 4840 4841 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4842 { 4843 if (translator_use_goto_tb(&ctx->base, dest)) { 4844 tcg_gen_goto_tb(n); 4845 gen_save_pc(dest); 4846 tcg_gen_exit_tb(ctx->base.tb, n); 4847 } else { 4848 gen_save_pc(dest); 4849 tcg_gen_lookup_and_goto_ptr(); 4850 } 4851 } 4852 4853 /* Branches (before delay slot) */ 4854 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4855 int insn_bytes, 4856 int rs, int rt, int32_t offset, 4857 int delayslot_size) 4858 { 4859 target_ulong btgt = -1; 4860 int blink = 0; 4861 int bcond_compute = 0; 4862 TCGv t0 = tcg_temp_new(); 4863 TCGv t1 = tcg_temp_new(); 4864 4865 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4866 #ifdef MIPS_DEBUG_DISAS 4867 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4868 TARGET_FMT_lx "\n", ctx->base.pc_next); 4869 #endif 4870 gen_reserved_instruction(ctx); 4871 goto out; 4872 } 4873 4874 /* Load needed operands */ 4875 switch (opc) { 4876 case OPC_BEQ: 4877 case OPC_BEQL: 4878 case OPC_BNE: 4879 case OPC_BNEL: 4880 /* Compare two registers */ 4881 if (rs != rt) { 4882 gen_load_gpr(t0, rs); 4883 gen_load_gpr(t1, rt); 4884 bcond_compute = 1; 4885 } 4886 btgt = ctx->base.pc_next + insn_bytes + offset; 4887 break; 4888 case OPC_BGEZ: 4889 case OPC_BGEZAL: 4890 case OPC_BGEZALL: 4891 case OPC_BGEZL: 4892 case OPC_BGTZ: 4893 case OPC_BGTZL: 4894 case OPC_BLEZ: 4895 case OPC_BLEZL: 4896 case OPC_BLTZ: 4897 case OPC_BLTZAL: 4898 case OPC_BLTZALL: 4899 case OPC_BLTZL: 4900 /* Compare to zero */ 4901 if (rs != 0) { 4902 gen_load_gpr(t0, rs); 4903 bcond_compute = 1; 4904 } 4905 btgt = ctx->base.pc_next + insn_bytes + offset; 4906 break; 4907 case OPC_BPOSGE32: 4908 #if defined(TARGET_MIPS64) 4909 case OPC_BPOSGE64: 4910 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4911 #else 4912 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4913 #endif 4914 bcond_compute = 1; 4915 btgt = ctx->base.pc_next + insn_bytes + offset; 4916 break; 4917 case OPC_J: 4918 case OPC_JAL: 4919 case OPC_JALX: 4920 /* Jump to immediate */ 4921 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4922 (uint32_t)offset; 4923 break; 4924 case OPC_JR: 4925 case OPC_JALR: 4926 /* Jump to register */ 4927 if (offset != 0 && offset != 16) { 4928 /* 4929 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4930 * others are reserved. 4931 */ 4932 MIPS_INVAL("jump hint"); 4933 gen_reserved_instruction(ctx); 4934 goto out; 4935 } 4936 gen_load_gpr(btarget, rs); 4937 break; 4938 default: 4939 MIPS_INVAL("branch/jump"); 4940 gen_reserved_instruction(ctx); 4941 goto out; 4942 } 4943 if (bcond_compute == 0) { 4944 /* No condition to be computed */ 4945 switch (opc) { 4946 case OPC_BEQ: /* rx == rx */ 4947 case OPC_BEQL: /* rx == rx likely */ 4948 case OPC_BGEZ: /* 0 >= 0 */ 4949 case OPC_BGEZL: /* 0 >= 0 likely */ 4950 case OPC_BLEZ: /* 0 <= 0 */ 4951 case OPC_BLEZL: /* 0 <= 0 likely */ 4952 /* Always take */ 4953 ctx->hflags |= MIPS_HFLAG_B; 4954 break; 4955 case OPC_BGEZAL: /* 0 >= 0 */ 4956 case OPC_BGEZALL: /* 0 >= 0 likely */ 4957 /* Always take and link */ 4958 blink = 31; 4959 ctx->hflags |= MIPS_HFLAG_B; 4960 break; 4961 case OPC_BNE: /* rx != rx */ 4962 case OPC_BGTZ: /* 0 > 0 */ 4963 case OPC_BLTZ: /* 0 < 0 */ 4964 /* Treat as NOP. */ 4965 goto out; 4966 case OPC_BLTZAL: /* 0 < 0 */ 4967 /* 4968 * Handle as an unconditional branch to get correct delay 4969 * slot checking. 4970 */ 4971 blink = 31; 4972 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4973 ctx->hflags |= MIPS_HFLAG_B; 4974 break; 4975 case OPC_BLTZALL: /* 0 < 0 likely */ 4976 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4977 /* Skip the instruction in the delay slot */ 4978 ctx->base.pc_next += 4; 4979 goto out; 4980 case OPC_BNEL: /* rx != rx likely */ 4981 case OPC_BGTZL: /* 0 > 0 likely */ 4982 case OPC_BLTZL: /* 0 < 0 likely */ 4983 /* Skip the instruction in the delay slot */ 4984 ctx->base.pc_next += 4; 4985 goto out; 4986 case OPC_J: 4987 ctx->hflags |= MIPS_HFLAG_B; 4988 break; 4989 case OPC_JALX: 4990 ctx->hflags |= MIPS_HFLAG_BX; 4991 /* Fallthrough */ 4992 case OPC_JAL: 4993 blink = 31; 4994 ctx->hflags |= MIPS_HFLAG_B; 4995 break; 4996 case OPC_JR: 4997 ctx->hflags |= MIPS_HFLAG_BR; 4998 break; 4999 case OPC_JALR: 5000 blink = rt; 5001 ctx->hflags |= MIPS_HFLAG_BR; 5002 break; 5003 default: 5004 MIPS_INVAL("branch/jump"); 5005 gen_reserved_instruction(ctx); 5006 goto out; 5007 } 5008 } else { 5009 switch (opc) { 5010 case OPC_BEQ: 5011 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5012 goto not_likely; 5013 case OPC_BEQL: 5014 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5015 goto likely; 5016 case OPC_BNE: 5017 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5018 goto not_likely; 5019 case OPC_BNEL: 5020 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5021 goto likely; 5022 case OPC_BGEZ: 5023 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5024 goto not_likely; 5025 case OPC_BGEZL: 5026 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5027 goto likely; 5028 case OPC_BGEZAL: 5029 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5030 blink = 31; 5031 goto not_likely; 5032 case OPC_BGEZALL: 5033 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5034 blink = 31; 5035 goto likely; 5036 case OPC_BGTZ: 5037 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5038 goto not_likely; 5039 case OPC_BGTZL: 5040 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5041 goto likely; 5042 case OPC_BLEZ: 5043 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5044 goto not_likely; 5045 case OPC_BLEZL: 5046 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5047 goto likely; 5048 case OPC_BLTZ: 5049 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5050 goto not_likely; 5051 case OPC_BLTZL: 5052 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5053 goto likely; 5054 case OPC_BPOSGE32: 5055 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5056 goto not_likely; 5057 #if defined(TARGET_MIPS64) 5058 case OPC_BPOSGE64: 5059 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5060 goto not_likely; 5061 #endif 5062 case OPC_BLTZAL: 5063 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5064 blink = 31; 5065 not_likely: 5066 ctx->hflags |= MIPS_HFLAG_BC; 5067 break; 5068 case OPC_BLTZALL: 5069 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5070 blink = 31; 5071 likely: 5072 ctx->hflags |= MIPS_HFLAG_BL; 5073 break; 5074 default: 5075 MIPS_INVAL("conditional branch/jump"); 5076 gen_reserved_instruction(ctx); 5077 goto out; 5078 } 5079 } 5080 5081 ctx->btarget = btgt; 5082 5083 switch (delayslot_size) { 5084 case 2: 5085 ctx->hflags |= MIPS_HFLAG_BDS16; 5086 break; 5087 case 4: 5088 ctx->hflags |= MIPS_HFLAG_BDS32; 5089 break; 5090 } 5091 5092 if (blink > 0) { 5093 int post_delay = insn_bytes + delayslot_size; 5094 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5095 5096 tcg_gen_movi_tl(cpu_gpr[blink], 5097 ctx->base.pc_next + post_delay + lowbit); 5098 } 5099 5100 out: 5101 if (insn_bytes == 2) { 5102 ctx->hflags |= MIPS_HFLAG_B16; 5103 } 5104 tcg_temp_free(t0); 5105 tcg_temp_free(t1); 5106 } 5107 5108 5109 /* special3 bitfield operations */ 5110 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5111 int rs, int lsb, int msb) 5112 { 5113 TCGv t0 = tcg_temp_new(); 5114 TCGv t1 = tcg_temp_new(); 5115 5116 gen_load_gpr(t1, rs); 5117 switch (opc) { 5118 case OPC_EXT: 5119 if (lsb + msb > 31) { 5120 goto fail; 5121 } 5122 if (msb != 31) { 5123 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5124 } else { 5125 /* 5126 * The two checks together imply that lsb == 0, 5127 * so this is a simple sign-extension. 5128 */ 5129 tcg_gen_ext32s_tl(t0, t1); 5130 } 5131 break; 5132 #if defined(TARGET_MIPS64) 5133 case OPC_DEXTU: 5134 lsb += 32; 5135 goto do_dext; 5136 case OPC_DEXTM: 5137 msb += 32; 5138 goto do_dext; 5139 case OPC_DEXT: 5140 do_dext: 5141 if (lsb + msb > 63) { 5142 goto fail; 5143 } 5144 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5145 break; 5146 #endif 5147 case OPC_INS: 5148 if (lsb > msb) { 5149 goto fail; 5150 } 5151 gen_load_gpr(t0, rt); 5152 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5153 tcg_gen_ext32s_tl(t0, t0); 5154 break; 5155 #if defined(TARGET_MIPS64) 5156 case OPC_DINSU: 5157 lsb += 32; 5158 /* FALLTHRU */ 5159 case OPC_DINSM: 5160 msb += 32; 5161 /* FALLTHRU */ 5162 case OPC_DINS: 5163 if (lsb > msb) { 5164 goto fail; 5165 } 5166 gen_load_gpr(t0, rt); 5167 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5168 break; 5169 #endif 5170 default: 5171 fail: 5172 MIPS_INVAL("bitops"); 5173 gen_reserved_instruction(ctx); 5174 tcg_temp_free(t0); 5175 tcg_temp_free(t1); 5176 return; 5177 } 5178 gen_store_gpr(t0, rt); 5179 tcg_temp_free(t0); 5180 tcg_temp_free(t1); 5181 } 5182 5183 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5184 { 5185 TCGv t0; 5186 5187 if (rd == 0) { 5188 /* If no destination, treat it as a NOP. */ 5189 return; 5190 } 5191 5192 t0 = tcg_temp_new(); 5193 gen_load_gpr(t0, rt); 5194 switch (op2) { 5195 case OPC_WSBH: 5196 { 5197 TCGv t1 = tcg_temp_new(); 5198 TCGv t2 = tcg_const_tl(0x00FF00FF); 5199 5200 tcg_gen_shri_tl(t1, t0, 8); 5201 tcg_gen_and_tl(t1, t1, t2); 5202 tcg_gen_and_tl(t0, t0, t2); 5203 tcg_gen_shli_tl(t0, t0, 8); 5204 tcg_gen_or_tl(t0, t0, t1); 5205 tcg_temp_free(t2); 5206 tcg_temp_free(t1); 5207 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5208 } 5209 break; 5210 case OPC_SEB: 5211 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5212 break; 5213 case OPC_SEH: 5214 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5215 break; 5216 #if defined(TARGET_MIPS64) 5217 case OPC_DSBH: 5218 { 5219 TCGv t1 = tcg_temp_new(); 5220 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5221 5222 tcg_gen_shri_tl(t1, t0, 8); 5223 tcg_gen_and_tl(t1, t1, t2); 5224 tcg_gen_and_tl(t0, t0, t2); 5225 tcg_gen_shli_tl(t0, t0, 8); 5226 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5227 tcg_temp_free(t2); 5228 tcg_temp_free(t1); 5229 } 5230 break; 5231 case OPC_DSHD: 5232 { 5233 TCGv t1 = tcg_temp_new(); 5234 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5235 5236 tcg_gen_shri_tl(t1, t0, 16); 5237 tcg_gen_and_tl(t1, t1, t2); 5238 tcg_gen_and_tl(t0, t0, t2); 5239 tcg_gen_shli_tl(t0, t0, 16); 5240 tcg_gen_or_tl(t0, t0, t1); 5241 tcg_gen_shri_tl(t1, t0, 32); 5242 tcg_gen_shli_tl(t0, t0, 32); 5243 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5244 tcg_temp_free(t2); 5245 tcg_temp_free(t1); 5246 } 5247 break; 5248 #endif 5249 default: 5250 MIPS_INVAL("bsfhl"); 5251 gen_reserved_instruction(ctx); 5252 tcg_temp_free(t0); 5253 return; 5254 } 5255 tcg_temp_free(t0); 5256 } 5257 5258 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5259 int rt, int bits) 5260 { 5261 TCGv t0; 5262 if (rd == 0) { 5263 /* Treat as NOP. */ 5264 return; 5265 } 5266 t0 = tcg_temp_new(); 5267 if (bits == 0 || bits == wordsz) { 5268 if (bits == 0) { 5269 gen_load_gpr(t0, rt); 5270 } else { 5271 gen_load_gpr(t0, rs); 5272 } 5273 switch (wordsz) { 5274 case 32: 5275 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5276 break; 5277 #if defined(TARGET_MIPS64) 5278 case 64: 5279 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5280 break; 5281 #endif 5282 } 5283 } else { 5284 TCGv t1 = tcg_temp_new(); 5285 gen_load_gpr(t0, rt); 5286 gen_load_gpr(t1, rs); 5287 switch (wordsz) { 5288 case 32: 5289 { 5290 TCGv_i64 t2 = tcg_temp_new_i64(); 5291 tcg_gen_concat_tl_i64(t2, t1, t0); 5292 tcg_gen_shri_i64(t2, t2, 32 - bits); 5293 gen_move_low32(cpu_gpr[rd], t2); 5294 tcg_temp_free_i64(t2); 5295 } 5296 break; 5297 #if defined(TARGET_MIPS64) 5298 case 64: 5299 tcg_gen_shli_tl(t0, t0, bits); 5300 tcg_gen_shri_tl(t1, t1, 64 - bits); 5301 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5302 break; 5303 #endif 5304 } 5305 tcg_temp_free(t1); 5306 } 5307 5308 tcg_temp_free(t0); 5309 } 5310 5311 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5312 { 5313 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5314 } 5315 5316 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5317 { 5318 TCGv t0; 5319 if (rd == 0) { 5320 /* Treat as NOP. */ 5321 return; 5322 } 5323 t0 = tcg_temp_new(); 5324 gen_load_gpr(t0, rt); 5325 switch (opc) { 5326 case OPC_BITSWAP: 5327 gen_helper_bitswap(cpu_gpr[rd], t0); 5328 break; 5329 #if defined(TARGET_MIPS64) 5330 case OPC_DBITSWAP: 5331 gen_helper_dbitswap(cpu_gpr[rd], t0); 5332 break; 5333 #endif 5334 } 5335 tcg_temp_free(t0); 5336 } 5337 5338 #ifndef CONFIG_USER_ONLY 5339 /* CP0 (MMU and control) */ 5340 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5341 { 5342 TCGv_i64 t0 = tcg_temp_new_i64(); 5343 TCGv_i64 t1 = tcg_temp_new_i64(); 5344 5345 tcg_gen_ext_tl_i64(t0, arg); 5346 tcg_gen_ld_i64(t1, cpu_env, off); 5347 #if defined(TARGET_MIPS64) 5348 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5349 #else 5350 tcg_gen_concat32_i64(t1, t1, t0); 5351 #endif 5352 tcg_gen_st_i64(t1, cpu_env, off); 5353 tcg_temp_free_i64(t1); 5354 tcg_temp_free_i64(t0); 5355 } 5356 5357 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5358 { 5359 TCGv_i64 t0 = tcg_temp_new_i64(); 5360 TCGv_i64 t1 = tcg_temp_new_i64(); 5361 5362 tcg_gen_ext_tl_i64(t0, arg); 5363 tcg_gen_ld_i64(t1, cpu_env, off); 5364 tcg_gen_concat32_i64(t1, t1, t0); 5365 tcg_gen_st_i64(t1, cpu_env, off); 5366 tcg_temp_free_i64(t1); 5367 tcg_temp_free_i64(t0); 5368 } 5369 5370 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5371 { 5372 TCGv_i64 t0 = tcg_temp_new_i64(); 5373 5374 tcg_gen_ld_i64(t0, cpu_env, off); 5375 #if defined(TARGET_MIPS64) 5376 tcg_gen_shri_i64(t0, t0, 30); 5377 #else 5378 tcg_gen_shri_i64(t0, t0, 32); 5379 #endif 5380 gen_move_low32(arg, t0); 5381 tcg_temp_free_i64(t0); 5382 } 5383 5384 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5385 { 5386 TCGv_i64 t0 = tcg_temp_new_i64(); 5387 5388 tcg_gen_ld_i64(t0, cpu_env, off); 5389 tcg_gen_shri_i64(t0, t0, 32 + shift); 5390 gen_move_low32(arg, t0); 5391 tcg_temp_free_i64(t0); 5392 } 5393 5394 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5395 { 5396 TCGv_i32 t0 = tcg_temp_new_i32(); 5397 5398 tcg_gen_ld_i32(t0, cpu_env, off); 5399 tcg_gen_ext_i32_tl(arg, t0); 5400 tcg_temp_free_i32(t0); 5401 } 5402 5403 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5404 { 5405 tcg_gen_ld_tl(arg, cpu_env, off); 5406 tcg_gen_ext32s_tl(arg, arg); 5407 } 5408 5409 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5410 { 5411 TCGv_i32 t0 = tcg_temp_new_i32(); 5412 5413 tcg_gen_trunc_tl_i32(t0, arg); 5414 tcg_gen_st_i32(t0, cpu_env, off); 5415 tcg_temp_free_i32(t0); 5416 } 5417 5418 #define CP0_CHECK(c) \ 5419 do { \ 5420 if (!(c)) { \ 5421 goto cp0_unimplemented; \ 5422 } \ 5423 } while (0) 5424 5425 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5426 { 5427 const char *register_name = "invalid"; 5428 5429 switch (reg) { 5430 case CP0_REGISTER_02: 5431 switch (sel) { 5432 case 0: 5433 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5434 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5435 register_name = "EntryLo0"; 5436 break; 5437 default: 5438 goto cp0_unimplemented; 5439 } 5440 break; 5441 case CP0_REGISTER_03: 5442 switch (sel) { 5443 case CP0_REG03__ENTRYLO1: 5444 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5445 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5446 register_name = "EntryLo1"; 5447 break; 5448 default: 5449 goto cp0_unimplemented; 5450 } 5451 break; 5452 case CP0_REGISTER_09: 5453 switch (sel) { 5454 case CP0_REG09__SAAR: 5455 CP0_CHECK(ctx->saar); 5456 gen_helper_mfhc0_saar(arg, cpu_env); 5457 register_name = "SAAR"; 5458 break; 5459 default: 5460 goto cp0_unimplemented; 5461 } 5462 break; 5463 case CP0_REGISTER_17: 5464 switch (sel) { 5465 case CP0_REG17__LLADDR: 5466 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5467 ctx->CP0_LLAddr_shift); 5468 register_name = "LLAddr"; 5469 break; 5470 case CP0_REG17__MAAR: 5471 CP0_CHECK(ctx->mrp); 5472 gen_helper_mfhc0_maar(arg, cpu_env); 5473 register_name = "MAAR"; 5474 break; 5475 default: 5476 goto cp0_unimplemented; 5477 } 5478 break; 5479 case CP0_REGISTER_19: 5480 switch (sel) { 5481 case CP0_REG19__WATCHHI0: 5482 case CP0_REG19__WATCHHI1: 5483 case CP0_REG19__WATCHHI2: 5484 case CP0_REG19__WATCHHI3: 5485 case CP0_REG19__WATCHHI4: 5486 case CP0_REG19__WATCHHI5: 5487 case CP0_REG19__WATCHHI6: 5488 case CP0_REG19__WATCHHI7: 5489 /* upper 32 bits are only available when Config5MI != 0 */ 5490 CP0_CHECK(ctx->mi); 5491 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5492 register_name = "WatchHi"; 5493 break; 5494 default: 5495 goto cp0_unimplemented; 5496 } 5497 break; 5498 case CP0_REGISTER_28: 5499 switch (sel) { 5500 case 0: 5501 case 2: 5502 case 4: 5503 case 6: 5504 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5505 register_name = "TagLo"; 5506 break; 5507 default: 5508 goto cp0_unimplemented; 5509 } 5510 break; 5511 default: 5512 goto cp0_unimplemented; 5513 } 5514 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5515 return; 5516 5517 cp0_unimplemented: 5518 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5519 register_name, reg, sel); 5520 tcg_gen_movi_tl(arg, 0); 5521 } 5522 5523 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5524 { 5525 const char *register_name = "invalid"; 5526 uint64_t mask = ctx->PAMask >> 36; 5527 5528 switch (reg) { 5529 case CP0_REGISTER_02: 5530 switch (sel) { 5531 case 0: 5532 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5533 tcg_gen_andi_tl(arg, arg, mask); 5534 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5535 register_name = "EntryLo0"; 5536 break; 5537 default: 5538 goto cp0_unimplemented; 5539 } 5540 break; 5541 case CP0_REGISTER_03: 5542 switch (sel) { 5543 case CP0_REG03__ENTRYLO1: 5544 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5545 tcg_gen_andi_tl(arg, arg, mask); 5546 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5547 register_name = "EntryLo1"; 5548 break; 5549 default: 5550 goto cp0_unimplemented; 5551 } 5552 break; 5553 case CP0_REGISTER_09: 5554 switch (sel) { 5555 case CP0_REG09__SAAR: 5556 CP0_CHECK(ctx->saar); 5557 gen_helper_mthc0_saar(cpu_env, arg); 5558 register_name = "SAAR"; 5559 break; 5560 default: 5561 goto cp0_unimplemented; 5562 } 5563 break; 5564 case CP0_REGISTER_17: 5565 switch (sel) { 5566 case CP0_REG17__LLADDR: 5567 /* 5568 * LLAddr is read-only (the only exception is bit 0 if LLB is 5569 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5570 * relevant for modern MIPS cores supporting MTHC0, therefore 5571 * treating MTHC0 to LLAddr as NOP. 5572 */ 5573 register_name = "LLAddr"; 5574 break; 5575 case CP0_REG17__MAAR: 5576 CP0_CHECK(ctx->mrp); 5577 gen_helper_mthc0_maar(cpu_env, arg); 5578 register_name = "MAAR"; 5579 break; 5580 default: 5581 goto cp0_unimplemented; 5582 } 5583 break; 5584 case CP0_REGISTER_19: 5585 switch (sel) { 5586 case CP0_REG19__WATCHHI0: 5587 case CP0_REG19__WATCHHI1: 5588 case CP0_REG19__WATCHHI2: 5589 case CP0_REG19__WATCHHI3: 5590 case CP0_REG19__WATCHHI4: 5591 case CP0_REG19__WATCHHI5: 5592 case CP0_REG19__WATCHHI6: 5593 case CP0_REG19__WATCHHI7: 5594 /* upper 32 bits are only available when Config5MI != 0 */ 5595 CP0_CHECK(ctx->mi); 5596 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5597 register_name = "WatchHi"; 5598 break; 5599 default: 5600 goto cp0_unimplemented; 5601 } 5602 break; 5603 case CP0_REGISTER_28: 5604 switch (sel) { 5605 case 0: 5606 case 2: 5607 case 4: 5608 case 6: 5609 tcg_gen_andi_tl(arg, arg, mask); 5610 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5611 register_name = "TagLo"; 5612 break; 5613 default: 5614 goto cp0_unimplemented; 5615 } 5616 break; 5617 default: 5618 goto cp0_unimplemented; 5619 } 5620 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5621 return; 5622 5623 cp0_unimplemented: 5624 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5625 register_name, reg, sel); 5626 } 5627 5628 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5629 { 5630 if (ctx->insn_flags & ISA_MIPS_R6) { 5631 tcg_gen_movi_tl(arg, 0); 5632 } else { 5633 tcg_gen_movi_tl(arg, ~0); 5634 } 5635 } 5636 5637 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5638 { 5639 const char *register_name = "invalid"; 5640 5641 if (sel != 0) { 5642 check_insn(ctx, ISA_MIPS_R1); 5643 } 5644 5645 switch (reg) { 5646 case CP0_REGISTER_00: 5647 switch (sel) { 5648 case CP0_REG00__INDEX: 5649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5650 register_name = "Index"; 5651 break; 5652 case CP0_REG00__MVPCONTROL: 5653 CP0_CHECK(ctx->insn_flags & ASE_MT); 5654 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5655 register_name = "MVPControl"; 5656 break; 5657 case CP0_REG00__MVPCONF0: 5658 CP0_CHECK(ctx->insn_flags & ASE_MT); 5659 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5660 register_name = "MVPConf0"; 5661 break; 5662 case CP0_REG00__MVPCONF1: 5663 CP0_CHECK(ctx->insn_flags & ASE_MT); 5664 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5665 register_name = "MVPConf1"; 5666 break; 5667 case CP0_REG00__VPCONTROL: 5668 CP0_CHECK(ctx->vp); 5669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5670 register_name = "VPControl"; 5671 break; 5672 default: 5673 goto cp0_unimplemented; 5674 } 5675 break; 5676 case CP0_REGISTER_01: 5677 switch (sel) { 5678 case CP0_REG01__RANDOM: 5679 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5680 gen_helper_mfc0_random(arg, cpu_env); 5681 register_name = "Random"; 5682 break; 5683 case CP0_REG01__VPECONTROL: 5684 CP0_CHECK(ctx->insn_flags & ASE_MT); 5685 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5686 register_name = "VPEControl"; 5687 break; 5688 case CP0_REG01__VPECONF0: 5689 CP0_CHECK(ctx->insn_flags & ASE_MT); 5690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5691 register_name = "VPEConf0"; 5692 break; 5693 case CP0_REG01__VPECONF1: 5694 CP0_CHECK(ctx->insn_flags & ASE_MT); 5695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5696 register_name = "VPEConf1"; 5697 break; 5698 case CP0_REG01__YQMASK: 5699 CP0_CHECK(ctx->insn_flags & ASE_MT); 5700 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5701 register_name = "YQMask"; 5702 break; 5703 case CP0_REG01__VPESCHEDULE: 5704 CP0_CHECK(ctx->insn_flags & ASE_MT); 5705 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5706 register_name = "VPESchedule"; 5707 break; 5708 case CP0_REG01__VPESCHEFBACK: 5709 CP0_CHECK(ctx->insn_flags & ASE_MT); 5710 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5711 register_name = "VPEScheFBack"; 5712 break; 5713 case CP0_REG01__VPEOPT: 5714 CP0_CHECK(ctx->insn_flags & ASE_MT); 5715 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5716 register_name = "VPEOpt"; 5717 break; 5718 default: 5719 goto cp0_unimplemented; 5720 } 5721 break; 5722 case CP0_REGISTER_02: 5723 switch (sel) { 5724 case CP0_REG02__ENTRYLO0: 5725 { 5726 TCGv_i64 tmp = tcg_temp_new_i64(); 5727 tcg_gen_ld_i64(tmp, cpu_env, 5728 offsetof(CPUMIPSState, CP0_EntryLo0)); 5729 #if defined(TARGET_MIPS64) 5730 if (ctx->rxi) { 5731 /* Move RI/XI fields to bits 31:30 */ 5732 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5733 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5734 } 5735 #endif 5736 gen_move_low32(arg, tmp); 5737 tcg_temp_free_i64(tmp); 5738 } 5739 register_name = "EntryLo0"; 5740 break; 5741 case CP0_REG02__TCSTATUS: 5742 CP0_CHECK(ctx->insn_flags & ASE_MT); 5743 gen_helper_mfc0_tcstatus(arg, cpu_env); 5744 register_name = "TCStatus"; 5745 break; 5746 case CP0_REG02__TCBIND: 5747 CP0_CHECK(ctx->insn_flags & ASE_MT); 5748 gen_helper_mfc0_tcbind(arg, cpu_env); 5749 register_name = "TCBind"; 5750 break; 5751 case CP0_REG02__TCRESTART: 5752 CP0_CHECK(ctx->insn_flags & ASE_MT); 5753 gen_helper_mfc0_tcrestart(arg, cpu_env); 5754 register_name = "TCRestart"; 5755 break; 5756 case CP0_REG02__TCHALT: 5757 CP0_CHECK(ctx->insn_flags & ASE_MT); 5758 gen_helper_mfc0_tchalt(arg, cpu_env); 5759 register_name = "TCHalt"; 5760 break; 5761 case CP0_REG02__TCCONTEXT: 5762 CP0_CHECK(ctx->insn_flags & ASE_MT); 5763 gen_helper_mfc0_tccontext(arg, cpu_env); 5764 register_name = "TCContext"; 5765 break; 5766 case CP0_REG02__TCSCHEDULE: 5767 CP0_CHECK(ctx->insn_flags & ASE_MT); 5768 gen_helper_mfc0_tcschedule(arg, cpu_env); 5769 register_name = "TCSchedule"; 5770 break; 5771 case CP0_REG02__TCSCHEFBACK: 5772 CP0_CHECK(ctx->insn_flags & ASE_MT); 5773 gen_helper_mfc0_tcschefback(arg, cpu_env); 5774 register_name = "TCScheFBack"; 5775 break; 5776 default: 5777 goto cp0_unimplemented; 5778 } 5779 break; 5780 case CP0_REGISTER_03: 5781 switch (sel) { 5782 case CP0_REG03__ENTRYLO1: 5783 { 5784 TCGv_i64 tmp = tcg_temp_new_i64(); 5785 tcg_gen_ld_i64(tmp, cpu_env, 5786 offsetof(CPUMIPSState, CP0_EntryLo1)); 5787 #if defined(TARGET_MIPS64) 5788 if (ctx->rxi) { 5789 /* Move RI/XI fields to bits 31:30 */ 5790 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5791 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5792 } 5793 #endif 5794 gen_move_low32(arg, tmp); 5795 tcg_temp_free_i64(tmp); 5796 } 5797 register_name = "EntryLo1"; 5798 break; 5799 case CP0_REG03__GLOBALNUM: 5800 CP0_CHECK(ctx->vp); 5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5802 register_name = "GlobalNumber"; 5803 break; 5804 default: 5805 goto cp0_unimplemented; 5806 } 5807 break; 5808 case CP0_REGISTER_04: 5809 switch (sel) { 5810 case CP0_REG04__CONTEXT: 5811 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5812 tcg_gen_ext32s_tl(arg, arg); 5813 register_name = "Context"; 5814 break; 5815 case CP0_REG04__CONTEXTCONFIG: 5816 /* SmartMIPS ASE */ 5817 /* gen_helper_mfc0_contextconfig(arg); */ 5818 register_name = "ContextConfig"; 5819 goto cp0_unimplemented; 5820 case CP0_REG04__USERLOCAL: 5821 CP0_CHECK(ctx->ulri); 5822 tcg_gen_ld_tl(arg, cpu_env, 5823 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5824 tcg_gen_ext32s_tl(arg, arg); 5825 register_name = "UserLocal"; 5826 break; 5827 case CP0_REG04__MMID: 5828 CP0_CHECK(ctx->mi); 5829 gen_helper_mtc0_memorymapid(cpu_env, arg); 5830 register_name = "MMID"; 5831 break; 5832 default: 5833 goto cp0_unimplemented; 5834 } 5835 break; 5836 case CP0_REGISTER_05: 5837 switch (sel) { 5838 case CP0_REG05__PAGEMASK: 5839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5840 register_name = "PageMask"; 5841 break; 5842 case CP0_REG05__PAGEGRAIN: 5843 check_insn(ctx, ISA_MIPS_R2); 5844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5845 register_name = "PageGrain"; 5846 break; 5847 case CP0_REG05__SEGCTL0: 5848 CP0_CHECK(ctx->sc); 5849 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5850 tcg_gen_ext32s_tl(arg, arg); 5851 register_name = "SegCtl0"; 5852 break; 5853 case CP0_REG05__SEGCTL1: 5854 CP0_CHECK(ctx->sc); 5855 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5856 tcg_gen_ext32s_tl(arg, arg); 5857 register_name = "SegCtl1"; 5858 break; 5859 case CP0_REG05__SEGCTL2: 5860 CP0_CHECK(ctx->sc); 5861 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5862 tcg_gen_ext32s_tl(arg, arg); 5863 register_name = "SegCtl2"; 5864 break; 5865 case CP0_REG05__PWBASE: 5866 check_pw(ctx); 5867 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5868 register_name = "PWBase"; 5869 break; 5870 case CP0_REG05__PWFIELD: 5871 check_pw(ctx); 5872 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5873 register_name = "PWField"; 5874 break; 5875 case CP0_REG05__PWSIZE: 5876 check_pw(ctx); 5877 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5878 register_name = "PWSize"; 5879 break; 5880 default: 5881 goto cp0_unimplemented; 5882 } 5883 break; 5884 case CP0_REGISTER_06: 5885 switch (sel) { 5886 case CP0_REG06__WIRED: 5887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5888 register_name = "Wired"; 5889 break; 5890 case CP0_REG06__SRSCONF0: 5891 check_insn(ctx, ISA_MIPS_R2); 5892 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5893 register_name = "SRSConf0"; 5894 break; 5895 case CP0_REG06__SRSCONF1: 5896 check_insn(ctx, ISA_MIPS_R2); 5897 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5898 register_name = "SRSConf1"; 5899 break; 5900 case CP0_REG06__SRSCONF2: 5901 check_insn(ctx, ISA_MIPS_R2); 5902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5903 register_name = "SRSConf2"; 5904 break; 5905 case CP0_REG06__SRSCONF3: 5906 check_insn(ctx, ISA_MIPS_R2); 5907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5908 register_name = "SRSConf3"; 5909 break; 5910 case CP0_REG06__SRSCONF4: 5911 check_insn(ctx, ISA_MIPS_R2); 5912 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5913 register_name = "SRSConf4"; 5914 break; 5915 case CP0_REG06__PWCTL: 5916 check_pw(ctx); 5917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5918 register_name = "PWCtl"; 5919 break; 5920 default: 5921 goto cp0_unimplemented; 5922 } 5923 break; 5924 case CP0_REGISTER_07: 5925 switch (sel) { 5926 case CP0_REG07__HWRENA: 5927 check_insn(ctx, ISA_MIPS_R2); 5928 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5929 register_name = "HWREna"; 5930 break; 5931 default: 5932 goto cp0_unimplemented; 5933 } 5934 break; 5935 case CP0_REGISTER_08: 5936 switch (sel) { 5937 case CP0_REG08__BADVADDR: 5938 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5939 tcg_gen_ext32s_tl(arg, arg); 5940 register_name = "BadVAddr"; 5941 break; 5942 case CP0_REG08__BADINSTR: 5943 CP0_CHECK(ctx->bi); 5944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5945 register_name = "BadInstr"; 5946 break; 5947 case CP0_REG08__BADINSTRP: 5948 CP0_CHECK(ctx->bp); 5949 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5950 register_name = "BadInstrP"; 5951 break; 5952 case CP0_REG08__BADINSTRX: 5953 CP0_CHECK(ctx->bi); 5954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5955 tcg_gen_andi_tl(arg, arg, ~0xffff); 5956 register_name = "BadInstrX"; 5957 break; 5958 default: 5959 goto cp0_unimplemented; 5960 } 5961 break; 5962 case CP0_REGISTER_09: 5963 switch (sel) { 5964 case CP0_REG09__COUNT: 5965 /* Mark as an IO operation because we read the time. */ 5966 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 5967 gen_io_start(); 5968 } 5969 gen_helper_mfc0_count(arg, cpu_env); 5970 /* 5971 * Break the TB to be able to take timer interrupts immediately 5972 * after reading count. DISAS_STOP isn't sufficient, we need to 5973 * ensure we break completely out of translated code. 5974 */ 5975 gen_save_pc(ctx->base.pc_next + 4); 5976 ctx->base.is_jmp = DISAS_EXIT; 5977 register_name = "Count"; 5978 break; 5979 case CP0_REG09__SAARI: 5980 CP0_CHECK(ctx->saar); 5981 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 5982 register_name = "SAARI"; 5983 break; 5984 case CP0_REG09__SAAR: 5985 CP0_CHECK(ctx->saar); 5986 gen_helper_mfc0_saar(arg, cpu_env); 5987 register_name = "SAAR"; 5988 break; 5989 default: 5990 goto cp0_unimplemented; 5991 } 5992 break; 5993 case CP0_REGISTER_10: 5994 switch (sel) { 5995 case CP0_REG10__ENTRYHI: 5996 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5997 tcg_gen_ext32s_tl(arg, arg); 5998 register_name = "EntryHi"; 5999 break; 6000 default: 6001 goto cp0_unimplemented; 6002 } 6003 break; 6004 case CP0_REGISTER_11: 6005 switch (sel) { 6006 case CP0_REG11__COMPARE: 6007 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6008 register_name = "Compare"; 6009 break; 6010 /* 6,7 are implementation dependent */ 6011 default: 6012 goto cp0_unimplemented; 6013 } 6014 break; 6015 case CP0_REGISTER_12: 6016 switch (sel) { 6017 case CP0_REG12__STATUS: 6018 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6019 register_name = "Status"; 6020 break; 6021 case CP0_REG12__INTCTL: 6022 check_insn(ctx, ISA_MIPS_R2); 6023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6024 register_name = "IntCtl"; 6025 break; 6026 case CP0_REG12__SRSCTL: 6027 check_insn(ctx, ISA_MIPS_R2); 6028 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6029 register_name = "SRSCtl"; 6030 break; 6031 case CP0_REG12__SRSMAP: 6032 check_insn(ctx, ISA_MIPS_R2); 6033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6034 register_name = "SRSMap"; 6035 break; 6036 default: 6037 goto cp0_unimplemented; 6038 } 6039 break; 6040 case CP0_REGISTER_13: 6041 switch (sel) { 6042 case CP0_REG13__CAUSE: 6043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6044 register_name = "Cause"; 6045 break; 6046 default: 6047 goto cp0_unimplemented; 6048 } 6049 break; 6050 case CP0_REGISTER_14: 6051 switch (sel) { 6052 case CP0_REG14__EPC: 6053 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6054 tcg_gen_ext32s_tl(arg, arg); 6055 register_name = "EPC"; 6056 break; 6057 default: 6058 goto cp0_unimplemented; 6059 } 6060 break; 6061 case CP0_REGISTER_15: 6062 switch (sel) { 6063 case CP0_REG15__PRID: 6064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6065 register_name = "PRid"; 6066 break; 6067 case CP0_REG15__EBASE: 6068 check_insn(ctx, ISA_MIPS_R2); 6069 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6070 tcg_gen_ext32s_tl(arg, arg); 6071 register_name = "EBase"; 6072 break; 6073 case CP0_REG15__CMGCRBASE: 6074 check_insn(ctx, ISA_MIPS_R2); 6075 CP0_CHECK(ctx->cmgcr); 6076 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6077 tcg_gen_ext32s_tl(arg, arg); 6078 register_name = "CMGCRBase"; 6079 break; 6080 default: 6081 goto cp0_unimplemented; 6082 } 6083 break; 6084 case CP0_REGISTER_16: 6085 switch (sel) { 6086 case CP0_REG16__CONFIG: 6087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6088 register_name = "Config"; 6089 break; 6090 case CP0_REG16__CONFIG1: 6091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6092 register_name = "Config1"; 6093 break; 6094 case CP0_REG16__CONFIG2: 6095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6096 register_name = "Config2"; 6097 break; 6098 case CP0_REG16__CONFIG3: 6099 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6100 register_name = "Config3"; 6101 break; 6102 case CP0_REG16__CONFIG4: 6103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6104 register_name = "Config4"; 6105 break; 6106 case CP0_REG16__CONFIG5: 6107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6108 register_name = "Config5"; 6109 break; 6110 /* 6,7 are implementation dependent */ 6111 case CP0_REG16__CONFIG6: 6112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6113 register_name = "Config6"; 6114 break; 6115 case CP0_REG16__CONFIG7: 6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6117 register_name = "Config7"; 6118 break; 6119 default: 6120 goto cp0_unimplemented; 6121 } 6122 break; 6123 case CP0_REGISTER_17: 6124 switch (sel) { 6125 case CP0_REG17__LLADDR: 6126 gen_helper_mfc0_lladdr(arg, cpu_env); 6127 register_name = "LLAddr"; 6128 break; 6129 case CP0_REG17__MAAR: 6130 CP0_CHECK(ctx->mrp); 6131 gen_helper_mfc0_maar(arg, cpu_env); 6132 register_name = "MAAR"; 6133 break; 6134 case CP0_REG17__MAARI: 6135 CP0_CHECK(ctx->mrp); 6136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6137 register_name = "MAARI"; 6138 break; 6139 default: 6140 goto cp0_unimplemented; 6141 } 6142 break; 6143 case CP0_REGISTER_18: 6144 switch (sel) { 6145 case CP0_REG18__WATCHLO0: 6146 case CP0_REG18__WATCHLO1: 6147 case CP0_REG18__WATCHLO2: 6148 case CP0_REG18__WATCHLO3: 6149 case CP0_REG18__WATCHLO4: 6150 case CP0_REG18__WATCHLO5: 6151 case CP0_REG18__WATCHLO6: 6152 case CP0_REG18__WATCHLO7: 6153 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6154 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6155 register_name = "WatchLo"; 6156 break; 6157 default: 6158 goto cp0_unimplemented; 6159 } 6160 break; 6161 case CP0_REGISTER_19: 6162 switch (sel) { 6163 case CP0_REG19__WATCHHI0: 6164 case CP0_REG19__WATCHHI1: 6165 case CP0_REG19__WATCHHI2: 6166 case CP0_REG19__WATCHHI3: 6167 case CP0_REG19__WATCHHI4: 6168 case CP0_REG19__WATCHHI5: 6169 case CP0_REG19__WATCHHI6: 6170 case CP0_REG19__WATCHHI7: 6171 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6172 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6173 register_name = "WatchHi"; 6174 break; 6175 default: 6176 goto cp0_unimplemented; 6177 } 6178 break; 6179 case CP0_REGISTER_20: 6180 switch (sel) { 6181 case CP0_REG20__XCONTEXT: 6182 #if defined(TARGET_MIPS64) 6183 check_insn(ctx, ISA_MIPS3); 6184 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6185 tcg_gen_ext32s_tl(arg, arg); 6186 register_name = "XContext"; 6187 break; 6188 #endif 6189 default: 6190 goto cp0_unimplemented; 6191 } 6192 break; 6193 case CP0_REGISTER_21: 6194 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6195 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6196 switch (sel) { 6197 case 0: 6198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6199 register_name = "Framemask"; 6200 break; 6201 default: 6202 goto cp0_unimplemented; 6203 } 6204 break; 6205 case CP0_REGISTER_22: 6206 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6207 register_name = "'Diagnostic"; /* implementation dependent */ 6208 break; 6209 case CP0_REGISTER_23: 6210 switch (sel) { 6211 case CP0_REG23__DEBUG: 6212 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6213 register_name = "Debug"; 6214 break; 6215 case CP0_REG23__TRACECONTROL: 6216 /* PDtrace support */ 6217 /* gen_helper_mfc0_tracecontrol(arg); */ 6218 register_name = "TraceControl"; 6219 goto cp0_unimplemented; 6220 case CP0_REG23__TRACECONTROL2: 6221 /* PDtrace support */ 6222 /* gen_helper_mfc0_tracecontrol2(arg); */ 6223 register_name = "TraceControl2"; 6224 goto cp0_unimplemented; 6225 case CP0_REG23__USERTRACEDATA1: 6226 /* PDtrace support */ 6227 /* gen_helper_mfc0_usertracedata1(arg);*/ 6228 register_name = "UserTraceData1"; 6229 goto cp0_unimplemented; 6230 case CP0_REG23__TRACEIBPC: 6231 /* PDtrace support */ 6232 /* gen_helper_mfc0_traceibpc(arg); */ 6233 register_name = "TraceIBPC"; 6234 goto cp0_unimplemented; 6235 case CP0_REG23__TRACEDBPC: 6236 /* PDtrace support */ 6237 /* gen_helper_mfc0_tracedbpc(arg); */ 6238 register_name = "TraceDBPC"; 6239 goto cp0_unimplemented; 6240 default: 6241 goto cp0_unimplemented; 6242 } 6243 break; 6244 case CP0_REGISTER_24: 6245 switch (sel) { 6246 case CP0_REG24__DEPC: 6247 /* EJTAG support */ 6248 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6249 tcg_gen_ext32s_tl(arg, arg); 6250 register_name = "DEPC"; 6251 break; 6252 default: 6253 goto cp0_unimplemented; 6254 } 6255 break; 6256 case CP0_REGISTER_25: 6257 switch (sel) { 6258 case CP0_REG25__PERFCTL0: 6259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6260 register_name = "Performance0"; 6261 break; 6262 case CP0_REG25__PERFCNT0: 6263 /* gen_helper_mfc0_performance1(arg); */ 6264 register_name = "Performance1"; 6265 goto cp0_unimplemented; 6266 case CP0_REG25__PERFCTL1: 6267 /* gen_helper_mfc0_performance2(arg); */ 6268 register_name = "Performance2"; 6269 goto cp0_unimplemented; 6270 case CP0_REG25__PERFCNT1: 6271 /* gen_helper_mfc0_performance3(arg); */ 6272 register_name = "Performance3"; 6273 goto cp0_unimplemented; 6274 case CP0_REG25__PERFCTL2: 6275 /* gen_helper_mfc0_performance4(arg); */ 6276 register_name = "Performance4"; 6277 goto cp0_unimplemented; 6278 case CP0_REG25__PERFCNT2: 6279 /* gen_helper_mfc0_performance5(arg); */ 6280 register_name = "Performance5"; 6281 goto cp0_unimplemented; 6282 case CP0_REG25__PERFCTL3: 6283 /* gen_helper_mfc0_performance6(arg); */ 6284 register_name = "Performance6"; 6285 goto cp0_unimplemented; 6286 case CP0_REG25__PERFCNT3: 6287 /* gen_helper_mfc0_performance7(arg); */ 6288 register_name = "Performance7"; 6289 goto cp0_unimplemented; 6290 default: 6291 goto cp0_unimplemented; 6292 } 6293 break; 6294 case CP0_REGISTER_26: 6295 switch (sel) { 6296 case CP0_REG26__ERRCTL: 6297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6298 register_name = "ErrCtl"; 6299 break; 6300 default: 6301 goto cp0_unimplemented; 6302 } 6303 break; 6304 case CP0_REGISTER_27: 6305 switch (sel) { 6306 case CP0_REG27__CACHERR: 6307 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6308 register_name = "CacheErr"; 6309 break; 6310 default: 6311 goto cp0_unimplemented; 6312 } 6313 break; 6314 case CP0_REGISTER_28: 6315 switch (sel) { 6316 case CP0_REG28__TAGLO: 6317 case CP0_REG28__TAGLO1: 6318 case CP0_REG28__TAGLO2: 6319 case CP0_REG28__TAGLO3: 6320 { 6321 TCGv_i64 tmp = tcg_temp_new_i64(); 6322 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6323 gen_move_low32(arg, tmp); 6324 tcg_temp_free_i64(tmp); 6325 } 6326 register_name = "TagLo"; 6327 break; 6328 case CP0_REG28__DATALO: 6329 case CP0_REG28__DATALO1: 6330 case CP0_REG28__DATALO2: 6331 case CP0_REG28__DATALO3: 6332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6333 register_name = "DataLo"; 6334 break; 6335 default: 6336 goto cp0_unimplemented; 6337 } 6338 break; 6339 case CP0_REGISTER_29: 6340 switch (sel) { 6341 case CP0_REG29__TAGHI: 6342 case CP0_REG29__TAGHI1: 6343 case CP0_REG29__TAGHI2: 6344 case CP0_REG29__TAGHI3: 6345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6346 register_name = "TagHi"; 6347 break; 6348 case CP0_REG29__DATAHI: 6349 case CP0_REG29__DATAHI1: 6350 case CP0_REG29__DATAHI2: 6351 case CP0_REG29__DATAHI3: 6352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6353 register_name = "DataHi"; 6354 break; 6355 default: 6356 goto cp0_unimplemented; 6357 } 6358 break; 6359 case CP0_REGISTER_30: 6360 switch (sel) { 6361 case CP0_REG30__ERROREPC: 6362 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6363 tcg_gen_ext32s_tl(arg, arg); 6364 register_name = "ErrorEPC"; 6365 break; 6366 default: 6367 goto cp0_unimplemented; 6368 } 6369 break; 6370 case CP0_REGISTER_31: 6371 switch (sel) { 6372 case CP0_REG31__DESAVE: 6373 /* EJTAG support */ 6374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6375 register_name = "DESAVE"; 6376 break; 6377 case CP0_REG31__KSCRATCH1: 6378 case CP0_REG31__KSCRATCH2: 6379 case CP0_REG31__KSCRATCH3: 6380 case CP0_REG31__KSCRATCH4: 6381 case CP0_REG31__KSCRATCH5: 6382 case CP0_REG31__KSCRATCH6: 6383 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6384 tcg_gen_ld_tl(arg, cpu_env, 6385 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6386 tcg_gen_ext32s_tl(arg, arg); 6387 register_name = "KScratch"; 6388 break; 6389 default: 6390 goto cp0_unimplemented; 6391 } 6392 break; 6393 default: 6394 goto cp0_unimplemented; 6395 } 6396 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6397 return; 6398 6399 cp0_unimplemented: 6400 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6401 register_name, reg, sel); 6402 gen_mfc0_unimplemented(ctx, arg); 6403 } 6404 6405 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6406 { 6407 const char *register_name = "invalid"; 6408 6409 if (sel != 0) { 6410 check_insn(ctx, ISA_MIPS_R1); 6411 } 6412 6413 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6414 gen_io_start(); 6415 } 6416 6417 switch (reg) { 6418 case CP0_REGISTER_00: 6419 switch (sel) { 6420 case CP0_REG00__INDEX: 6421 gen_helper_mtc0_index(cpu_env, arg); 6422 register_name = "Index"; 6423 break; 6424 case CP0_REG00__MVPCONTROL: 6425 CP0_CHECK(ctx->insn_flags & ASE_MT); 6426 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6427 register_name = "MVPControl"; 6428 break; 6429 case CP0_REG00__MVPCONF0: 6430 CP0_CHECK(ctx->insn_flags & ASE_MT); 6431 /* ignored */ 6432 register_name = "MVPConf0"; 6433 break; 6434 case CP0_REG00__MVPCONF1: 6435 CP0_CHECK(ctx->insn_flags & ASE_MT); 6436 /* ignored */ 6437 register_name = "MVPConf1"; 6438 break; 6439 case CP0_REG00__VPCONTROL: 6440 CP0_CHECK(ctx->vp); 6441 /* ignored */ 6442 register_name = "VPControl"; 6443 break; 6444 default: 6445 goto cp0_unimplemented; 6446 } 6447 break; 6448 case CP0_REGISTER_01: 6449 switch (sel) { 6450 case CP0_REG01__RANDOM: 6451 /* ignored */ 6452 register_name = "Random"; 6453 break; 6454 case CP0_REG01__VPECONTROL: 6455 CP0_CHECK(ctx->insn_flags & ASE_MT); 6456 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6457 register_name = "VPEControl"; 6458 break; 6459 case CP0_REG01__VPECONF0: 6460 CP0_CHECK(ctx->insn_flags & ASE_MT); 6461 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6462 register_name = "VPEConf0"; 6463 break; 6464 case CP0_REG01__VPECONF1: 6465 CP0_CHECK(ctx->insn_flags & ASE_MT); 6466 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6467 register_name = "VPEConf1"; 6468 break; 6469 case CP0_REG01__YQMASK: 6470 CP0_CHECK(ctx->insn_flags & ASE_MT); 6471 gen_helper_mtc0_yqmask(cpu_env, arg); 6472 register_name = "YQMask"; 6473 break; 6474 case CP0_REG01__VPESCHEDULE: 6475 CP0_CHECK(ctx->insn_flags & ASE_MT); 6476 tcg_gen_st_tl(arg, cpu_env, 6477 offsetof(CPUMIPSState, CP0_VPESchedule)); 6478 register_name = "VPESchedule"; 6479 break; 6480 case CP0_REG01__VPESCHEFBACK: 6481 CP0_CHECK(ctx->insn_flags & ASE_MT); 6482 tcg_gen_st_tl(arg, cpu_env, 6483 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6484 register_name = "VPEScheFBack"; 6485 break; 6486 case CP0_REG01__VPEOPT: 6487 CP0_CHECK(ctx->insn_flags & ASE_MT); 6488 gen_helper_mtc0_vpeopt(cpu_env, arg); 6489 register_name = "VPEOpt"; 6490 break; 6491 default: 6492 goto cp0_unimplemented; 6493 } 6494 break; 6495 case CP0_REGISTER_02: 6496 switch (sel) { 6497 case CP0_REG02__ENTRYLO0: 6498 gen_helper_mtc0_entrylo0(cpu_env, arg); 6499 register_name = "EntryLo0"; 6500 break; 6501 case CP0_REG02__TCSTATUS: 6502 CP0_CHECK(ctx->insn_flags & ASE_MT); 6503 gen_helper_mtc0_tcstatus(cpu_env, arg); 6504 register_name = "TCStatus"; 6505 break; 6506 case CP0_REG02__TCBIND: 6507 CP0_CHECK(ctx->insn_flags & ASE_MT); 6508 gen_helper_mtc0_tcbind(cpu_env, arg); 6509 register_name = "TCBind"; 6510 break; 6511 case CP0_REG02__TCRESTART: 6512 CP0_CHECK(ctx->insn_flags & ASE_MT); 6513 gen_helper_mtc0_tcrestart(cpu_env, arg); 6514 register_name = "TCRestart"; 6515 break; 6516 case CP0_REG02__TCHALT: 6517 CP0_CHECK(ctx->insn_flags & ASE_MT); 6518 gen_helper_mtc0_tchalt(cpu_env, arg); 6519 register_name = "TCHalt"; 6520 break; 6521 case CP0_REG02__TCCONTEXT: 6522 CP0_CHECK(ctx->insn_flags & ASE_MT); 6523 gen_helper_mtc0_tccontext(cpu_env, arg); 6524 register_name = "TCContext"; 6525 break; 6526 case CP0_REG02__TCSCHEDULE: 6527 CP0_CHECK(ctx->insn_flags & ASE_MT); 6528 gen_helper_mtc0_tcschedule(cpu_env, arg); 6529 register_name = "TCSchedule"; 6530 break; 6531 case CP0_REG02__TCSCHEFBACK: 6532 CP0_CHECK(ctx->insn_flags & ASE_MT); 6533 gen_helper_mtc0_tcschefback(cpu_env, arg); 6534 register_name = "TCScheFBack"; 6535 break; 6536 default: 6537 goto cp0_unimplemented; 6538 } 6539 break; 6540 case CP0_REGISTER_03: 6541 switch (sel) { 6542 case CP0_REG03__ENTRYLO1: 6543 gen_helper_mtc0_entrylo1(cpu_env, arg); 6544 register_name = "EntryLo1"; 6545 break; 6546 case CP0_REG03__GLOBALNUM: 6547 CP0_CHECK(ctx->vp); 6548 /* ignored */ 6549 register_name = "GlobalNumber"; 6550 break; 6551 default: 6552 goto cp0_unimplemented; 6553 } 6554 break; 6555 case CP0_REGISTER_04: 6556 switch (sel) { 6557 case CP0_REG04__CONTEXT: 6558 gen_helper_mtc0_context(cpu_env, arg); 6559 register_name = "Context"; 6560 break; 6561 case CP0_REG04__CONTEXTCONFIG: 6562 /* SmartMIPS ASE */ 6563 /* gen_helper_mtc0_contextconfig(arg); */ 6564 register_name = "ContextConfig"; 6565 goto cp0_unimplemented; 6566 case CP0_REG04__USERLOCAL: 6567 CP0_CHECK(ctx->ulri); 6568 tcg_gen_st_tl(arg, cpu_env, 6569 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6570 register_name = "UserLocal"; 6571 break; 6572 case CP0_REG04__MMID: 6573 CP0_CHECK(ctx->mi); 6574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6575 register_name = "MMID"; 6576 break; 6577 default: 6578 goto cp0_unimplemented; 6579 } 6580 break; 6581 case CP0_REGISTER_05: 6582 switch (sel) { 6583 case CP0_REG05__PAGEMASK: 6584 gen_helper_mtc0_pagemask(cpu_env, arg); 6585 register_name = "PageMask"; 6586 break; 6587 case CP0_REG05__PAGEGRAIN: 6588 check_insn(ctx, ISA_MIPS_R2); 6589 gen_helper_mtc0_pagegrain(cpu_env, arg); 6590 register_name = "PageGrain"; 6591 ctx->base.is_jmp = DISAS_STOP; 6592 break; 6593 case CP0_REG05__SEGCTL0: 6594 CP0_CHECK(ctx->sc); 6595 gen_helper_mtc0_segctl0(cpu_env, arg); 6596 register_name = "SegCtl0"; 6597 break; 6598 case CP0_REG05__SEGCTL1: 6599 CP0_CHECK(ctx->sc); 6600 gen_helper_mtc0_segctl1(cpu_env, arg); 6601 register_name = "SegCtl1"; 6602 break; 6603 case CP0_REG05__SEGCTL2: 6604 CP0_CHECK(ctx->sc); 6605 gen_helper_mtc0_segctl2(cpu_env, arg); 6606 register_name = "SegCtl2"; 6607 break; 6608 case CP0_REG05__PWBASE: 6609 check_pw(ctx); 6610 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6611 register_name = "PWBase"; 6612 break; 6613 case CP0_REG05__PWFIELD: 6614 check_pw(ctx); 6615 gen_helper_mtc0_pwfield(cpu_env, arg); 6616 register_name = "PWField"; 6617 break; 6618 case CP0_REG05__PWSIZE: 6619 check_pw(ctx); 6620 gen_helper_mtc0_pwsize(cpu_env, arg); 6621 register_name = "PWSize"; 6622 break; 6623 default: 6624 goto cp0_unimplemented; 6625 } 6626 break; 6627 case CP0_REGISTER_06: 6628 switch (sel) { 6629 case CP0_REG06__WIRED: 6630 gen_helper_mtc0_wired(cpu_env, arg); 6631 register_name = "Wired"; 6632 break; 6633 case CP0_REG06__SRSCONF0: 6634 check_insn(ctx, ISA_MIPS_R2); 6635 gen_helper_mtc0_srsconf0(cpu_env, arg); 6636 register_name = "SRSConf0"; 6637 break; 6638 case CP0_REG06__SRSCONF1: 6639 check_insn(ctx, ISA_MIPS_R2); 6640 gen_helper_mtc0_srsconf1(cpu_env, arg); 6641 register_name = "SRSConf1"; 6642 break; 6643 case CP0_REG06__SRSCONF2: 6644 check_insn(ctx, ISA_MIPS_R2); 6645 gen_helper_mtc0_srsconf2(cpu_env, arg); 6646 register_name = "SRSConf2"; 6647 break; 6648 case CP0_REG06__SRSCONF3: 6649 check_insn(ctx, ISA_MIPS_R2); 6650 gen_helper_mtc0_srsconf3(cpu_env, arg); 6651 register_name = "SRSConf3"; 6652 break; 6653 case CP0_REG06__SRSCONF4: 6654 check_insn(ctx, ISA_MIPS_R2); 6655 gen_helper_mtc0_srsconf4(cpu_env, arg); 6656 register_name = "SRSConf4"; 6657 break; 6658 case CP0_REG06__PWCTL: 6659 check_pw(ctx); 6660 gen_helper_mtc0_pwctl(cpu_env, arg); 6661 register_name = "PWCtl"; 6662 break; 6663 default: 6664 goto cp0_unimplemented; 6665 } 6666 break; 6667 case CP0_REGISTER_07: 6668 switch (sel) { 6669 case CP0_REG07__HWRENA: 6670 check_insn(ctx, ISA_MIPS_R2); 6671 gen_helper_mtc0_hwrena(cpu_env, arg); 6672 ctx->base.is_jmp = DISAS_STOP; 6673 register_name = "HWREna"; 6674 break; 6675 default: 6676 goto cp0_unimplemented; 6677 } 6678 break; 6679 case CP0_REGISTER_08: 6680 switch (sel) { 6681 case CP0_REG08__BADVADDR: 6682 /* ignored */ 6683 register_name = "BadVAddr"; 6684 break; 6685 case CP0_REG08__BADINSTR: 6686 /* ignored */ 6687 register_name = "BadInstr"; 6688 break; 6689 case CP0_REG08__BADINSTRP: 6690 /* ignored */ 6691 register_name = "BadInstrP"; 6692 break; 6693 case CP0_REG08__BADINSTRX: 6694 /* ignored */ 6695 register_name = "BadInstrX"; 6696 break; 6697 default: 6698 goto cp0_unimplemented; 6699 } 6700 break; 6701 case CP0_REGISTER_09: 6702 switch (sel) { 6703 case CP0_REG09__COUNT: 6704 gen_helper_mtc0_count(cpu_env, arg); 6705 register_name = "Count"; 6706 break; 6707 case CP0_REG09__SAARI: 6708 CP0_CHECK(ctx->saar); 6709 gen_helper_mtc0_saari(cpu_env, arg); 6710 register_name = "SAARI"; 6711 break; 6712 case CP0_REG09__SAAR: 6713 CP0_CHECK(ctx->saar); 6714 gen_helper_mtc0_saar(cpu_env, arg); 6715 register_name = "SAAR"; 6716 break; 6717 default: 6718 goto cp0_unimplemented; 6719 } 6720 break; 6721 case CP0_REGISTER_10: 6722 switch (sel) { 6723 case CP0_REG10__ENTRYHI: 6724 gen_helper_mtc0_entryhi(cpu_env, arg); 6725 register_name = "EntryHi"; 6726 break; 6727 default: 6728 goto cp0_unimplemented; 6729 } 6730 break; 6731 case CP0_REGISTER_11: 6732 switch (sel) { 6733 case CP0_REG11__COMPARE: 6734 gen_helper_mtc0_compare(cpu_env, arg); 6735 register_name = "Compare"; 6736 break; 6737 /* 6,7 are implementation dependent */ 6738 default: 6739 goto cp0_unimplemented; 6740 } 6741 break; 6742 case CP0_REGISTER_12: 6743 switch (sel) { 6744 case CP0_REG12__STATUS: 6745 save_cpu_state(ctx, 1); 6746 gen_helper_mtc0_status(cpu_env, arg); 6747 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6748 gen_save_pc(ctx->base.pc_next + 4); 6749 ctx->base.is_jmp = DISAS_EXIT; 6750 register_name = "Status"; 6751 break; 6752 case CP0_REG12__INTCTL: 6753 check_insn(ctx, ISA_MIPS_R2); 6754 gen_helper_mtc0_intctl(cpu_env, arg); 6755 /* Stop translation as we may have switched the execution mode */ 6756 ctx->base.is_jmp = DISAS_STOP; 6757 register_name = "IntCtl"; 6758 break; 6759 case CP0_REG12__SRSCTL: 6760 check_insn(ctx, ISA_MIPS_R2); 6761 gen_helper_mtc0_srsctl(cpu_env, arg); 6762 /* Stop translation as we may have switched the execution mode */ 6763 ctx->base.is_jmp = DISAS_STOP; 6764 register_name = "SRSCtl"; 6765 break; 6766 case CP0_REG12__SRSMAP: 6767 check_insn(ctx, ISA_MIPS_R2); 6768 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6769 /* Stop translation as we may have switched the execution mode */ 6770 ctx->base.is_jmp = DISAS_STOP; 6771 register_name = "SRSMap"; 6772 break; 6773 default: 6774 goto cp0_unimplemented; 6775 } 6776 break; 6777 case CP0_REGISTER_13: 6778 switch (sel) { 6779 case CP0_REG13__CAUSE: 6780 save_cpu_state(ctx, 1); 6781 gen_helper_mtc0_cause(cpu_env, arg); 6782 /* 6783 * Stop translation as we may have triggered an interrupt. 6784 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6785 * translated code to check for pending interrupts. 6786 */ 6787 gen_save_pc(ctx->base.pc_next + 4); 6788 ctx->base.is_jmp = DISAS_EXIT; 6789 register_name = "Cause"; 6790 break; 6791 default: 6792 goto cp0_unimplemented; 6793 } 6794 break; 6795 case CP0_REGISTER_14: 6796 switch (sel) { 6797 case CP0_REG14__EPC: 6798 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6799 register_name = "EPC"; 6800 break; 6801 default: 6802 goto cp0_unimplemented; 6803 } 6804 break; 6805 case CP0_REGISTER_15: 6806 switch (sel) { 6807 case CP0_REG15__PRID: 6808 /* ignored */ 6809 register_name = "PRid"; 6810 break; 6811 case CP0_REG15__EBASE: 6812 check_insn(ctx, ISA_MIPS_R2); 6813 gen_helper_mtc0_ebase(cpu_env, arg); 6814 register_name = "EBase"; 6815 break; 6816 default: 6817 goto cp0_unimplemented; 6818 } 6819 break; 6820 case CP0_REGISTER_16: 6821 switch (sel) { 6822 case CP0_REG16__CONFIG: 6823 gen_helper_mtc0_config0(cpu_env, arg); 6824 register_name = "Config"; 6825 /* Stop translation as we may have switched the execution mode */ 6826 ctx->base.is_jmp = DISAS_STOP; 6827 break; 6828 case CP0_REG16__CONFIG1: 6829 /* ignored, read only */ 6830 register_name = "Config1"; 6831 break; 6832 case CP0_REG16__CONFIG2: 6833 gen_helper_mtc0_config2(cpu_env, arg); 6834 register_name = "Config2"; 6835 /* Stop translation as we may have switched the execution mode */ 6836 ctx->base.is_jmp = DISAS_STOP; 6837 break; 6838 case CP0_REG16__CONFIG3: 6839 gen_helper_mtc0_config3(cpu_env, arg); 6840 register_name = "Config3"; 6841 /* Stop translation as we may have switched the execution mode */ 6842 ctx->base.is_jmp = DISAS_STOP; 6843 break; 6844 case CP0_REG16__CONFIG4: 6845 gen_helper_mtc0_config4(cpu_env, arg); 6846 register_name = "Config4"; 6847 ctx->base.is_jmp = DISAS_STOP; 6848 break; 6849 case CP0_REG16__CONFIG5: 6850 gen_helper_mtc0_config5(cpu_env, arg); 6851 register_name = "Config5"; 6852 /* Stop translation as we may have switched the execution mode */ 6853 ctx->base.is_jmp = DISAS_STOP; 6854 break; 6855 /* 6,7 are implementation dependent */ 6856 case CP0_REG16__CONFIG6: 6857 /* ignored */ 6858 register_name = "Config6"; 6859 break; 6860 case CP0_REG16__CONFIG7: 6861 /* ignored */ 6862 register_name = "Config7"; 6863 break; 6864 default: 6865 register_name = "Invalid config selector"; 6866 goto cp0_unimplemented; 6867 } 6868 break; 6869 case CP0_REGISTER_17: 6870 switch (sel) { 6871 case CP0_REG17__LLADDR: 6872 gen_helper_mtc0_lladdr(cpu_env, arg); 6873 register_name = "LLAddr"; 6874 break; 6875 case CP0_REG17__MAAR: 6876 CP0_CHECK(ctx->mrp); 6877 gen_helper_mtc0_maar(cpu_env, arg); 6878 register_name = "MAAR"; 6879 break; 6880 case CP0_REG17__MAARI: 6881 CP0_CHECK(ctx->mrp); 6882 gen_helper_mtc0_maari(cpu_env, arg); 6883 register_name = "MAARI"; 6884 break; 6885 default: 6886 goto cp0_unimplemented; 6887 } 6888 break; 6889 case CP0_REGISTER_18: 6890 switch (sel) { 6891 case CP0_REG18__WATCHLO0: 6892 case CP0_REG18__WATCHLO1: 6893 case CP0_REG18__WATCHLO2: 6894 case CP0_REG18__WATCHLO3: 6895 case CP0_REG18__WATCHLO4: 6896 case CP0_REG18__WATCHLO5: 6897 case CP0_REG18__WATCHLO6: 6898 case CP0_REG18__WATCHLO7: 6899 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6900 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6901 register_name = "WatchLo"; 6902 break; 6903 default: 6904 goto cp0_unimplemented; 6905 } 6906 break; 6907 case CP0_REGISTER_19: 6908 switch (sel) { 6909 case CP0_REG19__WATCHHI0: 6910 case CP0_REG19__WATCHHI1: 6911 case CP0_REG19__WATCHHI2: 6912 case CP0_REG19__WATCHHI3: 6913 case CP0_REG19__WATCHHI4: 6914 case CP0_REG19__WATCHHI5: 6915 case CP0_REG19__WATCHHI6: 6916 case CP0_REG19__WATCHHI7: 6917 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6918 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6919 register_name = "WatchHi"; 6920 break; 6921 default: 6922 goto cp0_unimplemented; 6923 } 6924 break; 6925 case CP0_REGISTER_20: 6926 switch (sel) { 6927 case CP0_REG20__XCONTEXT: 6928 #if defined(TARGET_MIPS64) 6929 check_insn(ctx, ISA_MIPS3); 6930 gen_helper_mtc0_xcontext(cpu_env, arg); 6931 register_name = "XContext"; 6932 break; 6933 #endif 6934 default: 6935 goto cp0_unimplemented; 6936 } 6937 break; 6938 case CP0_REGISTER_21: 6939 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6940 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6941 switch (sel) { 6942 case 0: 6943 gen_helper_mtc0_framemask(cpu_env, arg); 6944 register_name = "Framemask"; 6945 break; 6946 default: 6947 goto cp0_unimplemented; 6948 } 6949 break; 6950 case CP0_REGISTER_22: 6951 /* ignored */ 6952 register_name = "Diagnostic"; /* implementation dependent */ 6953 break; 6954 case CP0_REGISTER_23: 6955 switch (sel) { 6956 case CP0_REG23__DEBUG: 6957 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 6958 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6959 gen_save_pc(ctx->base.pc_next + 4); 6960 ctx->base.is_jmp = DISAS_EXIT; 6961 register_name = "Debug"; 6962 break; 6963 case CP0_REG23__TRACECONTROL: 6964 /* PDtrace support */ 6965 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 6966 register_name = "TraceControl"; 6967 /* Stop translation as we may have switched the execution mode */ 6968 ctx->base.is_jmp = DISAS_STOP; 6969 goto cp0_unimplemented; 6970 case CP0_REG23__TRACECONTROL2: 6971 /* PDtrace support */ 6972 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 6973 register_name = "TraceControl2"; 6974 /* Stop translation as we may have switched the execution mode */ 6975 ctx->base.is_jmp = DISAS_STOP; 6976 goto cp0_unimplemented; 6977 case CP0_REG23__USERTRACEDATA1: 6978 /* Stop translation as we may have switched the execution mode */ 6979 ctx->base.is_jmp = DISAS_STOP; 6980 /* PDtrace support */ 6981 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 6982 register_name = "UserTraceData"; 6983 /* Stop translation as we may have switched the execution mode */ 6984 ctx->base.is_jmp = DISAS_STOP; 6985 goto cp0_unimplemented; 6986 case CP0_REG23__TRACEIBPC: 6987 /* PDtrace support */ 6988 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 6989 /* Stop translation as we may have switched the execution mode */ 6990 ctx->base.is_jmp = DISAS_STOP; 6991 register_name = "TraceIBPC"; 6992 goto cp0_unimplemented; 6993 case CP0_REG23__TRACEDBPC: 6994 /* PDtrace support */ 6995 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 6996 /* Stop translation as we may have switched the execution mode */ 6997 ctx->base.is_jmp = DISAS_STOP; 6998 register_name = "TraceDBPC"; 6999 goto cp0_unimplemented; 7000 default: 7001 goto cp0_unimplemented; 7002 } 7003 break; 7004 case CP0_REGISTER_24: 7005 switch (sel) { 7006 case CP0_REG24__DEPC: 7007 /* EJTAG support */ 7008 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7009 register_name = "DEPC"; 7010 break; 7011 default: 7012 goto cp0_unimplemented; 7013 } 7014 break; 7015 case CP0_REGISTER_25: 7016 switch (sel) { 7017 case CP0_REG25__PERFCTL0: 7018 gen_helper_mtc0_performance0(cpu_env, arg); 7019 register_name = "Performance0"; 7020 break; 7021 case CP0_REG25__PERFCNT0: 7022 /* gen_helper_mtc0_performance1(arg); */ 7023 register_name = "Performance1"; 7024 goto cp0_unimplemented; 7025 case CP0_REG25__PERFCTL1: 7026 /* gen_helper_mtc0_performance2(arg); */ 7027 register_name = "Performance2"; 7028 goto cp0_unimplemented; 7029 case CP0_REG25__PERFCNT1: 7030 /* gen_helper_mtc0_performance3(arg); */ 7031 register_name = "Performance3"; 7032 goto cp0_unimplemented; 7033 case CP0_REG25__PERFCTL2: 7034 /* gen_helper_mtc0_performance4(arg); */ 7035 register_name = "Performance4"; 7036 goto cp0_unimplemented; 7037 case CP0_REG25__PERFCNT2: 7038 /* gen_helper_mtc0_performance5(arg); */ 7039 register_name = "Performance5"; 7040 goto cp0_unimplemented; 7041 case CP0_REG25__PERFCTL3: 7042 /* gen_helper_mtc0_performance6(arg); */ 7043 register_name = "Performance6"; 7044 goto cp0_unimplemented; 7045 case CP0_REG25__PERFCNT3: 7046 /* gen_helper_mtc0_performance7(arg); */ 7047 register_name = "Performance7"; 7048 goto cp0_unimplemented; 7049 default: 7050 goto cp0_unimplemented; 7051 } 7052 break; 7053 case CP0_REGISTER_26: 7054 switch (sel) { 7055 case CP0_REG26__ERRCTL: 7056 gen_helper_mtc0_errctl(cpu_env, arg); 7057 ctx->base.is_jmp = DISAS_STOP; 7058 register_name = "ErrCtl"; 7059 break; 7060 default: 7061 goto cp0_unimplemented; 7062 } 7063 break; 7064 case CP0_REGISTER_27: 7065 switch (sel) { 7066 case CP0_REG27__CACHERR: 7067 /* ignored */ 7068 register_name = "CacheErr"; 7069 break; 7070 default: 7071 goto cp0_unimplemented; 7072 } 7073 break; 7074 case CP0_REGISTER_28: 7075 switch (sel) { 7076 case CP0_REG28__TAGLO: 7077 case CP0_REG28__TAGLO1: 7078 case CP0_REG28__TAGLO2: 7079 case CP0_REG28__TAGLO3: 7080 gen_helper_mtc0_taglo(cpu_env, arg); 7081 register_name = "TagLo"; 7082 break; 7083 case CP0_REG28__DATALO: 7084 case CP0_REG28__DATALO1: 7085 case CP0_REG28__DATALO2: 7086 case CP0_REG28__DATALO3: 7087 gen_helper_mtc0_datalo(cpu_env, arg); 7088 register_name = "DataLo"; 7089 break; 7090 default: 7091 goto cp0_unimplemented; 7092 } 7093 break; 7094 case CP0_REGISTER_29: 7095 switch (sel) { 7096 case CP0_REG29__TAGHI: 7097 case CP0_REG29__TAGHI1: 7098 case CP0_REG29__TAGHI2: 7099 case CP0_REG29__TAGHI3: 7100 gen_helper_mtc0_taghi(cpu_env, arg); 7101 register_name = "TagHi"; 7102 break; 7103 case CP0_REG29__DATAHI: 7104 case CP0_REG29__DATAHI1: 7105 case CP0_REG29__DATAHI2: 7106 case CP0_REG29__DATAHI3: 7107 gen_helper_mtc0_datahi(cpu_env, arg); 7108 register_name = "DataHi"; 7109 break; 7110 default: 7111 register_name = "invalid sel"; 7112 goto cp0_unimplemented; 7113 } 7114 break; 7115 case CP0_REGISTER_30: 7116 switch (sel) { 7117 case CP0_REG30__ERROREPC: 7118 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7119 register_name = "ErrorEPC"; 7120 break; 7121 default: 7122 goto cp0_unimplemented; 7123 } 7124 break; 7125 case CP0_REGISTER_31: 7126 switch (sel) { 7127 case CP0_REG31__DESAVE: 7128 /* EJTAG support */ 7129 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7130 register_name = "DESAVE"; 7131 break; 7132 case CP0_REG31__KSCRATCH1: 7133 case CP0_REG31__KSCRATCH2: 7134 case CP0_REG31__KSCRATCH3: 7135 case CP0_REG31__KSCRATCH4: 7136 case CP0_REG31__KSCRATCH5: 7137 case CP0_REG31__KSCRATCH6: 7138 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7139 tcg_gen_st_tl(arg, cpu_env, 7140 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7141 register_name = "KScratch"; 7142 break; 7143 default: 7144 goto cp0_unimplemented; 7145 } 7146 break; 7147 default: 7148 goto cp0_unimplemented; 7149 } 7150 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7151 7152 /* For simplicity assume that all writes can cause interrupts. */ 7153 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7154 /* 7155 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7156 * translated code to check for pending interrupts. 7157 */ 7158 gen_save_pc(ctx->base.pc_next + 4); 7159 ctx->base.is_jmp = DISAS_EXIT; 7160 } 7161 return; 7162 7163 cp0_unimplemented: 7164 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7165 register_name, reg, sel); 7166 } 7167 7168 #if defined(TARGET_MIPS64) 7169 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7170 { 7171 const char *register_name = "invalid"; 7172 7173 if (sel != 0) { 7174 check_insn(ctx, ISA_MIPS_R1); 7175 } 7176 7177 switch (reg) { 7178 case CP0_REGISTER_00: 7179 switch (sel) { 7180 case CP0_REG00__INDEX: 7181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7182 register_name = "Index"; 7183 break; 7184 case CP0_REG00__MVPCONTROL: 7185 CP0_CHECK(ctx->insn_flags & ASE_MT); 7186 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7187 register_name = "MVPControl"; 7188 break; 7189 case CP0_REG00__MVPCONF0: 7190 CP0_CHECK(ctx->insn_flags & ASE_MT); 7191 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7192 register_name = "MVPConf0"; 7193 break; 7194 case CP0_REG00__MVPCONF1: 7195 CP0_CHECK(ctx->insn_flags & ASE_MT); 7196 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7197 register_name = "MVPConf1"; 7198 break; 7199 case CP0_REG00__VPCONTROL: 7200 CP0_CHECK(ctx->vp); 7201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7202 register_name = "VPControl"; 7203 break; 7204 default: 7205 goto cp0_unimplemented; 7206 } 7207 break; 7208 case CP0_REGISTER_01: 7209 switch (sel) { 7210 case CP0_REG01__RANDOM: 7211 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7212 gen_helper_mfc0_random(arg, cpu_env); 7213 register_name = "Random"; 7214 break; 7215 case CP0_REG01__VPECONTROL: 7216 CP0_CHECK(ctx->insn_flags & ASE_MT); 7217 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7218 register_name = "VPEControl"; 7219 break; 7220 case CP0_REG01__VPECONF0: 7221 CP0_CHECK(ctx->insn_flags & ASE_MT); 7222 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7223 register_name = "VPEConf0"; 7224 break; 7225 case CP0_REG01__VPECONF1: 7226 CP0_CHECK(ctx->insn_flags & ASE_MT); 7227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7228 register_name = "VPEConf1"; 7229 break; 7230 case CP0_REG01__YQMASK: 7231 CP0_CHECK(ctx->insn_flags & ASE_MT); 7232 tcg_gen_ld_tl(arg, cpu_env, 7233 offsetof(CPUMIPSState, CP0_YQMask)); 7234 register_name = "YQMask"; 7235 break; 7236 case CP0_REG01__VPESCHEDULE: 7237 CP0_CHECK(ctx->insn_flags & ASE_MT); 7238 tcg_gen_ld_tl(arg, cpu_env, 7239 offsetof(CPUMIPSState, CP0_VPESchedule)); 7240 register_name = "VPESchedule"; 7241 break; 7242 case CP0_REG01__VPESCHEFBACK: 7243 CP0_CHECK(ctx->insn_flags & ASE_MT); 7244 tcg_gen_ld_tl(arg, cpu_env, 7245 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7246 register_name = "VPEScheFBack"; 7247 break; 7248 case CP0_REG01__VPEOPT: 7249 CP0_CHECK(ctx->insn_flags & ASE_MT); 7250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7251 register_name = "VPEOpt"; 7252 break; 7253 default: 7254 goto cp0_unimplemented; 7255 } 7256 break; 7257 case CP0_REGISTER_02: 7258 switch (sel) { 7259 case CP0_REG02__ENTRYLO0: 7260 tcg_gen_ld_tl(arg, cpu_env, 7261 offsetof(CPUMIPSState, CP0_EntryLo0)); 7262 register_name = "EntryLo0"; 7263 break; 7264 case CP0_REG02__TCSTATUS: 7265 CP0_CHECK(ctx->insn_flags & ASE_MT); 7266 gen_helper_mfc0_tcstatus(arg, cpu_env); 7267 register_name = "TCStatus"; 7268 break; 7269 case CP0_REG02__TCBIND: 7270 CP0_CHECK(ctx->insn_flags & ASE_MT); 7271 gen_helper_mfc0_tcbind(arg, cpu_env); 7272 register_name = "TCBind"; 7273 break; 7274 case CP0_REG02__TCRESTART: 7275 CP0_CHECK(ctx->insn_flags & ASE_MT); 7276 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7277 register_name = "TCRestart"; 7278 break; 7279 case CP0_REG02__TCHALT: 7280 CP0_CHECK(ctx->insn_flags & ASE_MT); 7281 gen_helper_dmfc0_tchalt(arg, cpu_env); 7282 register_name = "TCHalt"; 7283 break; 7284 case CP0_REG02__TCCONTEXT: 7285 CP0_CHECK(ctx->insn_flags & ASE_MT); 7286 gen_helper_dmfc0_tccontext(arg, cpu_env); 7287 register_name = "TCContext"; 7288 break; 7289 case CP0_REG02__TCSCHEDULE: 7290 CP0_CHECK(ctx->insn_flags & ASE_MT); 7291 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7292 register_name = "TCSchedule"; 7293 break; 7294 case CP0_REG02__TCSCHEFBACK: 7295 CP0_CHECK(ctx->insn_flags & ASE_MT); 7296 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7297 register_name = "TCScheFBack"; 7298 break; 7299 default: 7300 goto cp0_unimplemented; 7301 } 7302 break; 7303 case CP0_REGISTER_03: 7304 switch (sel) { 7305 case CP0_REG03__ENTRYLO1: 7306 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7307 register_name = "EntryLo1"; 7308 break; 7309 case CP0_REG03__GLOBALNUM: 7310 CP0_CHECK(ctx->vp); 7311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7312 register_name = "GlobalNumber"; 7313 break; 7314 default: 7315 goto cp0_unimplemented; 7316 } 7317 break; 7318 case CP0_REGISTER_04: 7319 switch (sel) { 7320 case CP0_REG04__CONTEXT: 7321 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7322 register_name = "Context"; 7323 break; 7324 case CP0_REG04__CONTEXTCONFIG: 7325 /* SmartMIPS ASE */ 7326 /* gen_helper_dmfc0_contextconfig(arg); */ 7327 register_name = "ContextConfig"; 7328 goto cp0_unimplemented; 7329 case CP0_REG04__USERLOCAL: 7330 CP0_CHECK(ctx->ulri); 7331 tcg_gen_ld_tl(arg, cpu_env, 7332 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7333 register_name = "UserLocal"; 7334 break; 7335 case CP0_REG04__MMID: 7336 CP0_CHECK(ctx->mi); 7337 gen_helper_mtc0_memorymapid(cpu_env, arg); 7338 register_name = "MMID"; 7339 break; 7340 default: 7341 goto cp0_unimplemented; 7342 } 7343 break; 7344 case CP0_REGISTER_05: 7345 switch (sel) { 7346 case CP0_REG05__PAGEMASK: 7347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7348 register_name = "PageMask"; 7349 break; 7350 case CP0_REG05__PAGEGRAIN: 7351 check_insn(ctx, ISA_MIPS_R2); 7352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7353 register_name = "PageGrain"; 7354 break; 7355 case CP0_REG05__SEGCTL0: 7356 CP0_CHECK(ctx->sc); 7357 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7358 register_name = "SegCtl0"; 7359 break; 7360 case CP0_REG05__SEGCTL1: 7361 CP0_CHECK(ctx->sc); 7362 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7363 register_name = "SegCtl1"; 7364 break; 7365 case CP0_REG05__SEGCTL2: 7366 CP0_CHECK(ctx->sc); 7367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7368 register_name = "SegCtl2"; 7369 break; 7370 case CP0_REG05__PWBASE: 7371 check_pw(ctx); 7372 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7373 register_name = "PWBase"; 7374 break; 7375 case CP0_REG05__PWFIELD: 7376 check_pw(ctx); 7377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7378 register_name = "PWField"; 7379 break; 7380 case CP0_REG05__PWSIZE: 7381 check_pw(ctx); 7382 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7383 register_name = "PWSize"; 7384 break; 7385 default: 7386 goto cp0_unimplemented; 7387 } 7388 break; 7389 case CP0_REGISTER_06: 7390 switch (sel) { 7391 case CP0_REG06__WIRED: 7392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7393 register_name = "Wired"; 7394 break; 7395 case CP0_REG06__SRSCONF0: 7396 check_insn(ctx, ISA_MIPS_R2); 7397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7398 register_name = "SRSConf0"; 7399 break; 7400 case CP0_REG06__SRSCONF1: 7401 check_insn(ctx, ISA_MIPS_R2); 7402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7403 register_name = "SRSConf1"; 7404 break; 7405 case CP0_REG06__SRSCONF2: 7406 check_insn(ctx, ISA_MIPS_R2); 7407 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7408 register_name = "SRSConf2"; 7409 break; 7410 case CP0_REG06__SRSCONF3: 7411 check_insn(ctx, ISA_MIPS_R2); 7412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7413 register_name = "SRSConf3"; 7414 break; 7415 case CP0_REG06__SRSCONF4: 7416 check_insn(ctx, ISA_MIPS_R2); 7417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7418 register_name = "SRSConf4"; 7419 break; 7420 case CP0_REG06__PWCTL: 7421 check_pw(ctx); 7422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7423 register_name = "PWCtl"; 7424 break; 7425 default: 7426 goto cp0_unimplemented; 7427 } 7428 break; 7429 case CP0_REGISTER_07: 7430 switch (sel) { 7431 case CP0_REG07__HWRENA: 7432 check_insn(ctx, ISA_MIPS_R2); 7433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7434 register_name = "HWREna"; 7435 break; 7436 default: 7437 goto cp0_unimplemented; 7438 } 7439 break; 7440 case CP0_REGISTER_08: 7441 switch (sel) { 7442 case CP0_REG08__BADVADDR: 7443 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7444 register_name = "BadVAddr"; 7445 break; 7446 case CP0_REG08__BADINSTR: 7447 CP0_CHECK(ctx->bi); 7448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7449 register_name = "BadInstr"; 7450 break; 7451 case CP0_REG08__BADINSTRP: 7452 CP0_CHECK(ctx->bp); 7453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7454 register_name = "BadInstrP"; 7455 break; 7456 case CP0_REG08__BADINSTRX: 7457 CP0_CHECK(ctx->bi); 7458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7459 tcg_gen_andi_tl(arg, arg, ~0xffff); 7460 register_name = "BadInstrX"; 7461 break; 7462 default: 7463 goto cp0_unimplemented; 7464 } 7465 break; 7466 case CP0_REGISTER_09: 7467 switch (sel) { 7468 case CP0_REG09__COUNT: 7469 /* Mark as an IO operation because we read the time. */ 7470 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7471 gen_io_start(); 7472 } 7473 gen_helper_mfc0_count(arg, cpu_env); 7474 /* 7475 * Break the TB to be able to take timer interrupts immediately 7476 * after reading count. DISAS_STOP isn't sufficient, we need to 7477 * ensure we break completely out of translated code. 7478 */ 7479 gen_save_pc(ctx->base.pc_next + 4); 7480 ctx->base.is_jmp = DISAS_EXIT; 7481 register_name = "Count"; 7482 break; 7483 case CP0_REG09__SAARI: 7484 CP0_CHECK(ctx->saar); 7485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7486 register_name = "SAARI"; 7487 break; 7488 case CP0_REG09__SAAR: 7489 CP0_CHECK(ctx->saar); 7490 gen_helper_dmfc0_saar(arg, cpu_env); 7491 register_name = "SAAR"; 7492 break; 7493 default: 7494 goto cp0_unimplemented; 7495 } 7496 break; 7497 case CP0_REGISTER_10: 7498 switch (sel) { 7499 case CP0_REG10__ENTRYHI: 7500 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7501 register_name = "EntryHi"; 7502 break; 7503 default: 7504 goto cp0_unimplemented; 7505 } 7506 break; 7507 case CP0_REGISTER_11: 7508 switch (sel) { 7509 case CP0_REG11__COMPARE: 7510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7511 register_name = "Compare"; 7512 break; 7513 /* 6,7 are implementation dependent */ 7514 default: 7515 goto cp0_unimplemented; 7516 } 7517 break; 7518 case CP0_REGISTER_12: 7519 switch (sel) { 7520 case CP0_REG12__STATUS: 7521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7522 register_name = "Status"; 7523 break; 7524 case CP0_REG12__INTCTL: 7525 check_insn(ctx, ISA_MIPS_R2); 7526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7527 register_name = "IntCtl"; 7528 break; 7529 case CP0_REG12__SRSCTL: 7530 check_insn(ctx, ISA_MIPS_R2); 7531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7532 register_name = "SRSCtl"; 7533 break; 7534 case CP0_REG12__SRSMAP: 7535 check_insn(ctx, ISA_MIPS_R2); 7536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7537 register_name = "SRSMap"; 7538 break; 7539 default: 7540 goto cp0_unimplemented; 7541 } 7542 break; 7543 case CP0_REGISTER_13: 7544 switch (sel) { 7545 case CP0_REG13__CAUSE: 7546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7547 register_name = "Cause"; 7548 break; 7549 default: 7550 goto cp0_unimplemented; 7551 } 7552 break; 7553 case CP0_REGISTER_14: 7554 switch (sel) { 7555 case CP0_REG14__EPC: 7556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7557 register_name = "EPC"; 7558 break; 7559 default: 7560 goto cp0_unimplemented; 7561 } 7562 break; 7563 case CP0_REGISTER_15: 7564 switch (sel) { 7565 case CP0_REG15__PRID: 7566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7567 register_name = "PRid"; 7568 break; 7569 case CP0_REG15__EBASE: 7570 check_insn(ctx, ISA_MIPS_R2); 7571 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7572 register_name = "EBase"; 7573 break; 7574 case CP0_REG15__CMGCRBASE: 7575 check_insn(ctx, ISA_MIPS_R2); 7576 CP0_CHECK(ctx->cmgcr); 7577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7578 register_name = "CMGCRBase"; 7579 break; 7580 default: 7581 goto cp0_unimplemented; 7582 } 7583 break; 7584 case CP0_REGISTER_16: 7585 switch (sel) { 7586 case CP0_REG16__CONFIG: 7587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7588 register_name = "Config"; 7589 break; 7590 case CP0_REG16__CONFIG1: 7591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7592 register_name = "Config1"; 7593 break; 7594 case CP0_REG16__CONFIG2: 7595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7596 register_name = "Config2"; 7597 break; 7598 case CP0_REG16__CONFIG3: 7599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7600 register_name = "Config3"; 7601 break; 7602 case CP0_REG16__CONFIG4: 7603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7604 register_name = "Config4"; 7605 break; 7606 case CP0_REG16__CONFIG5: 7607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7608 register_name = "Config5"; 7609 break; 7610 /* 6,7 are implementation dependent */ 7611 case CP0_REG16__CONFIG6: 7612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7613 register_name = "Config6"; 7614 break; 7615 case CP0_REG16__CONFIG7: 7616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7617 register_name = "Config7"; 7618 break; 7619 default: 7620 goto cp0_unimplemented; 7621 } 7622 break; 7623 case CP0_REGISTER_17: 7624 switch (sel) { 7625 case CP0_REG17__LLADDR: 7626 gen_helper_dmfc0_lladdr(arg, cpu_env); 7627 register_name = "LLAddr"; 7628 break; 7629 case CP0_REG17__MAAR: 7630 CP0_CHECK(ctx->mrp); 7631 gen_helper_dmfc0_maar(arg, cpu_env); 7632 register_name = "MAAR"; 7633 break; 7634 case CP0_REG17__MAARI: 7635 CP0_CHECK(ctx->mrp); 7636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7637 register_name = "MAARI"; 7638 break; 7639 default: 7640 goto cp0_unimplemented; 7641 } 7642 break; 7643 case CP0_REGISTER_18: 7644 switch (sel) { 7645 case CP0_REG18__WATCHLO0: 7646 case CP0_REG18__WATCHLO1: 7647 case CP0_REG18__WATCHLO2: 7648 case CP0_REG18__WATCHLO3: 7649 case CP0_REG18__WATCHLO4: 7650 case CP0_REG18__WATCHLO5: 7651 case CP0_REG18__WATCHLO6: 7652 case CP0_REG18__WATCHLO7: 7653 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7654 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7655 register_name = "WatchLo"; 7656 break; 7657 default: 7658 goto cp0_unimplemented; 7659 } 7660 break; 7661 case CP0_REGISTER_19: 7662 switch (sel) { 7663 case CP0_REG19__WATCHHI0: 7664 case CP0_REG19__WATCHHI1: 7665 case CP0_REG19__WATCHHI2: 7666 case CP0_REG19__WATCHHI3: 7667 case CP0_REG19__WATCHHI4: 7668 case CP0_REG19__WATCHHI5: 7669 case CP0_REG19__WATCHHI6: 7670 case CP0_REG19__WATCHHI7: 7671 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7672 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7673 register_name = "WatchHi"; 7674 break; 7675 default: 7676 goto cp0_unimplemented; 7677 } 7678 break; 7679 case CP0_REGISTER_20: 7680 switch (sel) { 7681 case CP0_REG20__XCONTEXT: 7682 check_insn(ctx, ISA_MIPS3); 7683 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7684 register_name = "XContext"; 7685 break; 7686 default: 7687 goto cp0_unimplemented; 7688 } 7689 break; 7690 case CP0_REGISTER_21: 7691 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7692 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7693 switch (sel) { 7694 case 0: 7695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7696 register_name = "Framemask"; 7697 break; 7698 default: 7699 goto cp0_unimplemented; 7700 } 7701 break; 7702 case CP0_REGISTER_22: 7703 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7704 register_name = "'Diagnostic"; /* implementation dependent */ 7705 break; 7706 case CP0_REGISTER_23: 7707 switch (sel) { 7708 case CP0_REG23__DEBUG: 7709 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7710 register_name = "Debug"; 7711 break; 7712 case CP0_REG23__TRACECONTROL: 7713 /* PDtrace support */ 7714 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7715 register_name = "TraceControl"; 7716 goto cp0_unimplemented; 7717 case CP0_REG23__TRACECONTROL2: 7718 /* PDtrace support */ 7719 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7720 register_name = "TraceControl2"; 7721 goto cp0_unimplemented; 7722 case CP0_REG23__USERTRACEDATA1: 7723 /* PDtrace support */ 7724 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7725 register_name = "UserTraceData1"; 7726 goto cp0_unimplemented; 7727 case CP0_REG23__TRACEIBPC: 7728 /* PDtrace support */ 7729 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7730 register_name = "TraceIBPC"; 7731 goto cp0_unimplemented; 7732 case CP0_REG23__TRACEDBPC: 7733 /* PDtrace support */ 7734 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7735 register_name = "TraceDBPC"; 7736 goto cp0_unimplemented; 7737 default: 7738 goto cp0_unimplemented; 7739 } 7740 break; 7741 case CP0_REGISTER_24: 7742 switch (sel) { 7743 case CP0_REG24__DEPC: 7744 /* EJTAG support */ 7745 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7746 register_name = "DEPC"; 7747 break; 7748 default: 7749 goto cp0_unimplemented; 7750 } 7751 break; 7752 case CP0_REGISTER_25: 7753 switch (sel) { 7754 case CP0_REG25__PERFCTL0: 7755 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7756 register_name = "Performance0"; 7757 break; 7758 case CP0_REG25__PERFCNT0: 7759 /* gen_helper_dmfc0_performance1(arg); */ 7760 register_name = "Performance1"; 7761 goto cp0_unimplemented; 7762 case CP0_REG25__PERFCTL1: 7763 /* gen_helper_dmfc0_performance2(arg); */ 7764 register_name = "Performance2"; 7765 goto cp0_unimplemented; 7766 case CP0_REG25__PERFCNT1: 7767 /* gen_helper_dmfc0_performance3(arg); */ 7768 register_name = "Performance3"; 7769 goto cp0_unimplemented; 7770 case CP0_REG25__PERFCTL2: 7771 /* gen_helper_dmfc0_performance4(arg); */ 7772 register_name = "Performance4"; 7773 goto cp0_unimplemented; 7774 case CP0_REG25__PERFCNT2: 7775 /* gen_helper_dmfc0_performance5(arg); */ 7776 register_name = "Performance5"; 7777 goto cp0_unimplemented; 7778 case CP0_REG25__PERFCTL3: 7779 /* gen_helper_dmfc0_performance6(arg); */ 7780 register_name = "Performance6"; 7781 goto cp0_unimplemented; 7782 case CP0_REG25__PERFCNT3: 7783 /* gen_helper_dmfc0_performance7(arg); */ 7784 register_name = "Performance7"; 7785 goto cp0_unimplemented; 7786 default: 7787 goto cp0_unimplemented; 7788 } 7789 break; 7790 case CP0_REGISTER_26: 7791 switch (sel) { 7792 case CP0_REG26__ERRCTL: 7793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7794 register_name = "ErrCtl"; 7795 break; 7796 default: 7797 goto cp0_unimplemented; 7798 } 7799 break; 7800 case CP0_REGISTER_27: 7801 switch (sel) { 7802 /* ignored */ 7803 case CP0_REG27__CACHERR: 7804 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7805 register_name = "CacheErr"; 7806 break; 7807 default: 7808 goto cp0_unimplemented; 7809 } 7810 break; 7811 case CP0_REGISTER_28: 7812 switch (sel) { 7813 case CP0_REG28__TAGLO: 7814 case CP0_REG28__TAGLO1: 7815 case CP0_REG28__TAGLO2: 7816 case CP0_REG28__TAGLO3: 7817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7818 register_name = "TagLo"; 7819 break; 7820 case CP0_REG28__DATALO: 7821 case CP0_REG28__DATALO1: 7822 case CP0_REG28__DATALO2: 7823 case CP0_REG28__DATALO3: 7824 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7825 register_name = "DataLo"; 7826 break; 7827 default: 7828 goto cp0_unimplemented; 7829 } 7830 break; 7831 case CP0_REGISTER_29: 7832 switch (sel) { 7833 case CP0_REG29__TAGHI: 7834 case CP0_REG29__TAGHI1: 7835 case CP0_REG29__TAGHI2: 7836 case CP0_REG29__TAGHI3: 7837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7838 register_name = "TagHi"; 7839 break; 7840 case CP0_REG29__DATAHI: 7841 case CP0_REG29__DATAHI1: 7842 case CP0_REG29__DATAHI2: 7843 case CP0_REG29__DATAHI3: 7844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7845 register_name = "DataHi"; 7846 break; 7847 default: 7848 goto cp0_unimplemented; 7849 } 7850 break; 7851 case CP0_REGISTER_30: 7852 switch (sel) { 7853 case CP0_REG30__ERROREPC: 7854 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7855 register_name = "ErrorEPC"; 7856 break; 7857 default: 7858 goto cp0_unimplemented; 7859 } 7860 break; 7861 case CP0_REGISTER_31: 7862 switch (sel) { 7863 case CP0_REG31__DESAVE: 7864 /* EJTAG support */ 7865 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7866 register_name = "DESAVE"; 7867 break; 7868 case CP0_REG31__KSCRATCH1: 7869 case CP0_REG31__KSCRATCH2: 7870 case CP0_REG31__KSCRATCH3: 7871 case CP0_REG31__KSCRATCH4: 7872 case CP0_REG31__KSCRATCH5: 7873 case CP0_REG31__KSCRATCH6: 7874 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7875 tcg_gen_ld_tl(arg, cpu_env, 7876 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7877 register_name = "KScratch"; 7878 break; 7879 default: 7880 goto cp0_unimplemented; 7881 } 7882 break; 7883 default: 7884 goto cp0_unimplemented; 7885 } 7886 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7887 return; 7888 7889 cp0_unimplemented: 7890 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7891 register_name, reg, sel); 7892 gen_mfc0_unimplemented(ctx, arg); 7893 } 7894 7895 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7896 { 7897 const char *register_name = "invalid"; 7898 7899 if (sel != 0) { 7900 check_insn(ctx, ISA_MIPS_R1); 7901 } 7902 7903 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7904 gen_io_start(); 7905 } 7906 7907 switch (reg) { 7908 case CP0_REGISTER_00: 7909 switch (sel) { 7910 case CP0_REG00__INDEX: 7911 gen_helper_mtc0_index(cpu_env, arg); 7912 register_name = "Index"; 7913 break; 7914 case CP0_REG00__MVPCONTROL: 7915 CP0_CHECK(ctx->insn_flags & ASE_MT); 7916 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 7917 register_name = "MVPControl"; 7918 break; 7919 case CP0_REG00__MVPCONF0: 7920 CP0_CHECK(ctx->insn_flags & ASE_MT); 7921 /* ignored */ 7922 register_name = "MVPConf0"; 7923 break; 7924 case CP0_REG00__MVPCONF1: 7925 CP0_CHECK(ctx->insn_flags & ASE_MT); 7926 /* ignored */ 7927 register_name = "MVPConf1"; 7928 break; 7929 case CP0_REG00__VPCONTROL: 7930 CP0_CHECK(ctx->vp); 7931 /* ignored */ 7932 register_name = "VPControl"; 7933 break; 7934 default: 7935 goto cp0_unimplemented; 7936 } 7937 break; 7938 case CP0_REGISTER_01: 7939 switch (sel) { 7940 case CP0_REG01__RANDOM: 7941 /* ignored */ 7942 register_name = "Random"; 7943 break; 7944 case CP0_REG01__VPECONTROL: 7945 CP0_CHECK(ctx->insn_flags & ASE_MT); 7946 gen_helper_mtc0_vpecontrol(cpu_env, arg); 7947 register_name = "VPEControl"; 7948 break; 7949 case CP0_REG01__VPECONF0: 7950 CP0_CHECK(ctx->insn_flags & ASE_MT); 7951 gen_helper_mtc0_vpeconf0(cpu_env, arg); 7952 register_name = "VPEConf0"; 7953 break; 7954 case CP0_REG01__VPECONF1: 7955 CP0_CHECK(ctx->insn_flags & ASE_MT); 7956 gen_helper_mtc0_vpeconf1(cpu_env, arg); 7957 register_name = "VPEConf1"; 7958 break; 7959 case CP0_REG01__YQMASK: 7960 CP0_CHECK(ctx->insn_flags & ASE_MT); 7961 gen_helper_mtc0_yqmask(cpu_env, arg); 7962 register_name = "YQMask"; 7963 break; 7964 case CP0_REG01__VPESCHEDULE: 7965 CP0_CHECK(ctx->insn_flags & ASE_MT); 7966 tcg_gen_st_tl(arg, cpu_env, 7967 offsetof(CPUMIPSState, CP0_VPESchedule)); 7968 register_name = "VPESchedule"; 7969 break; 7970 case CP0_REG01__VPESCHEFBACK: 7971 CP0_CHECK(ctx->insn_flags & ASE_MT); 7972 tcg_gen_st_tl(arg, cpu_env, 7973 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7974 register_name = "VPEScheFBack"; 7975 break; 7976 case CP0_REG01__VPEOPT: 7977 CP0_CHECK(ctx->insn_flags & ASE_MT); 7978 gen_helper_mtc0_vpeopt(cpu_env, arg); 7979 register_name = "VPEOpt"; 7980 break; 7981 default: 7982 goto cp0_unimplemented; 7983 } 7984 break; 7985 case CP0_REGISTER_02: 7986 switch (sel) { 7987 case CP0_REG02__ENTRYLO0: 7988 gen_helper_dmtc0_entrylo0(cpu_env, arg); 7989 register_name = "EntryLo0"; 7990 break; 7991 case CP0_REG02__TCSTATUS: 7992 CP0_CHECK(ctx->insn_flags & ASE_MT); 7993 gen_helper_mtc0_tcstatus(cpu_env, arg); 7994 register_name = "TCStatus"; 7995 break; 7996 case CP0_REG02__TCBIND: 7997 CP0_CHECK(ctx->insn_flags & ASE_MT); 7998 gen_helper_mtc0_tcbind(cpu_env, arg); 7999 register_name = "TCBind"; 8000 break; 8001 case CP0_REG02__TCRESTART: 8002 CP0_CHECK(ctx->insn_flags & ASE_MT); 8003 gen_helper_mtc0_tcrestart(cpu_env, arg); 8004 register_name = "TCRestart"; 8005 break; 8006 case CP0_REG02__TCHALT: 8007 CP0_CHECK(ctx->insn_flags & ASE_MT); 8008 gen_helper_mtc0_tchalt(cpu_env, arg); 8009 register_name = "TCHalt"; 8010 break; 8011 case CP0_REG02__TCCONTEXT: 8012 CP0_CHECK(ctx->insn_flags & ASE_MT); 8013 gen_helper_mtc0_tccontext(cpu_env, arg); 8014 register_name = "TCContext"; 8015 break; 8016 case CP0_REG02__TCSCHEDULE: 8017 CP0_CHECK(ctx->insn_flags & ASE_MT); 8018 gen_helper_mtc0_tcschedule(cpu_env, arg); 8019 register_name = "TCSchedule"; 8020 break; 8021 case CP0_REG02__TCSCHEFBACK: 8022 CP0_CHECK(ctx->insn_flags & ASE_MT); 8023 gen_helper_mtc0_tcschefback(cpu_env, arg); 8024 register_name = "TCScheFBack"; 8025 break; 8026 default: 8027 goto cp0_unimplemented; 8028 } 8029 break; 8030 case CP0_REGISTER_03: 8031 switch (sel) { 8032 case CP0_REG03__ENTRYLO1: 8033 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8034 register_name = "EntryLo1"; 8035 break; 8036 case CP0_REG03__GLOBALNUM: 8037 CP0_CHECK(ctx->vp); 8038 /* ignored */ 8039 register_name = "GlobalNumber"; 8040 break; 8041 default: 8042 goto cp0_unimplemented; 8043 } 8044 break; 8045 case CP0_REGISTER_04: 8046 switch (sel) { 8047 case CP0_REG04__CONTEXT: 8048 gen_helper_mtc0_context(cpu_env, arg); 8049 register_name = "Context"; 8050 break; 8051 case CP0_REG04__CONTEXTCONFIG: 8052 /* SmartMIPS ASE */ 8053 /* gen_helper_dmtc0_contextconfig(arg); */ 8054 register_name = "ContextConfig"; 8055 goto cp0_unimplemented; 8056 case CP0_REG04__USERLOCAL: 8057 CP0_CHECK(ctx->ulri); 8058 tcg_gen_st_tl(arg, cpu_env, 8059 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8060 register_name = "UserLocal"; 8061 break; 8062 case CP0_REG04__MMID: 8063 CP0_CHECK(ctx->mi); 8064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8065 register_name = "MMID"; 8066 break; 8067 default: 8068 goto cp0_unimplemented; 8069 } 8070 break; 8071 case CP0_REGISTER_05: 8072 switch (sel) { 8073 case CP0_REG05__PAGEMASK: 8074 gen_helper_mtc0_pagemask(cpu_env, arg); 8075 register_name = "PageMask"; 8076 break; 8077 case CP0_REG05__PAGEGRAIN: 8078 check_insn(ctx, ISA_MIPS_R2); 8079 gen_helper_mtc0_pagegrain(cpu_env, arg); 8080 register_name = "PageGrain"; 8081 break; 8082 case CP0_REG05__SEGCTL0: 8083 CP0_CHECK(ctx->sc); 8084 gen_helper_mtc0_segctl0(cpu_env, arg); 8085 register_name = "SegCtl0"; 8086 break; 8087 case CP0_REG05__SEGCTL1: 8088 CP0_CHECK(ctx->sc); 8089 gen_helper_mtc0_segctl1(cpu_env, arg); 8090 register_name = "SegCtl1"; 8091 break; 8092 case CP0_REG05__SEGCTL2: 8093 CP0_CHECK(ctx->sc); 8094 gen_helper_mtc0_segctl2(cpu_env, arg); 8095 register_name = "SegCtl2"; 8096 break; 8097 case CP0_REG05__PWBASE: 8098 check_pw(ctx); 8099 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8100 register_name = "PWBase"; 8101 break; 8102 case CP0_REG05__PWFIELD: 8103 check_pw(ctx); 8104 gen_helper_mtc0_pwfield(cpu_env, arg); 8105 register_name = "PWField"; 8106 break; 8107 case CP0_REG05__PWSIZE: 8108 check_pw(ctx); 8109 gen_helper_mtc0_pwsize(cpu_env, arg); 8110 register_name = "PWSize"; 8111 break; 8112 default: 8113 goto cp0_unimplemented; 8114 } 8115 break; 8116 case CP0_REGISTER_06: 8117 switch (sel) { 8118 case CP0_REG06__WIRED: 8119 gen_helper_mtc0_wired(cpu_env, arg); 8120 register_name = "Wired"; 8121 break; 8122 case CP0_REG06__SRSCONF0: 8123 check_insn(ctx, ISA_MIPS_R2); 8124 gen_helper_mtc0_srsconf0(cpu_env, arg); 8125 register_name = "SRSConf0"; 8126 break; 8127 case CP0_REG06__SRSCONF1: 8128 check_insn(ctx, ISA_MIPS_R2); 8129 gen_helper_mtc0_srsconf1(cpu_env, arg); 8130 register_name = "SRSConf1"; 8131 break; 8132 case CP0_REG06__SRSCONF2: 8133 check_insn(ctx, ISA_MIPS_R2); 8134 gen_helper_mtc0_srsconf2(cpu_env, arg); 8135 register_name = "SRSConf2"; 8136 break; 8137 case CP0_REG06__SRSCONF3: 8138 check_insn(ctx, ISA_MIPS_R2); 8139 gen_helper_mtc0_srsconf3(cpu_env, arg); 8140 register_name = "SRSConf3"; 8141 break; 8142 case CP0_REG06__SRSCONF4: 8143 check_insn(ctx, ISA_MIPS_R2); 8144 gen_helper_mtc0_srsconf4(cpu_env, arg); 8145 register_name = "SRSConf4"; 8146 break; 8147 case CP0_REG06__PWCTL: 8148 check_pw(ctx); 8149 gen_helper_mtc0_pwctl(cpu_env, arg); 8150 register_name = "PWCtl"; 8151 break; 8152 default: 8153 goto cp0_unimplemented; 8154 } 8155 break; 8156 case CP0_REGISTER_07: 8157 switch (sel) { 8158 case CP0_REG07__HWRENA: 8159 check_insn(ctx, ISA_MIPS_R2); 8160 gen_helper_mtc0_hwrena(cpu_env, arg); 8161 ctx->base.is_jmp = DISAS_STOP; 8162 register_name = "HWREna"; 8163 break; 8164 default: 8165 goto cp0_unimplemented; 8166 } 8167 break; 8168 case CP0_REGISTER_08: 8169 switch (sel) { 8170 case CP0_REG08__BADVADDR: 8171 /* ignored */ 8172 register_name = "BadVAddr"; 8173 break; 8174 case CP0_REG08__BADINSTR: 8175 /* ignored */ 8176 register_name = "BadInstr"; 8177 break; 8178 case CP0_REG08__BADINSTRP: 8179 /* ignored */ 8180 register_name = "BadInstrP"; 8181 break; 8182 case CP0_REG08__BADINSTRX: 8183 /* ignored */ 8184 register_name = "BadInstrX"; 8185 break; 8186 default: 8187 goto cp0_unimplemented; 8188 } 8189 break; 8190 case CP0_REGISTER_09: 8191 switch (sel) { 8192 case CP0_REG09__COUNT: 8193 gen_helper_mtc0_count(cpu_env, arg); 8194 register_name = "Count"; 8195 break; 8196 case CP0_REG09__SAARI: 8197 CP0_CHECK(ctx->saar); 8198 gen_helper_mtc0_saari(cpu_env, arg); 8199 register_name = "SAARI"; 8200 break; 8201 case CP0_REG09__SAAR: 8202 CP0_CHECK(ctx->saar); 8203 gen_helper_mtc0_saar(cpu_env, arg); 8204 register_name = "SAAR"; 8205 break; 8206 default: 8207 goto cp0_unimplemented; 8208 } 8209 /* Stop translation as we may have switched the execution mode */ 8210 ctx->base.is_jmp = DISAS_STOP; 8211 break; 8212 case CP0_REGISTER_10: 8213 switch (sel) { 8214 case CP0_REG10__ENTRYHI: 8215 gen_helper_mtc0_entryhi(cpu_env, arg); 8216 register_name = "EntryHi"; 8217 break; 8218 default: 8219 goto cp0_unimplemented; 8220 } 8221 break; 8222 case CP0_REGISTER_11: 8223 switch (sel) { 8224 case CP0_REG11__COMPARE: 8225 gen_helper_mtc0_compare(cpu_env, arg); 8226 register_name = "Compare"; 8227 break; 8228 /* 6,7 are implementation dependent */ 8229 default: 8230 goto cp0_unimplemented; 8231 } 8232 /* Stop translation as we may have switched the execution mode */ 8233 ctx->base.is_jmp = DISAS_STOP; 8234 break; 8235 case CP0_REGISTER_12: 8236 switch (sel) { 8237 case CP0_REG12__STATUS: 8238 save_cpu_state(ctx, 1); 8239 gen_helper_mtc0_status(cpu_env, arg); 8240 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8241 gen_save_pc(ctx->base.pc_next + 4); 8242 ctx->base.is_jmp = DISAS_EXIT; 8243 register_name = "Status"; 8244 break; 8245 case CP0_REG12__INTCTL: 8246 check_insn(ctx, ISA_MIPS_R2); 8247 gen_helper_mtc0_intctl(cpu_env, arg); 8248 /* Stop translation as we may have switched the execution mode */ 8249 ctx->base.is_jmp = DISAS_STOP; 8250 register_name = "IntCtl"; 8251 break; 8252 case CP0_REG12__SRSCTL: 8253 check_insn(ctx, ISA_MIPS_R2); 8254 gen_helper_mtc0_srsctl(cpu_env, arg); 8255 /* Stop translation as we may have switched the execution mode */ 8256 ctx->base.is_jmp = DISAS_STOP; 8257 register_name = "SRSCtl"; 8258 break; 8259 case CP0_REG12__SRSMAP: 8260 check_insn(ctx, ISA_MIPS_R2); 8261 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8262 /* Stop translation as we may have switched the execution mode */ 8263 ctx->base.is_jmp = DISAS_STOP; 8264 register_name = "SRSMap"; 8265 break; 8266 default: 8267 goto cp0_unimplemented; 8268 } 8269 break; 8270 case CP0_REGISTER_13: 8271 switch (sel) { 8272 case CP0_REG13__CAUSE: 8273 save_cpu_state(ctx, 1); 8274 gen_helper_mtc0_cause(cpu_env, arg); 8275 /* 8276 * Stop translation as we may have triggered an interrupt. 8277 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8278 * translated code to check for pending interrupts. 8279 */ 8280 gen_save_pc(ctx->base.pc_next + 4); 8281 ctx->base.is_jmp = DISAS_EXIT; 8282 register_name = "Cause"; 8283 break; 8284 default: 8285 goto cp0_unimplemented; 8286 } 8287 break; 8288 case CP0_REGISTER_14: 8289 switch (sel) { 8290 case CP0_REG14__EPC: 8291 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8292 register_name = "EPC"; 8293 break; 8294 default: 8295 goto cp0_unimplemented; 8296 } 8297 break; 8298 case CP0_REGISTER_15: 8299 switch (sel) { 8300 case CP0_REG15__PRID: 8301 /* ignored */ 8302 register_name = "PRid"; 8303 break; 8304 case CP0_REG15__EBASE: 8305 check_insn(ctx, ISA_MIPS_R2); 8306 gen_helper_mtc0_ebase(cpu_env, arg); 8307 register_name = "EBase"; 8308 break; 8309 default: 8310 goto cp0_unimplemented; 8311 } 8312 break; 8313 case CP0_REGISTER_16: 8314 switch (sel) { 8315 case CP0_REG16__CONFIG: 8316 gen_helper_mtc0_config0(cpu_env, arg); 8317 register_name = "Config"; 8318 /* Stop translation as we may have switched the execution mode */ 8319 ctx->base.is_jmp = DISAS_STOP; 8320 break; 8321 case CP0_REG16__CONFIG1: 8322 /* ignored, read only */ 8323 register_name = "Config1"; 8324 break; 8325 case CP0_REG16__CONFIG2: 8326 gen_helper_mtc0_config2(cpu_env, arg); 8327 register_name = "Config2"; 8328 /* Stop translation as we may have switched the execution mode */ 8329 ctx->base.is_jmp = DISAS_STOP; 8330 break; 8331 case CP0_REG16__CONFIG3: 8332 gen_helper_mtc0_config3(cpu_env, arg); 8333 register_name = "Config3"; 8334 /* Stop translation as we may have switched the execution mode */ 8335 ctx->base.is_jmp = DISAS_STOP; 8336 break; 8337 case CP0_REG16__CONFIG4: 8338 /* currently ignored */ 8339 register_name = "Config4"; 8340 break; 8341 case CP0_REG16__CONFIG5: 8342 gen_helper_mtc0_config5(cpu_env, arg); 8343 register_name = "Config5"; 8344 /* Stop translation as we may have switched the execution mode */ 8345 ctx->base.is_jmp = DISAS_STOP; 8346 break; 8347 /* 6,7 are implementation dependent */ 8348 default: 8349 register_name = "Invalid config selector"; 8350 goto cp0_unimplemented; 8351 } 8352 break; 8353 case CP0_REGISTER_17: 8354 switch (sel) { 8355 case CP0_REG17__LLADDR: 8356 gen_helper_mtc0_lladdr(cpu_env, arg); 8357 register_name = "LLAddr"; 8358 break; 8359 case CP0_REG17__MAAR: 8360 CP0_CHECK(ctx->mrp); 8361 gen_helper_mtc0_maar(cpu_env, arg); 8362 register_name = "MAAR"; 8363 break; 8364 case CP0_REG17__MAARI: 8365 CP0_CHECK(ctx->mrp); 8366 gen_helper_mtc0_maari(cpu_env, arg); 8367 register_name = "MAARI"; 8368 break; 8369 default: 8370 goto cp0_unimplemented; 8371 } 8372 break; 8373 case CP0_REGISTER_18: 8374 switch (sel) { 8375 case CP0_REG18__WATCHLO0: 8376 case CP0_REG18__WATCHLO1: 8377 case CP0_REG18__WATCHLO2: 8378 case CP0_REG18__WATCHLO3: 8379 case CP0_REG18__WATCHLO4: 8380 case CP0_REG18__WATCHLO5: 8381 case CP0_REG18__WATCHLO6: 8382 case CP0_REG18__WATCHLO7: 8383 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8384 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8385 register_name = "WatchLo"; 8386 break; 8387 default: 8388 goto cp0_unimplemented; 8389 } 8390 break; 8391 case CP0_REGISTER_19: 8392 switch (sel) { 8393 case CP0_REG19__WATCHHI0: 8394 case CP0_REG19__WATCHHI1: 8395 case CP0_REG19__WATCHHI2: 8396 case CP0_REG19__WATCHHI3: 8397 case CP0_REG19__WATCHHI4: 8398 case CP0_REG19__WATCHHI5: 8399 case CP0_REG19__WATCHHI6: 8400 case CP0_REG19__WATCHHI7: 8401 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8402 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8403 register_name = "WatchHi"; 8404 break; 8405 default: 8406 goto cp0_unimplemented; 8407 } 8408 break; 8409 case CP0_REGISTER_20: 8410 switch (sel) { 8411 case CP0_REG20__XCONTEXT: 8412 check_insn(ctx, ISA_MIPS3); 8413 gen_helper_mtc0_xcontext(cpu_env, arg); 8414 register_name = "XContext"; 8415 break; 8416 default: 8417 goto cp0_unimplemented; 8418 } 8419 break; 8420 case CP0_REGISTER_21: 8421 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8422 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8423 switch (sel) { 8424 case 0: 8425 gen_helper_mtc0_framemask(cpu_env, arg); 8426 register_name = "Framemask"; 8427 break; 8428 default: 8429 goto cp0_unimplemented; 8430 } 8431 break; 8432 case CP0_REGISTER_22: 8433 /* ignored */ 8434 register_name = "Diagnostic"; /* implementation dependent */ 8435 break; 8436 case CP0_REGISTER_23: 8437 switch (sel) { 8438 case CP0_REG23__DEBUG: 8439 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8440 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8441 gen_save_pc(ctx->base.pc_next + 4); 8442 ctx->base.is_jmp = DISAS_EXIT; 8443 register_name = "Debug"; 8444 break; 8445 case CP0_REG23__TRACECONTROL: 8446 /* PDtrace support */ 8447 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8448 /* Stop translation as we may have switched the execution mode */ 8449 ctx->base.is_jmp = DISAS_STOP; 8450 register_name = "TraceControl"; 8451 goto cp0_unimplemented; 8452 case CP0_REG23__TRACECONTROL2: 8453 /* PDtrace support */ 8454 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8455 /* Stop translation as we may have switched the execution mode */ 8456 ctx->base.is_jmp = DISAS_STOP; 8457 register_name = "TraceControl2"; 8458 goto cp0_unimplemented; 8459 case CP0_REG23__USERTRACEDATA1: 8460 /* PDtrace support */ 8461 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8462 /* Stop translation as we may have switched the execution mode */ 8463 ctx->base.is_jmp = DISAS_STOP; 8464 register_name = "UserTraceData1"; 8465 goto cp0_unimplemented; 8466 case CP0_REG23__TRACEIBPC: 8467 /* PDtrace support */ 8468 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8469 /* Stop translation as we may have switched the execution mode */ 8470 ctx->base.is_jmp = DISAS_STOP; 8471 register_name = "TraceIBPC"; 8472 goto cp0_unimplemented; 8473 case CP0_REG23__TRACEDBPC: 8474 /* PDtrace support */ 8475 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8476 /* Stop translation as we may have switched the execution mode */ 8477 ctx->base.is_jmp = DISAS_STOP; 8478 register_name = "TraceDBPC"; 8479 goto cp0_unimplemented; 8480 default: 8481 goto cp0_unimplemented; 8482 } 8483 break; 8484 case CP0_REGISTER_24: 8485 switch (sel) { 8486 case CP0_REG24__DEPC: 8487 /* EJTAG support */ 8488 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8489 register_name = "DEPC"; 8490 break; 8491 default: 8492 goto cp0_unimplemented; 8493 } 8494 break; 8495 case CP0_REGISTER_25: 8496 switch (sel) { 8497 case CP0_REG25__PERFCTL0: 8498 gen_helper_mtc0_performance0(cpu_env, arg); 8499 register_name = "Performance0"; 8500 break; 8501 case CP0_REG25__PERFCNT0: 8502 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8503 register_name = "Performance1"; 8504 goto cp0_unimplemented; 8505 case CP0_REG25__PERFCTL1: 8506 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8507 register_name = "Performance2"; 8508 goto cp0_unimplemented; 8509 case CP0_REG25__PERFCNT1: 8510 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8511 register_name = "Performance3"; 8512 goto cp0_unimplemented; 8513 case CP0_REG25__PERFCTL2: 8514 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8515 register_name = "Performance4"; 8516 goto cp0_unimplemented; 8517 case CP0_REG25__PERFCNT2: 8518 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8519 register_name = "Performance5"; 8520 goto cp0_unimplemented; 8521 case CP0_REG25__PERFCTL3: 8522 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8523 register_name = "Performance6"; 8524 goto cp0_unimplemented; 8525 case CP0_REG25__PERFCNT3: 8526 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8527 register_name = "Performance7"; 8528 goto cp0_unimplemented; 8529 default: 8530 goto cp0_unimplemented; 8531 } 8532 break; 8533 case CP0_REGISTER_26: 8534 switch (sel) { 8535 case CP0_REG26__ERRCTL: 8536 gen_helper_mtc0_errctl(cpu_env, arg); 8537 ctx->base.is_jmp = DISAS_STOP; 8538 register_name = "ErrCtl"; 8539 break; 8540 default: 8541 goto cp0_unimplemented; 8542 } 8543 break; 8544 case CP0_REGISTER_27: 8545 switch (sel) { 8546 case CP0_REG27__CACHERR: 8547 /* ignored */ 8548 register_name = "CacheErr"; 8549 break; 8550 default: 8551 goto cp0_unimplemented; 8552 } 8553 break; 8554 case CP0_REGISTER_28: 8555 switch (sel) { 8556 case CP0_REG28__TAGLO: 8557 case CP0_REG28__TAGLO1: 8558 case CP0_REG28__TAGLO2: 8559 case CP0_REG28__TAGLO3: 8560 gen_helper_mtc0_taglo(cpu_env, arg); 8561 register_name = "TagLo"; 8562 break; 8563 case CP0_REG28__DATALO: 8564 case CP0_REG28__DATALO1: 8565 case CP0_REG28__DATALO2: 8566 case CP0_REG28__DATALO3: 8567 gen_helper_mtc0_datalo(cpu_env, arg); 8568 register_name = "DataLo"; 8569 break; 8570 default: 8571 goto cp0_unimplemented; 8572 } 8573 break; 8574 case CP0_REGISTER_29: 8575 switch (sel) { 8576 case CP0_REG29__TAGHI: 8577 case CP0_REG29__TAGHI1: 8578 case CP0_REG29__TAGHI2: 8579 case CP0_REG29__TAGHI3: 8580 gen_helper_mtc0_taghi(cpu_env, arg); 8581 register_name = "TagHi"; 8582 break; 8583 case CP0_REG29__DATAHI: 8584 case CP0_REG29__DATAHI1: 8585 case CP0_REG29__DATAHI2: 8586 case CP0_REG29__DATAHI3: 8587 gen_helper_mtc0_datahi(cpu_env, arg); 8588 register_name = "DataHi"; 8589 break; 8590 default: 8591 register_name = "invalid sel"; 8592 goto cp0_unimplemented; 8593 } 8594 break; 8595 case CP0_REGISTER_30: 8596 switch (sel) { 8597 case CP0_REG30__ERROREPC: 8598 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8599 register_name = "ErrorEPC"; 8600 break; 8601 default: 8602 goto cp0_unimplemented; 8603 } 8604 break; 8605 case CP0_REGISTER_31: 8606 switch (sel) { 8607 case CP0_REG31__DESAVE: 8608 /* EJTAG support */ 8609 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8610 register_name = "DESAVE"; 8611 break; 8612 case CP0_REG31__KSCRATCH1: 8613 case CP0_REG31__KSCRATCH2: 8614 case CP0_REG31__KSCRATCH3: 8615 case CP0_REG31__KSCRATCH4: 8616 case CP0_REG31__KSCRATCH5: 8617 case CP0_REG31__KSCRATCH6: 8618 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8619 tcg_gen_st_tl(arg, cpu_env, 8620 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8621 register_name = "KScratch"; 8622 break; 8623 default: 8624 goto cp0_unimplemented; 8625 } 8626 break; 8627 default: 8628 goto cp0_unimplemented; 8629 } 8630 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8631 8632 /* For simplicity assume that all writes can cause interrupts. */ 8633 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8634 /* 8635 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8636 * translated code to check for pending interrupts. 8637 */ 8638 gen_save_pc(ctx->base.pc_next + 4); 8639 ctx->base.is_jmp = DISAS_EXIT; 8640 } 8641 return; 8642 8643 cp0_unimplemented: 8644 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8645 register_name, reg, sel); 8646 } 8647 #endif /* TARGET_MIPS64 */ 8648 8649 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8650 int u, int sel, int h) 8651 { 8652 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8653 TCGv t0 = tcg_temp_local_new(); 8654 8655 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8656 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8657 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8658 tcg_gen_movi_tl(t0, -1); 8659 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8660 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8661 tcg_gen_movi_tl(t0, -1); 8662 } else if (u == 0) { 8663 switch (rt) { 8664 case 1: 8665 switch (sel) { 8666 case 1: 8667 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8668 break; 8669 case 2: 8670 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8671 break; 8672 default: 8673 goto die; 8674 break; 8675 } 8676 break; 8677 case 2: 8678 switch (sel) { 8679 case 1: 8680 gen_helper_mftc0_tcstatus(t0, cpu_env); 8681 break; 8682 case 2: 8683 gen_helper_mftc0_tcbind(t0, cpu_env); 8684 break; 8685 case 3: 8686 gen_helper_mftc0_tcrestart(t0, cpu_env); 8687 break; 8688 case 4: 8689 gen_helper_mftc0_tchalt(t0, cpu_env); 8690 break; 8691 case 5: 8692 gen_helper_mftc0_tccontext(t0, cpu_env); 8693 break; 8694 case 6: 8695 gen_helper_mftc0_tcschedule(t0, cpu_env); 8696 break; 8697 case 7: 8698 gen_helper_mftc0_tcschefback(t0, cpu_env); 8699 break; 8700 default: 8701 gen_mfc0(ctx, t0, rt, sel); 8702 break; 8703 } 8704 break; 8705 case 10: 8706 switch (sel) { 8707 case 0: 8708 gen_helper_mftc0_entryhi(t0, cpu_env); 8709 break; 8710 default: 8711 gen_mfc0(ctx, t0, rt, sel); 8712 break; 8713 } 8714 break; 8715 case 12: 8716 switch (sel) { 8717 case 0: 8718 gen_helper_mftc0_status(t0, cpu_env); 8719 break; 8720 default: 8721 gen_mfc0(ctx, t0, rt, sel); 8722 break; 8723 } 8724 break; 8725 case 13: 8726 switch (sel) { 8727 case 0: 8728 gen_helper_mftc0_cause(t0, cpu_env); 8729 break; 8730 default: 8731 goto die; 8732 break; 8733 } 8734 break; 8735 case 14: 8736 switch (sel) { 8737 case 0: 8738 gen_helper_mftc0_epc(t0, cpu_env); 8739 break; 8740 default: 8741 goto die; 8742 break; 8743 } 8744 break; 8745 case 15: 8746 switch (sel) { 8747 case 1: 8748 gen_helper_mftc0_ebase(t0, cpu_env); 8749 break; 8750 default: 8751 goto die; 8752 break; 8753 } 8754 break; 8755 case 16: 8756 switch (sel) { 8757 case 0: 8758 case 1: 8759 case 2: 8760 case 3: 8761 case 4: 8762 case 5: 8763 case 6: 8764 case 7: 8765 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 8766 break; 8767 default: 8768 goto die; 8769 break; 8770 } 8771 break; 8772 case 23: 8773 switch (sel) { 8774 case 0: 8775 gen_helper_mftc0_debug(t0, cpu_env); 8776 break; 8777 default: 8778 gen_mfc0(ctx, t0, rt, sel); 8779 break; 8780 } 8781 break; 8782 default: 8783 gen_mfc0(ctx, t0, rt, sel); 8784 } 8785 } else { 8786 switch (sel) { 8787 /* GPR registers. */ 8788 case 0: 8789 gen_helper_1e0i(mftgpr, t0, rt); 8790 break; 8791 /* Auxiliary CPU registers */ 8792 case 1: 8793 switch (rt) { 8794 case 0: 8795 gen_helper_1e0i(mftlo, t0, 0); 8796 break; 8797 case 1: 8798 gen_helper_1e0i(mfthi, t0, 0); 8799 break; 8800 case 2: 8801 gen_helper_1e0i(mftacx, t0, 0); 8802 break; 8803 case 4: 8804 gen_helper_1e0i(mftlo, t0, 1); 8805 break; 8806 case 5: 8807 gen_helper_1e0i(mfthi, t0, 1); 8808 break; 8809 case 6: 8810 gen_helper_1e0i(mftacx, t0, 1); 8811 break; 8812 case 8: 8813 gen_helper_1e0i(mftlo, t0, 2); 8814 break; 8815 case 9: 8816 gen_helper_1e0i(mfthi, t0, 2); 8817 break; 8818 case 10: 8819 gen_helper_1e0i(mftacx, t0, 2); 8820 break; 8821 case 12: 8822 gen_helper_1e0i(mftlo, t0, 3); 8823 break; 8824 case 13: 8825 gen_helper_1e0i(mfthi, t0, 3); 8826 break; 8827 case 14: 8828 gen_helper_1e0i(mftacx, t0, 3); 8829 break; 8830 case 16: 8831 gen_helper_mftdsp(t0, cpu_env); 8832 break; 8833 default: 8834 goto die; 8835 } 8836 break; 8837 /* Floating point (COP1). */ 8838 case 2: 8839 /* XXX: For now we support only a single FPU context. */ 8840 if (h == 0) { 8841 TCGv_i32 fp0 = tcg_temp_new_i32(); 8842 8843 gen_load_fpr32(ctx, fp0, rt); 8844 tcg_gen_ext_i32_tl(t0, fp0); 8845 tcg_temp_free_i32(fp0); 8846 } else { 8847 TCGv_i32 fp0 = tcg_temp_new_i32(); 8848 8849 gen_load_fpr32h(ctx, fp0, rt); 8850 tcg_gen_ext_i32_tl(t0, fp0); 8851 tcg_temp_free_i32(fp0); 8852 } 8853 break; 8854 case 3: 8855 /* XXX: For now we support only a single FPU context. */ 8856 gen_helper_1e0i(cfc1, t0, rt); 8857 break; 8858 /* COP2: Not implemented. */ 8859 case 4: 8860 case 5: 8861 /* fall through */ 8862 default: 8863 goto die; 8864 } 8865 } 8866 trace_mips_translate_tr("mftr", rt, u, sel, h); 8867 gen_store_gpr(t0, rd); 8868 tcg_temp_free(t0); 8869 return; 8870 8871 die: 8872 tcg_temp_free(t0); 8873 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8874 gen_reserved_instruction(ctx); 8875 } 8876 8877 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8878 int u, int sel, int h) 8879 { 8880 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8881 TCGv t0 = tcg_temp_local_new(); 8882 8883 gen_load_gpr(t0, rt); 8884 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8885 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8886 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8887 /* NOP */ 8888 ; 8889 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8890 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8891 /* NOP */ 8892 ; 8893 } else if (u == 0) { 8894 switch (rd) { 8895 case 1: 8896 switch (sel) { 8897 case 1: 8898 gen_helper_mttc0_vpecontrol(cpu_env, t0); 8899 break; 8900 case 2: 8901 gen_helper_mttc0_vpeconf0(cpu_env, t0); 8902 break; 8903 default: 8904 goto die; 8905 break; 8906 } 8907 break; 8908 case 2: 8909 switch (sel) { 8910 case 1: 8911 gen_helper_mttc0_tcstatus(cpu_env, t0); 8912 break; 8913 case 2: 8914 gen_helper_mttc0_tcbind(cpu_env, t0); 8915 break; 8916 case 3: 8917 gen_helper_mttc0_tcrestart(cpu_env, t0); 8918 break; 8919 case 4: 8920 gen_helper_mttc0_tchalt(cpu_env, t0); 8921 break; 8922 case 5: 8923 gen_helper_mttc0_tccontext(cpu_env, t0); 8924 break; 8925 case 6: 8926 gen_helper_mttc0_tcschedule(cpu_env, t0); 8927 break; 8928 case 7: 8929 gen_helper_mttc0_tcschefback(cpu_env, t0); 8930 break; 8931 default: 8932 gen_mtc0(ctx, t0, rd, sel); 8933 break; 8934 } 8935 break; 8936 case 10: 8937 switch (sel) { 8938 case 0: 8939 gen_helper_mttc0_entryhi(cpu_env, t0); 8940 break; 8941 default: 8942 gen_mtc0(ctx, t0, rd, sel); 8943 break; 8944 } 8945 break; 8946 case 12: 8947 switch (sel) { 8948 case 0: 8949 gen_helper_mttc0_status(cpu_env, t0); 8950 break; 8951 default: 8952 gen_mtc0(ctx, t0, rd, sel); 8953 break; 8954 } 8955 break; 8956 case 13: 8957 switch (sel) { 8958 case 0: 8959 gen_helper_mttc0_cause(cpu_env, t0); 8960 break; 8961 default: 8962 goto die; 8963 break; 8964 } 8965 break; 8966 case 15: 8967 switch (sel) { 8968 case 1: 8969 gen_helper_mttc0_ebase(cpu_env, t0); 8970 break; 8971 default: 8972 goto die; 8973 break; 8974 } 8975 break; 8976 case 23: 8977 switch (sel) { 8978 case 0: 8979 gen_helper_mttc0_debug(cpu_env, t0); 8980 break; 8981 default: 8982 gen_mtc0(ctx, t0, rd, sel); 8983 break; 8984 } 8985 break; 8986 default: 8987 gen_mtc0(ctx, t0, rd, sel); 8988 } 8989 } else { 8990 switch (sel) { 8991 /* GPR registers. */ 8992 case 0: 8993 gen_helper_0e1i(mttgpr, t0, rd); 8994 break; 8995 /* Auxiliary CPU registers */ 8996 case 1: 8997 switch (rd) { 8998 case 0: 8999 gen_helper_0e1i(mttlo, t0, 0); 9000 break; 9001 case 1: 9002 gen_helper_0e1i(mtthi, t0, 0); 9003 break; 9004 case 2: 9005 gen_helper_0e1i(mttacx, t0, 0); 9006 break; 9007 case 4: 9008 gen_helper_0e1i(mttlo, t0, 1); 9009 break; 9010 case 5: 9011 gen_helper_0e1i(mtthi, t0, 1); 9012 break; 9013 case 6: 9014 gen_helper_0e1i(mttacx, t0, 1); 9015 break; 9016 case 8: 9017 gen_helper_0e1i(mttlo, t0, 2); 9018 break; 9019 case 9: 9020 gen_helper_0e1i(mtthi, t0, 2); 9021 break; 9022 case 10: 9023 gen_helper_0e1i(mttacx, t0, 2); 9024 break; 9025 case 12: 9026 gen_helper_0e1i(mttlo, t0, 3); 9027 break; 9028 case 13: 9029 gen_helper_0e1i(mtthi, t0, 3); 9030 break; 9031 case 14: 9032 gen_helper_0e1i(mttacx, t0, 3); 9033 break; 9034 case 16: 9035 gen_helper_mttdsp(cpu_env, t0); 9036 break; 9037 default: 9038 goto die; 9039 } 9040 break; 9041 /* Floating point (COP1). */ 9042 case 2: 9043 /* XXX: For now we support only a single FPU context. */ 9044 if (h == 0) { 9045 TCGv_i32 fp0 = tcg_temp_new_i32(); 9046 9047 tcg_gen_trunc_tl_i32(fp0, t0); 9048 gen_store_fpr32(ctx, fp0, rd); 9049 tcg_temp_free_i32(fp0); 9050 } else { 9051 TCGv_i32 fp0 = tcg_temp_new_i32(); 9052 9053 tcg_gen_trunc_tl_i32(fp0, t0); 9054 gen_store_fpr32h(ctx, fp0, rd); 9055 tcg_temp_free_i32(fp0); 9056 } 9057 break; 9058 case 3: 9059 /* XXX: For now we support only a single FPU context. */ 9060 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 9061 /* Stop translation as we may have changed hflags */ 9062 ctx->base.is_jmp = DISAS_STOP; 9063 break; 9064 /* COP2: Not implemented. */ 9065 case 4: 9066 case 5: 9067 /* fall through */ 9068 default: 9069 goto die; 9070 } 9071 } 9072 trace_mips_translate_tr("mttr", rd, u, sel, h); 9073 tcg_temp_free(t0); 9074 return; 9075 9076 die: 9077 tcg_temp_free(t0); 9078 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9079 gen_reserved_instruction(ctx); 9080 } 9081 9082 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9083 int rt, int rd) 9084 { 9085 const char *opn = "ldst"; 9086 9087 check_cp0_enabled(ctx); 9088 switch (opc) { 9089 case OPC_MFC0: 9090 if (rt == 0) { 9091 /* Treat as NOP. */ 9092 return; 9093 } 9094 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9095 opn = "mfc0"; 9096 break; 9097 case OPC_MTC0: 9098 { 9099 TCGv t0 = tcg_temp_new(); 9100 9101 gen_load_gpr(t0, rt); 9102 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9103 tcg_temp_free(t0); 9104 } 9105 opn = "mtc0"; 9106 break; 9107 #if defined(TARGET_MIPS64) 9108 case OPC_DMFC0: 9109 check_insn(ctx, ISA_MIPS3); 9110 if (rt == 0) { 9111 /* Treat as NOP. */ 9112 return; 9113 } 9114 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9115 opn = "dmfc0"; 9116 break; 9117 case OPC_DMTC0: 9118 check_insn(ctx, ISA_MIPS3); 9119 { 9120 TCGv t0 = tcg_temp_new(); 9121 9122 gen_load_gpr(t0, rt); 9123 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9124 tcg_temp_free(t0); 9125 } 9126 opn = "dmtc0"; 9127 break; 9128 #endif 9129 case OPC_MFHC0: 9130 check_mvh(ctx); 9131 if (rt == 0) { 9132 /* Treat as NOP. */ 9133 return; 9134 } 9135 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9136 opn = "mfhc0"; 9137 break; 9138 case OPC_MTHC0: 9139 check_mvh(ctx); 9140 { 9141 TCGv t0 = tcg_temp_new(); 9142 gen_load_gpr(t0, rt); 9143 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9144 tcg_temp_free(t0); 9145 } 9146 opn = "mthc0"; 9147 break; 9148 case OPC_MFTR: 9149 check_cp0_enabled(ctx); 9150 if (rd == 0) { 9151 /* Treat as NOP. */ 9152 return; 9153 } 9154 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9155 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9156 opn = "mftr"; 9157 break; 9158 case OPC_MTTR: 9159 check_cp0_enabled(ctx); 9160 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9161 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9162 opn = "mttr"; 9163 break; 9164 case OPC_TLBWI: 9165 opn = "tlbwi"; 9166 if (!env->tlb->helper_tlbwi) { 9167 goto die; 9168 } 9169 gen_helper_tlbwi(cpu_env); 9170 break; 9171 case OPC_TLBINV: 9172 opn = "tlbinv"; 9173 if (ctx->ie >= 2) { 9174 if (!env->tlb->helper_tlbinv) { 9175 goto die; 9176 } 9177 gen_helper_tlbinv(cpu_env); 9178 } /* treat as nop if TLBINV not supported */ 9179 break; 9180 case OPC_TLBINVF: 9181 opn = "tlbinvf"; 9182 if (ctx->ie >= 2) { 9183 if (!env->tlb->helper_tlbinvf) { 9184 goto die; 9185 } 9186 gen_helper_tlbinvf(cpu_env); 9187 } /* treat as nop if TLBINV not supported */ 9188 break; 9189 case OPC_TLBWR: 9190 opn = "tlbwr"; 9191 if (!env->tlb->helper_tlbwr) { 9192 goto die; 9193 } 9194 gen_helper_tlbwr(cpu_env); 9195 break; 9196 case OPC_TLBP: 9197 opn = "tlbp"; 9198 if (!env->tlb->helper_tlbp) { 9199 goto die; 9200 } 9201 gen_helper_tlbp(cpu_env); 9202 break; 9203 case OPC_TLBR: 9204 opn = "tlbr"; 9205 if (!env->tlb->helper_tlbr) { 9206 goto die; 9207 } 9208 gen_helper_tlbr(cpu_env); 9209 break; 9210 case OPC_ERET: /* OPC_ERETNC */ 9211 if ((ctx->insn_flags & ISA_MIPS_R6) && 9212 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9213 goto die; 9214 } else { 9215 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9216 if (ctx->opcode & (1 << bit_shift)) { 9217 /* OPC_ERETNC */ 9218 opn = "eretnc"; 9219 check_insn(ctx, ISA_MIPS_R5); 9220 gen_helper_eretnc(cpu_env); 9221 } else { 9222 /* OPC_ERET */ 9223 opn = "eret"; 9224 check_insn(ctx, ISA_MIPS2); 9225 gen_helper_eret(cpu_env); 9226 } 9227 ctx->base.is_jmp = DISAS_EXIT; 9228 } 9229 break; 9230 case OPC_DERET: 9231 opn = "deret"; 9232 check_insn(ctx, ISA_MIPS_R1); 9233 if ((ctx->insn_flags & ISA_MIPS_R6) && 9234 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9235 goto die; 9236 } 9237 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9238 MIPS_INVAL(opn); 9239 gen_reserved_instruction(ctx); 9240 } else { 9241 gen_helper_deret(cpu_env); 9242 ctx->base.is_jmp = DISAS_EXIT; 9243 } 9244 break; 9245 case OPC_WAIT: 9246 opn = "wait"; 9247 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9248 if ((ctx->insn_flags & ISA_MIPS_R6) && 9249 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9250 goto die; 9251 } 9252 /* If we get an exception, we want to restart at next instruction */ 9253 ctx->base.pc_next += 4; 9254 save_cpu_state(ctx, 1); 9255 ctx->base.pc_next -= 4; 9256 gen_helper_wait(cpu_env); 9257 ctx->base.is_jmp = DISAS_NORETURN; 9258 break; 9259 default: 9260 die: 9261 MIPS_INVAL(opn); 9262 gen_reserved_instruction(ctx); 9263 return; 9264 } 9265 (void)opn; /* avoid a compiler warning */ 9266 } 9267 #endif /* !CONFIG_USER_ONLY */ 9268 9269 /* CP1 Branches (before delay slot) */ 9270 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9271 int32_t cc, int32_t offset) 9272 { 9273 target_ulong btarget; 9274 TCGv_i32 t0 = tcg_temp_new_i32(); 9275 9276 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9277 gen_reserved_instruction(ctx); 9278 goto out; 9279 } 9280 9281 if (cc != 0) { 9282 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9283 } 9284 9285 btarget = ctx->base.pc_next + 4 + offset; 9286 9287 switch (op) { 9288 case OPC_BC1F: 9289 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9290 tcg_gen_not_i32(t0, t0); 9291 tcg_gen_andi_i32(t0, t0, 1); 9292 tcg_gen_extu_i32_tl(bcond, t0); 9293 goto not_likely; 9294 case OPC_BC1FL: 9295 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9296 tcg_gen_not_i32(t0, t0); 9297 tcg_gen_andi_i32(t0, t0, 1); 9298 tcg_gen_extu_i32_tl(bcond, t0); 9299 goto likely; 9300 case OPC_BC1T: 9301 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9302 tcg_gen_andi_i32(t0, t0, 1); 9303 tcg_gen_extu_i32_tl(bcond, t0); 9304 goto not_likely; 9305 case OPC_BC1TL: 9306 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9307 tcg_gen_andi_i32(t0, t0, 1); 9308 tcg_gen_extu_i32_tl(bcond, t0); 9309 likely: 9310 ctx->hflags |= MIPS_HFLAG_BL; 9311 break; 9312 case OPC_BC1FANY2: 9313 { 9314 TCGv_i32 t1 = tcg_temp_new_i32(); 9315 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9316 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9317 tcg_gen_nand_i32(t0, t0, t1); 9318 tcg_temp_free_i32(t1); 9319 tcg_gen_andi_i32(t0, t0, 1); 9320 tcg_gen_extu_i32_tl(bcond, t0); 9321 } 9322 goto not_likely; 9323 case OPC_BC1TANY2: 9324 { 9325 TCGv_i32 t1 = tcg_temp_new_i32(); 9326 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9327 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9328 tcg_gen_or_i32(t0, t0, t1); 9329 tcg_temp_free_i32(t1); 9330 tcg_gen_andi_i32(t0, t0, 1); 9331 tcg_gen_extu_i32_tl(bcond, t0); 9332 } 9333 goto not_likely; 9334 case OPC_BC1FANY4: 9335 { 9336 TCGv_i32 t1 = tcg_temp_new_i32(); 9337 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9338 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9339 tcg_gen_and_i32(t0, t0, t1); 9340 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9341 tcg_gen_and_i32(t0, t0, t1); 9342 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9343 tcg_gen_nand_i32(t0, t0, t1); 9344 tcg_temp_free_i32(t1); 9345 tcg_gen_andi_i32(t0, t0, 1); 9346 tcg_gen_extu_i32_tl(bcond, t0); 9347 } 9348 goto not_likely; 9349 case OPC_BC1TANY4: 9350 { 9351 TCGv_i32 t1 = tcg_temp_new_i32(); 9352 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9353 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9354 tcg_gen_or_i32(t0, t0, t1); 9355 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9356 tcg_gen_or_i32(t0, t0, t1); 9357 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9358 tcg_gen_or_i32(t0, t0, t1); 9359 tcg_temp_free_i32(t1); 9360 tcg_gen_andi_i32(t0, t0, 1); 9361 tcg_gen_extu_i32_tl(bcond, t0); 9362 } 9363 not_likely: 9364 ctx->hflags |= MIPS_HFLAG_BC; 9365 break; 9366 default: 9367 MIPS_INVAL("cp1 cond branch"); 9368 gen_reserved_instruction(ctx); 9369 goto out; 9370 } 9371 ctx->btarget = btarget; 9372 ctx->hflags |= MIPS_HFLAG_BDS32; 9373 out: 9374 tcg_temp_free_i32(t0); 9375 } 9376 9377 /* R6 CP1 Branches */ 9378 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9379 int32_t ft, int32_t offset, 9380 int delayslot_size) 9381 { 9382 target_ulong btarget; 9383 TCGv_i64 t0 = tcg_temp_new_i64(); 9384 9385 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9386 #ifdef MIPS_DEBUG_DISAS 9387 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9388 "\n", ctx->base.pc_next); 9389 #endif 9390 gen_reserved_instruction(ctx); 9391 goto out; 9392 } 9393 9394 gen_load_fpr64(ctx, t0, ft); 9395 tcg_gen_andi_i64(t0, t0, 1); 9396 9397 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9398 9399 switch (op) { 9400 case OPC_BC1EQZ: 9401 tcg_gen_xori_i64(t0, t0, 1); 9402 ctx->hflags |= MIPS_HFLAG_BC; 9403 break; 9404 case OPC_BC1NEZ: 9405 /* t0 already set */ 9406 ctx->hflags |= MIPS_HFLAG_BC; 9407 break; 9408 default: 9409 MIPS_INVAL("cp1 cond branch"); 9410 gen_reserved_instruction(ctx); 9411 goto out; 9412 } 9413 9414 tcg_gen_trunc_i64_tl(bcond, t0); 9415 9416 ctx->btarget = btarget; 9417 9418 switch (delayslot_size) { 9419 case 2: 9420 ctx->hflags |= MIPS_HFLAG_BDS16; 9421 break; 9422 case 4: 9423 ctx->hflags |= MIPS_HFLAG_BDS32; 9424 break; 9425 } 9426 9427 out: 9428 tcg_temp_free_i64(t0); 9429 } 9430 9431 /* Coprocessor 1 (FPU) */ 9432 9433 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9434 9435 enum fopcode { 9436 OPC_ADD_S = FOP(0, FMT_S), 9437 OPC_SUB_S = FOP(1, FMT_S), 9438 OPC_MUL_S = FOP(2, FMT_S), 9439 OPC_DIV_S = FOP(3, FMT_S), 9440 OPC_SQRT_S = FOP(4, FMT_S), 9441 OPC_ABS_S = FOP(5, FMT_S), 9442 OPC_MOV_S = FOP(6, FMT_S), 9443 OPC_NEG_S = FOP(7, FMT_S), 9444 OPC_ROUND_L_S = FOP(8, FMT_S), 9445 OPC_TRUNC_L_S = FOP(9, FMT_S), 9446 OPC_CEIL_L_S = FOP(10, FMT_S), 9447 OPC_FLOOR_L_S = FOP(11, FMT_S), 9448 OPC_ROUND_W_S = FOP(12, FMT_S), 9449 OPC_TRUNC_W_S = FOP(13, FMT_S), 9450 OPC_CEIL_W_S = FOP(14, FMT_S), 9451 OPC_FLOOR_W_S = FOP(15, FMT_S), 9452 OPC_SEL_S = FOP(16, FMT_S), 9453 OPC_MOVCF_S = FOP(17, FMT_S), 9454 OPC_MOVZ_S = FOP(18, FMT_S), 9455 OPC_MOVN_S = FOP(19, FMT_S), 9456 OPC_SELEQZ_S = FOP(20, FMT_S), 9457 OPC_RECIP_S = FOP(21, FMT_S), 9458 OPC_RSQRT_S = FOP(22, FMT_S), 9459 OPC_SELNEZ_S = FOP(23, FMT_S), 9460 OPC_MADDF_S = FOP(24, FMT_S), 9461 OPC_MSUBF_S = FOP(25, FMT_S), 9462 OPC_RINT_S = FOP(26, FMT_S), 9463 OPC_CLASS_S = FOP(27, FMT_S), 9464 OPC_MIN_S = FOP(28, FMT_S), 9465 OPC_RECIP2_S = FOP(28, FMT_S), 9466 OPC_MINA_S = FOP(29, FMT_S), 9467 OPC_RECIP1_S = FOP(29, FMT_S), 9468 OPC_MAX_S = FOP(30, FMT_S), 9469 OPC_RSQRT1_S = FOP(30, FMT_S), 9470 OPC_MAXA_S = FOP(31, FMT_S), 9471 OPC_RSQRT2_S = FOP(31, FMT_S), 9472 OPC_CVT_D_S = FOP(33, FMT_S), 9473 OPC_CVT_W_S = FOP(36, FMT_S), 9474 OPC_CVT_L_S = FOP(37, FMT_S), 9475 OPC_CVT_PS_S = FOP(38, FMT_S), 9476 OPC_CMP_F_S = FOP(48, FMT_S), 9477 OPC_CMP_UN_S = FOP(49, FMT_S), 9478 OPC_CMP_EQ_S = FOP(50, FMT_S), 9479 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9480 OPC_CMP_OLT_S = FOP(52, FMT_S), 9481 OPC_CMP_ULT_S = FOP(53, FMT_S), 9482 OPC_CMP_OLE_S = FOP(54, FMT_S), 9483 OPC_CMP_ULE_S = FOP(55, FMT_S), 9484 OPC_CMP_SF_S = FOP(56, FMT_S), 9485 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9486 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9487 OPC_CMP_NGL_S = FOP(59, FMT_S), 9488 OPC_CMP_LT_S = FOP(60, FMT_S), 9489 OPC_CMP_NGE_S = FOP(61, FMT_S), 9490 OPC_CMP_LE_S = FOP(62, FMT_S), 9491 OPC_CMP_NGT_S = FOP(63, FMT_S), 9492 9493 OPC_ADD_D = FOP(0, FMT_D), 9494 OPC_SUB_D = FOP(1, FMT_D), 9495 OPC_MUL_D = FOP(2, FMT_D), 9496 OPC_DIV_D = FOP(3, FMT_D), 9497 OPC_SQRT_D = FOP(4, FMT_D), 9498 OPC_ABS_D = FOP(5, FMT_D), 9499 OPC_MOV_D = FOP(6, FMT_D), 9500 OPC_NEG_D = FOP(7, FMT_D), 9501 OPC_ROUND_L_D = FOP(8, FMT_D), 9502 OPC_TRUNC_L_D = FOP(9, FMT_D), 9503 OPC_CEIL_L_D = FOP(10, FMT_D), 9504 OPC_FLOOR_L_D = FOP(11, FMT_D), 9505 OPC_ROUND_W_D = FOP(12, FMT_D), 9506 OPC_TRUNC_W_D = FOP(13, FMT_D), 9507 OPC_CEIL_W_D = FOP(14, FMT_D), 9508 OPC_FLOOR_W_D = FOP(15, FMT_D), 9509 OPC_SEL_D = FOP(16, FMT_D), 9510 OPC_MOVCF_D = FOP(17, FMT_D), 9511 OPC_MOVZ_D = FOP(18, FMT_D), 9512 OPC_MOVN_D = FOP(19, FMT_D), 9513 OPC_SELEQZ_D = FOP(20, FMT_D), 9514 OPC_RECIP_D = FOP(21, FMT_D), 9515 OPC_RSQRT_D = FOP(22, FMT_D), 9516 OPC_SELNEZ_D = FOP(23, FMT_D), 9517 OPC_MADDF_D = FOP(24, FMT_D), 9518 OPC_MSUBF_D = FOP(25, FMT_D), 9519 OPC_RINT_D = FOP(26, FMT_D), 9520 OPC_CLASS_D = FOP(27, FMT_D), 9521 OPC_MIN_D = FOP(28, FMT_D), 9522 OPC_RECIP2_D = FOP(28, FMT_D), 9523 OPC_MINA_D = FOP(29, FMT_D), 9524 OPC_RECIP1_D = FOP(29, FMT_D), 9525 OPC_MAX_D = FOP(30, FMT_D), 9526 OPC_RSQRT1_D = FOP(30, FMT_D), 9527 OPC_MAXA_D = FOP(31, FMT_D), 9528 OPC_RSQRT2_D = FOP(31, FMT_D), 9529 OPC_CVT_S_D = FOP(32, FMT_D), 9530 OPC_CVT_W_D = FOP(36, FMT_D), 9531 OPC_CVT_L_D = FOP(37, FMT_D), 9532 OPC_CMP_F_D = FOP(48, FMT_D), 9533 OPC_CMP_UN_D = FOP(49, FMT_D), 9534 OPC_CMP_EQ_D = FOP(50, FMT_D), 9535 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9536 OPC_CMP_OLT_D = FOP(52, FMT_D), 9537 OPC_CMP_ULT_D = FOP(53, FMT_D), 9538 OPC_CMP_OLE_D = FOP(54, FMT_D), 9539 OPC_CMP_ULE_D = FOP(55, FMT_D), 9540 OPC_CMP_SF_D = FOP(56, FMT_D), 9541 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9542 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9543 OPC_CMP_NGL_D = FOP(59, FMT_D), 9544 OPC_CMP_LT_D = FOP(60, FMT_D), 9545 OPC_CMP_NGE_D = FOP(61, FMT_D), 9546 OPC_CMP_LE_D = FOP(62, FMT_D), 9547 OPC_CMP_NGT_D = FOP(63, FMT_D), 9548 9549 OPC_CVT_S_W = FOP(32, FMT_W), 9550 OPC_CVT_D_W = FOP(33, FMT_W), 9551 OPC_CVT_S_L = FOP(32, FMT_L), 9552 OPC_CVT_D_L = FOP(33, FMT_L), 9553 OPC_CVT_PS_PW = FOP(38, FMT_W), 9554 9555 OPC_ADD_PS = FOP(0, FMT_PS), 9556 OPC_SUB_PS = FOP(1, FMT_PS), 9557 OPC_MUL_PS = FOP(2, FMT_PS), 9558 OPC_DIV_PS = FOP(3, FMT_PS), 9559 OPC_ABS_PS = FOP(5, FMT_PS), 9560 OPC_MOV_PS = FOP(6, FMT_PS), 9561 OPC_NEG_PS = FOP(7, FMT_PS), 9562 OPC_MOVCF_PS = FOP(17, FMT_PS), 9563 OPC_MOVZ_PS = FOP(18, FMT_PS), 9564 OPC_MOVN_PS = FOP(19, FMT_PS), 9565 OPC_ADDR_PS = FOP(24, FMT_PS), 9566 OPC_MULR_PS = FOP(26, FMT_PS), 9567 OPC_RECIP2_PS = FOP(28, FMT_PS), 9568 OPC_RECIP1_PS = FOP(29, FMT_PS), 9569 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9570 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9571 9572 OPC_CVT_S_PU = FOP(32, FMT_PS), 9573 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9574 OPC_CVT_S_PL = FOP(40, FMT_PS), 9575 OPC_PLL_PS = FOP(44, FMT_PS), 9576 OPC_PLU_PS = FOP(45, FMT_PS), 9577 OPC_PUL_PS = FOP(46, FMT_PS), 9578 OPC_PUU_PS = FOP(47, FMT_PS), 9579 OPC_CMP_F_PS = FOP(48, FMT_PS), 9580 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9581 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9582 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9583 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9584 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9585 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9586 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9587 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9588 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9589 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9590 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9591 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9592 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9593 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9594 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9595 }; 9596 9597 enum r6_f_cmp_op { 9598 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9599 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9600 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9601 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9602 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9603 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9604 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9605 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9606 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9607 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9608 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9609 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9610 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9611 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9612 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9613 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9614 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9615 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9616 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9617 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9618 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9619 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9620 9621 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9622 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9623 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9624 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9625 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9626 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9627 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9628 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9629 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9630 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9631 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9632 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9633 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9634 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9635 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9636 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9637 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9638 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9639 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9640 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9641 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9642 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9643 }; 9644 9645 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9646 { 9647 TCGv t0 = tcg_temp_new(); 9648 9649 switch (opc) { 9650 case OPC_MFC1: 9651 { 9652 TCGv_i32 fp0 = tcg_temp_new_i32(); 9653 9654 gen_load_fpr32(ctx, fp0, fs); 9655 tcg_gen_ext_i32_tl(t0, fp0); 9656 tcg_temp_free_i32(fp0); 9657 } 9658 gen_store_gpr(t0, rt); 9659 break; 9660 case OPC_MTC1: 9661 gen_load_gpr(t0, rt); 9662 { 9663 TCGv_i32 fp0 = tcg_temp_new_i32(); 9664 9665 tcg_gen_trunc_tl_i32(fp0, t0); 9666 gen_store_fpr32(ctx, fp0, fs); 9667 tcg_temp_free_i32(fp0); 9668 } 9669 break; 9670 case OPC_CFC1: 9671 gen_helper_1e0i(cfc1, t0, fs); 9672 gen_store_gpr(t0, rt); 9673 break; 9674 case OPC_CTC1: 9675 gen_load_gpr(t0, rt); 9676 save_cpu_state(ctx, 0); 9677 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9678 /* Stop translation as we may have changed hflags */ 9679 ctx->base.is_jmp = DISAS_STOP; 9680 break; 9681 #if defined(TARGET_MIPS64) 9682 case OPC_DMFC1: 9683 gen_load_fpr64(ctx, t0, fs); 9684 gen_store_gpr(t0, rt); 9685 break; 9686 case OPC_DMTC1: 9687 gen_load_gpr(t0, rt); 9688 gen_store_fpr64(ctx, t0, fs); 9689 break; 9690 #endif 9691 case OPC_MFHC1: 9692 { 9693 TCGv_i32 fp0 = tcg_temp_new_i32(); 9694 9695 gen_load_fpr32h(ctx, fp0, fs); 9696 tcg_gen_ext_i32_tl(t0, fp0); 9697 tcg_temp_free_i32(fp0); 9698 } 9699 gen_store_gpr(t0, rt); 9700 break; 9701 case OPC_MTHC1: 9702 gen_load_gpr(t0, rt); 9703 { 9704 TCGv_i32 fp0 = tcg_temp_new_i32(); 9705 9706 tcg_gen_trunc_tl_i32(fp0, t0); 9707 gen_store_fpr32h(ctx, fp0, fs); 9708 tcg_temp_free_i32(fp0); 9709 } 9710 break; 9711 default: 9712 MIPS_INVAL("cp1 move"); 9713 gen_reserved_instruction(ctx); 9714 goto out; 9715 } 9716 9717 out: 9718 tcg_temp_free(t0); 9719 } 9720 9721 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9722 { 9723 TCGLabel *l1; 9724 TCGCond cond; 9725 TCGv_i32 t0; 9726 9727 if (rd == 0) { 9728 /* Treat as NOP. */ 9729 return; 9730 } 9731 9732 if (tf) { 9733 cond = TCG_COND_EQ; 9734 } else { 9735 cond = TCG_COND_NE; 9736 } 9737 9738 l1 = gen_new_label(); 9739 t0 = tcg_temp_new_i32(); 9740 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9741 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9742 tcg_temp_free_i32(t0); 9743 gen_load_gpr(cpu_gpr[rd], rs); 9744 gen_set_label(l1); 9745 } 9746 9747 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9748 int tf) 9749 { 9750 int cond; 9751 TCGv_i32 t0 = tcg_temp_new_i32(); 9752 TCGLabel *l1 = gen_new_label(); 9753 9754 if (tf) { 9755 cond = TCG_COND_EQ; 9756 } else { 9757 cond = TCG_COND_NE; 9758 } 9759 9760 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9761 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9762 gen_load_fpr32(ctx, t0, fs); 9763 gen_store_fpr32(ctx, t0, fd); 9764 gen_set_label(l1); 9765 tcg_temp_free_i32(t0); 9766 } 9767 9768 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9769 int tf) 9770 { 9771 int cond; 9772 TCGv_i32 t0 = tcg_temp_new_i32(); 9773 TCGv_i64 fp0; 9774 TCGLabel *l1 = gen_new_label(); 9775 9776 if (tf) { 9777 cond = TCG_COND_EQ; 9778 } else { 9779 cond = TCG_COND_NE; 9780 } 9781 9782 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9783 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9784 tcg_temp_free_i32(t0); 9785 fp0 = tcg_temp_new_i64(); 9786 gen_load_fpr64(ctx, fp0, fs); 9787 gen_store_fpr64(ctx, fp0, fd); 9788 tcg_temp_free_i64(fp0); 9789 gen_set_label(l1); 9790 } 9791 9792 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9793 int cc, int tf) 9794 { 9795 int cond; 9796 TCGv_i32 t0 = tcg_temp_new_i32(); 9797 TCGLabel *l1 = gen_new_label(); 9798 TCGLabel *l2 = gen_new_label(); 9799 9800 if (tf) { 9801 cond = TCG_COND_EQ; 9802 } else { 9803 cond = TCG_COND_NE; 9804 } 9805 9806 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9807 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9808 gen_load_fpr32(ctx, t0, fs); 9809 gen_store_fpr32(ctx, t0, fd); 9810 gen_set_label(l1); 9811 9812 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9813 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9814 gen_load_fpr32h(ctx, t0, fs); 9815 gen_store_fpr32h(ctx, t0, fd); 9816 tcg_temp_free_i32(t0); 9817 gen_set_label(l2); 9818 } 9819 9820 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9821 int fs) 9822 { 9823 TCGv_i32 t1 = tcg_const_i32(0); 9824 TCGv_i32 fp0 = tcg_temp_new_i32(); 9825 TCGv_i32 fp1 = tcg_temp_new_i32(); 9826 TCGv_i32 fp2 = tcg_temp_new_i32(); 9827 gen_load_fpr32(ctx, fp0, fd); 9828 gen_load_fpr32(ctx, fp1, ft); 9829 gen_load_fpr32(ctx, fp2, fs); 9830 9831 switch (op1) { 9832 case OPC_SEL_S: 9833 tcg_gen_andi_i32(fp0, fp0, 1); 9834 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9835 break; 9836 case OPC_SELEQZ_S: 9837 tcg_gen_andi_i32(fp1, fp1, 1); 9838 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9839 break; 9840 case OPC_SELNEZ_S: 9841 tcg_gen_andi_i32(fp1, fp1, 1); 9842 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9843 break; 9844 default: 9845 MIPS_INVAL("gen_sel_s"); 9846 gen_reserved_instruction(ctx); 9847 break; 9848 } 9849 9850 gen_store_fpr32(ctx, fp0, fd); 9851 tcg_temp_free_i32(fp2); 9852 tcg_temp_free_i32(fp1); 9853 tcg_temp_free_i32(fp0); 9854 tcg_temp_free_i32(t1); 9855 } 9856 9857 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9858 int fs) 9859 { 9860 TCGv_i64 t1 = tcg_const_i64(0); 9861 TCGv_i64 fp0 = tcg_temp_new_i64(); 9862 TCGv_i64 fp1 = tcg_temp_new_i64(); 9863 TCGv_i64 fp2 = tcg_temp_new_i64(); 9864 gen_load_fpr64(ctx, fp0, fd); 9865 gen_load_fpr64(ctx, fp1, ft); 9866 gen_load_fpr64(ctx, fp2, fs); 9867 9868 switch (op1) { 9869 case OPC_SEL_D: 9870 tcg_gen_andi_i64(fp0, fp0, 1); 9871 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9872 break; 9873 case OPC_SELEQZ_D: 9874 tcg_gen_andi_i64(fp1, fp1, 1); 9875 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9876 break; 9877 case OPC_SELNEZ_D: 9878 tcg_gen_andi_i64(fp1, fp1, 1); 9879 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9880 break; 9881 default: 9882 MIPS_INVAL("gen_sel_d"); 9883 gen_reserved_instruction(ctx); 9884 break; 9885 } 9886 9887 gen_store_fpr64(ctx, fp0, fd); 9888 tcg_temp_free_i64(fp2); 9889 tcg_temp_free_i64(fp1); 9890 tcg_temp_free_i64(fp0); 9891 tcg_temp_free_i64(t1); 9892 } 9893 9894 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9895 int ft, int fs, int fd, int cc) 9896 { 9897 uint32_t func = ctx->opcode & 0x3f; 9898 switch (op1) { 9899 case OPC_ADD_S: 9900 { 9901 TCGv_i32 fp0 = tcg_temp_new_i32(); 9902 TCGv_i32 fp1 = tcg_temp_new_i32(); 9903 9904 gen_load_fpr32(ctx, fp0, fs); 9905 gen_load_fpr32(ctx, fp1, ft); 9906 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 9907 tcg_temp_free_i32(fp1); 9908 gen_store_fpr32(ctx, fp0, fd); 9909 tcg_temp_free_i32(fp0); 9910 } 9911 break; 9912 case OPC_SUB_S: 9913 { 9914 TCGv_i32 fp0 = tcg_temp_new_i32(); 9915 TCGv_i32 fp1 = tcg_temp_new_i32(); 9916 9917 gen_load_fpr32(ctx, fp0, fs); 9918 gen_load_fpr32(ctx, fp1, ft); 9919 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 9920 tcg_temp_free_i32(fp1); 9921 gen_store_fpr32(ctx, fp0, fd); 9922 tcg_temp_free_i32(fp0); 9923 } 9924 break; 9925 case OPC_MUL_S: 9926 { 9927 TCGv_i32 fp0 = tcg_temp_new_i32(); 9928 TCGv_i32 fp1 = tcg_temp_new_i32(); 9929 9930 gen_load_fpr32(ctx, fp0, fs); 9931 gen_load_fpr32(ctx, fp1, ft); 9932 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 9933 tcg_temp_free_i32(fp1); 9934 gen_store_fpr32(ctx, fp0, fd); 9935 tcg_temp_free_i32(fp0); 9936 } 9937 break; 9938 case OPC_DIV_S: 9939 { 9940 TCGv_i32 fp0 = tcg_temp_new_i32(); 9941 TCGv_i32 fp1 = tcg_temp_new_i32(); 9942 9943 gen_load_fpr32(ctx, fp0, fs); 9944 gen_load_fpr32(ctx, fp1, ft); 9945 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 9946 tcg_temp_free_i32(fp1); 9947 gen_store_fpr32(ctx, fp0, fd); 9948 tcg_temp_free_i32(fp0); 9949 } 9950 break; 9951 case OPC_SQRT_S: 9952 { 9953 TCGv_i32 fp0 = tcg_temp_new_i32(); 9954 9955 gen_load_fpr32(ctx, fp0, fs); 9956 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 9957 gen_store_fpr32(ctx, fp0, fd); 9958 tcg_temp_free_i32(fp0); 9959 } 9960 break; 9961 case OPC_ABS_S: 9962 { 9963 TCGv_i32 fp0 = tcg_temp_new_i32(); 9964 9965 gen_load_fpr32(ctx, fp0, fs); 9966 if (ctx->abs2008) { 9967 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9968 } else { 9969 gen_helper_float_abs_s(fp0, fp0); 9970 } 9971 gen_store_fpr32(ctx, fp0, fd); 9972 tcg_temp_free_i32(fp0); 9973 } 9974 break; 9975 case OPC_MOV_S: 9976 { 9977 TCGv_i32 fp0 = tcg_temp_new_i32(); 9978 9979 gen_load_fpr32(ctx, fp0, fs); 9980 gen_store_fpr32(ctx, fp0, fd); 9981 tcg_temp_free_i32(fp0); 9982 } 9983 break; 9984 case OPC_NEG_S: 9985 { 9986 TCGv_i32 fp0 = tcg_temp_new_i32(); 9987 9988 gen_load_fpr32(ctx, fp0, fs); 9989 if (ctx->abs2008) { 9990 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9991 } else { 9992 gen_helper_float_chs_s(fp0, fp0); 9993 } 9994 gen_store_fpr32(ctx, fp0, fd); 9995 tcg_temp_free_i32(fp0); 9996 } 9997 break; 9998 case OPC_ROUND_L_S: 9999 check_cp1_64bitmode(ctx); 10000 { 10001 TCGv_i32 fp32 = tcg_temp_new_i32(); 10002 TCGv_i64 fp64 = tcg_temp_new_i64(); 10003 10004 gen_load_fpr32(ctx, fp32, fs); 10005 if (ctx->nan2008) { 10006 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10007 } else { 10008 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10009 } 10010 tcg_temp_free_i32(fp32); 10011 gen_store_fpr64(ctx, fp64, fd); 10012 tcg_temp_free_i64(fp64); 10013 } 10014 break; 10015 case OPC_TRUNC_L_S: 10016 check_cp1_64bitmode(ctx); 10017 { 10018 TCGv_i32 fp32 = tcg_temp_new_i32(); 10019 TCGv_i64 fp64 = tcg_temp_new_i64(); 10020 10021 gen_load_fpr32(ctx, fp32, fs); 10022 if (ctx->nan2008) { 10023 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10024 } else { 10025 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10026 } 10027 tcg_temp_free_i32(fp32); 10028 gen_store_fpr64(ctx, fp64, fd); 10029 tcg_temp_free_i64(fp64); 10030 } 10031 break; 10032 case OPC_CEIL_L_S: 10033 check_cp1_64bitmode(ctx); 10034 { 10035 TCGv_i32 fp32 = tcg_temp_new_i32(); 10036 TCGv_i64 fp64 = tcg_temp_new_i64(); 10037 10038 gen_load_fpr32(ctx, fp32, fs); 10039 if (ctx->nan2008) { 10040 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10041 } else { 10042 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10043 } 10044 tcg_temp_free_i32(fp32); 10045 gen_store_fpr64(ctx, fp64, fd); 10046 tcg_temp_free_i64(fp64); 10047 } 10048 break; 10049 case OPC_FLOOR_L_S: 10050 check_cp1_64bitmode(ctx); 10051 { 10052 TCGv_i32 fp32 = tcg_temp_new_i32(); 10053 TCGv_i64 fp64 = tcg_temp_new_i64(); 10054 10055 gen_load_fpr32(ctx, fp32, fs); 10056 if (ctx->nan2008) { 10057 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10058 } else { 10059 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10060 } 10061 tcg_temp_free_i32(fp32); 10062 gen_store_fpr64(ctx, fp64, fd); 10063 tcg_temp_free_i64(fp64); 10064 } 10065 break; 10066 case OPC_ROUND_W_S: 10067 { 10068 TCGv_i32 fp0 = tcg_temp_new_i32(); 10069 10070 gen_load_fpr32(ctx, fp0, fs); 10071 if (ctx->nan2008) { 10072 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10073 } else { 10074 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10075 } 10076 gen_store_fpr32(ctx, fp0, fd); 10077 tcg_temp_free_i32(fp0); 10078 } 10079 break; 10080 case OPC_TRUNC_W_S: 10081 { 10082 TCGv_i32 fp0 = tcg_temp_new_i32(); 10083 10084 gen_load_fpr32(ctx, fp0, fs); 10085 if (ctx->nan2008) { 10086 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10087 } else { 10088 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10089 } 10090 gen_store_fpr32(ctx, fp0, fd); 10091 tcg_temp_free_i32(fp0); 10092 } 10093 break; 10094 case OPC_CEIL_W_S: 10095 { 10096 TCGv_i32 fp0 = tcg_temp_new_i32(); 10097 10098 gen_load_fpr32(ctx, fp0, fs); 10099 if (ctx->nan2008) { 10100 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10101 } else { 10102 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10103 } 10104 gen_store_fpr32(ctx, fp0, fd); 10105 tcg_temp_free_i32(fp0); 10106 } 10107 break; 10108 case OPC_FLOOR_W_S: 10109 { 10110 TCGv_i32 fp0 = tcg_temp_new_i32(); 10111 10112 gen_load_fpr32(ctx, fp0, fs); 10113 if (ctx->nan2008) { 10114 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10115 } else { 10116 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10117 } 10118 gen_store_fpr32(ctx, fp0, fd); 10119 tcg_temp_free_i32(fp0); 10120 } 10121 break; 10122 case OPC_SEL_S: 10123 check_insn(ctx, ISA_MIPS_R6); 10124 gen_sel_s(ctx, op1, fd, ft, fs); 10125 break; 10126 case OPC_SELEQZ_S: 10127 check_insn(ctx, ISA_MIPS_R6); 10128 gen_sel_s(ctx, op1, fd, ft, fs); 10129 break; 10130 case OPC_SELNEZ_S: 10131 check_insn(ctx, ISA_MIPS_R6); 10132 gen_sel_s(ctx, op1, fd, ft, fs); 10133 break; 10134 case OPC_MOVCF_S: 10135 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10136 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10137 break; 10138 case OPC_MOVZ_S: 10139 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10140 { 10141 TCGLabel *l1 = gen_new_label(); 10142 TCGv_i32 fp0; 10143 10144 if (ft != 0) { 10145 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10146 } 10147 fp0 = tcg_temp_new_i32(); 10148 gen_load_fpr32(ctx, fp0, fs); 10149 gen_store_fpr32(ctx, fp0, fd); 10150 tcg_temp_free_i32(fp0); 10151 gen_set_label(l1); 10152 } 10153 break; 10154 case OPC_MOVN_S: 10155 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10156 { 10157 TCGLabel *l1 = gen_new_label(); 10158 TCGv_i32 fp0; 10159 10160 if (ft != 0) { 10161 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10162 fp0 = tcg_temp_new_i32(); 10163 gen_load_fpr32(ctx, fp0, fs); 10164 gen_store_fpr32(ctx, fp0, fd); 10165 tcg_temp_free_i32(fp0); 10166 gen_set_label(l1); 10167 } 10168 } 10169 break; 10170 case OPC_RECIP_S: 10171 { 10172 TCGv_i32 fp0 = tcg_temp_new_i32(); 10173 10174 gen_load_fpr32(ctx, fp0, fs); 10175 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10176 gen_store_fpr32(ctx, fp0, fd); 10177 tcg_temp_free_i32(fp0); 10178 } 10179 break; 10180 case OPC_RSQRT_S: 10181 { 10182 TCGv_i32 fp0 = tcg_temp_new_i32(); 10183 10184 gen_load_fpr32(ctx, fp0, fs); 10185 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10186 gen_store_fpr32(ctx, fp0, fd); 10187 tcg_temp_free_i32(fp0); 10188 } 10189 break; 10190 case OPC_MADDF_S: 10191 check_insn(ctx, ISA_MIPS_R6); 10192 { 10193 TCGv_i32 fp0 = tcg_temp_new_i32(); 10194 TCGv_i32 fp1 = tcg_temp_new_i32(); 10195 TCGv_i32 fp2 = tcg_temp_new_i32(); 10196 gen_load_fpr32(ctx, fp0, fs); 10197 gen_load_fpr32(ctx, fp1, ft); 10198 gen_load_fpr32(ctx, fp2, fd); 10199 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10200 gen_store_fpr32(ctx, fp2, fd); 10201 tcg_temp_free_i32(fp2); 10202 tcg_temp_free_i32(fp1); 10203 tcg_temp_free_i32(fp0); 10204 } 10205 break; 10206 case OPC_MSUBF_S: 10207 check_insn(ctx, ISA_MIPS_R6); 10208 { 10209 TCGv_i32 fp0 = tcg_temp_new_i32(); 10210 TCGv_i32 fp1 = tcg_temp_new_i32(); 10211 TCGv_i32 fp2 = tcg_temp_new_i32(); 10212 gen_load_fpr32(ctx, fp0, fs); 10213 gen_load_fpr32(ctx, fp1, ft); 10214 gen_load_fpr32(ctx, fp2, fd); 10215 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10216 gen_store_fpr32(ctx, fp2, fd); 10217 tcg_temp_free_i32(fp2); 10218 tcg_temp_free_i32(fp1); 10219 tcg_temp_free_i32(fp0); 10220 } 10221 break; 10222 case OPC_RINT_S: 10223 check_insn(ctx, ISA_MIPS_R6); 10224 { 10225 TCGv_i32 fp0 = tcg_temp_new_i32(); 10226 gen_load_fpr32(ctx, fp0, fs); 10227 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10228 gen_store_fpr32(ctx, fp0, fd); 10229 tcg_temp_free_i32(fp0); 10230 } 10231 break; 10232 case OPC_CLASS_S: 10233 check_insn(ctx, ISA_MIPS_R6); 10234 { 10235 TCGv_i32 fp0 = tcg_temp_new_i32(); 10236 gen_load_fpr32(ctx, fp0, fs); 10237 gen_helper_float_class_s(fp0, cpu_env, fp0); 10238 gen_store_fpr32(ctx, fp0, fd); 10239 tcg_temp_free_i32(fp0); 10240 } 10241 break; 10242 case OPC_MIN_S: /* OPC_RECIP2_S */ 10243 if (ctx->insn_flags & ISA_MIPS_R6) { 10244 /* OPC_MIN_S */ 10245 TCGv_i32 fp0 = tcg_temp_new_i32(); 10246 TCGv_i32 fp1 = tcg_temp_new_i32(); 10247 TCGv_i32 fp2 = tcg_temp_new_i32(); 10248 gen_load_fpr32(ctx, fp0, fs); 10249 gen_load_fpr32(ctx, fp1, ft); 10250 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10251 gen_store_fpr32(ctx, fp2, fd); 10252 tcg_temp_free_i32(fp2); 10253 tcg_temp_free_i32(fp1); 10254 tcg_temp_free_i32(fp0); 10255 } else { 10256 /* OPC_RECIP2_S */ 10257 check_cp1_64bitmode(ctx); 10258 { 10259 TCGv_i32 fp0 = tcg_temp_new_i32(); 10260 TCGv_i32 fp1 = tcg_temp_new_i32(); 10261 10262 gen_load_fpr32(ctx, fp0, fs); 10263 gen_load_fpr32(ctx, fp1, ft); 10264 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10265 tcg_temp_free_i32(fp1); 10266 gen_store_fpr32(ctx, fp0, fd); 10267 tcg_temp_free_i32(fp0); 10268 } 10269 } 10270 break; 10271 case OPC_MINA_S: /* OPC_RECIP1_S */ 10272 if (ctx->insn_flags & ISA_MIPS_R6) { 10273 /* OPC_MINA_S */ 10274 TCGv_i32 fp0 = tcg_temp_new_i32(); 10275 TCGv_i32 fp1 = tcg_temp_new_i32(); 10276 TCGv_i32 fp2 = tcg_temp_new_i32(); 10277 gen_load_fpr32(ctx, fp0, fs); 10278 gen_load_fpr32(ctx, fp1, ft); 10279 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10280 gen_store_fpr32(ctx, fp2, fd); 10281 tcg_temp_free_i32(fp2); 10282 tcg_temp_free_i32(fp1); 10283 tcg_temp_free_i32(fp0); 10284 } else { 10285 /* OPC_RECIP1_S */ 10286 check_cp1_64bitmode(ctx); 10287 { 10288 TCGv_i32 fp0 = tcg_temp_new_i32(); 10289 10290 gen_load_fpr32(ctx, fp0, fs); 10291 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10292 gen_store_fpr32(ctx, fp0, fd); 10293 tcg_temp_free_i32(fp0); 10294 } 10295 } 10296 break; 10297 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10298 if (ctx->insn_flags & ISA_MIPS_R6) { 10299 /* OPC_MAX_S */ 10300 TCGv_i32 fp0 = tcg_temp_new_i32(); 10301 TCGv_i32 fp1 = tcg_temp_new_i32(); 10302 gen_load_fpr32(ctx, fp0, fs); 10303 gen_load_fpr32(ctx, fp1, ft); 10304 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10305 gen_store_fpr32(ctx, fp1, fd); 10306 tcg_temp_free_i32(fp1); 10307 tcg_temp_free_i32(fp0); 10308 } else { 10309 /* OPC_RSQRT1_S */ 10310 check_cp1_64bitmode(ctx); 10311 { 10312 TCGv_i32 fp0 = tcg_temp_new_i32(); 10313 10314 gen_load_fpr32(ctx, fp0, fs); 10315 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10316 gen_store_fpr32(ctx, fp0, fd); 10317 tcg_temp_free_i32(fp0); 10318 } 10319 } 10320 break; 10321 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10322 if (ctx->insn_flags & ISA_MIPS_R6) { 10323 /* OPC_MAXA_S */ 10324 TCGv_i32 fp0 = tcg_temp_new_i32(); 10325 TCGv_i32 fp1 = tcg_temp_new_i32(); 10326 gen_load_fpr32(ctx, fp0, fs); 10327 gen_load_fpr32(ctx, fp1, ft); 10328 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10329 gen_store_fpr32(ctx, fp1, fd); 10330 tcg_temp_free_i32(fp1); 10331 tcg_temp_free_i32(fp0); 10332 } else { 10333 /* OPC_RSQRT2_S */ 10334 check_cp1_64bitmode(ctx); 10335 { 10336 TCGv_i32 fp0 = tcg_temp_new_i32(); 10337 TCGv_i32 fp1 = tcg_temp_new_i32(); 10338 10339 gen_load_fpr32(ctx, fp0, fs); 10340 gen_load_fpr32(ctx, fp1, ft); 10341 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10342 tcg_temp_free_i32(fp1); 10343 gen_store_fpr32(ctx, fp0, fd); 10344 tcg_temp_free_i32(fp0); 10345 } 10346 } 10347 break; 10348 case OPC_CVT_D_S: 10349 check_cp1_registers(ctx, fd); 10350 { 10351 TCGv_i32 fp32 = tcg_temp_new_i32(); 10352 TCGv_i64 fp64 = tcg_temp_new_i64(); 10353 10354 gen_load_fpr32(ctx, fp32, fs); 10355 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10356 tcg_temp_free_i32(fp32); 10357 gen_store_fpr64(ctx, fp64, fd); 10358 tcg_temp_free_i64(fp64); 10359 } 10360 break; 10361 case OPC_CVT_W_S: 10362 { 10363 TCGv_i32 fp0 = tcg_temp_new_i32(); 10364 10365 gen_load_fpr32(ctx, fp0, fs); 10366 if (ctx->nan2008) { 10367 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10368 } else { 10369 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10370 } 10371 gen_store_fpr32(ctx, fp0, fd); 10372 tcg_temp_free_i32(fp0); 10373 } 10374 break; 10375 case OPC_CVT_L_S: 10376 check_cp1_64bitmode(ctx); 10377 { 10378 TCGv_i32 fp32 = tcg_temp_new_i32(); 10379 TCGv_i64 fp64 = tcg_temp_new_i64(); 10380 10381 gen_load_fpr32(ctx, fp32, fs); 10382 if (ctx->nan2008) { 10383 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10384 } else { 10385 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10386 } 10387 tcg_temp_free_i32(fp32); 10388 gen_store_fpr64(ctx, fp64, fd); 10389 tcg_temp_free_i64(fp64); 10390 } 10391 break; 10392 case OPC_CVT_PS_S: 10393 check_ps(ctx); 10394 { 10395 TCGv_i64 fp64 = tcg_temp_new_i64(); 10396 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10397 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10398 10399 gen_load_fpr32(ctx, fp32_0, fs); 10400 gen_load_fpr32(ctx, fp32_1, ft); 10401 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10402 tcg_temp_free_i32(fp32_1); 10403 tcg_temp_free_i32(fp32_0); 10404 gen_store_fpr64(ctx, fp64, fd); 10405 tcg_temp_free_i64(fp64); 10406 } 10407 break; 10408 case OPC_CMP_F_S: 10409 case OPC_CMP_UN_S: 10410 case OPC_CMP_EQ_S: 10411 case OPC_CMP_UEQ_S: 10412 case OPC_CMP_OLT_S: 10413 case OPC_CMP_ULT_S: 10414 case OPC_CMP_OLE_S: 10415 case OPC_CMP_ULE_S: 10416 case OPC_CMP_SF_S: 10417 case OPC_CMP_NGLE_S: 10418 case OPC_CMP_SEQ_S: 10419 case OPC_CMP_NGL_S: 10420 case OPC_CMP_LT_S: 10421 case OPC_CMP_NGE_S: 10422 case OPC_CMP_LE_S: 10423 case OPC_CMP_NGT_S: 10424 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10425 if (ctx->opcode & (1 << 6)) { 10426 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10427 } else { 10428 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10429 } 10430 break; 10431 case OPC_ADD_D: 10432 check_cp1_registers(ctx, fs | ft | fd); 10433 { 10434 TCGv_i64 fp0 = tcg_temp_new_i64(); 10435 TCGv_i64 fp1 = tcg_temp_new_i64(); 10436 10437 gen_load_fpr64(ctx, fp0, fs); 10438 gen_load_fpr64(ctx, fp1, ft); 10439 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10440 tcg_temp_free_i64(fp1); 10441 gen_store_fpr64(ctx, fp0, fd); 10442 tcg_temp_free_i64(fp0); 10443 } 10444 break; 10445 case OPC_SUB_D: 10446 check_cp1_registers(ctx, fs | ft | fd); 10447 { 10448 TCGv_i64 fp0 = tcg_temp_new_i64(); 10449 TCGv_i64 fp1 = tcg_temp_new_i64(); 10450 10451 gen_load_fpr64(ctx, fp0, fs); 10452 gen_load_fpr64(ctx, fp1, ft); 10453 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10454 tcg_temp_free_i64(fp1); 10455 gen_store_fpr64(ctx, fp0, fd); 10456 tcg_temp_free_i64(fp0); 10457 } 10458 break; 10459 case OPC_MUL_D: 10460 check_cp1_registers(ctx, fs | ft | fd); 10461 { 10462 TCGv_i64 fp0 = tcg_temp_new_i64(); 10463 TCGv_i64 fp1 = tcg_temp_new_i64(); 10464 10465 gen_load_fpr64(ctx, fp0, fs); 10466 gen_load_fpr64(ctx, fp1, ft); 10467 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10468 tcg_temp_free_i64(fp1); 10469 gen_store_fpr64(ctx, fp0, fd); 10470 tcg_temp_free_i64(fp0); 10471 } 10472 break; 10473 case OPC_DIV_D: 10474 check_cp1_registers(ctx, fs | ft | fd); 10475 { 10476 TCGv_i64 fp0 = tcg_temp_new_i64(); 10477 TCGv_i64 fp1 = tcg_temp_new_i64(); 10478 10479 gen_load_fpr64(ctx, fp0, fs); 10480 gen_load_fpr64(ctx, fp1, ft); 10481 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10482 tcg_temp_free_i64(fp1); 10483 gen_store_fpr64(ctx, fp0, fd); 10484 tcg_temp_free_i64(fp0); 10485 } 10486 break; 10487 case OPC_SQRT_D: 10488 check_cp1_registers(ctx, fs | fd); 10489 { 10490 TCGv_i64 fp0 = tcg_temp_new_i64(); 10491 10492 gen_load_fpr64(ctx, fp0, fs); 10493 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10494 gen_store_fpr64(ctx, fp0, fd); 10495 tcg_temp_free_i64(fp0); 10496 } 10497 break; 10498 case OPC_ABS_D: 10499 check_cp1_registers(ctx, fs | fd); 10500 { 10501 TCGv_i64 fp0 = tcg_temp_new_i64(); 10502 10503 gen_load_fpr64(ctx, fp0, fs); 10504 if (ctx->abs2008) { 10505 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10506 } else { 10507 gen_helper_float_abs_d(fp0, fp0); 10508 } 10509 gen_store_fpr64(ctx, fp0, fd); 10510 tcg_temp_free_i64(fp0); 10511 } 10512 break; 10513 case OPC_MOV_D: 10514 check_cp1_registers(ctx, fs | fd); 10515 { 10516 TCGv_i64 fp0 = tcg_temp_new_i64(); 10517 10518 gen_load_fpr64(ctx, fp0, fs); 10519 gen_store_fpr64(ctx, fp0, fd); 10520 tcg_temp_free_i64(fp0); 10521 } 10522 break; 10523 case OPC_NEG_D: 10524 check_cp1_registers(ctx, fs | fd); 10525 { 10526 TCGv_i64 fp0 = tcg_temp_new_i64(); 10527 10528 gen_load_fpr64(ctx, fp0, fs); 10529 if (ctx->abs2008) { 10530 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10531 } else { 10532 gen_helper_float_chs_d(fp0, fp0); 10533 } 10534 gen_store_fpr64(ctx, fp0, fd); 10535 tcg_temp_free_i64(fp0); 10536 } 10537 break; 10538 case OPC_ROUND_L_D: 10539 check_cp1_64bitmode(ctx); 10540 { 10541 TCGv_i64 fp0 = tcg_temp_new_i64(); 10542 10543 gen_load_fpr64(ctx, fp0, fs); 10544 if (ctx->nan2008) { 10545 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10546 } else { 10547 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10548 } 10549 gen_store_fpr64(ctx, fp0, fd); 10550 tcg_temp_free_i64(fp0); 10551 } 10552 break; 10553 case OPC_TRUNC_L_D: 10554 check_cp1_64bitmode(ctx); 10555 { 10556 TCGv_i64 fp0 = tcg_temp_new_i64(); 10557 10558 gen_load_fpr64(ctx, fp0, fs); 10559 if (ctx->nan2008) { 10560 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10561 } else { 10562 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10563 } 10564 gen_store_fpr64(ctx, fp0, fd); 10565 tcg_temp_free_i64(fp0); 10566 } 10567 break; 10568 case OPC_CEIL_L_D: 10569 check_cp1_64bitmode(ctx); 10570 { 10571 TCGv_i64 fp0 = tcg_temp_new_i64(); 10572 10573 gen_load_fpr64(ctx, fp0, fs); 10574 if (ctx->nan2008) { 10575 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10576 } else { 10577 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10578 } 10579 gen_store_fpr64(ctx, fp0, fd); 10580 tcg_temp_free_i64(fp0); 10581 } 10582 break; 10583 case OPC_FLOOR_L_D: 10584 check_cp1_64bitmode(ctx); 10585 { 10586 TCGv_i64 fp0 = tcg_temp_new_i64(); 10587 10588 gen_load_fpr64(ctx, fp0, fs); 10589 if (ctx->nan2008) { 10590 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10591 } else { 10592 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10593 } 10594 gen_store_fpr64(ctx, fp0, fd); 10595 tcg_temp_free_i64(fp0); 10596 } 10597 break; 10598 case OPC_ROUND_W_D: 10599 check_cp1_registers(ctx, fs); 10600 { 10601 TCGv_i32 fp32 = tcg_temp_new_i32(); 10602 TCGv_i64 fp64 = tcg_temp_new_i64(); 10603 10604 gen_load_fpr64(ctx, fp64, fs); 10605 if (ctx->nan2008) { 10606 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10607 } else { 10608 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10609 } 10610 tcg_temp_free_i64(fp64); 10611 gen_store_fpr32(ctx, fp32, fd); 10612 tcg_temp_free_i32(fp32); 10613 } 10614 break; 10615 case OPC_TRUNC_W_D: 10616 check_cp1_registers(ctx, fs); 10617 { 10618 TCGv_i32 fp32 = tcg_temp_new_i32(); 10619 TCGv_i64 fp64 = tcg_temp_new_i64(); 10620 10621 gen_load_fpr64(ctx, fp64, fs); 10622 if (ctx->nan2008) { 10623 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10624 } else { 10625 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10626 } 10627 tcg_temp_free_i64(fp64); 10628 gen_store_fpr32(ctx, fp32, fd); 10629 tcg_temp_free_i32(fp32); 10630 } 10631 break; 10632 case OPC_CEIL_W_D: 10633 check_cp1_registers(ctx, fs); 10634 { 10635 TCGv_i32 fp32 = tcg_temp_new_i32(); 10636 TCGv_i64 fp64 = tcg_temp_new_i64(); 10637 10638 gen_load_fpr64(ctx, fp64, fs); 10639 if (ctx->nan2008) { 10640 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10641 } else { 10642 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10643 } 10644 tcg_temp_free_i64(fp64); 10645 gen_store_fpr32(ctx, fp32, fd); 10646 tcg_temp_free_i32(fp32); 10647 } 10648 break; 10649 case OPC_FLOOR_W_D: 10650 check_cp1_registers(ctx, fs); 10651 { 10652 TCGv_i32 fp32 = tcg_temp_new_i32(); 10653 TCGv_i64 fp64 = tcg_temp_new_i64(); 10654 10655 gen_load_fpr64(ctx, fp64, fs); 10656 if (ctx->nan2008) { 10657 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10658 } else { 10659 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10660 } 10661 tcg_temp_free_i64(fp64); 10662 gen_store_fpr32(ctx, fp32, fd); 10663 tcg_temp_free_i32(fp32); 10664 } 10665 break; 10666 case OPC_SEL_D: 10667 check_insn(ctx, ISA_MIPS_R6); 10668 gen_sel_d(ctx, op1, fd, ft, fs); 10669 break; 10670 case OPC_SELEQZ_D: 10671 check_insn(ctx, ISA_MIPS_R6); 10672 gen_sel_d(ctx, op1, fd, ft, fs); 10673 break; 10674 case OPC_SELNEZ_D: 10675 check_insn(ctx, ISA_MIPS_R6); 10676 gen_sel_d(ctx, op1, fd, ft, fs); 10677 break; 10678 case OPC_MOVCF_D: 10679 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10680 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10681 break; 10682 case OPC_MOVZ_D: 10683 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10684 { 10685 TCGLabel *l1 = gen_new_label(); 10686 TCGv_i64 fp0; 10687 10688 if (ft != 0) { 10689 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10690 } 10691 fp0 = tcg_temp_new_i64(); 10692 gen_load_fpr64(ctx, fp0, fs); 10693 gen_store_fpr64(ctx, fp0, fd); 10694 tcg_temp_free_i64(fp0); 10695 gen_set_label(l1); 10696 } 10697 break; 10698 case OPC_MOVN_D: 10699 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10700 { 10701 TCGLabel *l1 = gen_new_label(); 10702 TCGv_i64 fp0; 10703 10704 if (ft != 0) { 10705 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10706 fp0 = tcg_temp_new_i64(); 10707 gen_load_fpr64(ctx, fp0, fs); 10708 gen_store_fpr64(ctx, fp0, fd); 10709 tcg_temp_free_i64(fp0); 10710 gen_set_label(l1); 10711 } 10712 } 10713 break; 10714 case OPC_RECIP_D: 10715 check_cp1_registers(ctx, fs | fd); 10716 { 10717 TCGv_i64 fp0 = tcg_temp_new_i64(); 10718 10719 gen_load_fpr64(ctx, fp0, fs); 10720 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10721 gen_store_fpr64(ctx, fp0, fd); 10722 tcg_temp_free_i64(fp0); 10723 } 10724 break; 10725 case OPC_RSQRT_D: 10726 check_cp1_registers(ctx, fs | fd); 10727 { 10728 TCGv_i64 fp0 = tcg_temp_new_i64(); 10729 10730 gen_load_fpr64(ctx, fp0, fs); 10731 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10732 gen_store_fpr64(ctx, fp0, fd); 10733 tcg_temp_free_i64(fp0); 10734 } 10735 break; 10736 case OPC_MADDF_D: 10737 check_insn(ctx, ISA_MIPS_R6); 10738 { 10739 TCGv_i64 fp0 = tcg_temp_new_i64(); 10740 TCGv_i64 fp1 = tcg_temp_new_i64(); 10741 TCGv_i64 fp2 = tcg_temp_new_i64(); 10742 gen_load_fpr64(ctx, fp0, fs); 10743 gen_load_fpr64(ctx, fp1, ft); 10744 gen_load_fpr64(ctx, fp2, fd); 10745 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10746 gen_store_fpr64(ctx, fp2, fd); 10747 tcg_temp_free_i64(fp2); 10748 tcg_temp_free_i64(fp1); 10749 tcg_temp_free_i64(fp0); 10750 } 10751 break; 10752 case OPC_MSUBF_D: 10753 check_insn(ctx, ISA_MIPS_R6); 10754 { 10755 TCGv_i64 fp0 = tcg_temp_new_i64(); 10756 TCGv_i64 fp1 = tcg_temp_new_i64(); 10757 TCGv_i64 fp2 = tcg_temp_new_i64(); 10758 gen_load_fpr64(ctx, fp0, fs); 10759 gen_load_fpr64(ctx, fp1, ft); 10760 gen_load_fpr64(ctx, fp2, fd); 10761 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10762 gen_store_fpr64(ctx, fp2, fd); 10763 tcg_temp_free_i64(fp2); 10764 tcg_temp_free_i64(fp1); 10765 tcg_temp_free_i64(fp0); 10766 } 10767 break; 10768 case OPC_RINT_D: 10769 check_insn(ctx, ISA_MIPS_R6); 10770 { 10771 TCGv_i64 fp0 = tcg_temp_new_i64(); 10772 gen_load_fpr64(ctx, fp0, fs); 10773 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10774 gen_store_fpr64(ctx, fp0, fd); 10775 tcg_temp_free_i64(fp0); 10776 } 10777 break; 10778 case OPC_CLASS_D: 10779 check_insn(ctx, ISA_MIPS_R6); 10780 { 10781 TCGv_i64 fp0 = tcg_temp_new_i64(); 10782 gen_load_fpr64(ctx, fp0, fs); 10783 gen_helper_float_class_d(fp0, cpu_env, fp0); 10784 gen_store_fpr64(ctx, fp0, fd); 10785 tcg_temp_free_i64(fp0); 10786 } 10787 break; 10788 case OPC_MIN_D: /* OPC_RECIP2_D */ 10789 if (ctx->insn_flags & ISA_MIPS_R6) { 10790 /* OPC_MIN_D */ 10791 TCGv_i64 fp0 = tcg_temp_new_i64(); 10792 TCGv_i64 fp1 = tcg_temp_new_i64(); 10793 gen_load_fpr64(ctx, fp0, fs); 10794 gen_load_fpr64(ctx, fp1, ft); 10795 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10796 gen_store_fpr64(ctx, fp1, fd); 10797 tcg_temp_free_i64(fp1); 10798 tcg_temp_free_i64(fp0); 10799 } else { 10800 /* OPC_RECIP2_D */ 10801 check_cp1_64bitmode(ctx); 10802 { 10803 TCGv_i64 fp0 = tcg_temp_new_i64(); 10804 TCGv_i64 fp1 = tcg_temp_new_i64(); 10805 10806 gen_load_fpr64(ctx, fp0, fs); 10807 gen_load_fpr64(ctx, fp1, ft); 10808 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10809 tcg_temp_free_i64(fp1); 10810 gen_store_fpr64(ctx, fp0, fd); 10811 tcg_temp_free_i64(fp0); 10812 } 10813 } 10814 break; 10815 case OPC_MINA_D: /* OPC_RECIP1_D */ 10816 if (ctx->insn_flags & ISA_MIPS_R6) { 10817 /* OPC_MINA_D */ 10818 TCGv_i64 fp0 = tcg_temp_new_i64(); 10819 TCGv_i64 fp1 = tcg_temp_new_i64(); 10820 gen_load_fpr64(ctx, fp0, fs); 10821 gen_load_fpr64(ctx, fp1, ft); 10822 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10823 gen_store_fpr64(ctx, fp1, fd); 10824 tcg_temp_free_i64(fp1); 10825 tcg_temp_free_i64(fp0); 10826 } else { 10827 /* OPC_RECIP1_D */ 10828 check_cp1_64bitmode(ctx); 10829 { 10830 TCGv_i64 fp0 = tcg_temp_new_i64(); 10831 10832 gen_load_fpr64(ctx, fp0, fs); 10833 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10834 gen_store_fpr64(ctx, fp0, fd); 10835 tcg_temp_free_i64(fp0); 10836 } 10837 } 10838 break; 10839 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10840 if (ctx->insn_flags & ISA_MIPS_R6) { 10841 /* OPC_MAX_D */ 10842 TCGv_i64 fp0 = tcg_temp_new_i64(); 10843 TCGv_i64 fp1 = tcg_temp_new_i64(); 10844 gen_load_fpr64(ctx, fp0, fs); 10845 gen_load_fpr64(ctx, fp1, ft); 10846 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10847 gen_store_fpr64(ctx, fp1, fd); 10848 tcg_temp_free_i64(fp1); 10849 tcg_temp_free_i64(fp0); 10850 } else { 10851 /* OPC_RSQRT1_D */ 10852 check_cp1_64bitmode(ctx); 10853 { 10854 TCGv_i64 fp0 = tcg_temp_new_i64(); 10855 10856 gen_load_fpr64(ctx, fp0, fs); 10857 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10858 gen_store_fpr64(ctx, fp0, fd); 10859 tcg_temp_free_i64(fp0); 10860 } 10861 } 10862 break; 10863 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10864 if (ctx->insn_flags & ISA_MIPS_R6) { 10865 /* OPC_MAXA_D */ 10866 TCGv_i64 fp0 = tcg_temp_new_i64(); 10867 TCGv_i64 fp1 = tcg_temp_new_i64(); 10868 gen_load_fpr64(ctx, fp0, fs); 10869 gen_load_fpr64(ctx, fp1, ft); 10870 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 10871 gen_store_fpr64(ctx, fp1, fd); 10872 tcg_temp_free_i64(fp1); 10873 tcg_temp_free_i64(fp0); 10874 } else { 10875 /* OPC_RSQRT2_D */ 10876 check_cp1_64bitmode(ctx); 10877 { 10878 TCGv_i64 fp0 = tcg_temp_new_i64(); 10879 TCGv_i64 fp1 = tcg_temp_new_i64(); 10880 10881 gen_load_fpr64(ctx, fp0, fs); 10882 gen_load_fpr64(ctx, fp1, ft); 10883 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 10884 tcg_temp_free_i64(fp1); 10885 gen_store_fpr64(ctx, fp0, fd); 10886 tcg_temp_free_i64(fp0); 10887 } 10888 } 10889 break; 10890 case OPC_CMP_F_D: 10891 case OPC_CMP_UN_D: 10892 case OPC_CMP_EQ_D: 10893 case OPC_CMP_UEQ_D: 10894 case OPC_CMP_OLT_D: 10895 case OPC_CMP_ULT_D: 10896 case OPC_CMP_OLE_D: 10897 case OPC_CMP_ULE_D: 10898 case OPC_CMP_SF_D: 10899 case OPC_CMP_NGLE_D: 10900 case OPC_CMP_SEQ_D: 10901 case OPC_CMP_NGL_D: 10902 case OPC_CMP_LT_D: 10903 case OPC_CMP_NGE_D: 10904 case OPC_CMP_LE_D: 10905 case OPC_CMP_NGT_D: 10906 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10907 if (ctx->opcode & (1 << 6)) { 10908 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10909 } else { 10910 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10911 } 10912 break; 10913 case OPC_CVT_S_D: 10914 check_cp1_registers(ctx, fs); 10915 { 10916 TCGv_i32 fp32 = tcg_temp_new_i32(); 10917 TCGv_i64 fp64 = tcg_temp_new_i64(); 10918 10919 gen_load_fpr64(ctx, fp64, fs); 10920 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 10921 tcg_temp_free_i64(fp64); 10922 gen_store_fpr32(ctx, fp32, fd); 10923 tcg_temp_free_i32(fp32); 10924 } 10925 break; 10926 case OPC_CVT_W_D: 10927 check_cp1_registers(ctx, fs); 10928 { 10929 TCGv_i32 fp32 = tcg_temp_new_i32(); 10930 TCGv_i64 fp64 = tcg_temp_new_i64(); 10931 10932 gen_load_fpr64(ctx, fp64, fs); 10933 if (ctx->nan2008) { 10934 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 10935 } else { 10936 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 10937 } 10938 tcg_temp_free_i64(fp64); 10939 gen_store_fpr32(ctx, fp32, fd); 10940 tcg_temp_free_i32(fp32); 10941 } 10942 break; 10943 case OPC_CVT_L_D: 10944 check_cp1_64bitmode(ctx); 10945 { 10946 TCGv_i64 fp0 = tcg_temp_new_i64(); 10947 10948 gen_load_fpr64(ctx, fp0, fs); 10949 if (ctx->nan2008) { 10950 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 10951 } else { 10952 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 10953 } 10954 gen_store_fpr64(ctx, fp0, fd); 10955 tcg_temp_free_i64(fp0); 10956 } 10957 break; 10958 case OPC_CVT_S_W: 10959 { 10960 TCGv_i32 fp0 = tcg_temp_new_i32(); 10961 10962 gen_load_fpr32(ctx, fp0, fs); 10963 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 10964 gen_store_fpr32(ctx, fp0, fd); 10965 tcg_temp_free_i32(fp0); 10966 } 10967 break; 10968 case OPC_CVT_D_W: 10969 check_cp1_registers(ctx, fd); 10970 { 10971 TCGv_i32 fp32 = tcg_temp_new_i32(); 10972 TCGv_i64 fp64 = tcg_temp_new_i64(); 10973 10974 gen_load_fpr32(ctx, fp32, fs); 10975 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 10976 tcg_temp_free_i32(fp32); 10977 gen_store_fpr64(ctx, fp64, fd); 10978 tcg_temp_free_i64(fp64); 10979 } 10980 break; 10981 case OPC_CVT_S_L: 10982 check_cp1_64bitmode(ctx); 10983 { 10984 TCGv_i32 fp32 = tcg_temp_new_i32(); 10985 TCGv_i64 fp64 = tcg_temp_new_i64(); 10986 10987 gen_load_fpr64(ctx, fp64, fs); 10988 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 10989 tcg_temp_free_i64(fp64); 10990 gen_store_fpr32(ctx, fp32, fd); 10991 tcg_temp_free_i32(fp32); 10992 } 10993 break; 10994 case OPC_CVT_D_L: 10995 check_cp1_64bitmode(ctx); 10996 { 10997 TCGv_i64 fp0 = tcg_temp_new_i64(); 10998 10999 gen_load_fpr64(ctx, fp0, fs); 11000 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11001 gen_store_fpr64(ctx, fp0, fd); 11002 tcg_temp_free_i64(fp0); 11003 } 11004 break; 11005 case OPC_CVT_PS_PW: 11006 check_ps(ctx); 11007 { 11008 TCGv_i64 fp0 = tcg_temp_new_i64(); 11009 11010 gen_load_fpr64(ctx, fp0, fs); 11011 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11012 gen_store_fpr64(ctx, fp0, fd); 11013 tcg_temp_free_i64(fp0); 11014 } 11015 break; 11016 case OPC_ADD_PS: 11017 check_ps(ctx); 11018 { 11019 TCGv_i64 fp0 = tcg_temp_new_i64(); 11020 TCGv_i64 fp1 = tcg_temp_new_i64(); 11021 11022 gen_load_fpr64(ctx, fp0, fs); 11023 gen_load_fpr64(ctx, fp1, ft); 11024 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11025 tcg_temp_free_i64(fp1); 11026 gen_store_fpr64(ctx, fp0, fd); 11027 tcg_temp_free_i64(fp0); 11028 } 11029 break; 11030 case OPC_SUB_PS: 11031 check_ps(ctx); 11032 { 11033 TCGv_i64 fp0 = tcg_temp_new_i64(); 11034 TCGv_i64 fp1 = tcg_temp_new_i64(); 11035 11036 gen_load_fpr64(ctx, fp0, fs); 11037 gen_load_fpr64(ctx, fp1, ft); 11038 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11039 tcg_temp_free_i64(fp1); 11040 gen_store_fpr64(ctx, fp0, fd); 11041 tcg_temp_free_i64(fp0); 11042 } 11043 break; 11044 case OPC_MUL_PS: 11045 check_ps(ctx); 11046 { 11047 TCGv_i64 fp0 = tcg_temp_new_i64(); 11048 TCGv_i64 fp1 = tcg_temp_new_i64(); 11049 11050 gen_load_fpr64(ctx, fp0, fs); 11051 gen_load_fpr64(ctx, fp1, ft); 11052 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11053 tcg_temp_free_i64(fp1); 11054 gen_store_fpr64(ctx, fp0, fd); 11055 tcg_temp_free_i64(fp0); 11056 } 11057 break; 11058 case OPC_ABS_PS: 11059 check_ps(ctx); 11060 { 11061 TCGv_i64 fp0 = tcg_temp_new_i64(); 11062 11063 gen_load_fpr64(ctx, fp0, fs); 11064 gen_helper_float_abs_ps(fp0, fp0); 11065 gen_store_fpr64(ctx, fp0, fd); 11066 tcg_temp_free_i64(fp0); 11067 } 11068 break; 11069 case OPC_MOV_PS: 11070 check_ps(ctx); 11071 { 11072 TCGv_i64 fp0 = tcg_temp_new_i64(); 11073 11074 gen_load_fpr64(ctx, fp0, fs); 11075 gen_store_fpr64(ctx, fp0, fd); 11076 tcg_temp_free_i64(fp0); 11077 } 11078 break; 11079 case OPC_NEG_PS: 11080 check_ps(ctx); 11081 { 11082 TCGv_i64 fp0 = tcg_temp_new_i64(); 11083 11084 gen_load_fpr64(ctx, fp0, fs); 11085 gen_helper_float_chs_ps(fp0, fp0); 11086 gen_store_fpr64(ctx, fp0, fd); 11087 tcg_temp_free_i64(fp0); 11088 } 11089 break; 11090 case OPC_MOVCF_PS: 11091 check_ps(ctx); 11092 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11093 break; 11094 case OPC_MOVZ_PS: 11095 check_ps(ctx); 11096 { 11097 TCGLabel *l1 = gen_new_label(); 11098 TCGv_i64 fp0; 11099 11100 if (ft != 0) { 11101 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11102 } 11103 fp0 = tcg_temp_new_i64(); 11104 gen_load_fpr64(ctx, fp0, fs); 11105 gen_store_fpr64(ctx, fp0, fd); 11106 tcg_temp_free_i64(fp0); 11107 gen_set_label(l1); 11108 } 11109 break; 11110 case OPC_MOVN_PS: 11111 check_ps(ctx); 11112 { 11113 TCGLabel *l1 = gen_new_label(); 11114 TCGv_i64 fp0; 11115 11116 if (ft != 0) { 11117 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11118 fp0 = tcg_temp_new_i64(); 11119 gen_load_fpr64(ctx, fp0, fs); 11120 gen_store_fpr64(ctx, fp0, fd); 11121 tcg_temp_free_i64(fp0); 11122 gen_set_label(l1); 11123 } 11124 } 11125 break; 11126 case OPC_ADDR_PS: 11127 check_ps(ctx); 11128 { 11129 TCGv_i64 fp0 = tcg_temp_new_i64(); 11130 TCGv_i64 fp1 = tcg_temp_new_i64(); 11131 11132 gen_load_fpr64(ctx, fp0, ft); 11133 gen_load_fpr64(ctx, fp1, fs); 11134 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11135 tcg_temp_free_i64(fp1); 11136 gen_store_fpr64(ctx, fp0, fd); 11137 tcg_temp_free_i64(fp0); 11138 } 11139 break; 11140 case OPC_MULR_PS: 11141 check_ps(ctx); 11142 { 11143 TCGv_i64 fp0 = tcg_temp_new_i64(); 11144 TCGv_i64 fp1 = tcg_temp_new_i64(); 11145 11146 gen_load_fpr64(ctx, fp0, ft); 11147 gen_load_fpr64(ctx, fp1, fs); 11148 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11149 tcg_temp_free_i64(fp1); 11150 gen_store_fpr64(ctx, fp0, fd); 11151 tcg_temp_free_i64(fp0); 11152 } 11153 break; 11154 case OPC_RECIP2_PS: 11155 check_ps(ctx); 11156 { 11157 TCGv_i64 fp0 = tcg_temp_new_i64(); 11158 TCGv_i64 fp1 = tcg_temp_new_i64(); 11159 11160 gen_load_fpr64(ctx, fp0, fs); 11161 gen_load_fpr64(ctx, fp1, ft); 11162 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11163 tcg_temp_free_i64(fp1); 11164 gen_store_fpr64(ctx, fp0, fd); 11165 tcg_temp_free_i64(fp0); 11166 } 11167 break; 11168 case OPC_RECIP1_PS: 11169 check_ps(ctx); 11170 { 11171 TCGv_i64 fp0 = tcg_temp_new_i64(); 11172 11173 gen_load_fpr64(ctx, fp0, fs); 11174 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11175 gen_store_fpr64(ctx, fp0, fd); 11176 tcg_temp_free_i64(fp0); 11177 } 11178 break; 11179 case OPC_RSQRT1_PS: 11180 check_ps(ctx); 11181 { 11182 TCGv_i64 fp0 = tcg_temp_new_i64(); 11183 11184 gen_load_fpr64(ctx, fp0, fs); 11185 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11186 gen_store_fpr64(ctx, fp0, fd); 11187 tcg_temp_free_i64(fp0); 11188 } 11189 break; 11190 case OPC_RSQRT2_PS: 11191 check_ps(ctx); 11192 { 11193 TCGv_i64 fp0 = tcg_temp_new_i64(); 11194 TCGv_i64 fp1 = tcg_temp_new_i64(); 11195 11196 gen_load_fpr64(ctx, fp0, fs); 11197 gen_load_fpr64(ctx, fp1, ft); 11198 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11199 tcg_temp_free_i64(fp1); 11200 gen_store_fpr64(ctx, fp0, fd); 11201 tcg_temp_free_i64(fp0); 11202 } 11203 break; 11204 case OPC_CVT_S_PU: 11205 check_cp1_64bitmode(ctx); 11206 { 11207 TCGv_i32 fp0 = tcg_temp_new_i32(); 11208 11209 gen_load_fpr32h(ctx, fp0, fs); 11210 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11211 gen_store_fpr32(ctx, fp0, fd); 11212 tcg_temp_free_i32(fp0); 11213 } 11214 break; 11215 case OPC_CVT_PW_PS: 11216 check_ps(ctx); 11217 { 11218 TCGv_i64 fp0 = tcg_temp_new_i64(); 11219 11220 gen_load_fpr64(ctx, fp0, fs); 11221 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11222 gen_store_fpr64(ctx, fp0, fd); 11223 tcg_temp_free_i64(fp0); 11224 } 11225 break; 11226 case OPC_CVT_S_PL: 11227 check_cp1_64bitmode(ctx); 11228 { 11229 TCGv_i32 fp0 = tcg_temp_new_i32(); 11230 11231 gen_load_fpr32(ctx, fp0, fs); 11232 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11233 gen_store_fpr32(ctx, fp0, fd); 11234 tcg_temp_free_i32(fp0); 11235 } 11236 break; 11237 case OPC_PLL_PS: 11238 check_ps(ctx); 11239 { 11240 TCGv_i32 fp0 = tcg_temp_new_i32(); 11241 TCGv_i32 fp1 = tcg_temp_new_i32(); 11242 11243 gen_load_fpr32(ctx, fp0, fs); 11244 gen_load_fpr32(ctx, fp1, ft); 11245 gen_store_fpr32h(ctx, fp0, fd); 11246 gen_store_fpr32(ctx, fp1, fd); 11247 tcg_temp_free_i32(fp0); 11248 tcg_temp_free_i32(fp1); 11249 } 11250 break; 11251 case OPC_PLU_PS: 11252 check_ps(ctx); 11253 { 11254 TCGv_i32 fp0 = tcg_temp_new_i32(); 11255 TCGv_i32 fp1 = tcg_temp_new_i32(); 11256 11257 gen_load_fpr32(ctx, fp0, fs); 11258 gen_load_fpr32h(ctx, fp1, ft); 11259 gen_store_fpr32(ctx, fp1, fd); 11260 gen_store_fpr32h(ctx, fp0, fd); 11261 tcg_temp_free_i32(fp0); 11262 tcg_temp_free_i32(fp1); 11263 } 11264 break; 11265 case OPC_PUL_PS: 11266 check_ps(ctx); 11267 { 11268 TCGv_i32 fp0 = tcg_temp_new_i32(); 11269 TCGv_i32 fp1 = tcg_temp_new_i32(); 11270 11271 gen_load_fpr32h(ctx, fp0, fs); 11272 gen_load_fpr32(ctx, fp1, ft); 11273 gen_store_fpr32(ctx, fp1, fd); 11274 gen_store_fpr32h(ctx, fp0, fd); 11275 tcg_temp_free_i32(fp0); 11276 tcg_temp_free_i32(fp1); 11277 } 11278 break; 11279 case OPC_PUU_PS: 11280 check_ps(ctx); 11281 { 11282 TCGv_i32 fp0 = tcg_temp_new_i32(); 11283 TCGv_i32 fp1 = tcg_temp_new_i32(); 11284 11285 gen_load_fpr32h(ctx, fp0, fs); 11286 gen_load_fpr32h(ctx, fp1, ft); 11287 gen_store_fpr32(ctx, fp1, fd); 11288 gen_store_fpr32h(ctx, fp0, fd); 11289 tcg_temp_free_i32(fp0); 11290 tcg_temp_free_i32(fp1); 11291 } 11292 break; 11293 case OPC_CMP_F_PS: 11294 case OPC_CMP_UN_PS: 11295 case OPC_CMP_EQ_PS: 11296 case OPC_CMP_UEQ_PS: 11297 case OPC_CMP_OLT_PS: 11298 case OPC_CMP_ULT_PS: 11299 case OPC_CMP_OLE_PS: 11300 case OPC_CMP_ULE_PS: 11301 case OPC_CMP_SF_PS: 11302 case OPC_CMP_NGLE_PS: 11303 case OPC_CMP_SEQ_PS: 11304 case OPC_CMP_NGL_PS: 11305 case OPC_CMP_LT_PS: 11306 case OPC_CMP_NGE_PS: 11307 case OPC_CMP_LE_PS: 11308 case OPC_CMP_NGT_PS: 11309 if (ctx->opcode & (1 << 6)) { 11310 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11311 } else { 11312 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11313 } 11314 break; 11315 default: 11316 MIPS_INVAL("farith"); 11317 gen_reserved_instruction(ctx); 11318 return; 11319 } 11320 } 11321 11322 /* Coprocessor 3 (FPU) */ 11323 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11324 int fd, int fs, int base, int index) 11325 { 11326 TCGv t0 = tcg_temp_new(); 11327 11328 if (base == 0) { 11329 gen_load_gpr(t0, index); 11330 } else if (index == 0) { 11331 gen_load_gpr(t0, base); 11332 } else { 11333 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11334 } 11335 /* 11336 * Don't do NOP if destination is zero: we must perform the actual 11337 * memory access. 11338 */ 11339 switch (opc) { 11340 case OPC_LWXC1: 11341 check_cop1x(ctx); 11342 { 11343 TCGv_i32 fp0 = tcg_temp_new_i32(); 11344 11345 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11346 tcg_gen_trunc_tl_i32(fp0, t0); 11347 gen_store_fpr32(ctx, fp0, fd); 11348 tcg_temp_free_i32(fp0); 11349 } 11350 break; 11351 case OPC_LDXC1: 11352 check_cop1x(ctx); 11353 check_cp1_registers(ctx, fd); 11354 { 11355 TCGv_i64 fp0 = tcg_temp_new_i64(); 11356 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11357 gen_store_fpr64(ctx, fp0, fd); 11358 tcg_temp_free_i64(fp0); 11359 } 11360 break; 11361 case OPC_LUXC1: 11362 check_cp1_64bitmode(ctx); 11363 tcg_gen_andi_tl(t0, t0, ~0x7); 11364 { 11365 TCGv_i64 fp0 = tcg_temp_new_i64(); 11366 11367 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11368 gen_store_fpr64(ctx, fp0, fd); 11369 tcg_temp_free_i64(fp0); 11370 } 11371 break; 11372 case OPC_SWXC1: 11373 check_cop1x(ctx); 11374 { 11375 TCGv_i32 fp0 = tcg_temp_new_i32(); 11376 gen_load_fpr32(ctx, fp0, fs); 11377 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11378 tcg_temp_free_i32(fp0); 11379 } 11380 break; 11381 case OPC_SDXC1: 11382 check_cop1x(ctx); 11383 check_cp1_registers(ctx, fs); 11384 { 11385 TCGv_i64 fp0 = tcg_temp_new_i64(); 11386 gen_load_fpr64(ctx, fp0, fs); 11387 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11388 tcg_temp_free_i64(fp0); 11389 } 11390 break; 11391 case OPC_SUXC1: 11392 check_cp1_64bitmode(ctx); 11393 tcg_gen_andi_tl(t0, t0, ~0x7); 11394 { 11395 TCGv_i64 fp0 = tcg_temp_new_i64(); 11396 gen_load_fpr64(ctx, fp0, fs); 11397 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11398 tcg_temp_free_i64(fp0); 11399 } 11400 break; 11401 } 11402 tcg_temp_free(t0); 11403 } 11404 11405 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11406 int fd, int fr, int fs, int ft) 11407 { 11408 switch (opc) { 11409 case OPC_ALNV_PS: 11410 check_ps(ctx); 11411 { 11412 TCGv t0 = tcg_temp_local_new(); 11413 TCGv_i32 fp = tcg_temp_new_i32(); 11414 TCGv_i32 fph = tcg_temp_new_i32(); 11415 TCGLabel *l1 = gen_new_label(); 11416 TCGLabel *l2 = gen_new_label(); 11417 11418 gen_load_gpr(t0, fr); 11419 tcg_gen_andi_tl(t0, t0, 0x7); 11420 11421 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11422 gen_load_fpr32(ctx, fp, fs); 11423 gen_load_fpr32h(ctx, fph, fs); 11424 gen_store_fpr32(ctx, fp, fd); 11425 gen_store_fpr32h(ctx, fph, fd); 11426 tcg_gen_br(l2); 11427 gen_set_label(l1); 11428 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11429 tcg_temp_free(t0); 11430 if (cpu_is_bigendian(ctx)) { 11431 gen_load_fpr32(ctx, fp, fs); 11432 gen_load_fpr32h(ctx, fph, ft); 11433 gen_store_fpr32h(ctx, fp, fd); 11434 gen_store_fpr32(ctx, fph, fd); 11435 } else { 11436 gen_load_fpr32h(ctx, fph, fs); 11437 gen_load_fpr32(ctx, fp, ft); 11438 gen_store_fpr32(ctx, fph, fd); 11439 gen_store_fpr32h(ctx, fp, fd); 11440 } 11441 gen_set_label(l2); 11442 tcg_temp_free_i32(fp); 11443 tcg_temp_free_i32(fph); 11444 } 11445 break; 11446 case OPC_MADD_S: 11447 check_cop1x(ctx); 11448 { 11449 TCGv_i32 fp0 = tcg_temp_new_i32(); 11450 TCGv_i32 fp1 = tcg_temp_new_i32(); 11451 TCGv_i32 fp2 = tcg_temp_new_i32(); 11452 11453 gen_load_fpr32(ctx, fp0, fs); 11454 gen_load_fpr32(ctx, fp1, ft); 11455 gen_load_fpr32(ctx, fp2, fr); 11456 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11457 tcg_temp_free_i32(fp0); 11458 tcg_temp_free_i32(fp1); 11459 gen_store_fpr32(ctx, fp2, fd); 11460 tcg_temp_free_i32(fp2); 11461 } 11462 break; 11463 case OPC_MADD_D: 11464 check_cop1x(ctx); 11465 check_cp1_registers(ctx, fd | fs | ft | fr); 11466 { 11467 TCGv_i64 fp0 = tcg_temp_new_i64(); 11468 TCGv_i64 fp1 = tcg_temp_new_i64(); 11469 TCGv_i64 fp2 = tcg_temp_new_i64(); 11470 11471 gen_load_fpr64(ctx, fp0, fs); 11472 gen_load_fpr64(ctx, fp1, ft); 11473 gen_load_fpr64(ctx, fp2, fr); 11474 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11475 tcg_temp_free_i64(fp0); 11476 tcg_temp_free_i64(fp1); 11477 gen_store_fpr64(ctx, fp2, fd); 11478 tcg_temp_free_i64(fp2); 11479 } 11480 break; 11481 case OPC_MADD_PS: 11482 check_ps(ctx); 11483 { 11484 TCGv_i64 fp0 = tcg_temp_new_i64(); 11485 TCGv_i64 fp1 = tcg_temp_new_i64(); 11486 TCGv_i64 fp2 = tcg_temp_new_i64(); 11487 11488 gen_load_fpr64(ctx, fp0, fs); 11489 gen_load_fpr64(ctx, fp1, ft); 11490 gen_load_fpr64(ctx, fp2, fr); 11491 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11492 tcg_temp_free_i64(fp0); 11493 tcg_temp_free_i64(fp1); 11494 gen_store_fpr64(ctx, fp2, fd); 11495 tcg_temp_free_i64(fp2); 11496 } 11497 break; 11498 case OPC_MSUB_S: 11499 check_cop1x(ctx); 11500 { 11501 TCGv_i32 fp0 = tcg_temp_new_i32(); 11502 TCGv_i32 fp1 = tcg_temp_new_i32(); 11503 TCGv_i32 fp2 = tcg_temp_new_i32(); 11504 11505 gen_load_fpr32(ctx, fp0, fs); 11506 gen_load_fpr32(ctx, fp1, ft); 11507 gen_load_fpr32(ctx, fp2, fr); 11508 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11509 tcg_temp_free_i32(fp0); 11510 tcg_temp_free_i32(fp1); 11511 gen_store_fpr32(ctx, fp2, fd); 11512 tcg_temp_free_i32(fp2); 11513 } 11514 break; 11515 case OPC_MSUB_D: 11516 check_cop1x(ctx); 11517 check_cp1_registers(ctx, fd | fs | ft | fr); 11518 { 11519 TCGv_i64 fp0 = tcg_temp_new_i64(); 11520 TCGv_i64 fp1 = tcg_temp_new_i64(); 11521 TCGv_i64 fp2 = tcg_temp_new_i64(); 11522 11523 gen_load_fpr64(ctx, fp0, fs); 11524 gen_load_fpr64(ctx, fp1, ft); 11525 gen_load_fpr64(ctx, fp2, fr); 11526 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11527 tcg_temp_free_i64(fp0); 11528 tcg_temp_free_i64(fp1); 11529 gen_store_fpr64(ctx, fp2, fd); 11530 tcg_temp_free_i64(fp2); 11531 } 11532 break; 11533 case OPC_MSUB_PS: 11534 check_ps(ctx); 11535 { 11536 TCGv_i64 fp0 = tcg_temp_new_i64(); 11537 TCGv_i64 fp1 = tcg_temp_new_i64(); 11538 TCGv_i64 fp2 = tcg_temp_new_i64(); 11539 11540 gen_load_fpr64(ctx, fp0, fs); 11541 gen_load_fpr64(ctx, fp1, ft); 11542 gen_load_fpr64(ctx, fp2, fr); 11543 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11544 tcg_temp_free_i64(fp0); 11545 tcg_temp_free_i64(fp1); 11546 gen_store_fpr64(ctx, fp2, fd); 11547 tcg_temp_free_i64(fp2); 11548 } 11549 break; 11550 case OPC_NMADD_S: 11551 check_cop1x(ctx); 11552 { 11553 TCGv_i32 fp0 = tcg_temp_new_i32(); 11554 TCGv_i32 fp1 = tcg_temp_new_i32(); 11555 TCGv_i32 fp2 = tcg_temp_new_i32(); 11556 11557 gen_load_fpr32(ctx, fp0, fs); 11558 gen_load_fpr32(ctx, fp1, ft); 11559 gen_load_fpr32(ctx, fp2, fr); 11560 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11561 tcg_temp_free_i32(fp0); 11562 tcg_temp_free_i32(fp1); 11563 gen_store_fpr32(ctx, fp2, fd); 11564 tcg_temp_free_i32(fp2); 11565 } 11566 break; 11567 case OPC_NMADD_D: 11568 check_cop1x(ctx); 11569 check_cp1_registers(ctx, fd | fs | ft | fr); 11570 { 11571 TCGv_i64 fp0 = tcg_temp_new_i64(); 11572 TCGv_i64 fp1 = tcg_temp_new_i64(); 11573 TCGv_i64 fp2 = tcg_temp_new_i64(); 11574 11575 gen_load_fpr64(ctx, fp0, fs); 11576 gen_load_fpr64(ctx, fp1, ft); 11577 gen_load_fpr64(ctx, fp2, fr); 11578 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11579 tcg_temp_free_i64(fp0); 11580 tcg_temp_free_i64(fp1); 11581 gen_store_fpr64(ctx, fp2, fd); 11582 tcg_temp_free_i64(fp2); 11583 } 11584 break; 11585 case OPC_NMADD_PS: 11586 check_ps(ctx); 11587 { 11588 TCGv_i64 fp0 = tcg_temp_new_i64(); 11589 TCGv_i64 fp1 = tcg_temp_new_i64(); 11590 TCGv_i64 fp2 = tcg_temp_new_i64(); 11591 11592 gen_load_fpr64(ctx, fp0, fs); 11593 gen_load_fpr64(ctx, fp1, ft); 11594 gen_load_fpr64(ctx, fp2, fr); 11595 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11596 tcg_temp_free_i64(fp0); 11597 tcg_temp_free_i64(fp1); 11598 gen_store_fpr64(ctx, fp2, fd); 11599 tcg_temp_free_i64(fp2); 11600 } 11601 break; 11602 case OPC_NMSUB_S: 11603 check_cop1x(ctx); 11604 { 11605 TCGv_i32 fp0 = tcg_temp_new_i32(); 11606 TCGv_i32 fp1 = tcg_temp_new_i32(); 11607 TCGv_i32 fp2 = tcg_temp_new_i32(); 11608 11609 gen_load_fpr32(ctx, fp0, fs); 11610 gen_load_fpr32(ctx, fp1, ft); 11611 gen_load_fpr32(ctx, fp2, fr); 11612 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11613 tcg_temp_free_i32(fp0); 11614 tcg_temp_free_i32(fp1); 11615 gen_store_fpr32(ctx, fp2, fd); 11616 tcg_temp_free_i32(fp2); 11617 } 11618 break; 11619 case OPC_NMSUB_D: 11620 check_cop1x(ctx); 11621 check_cp1_registers(ctx, fd | fs | ft | fr); 11622 { 11623 TCGv_i64 fp0 = tcg_temp_new_i64(); 11624 TCGv_i64 fp1 = tcg_temp_new_i64(); 11625 TCGv_i64 fp2 = tcg_temp_new_i64(); 11626 11627 gen_load_fpr64(ctx, fp0, fs); 11628 gen_load_fpr64(ctx, fp1, ft); 11629 gen_load_fpr64(ctx, fp2, fr); 11630 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11631 tcg_temp_free_i64(fp0); 11632 tcg_temp_free_i64(fp1); 11633 gen_store_fpr64(ctx, fp2, fd); 11634 tcg_temp_free_i64(fp2); 11635 } 11636 break; 11637 case OPC_NMSUB_PS: 11638 check_ps(ctx); 11639 { 11640 TCGv_i64 fp0 = tcg_temp_new_i64(); 11641 TCGv_i64 fp1 = tcg_temp_new_i64(); 11642 TCGv_i64 fp2 = tcg_temp_new_i64(); 11643 11644 gen_load_fpr64(ctx, fp0, fs); 11645 gen_load_fpr64(ctx, fp1, ft); 11646 gen_load_fpr64(ctx, fp2, fr); 11647 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11648 tcg_temp_free_i64(fp0); 11649 tcg_temp_free_i64(fp1); 11650 gen_store_fpr64(ctx, fp2, fd); 11651 tcg_temp_free_i64(fp2); 11652 } 11653 break; 11654 default: 11655 MIPS_INVAL("flt3_arith"); 11656 gen_reserved_instruction(ctx); 11657 return; 11658 } 11659 } 11660 11661 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11662 { 11663 TCGv t0; 11664 11665 #if !defined(CONFIG_USER_ONLY) 11666 /* 11667 * The Linux kernel will emulate rdhwr if it's not supported natively. 11668 * Therefore only check the ISA in system mode. 11669 */ 11670 check_insn(ctx, ISA_MIPS_R2); 11671 #endif 11672 t0 = tcg_temp_new(); 11673 11674 switch (rd) { 11675 case 0: 11676 gen_helper_rdhwr_cpunum(t0, cpu_env); 11677 gen_store_gpr(t0, rt); 11678 break; 11679 case 1: 11680 gen_helper_rdhwr_synci_step(t0, cpu_env); 11681 gen_store_gpr(t0, rt); 11682 break; 11683 case 2: 11684 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11685 gen_io_start(); 11686 } 11687 gen_helper_rdhwr_cc(t0, cpu_env); 11688 gen_store_gpr(t0, rt); 11689 /* 11690 * Break the TB to be able to take timer interrupts immediately 11691 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11692 * we break completely out of translated code. 11693 */ 11694 gen_save_pc(ctx->base.pc_next + 4); 11695 ctx->base.is_jmp = DISAS_EXIT; 11696 break; 11697 case 3: 11698 gen_helper_rdhwr_ccres(t0, cpu_env); 11699 gen_store_gpr(t0, rt); 11700 break; 11701 case 4: 11702 check_insn(ctx, ISA_MIPS_R6); 11703 if (sel != 0) { 11704 /* 11705 * Performance counter registers are not implemented other than 11706 * control register 0. 11707 */ 11708 generate_exception(ctx, EXCP_RI); 11709 } 11710 gen_helper_rdhwr_performance(t0, cpu_env); 11711 gen_store_gpr(t0, rt); 11712 break; 11713 case 5: 11714 check_insn(ctx, ISA_MIPS_R6); 11715 gen_helper_rdhwr_xnp(t0, cpu_env); 11716 gen_store_gpr(t0, rt); 11717 break; 11718 case 29: 11719 #if defined(CONFIG_USER_ONLY) 11720 tcg_gen_ld_tl(t0, cpu_env, 11721 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11722 gen_store_gpr(t0, rt); 11723 break; 11724 #else 11725 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11726 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11727 tcg_gen_ld_tl(t0, cpu_env, 11728 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11729 gen_store_gpr(t0, rt); 11730 } else { 11731 gen_reserved_instruction(ctx); 11732 } 11733 break; 11734 #endif 11735 default: /* Invalid */ 11736 MIPS_INVAL("rdhwr"); 11737 gen_reserved_instruction(ctx); 11738 break; 11739 } 11740 tcg_temp_free(t0); 11741 } 11742 11743 static inline void clear_branch_hflags(DisasContext *ctx) 11744 { 11745 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11746 if (ctx->base.is_jmp == DISAS_NEXT) { 11747 save_cpu_state(ctx, 0); 11748 } else { 11749 /* 11750 * It is not safe to save ctx->hflags as hflags may be changed 11751 * in execution time by the instruction in delay / forbidden slot. 11752 */ 11753 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11754 } 11755 } 11756 11757 static void gen_branch(DisasContext *ctx, int insn_bytes) 11758 { 11759 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11760 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11761 /* Branches completion */ 11762 clear_branch_hflags(ctx); 11763 ctx->base.is_jmp = DISAS_NORETURN; 11764 /* FIXME: Need to clear can_do_io. */ 11765 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11766 case MIPS_HFLAG_FBNSLOT: 11767 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11768 break; 11769 case MIPS_HFLAG_B: 11770 /* unconditional branch */ 11771 if (proc_hflags & MIPS_HFLAG_BX) { 11772 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11773 } 11774 gen_goto_tb(ctx, 0, ctx->btarget); 11775 break; 11776 case MIPS_HFLAG_BL: 11777 /* blikely taken case */ 11778 gen_goto_tb(ctx, 0, ctx->btarget); 11779 break; 11780 case MIPS_HFLAG_BC: 11781 /* Conditional branch */ 11782 { 11783 TCGLabel *l1 = gen_new_label(); 11784 11785 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11786 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11787 gen_set_label(l1); 11788 gen_goto_tb(ctx, 0, ctx->btarget); 11789 } 11790 break; 11791 case MIPS_HFLAG_BR: 11792 /* unconditional branch to register */ 11793 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11794 TCGv t0 = tcg_temp_new(); 11795 TCGv_i32 t1 = tcg_temp_new_i32(); 11796 11797 tcg_gen_andi_tl(t0, btarget, 0x1); 11798 tcg_gen_trunc_tl_i32(t1, t0); 11799 tcg_temp_free(t0); 11800 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11801 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11802 tcg_gen_or_i32(hflags, hflags, t1); 11803 tcg_temp_free_i32(t1); 11804 11805 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11806 } else { 11807 tcg_gen_mov_tl(cpu_PC, btarget); 11808 } 11809 tcg_gen_lookup_and_goto_ptr(); 11810 break; 11811 default: 11812 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11813 gen_reserved_instruction(ctx); 11814 } 11815 } 11816 } 11817 11818 /* Compact Branches */ 11819 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11820 int rs, int rt, int32_t offset) 11821 { 11822 int bcond_compute = 0; 11823 TCGv t0 = tcg_temp_new(); 11824 TCGv t1 = tcg_temp_new(); 11825 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11826 11827 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11828 #ifdef MIPS_DEBUG_DISAS 11829 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11830 "\n", ctx->base.pc_next); 11831 #endif 11832 gen_reserved_instruction(ctx); 11833 goto out; 11834 } 11835 11836 /* Load needed operands and calculate btarget */ 11837 switch (opc) { 11838 /* compact branch */ 11839 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11840 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11841 gen_load_gpr(t0, rs); 11842 gen_load_gpr(t1, rt); 11843 bcond_compute = 1; 11844 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11845 if (rs <= rt && rs == 0) { 11846 /* OPC_BEQZALC, OPC_BNEZALC */ 11847 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11848 } 11849 break; 11850 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11851 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11852 gen_load_gpr(t0, rs); 11853 gen_load_gpr(t1, rt); 11854 bcond_compute = 1; 11855 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11856 break; 11857 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11858 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11859 if (rs == 0 || rs == rt) { 11860 /* OPC_BLEZALC, OPC_BGEZALC */ 11861 /* OPC_BGTZALC, OPC_BLTZALC */ 11862 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11863 } 11864 gen_load_gpr(t0, rs); 11865 gen_load_gpr(t1, rt); 11866 bcond_compute = 1; 11867 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11868 break; 11869 case OPC_BC: 11870 case OPC_BALC: 11871 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11872 break; 11873 case OPC_BEQZC: 11874 case OPC_BNEZC: 11875 if (rs != 0) { 11876 /* OPC_BEQZC, OPC_BNEZC */ 11877 gen_load_gpr(t0, rs); 11878 bcond_compute = 1; 11879 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11880 } else { 11881 /* OPC_JIC, OPC_JIALC */ 11882 TCGv tbase = tcg_temp_new(); 11883 TCGv toffset = tcg_constant_tl(offset); 11884 11885 gen_load_gpr(tbase, rt); 11886 gen_op_addr_add(ctx, btarget, tbase, toffset); 11887 tcg_temp_free(tbase); 11888 } 11889 break; 11890 default: 11891 MIPS_INVAL("Compact branch/jump"); 11892 gen_reserved_instruction(ctx); 11893 goto out; 11894 } 11895 11896 if (bcond_compute == 0) { 11897 /* Unconditional compact branch */ 11898 switch (opc) { 11899 case OPC_JIALC: 11900 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11901 /* Fallthrough */ 11902 case OPC_JIC: 11903 ctx->hflags |= MIPS_HFLAG_BR; 11904 break; 11905 case OPC_BALC: 11906 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11907 /* Fallthrough */ 11908 case OPC_BC: 11909 ctx->hflags |= MIPS_HFLAG_B; 11910 break; 11911 default: 11912 MIPS_INVAL("Compact branch/jump"); 11913 gen_reserved_instruction(ctx); 11914 goto out; 11915 } 11916 11917 /* Generating branch here as compact branches don't have delay slot */ 11918 gen_branch(ctx, 4); 11919 } else { 11920 /* Conditional compact branch */ 11921 TCGLabel *fs = gen_new_label(); 11922 save_cpu_state(ctx, 0); 11923 11924 switch (opc) { 11925 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11926 if (rs == 0 && rt != 0) { 11927 /* OPC_BLEZALC */ 11928 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11929 } else if (rs != 0 && rt != 0 && rs == rt) { 11930 /* OPC_BGEZALC */ 11931 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11932 } else { 11933 /* OPC_BGEUC */ 11934 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11935 } 11936 break; 11937 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11938 if (rs == 0 && rt != 0) { 11939 /* OPC_BGTZALC */ 11940 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11941 } else if (rs != 0 && rt != 0 && rs == rt) { 11942 /* OPC_BLTZALC */ 11943 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11944 } else { 11945 /* OPC_BLTUC */ 11946 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11947 } 11948 break; 11949 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11950 if (rs == 0 && rt != 0) { 11951 /* OPC_BLEZC */ 11952 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11953 } else if (rs != 0 && rt != 0 && rs == rt) { 11954 /* OPC_BGEZC */ 11955 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11956 } else { 11957 /* OPC_BGEC */ 11958 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11959 } 11960 break; 11961 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11962 if (rs == 0 && rt != 0) { 11963 /* OPC_BGTZC */ 11964 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11965 } else if (rs != 0 && rt != 0 && rs == rt) { 11966 /* OPC_BLTZC */ 11967 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11968 } else { 11969 /* OPC_BLTC */ 11970 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11971 } 11972 break; 11973 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11974 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11975 if (rs >= rt) { 11976 /* OPC_BOVC, OPC_BNVC */ 11977 TCGv t2 = tcg_temp_new(); 11978 TCGv t3 = tcg_temp_new(); 11979 TCGv t4 = tcg_temp_new(); 11980 TCGv input_overflow = tcg_temp_new(); 11981 11982 gen_load_gpr(t0, rs); 11983 gen_load_gpr(t1, rt); 11984 tcg_gen_ext32s_tl(t2, t0); 11985 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11986 tcg_gen_ext32s_tl(t3, t1); 11987 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11988 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11989 11990 tcg_gen_add_tl(t4, t2, t3); 11991 tcg_gen_ext32s_tl(t4, t4); 11992 tcg_gen_xor_tl(t2, t2, t3); 11993 tcg_gen_xor_tl(t3, t4, t3); 11994 tcg_gen_andc_tl(t2, t3, t2); 11995 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11996 tcg_gen_or_tl(t4, t4, input_overflow); 11997 if (opc == OPC_BOVC) { 11998 /* OPC_BOVC */ 11999 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12000 } else { 12001 /* OPC_BNVC */ 12002 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12003 } 12004 tcg_temp_free(input_overflow); 12005 tcg_temp_free(t4); 12006 tcg_temp_free(t3); 12007 tcg_temp_free(t2); 12008 } else if (rs < rt && rs == 0) { 12009 /* OPC_BEQZALC, OPC_BNEZALC */ 12010 if (opc == OPC_BEQZALC) { 12011 /* OPC_BEQZALC */ 12012 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12013 } else { 12014 /* OPC_BNEZALC */ 12015 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12016 } 12017 } else { 12018 /* OPC_BEQC, OPC_BNEC */ 12019 if (opc == OPC_BEQC) { 12020 /* OPC_BEQC */ 12021 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12022 } else { 12023 /* OPC_BNEC */ 12024 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12025 } 12026 } 12027 break; 12028 case OPC_BEQZC: 12029 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12030 break; 12031 case OPC_BNEZC: 12032 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12033 break; 12034 default: 12035 MIPS_INVAL("Compact conditional branch/jump"); 12036 gen_reserved_instruction(ctx); 12037 goto out; 12038 } 12039 12040 /* Generating branch here as compact branches don't have delay slot */ 12041 gen_goto_tb(ctx, 1, ctx->btarget); 12042 gen_set_label(fs); 12043 12044 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12045 } 12046 12047 out: 12048 tcg_temp_free(t0); 12049 tcg_temp_free(t1); 12050 } 12051 12052 void gen_addiupc(DisasContext *ctx, int rx, int imm, 12053 int is_64_bit, int extended) 12054 { 12055 TCGv t0; 12056 12057 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12058 gen_reserved_instruction(ctx); 12059 return; 12060 } 12061 12062 t0 = tcg_temp_new(); 12063 12064 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12065 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12066 if (!is_64_bit) { 12067 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12068 } 12069 12070 tcg_temp_free(t0); 12071 } 12072 12073 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12074 int16_t offset) 12075 { 12076 TCGv_i32 t0 = tcg_const_i32(op); 12077 TCGv t1 = tcg_temp_new(); 12078 gen_base_offset_addr(ctx, t1, base, offset); 12079 gen_helper_cache(cpu_env, t1, t0); 12080 tcg_temp_free(t1); 12081 tcg_temp_free_i32(t0); 12082 } 12083 12084 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 12085 { 12086 #ifdef CONFIG_USER_ONLY 12087 return false; 12088 #else 12089 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 12090 return semihosting_enabled(is_user) && sdbbp_code == 1; 12091 #endif 12092 } 12093 12094 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 12095 { 12096 TCGv t0 = tcg_temp_new(); 12097 TCGv t1 = tcg_temp_new(); 12098 12099 gen_load_gpr(t0, base); 12100 12101 if (index != 0) { 12102 gen_load_gpr(t1, index); 12103 tcg_gen_shli_tl(t1, t1, 2); 12104 gen_op_addr_add(ctx, t0, t1, t0); 12105 } 12106 12107 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 12108 gen_store_gpr(t1, rd); 12109 12110 tcg_temp_free(t0); 12111 tcg_temp_free(t1); 12112 } 12113 12114 static void gen_sync(int stype) 12115 { 12116 TCGBar tcg_mo = TCG_BAR_SC; 12117 12118 switch (stype) { 12119 case 0x4: /* SYNC_WMB */ 12120 tcg_mo |= TCG_MO_ST_ST; 12121 break; 12122 case 0x10: /* SYNC_MB */ 12123 tcg_mo |= TCG_MO_ALL; 12124 break; 12125 case 0x11: /* SYNC_ACQUIRE */ 12126 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 12127 break; 12128 case 0x12: /* SYNC_RELEASE */ 12129 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 12130 break; 12131 case 0x13: /* SYNC_RMB */ 12132 tcg_mo |= TCG_MO_LD_LD; 12133 break; 12134 default: 12135 tcg_mo |= TCG_MO_ALL; 12136 break; 12137 } 12138 12139 tcg_gen_mb(tcg_mo); 12140 } 12141 12142 /* ISA extensions (ASEs) */ 12143 12144 /* MIPS16 extension to MIPS32 */ 12145 #include "mips16e_translate.c.inc" 12146 12147 /* microMIPS extension to MIPS32/MIPS64 */ 12148 12149 /* 12150 * Values for microMIPS fmt field. Variable-width, depending on which 12151 * formats the instruction supports. 12152 */ 12153 enum { 12154 FMT_SD_S = 0, 12155 FMT_SD_D = 1, 12156 12157 FMT_SDPS_S = 0, 12158 FMT_SDPS_D = 1, 12159 FMT_SDPS_PS = 2, 12160 12161 FMT_SWL_S = 0, 12162 FMT_SWL_W = 1, 12163 FMT_SWL_L = 2, 12164 12165 FMT_DWL_D = 0, 12166 FMT_DWL_W = 1, 12167 FMT_DWL_L = 2 12168 }; 12169 12170 #include "micromips_translate.c.inc" 12171 12172 #include "nanomips_translate.c.inc" 12173 12174 /* MIPSDSP functions. */ 12175 12176 /* Indexed load is not for DSP only */ 12177 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 12178 int rd, int base, int offset) 12179 { 12180 TCGv t0; 12181 12182 if (!(ctx->insn_flags & INSN_OCTEON)) { 12183 check_dsp(ctx); 12184 } 12185 t0 = tcg_temp_new(); 12186 12187 if (base == 0) { 12188 gen_load_gpr(t0, offset); 12189 } else if (offset == 0) { 12190 gen_load_gpr(t0, base); 12191 } else { 12192 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 12193 } 12194 12195 switch (opc) { 12196 case OPC_LBUX: 12197 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 12198 gen_store_gpr(t0, rd); 12199 break; 12200 case OPC_LHX: 12201 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 12202 gen_store_gpr(t0, rd); 12203 break; 12204 case OPC_LWX: 12205 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 12206 gen_store_gpr(t0, rd); 12207 break; 12208 #if defined(TARGET_MIPS64) 12209 case OPC_LDX: 12210 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 12211 gen_store_gpr(t0, rd); 12212 break; 12213 #endif 12214 } 12215 tcg_temp_free(t0); 12216 } 12217 12218 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 12219 int ret, int v1, int v2) 12220 { 12221 TCGv v1_t; 12222 TCGv v2_t; 12223 12224 if (ret == 0) { 12225 /* Treat as NOP. */ 12226 return; 12227 } 12228 12229 v1_t = tcg_temp_new(); 12230 v2_t = tcg_temp_new(); 12231 12232 gen_load_gpr(v1_t, v1); 12233 gen_load_gpr(v2_t, v2); 12234 12235 switch (op1) { 12236 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 12237 case OPC_MULT_G_2E: 12238 check_dsp_r2(ctx); 12239 switch (op2) { 12240 case OPC_ADDUH_QB: 12241 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 12242 break; 12243 case OPC_ADDUH_R_QB: 12244 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12245 break; 12246 case OPC_ADDQH_PH: 12247 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 12248 break; 12249 case OPC_ADDQH_R_PH: 12250 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12251 break; 12252 case OPC_ADDQH_W: 12253 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 12254 break; 12255 case OPC_ADDQH_R_W: 12256 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12257 break; 12258 case OPC_SUBUH_QB: 12259 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 12260 break; 12261 case OPC_SUBUH_R_QB: 12262 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12263 break; 12264 case OPC_SUBQH_PH: 12265 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 12266 break; 12267 case OPC_SUBQH_R_PH: 12268 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12269 break; 12270 case OPC_SUBQH_W: 12271 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 12272 break; 12273 case OPC_SUBQH_R_W: 12274 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12275 break; 12276 } 12277 break; 12278 case OPC_ABSQ_S_PH_DSP: 12279 switch (op2) { 12280 case OPC_ABSQ_S_QB: 12281 check_dsp_r2(ctx); 12282 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 12283 break; 12284 case OPC_ABSQ_S_PH: 12285 check_dsp(ctx); 12286 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 12287 break; 12288 case OPC_ABSQ_S_W: 12289 check_dsp(ctx); 12290 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 12291 break; 12292 case OPC_PRECEQ_W_PHL: 12293 check_dsp(ctx); 12294 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 12295 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12296 break; 12297 case OPC_PRECEQ_W_PHR: 12298 check_dsp(ctx); 12299 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 12300 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 12301 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12302 break; 12303 case OPC_PRECEQU_PH_QBL: 12304 check_dsp(ctx); 12305 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 12306 break; 12307 case OPC_PRECEQU_PH_QBR: 12308 check_dsp(ctx); 12309 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 12310 break; 12311 case OPC_PRECEQU_PH_QBLA: 12312 check_dsp(ctx); 12313 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 12314 break; 12315 case OPC_PRECEQU_PH_QBRA: 12316 check_dsp(ctx); 12317 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 12318 break; 12319 case OPC_PRECEU_PH_QBL: 12320 check_dsp(ctx); 12321 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 12322 break; 12323 case OPC_PRECEU_PH_QBR: 12324 check_dsp(ctx); 12325 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 12326 break; 12327 case OPC_PRECEU_PH_QBLA: 12328 check_dsp(ctx); 12329 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 12330 break; 12331 case OPC_PRECEU_PH_QBRA: 12332 check_dsp(ctx); 12333 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 12334 break; 12335 } 12336 break; 12337 case OPC_ADDU_QB_DSP: 12338 switch (op2) { 12339 case OPC_ADDQ_PH: 12340 check_dsp(ctx); 12341 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12342 break; 12343 case OPC_ADDQ_S_PH: 12344 check_dsp(ctx); 12345 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12346 break; 12347 case OPC_ADDQ_S_W: 12348 check_dsp(ctx); 12349 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12350 break; 12351 case OPC_ADDU_QB: 12352 check_dsp(ctx); 12353 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12354 break; 12355 case OPC_ADDU_S_QB: 12356 check_dsp(ctx); 12357 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12358 break; 12359 case OPC_ADDU_PH: 12360 check_dsp_r2(ctx); 12361 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12362 break; 12363 case OPC_ADDU_S_PH: 12364 check_dsp_r2(ctx); 12365 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12366 break; 12367 case OPC_SUBQ_PH: 12368 check_dsp(ctx); 12369 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12370 break; 12371 case OPC_SUBQ_S_PH: 12372 check_dsp(ctx); 12373 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12374 break; 12375 case OPC_SUBQ_S_W: 12376 check_dsp(ctx); 12377 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12378 break; 12379 case OPC_SUBU_QB: 12380 check_dsp(ctx); 12381 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12382 break; 12383 case OPC_SUBU_S_QB: 12384 check_dsp(ctx); 12385 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12386 break; 12387 case OPC_SUBU_PH: 12388 check_dsp_r2(ctx); 12389 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12390 break; 12391 case OPC_SUBU_S_PH: 12392 check_dsp_r2(ctx); 12393 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12394 break; 12395 case OPC_ADDSC: 12396 check_dsp(ctx); 12397 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12398 break; 12399 case OPC_ADDWC: 12400 check_dsp(ctx); 12401 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12402 break; 12403 case OPC_MODSUB: 12404 check_dsp(ctx); 12405 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 12406 break; 12407 case OPC_RADDU_W_QB: 12408 check_dsp(ctx); 12409 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 12410 break; 12411 } 12412 break; 12413 case OPC_CMPU_EQ_QB_DSP: 12414 switch (op2) { 12415 case OPC_PRECR_QB_PH: 12416 check_dsp_r2(ctx); 12417 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12418 break; 12419 case OPC_PRECRQ_QB_PH: 12420 check_dsp(ctx); 12421 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12422 break; 12423 case OPC_PRECR_SRA_PH_W: 12424 check_dsp_r2(ctx); 12425 { 12426 TCGv_i32 sa_t = tcg_const_i32(v2); 12427 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 12428 cpu_gpr[ret]); 12429 tcg_temp_free_i32(sa_t); 12430 break; 12431 } 12432 case OPC_PRECR_SRA_R_PH_W: 12433 check_dsp_r2(ctx); 12434 { 12435 TCGv_i32 sa_t = tcg_const_i32(v2); 12436 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 12437 cpu_gpr[ret]); 12438 tcg_temp_free_i32(sa_t); 12439 break; 12440 } 12441 case OPC_PRECRQ_PH_W: 12442 check_dsp(ctx); 12443 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 12444 break; 12445 case OPC_PRECRQ_RS_PH_W: 12446 check_dsp(ctx); 12447 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12448 break; 12449 case OPC_PRECRQU_S_QB_PH: 12450 check_dsp(ctx); 12451 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12452 break; 12453 } 12454 break; 12455 #ifdef TARGET_MIPS64 12456 case OPC_ABSQ_S_QH_DSP: 12457 switch (op2) { 12458 case OPC_PRECEQ_L_PWL: 12459 check_dsp(ctx); 12460 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 12461 break; 12462 case OPC_PRECEQ_L_PWR: 12463 check_dsp(ctx); 12464 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 12465 break; 12466 case OPC_PRECEQ_PW_QHL: 12467 check_dsp(ctx); 12468 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 12469 break; 12470 case OPC_PRECEQ_PW_QHR: 12471 check_dsp(ctx); 12472 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 12473 break; 12474 case OPC_PRECEQ_PW_QHLA: 12475 check_dsp(ctx); 12476 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 12477 break; 12478 case OPC_PRECEQ_PW_QHRA: 12479 check_dsp(ctx); 12480 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 12481 break; 12482 case OPC_PRECEQU_QH_OBL: 12483 check_dsp(ctx); 12484 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 12485 break; 12486 case OPC_PRECEQU_QH_OBR: 12487 check_dsp(ctx); 12488 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 12489 break; 12490 case OPC_PRECEQU_QH_OBLA: 12491 check_dsp(ctx); 12492 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 12493 break; 12494 case OPC_PRECEQU_QH_OBRA: 12495 check_dsp(ctx); 12496 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 12497 break; 12498 case OPC_PRECEU_QH_OBL: 12499 check_dsp(ctx); 12500 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 12501 break; 12502 case OPC_PRECEU_QH_OBR: 12503 check_dsp(ctx); 12504 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 12505 break; 12506 case OPC_PRECEU_QH_OBLA: 12507 check_dsp(ctx); 12508 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 12509 break; 12510 case OPC_PRECEU_QH_OBRA: 12511 check_dsp(ctx); 12512 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 12513 break; 12514 case OPC_ABSQ_S_OB: 12515 check_dsp_r2(ctx); 12516 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 12517 break; 12518 case OPC_ABSQ_S_PW: 12519 check_dsp(ctx); 12520 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 12521 break; 12522 case OPC_ABSQ_S_QH: 12523 check_dsp(ctx); 12524 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 12525 break; 12526 } 12527 break; 12528 case OPC_ADDU_OB_DSP: 12529 switch (op2) { 12530 case OPC_RADDU_L_OB: 12531 check_dsp(ctx); 12532 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 12533 break; 12534 case OPC_SUBQ_PW: 12535 check_dsp(ctx); 12536 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12537 break; 12538 case OPC_SUBQ_S_PW: 12539 check_dsp(ctx); 12540 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12541 break; 12542 case OPC_SUBQ_QH: 12543 check_dsp(ctx); 12544 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12545 break; 12546 case OPC_SUBQ_S_QH: 12547 check_dsp(ctx); 12548 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12549 break; 12550 case OPC_SUBU_OB: 12551 check_dsp(ctx); 12552 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12553 break; 12554 case OPC_SUBU_S_OB: 12555 check_dsp(ctx); 12556 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12557 break; 12558 case OPC_SUBU_QH: 12559 check_dsp_r2(ctx); 12560 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12561 break; 12562 case OPC_SUBU_S_QH: 12563 check_dsp_r2(ctx); 12564 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12565 break; 12566 case OPC_SUBUH_OB: 12567 check_dsp_r2(ctx); 12568 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12569 break; 12570 case OPC_SUBUH_R_OB: 12571 check_dsp_r2(ctx); 12572 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12573 break; 12574 case OPC_ADDQ_PW: 12575 check_dsp(ctx); 12576 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12577 break; 12578 case OPC_ADDQ_S_PW: 12579 check_dsp(ctx); 12580 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12581 break; 12582 case OPC_ADDQ_QH: 12583 check_dsp(ctx); 12584 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12585 break; 12586 case OPC_ADDQ_S_QH: 12587 check_dsp(ctx); 12588 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12589 break; 12590 case OPC_ADDU_OB: 12591 check_dsp(ctx); 12592 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12593 break; 12594 case OPC_ADDU_S_OB: 12595 check_dsp(ctx); 12596 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12597 break; 12598 case OPC_ADDU_QH: 12599 check_dsp_r2(ctx); 12600 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12601 break; 12602 case OPC_ADDU_S_QH: 12603 check_dsp_r2(ctx); 12604 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12605 break; 12606 case OPC_ADDUH_OB: 12607 check_dsp_r2(ctx); 12608 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12609 break; 12610 case OPC_ADDUH_R_OB: 12611 check_dsp_r2(ctx); 12612 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12613 break; 12614 } 12615 break; 12616 case OPC_CMPU_EQ_OB_DSP: 12617 switch (op2) { 12618 case OPC_PRECR_OB_QH: 12619 check_dsp_r2(ctx); 12620 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12621 break; 12622 case OPC_PRECR_SRA_QH_PW: 12623 check_dsp_r2(ctx); 12624 { 12625 TCGv_i32 ret_t = tcg_const_i32(ret); 12626 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12627 tcg_temp_free_i32(ret_t); 12628 break; 12629 } 12630 case OPC_PRECR_SRA_R_QH_PW: 12631 check_dsp_r2(ctx); 12632 { 12633 TCGv_i32 sa_v = tcg_const_i32(ret); 12634 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12635 tcg_temp_free_i32(sa_v); 12636 break; 12637 } 12638 case OPC_PRECRQ_OB_QH: 12639 check_dsp(ctx); 12640 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12641 break; 12642 case OPC_PRECRQ_PW_L: 12643 check_dsp(ctx); 12644 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12645 break; 12646 case OPC_PRECRQ_QH_PW: 12647 check_dsp(ctx); 12648 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12649 break; 12650 case OPC_PRECRQ_RS_QH_PW: 12651 check_dsp(ctx); 12652 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12653 break; 12654 case OPC_PRECRQU_S_OB_QH: 12655 check_dsp(ctx); 12656 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12657 break; 12658 } 12659 break; 12660 #endif 12661 } 12662 12663 tcg_temp_free(v1_t); 12664 tcg_temp_free(v2_t); 12665 } 12666 12667 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12668 int ret, int v1, int v2) 12669 { 12670 uint32_t op2; 12671 TCGv t0; 12672 TCGv v1_t; 12673 TCGv v2_t; 12674 12675 if (ret == 0) { 12676 /* Treat as NOP. */ 12677 return; 12678 } 12679 12680 t0 = tcg_temp_new(); 12681 v1_t = tcg_temp_new(); 12682 v2_t = tcg_temp_new(); 12683 12684 tcg_gen_movi_tl(t0, v1); 12685 gen_load_gpr(v1_t, v1); 12686 gen_load_gpr(v2_t, v2); 12687 12688 switch (opc) { 12689 case OPC_SHLL_QB_DSP: 12690 { 12691 op2 = MASK_SHLL_QB(ctx->opcode); 12692 switch (op2) { 12693 case OPC_SHLL_QB: 12694 check_dsp(ctx); 12695 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12696 break; 12697 case OPC_SHLLV_QB: 12698 check_dsp(ctx); 12699 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12700 break; 12701 case OPC_SHLL_PH: 12702 check_dsp(ctx); 12703 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12704 break; 12705 case OPC_SHLLV_PH: 12706 check_dsp(ctx); 12707 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12708 break; 12709 case OPC_SHLL_S_PH: 12710 check_dsp(ctx); 12711 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12712 break; 12713 case OPC_SHLLV_S_PH: 12714 check_dsp(ctx); 12715 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12716 break; 12717 case OPC_SHLL_S_W: 12718 check_dsp(ctx); 12719 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12720 break; 12721 case OPC_SHLLV_S_W: 12722 check_dsp(ctx); 12723 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12724 break; 12725 case OPC_SHRL_QB: 12726 check_dsp(ctx); 12727 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12728 break; 12729 case OPC_SHRLV_QB: 12730 check_dsp(ctx); 12731 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12732 break; 12733 case OPC_SHRL_PH: 12734 check_dsp_r2(ctx); 12735 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12736 break; 12737 case OPC_SHRLV_PH: 12738 check_dsp_r2(ctx); 12739 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12740 break; 12741 case OPC_SHRA_QB: 12742 check_dsp_r2(ctx); 12743 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12744 break; 12745 case OPC_SHRA_R_QB: 12746 check_dsp_r2(ctx); 12747 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12748 break; 12749 case OPC_SHRAV_QB: 12750 check_dsp_r2(ctx); 12751 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12752 break; 12753 case OPC_SHRAV_R_QB: 12754 check_dsp_r2(ctx); 12755 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12756 break; 12757 case OPC_SHRA_PH: 12758 check_dsp(ctx); 12759 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12760 break; 12761 case OPC_SHRA_R_PH: 12762 check_dsp(ctx); 12763 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12764 break; 12765 case OPC_SHRAV_PH: 12766 check_dsp(ctx); 12767 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12768 break; 12769 case OPC_SHRAV_R_PH: 12770 check_dsp(ctx); 12771 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12772 break; 12773 case OPC_SHRA_R_W: 12774 check_dsp(ctx); 12775 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12776 break; 12777 case OPC_SHRAV_R_W: 12778 check_dsp(ctx); 12779 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12780 break; 12781 default: /* Invalid */ 12782 MIPS_INVAL("MASK SHLL.QB"); 12783 gen_reserved_instruction(ctx); 12784 break; 12785 } 12786 break; 12787 } 12788 #ifdef TARGET_MIPS64 12789 case OPC_SHLL_OB_DSP: 12790 op2 = MASK_SHLL_OB(ctx->opcode); 12791 switch (op2) { 12792 case OPC_SHLL_PW: 12793 check_dsp(ctx); 12794 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12795 break; 12796 case OPC_SHLLV_PW: 12797 check_dsp(ctx); 12798 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12799 break; 12800 case OPC_SHLL_S_PW: 12801 check_dsp(ctx); 12802 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12803 break; 12804 case OPC_SHLLV_S_PW: 12805 check_dsp(ctx); 12806 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12807 break; 12808 case OPC_SHLL_OB: 12809 check_dsp(ctx); 12810 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12811 break; 12812 case OPC_SHLLV_OB: 12813 check_dsp(ctx); 12814 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12815 break; 12816 case OPC_SHLL_QH: 12817 check_dsp(ctx); 12818 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12819 break; 12820 case OPC_SHLLV_QH: 12821 check_dsp(ctx); 12822 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12823 break; 12824 case OPC_SHLL_S_QH: 12825 check_dsp(ctx); 12826 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12827 break; 12828 case OPC_SHLLV_S_QH: 12829 check_dsp(ctx); 12830 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12831 break; 12832 case OPC_SHRA_OB: 12833 check_dsp_r2(ctx); 12834 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12835 break; 12836 case OPC_SHRAV_OB: 12837 check_dsp_r2(ctx); 12838 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12839 break; 12840 case OPC_SHRA_R_OB: 12841 check_dsp_r2(ctx); 12842 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12843 break; 12844 case OPC_SHRAV_R_OB: 12845 check_dsp_r2(ctx); 12846 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12847 break; 12848 case OPC_SHRA_PW: 12849 check_dsp(ctx); 12850 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12851 break; 12852 case OPC_SHRAV_PW: 12853 check_dsp(ctx); 12854 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12855 break; 12856 case OPC_SHRA_R_PW: 12857 check_dsp(ctx); 12858 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12859 break; 12860 case OPC_SHRAV_R_PW: 12861 check_dsp(ctx); 12862 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12863 break; 12864 case OPC_SHRA_QH: 12865 check_dsp(ctx); 12866 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12867 break; 12868 case OPC_SHRAV_QH: 12869 check_dsp(ctx); 12870 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12871 break; 12872 case OPC_SHRA_R_QH: 12873 check_dsp(ctx); 12874 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12875 break; 12876 case OPC_SHRAV_R_QH: 12877 check_dsp(ctx); 12878 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12879 break; 12880 case OPC_SHRL_OB: 12881 check_dsp(ctx); 12882 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12883 break; 12884 case OPC_SHRLV_OB: 12885 check_dsp(ctx); 12886 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12887 break; 12888 case OPC_SHRL_QH: 12889 check_dsp_r2(ctx); 12890 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12891 break; 12892 case OPC_SHRLV_QH: 12893 check_dsp_r2(ctx); 12894 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12895 break; 12896 default: /* Invalid */ 12897 MIPS_INVAL("MASK SHLL.OB"); 12898 gen_reserved_instruction(ctx); 12899 break; 12900 } 12901 break; 12902 #endif 12903 } 12904 12905 tcg_temp_free(t0); 12906 tcg_temp_free(v1_t); 12907 tcg_temp_free(v2_t); 12908 } 12909 12910 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12911 int ret, int v1, int v2, int check_ret) 12912 { 12913 TCGv_i32 t0; 12914 TCGv v1_t; 12915 TCGv v2_t; 12916 12917 if ((ret == 0) && (check_ret == 1)) { 12918 /* Treat as NOP. */ 12919 return; 12920 } 12921 12922 t0 = tcg_temp_new_i32(); 12923 v1_t = tcg_temp_new(); 12924 v2_t = tcg_temp_new(); 12925 12926 tcg_gen_movi_i32(t0, ret); 12927 gen_load_gpr(v1_t, v1); 12928 gen_load_gpr(v2_t, v2); 12929 12930 switch (op1) { 12931 /* 12932 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 12933 * the same mask and op1. 12934 */ 12935 case OPC_MULT_G_2E: 12936 check_dsp_r2(ctx); 12937 switch (op2) { 12938 case OPC_MUL_PH: 12939 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12940 break; 12941 case OPC_MUL_S_PH: 12942 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12943 break; 12944 case OPC_MULQ_S_W: 12945 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12946 break; 12947 case OPC_MULQ_RS_W: 12948 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12949 break; 12950 } 12951 break; 12952 case OPC_DPA_W_PH_DSP: 12953 switch (op2) { 12954 case OPC_DPAU_H_QBL: 12955 check_dsp(ctx); 12956 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 12957 break; 12958 case OPC_DPAU_H_QBR: 12959 check_dsp(ctx); 12960 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 12961 break; 12962 case OPC_DPSU_H_QBL: 12963 check_dsp(ctx); 12964 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 12965 break; 12966 case OPC_DPSU_H_QBR: 12967 check_dsp(ctx); 12968 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 12969 break; 12970 case OPC_DPA_W_PH: 12971 check_dsp_r2(ctx); 12972 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 12973 break; 12974 case OPC_DPAX_W_PH: 12975 check_dsp_r2(ctx); 12976 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 12977 break; 12978 case OPC_DPAQ_S_W_PH: 12979 check_dsp(ctx); 12980 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12981 break; 12982 case OPC_DPAQX_S_W_PH: 12983 check_dsp_r2(ctx); 12984 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 12985 break; 12986 case OPC_DPAQX_SA_W_PH: 12987 check_dsp_r2(ctx); 12988 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 12989 break; 12990 case OPC_DPS_W_PH: 12991 check_dsp_r2(ctx); 12992 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 12993 break; 12994 case OPC_DPSX_W_PH: 12995 check_dsp_r2(ctx); 12996 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 12997 break; 12998 case OPC_DPSQ_S_W_PH: 12999 check_dsp(ctx); 13000 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13001 break; 13002 case OPC_DPSQX_S_W_PH: 13003 check_dsp_r2(ctx); 13004 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13005 break; 13006 case OPC_DPSQX_SA_W_PH: 13007 check_dsp_r2(ctx); 13008 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13009 break; 13010 case OPC_MULSAQ_S_W_PH: 13011 check_dsp(ctx); 13012 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13013 break; 13014 case OPC_DPAQ_SA_L_W: 13015 check_dsp(ctx); 13016 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13017 break; 13018 case OPC_DPSQ_SA_L_W: 13019 check_dsp(ctx); 13020 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13021 break; 13022 case OPC_MAQ_S_W_PHL: 13023 check_dsp(ctx); 13024 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 13025 break; 13026 case OPC_MAQ_S_W_PHR: 13027 check_dsp(ctx); 13028 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 13029 break; 13030 case OPC_MAQ_SA_W_PHL: 13031 check_dsp(ctx); 13032 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 13033 break; 13034 case OPC_MAQ_SA_W_PHR: 13035 check_dsp(ctx); 13036 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 13037 break; 13038 case OPC_MULSA_W_PH: 13039 check_dsp_r2(ctx); 13040 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 13041 break; 13042 } 13043 break; 13044 #ifdef TARGET_MIPS64 13045 case OPC_DPAQ_W_QH_DSP: 13046 { 13047 int ac = ret & 0x03; 13048 tcg_gen_movi_i32(t0, ac); 13049 13050 switch (op2) { 13051 case OPC_DMADD: 13052 check_dsp(ctx); 13053 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 13054 break; 13055 case OPC_DMADDU: 13056 check_dsp(ctx); 13057 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 13058 break; 13059 case OPC_DMSUB: 13060 check_dsp(ctx); 13061 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 13062 break; 13063 case OPC_DMSUBU: 13064 check_dsp(ctx); 13065 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 13066 break; 13067 case OPC_DPA_W_QH: 13068 check_dsp_r2(ctx); 13069 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 13070 break; 13071 case OPC_DPAQ_S_W_QH: 13072 check_dsp(ctx); 13073 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13074 break; 13075 case OPC_DPAQ_SA_L_PW: 13076 check_dsp(ctx); 13077 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13078 break; 13079 case OPC_DPAU_H_OBL: 13080 check_dsp(ctx); 13081 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 13082 break; 13083 case OPC_DPAU_H_OBR: 13084 check_dsp(ctx); 13085 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 13086 break; 13087 case OPC_DPS_W_QH: 13088 check_dsp_r2(ctx); 13089 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 13090 break; 13091 case OPC_DPSQ_S_W_QH: 13092 check_dsp(ctx); 13093 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13094 break; 13095 case OPC_DPSQ_SA_L_PW: 13096 check_dsp(ctx); 13097 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13098 break; 13099 case OPC_DPSU_H_OBL: 13100 check_dsp(ctx); 13101 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 13102 break; 13103 case OPC_DPSU_H_OBR: 13104 check_dsp(ctx); 13105 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 13106 break; 13107 case OPC_MAQ_S_L_PWL: 13108 check_dsp(ctx); 13109 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 13110 break; 13111 case OPC_MAQ_S_L_PWR: 13112 check_dsp(ctx); 13113 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 13114 break; 13115 case OPC_MAQ_S_W_QHLL: 13116 check_dsp(ctx); 13117 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 13118 break; 13119 case OPC_MAQ_SA_W_QHLL: 13120 check_dsp(ctx); 13121 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 13122 break; 13123 case OPC_MAQ_S_W_QHLR: 13124 check_dsp(ctx); 13125 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 13126 break; 13127 case OPC_MAQ_SA_W_QHLR: 13128 check_dsp(ctx); 13129 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 13130 break; 13131 case OPC_MAQ_S_W_QHRL: 13132 check_dsp(ctx); 13133 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 13134 break; 13135 case OPC_MAQ_SA_W_QHRL: 13136 check_dsp(ctx); 13137 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 13138 break; 13139 case OPC_MAQ_S_W_QHRR: 13140 check_dsp(ctx); 13141 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 13142 break; 13143 case OPC_MAQ_SA_W_QHRR: 13144 check_dsp(ctx); 13145 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 13146 break; 13147 case OPC_MULSAQ_S_L_PW: 13148 check_dsp(ctx); 13149 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 13150 break; 13151 case OPC_MULSAQ_S_W_QH: 13152 check_dsp(ctx); 13153 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13154 break; 13155 } 13156 } 13157 break; 13158 #endif 13159 case OPC_ADDU_QB_DSP: 13160 switch (op2) { 13161 case OPC_MULEU_S_PH_QBL: 13162 check_dsp(ctx); 13163 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13164 break; 13165 case OPC_MULEU_S_PH_QBR: 13166 check_dsp(ctx); 13167 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13168 break; 13169 case OPC_MULQ_RS_PH: 13170 check_dsp(ctx); 13171 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13172 break; 13173 case OPC_MULEQ_S_W_PHL: 13174 check_dsp(ctx); 13175 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13176 break; 13177 case OPC_MULEQ_S_W_PHR: 13178 check_dsp(ctx); 13179 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13180 break; 13181 case OPC_MULQ_S_PH: 13182 check_dsp_r2(ctx); 13183 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13184 break; 13185 } 13186 break; 13187 #ifdef TARGET_MIPS64 13188 case OPC_ADDU_OB_DSP: 13189 switch (op2) { 13190 case OPC_MULEQ_S_PW_QHL: 13191 check_dsp(ctx); 13192 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13193 break; 13194 case OPC_MULEQ_S_PW_QHR: 13195 check_dsp(ctx); 13196 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13197 break; 13198 case OPC_MULEU_S_QH_OBL: 13199 check_dsp(ctx); 13200 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13201 break; 13202 case OPC_MULEU_S_QH_OBR: 13203 check_dsp(ctx); 13204 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13205 break; 13206 case OPC_MULQ_RS_QH: 13207 check_dsp(ctx); 13208 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13209 break; 13210 } 13211 break; 13212 #endif 13213 } 13214 13215 tcg_temp_free_i32(t0); 13216 tcg_temp_free(v1_t); 13217 tcg_temp_free(v2_t); 13218 } 13219 13220 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13221 int ret, int val) 13222 { 13223 int16_t imm; 13224 TCGv t0; 13225 TCGv val_t; 13226 13227 if (ret == 0) { 13228 /* Treat as NOP. */ 13229 return; 13230 } 13231 13232 t0 = tcg_temp_new(); 13233 val_t = tcg_temp_new(); 13234 gen_load_gpr(val_t, val); 13235 13236 switch (op1) { 13237 case OPC_ABSQ_S_PH_DSP: 13238 switch (op2) { 13239 case OPC_BITREV: 13240 check_dsp(ctx); 13241 gen_helper_bitrev(cpu_gpr[ret], val_t); 13242 break; 13243 case OPC_REPL_QB: 13244 check_dsp(ctx); 13245 { 13246 target_long result; 13247 imm = (ctx->opcode >> 16) & 0xFF; 13248 result = (uint32_t)imm << 24 | 13249 (uint32_t)imm << 16 | 13250 (uint32_t)imm << 8 | 13251 (uint32_t)imm; 13252 result = (int32_t)result; 13253 tcg_gen_movi_tl(cpu_gpr[ret], result); 13254 } 13255 break; 13256 case OPC_REPLV_QB: 13257 check_dsp(ctx); 13258 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13259 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13260 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13261 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13262 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13263 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13264 break; 13265 case OPC_REPL_PH: 13266 check_dsp(ctx); 13267 { 13268 imm = (ctx->opcode >> 16) & 0x03FF; 13269 imm = (int16_t)(imm << 6) >> 6; 13270 tcg_gen_movi_tl(cpu_gpr[ret], \ 13271 (target_long)((int32_t)imm << 16 | \ 13272 (uint16_t)imm)); 13273 } 13274 break; 13275 case OPC_REPLV_PH: 13276 check_dsp(ctx); 13277 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13278 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13279 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13280 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13281 break; 13282 } 13283 break; 13284 #ifdef TARGET_MIPS64 13285 case OPC_ABSQ_S_QH_DSP: 13286 switch (op2) { 13287 case OPC_REPL_OB: 13288 check_dsp(ctx); 13289 { 13290 target_long temp; 13291 13292 imm = (ctx->opcode >> 16) & 0xFF; 13293 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 13294 temp = (temp << 16) | temp; 13295 temp = (temp << 32) | temp; 13296 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13297 break; 13298 } 13299 case OPC_REPL_PW: 13300 check_dsp(ctx); 13301 { 13302 target_long temp; 13303 13304 imm = (ctx->opcode >> 16) & 0x03FF; 13305 imm = (int16_t)(imm << 6) >> 6; 13306 temp = ((target_long)imm << 32) \ 13307 | ((target_long)imm & 0xFFFFFFFF); 13308 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13309 break; 13310 } 13311 case OPC_REPL_QH: 13312 check_dsp(ctx); 13313 { 13314 target_long temp; 13315 13316 imm = (ctx->opcode >> 16) & 0x03FF; 13317 imm = (int16_t)(imm << 6) >> 6; 13318 13319 temp = ((uint64_t)(uint16_t)imm << 48) | 13320 ((uint64_t)(uint16_t)imm << 32) | 13321 ((uint64_t)(uint16_t)imm << 16) | 13322 (uint64_t)(uint16_t)imm; 13323 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13324 break; 13325 } 13326 case OPC_REPLV_OB: 13327 check_dsp(ctx); 13328 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13329 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13330 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13331 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13332 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13333 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13334 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13335 break; 13336 case OPC_REPLV_PW: 13337 check_dsp(ctx); 13338 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 13339 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13340 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13341 break; 13342 case OPC_REPLV_QH: 13343 check_dsp(ctx); 13344 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13345 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13346 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13347 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13348 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13349 break; 13350 } 13351 break; 13352 #endif 13353 } 13354 tcg_temp_free(t0); 13355 tcg_temp_free(val_t); 13356 } 13357 13358 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 13359 uint32_t op1, uint32_t op2, 13360 int ret, int v1, int v2, int check_ret) 13361 { 13362 TCGv t1; 13363 TCGv v1_t; 13364 TCGv v2_t; 13365 13366 if ((ret == 0) && (check_ret == 1)) { 13367 /* Treat as NOP. */ 13368 return; 13369 } 13370 13371 t1 = tcg_temp_new(); 13372 v1_t = tcg_temp_new(); 13373 v2_t = tcg_temp_new(); 13374 13375 gen_load_gpr(v1_t, v1); 13376 gen_load_gpr(v2_t, v2); 13377 13378 switch (op1) { 13379 case OPC_CMPU_EQ_QB_DSP: 13380 switch (op2) { 13381 case OPC_CMPU_EQ_QB: 13382 check_dsp(ctx); 13383 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 13384 break; 13385 case OPC_CMPU_LT_QB: 13386 check_dsp(ctx); 13387 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 13388 break; 13389 case OPC_CMPU_LE_QB: 13390 check_dsp(ctx); 13391 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 13392 break; 13393 case OPC_CMPGU_EQ_QB: 13394 check_dsp(ctx); 13395 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 13396 break; 13397 case OPC_CMPGU_LT_QB: 13398 check_dsp(ctx); 13399 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 13400 break; 13401 case OPC_CMPGU_LE_QB: 13402 check_dsp(ctx); 13403 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 13404 break; 13405 case OPC_CMPGDU_EQ_QB: 13406 check_dsp_r2(ctx); 13407 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 13408 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13409 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13410 tcg_gen_shli_tl(t1, t1, 24); 13411 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13412 break; 13413 case OPC_CMPGDU_LT_QB: 13414 check_dsp_r2(ctx); 13415 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 13416 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13417 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13418 tcg_gen_shli_tl(t1, t1, 24); 13419 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13420 break; 13421 case OPC_CMPGDU_LE_QB: 13422 check_dsp_r2(ctx); 13423 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 13424 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13425 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13426 tcg_gen_shli_tl(t1, t1, 24); 13427 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13428 break; 13429 case OPC_CMP_EQ_PH: 13430 check_dsp(ctx); 13431 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 13432 break; 13433 case OPC_CMP_LT_PH: 13434 check_dsp(ctx); 13435 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 13436 break; 13437 case OPC_CMP_LE_PH: 13438 check_dsp(ctx); 13439 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 13440 break; 13441 case OPC_PICK_QB: 13442 check_dsp(ctx); 13443 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13444 break; 13445 case OPC_PICK_PH: 13446 check_dsp(ctx); 13447 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13448 break; 13449 case OPC_PACKRL_PH: 13450 check_dsp(ctx); 13451 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 13452 break; 13453 } 13454 break; 13455 #ifdef TARGET_MIPS64 13456 case OPC_CMPU_EQ_OB_DSP: 13457 switch (op2) { 13458 case OPC_CMP_EQ_PW: 13459 check_dsp(ctx); 13460 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 13461 break; 13462 case OPC_CMP_LT_PW: 13463 check_dsp(ctx); 13464 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 13465 break; 13466 case OPC_CMP_LE_PW: 13467 check_dsp(ctx); 13468 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 13469 break; 13470 case OPC_CMP_EQ_QH: 13471 check_dsp(ctx); 13472 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 13473 break; 13474 case OPC_CMP_LT_QH: 13475 check_dsp(ctx); 13476 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 13477 break; 13478 case OPC_CMP_LE_QH: 13479 check_dsp(ctx); 13480 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 13481 break; 13482 case OPC_CMPGDU_EQ_OB: 13483 check_dsp_r2(ctx); 13484 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13485 break; 13486 case OPC_CMPGDU_LT_OB: 13487 check_dsp_r2(ctx); 13488 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13489 break; 13490 case OPC_CMPGDU_LE_OB: 13491 check_dsp_r2(ctx); 13492 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13493 break; 13494 case OPC_CMPGU_EQ_OB: 13495 check_dsp(ctx); 13496 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 13497 break; 13498 case OPC_CMPGU_LT_OB: 13499 check_dsp(ctx); 13500 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 13501 break; 13502 case OPC_CMPGU_LE_OB: 13503 check_dsp(ctx); 13504 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 13505 break; 13506 case OPC_CMPU_EQ_OB: 13507 check_dsp(ctx); 13508 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 13509 break; 13510 case OPC_CMPU_LT_OB: 13511 check_dsp(ctx); 13512 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 13513 break; 13514 case OPC_CMPU_LE_OB: 13515 check_dsp(ctx); 13516 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 13517 break; 13518 case OPC_PACKRL_PW: 13519 check_dsp(ctx); 13520 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 13521 break; 13522 case OPC_PICK_OB: 13523 check_dsp(ctx); 13524 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13525 break; 13526 case OPC_PICK_PW: 13527 check_dsp(ctx); 13528 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13529 break; 13530 case OPC_PICK_QH: 13531 check_dsp(ctx); 13532 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13533 break; 13534 } 13535 break; 13536 #endif 13537 } 13538 13539 tcg_temp_free(t1); 13540 tcg_temp_free(v1_t); 13541 tcg_temp_free(v2_t); 13542 } 13543 13544 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 13545 uint32_t op1, int rt, int rs, int sa) 13546 { 13547 TCGv t0; 13548 13549 check_dsp_r2(ctx); 13550 13551 if (rt == 0) { 13552 /* Treat as NOP. */ 13553 return; 13554 } 13555 13556 t0 = tcg_temp_new(); 13557 gen_load_gpr(t0, rs); 13558 13559 switch (op1) { 13560 case OPC_APPEND_DSP: 13561 switch (MASK_APPEND(ctx->opcode)) { 13562 case OPC_APPEND: 13563 if (sa != 0) { 13564 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 13565 } 13566 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13567 break; 13568 case OPC_PREPEND: 13569 if (sa != 0) { 13570 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 13571 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13572 tcg_gen_shli_tl(t0, t0, 32 - sa); 13573 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13574 } 13575 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13576 break; 13577 case OPC_BALIGN: 13578 sa &= 3; 13579 if (sa != 0 && sa != 2) { 13580 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13581 tcg_gen_ext32u_tl(t0, t0); 13582 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13583 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13584 } 13585 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13586 break; 13587 default: /* Invalid */ 13588 MIPS_INVAL("MASK APPEND"); 13589 gen_reserved_instruction(ctx); 13590 break; 13591 } 13592 break; 13593 #ifdef TARGET_MIPS64 13594 case OPC_DAPPEND_DSP: 13595 switch (MASK_DAPPEND(ctx->opcode)) { 13596 case OPC_DAPPEND: 13597 if (sa != 0) { 13598 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13599 } 13600 break; 13601 case OPC_PREPENDD: 13602 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13603 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13604 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13605 break; 13606 case OPC_PREPENDW: 13607 if (sa != 0) { 13608 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13609 tcg_gen_shli_tl(t0, t0, 64 - sa); 13610 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13611 } 13612 break; 13613 case OPC_DBALIGN: 13614 sa &= 7; 13615 if (sa != 0 && sa != 2 && sa != 4) { 13616 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13617 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13618 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13619 } 13620 break; 13621 default: /* Invalid */ 13622 MIPS_INVAL("MASK DAPPEND"); 13623 gen_reserved_instruction(ctx); 13624 break; 13625 } 13626 break; 13627 #endif 13628 } 13629 tcg_temp_free(t0); 13630 } 13631 13632 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13633 int ret, int v1, int v2, int check_ret) 13634 13635 { 13636 TCGv t0; 13637 TCGv t1; 13638 TCGv v1_t; 13639 int16_t imm; 13640 13641 if ((ret == 0) && (check_ret == 1)) { 13642 /* Treat as NOP. */ 13643 return; 13644 } 13645 13646 t0 = tcg_temp_new(); 13647 t1 = tcg_temp_new(); 13648 v1_t = tcg_temp_new(); 13649 13650 gen_load_gpr(v1_t, v1); 13651 13652 switch (op1) { 13653 case OPC_EXTR_W_DSP: 13654 check_dsp(ctx); 13655 switch (op2) { 13656 case OPC_EXTR_W: 13657 tcg_gen_movi_tl(t0, v2); 13658 tcg_gen_movi_tl(t1, v1); 13659 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13660 break; 13661 case OPC_EXTR_R_W: 13662 tcg_gen_movi_tl(t0, v2); 13663 tcg_gen_movi_tl(t1, v1); 13664 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13665 break; 13666 case OPC_EXTR_RS_W: 13667 tcg_gen_movi_tl(t0, v2); 13668 tcg_gen_movi_tl(t1, v1); 13669 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13670 break; 13671 case OPC_EXTR_S_H: 13672 tcg_gen_movi_tl(t0, v2); 13673 tcg_gen_movi_tl(t1, v1); 13674 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13675 break; 13676 case OPC_EXTRV_S_H: 13677 tcg_gen_movi_tl(t0, v2); 13678 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13679 break; 13680 case OPC_EXTRV_W: 13681 tcg_gen_movi_tl(t0, v2); 13682 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13683 break; 13684 case OPC_EXTRV_R_W: 13685 tcg_gen_movi_tl(t0, v2); 13686 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13687 break; 13688 case OPC_EXTRV_RS_W: 13689 tcg_gen_movi_tl(t0, v2); 13690 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13691 break; 13692 case OPC_EXTP: 13693 tcg_gen_movi_tl(t0, v2); 13694 tcg_gen_movi_tl(t1, v1); 13695 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13696 break; 13697 case OPC_EXTPV: 13698 tcg_gen_movi_tl(t0, v2); 13699 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13700 break; 13701 case OPC_EXTPDP: 13702 tcg_gen_movi_tl(t0, v2); 13703 tcg_gen_movi_tl(t1, v1); 13704 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13705 break; 13706 case OPC_EXTPDPV: 13707 tcg_gen_movi_tl(t0, v2); 13708 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13709 break; 13710 case OPC_SHILO: 13711 imm = (ctx->opcode >> 20) & 0x3F; 13712 tcg_gen_movi_tl(t0, ret); 13713 tcg_gen_movi_tl(t1, imm); 13714 gen_helper_shilo(t0, t1, cpu_env); 13715 break; 13716 case OPC_SHILOV: 13717 tcg_gen_movi_tl(t0, ret); 13718 gen_helper_shilo(t0, v1_t, cpu_env); 13719 break; 13720 case OPC_MTHLIP: 13721 tcg_gen_movi_tl(t0, ret); 13722 gen_helper_mthlip(t0, v1_t, cpu_env); 13723 break; 13724 case OPC_WRDSP: 13725 imm = (ctx->opcode >> 11) & 0x3FF; 13726 tcg_gen_movi_tl(t0, imm); 13727 gen_helper_wrdsp(v1_t, t0, cpu_env); 13728 break; 13729 case OPC_RDDSP: 13730 imm = (ctx->opcode >> 16) & 0x03FF; 13731 tcg_gen_movi_tl(t0, imm); 13732 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13733 break; 13734 } 13735 break; 13736 #ifdef TARGET_MIPS64 13737 case OPC_DEXTR_W_DSP: 13738 check_dsp(ctx); 13739 switch (op2) { 13740 case OPC_DMTHLIP: 13741 tcg_gen_movi_tl(t0, ret); 13742 gen_helper_dmthlip(v1_t, t0, cpu_env); 13743 break; 13744 case OPC_DSHILO: 13745 { 13746 int shift = (ctx->opcode >> 19) & 0x7F; 13747 int ac = (ctx->opcode >> 11) & 0x03; 13748 tcg_gen_movi_tl(t0, shift); 13749 tcg_gen_movi_tl(t1, ac); 13750 gen_helper_dshilo(t0, t1, cpu_env); 13751 break; 13752 } 13753 case OPC_DSHILOV: 13754 { 13755 int ac = (ctx->opcode >> 11) & 0x03; 13756 tcg_gen_movi_tl(t0, ac); 13757 gen_helper_dshilo(v1_t, t0, cpu_env); 13758 break; 13759 } 13760 case OPC_DEXTP: 13761 tcg_gen_movi_tl(t0, v2); 13762 tcg_gen_movi_tl(t1, v1); 13763 13764 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13765 break; 13766 case OPC_DEXTPV: 13767 tcg_gen_movi_tl(t0, v2); 13768 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13769 break; 13770 case OPC_DEXTPDP: 13771 tcg_gen_movi_tl(t0, v2); 13772 tcg_gen_movi_tl(t1, v1); 13773 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13774 break; 13775 case OPC_DEXTPDPV: 13776 tcg_gen_movi_tl(t0, v2); 13777 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13778 break; 13779 case OPC_DEXTR_L: 13780 tcg_gen_movi_tl(t0, v2); 13781 tcg_gen_movi_tl(t1, v1); 13782 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13783 break; 13784 case OPC_DEXTR_R_L: 13785 tcg_gen_movi_tl(t0, v2); 13786 tcg_gen_movi_tl(t1, v1); 13787 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13788 break; 13789 case OPC_DEXTR_RS_L: 13790 tcg_gen_movi_tl(t0, v2); 13791 tcg_gen_movi_tl(t1, v1); 13792 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13793 break; 13794 case OPC_DEXTR_W: 13795 tcg_gen_movi_tl(t0, v2); 13796 tcg_gen_movi_tl(t1, v1); 13797 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13798 break; 13799 case OPC_DEXTR_R_W: 13800 tcg_gen_movi_tl(t0, v2); 13801 tcg_gen_movi_tl(t1, v1); 13802 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13803 break; 13804 case OPC_DEXTR_RS_W: 13805 tcg_gen_movi_tl(t0, v2); 13806 tcg_gen_movi_tl(t1, v1); 13807 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13808 break; 13809 case OPC_DEXTR_S_H: 13810 tcg_gen_movi_tl(t0, v2); 13811 tcg_gen_movi_tl(t1, v1); 13812 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13813 break; 13814 case OPC_DEXTRV_S_H: 13815 tcg_gen_movi_tl(t0, v2); 13816 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13817 break; 13818 case OPC_DEXTRV_L: 13819 tcg_gen_movi_tl(t0, v2); 13820 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13821 break; 13822 case OPC_DEXTRV_R_L: 13823 tcg_gen_movi_tl(t0, v2); 13824 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13825 break; 13826 case OPC_DEXTRV_RS_L: 13827 tcg_gen_movi_tl(t0, v2); 13828 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13829 break; 13830 case OPC_DEXTRV_W: 13831 tcg_gen_movi_tl(t0, v2); 13832 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13833 break; 13834 case OPC_DEXTRV_R_W: 13835 tcg_gen_movi_tl(t0, v2); 13836 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13837 break; 13838 case OPC_DEXTRV_RS_W: 13839 tcg_gen_movi_tl(t0, v2); 13840 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13841 break; 13842 } 13843 break; 13844 #endif 13845 } 13846 13847 tcg_temp_free(t0); 13848 tcg_temp_free(t1); 13849 tcg_temp_free(v1_t); 13850 } 13851 13852 /* End MIPSDSP functions. */ 13853 13854 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13855 { 13856 int rs, rt, rd, sa; 13857 uint32_t op1, op2; 13858 13859 rs = (ctx->opcode >> 21) & 0x1f; 13860 rt = (ctx->opcode >> 16) & 0x1f; 13861 rd = (ctx->opcode >> 11) & 0x1f; 13862 sa = (ctx->opcode >> 6) & 0x1f; 13863 13864 op1 = MASK_SPECIAL(ctx->opcode); 13865 switch (op1) { 13866 case OPC_MULT: 13867 case OPC_MULTU: 13868 case OPC_DIV: 13869 case OPC_DIVU: 13870 op2 = MASK_R6_MULDIV(ctx->opcode); 13871 switch (op2) { 13872 case R6_OPC_MUL: 13873 case R6_OPC_MUH: 13874 case R6_OPC_MULU: 13875 case R6_OPC_MUHU: 13876 case R6_OPC_DIV: 13877 case R6_OPC_MOD: 13878 case R6_OPC_DIVU: 13879 case R6_OPC_MODU: 13880 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13881 break; 13882 default: 13883 MIPS_INVAL("special_r6 muldiv"); 13884 gen_reserved_instruction(ctx); 13885 break; 13886 } 13887 break; 13888 case OPC_SELEQZ: 13889 case OPC_SELNEZ: 13890 gen_cond_move(ctx, op1, rd, rs, rt); 13891 break; 13892 case R6_OPC_CLO: 13893 case R6_OPC_CLZ: 13894 if (rt == 0 && sa == 1) { 13895 /* 13896 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13897 * We need additionally to check other fields. 13898 */ 13899 gen_cl(ctx, op1, rd, rs); 13900 } else { 13901 gen_reserved_instruction(ctx); 13902 } 13903 break; 13904 case R6_OPC_SDBBP: 13905 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13906 ctx->base.is_jmp = DISAS_SEMIHOST; 13907 } else { 13908 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13909 gen_reserved_instruction(ctx); 13910 } else { 13911 generate_exception_end(ctx, EXCP_DBp); 13912 } 13913 } 13914 break; 13915 #if defined(TARGET_MIPS64) 13916 case R6_OPC_DCLO: 13917 case R6_OPC_DCLZ: 13918 if (rt == 0 && sa == 1) { 13919 /* 13920 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13921 * We need additionally to check other fields. 13922 */ 13923 check_mips_64(ctx); 13924 gen_cl(ctx, op1, rd, rs); 13925 } else { 13926 gen_reserved_instruction(ctx); 13927 } 13928 break; 13929 case OPC_DMULT: 13930 case OPC_DMULTU: 13931 case OPC_DDIV: 13932 case OPC_DDIVU: 13933 13934 op2 = MASK_R6_MULDIV(ctx->opcode); 13935 switch (op2) { 13936 case R6_OPC_DMUL: 13937 case R6_OPC_DMUH: 13938 case R6_OPC_DMULU: 13939 case R6_OPC_DMUHU: 13940 case R6_OPC_DDIV: 13941 case R6_OPC_DMOD: 13942 case R6_OPC_DDIVU: 13943 case R6_OPC_DMODU: 13944 check_mips_64(ctx); 13945 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13946 break; 13947 default: 13948 MIPS_INVAL("special_r6 muldiv"); 13949 gen_reserved_instruction(ctx); 13950 break; 13951 } 13952 break; 13953 #endif 13954 default: /* Invalid */ 13955 MIPS_INVAL("special_r6"); 13956 gen_reserved_instruction(ctx); 13957 break; 13958 } 13959 } 13960 13961 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13962 { 13963 int rs = extract32(ctx->opcode, 21, 5); 13964 int rt = extract32(ctx->opcode, 16, 5); 13965 int rd = extract32(ctx->opcode, 11, 5); 13966 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13967 13968 switch (op1) { 13969 case OPC_MOVN: /* Conditional move */ 13970 case OPC_MOVZ: 13971 gen_cond_move(ctx, op1, rd, rs, rt); 13972 break; 13973 case OPC_MFHI: /* Move from HI/LO */ 13974 case OPC_MFLO: 13975 gen_HILO(ctx, op1, 0, rd); 13976 break; 13977 case OPC_MTHI: 13978 case OPC_MTLO: /* Move to HI/LO */ 13979 gen_HILO(ctx, op1, 0, rs); 13980 break; 13981 case OPC_MULT: 13982 case OPC_MULTU: 13983 gen_mul_txx9(ctx, op1, rd, rs, rt); 13984 break; 13985 case OPC_DIV: 13986 case OPC_DIVU: 13987 gen_muldiv(ctx, op1, 0, rs, rt); 13988 break; 13989 #if defined(TARGET_MIPS64) 13990 case OPC_DMULT: 13991 case OPC_DMULTU: 13992 case OPC_DDIV: 13993 case OPC_DDIVU: 13994 check_insn_opc_user_only(ctx, INSN_R5900); 13995 gen_muldiv(ctx, op1, 0, rs, rt); 13996 break; 13997 #endif 13998 case OPC_JR: 13999 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14000 break; 14001 default: /* Invalid */ 14002 MIPS_INVAL("special_tx79"); 14003 gen_reserved_instruction(ctx); 14004 break; 14005 } 14006 } 14007 14008 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 14009 { 14010 int rs, rt, rd; 14011 uint32_t op1; 14012 14013 rs = (ctx->opcode >> 21) & 0x1f; 14014 rt = (ctx->opcode >> 16) & 0x1f; 14015 rd = (ctx->opcode >> 11) & 0x1f; 14016 14017 op1 = MASK_SPECIAL(ctx->opcode); 14018 switch (op1) { 14019 case OPC_MOVN: /* Conditional move */ 14020 case OPC_MOVZ: 14021 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 14022 INSN_LOONGSON2E | INSN_LOONGSON2F); 14023 gen_cond_move(ctx, op1, rd, rs, rt); 14024 break; 14025 case OPC_MFHI: /* Move from HI/LO */ 14026 case OPC_MFLO: 14027 gen_HILO(ctx, op1, rs & 3, rd); 14028 break; 14029 case OPC_MTHI: 14030 case OPC_MTLO: /* Move to HI/LO */ 14031 gen_HILO(ctx, op1, rd & 3, rs); 14032 break; 14033 case OPC_MOVCI: 14034 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 14035 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 14036 check_cp1_enabled(ctx); 14037 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 14038 (ctx->opcode >> 16) & 1); 14039 } else { 14040 generate_exception_err(ctx, EXCP_CpU, 1); 14041 } 14042 break; 14043 case OPC_MULT: 14044 case OPC_MULTU: 14045 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14046 break; 14047 case OPC_DIV: 14048 case OPC_DIVU: 14049 gen_muldiv(ctx, op1, 0, rs, rt); 14050 break; 14051 #if defined(TARGET_MIPS64) 14052 case OPC_DMULT: 14053 case OPC_DMULTU: 14054 case OPC_DDIV: 14055 case OPC_DDIVU: 14056 check_insn(ctx, ISA_MIPS3); 14057 check_mips_64(ctx); 14058 gen_muldiv(ctx, op1, 0, rs, rt); 14059 break; 14060 #endif 14061 case OPC_JR: 14062 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14063 break; 14064 case OPC_SPIM: 14065 #ifdef MIPS_STRICT_STANDARD 14066 MIPS_INVAL("SPIM"); 14067 gen_reserved_instruction(ctx); 14068 #else 14069 /* Implemented as RI exception for now. */ 14070 MIPS_INVAL("spim (unofficial)"); 14071 gen_reserved_instruction(ctx); 14072 #endif 14073 break; 14074 default: /* Invalid */ 14075 MIPS_INVAL("special_legacy"); 14076 gen_reserved_instruction(ctx); 14077 break; 14078 } 14079 } 14080 14081 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 14082 { 14083 int rs, rt, rd, sa; 14084 uint32_t op1; 14085 14086 rs = (ctx->opcode >> 21) & 0x1f; 14087 rt = (ctx->opcode >> 16) & 0x1f; 14088 rd = (ctx->opcode >> 11) & 0x1f; 14089 sa = (ctx->opcode >> 6) & 0x1f; 14090 14091 op1 = MASK_SPECIAL(ctx->opcode); 14092 switch (op1) { 14093 case OPC_SLL: /* Shift with immediate */ 14094 if (sa == 5 && rd == 0 && 14095 rs == 0 && rt == 0) { /* PAUSE */ 14096 if ((ctx->insn_flags & ISA_MIPS_R6) && 14097 (ctx->hflags & MIPS_HFLAG_BMASK)) { 14098 gen_reserved_instruction(ctx); 14099 break; 14100 } 14101 } 14102 /* Fallthrough */ 14103 case OPC_SRA: 14104 gen_shift_imm(ctx, op1, rd, rt, sa); 14105 break; 14106 case OPC_SRL: 14107 switch ((ctx->opcode >> 21) & 0x1f) { 14108 case 1: 14109 /* rotr is decoded as srl on non-R2 CPUs */ 14110 if (ctx->insn_flags & ISA_MIPS_R2) { 14111 op1 = OPC_ROTR; 14112 } 14113 /* Fallthrough */ 14114 case 0: 14115 gen_shift_imm(ctx, op1, rd, rt, sa); 14116 break; 14117 default: 14118 gen_reserved_instruction(ctx); 14119 break; 14120 } 14121 break; 14122 case OPC_ADD: 14123 case OPC_ADDU: 14124 case OPC_SUB: 14125 case OPC_SUBU: 14126 gen_arith(ctx, op1, rd, rs, rt); 14127 break; 14128 case OPC_SLLV: /* Shifts */ 14129 case OPC_SRAV: 14130 gen_shift(ctx, op1, rd, rs, rt); 14131 break; 14132 case OPC_SRLV: 14133 switch ((ctx->opcode >> 6) & 0x1f) { 14134 case 1: 14135 /* rotrv is decoded as srlv on non-R2 CPUs */ 14136 if (ctx->insn_flags & ISA_MIPS_R2) { 14137 op1 = OPC_ROTRV; 14138 } 14139 /* Fallthrough */ 14140 case 0: 14141 gen_shift(ctx, op1, rd, rs, rt); 14142 break; 14143 default: 14144 gen_reserved_instruction(ctx); 14145 break; 14146 } 14147 break; 14148 case OPC_SLT: /* Set on less than */ 14149 case OPC_SLTU: 14150 gen_slt(ctx, op1, rd, rs, rt); 14151 break; 14152 case OPC_AND: /* Logic*/ 14153 case OPC_OR: 14154 case OPC_NOR: 14155 case OPC_XOR: 14156 gen_logic(ctx, op1, rd, rs, rt); 14157 break; 14158 case OPC_JALR: 14159 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14160 break; 14161 case OPC_TGE: /* Traps */ 14162 case OPC_TGEU: 14163 case OPC_TLT: 14164 case OPC_TLTU: 14165 case OPC_TEQ: 14166 case OPC_TNE: 14167 check_insn(ctx, ISA_MIPS2); 14168 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 14169 break; 14170 case OPC_PMON: 14171 /* Pmon entry point, also R4010 selsl */ 14172 #ifdef MIPS_STRICT_STANDARD 14173 MIPS_INVAL("PMON / selsl"); 14174 gen_reserved_instruction(ctx); 14175 #else 14176 gen_helper_pmon(cpu_env, tcg_constant_i32(sa)); 14177 #endif 14178 break; 14179 case OPC_SYSCALL: 14180 generate_exception_end(ctx, EXCP_SYSCALL); 14181 break; 14182 case OPC_BREAK: 14183 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 14184 break; 14185 case OPC_SYNC: 14186 check_insn(ctx, ISA_MIPS2); 14187 gen_sync(extract32(ctx->opcode, 6, 5)); 14188 break; 14189 14190 #if defined(TARGET_MIPS64) 14191 /* MIPS64 specific opcodes */ 14192 case OPC_DSLL: 14193 case OPC_DSRA: 14194 case OPC_DSLL32: 14195 case OPC_DSRA32: 14196 check_insn(ctx, ISA_MIPS3); 14197 check_mips_64(ctx); 14198 gen_shift_imm(ctx, op1, rd, rt, sa); 14199 break; 14200 case OPC_DSRL: 14201 switch ((ctx->opcode >> 21) & 0x1f) { 14202 case 1: 14203 /* drotr is decoded as dsrl on non-R2 CPUs */ 14204 if (ctx->insn_flags & ISA_MIPS_R2) { 14205 op1 = OPC_DROTR; 14206 } 14207 /* Fallthrough */ 14208 case 0: 14209 check_insn(ctx, ISA_MIPS3); 14210 check_mips_64(ctx); 14211 gen_shift_imm(ctx, op1, rd, rt, sa); 14212 break; 14213 default: 14214 gen_reserved_instruction(ctx); 14215 break; 14216 } 14217 break; 14218 case OPC_DSRL32: 14219 switch ((ctx->opcode >> 21) & 0x1f) { 14220 case 1: 14221 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 14222 if (ctx->insn_flags & ISA_MIPS_R2) { 14223 op1 = OPC_DROTR32; 14224 } 14225 /* Fallthrough */ 14226 case 0: 14227 check_insn(ctx, ISA_MIPS3); 14228 check_mips_64(ctx); 14229 gen_shift_imm(ctx, op1, rd, rt, sa); 14230 break; 14231 default: 14232 gen_reserved_instruction(ctx); 14233 break; 14234 } 14235 break; 14236 case OPC_DADD: 14237 case OPC_DADDU: 14238 case OPC_DSUB: 14239 case OPC_DSUBU: 14240 check_insn(ctx, ISA_MIPS3); 14241 check_mips_64(ctx); 14242 gen_arith(ctx, op1, rd, rs, rt); 14243 break; 14244 case OPC_DSLLV: 14245 case OPC_DSRAV: 14246 check_insn(ctx, ISA_MIPS3); 14247 check_mips_64(ctx); 14248 gen_shift(ctx, op1, rd, rs, rt); 14249 break; 14250 case OPC_DSRLV: 14251 switch ((ctx->opcode >> 6) & 0x1f) { 14252 case 1: 14253 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 14254 if (ctx->insn_flags & ISA_MIPS_R2) { 14255 op1 = OPC_DROTRV; 14256 } 14257 /* Fallthrough */ 14258 case 0: 14259 check_insn(ctx, ISA_MIPS3); 14260 check_mips_64(ctx); 14261 gen_shift(ctx, op1, rd, rs, rt); 14262 break; 14263 default: 14264 gen_reserved_instruction(ctx); 14265 break; 14266 } 14267 break; 14268 #endif 14269 default: 14270 if (ctx->insn_flags & ISA_MIPS_R6) { 14271 decode_opc_special_r6(env, ctx); 14272 } else if (ctx->insn_flags & INSN_R5900) { 14273 decode_opc_special_tx79(env, ctx); 14274 } else { 14275 decode_opc_special_legacy(env, ctx); 14276 } 14277 } 14278 } 14279 14280 14281 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 14282 { 14283 int rs, rt, rd; 14284 uint32_t op1; 14285 14286 rs = (ctx->opcode >> 21) & 0x1f; 14287 rt = (ctx->opcode >> 16) & 0x1f; 14288 rd = (ctx->opcode >> 11) & 0x1f; 14289 14290 op1 = MASK_SPECIAL2(ctx->opcode); 14291 switch (op1) { 14292 case OPC_MADD: /* Multiply and add/sub */ 14293 case OPC_MADDU: 14294 case OPC_MSUB: 14295 case OPC_MSUBU: 14296 check_insn(ctx, ISA_MIPS_R1); 14297 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14298 break; 14299 case OPC_MUL: 14300 gen_arith(ctx, op1, rd, rs, rt); 14301 break; 14302 case OPC_DIV_G_2F: 14303 case OPC_DIVU_G_2F: 14304 case OPC_MULT_G_2F: 14305 case OPC_MULTU_G_2F: 14306 case OPC_MOD_G_2F: 14307 case OPC_MODU_G_2F: 14308 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14309 gen_loongson_integer(ctx, op1, rd, rs, rt); 14310 break; 14311 case OPC_CLO: 14312 case OPC_CLZ: 14313 check_insn(ctx, ISA_MIPS_R1); 14314 gen_cl(ctx, op1, rd, rs); 14315 break; 14316 case OPC_SDBBP: 14317 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 14318 ctx->base.is_jmp = DISAS_SEMIHOST; 14319 } else { 14320 /* 14321 * XXX: not clear which exception should be raised 14322 * when in debug mode... 14323 */ 14324 check_insn(ctx, ISA_MIPS_R1); 14325 generate_exception_end(ctx, EXCP_DBp); 14326 } 14327 break; 14328 #if defined(TARGET_MIPS64) 14329 case OPC_DCLO: 14330 case OPC_DCLZ: 14331 check_insn(ctx, ISA_MIPS_R1); 14332 check_mips_64(ctx); 14333 gen_cl(ctx, op1, rd, rs); 14334 break; 14335 case OPC_DMULT_G_2F: 14336 case OPC_DMULTU_G_2F: 14337 case OPC_DDIV_G_2F: 14338 case OPC_DDIVU_G_2F: 14339 case OPC_DMOD_G_2F: 14340 case OPC_DMODU_G_2F: 14341 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14342 gen_loongson_integer(ctx, op1, rd, rs, rt); 14343 break; 14344 #endif 14345 default: /* Invalid */ 14346 MIPS_INVAL("special2_legacy"); 14347 gen_reserved_instruction(ctx); 14348 break; 14349 } 14350 } 14351 14352 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 14353 { 14354 int rs, rt, rd, sa; 14355 uint32_t op1, op2; 14356 int16_t imm; 14357 14358 rs = (ctx->opcode >> 21) & 0x1f; 14359 rt = (ctx->opcode >> 16) & 0x1f; 14360 rd = (ctx->opcode >> 11) & 0x1f; 14361 sa = (ctx->opcode >> 6) & 0x1f; 14362 imm = (int16_t)ctx->opcode >> 7; 14363 14364 op1 = MASK_SPECIAL3(ctx->opcode); 14365 switch (op1) { 14366 case R6_OPC_PREF: 14367 if (rt >= 24) { 14368 /* hint codes 24-31 are reserved and signal RI */ 14369 gen_reserved_instruction(ctx); 14370 } 14371 /* Treat as NOP. */ 14372 break; 14373 case R6_OPC_CACHE: 14374 check_cp0_enabled(ctx); 14375 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14376 gen_cache_operation(ctx, rt, rs, imm); 14377 } 14378 break; 14379 case R6_OPC_SC: 14380 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14381 break; 14382 case R6_OPC_LL: 14383 gen_ld(ctx, op1, rt, rs, imm); 14384 break; 14385 case OPC_BSHFL: 14386 { 14387 if (rd == 0) { 14388 /* Treat as NOP. */ 14389 break; 14390 } 14391 op2 = MASK_BSHFL(ctx->opcode); 14392 switch (op2) { 14393 case OPC_ALIGN: 14394 case OPC_ALIGN_1: 14395 case OPC_ALIGN_2: 14396 case OPC_ALIGN_3: 14397 gen_align(ctx, 32, rd, rs, rt, sa & 3); 14398 break; 14399 case OPC_BITSWAP: 14400 gen_bitswap(ctx, op2, rd, rt); 14401 break; 14402 } 14403 } 14404 break; 14405 #ifndef CONFIG_USER_ONLY 14406 case OPC_GINV: 14407 if (unlikely(ctx->gi <= 1)) { 14408 gen_reserved_instruction(ctx); 14409 } 14410 check_cp0_enabled(ctx); 14411 switch ((ctx->opcode >> 6) & 3) { 14412 case 0: /* GINVI */ 14413 /* Treat as NOP. */ 14414 break; 14415 case 2: /* GINVT */ 14416 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 14417 break; 14418 default: 14419 gen_reserved_instruction(ctx); 14420 break; 14421 } 14422 break; 14423 #endif 14424 #if defined(TARGET_MIPS64) 14425 case R6_OPC_SCD: 14426 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 14427 break; 14428 case R6_OPC_LLD: 14429 gen_ld(ctx, op1, rt, rs, imm); 14430 break; 14431 case OPC_DBSHFL: 14432 check_mips_64(ctx); 14433 { 14434 if (rd == 0) { 14435 /* Treat as NOP. */ 14436 break; 14437 } 14438 op2 = MASK_DBSHFL(ctx->opcode); 14439 switch (op2) { 14440 case OPC_DALIGN: 14441 case OPC_DALIGN_1: 14442 case OPC_DALIGN_2: 14443 case OPC_DALIGN_3: 14444 case OPC_DALIGN_4: 14445 case OPC_DALIGN_5: 14446 case OPC_DALIGN_6: 14447 case OPC_DALIGN_7: 14448 gen_align(ctx, 64, rd, rs, rt, sa & 7); 14449 break; 14450 case OPC_DBITSWAP: 14451 gen_bitswap(ctx, op2, rd, rt); 14452 break; 14453 } 14454 14455 } 14456 break; 14457 #endif 14458 default: /* Invalid */ 14459 MIPS_INVAL("special3_r6"); 14460 gen_reserved_instruction(ctx); 14461 break; 14462 } 14463 } 14464 14465 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 14466 { 14467 int rs, rt, rd; 14468 uint32_t op1, op2; 14469 14470 rs = (ctx->opcode >> 21) & 0x1f; 14471 rt = (ctx->opcode >> 16) & 0x1f; 14472 rd = (ctx->opcode >> 11) & 0x1f; 14473 14474 op1 = MASK_SPECIAL3(ctx->opcode); 14475 switch (op1) { 14476 case OPC_DIV_G_2E: 14477 case OPC_DIVU_G_2E: 14478 case OPC_MOD_G_2E: 14479 case OPC_MODU_G_2E: 14480 case OPC_MULT_G_2E: 14481 case OPC_MULTU_G_2E: 14482 /* 14483 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 14484 * the same mask and op1. 14485 */ 14486 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 14487 op2 = MASK_ADDUH_QB(ctx->opcode); 14488 switch (op2) { 14489 case OPC_ADDUH_QB: 14490 case OPC_ADDUH_R_QB: 14491 case OPC_ADDQH_PH: 14492 case OPC_ADDQH_R_PH: 14493 case OPC_ADDQH_W: 14494 case OPC_ADDQH_R_W: 14495 case OPC_SUBUH_QB: 14496 case OPC_SUBUH_R_QB: 14497 case OPC_SUBQH_PH: 14498 case OPC_SUBQH_R_PH: 14499 case OPC_SUBQH_W: 14500 case OPC_SUBQH_R_W: 14501 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14502 break; 14503 case OPC_MUL_PH: 14504 case OPC_MUL_S_PH: 14505 case OPC_MULQ_S_W: 14506 case OPC_MULQ_RS_W: 14507 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14508 break; 14509 default: 14510 MIPS_INVAL("MASK ADDUH.QB"); 14511 gen_reserved_instruction(ctx); 14512 break; 14513 } 14514 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 14515 gen_loongson_integer(ctx, op1, rd, rs, rt); 14516 } else { 14517 gen_reserved_instruction(ctx); 14518 } 14519 break; 14520 case OPC_LX_DSP: 14521 op2 = MASK_LX(ctx->opcode); 14522 switch (op2) { 14523 #if defined(TARGET_MIPS64) 14524 case OPC_LDX: 14525 #endif 14526 case OPC_LBUX: 14527 case OPC_LHX: 14528 case OPC_LWX: 14529 gen_mips_lx(ctx, op2, rd, rs, rt); 14530 break; 14531 default: /* Invalid */ 14532 MIPS_INVAL("MASK LX"); 14533 gen_reserved_instruction(ctx); 14534 break; 14535 } 14536 break; 14537 case OPC_ABSQ_S_PH_DSP: 14538 op2 = MASK_ABSQ_S_PH(ctx->opcode); 14539 switch (op2) { 14540 case OPC_ABSQ_S_QB: 14541 case OPC_ABSQ_S_PH: 14542 case OPC_ABSQ_S_W: 14543 case OPC_PRECEQ_W_PHL: 14544 case OPC_PRECEQ_W_PHR: 14545 case OPC_PRECEQU_PH_QBL: 14546 case OPC_PRECEQU_PH_QBR: 14547 case OPC_PRECEQU_PH_QBLA: 14548 case OPC_PRECEQU_PH_QBRA: 14549 case OPC_PRECEU_PH_QBL: 14550 case OPC_PRECEU_PH_QBR: 14551 case OPC_PRECEU_PH_QBLA: 14552 case OPC_PRECEU_PH_QBRA: 14553 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14554 break; 14555 case OPC_BITREV: 14556 case OPC_REPL_QB: 14557 case OPC_REPLV_QB: 14558 case OPC_REPL_PH: 14559 case OPC_REPLV_PH: 14560 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14561 break; 14562 default: 14563 MIPS_INVAL("MASK ABSQ_S.PH"); 14564 gen_reserved_instruction(ctx); 14565 break; 14566 } 14567 break; 14568 case OPC_ADDU_QB_DSP: 14569 op2 = MASK_ADDU_QB(ctx->opcode); 14570 switch (op2) { 14571 case OPC_ADDQ_PH: 14572 case OPC_ADDQ_S_PH: 14573 case OPC_ADDQ_S_W: 14574 case OPC_ADDU_QB: 14575 case OPC_ADDU_S_QB: 14576 case OPC_ADDU_PH: 14577 case OPC_ADDU_S_PH: 14578 case OPC_SUBQ_PH: 14579 case OPC_SUBQ_S_PH: 14580 case OPC_SUBQ_S_W: 14581 case OPC_SUBU_QB: 14582 case OPC_SUBU_S_QB: 14583 case OPC_SUBU_PH: 14584 case OPC_SUBU_S_PH: 14585 case OPC_ADDSC: 14586 case OPC_ADDWC: 14587 case OPC_MODSUB: 14588 case OPC_RADDU_W_QB: 14589 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14590 break; 14591 case OPC_MULEU_S_PH_QBL: 14592 case OPC_MULEU_S_PH_QBR: 14593 case OPC_MULQ_RS_PH: 14594 case OPC_MULEQ_S_W_PHL: 14595 case OPC_MULEQ_S_W_PHR: 14596 case OPC_MULQ_S_PH: 14597 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14598 break; 14599 default: /* Invalid */ 14600 MIPS_INVAL("MASK ADDU.QB"); 14601 gen_reserved_instruction(ctx); 14602 break; 14603 14604 } 14605 break; 14606 case OPC_CMPU_EQ_QB_DSP: 14607 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14608 switch (op2) { 14609 case OPC_PRECR_SRA_PH_W: 14610 case OPC_PRECR_SRA_R_PH_W: 14611 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14612 break; 14613 case OPC_PRECR_QB_PH: 14614 case OPC_PRECRQ_QB_PH: 14615 case OPC_PRECRQ_PH_W: 14616 case OPC_PRECRQ_RS_PH_W: 14617 case OPC_PRECRQU_S_QB_PH: 14618 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14619 break; 14620 case OPC_CMPU_EQ_QB: 14621 case OPC_CMPU_LT_QB: 14622 case OPC_CMPU_LE_QB: 14623 case OPC_CMP_EQ_PH: 14624 case OPC_CMP_LT_PH: 14625 case OPC_CMP_LE_PH: 14626 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14627 break; 14628 case OPC_CMPGU_EQ_QB: 14629 case OPC_CMPGU_LT_QB: 14630 case OPC_CMPGU_LE_QB: 14631 case OPC_CMPGDU_EQ_QB: 14632 case OPC_CMPGDU_LT_QB: 14633 case OPC_CMPGDU_LE_QB: 14634 case OPC_PICK_QB: 14635 case OPC_PICK_PH: 14636 case OPC_PACKRL_PH: 14637 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14638 break; 14639 default: /* Invalid */ 14640 MIPS_INVAL("MASK CMPU.EQ.QB"); 14641 gen_reserved_instruction(ctx); 14642 break; 14643 } 14644 break; 14645 case OPC_SHLL_QB_DSP: 14646 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14647 break; 14648 case OPC_DPA_W_PH_DSP: 14649 op2 = MASK_DPA_W_PH(ctx->opcode); 14650 switch (op2) { 14651 case OPC_DPAU_H_QBL: 14652 case OPC_DPAU_H_QBR: 14653 case OPC_DPSU_H_QBL: 14654 case OPC_DPSU_H_QBR: 14655 case OPC_DPA_W_PH: 14656 case OPC_DPAX_W_PH: 14657 case OPC_DPAQ_S_W_PH: 14658 case OPC_DPAQX_S_W_PH: 14659 case OPC_DPAQX_SA_W_PH: 14660 case OPC_DPS_W_PH: 14661 case OPC_DPSX_W_PH: 14662 case OPC_DPSQ_S_W_PH: 14663 case OPC_DPSQX_S_W_PH: 14664 case OPC_DPSQX_SA_W_PH: 14665 case OPC_MULSAQ_S_W_PH: 14666 case OPC_DPAQ_SA_L_W: 14667 case OPC_DPSQ_SA_L_W: 14668 case OPC_MAQ_S_W_PHL: 14669 case OPC_MAQ_S_W_PHR: 14670 case OPC_MAQ_SA_W_PHL: 14671 case OPC_MAQ_SA_W_PHR: 14672 case OPC_MULSA_W_PH: 14673 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14674 break; 14675 default: /* Invalid */ 14676 MIPS_INVAL("MASK DPAW.PH"); 14677 gen_reserved_instruction(ctx); 14678 break; 14679 } 14680 break; 14681 case OPC_INSV_DSP: 14682 op2 = MASK_INSV(ctx->opcode); 14683 switch (op2) { 14684 case OPC_INSV: 14685 check_dsp(ctx); 14686 { 14687 TCGv t0, t1; 14688 14689 if (rt == 0) { 14690 break; 14691 } 14692 14693 t0 = tcg_temp_new(); 14694 t1 = tcg_temp_new(); 14695 14696 gen_load_gpr(t0, rt); 14697 gen_load_gpr(t1, rs); 14698 14699 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14700 14701 tcg_temp_free(t0); 14702 tcg_temp_free(t1); 14703 break; 14704 } 14705 default: /* Invalid */ 14706 MIPS_INVAL("MASK INSV"); 14707 gen_reserved_instruction(ctx); 14708 break; 14709 } 14710 break; 14711 case OPC_APPEND_DSP: 14712 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14713 break; 14714 case OPC_EXTR_W_DSP: 14715 op2 = MASK_EXTR_W(ctx->opcode); 14716 switch (op2) { 14717 case OPC_EXTR_W: 14718 case OPC_EXTR_R_W: 14719 case OPC_EXTR_RS_W: 14720 case OPC_EXTR_S_H: 14721 case OPC_EXTRV_S_H: 14722 case OPC_EXTRV_W: 14723 case OPC_EXTRV_R_W: 14724 case OPC_EXTRV_RS_W: 14725 case OPC_EXTP: 14726 case OPC_EXTPV: 14727 case OPC_EXTPDP: 14728 case OPC_EXTPDPV: 14729 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14730 break; 14731 case OPC_RDDSP: 14732 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14733 break; 14734 case OPC_SHILO: 14735 case OPC_SHILOV: 14736 case OPC_MTHLIP: 14737 case OPC_WRDSP: 14738 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14739 break; 14740 default: /* Invalid */ 14741 MIPS_INVAL("MASK EXTR.W"); 14742 gen_reserved_instruction(ctx); 14743 break; 14744 } 14745 break; 14746 #if defined(TARGET_MIPS64) 14747 case OPC_DDIV_G_2E: 14748 case OPC_DDIVU_G_2E: 14749 case OPC_DMULT_G_2E: 14750 case OPC_DMULTU_G_2E: 14751 case OPC_DMOD_G_2E: 14752 case OPC_DMODU_G_2E: 14753 check_insn(ctx, INSN_LOONGSON2E); 14754 gen_loongson_integer(ctx, op1, rd, rs, rt); 14755 break; 14756 case OPC_ABSQ_S_QH_DSP: 14757 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14758 switch (op2) { 14759 case OPC_PRECEQ_L_PWL: 14760 case OPC_PRECEQ_L_PWR: 14761 case OPC_PRECEQ_PW_QHL: 14762 case OPC_PRECEQ_PW_QHR: 14763 case OPC_PRECEQ_PW_QHLA: 14764 case OPC_PRECEQ_PW_QHRA: 14765 case OPC_PRECEQU_QH_OBL: 14766 case OPC_PRECEQU_QH_OBR: 14767 case OPC_PRECEQU_QH_OBLA: 14768 case OPC_PRECEQU_QH_OBRA: 14769 case OPC_PRECEU_QH_OBL: 14770 case OPC_PRECEU_QH_OBR: 14771 case OPC_PRECEU_QH_OBLA: 14772 case OPC_PRECEU_QH_OBRA: 14773 case OPC_ABSQ_S_OB: 14774 case OPC_ABSQ_S_PW: 14775 case OPC_ABSQ_S_QH: 14776 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14777 break; 14778 case OPC_REPL_OB: 14779 case OPC_REPL_PW: 14780 case OPC_REPL_QH: 14781 case OPC_REPLV_OB: 14782 case OPC_REPLV_PW: 14783 case OPC_REPLV_QH: 14784 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14785 break; 14786 default: /* Invalid */ 14787 MIPS_INVAL("MASK ABSQ_S.QH"); 14788 gen_reserved_instruction(ctx); 14789 break; 14790 } 14791 break; 14792 case OPC_ADDU_OB_DSP: 14793 op2 = MASK_ADDU_OB(ctx->opcode); 14794 switch (op2) { 14795 case OPC_RADDU_L_OB: 14796 case OPC_SUBQ_PW: 14797 case OPC_SUBQ_S_PW: 14798 case OPC_SUBQ_QH: 14799 case OPC_SUBQ_S_QH: 14800 case OPC_SUBU_OB: 14801 case OPC_SUBU_S_OB: 14802 case OPC_SUBU_QH: 14803 case OPC_SUBU_S_QH: 14804 case OPC_SUBUH_OB: 14805 case OPC_SUBUH_R_OB: 14806 case OPC_ADDQ_PW: 14807 case OPC_ADDQ_S_PW: 14808 case OPC_ADDQ_QH: 14809 case OPC_ADDQ_S_QH: 14810 case OPC_ADDU_OB: 14811 case OPC_ADDU_S_OB: 14812 case OPC_ADDU_QH: 14813 case OPC_ADDU_S_QH: 14814 case OPC_ADDUH_OB: 14815 case OPC_ADDUH_R_OB: 14816 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14817 break; 14818 case OPC_MULEQ_S_PW_QHL: 14819 case OPC_MULEQ_S_PW_QHR: 14820 case OPC_MULEU_S_QH_OBL: 14821 case OPC_MULEU_S_QH_OBR: 14822 case OPC_MULQ_RS_QH: 14823 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14824 break; 14825 default: /* Invalid */ 14826 MIPS_INVAL("MASK ADDU.OB"); 14827 gen_reserved_instruction(ctx); 14828 break; 14829 } 14830 break; 14831 case OPC_CMPU_EQ_OB_DSP: 14832 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14833 switch (op2) { 14834 case OPC_PRECR_SRA_QH_PW: 14835 case OPC_PRECR_SRA_R_QH_PW: 14836 /* Return value is rt. */ 14837 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14838 break; 14839 case OPC_PRECR_OB_QH: 14840 case OPC_PRECRQ_OB_QH: 14841 case OPC_PRECRQ_PW_L: 14842 case OPC_PRECRQ_QH_PW: 14843 case OPC_PRECRQ_RS_QH_PW: 14844 case OPC_PRECRQU_S_OB_QH: 14845 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14846 break; 14847 case OPC_CMPU_EQ_OB: 14848 case OPC_CMPU_LT_OB: 14849 case OPC_CMPU_LE_OB: 14850 case OPC_CMP_EQ_QH: 14851 case OPC_CMP_LT_QH: 14852 case OPC_CMP_LE_QH: 14853 case OPC_CMP_EQ_PW: 14854 case OPC_CMP_LT_PW: 14855 case OPC_CMP_LE_PW: 14856 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14857 break; 14858 case OPC_CMPGDU_EQ_OB: 14859 case OPC_CMPGDU_LT_OB: 14860 case OPC_CMPGDU_LE_OB: 14861 case OPC_CMPGU_EQ_OB: 14862 case OPC_CMPGU_LT_OB: 14863 case OPC_CMPGU_LE_OB: 14864 case OPC_PACKRL_PW: 14865 case OPC_PICK_OB: 14866 case OPC_PICK_PW: 14867 case OPC_PICK_QH: 14868 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14869 break; 14870 default: /* Invalid */ 14871 MIPS_INVAL("MASK CMPU_EQ.OB"); 14872 gen_reserved_instruction(ctx); 14873 break; 14874 } 14875 break; 14876 case OPC_DAPPEND_DSP: 14877 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14878 break; 14879 case OPC_DEXTR_W_DSP: 14880 op2 = MASK_DEXTR_W(ctx->opcode); 14881 switch (op2) { 14882 case OPC_DEXTP: 14883 case OPC_DEXTPDP: 14884 case OPC_DEXTPDPV: 14885 case OPC_DEXTPV: 14886 case OPC_DEXTR_L: 14887 case OPC_DEXTR_R_L: 14888 case OPC_DEXTR_RS_L: 14889 case OPC_DEXTR_W: 14890 case OPC_DEXTR_R_W: 14891 case OPC_DEXTR_RS_W: 14892 case OPC_DEXTR_S_H: 14893 case OPC_DEXTRV_L: 14894 case OPC_DEXTRV_R_L: 14895 case OPC_DEXTRV_RS_L: 14896 case OPC_DEXTRV_S_H: 14897 case OPC_DEXTRV_W: 14898 case OPC_DEXTRV_R_W: 14899 case OPC_DEXTRV_RS_W: 14900 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14901 break; 14902 case OPC_DMTHLIP: 14903 case OPC_DSHILO: 14904 case OPC_DSHILOV: 14905 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14906 break; 14907 default: /* Invalid */ 14908 MIPS_INVAL("MASK EXTR.W"); 14909 gen_reserved_instruction(ctx); 14910 break; 14911 } 14912 break; 14913 case OPC_DPAQ_W_QH_DSP: 14914 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14915 switch (op2) { 14916 case OPC_DPAU_H_OBL: 14917 case OPC_DPAU_H_OBR: 14918 case OPC_DPSU_H_OBL: 14919 case OPC_DPSU_H_OBR: 14920 case OPC_DPA_W_QH: 14921 case OPC_DPAQ_S_W_QH: 14922 case OPC_DPS_W_QH: 14923 case OPC_DPSQ_S_W_QH: 14924 case OPC_MULSAQ_S_W_QH: 14925 case OPC_DPAQ_SA_L_PW: 14926 case OPC_DPSQ_SA_L_PW: 14927 case OPC_MULSAQ_S_L_PW: 14928 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14929 break; 14930 case OPC_MAQ_S_W_QHLL: 14931 case OPC_MAQ_S_W_QHLR: 14932 case OPC_MAQ_S_W_QHRL: 14933 case OPC_MAQ_S_W_QHRR: 14934 case OPC_MAQ_SA_W_QHLL: 14935 case OPC_MAQ_SA_W_QHLR: 14936 case OPC_MAQ_SA_W_QHRL: 14937 case OPC_MAQ_SA_W_QHRR: 14938 case OPC_MAQ_S_L_PWL: 14939 case OPC_MAQ_S_L_PWR: 14940 case OPC_DMADD: 14941 case OPC_DMADDU: 14942 case OPC_DMSUB: 14943 case OPC_DMSUBU: 14944 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14945 break; 14946 default: /* Invalid */ 14947 MIPS_INVAL("MASK DPAQ.W.QH"); 14948 gen_reserved_instruction(ctx); 14949 break; 14950 } 14951 break; 14952 case OPC_DINSV_DSP: 14953 op2 = MASK_INSV(ctx->opcode); 14954 switch (op2) { 14955 case OPC_DINSV: 14956 { 14957 TCGv t0, t1; 14958 14959 check_dsp(ctx); 14960 14961 if (rt == 0) { 14962 break; 14963 } 14964 14965 t0 = tcg_temp_new(); 14966 t1 = tcg_temp_new(); 14967 14968 gen_load_gpr(t0, rt); 14969 gen_load_gpr(t1, rs); 14970 14971 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 14972 14973 tcg_temp_free(t0); 14974 tcg_temp_free(t1); 14975 break; 14976 } 14977 default: /* Invalid */ 14978 MIPS_INVAL("MASK DINSV"); 14979 gen_reserved_instruction(ctx); 14980 break; 14981 } 14982 break; 14983 case OPC_SHLL_OB_DSP: 14984 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14985 break; 14986 #endif 14987 default: /* Invalid */ 14988 MIPS_INVAL("special3_legacy"); 14989 gen_reserved_instruction(ctx); 14990 break; 14991 } 14992 } 14993 14994 14995 #if defined(TARGET_MIPS64) 14996 14997 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14998 { 14999 uint32_t opc = MASK_MMI(ctx->opcode); 15000 int rs = extract32(ctx->opcode, 21, 5); 15001 int rt = extract32(ctx->opcode, 16, 5); 15002 int rd = extract32(ctx->opcode, 11, 5); 15003 15004 switch (opc) { 15005 case MMI_OPC_MULT1: 15006 case MMI_OPC_MULTU1: 15007 case MMI_OPC_MADD: 15008 case MMI_OPC_MADDU: 15009 case MMI_OPC_MADD1: 15010 case MMI_OPC_MADDU1: 15011 gen_mul_txx9(ctx, opc, rd, rs, rt); 15012 break; 15013 case MMI_OPC_DIV1: 15014 case MMI_OPC_DIVU1: 15015 gen_div1_tx79(ctx, opc, rs, rt); 15016 break; 15017 default: 15018 MIPS_INVAL("TX79 MMI class"); 15019 gen_reserved_instruction(ctx); 15020 break; 15021 } 15022 } 15023 15024 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 15025 { 15026 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 15027 } 15028 15029 /* 15030 * The TX79-specific instruction Store Quadword 15031 * 15032 * +--------+-------+-------+------------------------+ 15033 * | 011111 | base | rt | offset | SQ 15034 * +--------+-------+-------+------------------------+ 15035 * 6 5 5 16 15036 * 15037 * has the same opcode as the Read Hardware Register instruction 15038 * 15039 * +--------+-------+-------+-------+-------+--------+ 15040 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 15041 * +--------+-------+-------+-------+-------+--------+ 15042 * 6 5 5 5 5 6 15043 * 15044 * that is required, trapped and emulated by the Linux kernel. However, all 15045 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 15046 * offset is odd. Therefore all valid SQ instructions can execute normally. 15047 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 15048 * between SQ and RDHWR, as the Linux kernel does. 15049 */ 15050 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 15051 { 15052 int base = extract32(ctx->opcode, 21, 5); 15053 int rt = extract32(ctx->opcode, 16, 5); 15054 int offset = extract32(ctx->opcode, 0, 16); 15055 15056 #ifdef CONFIG_USER_ONLY 15057 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 15058 uint32_t op2 = extract32(ctx->opcode, 6, 5); 15059 15060 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 15061 int rd = extract32(ctx->opcode, 11, 5); 15062 15063 gen_rdhwr(ctx, rt, rd, 0); 15064 return; 15065 } 15066 #endif 15067 15068 gen_mmi_sq(ctx, base, rt, offset); 15069 } 15070 15071 #endif 15072 15073 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 15074 { 15075 int rs, rt, rd, sa; 15076 uint32_t op1, op2; 15077 int16_t imm; 15078 15079 rs = (ctx->opcode >> 21) & 0x1f; 15080 rt = (ctx->opcode >> 16) & 0x1f; 15081 rd = (ctx->opcode >> 11) & 0x1f; 15082 sa = (ctx->opcode >> 6) & 0x1f; 15083 imm = sextract32(ctx->opcode, 7, 9); 15084 15085 op1 = MASK_SPECIAL3(ctx->opcode); 15086 15087 /* 15088 * EVA loads and stores overlap Loongson 2E instructions decoded by 15089 * decode_opc_special3_legacy(), so be careful to allow their decoding when 15090 * EVA is absent. 15091 */ 15092 if (ctx->eva) { 15093 switch (op1) { 15094 case OPC_LWLE: 15095 case OPC_LWRE: 15096 case OPC_LBUE: 15097 case OPC_LHUE: 15098 case OPC_LBE: 15099 case OPC_LHE: 15100 case OPC_LLE: 15101 case OPC_LWE: 15102 check_cp0_enabled(ctx); 15103 gen_ld(ctx, op1, rt, rs, imm); 15104 return; 15105 case OPC_SWLE: 15106 case OPC_SWRE: 15107 case OPC_SBE: 15108 case OPC_SHE: 15109 case OPC_SWE: 15110 check_cp0_enabled(ctx); 15111 gen_st(ctx, op1, rt, rs, imm); 15112 return; 15113 case OPC_SCE: 15114 check_cp0_enabled(ctx); 15115 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 15116 return; 15117 case OPC_CACHEE: 15118 check_eva(ctx); 15119 check_cp0_enabled(ctx); 15120 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15121 gen_cache_operation(ctx, rt, rs, imm); 15122 } 15123 return; 15124 case OPC_PREFE: 15125 check_cp0_enabled(ctx); 15126 /* Treat as NOP. */ 15127 return; 15128 } 15129 } 15130 15131 switch (op1) { 15132 case OPC_EXT: 15133 case OPC_INS: 15134 check_insn(ctx, ISA_MIPS_R2); 15135 gen_bitops(ctx, op1, rt, rs, sa, rd); 15136 break; 15137 case OPC_BSHFL: 15138 op2 = MASK_BSHFL(ctx->opcode); 15139 switch (op2) { 15140 case OPC_ALIGN: 15141 case OPC_ALIGN_1: 15142 case OPC_ALIGN_2: 15143 case OPC_ALIGN_3: 15144 case OPC_BITSWAP: 15145 check_insn(ctx, ISA_MIPS_R6); 15146 decode_opc_special3_r6(env, ctx); 15147 break; 15148 default: 15149 check_insn(ctx, ISA_MIPS_R2); 15150 gen_bshfl(ctx, op2, rt, rd); 15151 break; 15152 } 15153 break; 15154 #if defined(TARGET_MIPS64) 15155 case OPC_DEXTM: 15156 case OPC_DEXTU: 15157 case OPC_DEXT: 15158 case OPC_DINSM: 15159 case OPC_DINSU: 15160 case OPC_DINS: 15161 check_insn(ctx, ISA_MIPS_R2); 15162 check_mips_64(ctx); 15163 gen_bitops(ctx, op1, rt, rs, sa, rd); 15164 break; 15165 case OPC_DBSHFL: 15166 op2 = MASK_DBSHFL(ctx->opcode); 15167 switch (op2) { 15168 case OPC_DALIGN: 15169 case OPC_DALIGN_1: 15170 case OPC_DALIGN_2: 15171 case OPC_DALIGN_3: 15172 case OPC_DALIGN_4: 15173 case OPC_DALIGN_5: 15174 case OPC_DALIGN_6: 15175 case OPC_DALIGN_7: 15176 case OPC_DBITSWAP: 15177 check_insn(ctx, ISA_MIPS_R6); 15178 decode_opc_special3_r6(env, ctx); 15179 break; 15180 default: 15181 check_insn(ctx, ISA_MIPS_R2); 15182 check_mips_64(ctx); 15183 op2 = MASK_DBSHFL(ctx->opcode); 15184 gen_bshfl(ctx, op2, rt, rd); 15185 break; 15186 } 15187 break; 15188 #endif 15189 case OPC_RDHWR: 15190 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 15191 break; 15192 case OPC_FORK: 15193 check_mt(ctx); 15194 { 15195 TCGv t0 = tcg_temp_new(); 15196 TCGv t1 = tcg_temp_new(); 15197 15198 gen_load_gpr(t0, rt); 15199 gen_load_gpr(t1, rs); 15200 gen_helper_fork(t0, t1); 15201 tcg_temp_free(t0); 15202 tcg_temp_free(t1); 15203 } 15204 break; 15205 case OPC_YIELD: 15206 check_mt(ctx); 15207 { 15208 TCGv t0 = tcg_temp_new(); 15209 15210 gen_load_gpr(t0, rs); 15211 gen_helper_yield(t0, cpu_env, t0); 15212 gen_store_gpr(t0, rd); 15213 tcg_temp_free(t0); 15214 } 15215 break; 15216 default: 15217 if (ctx->insn_flags & ISA_MIPS_R6) { 15218 decode_opc_special3_r6(env, ctx); 15219 } else { 15220 decode_opc_special3_legacy(env, ctx); 15221 } 15222 } 15223 } 15224 15225 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 15226 { 15227 int32_t offset; 15228 int rs, rt, rd, sa; 15229 uint32_t op, op1; 15230 int16_t imm; 15231 15232 op = MASK_OP_MAJOR(ctx->opcode); 15233 rs = (ctx->opcode >> 21) & 0x1f; 15234 rt = (ctx->opcode >> 16) & 0x1f; 15235 rd = (ctx->opcode >> 11) & 0x1f; 15236 sa = (ctx->opcode >> 6) & 0x1f; 15237 imm = (int16_t)ctx->opcode; 15238 switch (op) { 15239 case OPC_SPECIAL: 15240 decode_opc_special(env, ctx); 15241 break; 15242 case OPC_SPECIAL2: 15243 #if defined(TARGET_MIPS64) 15244 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 15245 decode_mmi(env, ctx); 15246 break; 15247 } 15248 #endif 15249 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 15250 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 15251 gen_arith(ctx, OPC_MUL, rd, rs, rt); 15252 } else { 15253 decode_ase_mxu(ctx, ctx->opcode); 15254 } 15255 break; 15256 } 15257 decode_opc_special2_legacy(env, ctx); 15258 break; 15259 case OPC_SPECIAL3: 15260 #if defined(TARGET_MIPS64) 15261 if (ctx->insn_flags & INSN_R5900) { 15262 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 15263 } else { 15264 decode_opc_special3(env, ctx); 15265 } 15266 #else 15267 decode_opc_special3(env, ctx); 15268 #endif 15269 break; 15270 case OPC_REGIMM: 15271 op1 = MASK_REGIMM(ctx->opcode); 15272 switch (op1) { 15273 case OPC_BLTZL: /* REGIMM branches */ 15274 case OPC_BGEZL: 15275 case OPC_BLTZALL: 15276 case OPC_BGEZALL: 15277 check_insn(ctx, ISA_MIPS2); 15278 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15279 /* Fallthrough */ 15280 case OPC_BLTZ: 15281 case OPC_BGEZ: 15282 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15283 break; 15284 case OPC_BLTZAL: 15285 case OPC_BGEZAL: 15286 if (ctx->insn_flags & ISA_MIPS_R6) { 15287 if (rs == 0) { 15288 /* OPC_NAL, OPC_BAL */ 15289 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 15290 } else { 15291 gen_reserved_instruction(ctx); 15292 } 15293 } else { 15294 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15295 } 15296 break; 15297 case OPC_TGEI: /* REGIMM traps */ 15298 case OPC_TGEIU: 15299 case OPC_TLTI: 15300 case OPC_TLTIU: 15301 case OPC_TEQI: 15302 case OPC_TNEI: 15303 check_insn(ctx, ISA_MIPS2); 15304 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15305 gen_trap(ctx, op1, rs, -1, imm, 0); 15306 break; 15307 case OPC_SIGRIE: 15308 check_insn(ctx, ISA_MIPS_R6); 15309 gen_reserved_instruction(ctx); 15310 break; 15311 case OPC_SYNCI: 15312 check_insn(ctx, ISA_MIPS_R2); 15313 /* 15314 * Break the TB to be able to sync copied instructions 15315 * immediately. 15316 */ 15317 ctx->base.is_jmp = DISAS_STOP; 15318 break; 15319 case OPC_BPOSGE32: /* MIPS DSP branch */ 15320 #if defined(TARGET_MIPS64) 15321 case OPC_BPOSGE64: 15322 #endif 15323 check_dsp(ctx); 15324 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 15325 break; 15326 #if defined(TARGET_MIPS64) 15327 case OPC_DAHI: 15328 check_insn(ctx, ISA_MIPS_R6); 15329 check_mips_64(ctx); 15330 if (rs != 0) { 15331 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 15332 } 15333 break; 15334 case OPC_DATI: 15335 check_insn(ctx, ISA_MIPS_R6); 15336 check_mips_64(ctx); 15337 if (rs != 0) { 15338 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 15339 } 15340 break; 15341 #endif 15342 default: /* Invalid */ 15343 MIPS_INVAL("regimm"); 15344 gen_reserved_instruction(ctx); 15345 break; 15346 } 15347 break; 15348 case OPC_CP0: 15349 check_cp0_enabled(ctx); 15350 op1 = MASK_CP0(ctx->opcode); 15351 switch (op1) { 15352 case OPC_MFC0: 15353 case OPC_MTC0: 15354 case OPC_MFTR: 15355 case OPC_MTTR: 15356 case OPC_MFHC0: 15357 case OPC_MTHC0: 15358 #if defined(TARGET_MIPS64) 15359 case OPC_DMFC0: 15360 case OPC_DMTC0: 15361 #endif 15362 #ifndef CONFIG_USER_ONLY 15363 gen_cp0(env, ctx, op1, rt, rd); 15364 #endif /* !CONFIG_USER_ONLY */ 15365 break; 15366 case OPC_C0: 15367 case OPC_C0_1: 15368 case OPC_C0_2: 15369 case OPC_C0_3: 15370 case OPC_C0_4: 15371 case OPC_C0_5: 15372 case OPC_C0_6: 15373 case OPC_C0_7: 15374 case OPC_C0_8: 15375 case OPC_C0_9: 15376 case OPC_C0_A: 15377 case OPC_C0_B: 15378 case OPC_C0_C: 15379 case OPC_C0_D: 15380 case OPC_C0_E: 15381 case OPC_C0_F: 15382 #ifndef CONFIG_USER_ONLY 15383 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 15384 #endif /* !CONFIG_USER_ONLY */ 15385 break; 15386 case OPC_MFMC0: 15387 #ifndef CONFIG_USER_ONLY 15388 { 15389 uint32_t op2; 15390 TCGv t0 = tcg_temp_new(); 15391 15392 op2 = MASK_MFMC0(ctx->opcode); 15393 switch (op2) { 15394 case OPC_DMT: 15395 check_cp0_mt(ctx); 15396 gen_helper_dmt(t0); 15397 gen_store_gpr(t0, rt); 15398 break; 15399 case OPC_EMT: 15400 check_cp0_mt(ctx); 15401 gen_helper_emt(t0); 15402 gen_store_gpr(t0, rt); 15403 break; 15404 case OPC_DVPE: 15405 check_cp0_mt(ctx); 15406 gen_helper_dvpe(t0, cpu_env); 15407 gen_store_gpr(t0, rt); 15408 break; 15409 case OPC_EVPE: 15410 check_cp0_mt(ctx); 15411 gen_helper_evpe(t0, cpu_env); 15412 gen_store_gpr(t0, rt); 15413 break; 15414 case OPC_DVP: 15415 check_insn(ctx, ISA_MIPS_R6); 15416 if (ctx->vp) { 15417 gen_helper_dvp(t0, cpu_env); 15418 gen_store_gpr(t0, rt); 15419 } 15420 break; 15421 case OPC_EVP: 15422 check_insn(ctx, ISA_MIPS_R6); 15423 if (ctx->vp) { 15424 gen_helper_evp(t0, cpu_env); 15425 gen_store_gpr(t0, rt); 15426 } 15427 break; 15428 case OPC_DI: 15429 check_insn(ctx, ISA_MIPS_R2); 15430 save_cpu_state(ctx, 1); 15431 gen_helper_di(t0, cpu_env); 15432 gen_store_gpr(t0, rt); 15433 /* 15434 * Stop translation as we may have switched 15435 * the execution mode. 15436 */ 15437 ctx->base.is_jmp = DISAS_STOP; 15438 break; 15439 case OPC_EI: 15440 check_insn(ctx, ISA_MIPS_R2); 15441 save_cpu_state(ctx, 1); 15442 gen_helper_ei(t0, cpu_env); 15443 gen_store_gpr(t0, rt); 15444 /* 15445 * DISAS_STOP isn't sufficient, we need to ensure we break 15446 * out of translated code to check for pending interrupts. 15447 */ 15448 gen_save_pc(ctx->base.pc_next + 4); 15449 ctx->base.is_jmp = DISAS_EXIT; 15450 break; 15451 default: /* Invalid */ 15452 MIPS_INVAL("mfmc0"); 15453 gen_reserved_instruction(ctx); 15454 break; 15455 } 15456 tcg_temp_free(t0); 15457 } 15458 #endif /* !CONFIG_USER_ONLY */ 15459 break; 15460 case OPC_RDPGPR: 15461 check_insn(ctx, ISA_MIPS_R2); 15462 gen_load_srsgpr(rt, rd); 15463 break; 15464 case OPC_WRPGPR: 15465 check_insn(ctx, ISA_MIPS_R2); 15466 gen_store_srsgpr(rt, rd); 15467 break; 15468 default: 15469 MIPS_INVAL("cp0"); 15470 gen_reserved_instruction(ctx); 15471 break; 15472 } 15473 break; 15474 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 15475 if (ctx->insn_flags & ISA_MIPS_R6) { 15476 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 15477 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15478 } else { 15479 /* OPC_ADDI */ 15480 /* Arithmetic with immediate opcode */ 15481 gen_arith_imm(ctx, op, rt, rs, imm); 15482 } 15483 break; 15484 case OPC_ADDIU: 15485 gen_arith_imm(ctx, op, rt, rs, imm); 15486 break; 15487 case OPC_SLTI: /* Set on less than with immediate opcode */ 15488 case OPC_SLTIU: 15489 gen_slt_imm(ctx, op, rt, rs, imm); 15490 break; 15491 case OPC_ANDI: /* Arithmetic with immediate opcode */ 15492 case OPC_LUI: /* OPC_AUI */ 15493 case OPC_ORI: 15494 case OPC_XORI: 15495 gen_logic_imm(ctx, op, rt, rs, imm); 15496 break; 15497 case OPC_J: /* Jump */ 15498 case OPC_JAL: 15499 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15500 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15501 break; 15502 /* Branch */ 15503 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 15504 if (ctx->insn_flags & ISA_MIPS_R6) { 15505 if (rt == 0) { 15506 gen_reserved_instruction(ctx); 15507 break; 15508 } 15509 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 15510 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15511 } else { 15512 /* OPC_BLEZL */ 15513 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15514 } 15515 break; 15516 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 15517 if (ctx->insn_flags & ISA_MIPS_R6) { 15518 if (rt == 0) { 15519 gen_reserved_instruction(ctx); 15520 break; 15521 } 15522 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 15523 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15524 } else { 15525 /* OPC_BGTZL */ 15526 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15527 } 15528 break; 15529 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 15530 if (rt == 0) { 15531 /* OPC_BLEZ */ 15532 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15533 } else { 15534 check_insn(ctx, ISA_MIPS_R6); 15535 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 15536 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15537 } 15538 break; 15539 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 15540 if (rt == 0) { 15541 /* OPC_BGTZ */ 15542 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15543 } else { 15544 check_insn(ctx, ISA_MIPS_R6); 15545 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 15546 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15547 } 15548 break; 15549 case OPC_BEQL: 15550 case OPC_BNEL: 15551 check_insn(ctx, ISA_MIPS2); 15552 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15553 /* Fallthrough */ 15554 case OPC_BEQ: 15555 case OPC_BNE: 15556 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15557 break; 15558 case OPC_LL: /* Load and stores */ 15559 check_insn(ctx, ISA_MIPS2); 15560 if (ctx->insn_flags & INSN_R5900) { 15561 check_insn_opc_user_only(ctx, INSN_R5900); 15562 } 15563 /* Fallthrough */ 15564 case OPC_LWL: 15565 case OPC_LWR: 15566 case OPC_LB: 15567 case OPC_LH: 15568 case OPC_LW: 15569 case OPC_LWPC: 15570 case OPC_LBU: 15571 case OPC_LHU: 15572 gen_ld(ctx, op, rt, rs, imm); 15573 break; 15574 case OPC_SWL: 15575 case OPC_SWR: 15576 case OPC_SB: 15577 case OPC_SH: 15578 case OPC_SW: 15579 gen_st(ctx, op, rt, rs, imm); 15580 break; 15581 case OPC_SC: 15582 check_insn(ctx, ISA_MIPS2); 15583 if (ctx->insn_flags & INSN_R5900) { 15584 check_insn_opc_user_only(ctx, INSN_R5900); 15585 } 15586 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 15587 break; 15588 case OPC_CACHE: 15589 check_cp0_enabled(ctx); 15590 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 15591 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15592 gen_cache_operation(ctx, rt, rs, imm); 15593 } 15594 /* Treat as NOP. */ 15595 break; 15596 case OPC_PREF: 15597 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 15598 /* Treat as NOP. */ 15599 break; 15600 15601 /* Floating point (COP1). */ 15602 case OPC_LWC1: 15603 case OPC_LDC1: 15604 case OPC_SWC1: 15605 case OPC_SDC1: 15606 gen_cop1_ldst(ctx, op, rt, rs, imm); 15607 break; 15608 15609 case OPC_CP1: 15610 op1 = MASK_CP1(ctx->opcode); 15611 15612 switch (op1) { 15613 case OPC_MFHC1: 15614 case OPC_MTHC1: 15615 check_cp1_enabled(ctx); 15616 check_insn(ctx, ISA_MIPS_R2); 15617 /* fall through */ 15618 case OPC_MFC1: 15619 case OPC_CFC1: 15620 case OPC_MTC1: 15621 case OPC_CTC1: 15622 check_cp1_enabled(ctx); 15623 gen_cp1(ctx, op1, rt, rd); 15624 break; 15625 #if defined(TARGET_MIPS64) 15626 case OPC_DMFC1: 15627 case OPC_DMTC1: 15628 check_cp1_enabled(ctx); 15629 check_insn(ctx, ISA_MIPS3); 15630 check_mips_64(ctx); 15631 gen_cp1(ctx, op1, rt, rd); 15632 break; 15633 #endif 15634 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15635 check_cp1_enabled(ctx); 15636 if (ctx->insn_flags & ISA_MIPS_R6) { 15637 /* OPC_BC1EQZ */ 15638 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15639 rt, imm << 2, 4); 15640 } else { 15641 /* OPC_BC1ANY2 */ 15642 check_cop1x(ctx); 15643 check_insn(ctx, ASE_MIPS3D); 15644 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15645 (rt >> 2) & 0x7, imm << 2); 15646 } 15647 break; 15648 case OPC_BC1NEZ: 15649 check_cp1_enabled(ctx); 15650 check_insn(ctx, ISA_MIPS_R6); 15651 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15652 rt, imm << 2, 4); 15653 break; 15654 case OPC_BC1ANY4: 15655 check_cp1_enabled(ctx); 15656 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15657 check_cop1x(ctx); 15658 check_insn(ctx, ASE_MIPS3D); 15659 /* fall through */ 15660 case OPC_BC1: 15661 check_cp1_enabled(ctx); 15662 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15663 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15664 (rt >> 2) & 0x7, imm << 2); 15665 break; 15666 case OPC_PS_FMT: 15667 check_ps(ctx); 15668 /* fall through */ 15669 case OPC_S_FMT: 15670 case OPC_D_FMT: 15671 check_cp1_enabled(ctx); 15672 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15673 (imm >> 8) & 0x7); 15674 break; 15675 case OPC_W_FMT: 15676 case OPC_L_FMT: 15677 { 15678 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15679 check_cp1_enabled(ctx); 15680 if (ctx->insn_flags & ISA_MIPS_R6) { 15681 switch (r6_op) { 15682 case R6_OPC_CMP_AF_S: 15683 case R6_OPC_CMP_UN_S: 15684 case R6_OPC_CMP_EQ_S: 15685 case R6_OPC_CMP_UEQ_S: 15686 case R6_OPC_CMP_LT_S: 15687 case R6_OPC_CMP_ULT_S: 15688 case R6_OPC_CMP_LE_S: 15689 case R6_OPC_CMP_ULE_S: 15690 case R6_OPC_CMP_SAF_S: 15691 case R6_OPC_CMP_SUN_S: 15692 case R6_OPC_CMP_SEQ_S: 15693 case R6_OPC_CMP_SEUQ_S: 15694 case R6_OPC_CMP_SLT_S: 15695 case R6_OPC_CMP_SULT_S: 15696 case R6_OPC_CMP_SLE_S: 15697 case R6_OPC_CMP_SULE_S: 15698 case R6_OPC_CMP_OR_S: 15699 case R6_OPC_CMP_UNE_S: 15700 case R6_OPC_CMP_NE_S: 15701 case R6_OPC_CMP_SOR_S: 15702 case R6_OPC_CMP_SUNE_S: 15703 case R6_OPC_CMP_SNE_S: 15704 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15705 break; 15706 case R6_OPC_CMP_AF_D: 15707 case R6_OPC_CMP_UN_D: 15708 case R6_OPC_CMP_EQ_D: 15709 case R6_OPC_CMP_UEQ_D: 15710 case R6_OPC_CMP_LT_D: 15711 case R6_OPC_CMP_ULT_D: 15712 case R6_OPC_CMP_LE_D: 15713 case R6_OPC_CMP_ULE_D: 15714 case R6_OPC_CMP_SAF_D: 15715 case R6_OPC_CMP_SUN_D: 15716 case R6_OPC_CMP_SEQ_D: 15717 case R6_OPC_CMP_SEUQ_D: 15718 case R6_OPC_CMP_SLT_D: 15719 case R6_OPC_CMP_SULT_D: 15720 case R6_OPC_CMP_SLE_D: 15721 case R6_OPC_CMP_SULE_D: 15722 case R6_OPC_CMP_OR_D: 15723 case R6_OPC_CMP_UNE_D: 15724 case R6_OPC_CMP_NE_D: 15725 case R6_OPC_CMP_SOR_D: 15726 case R6_OPC_CMP_SUNE_D: 15727 case R6_OPC_CMP_SNE_D: 15728 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15729 break; 15730 default: 15731 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15732 rt, rd, sa, (imm >> 8) & 0x7); 15733 15734 break; 15735 } 15736 } else { 15737 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15738 (imm >> 8) & 0x7); 15739 } 15740 break; 15741 } 15742 default: 15743 MIPS_INVAL("cp1"); 15744 gen_reserved_instruction(ctx); 15745 break; 15746 } 15747 break; 15748 15749 /* Compact branches [R6] and COP2 [non-R6] */ 15750 case OPC_BC: /* OPC_LWC2 */ 15751 case OPC_BALC: /* OPC_SWC2 */ 15752 if (ctx->insn_flags & ISA_MIPS_R6) { 15753 /* OPC_BC, OPC_BALC */ 15754 gen_compute_compact_branch(ctx, op, 0, 0, 15755 sextract32(ctx->opcode << 2, 0, 28)); 15756 } else if (ctx->insn_flags & ASE_LEXT) { 15757 gen_loongson_lswc2(ctx, rt, rs, rd); 15758 } else { 15759 /* OPC_LWC2, OPC_SWC2 */ 15760 /* COP2: Not implemented. */ 15761 generate_exception_err(ctx, EXCP_CpU, 2); 15762 } 15763 break; 15764 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15765 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15766 if (ctx->insn_flags & ISA_MIPS_R6) { 15767 if (rs != 0) { 15768 /* OPC_BEQZC, OPC_BNEZC */ 15769 gen_compute_compact_branch(ctx, op, rs, 0, 15770 sextract32(ctx->opcode << 2, 0, 23)); 15771 } else { 15772 /* OPC_JIC, OPC_JIALC */ 15773 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15774 } 15775 } else if (ctx->insn_flags & ASE_LEXT) { 15776 gen_loongson_lsdc2(ctx, rt, rs, rd); 15777 } else { 15778 /* OPC_LWC2, OPC_SWC2 */ 15779 /* COP2: Not implemented. */ 15780 generate_exception_err(ctx, EXCP_CpU, 2); 15781 } 15782 break; 15783 case OPC_CP2: 15784 check_insn(ctx, ASE_LMMI); 15785 /* Note that these instructions use different fields. */ 15786 gen_loongson_multimedia(ctx, sa, rd, rt); 15787 break; 15788 15789 case OPC_CP3: 15790 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15791 check_cp1_enabled(ctx); 15792 op1 = MASK_CP3(ctx->opcode); 15793 switch (op1) { 15794 case OPC_LUXC1: 15795 case OPC_SUXC1: 15796 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15797 /* Fallthrough */ 15798 case OPC_LWXC1: 15799 case OPC_LDXC1: 15800 case OPC_SWXC1: 15801 case OPC_SDXC1: 15802 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15803 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15804 break; 15805 case OPC_PREFX: 15806 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15807 /* Treat as NOP. */ 15808 break; 15809 case OPC_ALNV_PS: 15810 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15811 /* Fallthrough */ 15812 case OPC_MADD_S: 15813 case OPC_MADD_D: 15814 case OPC_MADD_PS: 15815 case OPC_MSUB_S: 15816 case OPC_MSUB_D: 15817 case OPC_MSUB_PS: 15818 case OPC_NMADD_S: 15819 case OPC_NMADD_D: 15820 case OPC_NMADD_PS: 15821 case OPC_NMSUB_S: 15822 case OPC_NMSUB_D: 15823 case OPC_NMSUB_PS: 15824 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15825 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15826 break; 15827 default: 15828 MIPS_INVAL("cp3"); 15829 gen_reserved_instruction(ctx); 15830 break; 15831 } 15832 } else { 15833 generate_exception_err(ctx, EXCP_CpU, 1); 15834 } 15835 break; 15836 15837 #if defined(TARGET_MIPS64) 15838 /* MIPS64 opcodes */ 15839 case OPC_LLD: 15840 if (ctx->insn_flags & INSN_R5900) { 15841 check_insn_opc_user_only(ctx, INSN_R5900); 15842 } 15843 /* fall through */ 15844 case OPC_LDL: 15845 case OPC_LDR: 15846 case OPC_LWU: 15847 case OPC_LD: 15848 check_insn(ctx, ISA_MIPS3); 15849 check_mips_64(ctx); 15850 gen_ld(ctx, op, rt, rs, imm); 15851 break; 15852 case OPC_SDL: 15853 case OPC_SDR: 15854 case OPC_SD: 15855 check_insn(ctx, ISA_MIPS3); 15856 check_mips_64(ctx); 15857 gen_st(ctx, op, rt, rs, imm); 15858 break; 15859 case OPC_SCD: 15860 check_insn(ctx, ISA_MIPS3); 15861 if (ctx->insn_flags & INSN_R5900) { 15862 check_insn_opc_user_only(ctx, INSN_R5900); 15863 } 15864 check_mips_64(ctx); 15865 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 15866 break; 15867 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 15868 if (ctx->insn_flags & ISA_MIPS_R6) { 15869 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 15870 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15871 } else { 15872 /* OPC_DADDI */ 15873 check_insn(ctx, ISA_MIPS3); 15874 check_mips_64(ctx); 15875 gen_arith_imm(ctx, op, rt, rs, imm); 15876 } 15877 break; 15878 case OPC_DADDIU: 15879 check_insn(ctx, ISA_MIPS3); 15880 check_mips_64(ctx); 15881 gen_arith_imm(ctx, op, rt, rs, imm); 15882 break; 15883 #else 15884 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 15885 if (ctx->insn_flags & ISA_MIPS_R6) { 15886 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15887 } else { 15888 MIPS_INVAL("major opcode"); 15889 gen_reserved_instruction(ctx); 15890 } 15891 break; 15892 #endif 15893 case OPC_DAUI: /* OPC_JALX */ 15894 if (ctx->insn_flags & ISA_MIPS_R6) { 15895 #if defined(TARGET_MIPS64) 15896 /* OPC_DAUI */ 15897 check_mips_64(ctx); 15898 if (rs == 0) { 15899 generate_exception(ctx, EXCP_RI); 15900 } else if (rt != 0) { 15901 TCGv t0 = tcg_temp_new(); 15902 gen_load_gpr(t0, rs); 15903 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 15904 tcg_temp_free(t0); 15905 } 15906 #else 15907 gen_reserved_instruction(ctx); 15908 MIPS_INVAL("major opcode"); 15909 #endif 15910 } else { 15911 /* OPC_JALX */ 15912 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 15913 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15914 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15915 } 15916 break; 15917 case OPC_MDMX: 15918 /* MDMX: Not implemented. */ 15919 break; 15920 case OPC_PCREL: 15921 check_insn(ctx, ISA_MIPS_R6); 15922 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15923 break; 15924 default: /* Invalid */ 15925 MIPS_INVAL("major opcode"); 15926 return false; 15927 } 15928 return true; 15929 } 15930 15931 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15932 { 15933 /* make sure instructions are on a word boundary */ 15934 if (ctx->base.pc_next & 0x3) { 15935 env->CP0_BadVAddr = ctx->base.pc_next; 15936 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15937 return; 15938 } 15939 15940 /* Handle blikely not taken case */ 15941 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15942 TCGLabel *l1 = gen_new_label(); 15943 15944 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15945 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15946 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15947 gen_set_label(l1); 15948 } 15949 15950 /* Transition to the auto-generated decoder. */ 15951 15952 /* Vendor specific extensions */ 15953 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15954 return; 15955 } 15956 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15957 return; 15958 } 15959 #if defined(TARGET_MIPS64) 15960 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15961 return; 15962 } 15963 #endif 15964 15965 /* ISA extensions */ 15966 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15967 return; 15968 } 15969 15970 /* ISA (from latest to oldest) */ 15971 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15972 return; 15973 } 15974 15975 if (decode_opc_legacy(env, ctx)) { 15976 return; 15977 } 15978 15979 gen_reserved_instruction(ctx); 15980 } 15981 15982 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15983 { 15984 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15985 CPUMIPSState *env = cs->env_ptr; 15986 15987 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15988 ctx->saved_pc = -1; 15989 ctx->insn_flags = env->insn_flags; 15990 ctx->CP0_Config0 = env->CP0_Config0; 15991 ctx->CP0_Config1 = env->CP0_Config1; 15992 ctx->CP0_Config2 = env->CP0_Config2; 15993 ctx->CP0_Config3 = env->CP0_Config3; 15994 ctx->CP0_Config5 = env->CP0_Config5; 15995 ctx->btarget = 0; 15996 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15997 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15998 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15999 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 16000 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 16001 ctx->PAMask = env->PAMask; 16002 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 16003 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 16004 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 16005 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 16006 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 16007 /* Restore delay slot state from the tb context. */ 16008 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 16009 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 16010 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 16011 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 16012 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 16013 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 16014 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 16015 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 16016 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 16017 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 16018 restore_cpu_state(env, ctx); 16019 #ifdef CONFIG_USER_ONLY 16020 ctx->mem_idx = MIPS_HFLAG_UM; 16021 #else 16022 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 16023 #endif 16024 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 16025 (ctx->insn_flags & (ISA_MIPS_R6 | 16026 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 16027 16028 /* 16029 * Execute a branch and its delay slot as a single instruction. 16030 * This is what GDB expects and is consistent with what the 16031 * hardware does (e.g. if a delay slot instruction faults, the 16032 * reported PC is the PC of the branch). 16033 */ 16034 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) { 16035 ctx->base.max_insns = 2; 16036 } 16037 16038 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 16039 ctx->hflags); 16040 } 16041 16042 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 16043 { 16044 } 16045 16046 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 16047 { 16048 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16049 16050 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 16051 ctx->btarget); 16052 } 16053 16054 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 16055 { 16056 CPUMIPSState *env = cs->env_ptr; 16057 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16058 int insn_bytes; 16059 int is_slot; 16060 16061 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 16062 if (ctx->insn_flags & ISA_NANOMIPS32) { 16063 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16064 insn_bytes = decode_isa_nanomips(env, ctx); 16065 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 16066 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 16067 insn_bytes = 4; 16068 decode_opc(env, ctx); 16069 } else if (ctx->insn_flags & ASE_MICROMIPS) { 16070 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16071 insn_bytes = decode_isa_micromips(env, ctx); 16072 } else if (ctx->insn_flags & ASE_MIPS16) { 16073 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16074 insn_bytes = decode_ase_mips16e(env, ctx); 16075 } else { 16076 gen_reserved_instruction(ctx); 16077 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 16078 return; 16079 } 16080 16081 if (ctx->hflags & MIPS_HFLAG_BMASK) { 16082 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 16083 MIPS_HFLAG_FBNSLOT))) { 16084 /* 16085 * Force to generate branch as there is neither delay nor 16086 * forbidden slot. 16087 */ 16088 is_slot = 1; 16089 } 16090 if ((ctx->hflags & MIPS_HFLAG_M16) && 16091 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 16092 /* 16093 * Force to generate branch as microMIPS R6 doesn't restrict 16094 * branches in the forbidden slot. 16095 */ 16096 is_slot = 1; 16097 } 16098 } 16099 if (is_slot) { 16100 gen_branch(ctx, insn_bytes); 16101 } 16102 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 16103 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 16104 } 16105 ctx->base.pc_next += insn_bytes; 16106 16107 if (ctx->base.is_jmp != DISAS_NEXT) { 16108 return; 16109 } 16110 16111 /* 16112 * End the TB on (most) page crossings. 16113 * See mips_tr_init_disas_context about single-stepping a branch 16114 * together with its delay slot. 16115 */ 16116 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 16117 && !ctx->base.singlestep_enabled) { 16118 ctx->base.is_jmp = DISAS_TOO_MANY; 16119 } 16120 } 16121 16122 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 16123 { 16124 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16125 16126 switch (ctx->base.is_jmp) { 16127 case DISAS_STOP: 16128 gen_save_pc(ctx->base.pc_next); 16129 tcg_gen_lookup_and_goto_ptr(); 16130 break; 16131 case DISAS_NEXT: 16132 case DISAS_TOO_MANY: 16133 save_cpu_state(ctx, 0); 16134 gen_goto_tb(ctx, 0, ctx->base.pc_next); 16135 break; 16136 case DISAS_EXIT: 16137 tcg_gen_exit_tb(NULL, 0); 16138 break; 16139 case DISAS_NORETURN: 16140 break; 16141 default: 16142 g_assert_not_reached(); 16143 } 16144 } 16145 16146 static void mips_tr_disas_log(const DisasContextBase *dcbase, 16147 CPUState *cs, FILE *logfile) 16148 { 16149 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first)); 16150 target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size); 16151 } 16152 16153 static const TranslatorOps mips_tr_ops = { 16154 .init_disas_context = mips_tr_init_disas_context, 16155 .tb_start = mips_tr_tb_start, 16156 .insn_start = mips_tr_insn_start, 16157 .translate_insn = mips_tr_translate_insn, 16158 .tb_stop = mips_tr_tb_stop, 16159 .disas_log = mips_tr_disas_log, 16160 }; 16161 16162 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, 16163 target_ulong pc, void *host_pc) 16164 { 16165 DisasContext ctx; 16166 16167 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 16168 } 16169 16170 void mips_tcg_init(void) 16171 { 16172 int i; 16173 16174 cpu_gpr[0] = NULL; 16175 for (i = 1; i < 32; i++) 16176 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 16177 offsetof(CPUMIPSState, 16178 active_tc.gpr[i]), 16179 regnames[i]); 16180 #if defined(TARGET_MIPS64) 16181 cpu_gpr_hi[0] = NULL; 16182 16183 for (unsigned i = 1; i < 32; i++) { 16184 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 16185 16186 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 16187 offsetof(CPUMIPSState, 16188 active_tc.gpr_hi[i]), 16189 rname); 16190 } 16191 #endif /* !TARGET_MIPS64 */ 16192 for (i = 0; i < 32; i++) { 16193 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 16194 16195 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 16196 } 16197 msa_translate_init(); 16198 cpu_PC = tcg_global_mem_new(cpu_env, 16199 offsetof(CPUMIPSState, active_tc.PC), "PC"); 16200 for (i = 0; i < MIPS_DSP_ACC; i++) { 16201 cpu_HI[i] = tcg_global_mem_new(cpu_env, 16202 offsetof(CPUMIPSState, active_tc.HI[i]), 16203 regnames_HI[i]); 16204 cpu_LO[i] = tcg_global_mem_new(cpu_env, 16205 offsetof(CPUMIPSState, active_tc.LO[i]), 16206 regnames_LO[i]); 16207 } 16208 cpu_dspctrl = tcg_global_mem_new(cpu_env, 16209 offsetof(CPUMIPSState, 16210 active_tc.DSPControl), 16211 "DSPControl"); 16212 bcond = tcg_global_mem_new(cpu_env, 16213 offsetof(CPUMIPSState, bcond), "bcond"); 16214 btarget = tcg_global_mem_new(cpu_env, 16215 offsetof(CPUMIPSState, btarget), "btarget"); 16216 hflags = tcg_global_mem_new_i32(cpu_env, 16217 offsetof(CPUMIPSState, hflags), "hflags"); 16218 16219 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 16220 offsetof(CPUMIPSState, active_fpu.fcr0), 16221 "fcr0"); 16222 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 16223 offsetof(CPUMIPSState, active_fpu.fcr31), 16224 "fcr31"); 16225 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 16226 "lladdr"); 16227 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 16228 "llval"); 16229 16230 if (TARGET_LONG_BITS == 32) { 16231 mxu_translate_init(); 16232 } 16233 } 16234 16235 void mips_restore_state_to_opc(CPUState *cs, 16236 const TranslationBlock *tb, 16237 const uint64_t *data) 16238 { 16239 MIPSCPU *cpu = MIPS_CPU(cs); 16240 CPUMIPSState *env = &cpu->env; 16241 16242 env->active_tc.PC = data[0]; 16243 env->hflags &= ~MIPS_HFLAG_BMASK; 16244 env->hflags |= data[1]; 16245 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 16246 case MIPS_HFLAG_BR: 16247 break; 16248 case MIPS_HFLAG_BC: 16249 case MIPS_HFLAG_BL: 16250 case MIPS_HFLAG_B: 16251 env->btarget = data[2]; 16252 break; 16253 } 16254 } 16255