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