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