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