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/translator.h" 36 #include "exec/log.h" 37 #include "qemu/qemu-print.h" 38 #include "fpu_helper.h" 39 #include "translate.h" 40 41 /* 42 * Many sysemu-only helpers are not reachable for user-only. 43 * Define stub generators here, so that we need not either sprinkle 44 * ifdefs through the translator, nor provide the helper function. 45 */ 46 #define STUB_HELPER(NAME, ...) \ 47 static inline void gen_helper_##NAME(__VA_ARGS__) \ 48 { g_assert_not_reached(); } 49 50 #ifdef CONFIG_USER_ONLY 51 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 52 #endif 53 54 enum { 55 /* indirect opcode tables */ 56 OPC_SPECIAL = (0x00 << 26), 57 OPC_REGIMM = (0x01 << 26), 58 OPC_CP0 = (0x10 << 26), 59 OPC_CP2 = (0x12 << 26), 60 OPC_CP3 = (0x13 << 26), 61 OPC_SPECIAL2 = (0x1C << 26), 62 OPC_SPECIAL3 = (0x1F << 26), 63 /* arithmetic with immediate */ 64 OPC_ADDI = (0x08 << 26), 65 OPC_ADDIU = (0x09 << 26), 66 OPC_SLTI = (0x0A << 26), 67 OPC_SLTIU = (0x0B << 26), 68 /* logic with immediate */ 69 OPC_ANDI = (0x0C << 26), 70 OPC_ORI = (0x0D << 26), 71 OPC_XORI = (0x0E << 26), 72 OPC_LUI = (0x0F << 26), 73 /* arithmetic with immediate */ 74 OPC_DADDI = (0x18 << 26), 75 OPC_DADDIU = (0x19 << 26), 76 /* Jump and branches */ 77 OPC_J = (0x02 << 26), 78 OPC_JAL = (0x03 << 26), 79 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 80 OPC_BEQL = (0x14 << 26), 81 OPC_BNE = (0x05 << 26), 82 OPC_BNEL = (0x15 << 26), 83 OPC_BLEZ = (0x06 << 26), 84 OPC_BLEZL = (0x16 << 26), 85 OPC_BGTZ = (0x07 << 26), 86 OPC_BGTZL = (0x17 << 26), 87 OPC_JALX = (0x1D << 26), 88 OPC_DAUI = (0x1D << 26), 89 /* Load and stores */ 90 OPC_LDL = (0x1A << 26), 91 OPC_LDR = (0x1B << 26), 92 OPC_LB = (0x20 << 26), 93 OPC_LH = (0x21 << 26), 94 OPC_LWL = (0x22 << 26), 95 OPC_LW = (0x23 << 26), 96 OPC_LWPC = OPC_LW | 0x5, 97 OPC_LBU = (0x24 << 26), 98 OPC_LHU = (0x25 << 26), 99 OPC_LWR = (0x26 << 26), 100 OPC_LWU = (0x27 << 26), 101 OPC_SB = (0x28 << 26), 102 OPC_SH = (0x29 << 26), 103 OPC_SWL = (0x2A << 26), 104 OPC_SW = (0x2B << 26), 105 OPC_SDL = (0x2C << 26), 106 OPC_SDR = (0x2D << 26), 107 OPC_SWR = (0x2E << 26), 108 OPC_LL = (0x30 << 26), 109 OPC_LLD = (0x34 << 26), 110 OPC_LD = (0x37 << 26), 111 OPC_LDPC = OPC_LD | 0x5, 112 OPC_SC = (0x38 << 26), 113 OPC_SCD = (0x3C << 26), 114 OPC_SD = (0x3F << 26), 115 /* Floating point load/store */ 116 OPC_LWC1 = (0x31 << 26), 117 OPC_LWC2 = (0x32 << 26), 118 OPC_LDC1 = (0x35 << 26), 119 OPC_LDC2 = (0x36 << 26), 120 OPC_SWC1 = (0x39 << 26), 121 OPC_SWC2 = (0x3A << 26), 122 OPC_SDC1 = (0x3D << 26), 123 OPC_SDC2 = (0x3E << 26), 124 /* Compact Branches */ 125 OPC_BLEZALC = (0x06 << 26), 126 OPC_BGEZALC = (0x06 << 26), 127 OPC_BGEUC = (0x06 << 26), 128 OPC_BGTZALC = (0x07 << 26), 129 OPC_BLTZALC = (0x07 << 26), 130 OPC_BLTUC = (0x07 << 26), 131 OPC_BOVC = (0x08 << 26), 132 OPC_BEQZALC = (0x08 << 26), 133 OPC_BEQC = (0x08 << 26), 134 OPC_BLEZC = (0x16 << 26), 135 OPC_BGEZC = (0x16 << 26), 136 OPC_BGEC = (0x16 << 26), 137 OPC_BGTZC = (0x17 << 26), 138 OPC_BLTZC = (0x17 << 26), 139 OPC_BLTC = (0x17 << 26), 140 OPC_BNVC = (0x18 << 26), 141 OPC_BNEZALC = (0x18 << 26), 142 OPC_BNEC = (0x18 << 26), 143 OPC_BC = (0x32 << 26), 144 OPC_BEQZC = (0x36 << 26), 145 OPC_JIC = (0x36 << 26), 146 OPC_BALC = (0x3A << 26), 147 OPC_BNEZC = (0x3E << 26), 148 OPC_JIALC = (0x3E << 26), 149 /* MDMX ASE specific */ 150 OPC_MDMX = (0x1E << 26), 151 /* Cache and prefetch */ 152 OPC_CACHE = (0x2F << 26), 153 OPC_PREF = (0x33 << 26), 154 /* PC-relative address computation / loads */ 155 OPC_PCREL = (0x3B << 26), 156 }; 157 158 /* PC-relative address computation / loads */ 159 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 160 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 161 enum { 162 /* Instructions determined by bits 19 and 20 */ 163 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 164 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 165 OPC_LWUPC = OPC_PCREL | (2 << 19), 166 167 /* Instructions determined by bits 16 ... 20 */ 168 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 170 171 /* Other */ 172 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 173 }; 174 175 /* MIPS special opcodes */ 176 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 177 178 enum { 179 /* Shifts */ 180 OPC_SLL = 0x00 | OPC_SPECIAL, 181 /* NOP is SLL r0, r0, 0 */ 182 /* SSNOP is SLL r0, r0, 1 */ 183 /* EHB is SLL r0, r0, 3 */ 184 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 185 OPC_ROTR = OPC_SRL | (1 << 21), 186 OPC_SRA = 0x03 | OPC_SPECIAL, 187 OPC_SLLV = 0x04 | OPC_SPECIAL, 188 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 189 OPC_ROTRV = OPC_SRLV | (1 << 6), 190 OPC_SRAV = 0x07 | OPC_SPECIAL, 191 OPC_DSLLV = 0x14 | OPC_SPECIAL, 192 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 193 OPC_DROTRV = OPC_DSRLV | (1 << 6), 194 OPC_DSRAV = 0x17 | OPC_SPECIAL, 195 OPC_DSLL = 0x38 | OPC_SPECIAL, 196 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 197 OPC_DROTR = OPC_DSRL | (1 << 21), 198 OPC_DSRA = 0x3B | OPC_SPECIAL, 199 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 200 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 202 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 203 /* Multiplication / division */ 204 OPC_MULT = 0x18 | OPC_SPECIAL, 205 OPC_MULTU = 0x19 | OPC_SPECIAL, 206 OPC_DIV = 0x1A | OPC_SPECIAL, 207 OPC_DIVU = 0x1B | OPC_SPECIAL, 208 OPC_DMULT = 0x1C | OPC_SPECIAL, 209 OPC_DMULTU = 0x1D | OPC_SPECIAL, 210 OPC_DDIV = 0x1E | OPC_SPECIAL, 211 OPC_DDIVU = 0x1F | OPC_SPECIAL, 212 213 /* 2 registers arithmetic / logic */ 214 OPC_ADD = 0x20 | OPC_SPECIAL, 215 OPC_ADDU = 0x21 | OPC_SPECIAL, 216 OPC_SUB = 0x22 | OPC_SPECIAL, 217 OPC_SUBU = 0x23 | OPC_SPECIAL, 218 OPC_AND = 0x24 | OPC_SPECIAL, 219 OPC_OR = 0x25 | OPC_SPECIAL, 220 OPC_XOR = 0x26 | OPC_SPECIAL, 221 OPC_NOR = 0x27 | OPC_SPECIAL, 222 OPC_SLT = 0x2A | OPC_SPECIAL, 223 OPC_SLTU = 0x2B | OPC_SPECIAL, 224 OPC_DADD = 0x2C | OPC_SPECIAL, 225 OPC_DADDU = 0x2D | OPC_SPECIAL, 226 OPC_DSUB = 0x2E | OPC_SPECIAL, 227 OPC_DSUBU = 0x2F | OPC_SPECIAL, 228 /* Jumps */ 229 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 230 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 231 /* Traps */ 232 OPC_TGE = 0x30 | OPC_SPECIAL, 233 OPC_TGEU = 0x31 | OPC_SPECIAL, 234 OPC_TLT = 0x32 | OPC_SPECIAL, 235 OPC_TLTU = 0x33 | OPC_SPECIAL, 236 OPC_TEQ = 0x34 | OPC_SPECIAL, 237 OPC_TNE = 0x36 | OPC_SPECIAL, 238 /* HI / LO registers load & stores */ 239 OPC_MFHI = 0x10 | OPC_SPECIAL, 240 OPC_MTHI = 0x11 | OPC_SPECIAL, 241 OPC_MFLO = 0x12 | OPC_SPECIAL, 242 OPC_MTLO = 0x13 | OPC_SPECIAL, 243 /* Conditional moves */ 244 OPC_MOVZ = 0x0A | OPC_SPECIAL, 245 OPC_MOVN = 0x0B | OPC_SPECIAL, 246 247 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 248 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 249 250 OPC_MOVCI = 0x01 | OPC_SPECIAL, 251 252 /* Special */ 253 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 254 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 255 OPC_BREAK = 0x0D | OPC_SPECIAL, 256 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 257 OPC_SYNC = 0x0F | OPC_SPECIAL, 258 259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 263 }; 264 265 /* 266 * R6 Multiply and Divide instructions have the same opcode 267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 268 */ 269 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 270 271 enum { 272 R6_OPC_MUL = OPC_MULT | (2 << 6), 273 R6_OPC_MUH = OPC_MULT | (3 << 6), 274 R6_OPC_MULU = OPC_MULTU | (2 << 6), 275 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 276 R6_OPC_DIV = OPC_DIV | (2 << 6), 277 R6_OPC_MOD = OPC_DIV | (3 << 6), 278 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 279 R6_OPC_MODU = OPC_DIVU | (3 << 6), 280 281 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 282 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 285 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 286 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 289 290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 291 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 295 }; 296 297 /* REGIMM (rt field) opcodes */ 298 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 299 300 enum { 301 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 302 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 303 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 304 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 305 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 306 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 307 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 308 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 309 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 310 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 311 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 312 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 313 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 314 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 315 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 316 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 317 318 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 319 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 320 }; 321 322 /* Special2 opcodes */ 323 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 324 325 enum { 326 /* Multiply & xxx operations */ 327 OPC_MADD = 0x00 | OPC_SPECIAL2, 328 OPC_MADDU = 0x01 | OPC_SPECIAL2, 329 OPC_MUL = 0x02 | OPC_SPECIAL2, 330 OPC_MSUB = 0x04 | OPC_SPECIAL2, 331 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 332 /* Loongson 2F */ 333 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 334 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 335 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 336 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 337 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 338 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 339 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 340 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 341 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 342 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 343 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 344 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 345 /* Misc */ 346 OPC_CLZ = 0x20 | OPC_SPECIAL2, 347 OPC_CLO = 0x21 | OPC_SPECIAL2, 348 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 349 OPC_DCLO = 0x25 | OPC_SPECIAL2, 350 /* Special */ 351 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 352 }; 353 354 /* Special3 opcodes */ 355 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 356 357 enum { 358 OPC_EXT = 0x00 | OPC_SPECIAL3, 359 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 360 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 361 OPC_DEXT = 0x03 | OPC_SPECIAL3, 362 OPC_INS = 0x04 | OPC_SPECIAL3, 363 OPC_DINSM = 0x05 | OPC_SPECIAL3, 364 OPC_DINSU = 0x06 | OPC_SPECIAL3, 365 OPC_DINS = 0x07 | OPC_SPECIAL3, 366 OPC_FORK = 0x08 | OPC_SPECIAL3, 367 OPC_YIELD = 0x09 | OPC_SPECIAL3, 368 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 369 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 370 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 371 OPC_GINV = 0x3D | OPC_SPECIAL3, 372 373 /* Loongson 2E */ 374 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 375 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 376 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 377 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 378 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 379 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 380 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 381 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 382 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 383 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 384 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 385 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 386 387 /* MIPS DSP Load */ 388 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 389 /* MIPS DSP Arithmetic */ 390 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 391 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 392 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 393 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 394 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 395 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 396 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 397 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 398 /* MIPS DSP GPR-Based Shift Sub-class */ 399 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 400 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 401 /* MIPS DSP Multiply Sub-class insns */ 402 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 403 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 404 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 405 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 406 /* DSP Bit/Manipulation Sub-class */ 407 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 408 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 409 /* MIPS DSP Append Sub-class */ 410 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 411 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 412 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 413 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 414 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 415 416 /* EVA */ 417 OPC_LWLE = 0x19 | OPC_SPECIAL3, 418 OPC_LWRE = 0x1A | OPC_SPECIAL3, 419 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 420 OPC_SBE = 0x1C | OPC_SPECIAL3, 421 OPC_SHE = 0x1D | OPC_SPECIAL3, 422 OPC_SCE = 0x1E | OPC_SPECIAL3, 423 OPC_SWE = 0x1F | OPC_SPECIAL3, 424 OPC_SWLE = 0x21 | OPC_SPECIAL3, 425 OPC_SWRE = 0x22 | OPC_SPECIAL3, 426 OPC_PREFE = 0x23 | OPC_SPECIAL3, 427 OPC_LBUE = 0x28 | OPC_SPECIAL3, 428 OPC_LHUE = 0x29 | OPC_SPECIAL3, 429 OPC_LBE = 0x2C | OPC_SPECIAL3, 430 OPC_LHE = 0x2D | OPC_SPECIAL3, 431 OPC_LLE = 0x2E | OPC_SPECIAL3, 432 OPC_LWE = 0x2F | OPC_SPECIAL3, 433 434 /* R6 */ 435 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 436 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 437 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 438 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 439 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 440 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 441 }; 442 443 /* Loongson EXT load/store quad word opcodes */ 444 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 445 enum { 446 OPC_GSLQ = 0x0020 | OPC_LWC2, 447 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 448 OPC_GSSHFL = OPC_LWC2, 449 OPC_GSSQ = 0x0020 | OPC_SWC2, 450 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 451 OPC_GSSHFS = OPC_SWC2, 452 }; 453 454 /* Loongson EXT shifted load/store opcodes */ 455 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 456 enum { 457 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 458 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 459 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 460 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 461 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 462 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 463 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 464 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 465 }; 466 467 /* Loongson EXT LDC2/SDC2 opcodes */ 468 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 469 470 enum { 471 OPC_GSLBX = 0x0 | OPC_LDC2, 472 OPC_GSLHX = 0x1 | OPC_LDC2, 473 OPC_GSLWX = 0x2 | OPC_LDC2, 474 OPC_GSLDX = 0x3 | OPC_LDC2, 475 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 476 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 477 OPC_GSSBX = 0x0 | OPC_SDC2, 478 OPC_GSSHX = 0x1 | OPC_SDC2, 479 OPC_GSSWX = 0x2 | OPC_SDC2, 480 OPC_GSSDX = 0x3 | OPC_SDC2, 481 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 482 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 483 }; 484 485 /* BSHFL opcodes */ 486 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 487 488 enum { 489 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 490 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 491 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 492 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 493 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 494 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 495 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 496 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 497 }; 498 499 /* DBSHFL opcodes */ 500 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 501 502 enum { 503 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 504 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 505 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 506 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 507 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 508 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 509 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 510 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 511 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 512 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 513 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 514 }; 515 516 /* MIPS DSP REGIMM opcodes */ 517 enum { 518 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 519 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 520 }; 521 522 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 523 /* MIPS DSP Load */ 524 enum { 525 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 526 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 527 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 528 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 529 }; 530 531 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 532 enum { 533 /* MIPS DSP Arithmetic Sub-class */ 534 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 535 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 536 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 537 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 538 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 539 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 540 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 541 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 542 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 543 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 544 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 545 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 546 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 547 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 548 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 549 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 550 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 551 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 552 /* MIPS DSP Multiply Sub-class insns */ 553 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 554 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 555 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 556 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 557 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 558 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 559 }; 560 561 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 562 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 563 enum { 564 /* MIPS DSP Arithmetic Sub-class */ 565 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 566 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 567 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 568 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 569 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 570 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 571 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 572 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 573 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 574 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 575 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 576 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 577 /* MIPS DSP Multiply Sub-class insns */ 578 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 579 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 580 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 581 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 582 }; 583 584 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 585 enum { 586 /* MIPS DSP Arithmetic Sub-class */ 587 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 588 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 589 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 590 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 591 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 592 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 593 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 594 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 595 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 596 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 597 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 598 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 599 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 600 /* DSP Bit/Manipulation Sub-class */ 601 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 602 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 603 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 604 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 605 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 606 }; 607 608 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 609 enum { 610 /* MIPS DSP Arithmetic Sub-class */ 611 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 612 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 613 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 614 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 615 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 616 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 617 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 618 /* DSP Compare-Pick Sub-class */ 619 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 620 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 621 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 622 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 623 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 624 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 625 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 626 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 627 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 628 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 629 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 630 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 631 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 632 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 633 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 634 }; 635 636 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 637 enum { 638 /* MIPS DSP GPR-Based Shift Sub-class */ 639 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 640 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 641 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 642 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 643 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 644 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 645 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 646 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 647 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 648 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 649 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 650 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 651 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 652 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 653 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 654 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 655 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 656 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 657 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 658 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 659 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 660 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 661 }; 662 663 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 664 enum { 665 /* MIPS DSP Multiply Sub-class insns */ 666 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 667 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 668 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 669 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 670 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 671 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 672 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 673 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 674 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 675 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 676 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 677 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 678 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 679 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 680 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 681 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 682 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 683 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 684 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 685 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 686 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 687 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 688 }; 689 690 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 691 enum { 692 /* DSP Bit/Manipulation Sub-class */ 693 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 694 }; 695 696 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 697 enum { 698 /* MIPS DSP Append Sub-class */ 699 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 700 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 701 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 702 }; 703 704 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 705 enum { 706 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 707 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 708 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 709 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 710 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 711 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 712 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 713 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 714 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 715 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 716 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 717 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 718 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 719 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 720 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 721 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 722 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 723 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 724 }; 725 726 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 727 enum { 728 /* MIPS DSP Arithmetic Sub-class */ 729 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 730 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 731 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 732 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 733 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 734 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 735 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 736 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 737 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 738 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 739 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 740 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 741 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 742 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 743 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 744 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 745 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 746 /* DSP Bit/Manipulation Sub-class */ 747 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 748 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 749 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 750 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 752 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 753 }; 754 755 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 756 enum { 757 /* MIPS DSP Multiply Sub-class insns */ 758 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 759 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 760 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 761 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 762 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 763 /* MIPS DSP Arithmetic Sub-class */ 764 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 765 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 766 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 767 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 768 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 769 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 770 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 771 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 772 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 773 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 774 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 775 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 776 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 777 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 778 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 779 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 780 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 781 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 782 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 783 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 784 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 785 }; 786 787 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 788 enum { 789 /* DSP Compare-Pick Sub-class */ 790 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 791 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 792 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 793 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 794 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 795 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 796 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 797 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 798 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 799 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 800 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 801 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 802 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 803 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 804 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 805 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 806 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 807 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 808 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 809 /* MIPS DSP Arithmetic Sub-class */ 810 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 811 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 817 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 818 }; 819 820 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 821 enum { 822 /* DSP Append Sub-class */ 823 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 824 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 825 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 826 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 827 }; 828 829 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 830 enum { 831 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 832 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 833 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 834 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 835 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 836 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 837 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 838 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 839 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 840 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 841 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 842 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 843 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 844 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 845 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 846 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 847 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 848 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 849 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 850 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 851 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 852 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 853 }; 854 855 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 856 enum { 857 /* DSP Bit/Manipulation Sub-class */ 858 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 859 }; 860 861 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 862 enum { 863 /* MIPS DSP Multiply Sub-class insns */ 864 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 865 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 866 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 867 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 868 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 869 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 870 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 871 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 872 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 873 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 874 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 875 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 876 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 877 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 878 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 879 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 880 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 881 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 882 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 883 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 884 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 885 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 889 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 890 }; 891 892 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 893 enum { 894 /* MIPS DSP GPR-Based Shift Sub-class */ 895 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 896 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 897 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 898 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 899 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 900 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 901 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 902 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 903 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 904 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 905 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 906 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 907 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 908 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 909 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 910 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 911 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 912 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 913 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 914 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 915 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 916 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 920 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 921 }; 922 923 /* Coprocessor 0 (rs field) */ 924 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 925 926 enum { 927 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 928 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 929 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 930 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 931 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 932 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 933 OPC_MFTR = (0x08 << 21) | OPC_CP0, 934 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 935 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 936 OPC_MTTR = (0x0C << 21) | OPC_CP0, 937 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 938 OPC_C0 = (0x10 << 21) | OPC_CP0, 939 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 940 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 941 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 942 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 943 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 944 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 945 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 946 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 947 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 948 OPC_C0_A = (0x1A << 21) | OPC_CP0, 949 OPC_C0_B = (0x1B << 21) | OPC_CP0, 950 OPC_C0_C = (0x1C << 21) | OPC_CP0, 951 OPC_C0_D = (0x1D << 21) | OPC_CP0, 952 OPC_C0_E = (0x1E << 21) | OPC_CP0, 953 OPC_C0_F = (0x1F << 21) | OPC_CP0, 954 }; 955 956 /* MFMC0 opcodes */ 957 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 958 959 enum { 960 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 961 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 962 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 963 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 964 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 965 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 966 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 967 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 968 }; 969 970 /* Coprocessor 0 (with rs == C0) */ 971 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 972 973 enum { 974 OPC_TLBR = 0x01 | OPC_C0, 975 OPC_TLBWI = 0x02 | OPC_C0, 976 OPC_TLBINV = 0x03 | OPC_C0, 977 OPC_TLBINVF = 0x04 | OPC_C0, 978 OPC_TLBWR = 0x06 | OPC_C0, 979 OPC_TLBP = 0x08 | OPC_C0, 980 OPC_RFE = 0x10 | OPC_C0, 981 OPC_ERET = 0x18 | OPC_C0, 982 OPC_DERET = 0x1F | OPC_C0, 983 OPC_WAIT = 0x20 | OPC_C0, 984 }; 985 986 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 987 988 enum { 989 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 991 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 993 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 995 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 997 OPC_BC2 = (0x08 << 21) | OPC_CP2, 998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 1000 }; 1001 1002 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1003 1004 enum { 1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1013 1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1022 1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1031 1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1040 1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1047 1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1054 1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1061 1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1068 1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1075 1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1082 1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1089 1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1096 }; 1097 1098 1099 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1100 1101 enum { 1102 OPC_LWXC1 = 0x00 | OPC_CP3, 1103 OPC_LDXC1 = 0x01 | OPC_CP3, 1104 OPC_LUXC1 = 0x05 | OPC_CP3, 1105 OPC_SWXC1 = 0x08 | OPC_CP3, 1106 OPC_SDXC1 = 0x09 | OPC_CP3, 1107 OPC_SUXC1 = 0x0D | OPC_CP3, 1108 OPC_PREFX = 0x0F | OPC_CP3, 1109 OPC_ALNV_PS = 0x1E | OPC_CP3, 1110 OPC_MADD_S = 0x20 | OPC_CP3, 1111 OPC_MADD_D = 0x21 | OPC_CP3, 1112 OPC_MADD_PS = 0x26 | OPC_CP3, 1113 OPC_MSUB_S = 0x28 | OPC_CP3, 1114 OPC_MSUB_D = 0x29 | OPC_CP3, 1115 OPC_MSUB_PS = 0x2E | OPC_CP3, 1116 OPC_NMADD_S = 0x30 | OPC_CP3, 1117 OPC_NMADD_D = 0x31 | OPC_CP3, 1118 OPC_NMADD_PS = 0x36 | OPC_CP3, 1119 OPC_NMSUB_S = 0x38 | OPC_CP3, 1120 OPC_NMSUB_D = 0x39 | OPC_CP3, 1121 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1122 }; 1123 1124 /* 1125 * MMI (MultiMedia Instruction) encodings 1126 * ====================================== 1127 * 1128 * MMI instructions encoding table keys: 1129 * 1130 * * This code is reserved for future use. An attempt to execute it 1131 * causes a Reserved Instruction exception. 1132 * % This code indicates an instruction class. The instruction word 1133 * must be further decoded by examining additional tables that show 1134 * the values for other instruction fields. 1135 * # This code is reserved for the unsupported instructions DMULT, 1136 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1137 * to execute it causes a Reserved Instruction exception. 1138 * 1139 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1140 * 1141 * 31 26 0 1142 * +--------+----------------------------------------+ 1143 * | opcode | | 1144 * +--------+----------------------------------------+ 1145 * 1146 * opcode bits 28..26 1147 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1148 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1149 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1150 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1151 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1152 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1153 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1154 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1155 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1156 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1157 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1158 */ 1159 1160 enum { 1161 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1162 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1163 }; 1164 1165 /* 1166 * MMI instructions with opcode field = MMI: 1167 * 1168 * 31 26 5 0 1169 * +--------+-------------------------------+--------+ 1170 * | MMI | |function| 1171 * +--------+-------------------------------+--------+ 1172 * 1173 * function bits 2..0 1174 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1175 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1176 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1177 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1178 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1179 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1180 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1181 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1182 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1183 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1184 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1185 */ 1186 1187 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1188 enum { 1189 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1190 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1191 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1192 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1193 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1194 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1195 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1196 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1197 }; 1198 1199 /* global register indices */ 1200 TCGv cpu_gpr[32], cpu_PC; 1201 /* 1202 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1203 * and the upper halves in cpu_gpr_hi[]. 1204 */ 1205 TCGv_i64 cpu_gpr_hi[32]; 1206 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1207 static TCGv cpu_dspctrl, btarget; 1208 TCGv bcond; 1209 static TCGv cpu_lladdr, cpu_llval; 1210 static TCGv_i32 hflags; 1211 TCGv_i32 fpu_fcr0, fpu_fcr31; 1212 TCGv_i64 fpu_f64[32]; 1213 1214 #include "exec/gen-icount.h" 1215 1216 static const char regnames_HI[][4] = { 1217 "HI0", "HI1", "HI2", "HI3", 1218 }; 1219 1220 static const char regnames_LO[][4] = { 1221 "LO0", "LO1", "LO2", "LO3", 1222 }; 1223 1224 /* General purpose registers moves. */ 1225 void gen_load_gpr(TCGv t, int reg) 1226 { 1227 if (reg == 0) { 1228 tcg_gen_movi_tl(t, 0); 1229 } else { 1230 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1231 } 1232 } 1233 1234 void gen_store_gpr(TCGv t, int reg) 1235 { 1236 if (reg != 0) { 1237 tcg_gen_mov_tl(cpu_gpr[reg], t); 1238 } 1239 } 1240 1241 #if defined(TARGET_MIPS64) 1242 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1243 { 1244 if (reg == 0) { 1245 tcg_gen_movi_i64(t, 0); 1246 } else { 1247 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1248 } 1249 } 1250 1251 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1252 { 1253 if (reg != 0) { 1254 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1255 } 1256 } 1257 #endif /* TARGET_MIPS64 */ 1258 1259 /* Moves to/from shadow registers. */ 1260 static inline void gen_load_srsgpr(int from, int to) 1261 { 1262 TCGv t0 = tcg_temp_new(); 1263 1264 if (from == 0) { 1265 tcg_gen_movi_tl(t0, 0); 1266 } else { 1267 TCGv_i32 t2 = tcg_temp_new_i32(); 1268 TCGv_ptr addr = tcg_temp_new_ptr(); 1269 1270 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1271 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1272 tcg_gen_andi_i32(t2, t2, 0xf); 1273 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1274 tcg_gen_ext_i32_ptr(addr, t2); 1275 tcg_gen_add_ptr(addr, cpu_env, addr); 1276 1277 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1278 tcg_temp_free_ptr(addr); 1279 tcg_temp_free_i32(t2); 1280 } 1281 gen_store_gpr(t0, to); 1282 tcg_temp_free(t0); 1283 } 1284 1285 static inline void gen_store_srsgpr(int from, int to) 1286 { 1287 if (to != 0) { 1288 TCGv t0 = tcg_temp_new(); 1289 TCGv_i32 t2 = tcg_temp_new_i32(); 1290 TCGv_ptr addr = tcg_temp_new_ptr(); 1291 1292 gen_load_gpr(t0, from); 1293 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1294 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1295 tcg_gen_andi_i32(t2, t2, 0xf); 1296 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1297 tcg_gen_ext_i32_ptr(addr, t2); 1298 tcg_gen_add_ptr(addr, cpu_env, addr); 1299 1300 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1301 tcg_temp_free_ptr(addr); 1302 tcg_temp_free_i32(t2); 1303 tcg_temp_free(t0); 1304 } 1305 } 1306 1307 /* Tests */ 1308 static inline void gen_save_pc(target_ulong pc) 1309 { 1310 tcg_gen_movi_tl(cpu_PC, pc); 1311 } 1312 1313 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1314 { 1315 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1316 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1317 gen_save_pc(ctx->base.pc_next); 1318 ctx->saved_pc = ctx->base.pc_next; 1319 } 1320 if (ctx->hflags != ctx->saved_hflags) { 1321 tcg_gen_movi_i32(hflags, ctx->hflags); 1322 ctx->saved_hflags = ctx->hflags; 1323 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1324 case MIPS_HFLAG_BR: 1325 break; 1326 case MIPS_HFLAG_BC: 1327 case MIPS_HFLAG_BL: 1328 case MIPS_HFLAG_B: 1329 tcg_gen_movi_tl(btarget, ctx->btarget); 1330 break; 1331 } 1332 } 1333 } 1334 1335 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1336 { 1337 ctx->saved_hflags = ctx->hflags; 1338 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1339 case MIPS_HFLAG_BR: 1340 break; 1341 case MIPS_HFLAG_BC: 1342 case MIPS_HFLAG_BL: 1343 case MIPS_HFLAG_B: 1344 ctx->btarget = env->btarget; 1345 break; 1346 } 1347 } 1348 1349 void generate_exception_err(DisasContext *ctx, int excp, int err) 1350 { 1351 save_cpu_state(ctx, 1); 1352 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp), 1353 tcg_constant_i32(err)); 1354 ctx->base.is_jmp = DISAS_NORETURN; 1355 } 1356 1357 void generate_exception(DisasContext *ctx, int excp) 1358 { 1359 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); 1360 } 1361 1362 void generate_exception_end(DisasContext *ctx, int excp) 1363 { 1364 generate_exception_err(ctx, excp, 0); 1365 } 1366 1367 void generate_exception_break(DisasContext *ctx, int code) 1368 { 1369 #ifdef CONFIG_USER_ONLY 1370 /* Pass the break code along to cpu_loop. */ 1371 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 1372 offsetof(CPUMIPSState, error_code)); 1373 #endif 1374 generate_exception_end(ctx, EXCP_BREAK); 1375 } 1376 1377 void gen_reserved_instruction(DisasContext *ctx) 1378 { 1379 generate_exception_end(ctx, EXCP_RI); 1380 } 1381 1382 /* Floating point register moves. */ 1383 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1384 { 1385 if (ctx->hflags & MIPS_HFLAG_FRE) { 1386 generate_exception(ctx, EXCP_RI); 1387 } 1388 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1389 } 1390 1391 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1392 { 1393 TCGv_i64 t64; 1394 if (ctx->hflags & MIPS_HFLAG_FRE) { 1395 generate_exception(ctx, EXCP_RI); 1396 } 1397 t64 = tcg_temp_new_i64(); 1398 tcg_gen_extu_i32_i64(t64, t); 1399 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1400 tcg_temp_free_i64(t64); 1401 } 1402 1403 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1404 { 1405 if (ctx->hflags & MIPS_HFLAG_F64) { 1406 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1407 } else { 1408 gen_load_fpr32(ctx, t, reg | 1); 1409 } 1410 } 1411 1412 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1413 { 1414 if (ctx->hflags & MIPS_HFLAG_F64) { 1415 TCGv_i64 t64 = tcg_temp_new_i64(); 1416 tcg_gen_extu_i32_i64(t64, t); 1417 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1418 tcg_temp_free_i64(t64); 1419 } else { 1420 gen_store_fpr32(ctx, t, reg | 1); 1421 } 1422 } 1423 1424 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1425 { 1426 if (ctx->hflags & MIPS_HFLAG_F64) { 1427 tcg_gen_mov_i64(t, fpu_f64[reg]); 1428 } else { 1429 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1430 } 1431 } 1432 1433 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1434 { 1435 if (ctx->hflags & MIPS_HFLAG_F64) { 1436 tcg_gen_mov_i64(fpu_f64[reg], t); 1437 } else { 1438 TCGv_i64 t0; 1439 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1440 t0 = tcg_temp_new_i64(); 1441 tcg_gen_shri_i64(t0, t, 32); 1442 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1443 tcg_temp_free_i64(t0); 1444 } 1445 } 1446 1447 int get_fp_bit(int cc) 1448 { 1449 if (cc) { 1450 return 24 + cc; 1451 } else { 1452 return 23; 1453 } 1454 } 1455 1456 /* Addresses computation */ 1457 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1458 { 1459 tcg_gen_add_tl(ret, arg0, arg1); 1460 1461 #if defined(TARGET_MIPS64) 1462 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1463 tcg_gen_ext32s_i64(ret, ret); 1464 } 1465 #endif 1466 } 1467 1468 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1469 target_long ofs) 1470 { 1471 tcg_gen_addi_tl(ret, base, ofs); 1472 1473 #if defined(TARGET_MIPS64) 1474 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1475 tcg_gen_ext32s_i64(ret, ret); 1476 } 1477 #endif 1478 } 1479 1480 /* Addresses computation (translation time) */ 1481 static target_long addr_add(DisasContext *ctx, target_long base, 1482 target_long offset) 1483 { 1484 target_long sum = base + offset; 1485 1486 #if defined(TARGET_MIPS64) 1487 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1488 sum = (int32_t)sum; 1489 } 1490 #endif 1491 return sum; 1492 } 1493 1494 /* Sign-extract the low 32-bits to a target_long. */ 1495 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1496 { 1497 #if defined(TARGET_MIPS64) 1498 tcg_gen_ext32s_i64(ret, arg); 1499 #else 1500 tcg_gen_extrl_i64_i32(ret, arg); 1501 #endif 1502 } 1503 1504 /* Sign-extract the high 32-bits to a target_long. */ 1505 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1506 { 1507 #if defined(TARGET_MIPS64) 1508 tcg_gen_sari_i64(ret, arg, 32); 1509 #else 1510 tcg_gen_extrh_i64_i32(ret, arg); 1511 #endif 1512 } 1513 1514 bool check_cp0_enabled(DisasContext *ctx) 1515 { 1516 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1517 generate_exception_end(ctx, EXCP_CpU); 1518 return false; 1519 } 1520 return true; 1521 } 1522 1523 void check_cp1_enabled(DisasContext *ctx) 1524 { 1525 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1526 generate_exception_err(ctx, EXCP_CpU, 1); 1527 } 1528 } 1529 1530 /* 1531 * Verify that the processor is running with COP1X instructions enabled. 1532 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1533 * opcode tables. 1534 */ 1535 void check_cop1x(DisasContext *ctx) 1536 { 1537 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1538 gen_reserved_instruction(ctx); 1539 } 1540 } 1541 1542 /* 1543 * Verify that the processor is running with 64-bit floating-point 1544 * operations enabled. 1545 */ 1546 void check_cp1_64bitmode(DisasContext *ctx) 1547 { 1548 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { 1549 gen_reserved_instruction(ctx); 1550 } 1551 } 1552 1553 /* 1554 * Verify if floating point register is valid; an operation is not defined 1555 * if bit 0 of any register specification is set and the FR bit in the 1556 * Status register equals zero, since the register numbers specify an 1557 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1558 * in the Status register equals one, both even and odd register numbers 1559 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1560 * 1561 * Multiple 64 bit wide registers can be checked by calling 1562 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1563 */ 1564 void check_cp1_registers(DisasContext *ctx, int regs) 1565 { 1566 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1567 gen_reserved_instruction(ctx); 1568 } 1569 } 1570 1571 /* 1572 * Verify that the processor is running with DSP instructions enabled. 1573 * This is enabled by CP0 Status register MX(24) bit. 1574 */ 1575 static inline void check_dsp(DisasContext *ctx) 1576 { 1577 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1578 if (ctx->insn_flags & ASE_DSP) { 1579 generate_exception_end(ctx, EXCP_DSPDIS); 1580 } else { 1581 gen_reserved_instruction(ctx); 1582 } 1583 } 1584 } 1585 1586 static inline void check_dsp_r2(DisasContext *ctx) 1587 { 1588 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1589 if (ctx->insn_flags & ASE_DSP) { 1590 generate_exception_end(ctx, EXCP_DSPDIS); 1591 } else { 1592 gen_reserved_instruction(ctx); 1593 } 1594 } 1595 } 1596 1597 static inline void check_dsp_r3(DisasContext *ctx) 1598 { 1599 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1600 if (ctx->insn_flags & ASE_DSP) { 1601 generate_exception_end(ctx, EXCP_DSPDIS); 1602 } else { 1603 gen_reserved_instruction(ctx); 1604 } 1605 } 1606 } 1607 1608 /* 1609 * This code generates a "reserved instruction" exception if the 1610 * CPU does not support the instruction set corresponding to flags. 1611 */ 1612 void check_insn(DisasContext *ctx, uint64_t flags) 1613 { 1614 if (unlikely(!(ctx->insn_flags & flags))) { 1615 gen_reserved_instruction(ctx); 1616 } 1617 } 1618 1619 /* 1620 * This code generates a "reserved instruction" exception if the 1621 * CPU has corresponding flag set which indicates that the instruction 1622 * has been removed. 1623 */ 1624 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1625 { 1626 if (unlikely(ctx->insn_flags & flags)) { 1627 gen_reserved_instruction(ctx); 1628 } 1629 } 1630 1631 /* 1632 * The Linux kernel traps certain reserved instruction exceptions to 1633 * emulate the corresponding instructions. QEMU is the kernel in user 1634 * mode, so those traps are emulated by accepting the instructions. 1635 * 1636 * A reserved instruction exception is generated for flagged CPUs if 1637 * QEMU runs in system mode. 1638 */ 1639 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1640 { 1641 #ifndef CONFIG_USER_ONLY 1642 check_insn_opc_removed(ctx, flags); 1643 #endif 1644 } 1645 1646 /* 1647 * This code generates a "reserved instruction" exception if the 1648 * CPU does not support 64-bit paired-single (PS) floating point data type. 1649 */ 1650 static inline void check_ps(DisasContext *ctx) 1651 { 1652 if (unlikely(!ctx->ps)) { 1653 generate_exception(ctx, EXCP_RI); 1654 } 1655 check_cp1_64bitmode(ctx); 1656 } 1657 1658 /* 1659 * This code generates a "reserved instruction" exception if cpu is not 1660 * 64-bit or 64-bit instructions are not enabled. 1661 */ 1662 void check_mips_64(DisasContext *ctx) 1663 { 1664 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1665 gen_reserved_instruction(ctx); 1666 } 1667 } 1668 1669 #ifndef CONFIG_USER_ONLY 1670 static inline void check_mvh(DisasContext *ctx) 1671 { 1672 if (unlikely(!ctx->mvh)) { 1673 generate_exception(ctx, EXCP_RI); 1674 } 1675 } 1676 #endif 1677 1678 /* 1679 * This code generates a "reserved instruction" exception if the 1680 * Config5 XNP bit is set. 1681 */ 1682 static inline void check_xnp(DisasContext *ctx) 1683 { 1684 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1685 gen_reserved_instruction(ctx); 1686 } 1687 } 1688 1689 #ifndef CONFIG_USER_ONLY 1690 /* 1691 * This code generates a "reserved instruction" exception if the 1692 * Config3 PW bit is NOT set. 1693 */ 1694 static inline void check_pw(DisasContext *ctx) 1695 { 1696 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1697 gen_reserved_instruction(ctx); 1698 } 1699 } 1700 #endif 1701 1702 /* 1703 * This code generates a "reserved instruction" exception if the 1704 * Config3 MT bit is NOT set. 1705 */ 1706 static inline void check_mt(DisasContext *ctx) 1707 { 1708 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1709 gen_reserved_instruction(ctx); 1710 } 1711 } 1712 1713 #ifndef CONFIG_USER_ONLY 1714 /* 1715 * This code generates a "coprocessor unusable" exception if CP0 is not 1716 * available, and, if that is not the case, generates a "reserved instruction" 1717 * exception if the Config5 MT bit is NOT set. This is needed for availability 1718 * control of some of MT ASE instructions. 1719 */ 1720 static inline void check_cp0_mt(DisasContext *ctx) 1721 { 1722 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1723 generate_exception_end(ctx, EXCP_CpU); 1724 } else { 1725 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1726 gen_reserved_instruction(ctx); 1727 } 1728 } 1729 } 1730 #endif 1731 1732 /* 1733 * This code generates a "reserved instruction" exception if the 1734 * Config5 NMS bit is set. 1735 */ 1736 static inline void check_nms(DisasContext *ctx) 1737 { 1738 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1739 gen_reserved_instruction(ctx); 1740 } 1741 } 1742 1743 /* 1744 * This code generates a "reserved instruction" exception if the 1745 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1746 * Config2 TL, and Config5 L2C are unset. 1747 */ 1748 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1749 { 1750 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1751 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1752 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1753 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1754 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1755 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1756 gen_reserved_instruction(ctx); 1757 } 1758 } 1759 1760 /* 1761 * This code generates a "reserved instruction" exception if the 1762 * Config5 EVA bit is NOT set. 1763 */ 1764 static inline void check_eva(DisasContext *ctx) 1765 { 1766 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1767 gen_reserved_instruction(ctx); 1768 } 1769 } 1770 1771 1772 /* 1773 * Define small wrappers for gen_load_fpr* so that we have a uniform 1774 * calling interface for 32 and 64-bit FPRs. No sense in changing 1775 * all callers for gen_load_fpr32 when we need the CTX parameter for 1776 * this one use. 1777 */ 1778 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1779 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1780 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1781 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1782 int ft, int fs, int cc) \ 1783 { \ 1784 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1785 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1786 switch (ifmt) { \ 1787 case FMT_PS: \ 1788 check_ps(ctx); \ 1789 break; \ 1790 case FMT_D: \ 1791 if (abs) { \ 1792 check_cop1x(ctx); \ 1793 } \ 1794 check_cp1_registers(ctx, fs | ft); \ 1795 break; \ 1796 case FMT_S: \ 1797 if (abs) { \ 1798 check_cop1x(ctx); \ 1799 } \ 1800 break; \ 1801 } \ 1802 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1803 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1804 switch (n) { \ 1805 case 0: \ 1806 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1807 break; \ 1808 case 1: \ 1809 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1810 break; \ 1811 case 2: \ 1812 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1813 break; \ 1814 case 3: \ 1815 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1816 break; \ 1817 case 4: \ 1818 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1819 break; \ 1820 case 5: \ 1821 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1822 break; \ 1823 case 6: \ 1824 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1825 break; \ 1826 case 7: \ 1827 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1828 break; \ 1829 case 8: \ 1830 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1831 break; \ 1832 case 9: \ 1833 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1834 break; \ 1835 case 10: \ 1836 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1837 break; \ 1838 case 11: \ 1839 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1840 break; \ 1841 case 12: \ 1842 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1843 break; \ 1844 case 13: \ 1845 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1846 break; \ 1847 case 14: \ 1848 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1849 break; \ 1850 case 15: \ 1851 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1852 break; \ 1853 default: \ 1854 abort(); \ 1855 } \ 1856 tcg_temp_free_i##bits(fp0); \ 1857 tcg_temp_free_i##bits(fp1); \ 1858 } 1859 1860 FOP_CONDS(, 0, d, FMT_D, 64) 1861 FOP_CONDS(abs, 1, d, FMT_D, 64) 1862 FOP_CONDS(, 0, s, FMT_S, 32) 1863 FOP_CONDS(abs, 1, s, FMT_S, 32) 1864 FOP_CONDS(, 0, ps, FMT_PS, 64) 1865 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1866 #undef FOP_CONDS 1867 1868 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1869 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1870 int ft, int fs, int fd) \ 1871 { \ 1872 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1873 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1874 if (ifmt == FMT_D) { \ 1875 check_cp1_registers(ctx, fs | ft | fd); \ 1876 } \ 1877 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1878 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1879 switch (n) { \ 1880 case 0: \ 1881 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1882 break; \ 1883 case 1: \ 1884 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1885 break; \ 1886 case 2: \ 1887 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1888 break; \ 1889 case 3: \ 1890 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1891 break; \ 1892 case 4: \ 1893 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1894 break; \ 1895 case 5: \ 1896 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1897 break; \ 1898 case 6: \ 1899 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1900 break; \ 1901 case 7: \ 1902 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1903 break; \ 1904 case 8: \ 1905 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1906 break; \ 1907 case 9: \ 1908 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1909 break; \ 1910 case 10: \ 1911 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1912 break; \ 1913 case 11: \ 1914 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1915 break; \ 1916 case 12: \ 1917 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1918 break; \ 1919 case 13: \ 1920 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1921 break; \ 1922 case 14: \ 1923 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1924 break; \ 1925 case 15: \ 1926 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1927 break; \ 1928 case 17: \ 1929 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1930 break; \ 1931 case 18: \ 1932 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1933 break; \ 1934 case 19: \ 1935 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1936 break; \ 1937 case 25: \ 1938 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1939 break; \ 1940 case 26: \ 1941 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 1942 break; \ 1943 case 27: \ 1944 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 1945 break; \ 1946 default: \ 1947 abort(); \ 1948 } \ 1949 STORE; \ 1950 tcg_temp_free_i ## bits(fp0); \ 1951 tcg_temp_free_i ## bits(fp1); \ 1952 } 1953 1954 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1955 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1956 #undef FOP_CONDNS 1957 #undef gen_ldcmp_fpr32 1958 #undef gen_ldcmp_fpr64 1959 1960 /* load/store instructions. */ 1961 #ifdef CONFIG_USER_ONLY 1962 #define OP_LD_ATOMIC(insn, fname) \ 1963 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1964 DisasContext *ctx) \ 1965 { \ 1966 TCGv t0 = tcg_temp_new(); \ 1967 tcg_gen_mov_tl(t0, arg1); \ 1968 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 1969 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 1970 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 1971 tcg_temp_free(t0); \ 1972 } 1973 #else 1974 #define OP_LD_ATOMIC(insn, fname) \ 1975 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1976 DisasContext *ctx) \ 1977 { \ 1978 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \ 1979 } 1980 #endif 1981 OP_LD_ATOMIC(ll, ld32s); 1982 #if defined(TARGET_MIPS64) 1983 OP_LD_ATOMIC(lld, ld64); 1984 #endif 1985 #undef OP_LD_ATOMIC 1986 1987 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1988 { 1989 if (base == 0) { 1990 tcg_gen_movi_tl(addr, offset); 1991 } else if (offset == 0) { 1992 gen_load_gpr(addr, base); 1993 } else { 1994 tcg_gen_movi_tl(addr, offset); 1995 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1996 } 1997 } 1998 1999 static target_ulong pc_relative_pc(DisasContext *ctx) 2000 { 2001 target_ulong pc = ctx->base.pc_next; 2002 2003 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2004 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2005 2006 pc -= branch_bytes; 2007 } 2008 2009 pc &= ~(target_ulong)3; 2010 return pc; 2011 } 2012 2013 /* Load */ 2014 static void gen_ld(DisasContext *ctx, uint32_t opc, 2015 int rt, int base, int offset) 2016 { 2017 TCGv t0, t1, t2; 2018 int mem_idx = ctx->mem_idx; 2019 2020 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2021 INSN_LOONGSON3A)) { 2022 /* 2023 * Loongson CPU uses a load to zero register for prefetch. 2024 * We emulate it as a NOP. On other CPU we must perform the 2025 * actual memory access. 2026 */ 2027 return; 2028 } 2029 2030 t0 = tcg_temp_new(); 2031 gen_base_offset_addr(ctx, t0, base, offset); 2032 2033 switch (opc) { 2034 #if defined(TARGET_MIPS64) 2035 case OPC_LWU: 2036 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2037 ctx->default_tcg_memop_mask); 2038 gen_store_gpr(t0, rt); 2039 break; 2040 case OPC_LD: 2041 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ | 2042 ctx->default_tcg_memop_mask); 2043 gen_store_gpr(t0, rt); 2044 break; 2045 case OPC_LLD: 2046 case R6_OPC_LLD: 2047 op_ld_lld(t0, t0, mem_idx, ctx); 2048 gen_store_gpr(t0, rt); 2049 break; 2050 case OPC_LDL: 2051 t1 = tcg_temp_new(); 2052 /* 2053 * Do a byte access to possibly trigger a page 2054 * fault with the unaligned address. 2055 */ 2056 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2057 tcg_gen_andi_tl(t1, t0, 7); 2058 if (!cpu_is_bigendian(ctx)) { 2059 tcg_gen_xori_tl(t1, t1, 7); 2060 } 2061 tcg_gen_shli_tl(t1, t1, 3); 2062 tcg_gen_andi_tl(t0, t0, ~7); 2063 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2064 tcg_gen_shl_tl(t0, t0, t1); 2065 t2 = tcg_const_tl(-1); 2066 tcg_gen_shl_tl(t2, t2, t1); 2067 gen_load_gpr(t1, rt); 2068 tcg_gen_andc_tl(t1, t1, t2); 2069 tcg_temp_free(t2); 2070 tcg_gen_or_tl(t0, t0, t1); 2071 tcg_temp_free(t1); 2072 gen_store_gpr(t0, rt); 2073 break; 2074 case OPC_LDR: 2075 t1 = tcg_temp_new(); 2076 /* 2077 * Do a byte access to possibly trigger a page 2078 * fault with the unaligned address. 2079 */ 2080 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2081 tcg_gen_andi_tl(t1, t0, 7); 2082 if (cpu_is_bigendian(ctx)) { 2083 tcg_gen_xori_tl(t1, t1, 7); 2084 } 2085 tcg_gen_shli_tl(t1, t1, 3); 2086 tcg_gen_andi_tl(t0, t0, ~7); 2087 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2088 tcg_gen_shr_tl(t0, t0, t1); 2089 tcg_gen_xori_tl(t1, t1, 63); 2090 t2 = tcg_const_tl(0xfffffffffffffffeull); 2091 tcg_gen_shl_tl(t2, t2, t1); 2092 gen_load_gpr(t1, rt); 2093 tcg_gen_and_tl(t1, t1, t2); 2094 tcg_temp_free(t2); 2095 tcg_gen_or_tl(t0, t0, t1); 2096 tcg_temp_free(t1); 2097 gen_store_gpr(t0, rt); 2098 break; 2099 case OPC_LDPC: 2100 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2101 gen_op_addr_add(ctx, t0, t0, t1); 2102 tcg_temp_free(t1); 2103 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ); 2104 gen_store_gpr(t0, rt); 2105 break; 2106 #endif 2107 case OPC_LWPC: 2108 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2109 gen_op_addr_add(ctx, t0, t0, t1); 2110 tcg_temp_free(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 /* 2158 * Do a byte access to possibly trigger a page 2159 * fault with the unaligned address. 2160 */ 2161 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2162 tcg_gen_andi_tl(t1, t0, 3); 2163 if (!cpu_is_bigendian(ctx)) { 2164 tcg_gen_xori_tl(t1, t1, 3); 2165 } 2166 tcg_gen_shli_tl(t1, t1, 3); 2167 tcg_gen_andi_tl(t0, t0, ~3); 2168 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2169 tcg_gen_shl_tl(t0, t0, t1); 2170 t2 = tcg_const_tl(-1); 2171 tcg_gen_shl_tl(t2, t2, t1); 2172 gen_load_gpr(t1, rt); 2173 tcg_gen_andc_tl(t1, t1, t2); 2174 tcg_temp_free(t2); 2175 tcg_gen_or_tl(t0, t0, t1); 2176 tcg_temp_free(t1); 2177 tcg_gen_ext32s_tl(t0, t0); 2178 gen_store_gpr(t0, rt); 2179 break; 2180 case OPC_LWRE: 2181 mem_idx = MIPS_HFLAG_UM; 2182 /* fall through */ 2183 case OPC_LWR: 2184 t1 = tcg_temp_new(); 2185 /* 2186 * Do a byte access to possibly trigger a page 2187 * fault with the unaligned address. 2188 */ 2189 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2190 tcg_gen_andi_tl(t1, t0, 3); 2191 if (cpu_is_bigendian(ctx)) { 2192 tcg_gen_xori_tl(t1, t1, 3); 2193 } 2194 tcg_gen_shli_tl(t1, t1, 3); 2195 tcg_gen_andi_tl(t0, t0, ~3); 2196 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2197 tcg_gen_shr_tl(t0, t0, t1); 2198 tcg_gen_xori_tl(t1, t1, 31); 2199 t2 = tcg_const_tl(0xfffffffeull); 2200 tcg_gen_shl_tl(t2, t2, t1); 2201 gen_load_gpr(t1, rt); 2202 tcg_gen_and_tl(t1, t1, t2); 2203 tcg_temp_free(t2); 2204 tcg_gen_or_tl(t0, t0, t1); 2205 tcg_temp_free(t1); 2206 tcg_gen_ext32s_tl(t0, t0); 2207 gen_store_gpr(t0, rt); 2208 break; 2209 case OPC_LLE: 2210 mem_idx = MIPS_HFLAG_UM; 2211 /* fall through */ 2212 case OPC_LL: 2213 case R6_OPC_LL: 2214 op_ld_ll(t0, t0, mem_idx, ctx); 2215 gen_store_gpr(t0, rt); 2216 break; 2217 } 2218 tcg_temp_free(t0); 2219 } 2220 2221 /* Store */ 2222 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2223 int base, int offset) 2224 { 2225 TCGv t0 = tcg_temp_new(); 2226 TCGv t1 = tcg_temp_new(); 2227 int mem_idx = ctx->mem_idx; 2228 2229 gen_base_offset_addr(ctx, t0, base, offset); 2230 gen_load_gpr(t1, rt); 2231 switch (opc) { 2232 #if defined(TARGET_MIPS64) 2233 case OPC_SD: 2234 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ | 2235 ctx->default_tcg_memop_mask); 2236 break; 2237 case OPC_SDL: 2238 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2239 break; 2240 case OPC_SDR: 2241 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2242 break; 2243 #endif 2244 case OPC_SWE: 2245 mem_idx = MIPS_HFLAG_UM; 2246 /* fall through */ 2247 case OPC_SW: 2248 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2249 ctx->default_tcg_memop_mask); 2250 break; 2251 case OPC_SHE: 2252 mem_idx = MIPS_HFLAG_UM; 2253 /* fall through */ 2254 case OPC_SH: 2255 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2256 ctx->default_tcg_memop_mask); 2257 break; 2258 case OPC_SBE: 2259 mem_idx = MIPS_HFLAG_UM; 2260 /* fall through */ 2261 case OPC_SB: 2262 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2263 break; 2264 case OPC_SWLE: 2265 mem_idx = MIPS_HFLAG_UM; 2266 /* fall through */ 2267 case OPC_SWL: 2268 gen_helper_0e2i(swl, t1, t0, mem_idx); 2269 break; 2270 case OPC_SWRE: 2271 mem_idx = MIPS_HFLAG_UM; 2272 /* fall through */ 2273 case OPC_SWR: 2274 gen_helper_0e2i(swr, t1, t0, mem_idx); 2275 break; 2276 } 2277 tcg_temp_free(t0); 2278 tcg_temp_free(t1); 2279 } 2280 2281 2282 /* Store conditional */ 2283 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2284 MemOp tcg_mo, bool eva) 2285 { 2286 TCGv addr, t0, val; 2287 TCGLabel *l1 = gen_new_label(); 2288 TCGLabel *done = gen_new_label(); 2289 2290 t0 = tcg_temp_new(); 2291 addr = tcg_temp_new(); 2292 /* compare the address against that of the preceding LL */ 2293 gen_base_offset_addr(ctx, addr, base, offset); 2294 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2295 tcg_temp_free(addr); 2296 tcg_gen_movi_tl(t0, 0); 2297 gen_store_gpr(t0, rt); 2298 tcg_gen_br(done); 2299 2300 gen_set_label(l1); 2301 /* generate cmpxchg */ 2302 val = tcg_temp_new(); 2303 gen_load_gpr(val, rt); 2304 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2305 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2306 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2307 gen_store_gpr(t0, rt); 2308 tcg_temp_free(val); 2309 2310 gen_set_label(done); 2311 tcg_temp_free(t0); 2312 } 2313 2314 /* Load and store */ 2315 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2316 TCGv t0) 2317 { 2318 /* 2319 * Don't do NOP if destination is zero: we must perform the actual 2320 * memory access. 2321 */ 2322 switch (opc) { 2323 case OPC_LWC1: 2324 { 2325 TCGv_i32 fp0 = tcg_temp_new_i32(); 2326 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2327 ctx->default_tcg_memop_mask); 2328 gen_store_fpr32(ctx, fp0, ft); 2329 tcg_temp_free_i32(fp0); 2330 } 2331 break; 2332 case OPC_SWC1: 2333 { 2334 TCGv_i32 fp0 = tcg_temp_new_i32(); 2335 gen_load_fpr32(ctx, fp0, ft); 2336 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2337 ctx->default_tcg_memop_mask); 2338 tcg_temp_free_i32(fp0); 2339 } 2340 break; 2341 case OPC_LDC1: 2342 { 2343 TCGv_i64 fp0 = tcg_temp_new_i64(); 2344 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2345 ctx->default_tcg_memop_mask); 2346 gen_store_fpr64(ctx, fp0, ft); 2347 tcg_temp_free_i64(fp0); 2348 } 2349 break; 2350 case OPC_SDC1: 2351 { 2352 TCGv_i64 fp0 = tcg_temp_new_i64(); 2353 gen_load_fpr64(ctx, fp0, ft); 2354 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ | 2355 ctx->default_tcg_memop_mask); 2356 tcg_temp_free_i64(fp0); 2357 } 2358 break; 2359 default: 2360 MIPS_INVAL("flt_ldst"); 2361 gen_reserved_instruction(ctx); 2362 break; 2363 } 2364 } 2365 2366 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2367 int rs, int16_t imm) 2368 { 2369 TCGv t0 = tcg_temp_new(); 2370 2371 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2372 check_cp1_enabled(ctx); 2373 switch (op) { 2374 case OPC_LDC1: 2375 case OPC_SDC1: 2376 check_insn(ctx, ISA_MIPS2); 2377 /* Fallthrough */ 2378 default: 2379 gen_base_offset_addr(ctx, t0, rs, imm); 2380 gen_flt_ldst(ctx, op, rt, t0); 2381 } 2382 } else { 2383 generate_exception_err(ctx, EXCP_CpU, 1); 2384 } 2385 tcg_temp_free(t0); 2386 } 2387 2388 /* Arithmetic with immediate operand */ 2389 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2390 int rt, int rs, int imm) 2391 { 2392 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2393 2394 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2395 /* 2396 * If no destination, treat it as a NOP. 2397 * For addi, we must generate the overflow exception when needed. 2398 */ 2399 return; 2400 } 2401 switch (opc) { 2402 case OPC_ADDI: 2403 { 2404 TCGv t0 = tcg_temp_local_new(); 2405 TCGv t1 = tcg_temp_new(); 2406 TCGv t2 = tcg_temp_new(); 2407 TCGLabel *l1 = gen_new_label(); 2408 2409 gen_load_gpr(t1, rs); 2410 tcg_gen_addi_tl(t0, t1, uimm); 2411 tcg_gen_ext32s_tl(t0, t0); 2412 2413 tcg_gen_xori_tl(t1, t1, ~uimm); 2414 tcg_gen_xori_tl(t2, t0, uimm); 2415 tcg_gen_and_tl(t1, t1, t2); 2416 tcg_temp_free(t2); 2417 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2418 tcg_temp_free(t1); 2419 /* operands of same sign, result different sign */ 2420 generate_exception(ctx, EXCP_OVERFLOW); 2421 gen_set_label(l1); 2422 tcg_gen_ext32s_tl(t0, t0); 2423 gen_store_gpr(t0, rt); 2424 tcg_temp_free(t0); 2425 } 2426 break; 2427 case OPC_ADDIU: 2428 if (rs != 0) { 2429 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2430 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2431 } else { 2432 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2433 } 2434 break; 2435 #if defined(TARGET_MIPS64) 2436 case OPC_DADDI: 2437 { 2438 TCGv t0 = tcg_temp_local_new(); 2439 TCGv t1 = tcg_temp_new(); 2440 TCGv t2 = tcg_temp_new(); 2441 TCGLabel *l1 = gen_new_label(); 2442 2443 gen_load_gpr(t1, rs); 2444 tcg_gen_addi_tl(t0, t1, uimm); 2445 2446 tcg_gen_xori_tl(t1, t1, ~uimm); 2447 tcg_gen_xori_tl(t2, t0, uimm); 2448 tcg_gen_and_tl(t1, t1, t2); 2449 tcg_temp_free(t2); 2450 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2451 tcg_temp_free(t1); 2452 /* operands of same sign, result different sign */ 2453 generate_exception(ctx, EXCP_OVERFLOW); 2454 gen_set_label(l1); 2455 gen_store_gpr(t0, rt); 2456 tcg_temp_free(t0); 2457 } 2458 break; 2459 case OPC_DADDIU: 2460 if (rs != 0) { 2461 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2462 } else { 2463 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2464 } 2465 break; 2466 #endif 2467 } 2468 } 2469 2470 /* Logic with immediate operand */ 2471 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2472 int rt, int rs, int16_t imm) 2473 { 2474 target_ulong uimm; 2475 2476 if (rt == 0) { 2477 /* If no destination, treat it as a NOP. */ 2478 return; 2479 } 2480 uimm = (uint16_t)imm; 2481 switch (opc) { 2482 case OPC_ANDI: 2483 if (likely(rs != 0)) { 2484 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2485 } else { 2486 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2487 } 2488 break; 2489 case OPC_ORI: 2490 if (rs != 0) { 2491 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2492 } else { 2493 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2494 } 2495 break; 2496 case OPC_XORI: 2497 if (likely(rs != 0)) { 2498 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2499 } else { 2500 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2501 } 2502 break; 2503 case OPC_LUI: 2504 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2505 /* OPC_AUI */ 2506 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2507 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2508 } else { 2509 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2510 } 2511 break; 2512 2513 default: 2514 break; 2515 } 2516 } 2517 2518 /* Set on less than with immediate operand */ 2519 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2520 int rt, int rs, int16_t imm) 2521 { 2522 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2523 TCGv t0; 2524 2525 if (rt == 0) { 2526 /* If no destination, treat it as a NOP. */ 2527 return; 2528 } 2529 t0 = tcg_temp_new(); 2530 gen_load_gpr(t0, rs); 2531 switch (opc) { 2532 case OPC_SLTI: 2533 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2534 break; 2535 case OPC_SLTIU: 2536 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2537 break; 2538 } 2539 tcg_temp_free(t0); 2540 } 2541 2542 /* Shifts with immediate operand */ 2543 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2544 int rt, int rs, int16_t imm) 2545 { 2546 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2547 TCGv t0; 2548 2549 if (rt == 0) { 2550 /* If no destination, treat it as a NOP. */ 2551 return; 2552 } 2553 2554 t0 = tcg_temp_new(); 2555 gen_load_gpr(t0, rs); 2556 switch (opc) { 2557 case OPC_SLL: 2558 tcg_gen_shli_tl(t0, t0, uimm); 2559 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2560 break; 2561 case OPC_SRA: 2562 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2563 break; 2564 case OPC_SRL: 2565 if (uimm != 0) { 2566 tcg_gen_ext32u_tl(t0, t0); 2567 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2568 } else { 2569 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2570 } 2571 break; 2572 case OPC_ROTR: 2573 if (uimm != 0) { 2574 TCGv_i32 t1 = tcg_temp_new_i32(); 2575 2576 tcg_gen_trunc_tl_i32(t1, t0); 2577 tcg_gen_rotri_i32(t1, t1, uimm); 2578 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2579 tcg_temp_free_i32(t1); 2580 } else { 2581 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2582 } 2583 break; 2584 #if defined(TARGET_MIPS64) 2585 case OPC_DSLL: 2586 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2587 break; 2588 case OPC_DSRA: 2589 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2590 break; 2591 case OPC_DSRL: 2592 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2593 break; 2594 case OPC_DROTR: 2595 if (uimm != 0) { 2596 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2597 } else { 2598 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2599 } 2600 break; 2601 case OPC_DSLL32: 2602 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2603 break; 2604 case OPC_DSRA32: 2605 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2606 break; 2607 case OPC_DSRL32: 2608 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2609 break; 2610 case OPC_DROTR32: 2611 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2612 break; 2613 #endif 2614 } 2615 tcg_temp_free(t0); 2616 } 2617 2618 /* Arithmetic */ 2619 static void gen_arith(DisasContext *ctx, uint32_t opc, 2620 int rd, int rs, int rt) 2621 { 2622 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2623 && opc != OPC_DADD && opc != OPC_DSUB) { 2624 /* 2625 * If no destination, treat it as a NOP. 2626 * For add & sub, we must generate the overflow exception when needed. 2627 */ 2628 return; 2629 } 2630 2631 switch (opc) { 2632 case OPC_ADD: 2633 { 2634 TCGv t0 = tcg_temp_local_new(); 2635 TCGv t1 = tcg_temp_new(); 2636 TCGv t2 = tcg_temp_new(); 2637 TCGLabel *l1 = gen_new_label(); 2638 2639 gen_load_gpr(t1, rs); 2640 gen_load_gpr(t2, rt); 2641 tcg_gen_add_tl(t0, t1, t2); 2642 tcg_gen_ext32s_tl(t0, t0); 2643 tcg_gen_xor_tl(t1, t1, t2); 2644 tcg_gen_xor_tl(t2, t0, t2); 2645 tcg_gen_andc_tl(t1, t2, t1); 2646 tcg_temp_free(t2); 2647 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2648 tcg_temp_free(t1); 2649 /* operands of same sign, result different sign */ 2650 generate_exception(ctx, EXCP_OVERFLOW); 2651 gen_set_label(l1); 2652 gen_store_gpr(t0, rd); 2653 tcg_temp_free(t0); 2654 } 2655 break; 2656 case OPC_ADDU: 2657 if (rs != 0 && rt != 0) { 2658 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2659 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2660 } else if (rs == 0 && rt != 0) { 2661 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2662 } else if (rs != 0 && rt == 0) { 2663 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2664 } else { 2665 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2666 } 2667 break; 2668 case OPC_SUB: 2669 { 2670 TCGv t0 = tcg_temp_local_new(); 2671 TCGv t1 = tcg_temp_new(); 2672 TCGv t2 = tcg_temp_new(); 2673 TCGLabel *l1 = gen_new_label(); 2674 2675 gen_load_gpr(t1, rs); 2676 gen_load_gpr(t2, rt); 2677 tcg_gen_sub_tl(t0, t1, t2); 2678 tcg_gen_ext32s_tl(t0, t0); 2679 tcg_gen_xor_tl(t2, t1, t2); 2680 tcg_gen_xor_tl(t1, t0, t1); 2681 tcg_gen_and_tl(t1, t1, t2); 2682 tcg_temp_free(t2); 2683 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2684 tcg_temp_free(t1); 2685 /* 2686 * operands of different sign, first operand and the result 2687 * of different sign 2688 */ 2689 generate_exception(ctx, EXCP_OVERFLOW); 2690 gen_set_label(l1); 2691 gen_store_gpr(t0, rd); 2692 tcg_temp_free(t0); 2693 } 2694 break; 2695 case OPC_SUBU: 2696 if (rs != 0 && rt != 0) { 2697 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2698 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2699 } else if (rs == 0 && rt != 0) { 2700 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2702 } else if (rs != 0 && rt == 0) { 2703 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2704 } else { 2705 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2706 } 2707 break; 2708 #if defined(TARGET_MIPS64) 2709 case OPC_DADD: 2710 { 2711 TCGv t0 = tcg_temp_local_new(); 2712 TCGv t1 = tcg_temp_new(); 2713 TCGv t2 = tcg_temp_new(); 2714 TCGLabel *l1 = gen_new_label(); 2715 2716 gen_load_gpr(t1, rs); 2717 gen_load_gpr(t2, rt); 2718 tcg_gen_add_tl(t0, t1, t2); 2719 tcg_gen_xor_tl(t1, t1, t2); 2720 tcg_gen_xor_tl(t2, t0, t2); 2721 tcg_gen_andc_tl(t1, t2, t1); 2722 tcg_temp_free(t2); 2723 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2724 tcg_temp_free(t1); 2725 /* operands of same sign, result different sign */ 2726 generate_exception(ctx, EXCP_OVERFLOW); 2727 gen_set_label(l1); 2728 gen_store_gpr(t0, rd); 2729 tcg_temp_free(t0); 2730 } 2731 break; 2732 case OPC_DADDU: 2733 if (rs != 0 && rt != 0) { 2734 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2735 } else if (rs == 0 && rt != 0) { 2736 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2737 } else if (rs != 0 && rt == 0) { 2738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2739 } else { 2740 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2741 } 2742 break; 2743 case OPC_DSUB: 2744 { 2745 TCGv t0 = tcg_temp_local_new(); 2746 TCGv t1 = tcg_temp_new(); 2747 TCGv t2 = tcg_temp_new(); 2748 TCGLabel *l1 = gen_new_label(); 2749 2750 gen_load_gpr(t1, rs); 2751 gen_load_gpr(t2, rt); 2752 tcg_gen_sub_tl(t0, t1, t2); 2753 tcg_gen_xor_tl(t2, t1, t2); 2754 tcg_gen_xor_tl(t1, t0, t1); 2755 tcg_gen_and_tl(t1, t1, t2); 2756 tcg_temp_free(t2); 2757 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2758 tcg_temp_free(t1); 2759 /* 2760 * Operands of different sign, first operand and result different 2761 * sign. 2762 */ 2763 generate_exception(ctx, EXCP_OVERFLOW); 2764 gen_set_label(l1); 2765 gen_store_gpr(t0, rd); 2766 tcg_temp_free(t0); 2767 } 2768 break; 2769 case OPC_DSUBU: 2770 if (rs != 0 && rt != 0) { 2771 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2772 } else if (rs == 0 && rt != 0) { 2773 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2774 } else if (rs != 0 && rt == 0) { 2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2776 } else { 2777 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2778 } 2779 break; 2780 #endif 2781 case OPC_MUL: 2782 if (likely(rs != 0 && rt != 0)) { 2783 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2784 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2785 } else { 2786 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2787 } 2788 break; 2789 } 2790 } 2791 2792 /* Conditional move */ 2793 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2794 int rd, int rs, int rt) 2795 { 2796 TCGv t0, t1, t2; 2797 2798 if (rd == 0) { 2799 /* If no destination, treat it as a NOP. */ 2800 return; 2801 } 2802 2803 t0 = tcg_temp_new(); 2804 gen_load_gpr(t0, rt); 2805 t1 = tcg_const_tl(0); 2806 t2 = tcg_temp_new(); 2807 gen_load_gpr(t2, rs); 2808 switch (opc) { 2809 case OPC_MOVN: 2810 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2811 break; 2812 case OPC_MOVZ: 2813 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2814 break; 2815 case OPC_SELNEZ: 2816 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2817 break; 2818 case OPC_SELEQZ: 2819 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2820 break; 2821 } 2822 tcg_temp_free(t2); 2823 tcg_temp_free(t1); 2824 tcg_temp_free(t0); 2825 } 2826 2827 /* Logic */ 2828 static void gen_logic(DisasContext *ctx, uint32_t opc, 2829 int rd, int rs, int rt) 2830 { 2831 if (rd == 0) { 2832 /* If no destination, treat it as a NOP. */ 2833 return; 2834 } 2835 2836 switch (opc) { 2837 case OPC_AND: 2838 if (likely(rs != 0 && rt != 0)) { 2839 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2840 } else { 2841 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2842 } 2843 break; 2844 case OPC_NOR: 2845 if (rs != 0 && rt != 0) { 2846 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2847 } else if (rs == 0 && rt != 0) { 2848 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2849 } else if (rs != 0 && rt == 0) { 2850 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2851 } else { 2852 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2853 } 2854 break; 2855 case OPC_OR: 2856 if (likely(rs != 0 && rt != 0)) { 2857 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2858 } else if (rs == 0 && rt != 0) { 2859 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2860 } else if (rs != 0 && rt == 0) { 2861 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2862 } else { 2863 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2864 } 2865 break; 2866 case OPC_XOR: 2867 if (likely(rs != 0 && rt != 0)) { 2868 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2869 } else if (rs == 0 && rt != 0) { 2870 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2871 } else if (rs != 0 && rt == 0) { 2872 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2873 } else { 2874 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2875 } 2876 break; 2877 } 2878 } 2879 2880 /* Set on lower than */ 2881 static void gen_slt(DisasContext *ctx, uint32_t opc, 2882 int rd, int rs, int rt) 2883 { 2884 TCGv t0, t1; 2885 2886 if (rd == 0) { 2887 /* If no destination, treat it as a NOP. */ 2888 return; 2889 } 2890 2891 t0 = tcg_temp_new(); 2892 t1 = tcg_temp_new(); 2893 gen_load_gpr(t0, rs); 2894 gen_load_gpr(t1, rt); 2895 switch (opc) { 2896 case OPC_SLT: 2897 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2898 break; 2899 case OPC_SLTU: 2900 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2901 break; 2902 } 2903 tcg_temp_free(t0); 2904 tcg_temp_free(t1); 2905 } 2906 2907 /* Shifts */ 2908 static void gen_shift(DisasContext *ctx, uint32_t opc, 2909 int rd, int rs, int rt) 2910 { 2911 TCGv t0, t1; 2912 2913 if (rd == 0) { 2914 /* 2915 * If no destination, treat it as a NOP. 2916 * For add & sub, we must generate the overflow exception when needed. 2917 */ 2918 return; 2919 } 2920 2921 t0 = tcg_temp_new(); 2922 t1 = tcg_temp_new(); 2923 gen_load_gpr(t0, rs); 2924 gen_load_gpr(t1, rt); 2925 switch (opc) { 2926 case OPC_SLLV: 2927 tcg_gen_andi_tl(t0, t0, 0x1f); 2928 tcg_gen_shl_tl(t0, t1, t0); 2929 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2930 break; 2931 case OPC_SRAV: 2932 tcg_gen_andi_tl(t0, t0, 0x1f); 2933 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2934 break; 2935 case OPC_SRLV: 2936 tcg_gen_ext32u_tl(t1, t1); 2937 tcg_gen_andi_tl(t0, t0, 0x1f); 2938 tcg_gen_shr_tl(t0, t1, t0); 2939 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2940 break; 2941 case OPC_ROTRV: 2942 { 2943 TCGv_i32 t2 = tcg_temp_new_i32(); 2944 TCGv_i32 t3 = tcg_temp_new_i32(); 2945 2946 tcg_gen_trunc_tl_i32(t2, t0); 2947 tcg_gen_trunc_tl_i32(t3, t1); 2948 tcg_gen_andi_i32(t2, t2, 0x1f); 2949 tcg_gen_rotr_i32(t2, t3, t2); 2950 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2951 tcg_temp_free_i32(t2); 2952 tcg_temp_free_i32(t3); 2953 } 2954 break; 2955 #if defined(TARGET_MIPS64) 2956 case OPC_DSLLV: 2957 tcg_gen_andi_tl(t0, t0, 0x3f); 2958 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2959 break; 2960 case OPC_DSRAV: 2961 tcg_gen_andi_tl(t0, t0, 0x3f); 2962 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2963 break; 2964 case OPC_DSRLV: 2965 tcg_gen_andi_tl(t0, t0, 0x3f); 2966 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2967 break; 2968 case OPC_DROTRV: 2969 tcg_gen_andi_tl(t0, t0, 0x3f); 2970 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2971 break; 2972 #endif 2973 } 2974 tcg_temp_free(t0); 2975 tcg_temp_free(t1); 2976 } 2977 2978 /* Arithmetic on HI/LO registers */ 2979 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2980 { 2981 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2982 /* Treat as NOP. */ 2983 return; 2984 } 2985 2986 if (acc != 0) { 2987 check_dsp(ctx); 2988 } 2989 2990 switch (opc) { 2991 case OPC_MFHI: 2992 #if defined(TARGET_MIPS64) 2993 if (acc != 0) { 2994 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2995 } else 2996 #endif 2997 { 2998 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2999 } 3000 break; 3001 case OPC_MFLO: 3002 #if defined(TARGET_MIPS64) 3003 if (acc != 0) { 3004 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3005 } else 3006 #endif 3007 { 3008 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3009 } 3010 break; 3011 case OPC_MTHI: 3012 if (reg != 0) { 3013 #if defined(TARGET_MIPS64) 3014 if (acc != 0) { 3015 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3016 } else 3017 #endif 3018 { 3019 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3020 } 3021 } else { 3022 tcg_gen_movi_tl(cpu_HI[acc], 0); 3023 } 3024 break; 3025 case OPC_MTLO: 3026 if (reg != 0) { 3027 #if defined(TARGET_MIPS64) 3028 if (acc != 0) { 3029 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3030 } else 3031 #endif 3032 { 3033 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3034 } 3035 } else { 3036 tcg_gen_movi_tl(cpu_LO[acc], 0); 3037 } 3038 break; 3039 } 3040 } 3041 3042 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3043 MemOp memop) 3044 { 3045 TCGv t0 = tcg_const_tl(addr); 3046 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3047 gen_store_gpr(t0, reg); 3048 tcg_temp_free(t0); 3049 } 3050 3051 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3052 int rs) 3053 { 3054 target_long offset; 3055 target_long addr; 3056 3057 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3058 case OPC_ADDIUPC: 3059 if (rs != 0) { 3060 offset = sextract32(ctx->opcode << 2, 0, 21); 3061 addr = addr_add(ctx, pc, offset); 3062 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3063 } 3064 break; 3065 case R6_OPC_LWPC: 3066 offset = sextract32(ctx->opcode << 2, 0, 21); 3067 addr = addr_add(ctx, pc, offset); 3068 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3069 break; 3070 #if defined(TARGET_MIPS64) 3071 case OPC_LWUPC: 3072 check_mips_64(ctx); 3073 offset = sextract32(ctx->opcode << 2, 0, 21); 3074 addr = addr_add(ctx, pc, offset); 3075 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3076 break; 3077 #endif 3078 default: 3079 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3080 case OPC_AUIPC: 3081 if (rs != 0) { 3082 offset = sextract32(ctx->opcode, 0, 16) << 16; 3083 addr = addr_add(ctx, pc, offset); 3084 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3085 } 3086 break; 3087 case OPC_ALUIPC: 3088 if (rs != 0) { 3089 offset = sextract32(ctx->opcode, 0, 16) << 16; 3090 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3091 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3092 } 3093 break; 3094 #if defined(TARGET_MIPS64) 3095 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3096 case R6_OPC_LDPC + (1 << 16): 3097 case R6_OPC_LDPC + (2 << 16): 3098 case R6_OPC_LDPC + (3 << 16): 3099 check_mips_64(ctx); 3100 offset = sextract32(ctx->opcode << 3, 0, 21); 3101 addr = addr_add(ctx, (pc & ~0x7), offset); 3102 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ); 3103 break; 3104 #endif 3105 default: 3106 MIPS_INVAL("OPC_PCREL"); 3107 gen_reserved_instruction(ctx); 3108 break; 3109 } 3110 break; 3111 } 3112 } 3113 3114 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3115 { 3116 TCGv t0, t1; 3117 3118 if (rd == 0) { 3119 /* Treat as NOP. */ 3120 return; 3121 } 3122 3123 t0 = tcg_temp_new(); 3124 t1 = tcg_temp_new(); 3125 3126 gen_load_gpr(t0, rs); 3127 gen_load_gpr(t1, rt); 3128 3129 switch (opc) { 3130 case R6_OPC_DIV: 3131 { 3132 TCGv t2 = tcg_temp_new(); 3133 TCGv t3 = tcg_temp_new(); 3134 tcg_gen_ext32s_tl(t0, t0); 3135 tcg_gen_ext32s_tl(t1, t1); 3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3137 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3138 tcg_gen_and_tl(t2, t2, t3); 3139 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3140 tcg_gen_or_tl(t2, t2, t3); 3141 tcg_gen_movi_tl(t3, 0); 3142 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3143 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3144 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3145 tcg_temp_free(t3); 3146 tcg_temp_free(t2); 3147 } 3148 break; 3149 case R6_OPC_MOD: 3150 { 3151 TCGv t2 = tcg_temp_new(); 3152 TCGv t3 = tcg_temp_new(); 3153 tcg_gen_ext32s_tl(t0, t0); 3154 tcg_gen_ext32s_tl(t1, t1); 3155 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3156 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3157 tcg_gen_and_tl(t2, t2, t3); 3158 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3159 tcg_gen_or_tl(t2, t2, t3); 3160 tcg_gen_movi_tl(t3, 0); 3161 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3162 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3163 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3164 tcg_temp_free(t3); 3165 tcg_temp_free(t2); 3166 } 3167 break; 3168 case R6_OPC_DIVU: 3169 { 3170 TCGv t2 = tcg_const_tl(0); 3171 TCGv t3 = tcg_const_tl(1); 3172 tcg_gen_ext32u_tl(t0, t0); 3173 tcg_gen_ext32u_tl(t1, t1); 3174 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3175 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3176 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3177 tcg_temp_free(t3); 3178 tcg_temp_free(t2); 3179 } 3180 break; 3181 case R6_OPC_MODU: 3182 { 3183 TCGv t2 = tcg_const_tl(0); 3184 TCGv t3 = tcg_const_tl(1); 3185 tcg_gen_ext32u_tl(t0, t0); 3186 tcg_gen_ext32u_tl(t1, t1); 3187 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3188 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3189 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3190 tcg_temp_free(t3); 3191 tcg_temp_free(t2); 3192 } 3193 break; 3194 case R6_OPC_MUL: 3195 { 3196 TCGv_i32 t2 = tcg_temp_new_i32(); 3197 TCGv_i32 t3 = tcg_temp_new_i32(); 3198 tcg_gen_trunc_tl_i32(t2, t0); 3199 tcg_gen_trunc_tl_i32(t3, t1); 3200 tcg_gen_mul_i32(t2, t2, t3); 3201 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3202 tcg_temp_free_i32(t2); 3203 tcg_temp_free_i32(t3); 3204 } 3205 break; 3206 case R6_OPC_MUH: 3207 { 3208 TCGv_i32 t2 = tcg_temp_new_i32(); 3209 TCGv_i32 t3 = tcg_temp_new_i32(); 3210 tcg_gen_trunc_tl_i32(t2, t0); 3211 tcg_gen_trunc_tl_i32(t3, t1); 3212 tcg_gen_muls2_i32(t2, t3, t2, t3); 3213 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3214 tcg_temp_free_i32(t2); 3215 tcg_temp_free_i32(t3); 3216 } 3217 break; 3218 case R6_OPC_MULU: 3219 { 3220 TCGv_i32 t2 = tcg_temp_new_i32(); 3221 TCGv_i32 t3 = tcg_temp_new_i32(); 3222 tcg_gen_trunc_tl_i32(t2, t0); 3223 tcg_gen_trunc_tl_i32(t3, t1); 3224 tcg_gen_mul_i32(t2, t2, t3); 3225 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3226 tcg_temp_free_i32(t2); 3227 tcg_temp_free_i32(t3); 3228 } 3229 break; 3230 case R6_OPC_MUHU: 3231 { 3232 TCGv_i32 t2 = tcg_temp_new_i32(); 3233 TCGv_i32 t3 = tcg_temp_new_i32(); 3234 tcg_gen_trunc_tl_i32(t2, t0); 3235 tcg_gen_trunc_tl_i32(t3, t1); 3236 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3237 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3238 tcg_temp_free_i32(t2); 3239 tcg_temp_free_i32(t3); 3240 } 3241 break; 3242 #if defined(TARGET_MIPS64) 3243 case R6_OPC_DDIV: 3244 { 3245 TCGv t2 = tcg_temp_new(); 3246 TCGv t3 = tcg_temp_new(); 3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3248 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3249 tcg_gen_and_tl(t2, t2, t3); 3250 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3251 tcg_gen_or_tl(t2, t2, t3); 3252 tcg_gen_movi_tl(t3, 0); 3253 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3254 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3255 tcg_temp_free(t3); 3256 tcg_temp_free(t2); 3257 } 3258 break; 3259 case R6_OPC_DMOD: 3260 { 3261 TCGv t2 = tcg_temp_new(); 3262 TCGv t3 = tcg_temp_new(); 3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3265 tcg_gen_and_tl(t2, t2, t3); 3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3267 tcg_gen_or_tl(t2, t2, t3); 3268 tcg_gen_movi_tl(t3, 0); 3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3270 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3271 tcg_temp_free(t3); 3272 tcg_temp_free(t2); 3273 } 3274 break; 3275 case R6_OPC_DDIVU: 3276 { 3277 TCGv t2 = tcg_const_tl(0); 3278 TCGv t3 = tcg_const_tl(1); 3279 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3280 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3281 tcg_temp_free(t3); 3282 tcg_temp_free(t2); 3283 } 3284 break; 3285 case R6_OPC_DMODU: 3286 { 3287 TCGv t2 = tcg_const_tl(0); 3288 TCGv t3 = tcg_const_tl(1); 3289 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3290 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3291 tcg_temp_free(t3); 3292 tcg_temp_free(t2); 3293 } 3294 break; 3295 case R6_OPC_DMUL: 3296 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3297 break; 3298 case R6_OPC_DMUH: 3299 { 3300 TCGv t2 = tcg_temp_new(); 3301 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3302 tcg_temp_free(t2); 3303 } 3304 break; 3305 case R6_OPC_DMULU: 3306 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3307 break; 3308 case R6_OPC_DMUHU: 3309 { 3310 TCGv t2 = tcg_temp_new(); 3311 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3312 tcg_temp_free(t2); 3313 } 3314 break; 3315 #endif 3316 default: 3317 MIPS_INVAL("r6 mul/div"); 3318 gen_reserved_instruction(ctx); 3319 goto out; 3320 } 3321 out: 3322 tcg_temp_free(t0); 3323 tcg_temp_free(t1); 3324 } 3325 3326 #if defined(TARGET_MIPS64) 3327 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3328 { 3329 TCGv t0, t1; 3330 3331 t0 = tcg_temp_new(); 3332 t1 = tcg_temp_new(); 3333 3334 gen_load_gpr(t0, rs); 3335 gen_load_gpr(t1, rt); 3336 3337 switch (opc) { 3338 case MMI_OPC_DIV1: 3339 { 3340 TCGv t2 = tcg_temp_new(); 3341 TCGv t3 = tcg_temp_new(); 3342 tcg_gen_ext32s_tl(t0, t0); 3343 tcg_gen_ext32s_tl(t1, t1); 3344 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3345 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3346 tcg_gen_and_tl(t2, t2, t3); 3347 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3348 tcg_gen_or_tl(t2, t2, t3); 3349 tcg_gen_movi_tl(t3, 0); 3350 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3351 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3352 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3353 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3354 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3355 tcg_temp_free(t3); 3356 tcg_temp_free(t2); 3357 } 3358 break; 3359 case MMI_OPC_DIVU1: 3360 { 3361 TCGv t2 = tcg_const_tl(0); 3362 TCGv t3 = tcg_const_tl(1); 3363 tcg_gen_ext32u_tl(t0, t0); 3364 tcg_gen_ext32u_tl(t1, t1); 3365 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3366 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3367 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3368 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3369 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3370 tcg_temp_free(t3); 3371 tcg_temp_free(t2); 3372 } 3373 break; 3374 default: 3375 MIPS_INVAL("div1 TX79"); 3376 gen_reserved_instruction(ctx); 3377 goto out; 3378 } 3379 out: 3380 tcg_temp_free(t0); 3381 tcg_temp_free(t1); 3382 } 3383 #endif 3384 3385 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3386 int acc, int rs, int rt) 3387 { 3388 TCGv t0, t1; 3389 3390 t0 = tcg_temp_new(); 3391 t1 = tcg_temp_new(); 3392 3393 gen_load_gpr(t0, rs); 3394 gen_load_gpr(t1, rt); 3395 3396 if (acc != 0) { 3397 check_dsp(ctx); 3398 } 3399 3400 switch (opc) { 3401 case OPC_DIV: 3402 { 3403 TCGv t2 = tcg_temp_new(); 3404 TCGv t3 = tcg_temp_new(); 3405 tcg_gen_ext32s_tl(t0, t0); 3406 tcg_gen_ext32s_tl(t1, t1); 3407 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3408 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3409 tcg_gen_and_tl(t2, t2, t3); 3410 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3411 tcg_gen_or_tl(t2, t2, t3); 3412 tcg_gen_movi_tl(t3, 0); 3413 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3414 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3415 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3416 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3417 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3418 tcg_temp_free(t3); 3419 tcg_temp_free(t2); 3420 } 3421 break; 3422 case OPC_DIVU: 3423 { 3424 TCGv t2 = tcg_const_tl(0); 3425 TCGv t3 = tcg_const_tl(1); 3426 tcg_gen_ext32u_tl(t0, t0); 3427 tcg_gen_ext32u_tl(t1, t1); 3428 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3429 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3430 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3431 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3432 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3433 tcg_temp_free(t3); 3434 tcg_temp_free(t2); 3435 } 3436 break; 3437 case OPC_MULT: 3438 { 3439 TCGv_i32 t2 = tcg_temp_new_i32(); 3440 TCGv_i32 t3 = tcg_temp_new_i32(); 3441 tcg_gen_trunc_tl_i32(t2, t0); 3442 tcg_gen_trunc_tl_i32(t3, t1); 3443 tcg_gen_muls2_i32(t2, t3, t2, t3); 3444 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3445 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3446 tcg_temp_free_i32(t2); 3447 tcg_temp_free_i32(t3); 3448 } 3449 break; 3450 case OPC_MULTU: 3451 { 3452 TCGv_i32 t2 = tcg_temp_new_i32(); 3453 TCGv_i32 t3 = tcg_temp_new_i32(); 3454 tcg_gen_trunc_tl_i32(t2, t0); 3455 tcg_gen_trunc_tl_i32(t3, t1); 3456 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3457 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3458 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3459 tcg_temp_free_i32(t2); 3460 tcg_temp_free_i32(t3); 3461 } 3462 break; 3463 #if defined(TARGET_MIPS64) 3464 case OPC_DDIV: 3465 { 3466 TCGv t2 = tcg_temp_new(); 3467 TCGv t3 = tcg_temp_new(); 3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3469 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3470 tcg_gen_and_tl(t2, t2, t3); 3471 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3472 tcg_gen_or_tl(t2, t2, t3); 3473 tcg_gen_movi_tl(t3, 0); 3474 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3475 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3476 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3477 tcg_temp_free(t3); 3478 tcg_temp_free(t2); 3479 } 3480 break; 3481 case OPC_DDIVU: 3482 { 3483 TCGv t2 = tcg_const_tl(0); 3484 TCGv t3 = tcg_const_tl(1); 3485 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3486 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3487 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3488 tcg_temp_free(t3); 3489 tcg_temp_free(t2); 3490 } 3491 break; 3492 case OPC_DMULT: 3493 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3494 break; 3495 case OPC_DMULTU: 3496 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3497 break; 3498 #endif 3499 case OPC_MADD: 3500 { 3501 TCGv_i64 t2 = tcg_temp_new_i64(); 3502 TCGv_i64 t3 = tcg_temp_new_i64(); 3503 3504 tcg_gen_ext_tl_i64(t2, t0); 3505 tcg_gen_ext_tl_i64(t3, t1); 3506 tcg_gen_mul_i64(t2, t2, t3); 3507 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3508 tcg_gen_add_i64(t2, t2, t3); 3509 tcg_temp_free_i64(t3); 3510 gen_move_low32(cpu_LO[acc], t2); 3511 gen_move_high32(cpu_HI[acc], t2); 3512 tcg_temp_free_i64(t2); 3513 } 3514 break; 3515 case OPC_MADDU: 3516 { 3517 TCGv_i64 t2 = tcg_temp_new_i64(); 3518 TCGv_i64 t3 = tcg_temp_new_i64(); 3519 3520 tcg_gen_ext32u_tl(t0, t0); 3521 tcg_gen_ext32u_tl(t1, t1); 3522 tcg_gen_extu_tl_i64(t2, t0); 3523 tcg_gen_extu_tl_i64(t3, t1); 3524 tcg_gen_mul_i64(t2, t2, t3); 3525 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3526 tcg_gen_add_i64(t2, t2, t3); 3527 tcg_temp_free_i64(t3); 3528 gen_move_low32(cpu_LO[acc], t2); 3529 gen_move_high32(cpu_HI[acc], t2); 3530 tcg_temp_free_i64(t2); 3531 } 3532 break; 3533 case OPC_MSUB: 3534 { 3535 TCGv_i64 t2 = tcg_temp_new_i64(); 3536 TCGv_i64 t3 = tcg_temp_new_i64(); 3537 3538 tcg_gen_ext_tl_i64(t2, t0); 3539 tcg_gen_ext_tl_i64(t3, t1); 3540 tcg_gen_mul_i64(t2, t2, t3); 3541 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3542 tcg_gen_sub_i64(t2, t3, t2); 3543 tcg_temp_free_i64(t3); 3544 gen_move_low32(cpu_LO[acc], t2); 3545 gen_move_high32(cpu_HI[acc], t2); 3546 tcg_temp_free_i64(t2); 3547 } 3548 break; 3549 case OPC_MSUBU: 3550 { 3551 TCGv_i64 t2 = tcg_temp_new_i64(); 3552 TCGv_i64 t3 = tcg_temp_new_i64(); 3553 3554 tcg_gen_ext32u_tl(t0, t0); 3555 tcg_gen_ext32u_tl(t1, t1); 3556 tcg_gen_extu_tl_i64(t2, t0); 3557 tcg_gen_extu_tl_i64(t3, t1); 3558 tcg_gen_mul_i64(t2, t2, t3); 3559 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3560 tcg_gen_sub_i64(t2, t3, t2); 3561 tcg_temp_free_i64(t3); 3562 gen_move_low32(cpu_LO[acc], t2); 3563 gen_move_high32(cpu_HI[acc], t2); 3564 tcg_temp_free_i64(t2); 3565 } 3566 break; 3567 default: 3568 MIPS_INVAL("mul/div"); 3569 gen_reserved_instruction(ctx); 3570 goto out; 3571 } 3572 out: 3573 tcg_temp_free(t0); 3574 tcg_temp_free(t1); 3575 } 3576 3577 /* 3578 * These MULT[U] and MADD[U] instructions implemented in for example 3579 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3580 * architectures are special three-operand variants with the syntax 3581 * 3582 * MULT[U][1] rd, rs, rt 3583 * 3584 * such that 3585 * 3586 * (rd, LO, HI) <- rs * rt 3587 * 3588 * and 3589 * 3590 * MADD[U][1] rd, rs, rt 3591 * 3592 * such that 3593 * 3594 * (rd, LO, HI) <- (LO, HI) + rs * rt 3595 * 3596 * where the low-order 32-bits of the result is placed into both the 3597 * GPR rd and the special register LO. The high-order 32-bits of the 3598 * result is placed into the special register HI. 3599 * 3600 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3601 * which is the zero register that always reads as 0. 3602 */ 3603 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3604 int rd, int rs, int rt) 3605 { 3606 TCGv t0 = tcg_temp_new(); 3607 TCGv t1 = tcg_temp_new(); 3608 int acc = 0; 3609 3610 gen_load_gpr(t0, rs); 3611 gen_load_gpr(t1, rt); 3612 3613 switch (opc) { 3614 case MMI_OPC_MULT1: 3615 acc = 1; 3616 /* Fall through */ 3617 case OPC_MULT: 3618 { 3619 TCGv_i32 t2 = tcg_temp_new_i32(); 3620 TCGv_i32 t3 = tcg_temp_new_i32(); 3621 tcg_gen_trunc_tl_i32(t2, t0); 3622 tcg_gen_trunc_tl_i32(t3, t1); 3623 tcg_gen_muls2_i32(t2, t3, t2, t3); 3624 if (rd) { 3625 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3626 } 3627 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3628 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3629 tcg_temp_free_i32(t2); 3630 tcg_temp_free_i32(t3); 3631 } 3632 break; 3633 case MMI_OPC_MULTU1: 3634 acc = 1; 3635 /* Fall through */ 3636 case OPC_MULTU: 3637 { 3638 TCGv_i32 t2 = tcg_temp_new_i32(); 3639 TCGv_i32 t3 = tcg_temp_new_i32(); 3640 tcg_gen_trunc_tl_i32(t2, t0); 3641 tcg_gen_trunc_tl_i32(t3, t1); 3642 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3643 if (rd) { 3644 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3645 } 3646 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3647 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3648 tcg_temp_free_i32(t2); 3649 tcg_temp_free_i32(t3); 3650 } 3651 break; 3652 case MMI_OPC_MADD1: 3653 acc = 1; 3654 /* Fall through */ 3655 case MMI_OPC_MADD: 3656 { 3657 TCGv_i64 t2 = tcg_temp_new_i64(); 3658 TCGv_i64 t3 = tcg_temp_new_i64(); 3659 3660 tcg_gen_ext_tl_i64(t2, t0); 3661 tcg_gen_ext_tl_i64(t3, t1); 3662 tcg_gen_mul_i64(t2, t2, t3); 3663 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3664 tcg_gen_add_i64(t2, t2, t3); 3665 tcg_temp_free_i64(t3); 3666 gen_move_low32(cpu_LO[acc], t2); 3667 gen_move_high32(cpu_HI[acc], t2); 3668 if (rd) { 3669 gen_move_low32(cpu_gpr[rd], t2); 3670 } 3671 tcg_temp_free_i64(t2); 3672 } 3673 break; 3674 case MMI_OPC_MADDU1: 3675 acc = 1; 3676 /* Fall through */ 3677 case MMI_OPC_MADDU: 3678 { 3679 TCGv_i64 t2 = tcg_temp_new_i64(); 3680 TCGv_i64 t3 = tcg_temp_new_i64(); 3681 3682 tcg_gen_ext32u_tl(t0, t0); 3683 tcg_gen_ext32u_tl(t1, t1); 3684 tcg_gen_extu_tl_i64(t2, t0); 3685 tcg_gen_extu_tl_i64(t3, t1); 3686 tcg_gen_mul_i64(t2, t2, t3); 3687 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3688 tcg_gen_add_i64(t2, t2, t3); 3689 tcg_temp_free_i64(t3); 3690 gen_move_low32(cpu_LO[acc], t2); 3691 gen_move_high32(cpu_HI[acc], t2); 3692 if (rd) { 3693 gen_move_low32(cpu_gpr[rd], t2); 3694 } 3695 tcg_temp_free_i64(t2); 3696 } 3697 break; 3698 default: 3699 MIPS_INVAL("mul/madd TXx9"); 3700 gen_reserved_instruction(ctx); 3701 goto out; 3702 } 3703 3704 out: 3705 tcg_temp_free(t0); 3706 tcg_temp_free(t1); 3707 } 3708 3709 static void gen_cl(DisasContext *ctx, uint32_t opc, 3710 int rd, int rs) 3711 { 3712 TCGv t0; 3713 3714 if (rd == 0) { 3715 /* Treat as NOP. */ 3716 return; 3717 } 3718 t0 = cpu_gpr[rd]; 3719 gen_load_gpr(t0, rs); 3720 3721 switch (opc) { 3722 case OPC_CLO: 3723 case R6_OPC_CLO: 3724 #if defined(TARGET_MIPS64) 3725 case OPC_DCLO: 3726 case R6_OPC_DCLO: 3727 #endif 3728 tcg_gen_not_tl(t0, t0); 3729 break; 3730 } 3731 3732 switch (opc) { 3733 case OPC_CLO: 3734 case R6_OPC_CLO: 3735 case OPC_CLZ: 3736 case R6_OPC_CLZ: 3737 tcg_gen_ext32u_tl(t0, t0); 3738 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3739 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3740 break; 3741 #if defined(TARGET_MIPS64) 3742 case OPC_DCLO: 3743 case R6_OPC_DCLO: 3744 case OPC_DCLZ: 3745 case R6_OPC_DCLZ: 3746 tcg_gen_clzi_i64(t0, t0, 64); 3747 break; 3748 #endif 3749 } 3750 } 3751 3752 /* Godson integer instructions */ 3753 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3754 int rd, int rs, int rt) 3755 { 3756 TCGv t0, t1; 3757 3758 if (rd == 0) { 3759 /* Treat as NOP. */ 3760 return; 3761 } 3762 3763 switch (opc) { 3764 case OPC_MULT_G_2E: 3765 case OPC_MULT_G_2F: 3766 case OPC_MULTU_G_2E: 3767 case OPC_MULTU_G_2F: 3768 #if defined(TARGET_MIPS64) 3769 case OPC_DMULT_G_2E: 3770 case OPC_DMULT_G_2F: 3771 case OPC_DMULTU_G_2E: 3772 case OPC_DMULTU_G_2F: 3773 #endif 3774 t0 = tcg_temp_new(); 3775 t1 = tcg_temp_new(); 3776 break; 3777 default: 3778 t0 = tcg_temp_local_new(); 3779 t1 = tcg_temp_local_new(); 3780 break; 3781 } 3782 3783 gen_load_gpr(t0, rs); 3784 gen_load_gpr(t1, rt); 3785 3786 switch (opc) { 3787 case OPC_MULT_G_2E: 3788 case OPC_MULT_G_2F: 3789 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3790 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3791 break; 3792 case OPC_MULTU_G_2E: 3793 case OPC_MULTU_G_2F: 3794 tcg_gen_ext32u_tl(t0, t0); 3795 tcg_gen_ext32u_tl(t1, t1); 3796 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3797 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3798 break; 3799 case OPC_DIV_G_2E: 3800 case OPC_DIV_G_2F: 3801 { 3802 TCGLabel *l1 = gen_new_label(); 3803 TCGLabel *l2 = gen_new_label(); 3804 TCGLabel *l3 = gen_new_label(); 3805 tcg_gen_ext32s_tl(t0, t0); 3806 tcg_gen_ext32s_tl(t1, t1); 3807 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3808 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3809 tcg_gen_br(l3); 3810 gen_set_label(l1); 3811 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3812 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3813 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3814 tcg_gen_br(l3); 3815 gen_set_label(l2); 3816 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3817 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3818 gen_set_label(l3); 3819 } 3820 break; 3821 case OPC_DIVU_G_2E: 3822 case OPC_DIVU_G_2F: 3823 { 3824 TCGLabel *l1 = gen_new_label(); 3825 TCGLabel *l2 = gen_new_label(); 3826 tcg_gen_ext32u_tl(t0, t0); 3827 tcg_gen_ext32u_tl(t1, t1); 3828 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3829 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3830 tcg_gen_br(l2); 3831 gen_set_label(l1); 3832 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3833 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3834 gen_set_label(l2); 3835 } 3836 break; 3837 case OPC_MOD_G_2E: 3838 case OPC_MOD_G_2F: 3839 { 3840 TCGLabel *l1 = gen_new_label(); 3841 TCGLabel *l2 = gen_new_label(); 3842 TCGLabel *l3 = gen_new_label(); 3843 tcg_gen_ext32u_tl(t0, t0); 3844 tcg_gen_ext32u_tl(t1, t1); 3845 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3846 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3847 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3848 gen_set_label(l1); 3849 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3850 tcg_gen_br(l3); 3851 gen_set_label(l2); 3852 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3853 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3854 gen_set_label(l3); 3855 } 3856 break; 3857 case OPC_MODU_G_2E: 3858 case OPC_MODU_G_2F: 3859 { 3860 TCGLabel *l1 = gen_new_label(); 3861 TCGLabel *l2 = gen_new_label(); 3862 tcg_gen_ext32u_tl(t0, t0); 3863 tcg_gen_ext32u_tl(t1, t1); 3864 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3865 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3866 tcg_gen_br(l2); 3867 gen_set_label(l1); 3868 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3869 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3870 gen_set_label(l2); 3871 } 3872 break; 3873 #if defined(TARGET_MIPS64) 3874 case OPC_DMULT_G_2E: 3875 case OPC_DMULT_G_2F: 3876 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3877 break; 3878 case OPC_DMULTU_G_2E: 3879 case OPC_DMULTU_G_2F: 3880 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3881 break; 3882 case OPC_DDIV_G_2E: 3883 case OPC_DDIV_G_2F: 3884 { 3885 TCGLabel *l1 = gen_new_label(); 3886 TCGLabel *l2 = gen_new_label(); 3887 TCGLabel *l3 = gen_new_label(); 3888 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3889 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3890 tcg_gen_br(l3); 3891 gen_set_label(l1); 3892 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3893 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3894 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3895 tcg_gen_br(l3); 3896 gen_set_label(l2); 3897 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3898 gen_set_label(l3); 3899 } 3900 break; 3901 case OPC_DDIVU_G_2E: 3902 case OPC_DDIVU_G_2F: 3903 { 3904 TCGLabel *l1 = gen_new_label(); 3905 TCGLabel *l2 = gen_new_label(); 3906 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3907 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3908 tcg_gen_br(l2); 3909 gen_set_label(l1); 3910 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3911 gen_set_label(l2); 3912 } 3913 break; 3914 case OPC_DMOD_G_2E: 3915 case OPC_DMOD_G_2F: 3916 { 3917 TCGLabel *l1 = gen_new_label(); 3918 TCGLabel *l2 = gen_new_label(); 3919 TCGLabel *l3 = gen_new_label(); 3920 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3921 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 3922 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 3923 gen_set_label(l1); 3924 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3925 tcg_gen_br(l3); 3926 gen_set_label(l2); 3927 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3928 gen_set_label(l3); 3929 } 3930 break; 3931 case OPC_DMODU_G_2E: 3932 case OPC_DMODU_G_2F: 3933 { 3934 TCGLabel *l1 = gen_new_label(); 3935 TCGLabel *l2 = gen_new_label(); 3936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3937 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3938 tcg_gen_br(l2); 3939 gen_set_label(l1); 3940 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3941 gen_set_label(l2); 3942 } 3943 break; 3944 #endif 3945 } 3946 3947 tcg_temp_free(t0); 3948 tcg_temp_free(t1); 3949 } 3950 3951 /* Loongson multimedia instructions */ 3952 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3953 { 3954 uint32_t opc, shift_max; 3955 TCGv_i64 t0, t1; 3956 TCGCond cond; 3957 3958 opc = MASK_LMMI(ctx->opcode); 3959 switch (opc) { 3960 case OPC_ADD_CP2: 3961 case OPC_SUB_CP2: 3962 case OPC_DADD_CP2: 3963 case OPC_DSUB_CP2: 3964 t0 = tcg_temp_local_new_i64(); 3965 t1 = tcg_temp_local_new_i64(); 3966 break; 3967 default: 3968 t0 = tcg_temp_new_i64(); 3969 t1 = tcg_temp_new_i64(); 3970 break; 3971 } 3972 3973 check_cp1_enabled(ctx); 3974 gen_load_fpr64(ctx, t0, rs); 3975 gen_load_fpr64(ctx, t1, rt); 3976 3977 switch (opc) { 3978 case OPC_PADDSH: 3979 gen_helper_paddsh(t0, t0, t1); 3980 break; 3981 case OPC_PADDUSH: 3982 gen_helper_paddush(t0, t0, t1); 3983 break; 3984 case OPC_PADDH: 3985 gen_helper_paddh(t0, t0, t1); 3986 break; 3987 case OPC_PADDW: 3988 gen_helper_paddw(t0, t0, t1); 3989 break; 3990 case OPC_PADDSB: 3991 gen_helper_paddsb(t0, t0, t1); 3992 break; 3993 case OPC_PADDUSB: 3994 gen_helper_paddusb(t0, t0, t1); 3995 break; 3996 case OPC_PADDB: 3997 gen_helper_paddb(t0, t0, t1); 3998 break; 3999 4000 case OPC_PSUBSH: 4001 gen_helper_psubsh(t0, t0, t1); 4002 break; 4003 case OPC_PSUBUSH: 4004 gen_helper_psubush(t0, t0, t1); 4005 break; 4006 case OPC_PSUBH: 4007 gen_helper_psubh(t0, t0, t1); 4008 break; 4009 case OPC_PSUBW: 4010 gen_helper_psubw(t0, t0, t1); 4011 break; 4012 case OPC_PSUBSB: 4013 gen_helper_psubsb(t0, t0, t1); 4014 break; 4015 case OPC_PSUBUSB: 4016 gen_helper_psubusb(t0, t0, t1); 4017 break; 4018 case OPC_PSUBB: 4019 gen_helper_psubb(t0, t0, t1); 4020 break; 4021 4022 case OPC_PSHUFH: 4023 gen_helper_pshufh(t0, t0, t1); 4024 break; 4025 case OPC_PACKSSWH: 4026 gen_helper_packsswh(t0, t0, t1); 4027 break; 4028 case OPC_PACKSSHB: 4029 gen_helper_packsshb(t0, t0, t1); 4030 break; 4031 case OPC_PACKUSHB: 4032 gen_helper_packushb(t0, t0, t1); 4033 break; 4034 4035 case OPC_PUNPCKLHW: 4036 gen_helper_punpcklhw(t0, t0, t1); 4037 break; 4038 case OPC_PUNPCKHHW: 4039 gen_helper_punpckhhw(t0, t0, t1); 4040 break; 4041 case OPC_PUNPCKLBH: 4042 gen_helper_punpcklbh(t0, t0, t1); 4043 break; 4044 case OPC_PUNPCKHBH: 4045 gen_helper_punpckhbh(t0, t0, t1); 4046 break; 4047 case OPC_PUNPCKLWD: 4048 gen_helper_punpcklwd(t0, t0, t1); 4049 break; 4050 case OPC_PUNPCKHWD: 4051 gen_helper_punpckhwd(t0, t0, t1); 4052 break; 4053 4054 case OPC_PAVGH: 4055 gen_helper_pavgh(t0, t0, t1); 4056 break; 4057 case OPC_PAVGB: 4058 gen_helper_pavgb(t0, t0, t1); 4059 break; 4060 case OPC_PMAXSH: 4061 gen_helper_pmaxsh(t0, t0, t1); 4062 break; 4063 case OPC_PMINSH: 4064 gen_helper_pminsh(t0, t0, t1); 4065 break; 4066 case OPC_PMAXUB: 4067 gen_helper_pmaxub(t0, t0, t1); 4068 break; 4069 case OPC_PMINUB: 4070 gen_helper_pminub(t0, t0, t1); 4071 break; 4072 4073 case OPC_PCMPEQW: 4074 gen_helper_pcmpeqw(t0, t0, t1); 4075 break; 4076 case OPC_PCMPGTW: 4077 gen_helper_pcmpgtw(t0, t0, t1); 4078 break; 4079 case OPC_PCMPEQH: 4080 gen_helper_pcmpeqh(t0, t0, t1); 4081 break; 4082 case OPC_PCMPGTH: 4083 gen_helper_pcmpgth(t0, t0, t1); 4084 break; 4085 case OPC_PCMPEQB: 4086 gen_helper_pcmpeqb(t0, t0, t1); 4087 break; 4088 case OPC_PCMPGTB: 4089 gen_helper_pcmpgtb(t0, t0, t1); 4090 break; 4091 4092 case OPC_PSLLW: 4093 gen_helper_psllw(t0, t0, t1); 4094 break; 4095 case OPC_PSLLH: 4096 gen_helper_psllh(t0, t0, t1); 4097 break; 4098 case OPC_PSRLW: 4099 gen_helper_psrlw(t0, t0, t1); 4100 break; 4101 case OPC_PSRLH: 4102 gen_helper_psrlh(t0, t0, t1); 4103 break; 4104 case OPC_PSRAW: 4105 gen_helper_psraw(t0, t0, t1); 4106 break; 4107 case OPC_PSRAH: 4108 gen_helper_psrah(t0, t0, t1); 4109 break; 4110 4111 case OPC_PMULLH: 4112 gen_helper_pmullh(t0, t0, t1); 4113 break; 4114 case OPC_PMULHH: 4115 gen_helper_pmulhh(t0, t0, t1); 4116 break; 4117 case OPC_PMULHUH: 4118 gen_helper_pmulhuh(t0, t0, t1); 4119 break; 4120 case OPC_PMADDHW: 4121 gen_helper_pmaddhw(t0, t0, t1); 4122 break; 4123 4124 case OPC_PASUBUB: 4125 gen_helper_pasubub(t0, t0, t1); 4126 break; 4127 case OPC_BIADD: 4128 gen_helper_biadd(t0, t0); 4129 break; 4130 case OPC_PMOVMSKB: 4131 gen_helper_pmovmskb(t0, t0); 4132 break; 4133 4134 case OPC_PADDD: 4135 tcg_gen_add_i64(t0, t0, t1); 4136 break; 4137 case OPC_PSUBD: 4138 tcg_gen_sub_i64(t0, t0, t1); 4139 break; 4140 case OPC_XOR_CP2: 4141 tcg_gen_xor_i64(t0, t0, t1); 4142 break; 4143 case OPC_NOR_CP2: 4144 tcg_gen_nor_i64(t0, t0, t1); 4145 break; 4146 case OPC_AND_CP2: 4147 tcg_gen_and_i64(t0, t0, t1); 4148 break; 4149 case OPC_OR_CP2: 4150 tcg_gen_or_i64(t0, t0, t1); 4151 break; 4152 4153 case OPC_PANDN: 4154 tcg_gen_andc_i64(t0, t1, t0); 4155 break; 4156 4157 case OPC_PINSRH_0: 4158 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4159 break; 4160 case OPC_PINSRH_1: 4161 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4162 break; 4163 case OPC_PINSRH_2: 4164 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4165 break; 4166 case OPC_PINSRH_3: 4167 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4168 break; 4169 4170 case OPC_PEXTRH: 4171 tcg_gen_andi_i64(t1, t1, 3); 4172 tcg_gen_shli_i64(t1, t1, 4); 4173 tcg_gen_shr_i64(t0, t0, t1); 4174 tcg_gen_ext16u_i64(t0, t0); 4175 break; 4176 4177 case OPC_ADDU_CP2: 4178 tcg_gen_add_i64(t0, t0, t1); 4179 tcg_gen_ext32s_i64(t0, t0); 4180 break; 4181 case OPC_SUBU_CP2: 4182 tcg_gen_sub_i64(t0, t0, t1); 4183 tcg_gen_ext32s_i64(t0, t0); 4184 break; 4185 4186 case OPC_SLL_CP2: 4187 shift_max = 32; 4188 goto do_shift; 4189 case OPC_SRL_CP2: 4190 shift_max = 32; 4191 goto do_shift; 4192 case OPC_SRA_CP2: 4193 shift_max = 32; 4194 goto do_shift; 4195 case OPC_DSLL_CP2: 4196 shift_max = 64; 4197 goto do_shift; 4198 case OPC_DSRL_CP2: 4199 shift_max = 64; 4200 goto do_shift; 4201 case OPC_DSRA_CP2: 4202 shift_max = 64; 4203 goto do_shift; 4204 do_shift: 4205 /* Make sure shift count isn't TCG undefined behaviour. */ 4206 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4207 4208 switch (opc) { 4209 case OPC_SLL_CP2: 4210 case OPC_DSLL_CP2: 4211 tcg_gen_shl_i64(t0, t0, t1); 4212 break; 4213 case OPC_SRA_CP2: 4214 case OPC_DSRA_CP2: 4215 /* 4216 * Since SRA is UndefinedResult without sign-extended inputs, 4217 * we can treat SRA and DSRA the same. 4218 */ 4219 tcg_gen_sar_i64(t0, t0, t1); 4220 break; 4221 case OPC_SRL_CP2: 4222 /* We want to shift in zeros for SRL; zero-extend first. */ 4223 tcg_gen_ext32u_i64(t0, t0); 4224 /* FALLTHRU */ 4225 case OPC_DSRL_CP2: 4226 tcg_gen_shr_i64(t0, t0, t1); 4227 break; 4228 } 4229 4230 if (shift_max == 32) { 4231 tcg_gen_ext32s_i64(t0, t0); 4232 } 4233 4234 /* Shifts larger than MAX produce zero. */ 4235 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4236 tcg_gen_neg_i64(t1, t1); 4237 tcg_gen_and_i64(t0, t0, t1); 4238 break; 4239 4240 case OPC_ADD_CP2: 4241 case OPC_DADD_CP2: 4242 { 4243 TCGv_i64 t2 = tcg_temp_new_i64(); 4244 TCGLabel *lab = gen_new_label(); 4245 4246 tcg_gen_mov_i64(t2, t0); 4247 tcg_gen_add_i64(t0, t1, t2); 4248 if (opc == OPC_ADD_CP2) { 4249 tcg_gen_ext32s_i64(t0, t0); 4250 } 4251 tcg_gen_xor_i64(t1, t1, t2); 4252 tcg_gen_xor_i64(t2, t2, t0); 4253 tcg_gen_andc_i64(t1, t2, t1); 4254 tcg_temp_free_i64(t2); 4255 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4256 generate_exception(ctx, EXCP_OVERFLOW); 4257 gen_set_label(lab); 4258 break; 4259 } 4260 4261 case OPC_SUB_CP2: 4262 case OPC_DSUB_CP2: 4263 { 4264 TCGv_i64 t2 = tcg_temp_new_i64(); 4265 TCGLabel *lab = gen_new_label(); 4266 4267 tcg_gen_mov_i64(t2, t0); 4268 tcg_gen_sub_i64(t0, t1, t2); 4269 if (opc == OPC_SUB_CP2) { 4270 tcg_gen_ext32s_i64(t0, t0); 4271 } 4272 tcg_gen_xor_i64(t1, t1, t2); 4273 tcg_gen_xor_i64(t2, t2, t0); 4274 tcg_gen_and_i64(t1, t1, t2); 4275 tcg_temp_free_i64(t2); 4276 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4277 generate_exception(ctx, EXCP_OVERFLOW); 4278 gen_set_label(lab); 4279 break; 4280 } 4281 4282 case OPC_PMULUW: 4283 tcg_gen_ext32u_i64(t0, t0); 4284 tcg_gen_ext32u_i64(t1, t1); 4285 tcg_gen_mul_i64(t0, t0, t1); 4286 break; 4287 4288 case OPC_SEQU_CP2: 4289 case OPC_SEQ_CP2: 4290 cond = TCG_COND_EQ; 4291 goto do_cc_cond; 4292 break; 4293 case OPC_SLTU_CP2: 4294 cond = TCG_COND_LTU; 4295 goto do_cc_cond; 4296 break; 4297 case OPC_SLT_CP2: 4298 cond = TCG_COND_LT; 4299 goto do_cc_cond; 4300 break; 4301 case OPC_SLEU_CP2: 4302 cond = TCG_COND_LEU; 4303 goto do_cc_cond; 4304 break; 4305 case OPC_SLE_CP2: 4306 cond = TCG_COND_LE; 4307 do_cc_cond: 4308 { 4309 int cc = (ctx->opcode >> 8) & 0x7; 4310 TCGv_i64 t64 = tcg_temp_new_i64(); 4311 TCGv_i32 t32 = tcg_temp_new_i32(); 4312 4313 tcg_gen_setcond_i64(cond, t64, t0, t1); 4314 tcg_gen_extrl_i64_i32(t32, t64); 4315 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4316 get_fp_bit(cc), 1); 4317 4318 tcg_temp_free_i32(t32); 4319 tcg_temp_free_i64(t64); 4320 } 4321 goto no_rd; 4322 break; 4323 default: 4324 MIPS_INVAL("loongson_cp2"); 4325 gen_reserved_instruction(ctx); 4326 return; 4327 } 4328 4329 gen_store_fpr64(ctx, t0, rd); 4330 4331 no_rd: 4332 tcg_temp_free_i64(t0); 4333 tcg_temp_free_i64(t1); 4334 } 4335 4336 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4337 int rs, int rd) 4338 { 4339 TCGv t0, t1, t2; 4340 TCGv_i32 fp0; 4341 #if defined(TARGET_MIPS64) 4342 int lsq_rt1 = ctx->opcode & 0x1f; 4343 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4344 #endif 4345 int shf_offset = sextract32(ctx->opcode, 6, 8); 4346 4347 t0 = tcg_temp_new(); 4348 4349 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4350 #if defined(TARGET_MIPS64) 4351 case OPC_GSLQ: 4352 t1 = tcg_temp_new(); 4353 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4354 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4355 ctx->default_tcg_memop_mask); 4356 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4357 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4358 ctx->default_tcg_memop_mask); 4359 gen_store_gpr(t1, rt); 4360 gen_store_gpr(t0, lsq_rt1); 4361 tcg_temp_free(t1); 4362 break; 4363 case OPC_GSLQC1: 4364 check_cp1_enabled(ctx); 4365 t1 = tcg_temp_new(); 4366 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4367 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4368 ctx->default_tcg_memop_mask); 4369 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4370 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4371 ctx->default_tcg_memop_mask); 4372 gen_store_fpr64(ctx, t1, rt); 4373 gen_store_fpr64(ctx, t0, lsq_rt1); 4374 tcg_temp_free(t1); 4375 break; 4376 case OPC_GSSQ: 4377 t1 = tcg_temp_new(); 4378 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4379 gen_load_gpr(t1, rt); 4380 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4381 ctx->default_tcg_memop_mask); 4382 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4383 gen_load_gpr(t1, lsq_rt1); 4384 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4385 ctx->default_tcg_memop_mask); 4386 tcg_temp_free(t1); 4387 break; 4388 case OPC_GSSQC1: 4389 check_cp1_enabled(ctx); 4390 t1 = tcg_temp_new(); 4391 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4392 gen_load_fpr64(ctx, t1, rt); 4393 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4394 ctx->default_tcg_memop_mask); 4395 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4396 gen_load_fpr64(ctx, t1, lsq_rt1); 4397 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4398 ctx->default_tcg_memop_mask); 4399 tcg_temp_free(t1); 4400 break; 4401 #endif 4402 case OPC_GSSHFL: 4403 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4404 case OPC_GSLWLC1: 4405 check_cp1_enabled(ctx); 4406 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4407 t1 = tcg_temp_new(); 4408 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4409 tcg_gen_andi_tl(t1, t0, 3); 4410 if (!cpu_is_bigendian(ctx)) { 4411 tcg_gen_xori_tl(t1, t1, 3); 4412 } 4413 tcg_gen_shli_tl(t1, t1, 3); 4414 tcg_gen_andi_tl(t0, t0, ~3); 4415 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4416 tcg_gen_shl_tl(t0, t0, t1); 4417 t2 = tcg_const_tl(-1); 4418 tcg_gen_shl_tl(t2, t2, t1); 4419 fp0 = tcg_temp_new_i32(); 4420 gen_load_fpr32(ctx, fp0, rt); 4421 tcg_gen_ext_i32_tl(t1, fp0); 4422 tcg_gen_andc_tl(t1, t1, t2); 4423 tcg_temp_free(t2); 4424 tcg_gen_or_tl(t0, t0, t1); 4425 tcg_temp_free(t1); 4426 #if defined(TARGET_MIPS64) 4427 tcg_gen_extrl_i64_i32(fp0, t0); 4428 #else 4429 tcg_gen_ext32s_tl(fp0, t0); 4430 #endif 4431 gen_store_fpr32(ctx, fp0, rt); 4432 tcg_temp_free_i32(fp0); 4433 break; 4434 case OPC_GSLWRC1: 4435 check_cp1_enabled(ctx); 4436 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4437 t1 = tcg_temp_new(); 4438 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4439 tcg_gen_andi_tl(t1, t0, 3); 4440 if (cpu_is_bigendian(ctx)) { 4441 tcg_gen_xori_tl(t1, t1, 3); 4442 } 4443 tcg_gen_shli_tl(t1, t1, 3); 4444 tcg_gen_andi_tl(t0, t0, ~3); 4445 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4446 tcg_gen_shr_tl(t0, t0, t1); 4447 tcg_gen_xori_tl(t1, t1, 31); 4448 t2 = tcg_const_tl(0xfffffffeull); 4449 tcg_gen_shl_tl(t2, t2, t1); 4450 fp0 = tcg_temp_new_i32(); 4451 gen_load_fpr32(ctx, fp0, rt); 4452 tcg_gen_ext_i32_tl(t1, fp0); 4453 tcg_gen_and_tl(t1, t1, t2); 4454 tcg_temp_free(t2); 4455 tcg_gen_or_tl(t0, t0, t1); 4456 tcg_temp_free(t1); 4457 #if defined(TARGET_MIPS64) 4458 tcg_gen_extrl_i64_i32(fp0, t0); 4459 #else 4460 tcg_gen_ext32s_tl(fp0, t0); 4461 #endif 4462 gen_store_fpr32(ctx, fp0, rt); 4463 tcg_temp_free_i32(fp0); 4464 break; 4465 #if defined(TARGET_MIPS64) 4466 case OPC_GSLDLC1: 4467 check_cp1_enabled(ctx); 4468 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4469 t1 = tcg_temp_new(); 4470 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4471 tcg_gen_andi_tl(t1, t0, 7); 4472 if (!cpu_is_bigendian(ctx)) { 4473 tcg_gen_xori_tl(t1, t1, 7); 4474 } 4475 tcg_gen_shli_tl(t1, t1, 3); 4476 tcg_gen_andi_tl(t0, t0, ~7); 4477 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 4478 tcg_gen_shl_tl(t0, t0, t1); 4479 t2 = tcg_const_tl(-1); 4480 tcg_gen_shl_tl(t2, t2, t1); 4481 gen_load_fpr64(ctx, t1, rt); 4482 tcg_gen_andc_tl(t1, t1, t2); 4483 tcg_temp_free(t2); 4484 tcg_gen_or_tl(t0, t0, t1); 4485 tcg_temp_free(t1); 4486 gen_store_fpr64(ctx, t0, rt); 4487 break; 4488 case OPC_GSLDRC1: 4489 check_cp1_enabled(ctx); 4490 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4491 t1 = tcg_temp_new(); 4492 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4493 tcg_gen_andi_tl(t1, t0, 7); 4494 if (cpu_is_bigendian(ctx)) { 4495 tcg_gen_xori_tl(t1, t1, 7); 4496 } 4497 tcg_gen_shli_tl(t1, t1, 3); 4498 tcg_gen_andi_tl(t0, t0, ~7); 4499 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 4500 tcg_gen_shr_tl(t0, t0, t1); 4501 tcg_gen_xori_tl(t1, t1, 63); 4502 t2 = tcg_const_tl(0xfffffffffffffffeull); 4503 tcg_gen_shl_tl(t2, t2, t1); 4504 gen_load_fpr64(ctx, t1, rt); 4505 tcg_gen_and_tl(t1, t1, t2); 4506 tcg_temp_free(t2); 4507 tcg_gen_or_tl(t0, t0, t1); 4508 tcg_temp_free(t1); 4509 gen_store_fpr64(ctx, t0, rt); 4510 break; 4511 #endif 4512 default: 4513 MIPS_INVAL("loongson_gsshfl"); 4514 gen_reserved_instruction(ctx); 4515 break; 4516 } 4517 break; 4518 case OPC_GSSHFS: 4519 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4520 case OPC_GSSWLC1: 4521 check_cp1_enabled(ctx); 4522 t1 = tcg_temp_new(); 4523 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4524 fp0 = tcg_temp_new_i32(); 4525 gen_load_fpr32(ctx, fp0, rt); 4526 tcg_gen_ext_i32_tl(t1, fp0); 4527 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4528 tcg_temp_free_i32(fp0); 4529 tcg_temp_free(t1); 4530 break; 4531 case OPC_GSSWRC1: 4532 check_cp1_enabled(ctx); 4533 t1 = tcg_temp_new(); 4534 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4535 fp0 = tcg_temp_new_i32(); 4536 gen_load_fpr32(ctx, fp0, rt); 4537 tcg_gen_ext_i32_tl(t1, fp0); 4538 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4539 tcg_temp_free_i32(fp0); 4540 tcg_temp_free(t1); 4541 break; 4542 #if defined(TARGET_MIPS64) 4543 case OPC_GSSDLC1: 4544 check_cp1_enabled(ctx); 4545 t1 = tcg_temp_new(); 4546 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4547 gen_load_fpr64(ctx, t1, rt); 4548 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4549 tcg_temp_free(t1); 4550 break; 4551 case OPC_GSSDRC1: 4552 check_cp1_enabled(ctx); 4553 t1 = tcg_temp_new(); 4554 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4555 gen_load_fpr64(ctx, t1, rt); 4556 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4557 tcg_temp_free(t1); 4558 break; 4559 #endif 4560 default: 4561 MIPS_INVAL("loongson_gsshfs"); 4562 gen_reserved_instruction(ctx); 4563 break; 4564 } 4565 break; 4566 default: 4567 MIPS_INVAL("loongson_gslsq"); 4568 gen_reserved_instruction(ctx); 4569 break; 4570 } 4571 tcg_temp_free(t0); 4572 } 4573 4574 /* Loongson EXT LDC2/SDC2 */ 4575 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4576 int rs, int rd) 4577 { 4578 int offset = sextract32(ctx->opcode, 3, 8); 4579 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4580 TCGv t0, t1; 4581 TCGv_i32 fp0; 4582 4583 /* Pre-conditions */ 4584 switch (opc) { 4585 case OPC_GSLBX: 4586 case OPC_GSLHX: 4587 case OPC_GSLWX: 4588 case OPC_GSLDX: 4589 /* prefetch, implement as NOP */ 4590 if (rt == 0) { 4591 return; 4592 } 4593 break; 4594 case OPC_GSSBX: 4595 case OPC_GSSHX: 4596 case OPC_GSSWX: 4597 case OPC_GSSDX: 4598 break; 4599 case OPC_GSLWXC1: 4600 #if defined(TARGET_MIPS64) 4601 case OPC_GSLDXC1: 4602 #endif 4603 check_cp1_enabled(ctx); 4604 /* prefetch, implement as NOP */ 4605 if (rt == 0) { 4606 return; 4607 } 4608 break; 4609 case OPC_GSSWXC1: 4610 #if defined(TARGET_MIPS64) 4611 case OPC_GSSDXC1: 4612 #endif 4613 check_cp1_enabled(ctx); 4614 break; 4615 default: 4616 MIPS_INVAL("loongson_lsdc2"); 4617 gen_reserved_instruction(ctx); 4618 return; 4619 break; 4620 } 4621 4622 t0 = tcg_temp_new(); 4623 4624 gen_base_offset_addr(ctx, t0, rs, offset); 4625 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4626 4627 switch (opc) { 4628 case OPC_GSLBX: 4629 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4630 gen_store_gpr(t0, rt); 4631 break; 4632 case OPC_GSLHX: 4633 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4634 ctx->default_tcg_memop_mask); 4635 gen_store_gpr(t0, rt); 4636 break; 4637 case OPC_GSLWX: 4638 gen_base_offset_addr(ctx, t0, rs, offset); 4639 if (rd) { 4640 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4641 } 4642 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4643 ctx->default_tcg_memop_mask); 4644 gen_store_gpr(t0, rt); 4645 break; 4646 #if defined(TARGET_MIPS64) 4647 case OPC_GSLDX: 4648 gen_base_offset_addr(ctx, t0, rs, offset); 4649 if (rd) { 4650 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4651 } 4652 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4653 ctx->default_tcg_memop_mask); 4654 gen_store_gpr(t0, rt); 4655 break; 4656 #endif 4657 case OPC_GSLWXC1: 4658 gen_base_offset_addr(ctx, t0, rs, offset); 4659 if (rd) { 4660 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4661 } 4662 fp0 = tcg_temp_new_i32(); 4663 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4664 ctx->default_tcg_memop_mask); 4665 gen_store_fpr32(ctx, fp0, rt); 4666 tcg_temp_free_i32(fp0); 4667 break; 4668 #if defined(TARGET_MIPS64) 4669 case OPC_GSLDXC1: 4670 gen_base_offset_addr(ctx, t0, rs, offset); 4671 if (rd) { 4672 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4673 } 4674 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ | 4675 ctx->default_tcg_memop_mask); 4676 gen_store_fpr64(ctx, t0, rt); 4677 break; 4678 #endif 4679 case OPC_GSSBX: 4680 t1 = tcg_temp_new(); 4681 gen_load_gpr(t1, rt); 4682 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4683 tcg_temp_free(t1); 4684 break; 4685 case OPC_GSSHX: 4686 t1 = tcg_temp_new(); 4687 gen_load_gpr(t1, rt); 4688 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4689 ctx->default_tcg_memop_mask); 4690 tcg_temp_free(t1); 4691 break; 4692 case OPC_GSSWX: 4693 t1 = tcg_temp_new(); 4694 gen_load_gpr(t1, rt); 4695 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4696 ctx->default_tcg_memop_mask); 4697 tcg_temp_free(t1); 4698 break; 4699 #if defined(TARGET_MIPS64) 4700 case OPC_GSSDX: 4701 t1 = tcg_temp_new(); 4702 gen_load_gpr(t1, rt); 4703 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ | 4704 ctx->default_tcg_memop_mask); 4705 tcg_temp_free(t1); 4706 break; 4707 #endif 4708 case OPC_GSSWXC1: 4709 fp0 = tcg_temp_new_i32(); 4710 gen_load_fpr32(ctx, fp0, rt); 4711 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4712 ctx->default_tcg_memop_mask); 4713 tcg_temp_free_i32(fp0); 4714 break; 4715 #if defined(TARGET_MIPS64) 4716 case OPC_GSSDXC1: 4717 t1 = tcg_temp_new(); 4718 gen_load_fpr64(ctx, t1, rt); 4719 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ | 4720 ctx->default_tcg_memop_mask); 4721 tcg_temp_free(t1); 4722 break; 4723 #endif 4724 default: 4725 break; 4726 } 4727 4728 tcg_temp_free(t0); 4729 } 4730 4731 /* Traps */ 4732 static void gen_trap(DisasContext *ctx, uint32_t opc, 4733 int rs, int rt, int16_t imm, int code) 4734 { 4735 int cond; 4736 TCGv t0 = tcg_temp_new(); 4737 TCGv t1 = tcg_temp_new(); 4738 4739 cond = 0; 4740 /* Load needed operands */ 4741 switch (opc) { 4742 case OPC_TEQ: 4743 case OPC_TGE: 4744 case OPC_TGEU: 4745 case OPC_TLT: 4746 case OPC_TLTU: 4747 case OPC_TNE: 4748 /* Compare two registers */ 4749 if (rs != rt) { 4750 gen_load_gpr(t0, rs); 4751 gen_load_gpr(t1, rt); 4752 cond = 1; 4753 } 4754 break; 4755 case OPC_TEQI: 4756 case OPC_TGEI: 4757 case OPC_TGEIU: 4758 case OPC_TLTI: 4759 case OPC_TLTIU: 4760 case OPC_TNEI: 4761 /* Compare register to immediate */ 4762 if (rs != 0 || imm != 0) { 4763 gen_load_gpr(t0, rs); 4764 tcg_gen_movi_tl(t1, (int32_t)imm); 4765 cond = 1; 4766 } 4767 break; 4768 } 4769 if (cond == 0) { 4770 switch (opc) { 4771 case OPC_TEQ: /* rs == rs */ 4772 case OPC_TEQI: /* r0 == 0 */ 4773 case OPC_TGE: /* rs >= rs */ 4774 case OPC_TGEI: /* r0 >= 0 */ 4775 case OPC_TGEU: /* rs >= rs unsigned */ 4776 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4777 /* Always trap */ 4778 #ifdef CONFIG_USER_ONLY 4779 /* Pass the break code along to cpu_loop. */ 4780 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4781 offsetof(CPUMIPSState, error_code)); 4782 #endif 4783 generate_exception_end(ctx, EXCP_TRAP); 4784 break; 4785 case OPC_TLT: /* rs < rs */ 4786 case OPC_TLTI: /* r0 < 0 */ 4787 case OPC_TLTU: /* rs < rs unsigned */ 4788 case OPC_TLTIU: /* r0 < 0 unsigned */ 4789 case OPC_TNE: /* rs != rs */ 4790 case OPC_TNEI: /* r0 != 0 */ 4791 /* Never trap: treat as NOP. */ 4792 break; 4793 } 4794 } else { 4795 TCGLabel *l1 = gen_new_label(); 4796 4797 switch (opc) { 4798 case OPC_TEQ: 4799 case OPC_TEQI: 4800 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4801 break; 4802 case OPC_TGE: 4803 case OPC_TGEI: 4804 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4805 break; 4806 case OPC_TGEU: 4807 case OPC_TGEIU: 4808 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4809 break; 4810 case OPC_TLT: 4811 case OPC_TLTI: 4812 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4813 break; 4814 case OPC_TLTU: 4815 case OPC_TLTIU: 4816 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4817 break; 4818 case OPC_TNE: 4819 case OPC_TNEI: 4820 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4821 break; 4822 } 4823 #ifdef CONFIG_USER_ONLY 4824 /* Pass the break code along to cpu_loop. */ 4825 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env, 4826 offsetof(CPUMIPSState, error_code)); 4827 #endif 4828 /* Like save_cpu_state, only don't update saved values. */ 4829 if (ctx->base.pc_next != ctx->saved_pc) { 4830 gen_save_pc(ctx->base.pc_next); 4831 } 4832 if (ctx->hflags != ctx->saved_hflags) { 4833 tcg_gen_movi_i32(hflags, ctx->hflags); 4834 } 4835 generate_exception(ctx, EXCP_TRAP); 4836 gen_set_label(l1); 4837 } 4838 tcg_temp_free(t0); 4839 tcg_temp_free(t1); 4840 } 4841 4842 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4843 { 4844 if (translator_use_goto_tb(&ctx->base, dest)) { 4845 tcg_gen_goto_tb(n); 4846 gen_save_pc(dest); 4847 tcg_gen_exit_tb(ctx->base.tb, n); 4848 } else { 4849 gen_save_pc(dest); 4850 tcg_gen_lookup_and_goto_ptr(); 4851 } 4852 } 4853 4854 /* Branches (before delay slot) */ 4855 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4856 int insn_bytes, 4857 int rs, int rt, int32_t offset, 4858 int delayslot_size) 4859 { 4860 target_ulong btgt = -1; 4861 int blink = 0; 4862 int bcond_compute = 0; 4863 TCGv t0 = tcg_temp_new(); 4864 TCGv t1 = tcg_temp_new(); 4865 4866 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4867 #ifdef MIPS_DEBUG_DISAS 4868 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4869 TARGET_FMT_lx "\n", ctx->base.pc_next); 4870 #endif 4871 gen_reserved_instruction(ctx); 4872 goto out; 4873 } 4874 4875 /* Load needed operands */ 4876 switch (opc) { 4877 case OPC_BEQ: 4878 case OPC_BEQL: 4879 case OPC_BNE: 4880 case OPC_BNEL: 4881 /* Compare two registers */ 4882 if (rs != rt) { 4883 gen_load_gpr(t0, rs); 4884 gen_load_gpr(t1, rt); 4885 bcond_compute = 1; 4886 } 4887 btgt = ctx->base.pc_next + insn_bytes + offset; 4888 break; 4889 case OPC_BGEZ: 4890 case OPC_BGEZAL: 4891 case OPC_BGEZALL: 4892 case OPC_BGEZL: 4893 case OPC_BGTZ: 4894 case OPC_BGTZL: 4895 case OPC_BLEZ: 4896 case OPC_BLEZL: 4897 case OPC_BLTZ: 4898 case OPC_BLTZAL: 4899 case OPC_BLTZALL: 4900 case OPC_BLTZL: 4901 /* Compare to zero */ 4902 if (rs != 0) { 4903 gen_load_gpr(t0, rs); 4904 bcond_compute = 1; 4905 } 4906 btgt = ctx->base.pc_next + insn_bytes + offset; 4907 break; 4908 case OPC_BPOSGE32: 4909 #if defined(TARGET_MIPS64) 4910 case OPC_BPOSGE64: 4911 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4912 #else 4913 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4914 #endif 4915 bcond_compute = 1; 4916 btgt = ctx->base.pc_next + insn_bytes + offset; 4917 break; 4918 case OPC_J: 4919 case OPC_JAL: 4920 case OPC_JALX: 4921 /* Jump to immediate */ 4922 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4923 (uint32_t)offset; 4924 break; 4925 case OPC_JR: 4926 case OPC_JALR: 4927 /* Jump to register */ 4928 if (offset != 0 && offset != 16) { 4929 /* 4930 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4931 * others are reserved. 4932 */ 4933 MIPS_INVAL("jump hint"); 4934 gen_reserved_instruction(ctx); 4935 goto out; 4936 } 4937 gen_load_gpr(btarget, rs); 4938 break; 4939 default: 4940 MIPS_INVAL("branch/jump"); 4941 gen_reserved_instruction(ctx); 4942 goto out; 4943 } 4944 if (bcond_compute == 0) { 4945 /* No condition to be computed */ 4946 switch (opc) { 4947 case OPC_BEQ: /* rx == rx */ 4948 case OPC_BEQL: /* rx == rx likely */ 4949 case OPC_BGEZ: /* 0 >= 0 */ 4950 case OPC_BGEZL: /* 0 >= 0 likely */ 4951 case OPC_BLEZ: /* 0 <= 0 */ 4952 case OPC_BLEZL: /* 0 <= 0 likely */ 4953 /* Always take */ 4954 ctx->hflags |= MIPS_HFLAG_B; 4955 break; 4956 case OPC_BGEZAL: /* 0 >= 0 */ 4957 case OPC_BGEZALL: /* 0 >= 0 likely */ 4958 /* Always take and link */ 4959 blink = 31; 4960 ctx->hflags |= MIPS_HFLAG_B; 4961 break; 4962 case OPC_BNE: /* rx != rx */ 4963 case OPC_BGTZ: /* 0 > 0 */ 4964 case OPC_BLTZ: /* 0 < 0 */ 4965 /* Treat as NOP. */ 4966 goto out; 4967 case OPC_BLTZAL: /* 0 < 0 */ 4968 /* 4969 * Handle as an unconditional branch to get correct delay 4970 * slot checking. 4971 */ 4972 blink = 31; 4973 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4974 ctx->hflags |= MIPS_HFLAG_B; 4975 break; 4976 case OPC_BLTZALL: /* 0 < 0 likely */ 4977 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4978 /* Skip the instruction in the delay slot */ 4979 ctx->base.pc_next += 4; 4980 goto out; 4981 case OPC_BNEL: /* rx != rx likely */ 4982 case OPC_BGTZL: /* 0 > 0 likely */ 4983 case OPC_BLTZL: /* 0 < 0 likely */ 4984 /* Skip the instruction in the delay slot */ 4985 ctx->base.pc_next += 4; 4986 goto out; 4987 case OPC_J: 4988 ctx->hflags |= MIPS_HFLAG_B; 4989 break; 4990 case OPC_JALX: 4991 ctx->hflags |= MIPS_HFLAG_BX; 4992 /* Fallthrough */ 4993 case OPC_JAL: 4994 blink = 31; 4995 ctx->hflags |= MIPS_HFLAG_B; 4996 break; 4997 case OPC_JR: 4998 ctx->hflags |= MIPS_HFLAG_BR; 4999 break; 5000 case OPC_JALR: 5001 blink = rt; 5002 ctx->hflags |= MIPS_HFLAG_BR; 5003 break; 5004 default: 5005 MIPS_INVAL("branch/jump"); 5006 gen_reserved_instruction(ctx); 5007 goto out; 5008 } 5009 } else { 5010 switch (opc) { 5011 case OPC_BEQ: 5012 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5013 goto not_likely; 5014 case OPC_BEQL: 5015 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5016 goto likely; 5017 case OPC_BNE: 5018 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5019 goto not_likely; 5020 case OPC_BNEL: 5021 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5022 goto likely; 5023 case OPC_BGEZ: 5024 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5025 goto not_likely; 5026 case OPC_BGEZL: 5027 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5028 goto likely; 5029 case OPC_BGEZAL: 5030 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5031 blink = 31; 5032 goto not_likely; 5033 case OPC_BGEZALL: 5034 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5035 blink = 31; 5036 goto likely; 5037 case OPC_BGTZ: 5038 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5039 goto not_likely; 5040 case OPC_BGTZL: 5041 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5042 goto likely; 5043 case OPC_BLEZ: 5044 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5045 goto not_likely; 5046 case OPC_BLEZL: 5047 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5048 goto likely; 5049 case OPC_BLTZ: 5050 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5051 goto not_likely; 5052 case OPC_BLTZL: 5053 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5054 goto likely; 5055 case OPC_BPOSGE32: 5056 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5057 goto not_likely; 5058 #if defined(TARGET_MIPS64) 5059 case OPC_BPOSGE64: 5060 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5061 goto not_likely; 5062 #endif 5063 case OPC_BLTZAL: 5064 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5065 blink = 31; 5066 not_likely: 5067 ctx->hflags |= MIPS_HFLAG_BC; 5068 break; 5069 case OPC_BLTZALL: 5070 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5071 blink = 31; 5072 likely: 5073 ctx->hflags |= MIPS_HFLAG_BL; 5074 break; 5075 default: 5076 MIPS_INVAL("conditional branch/jump"); 5077 gen_reserved_instruction(ctx); 5078 goto out; 5079 } 5080 } 5081 5082 ctx->btarget = btgt; 5083 5084 switch (delayslot_size) { 5085 case 2: 5086 ctx->hflags |= MIPS_HFLAG_BDS16; 5087 break; 5088 case 4: 5089 ctx->hflags |= MIPS_HFLAG_BDS32; 5090 break; 5091 } 5092 5093 if (blink > 0) { 5094 int post_delay = insn_bytes + delayslot_size; 5095 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5096 5097 tcg_gen_movi_tl(cpu_gpr[blink], 5098 ctx->base.pc_next + post_delay + lowbit); 5099 } 5100 5101 out: 5102 if (insn_bytes == 2) { 5103 ctx->hflags |= MIPS_HFLAG_B16; 5104 } 5105 tcg_temp_free(t0); 5106 tcg_temp_free(t1); 5107 } 5108 5109 5110 /* special3 bitfield operations */ 5111 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5112 int rs, int lsb, int msb) 5113 { 5114 TCGv t0 = tcg_temp_new(); 5115 TCGv t1 = tcg_temp_new(); 5116 5117 gen_load_gpr(t1, rs); 5118 switch (opc) { 5119 case OPC_EXT: 5120 if (lsb + msb > 31) { 5121 goto fail; 5122 } 5123 if (msb != 31) { 5124 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5125 } else { 5126 /* 5127 * The two checks together imply that lsb == 0, 5128 * so this is a simple sign-extension. 5129 */ 5130 tcg_gen_ext32s_tl(t0, t1); 5131 } 5132 break; 5133 #if defined(TARGET_MIPS64) 5134 case OPC_DEXTU: 5135 lsb += 32; 5136 goto do_dext; 5137 case OPC_DEXTM: 5138 msb += 32; 5139 goto do_dext; 5140 case OPC_DEXT: 5141 do_dext: 5142 if (lsb + msb > 63) { 5143 goto fail; 5144 } 5145 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5146 break; 5147 #endif 5148 case OPC_INS: 5149 if (lsb > msb) { 5150 goto fail; 5151 } 5152 gen_load_gpr(t0, rt); 5153 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5154 tcg_gen_ext32s_tl(t0, t0); 5155 break; 5156 #if defined(TARGET_MIPS64) 5157 case OPC_DINSU: 5158 lsb += 32; 5159 /* FALLTHRU */ 5160 case OPC_DINSM: 5161 msb += 32; 5162 /* FALLTHRU */ 5163 case OPC_DINS: 5164 if (lsb > msb) { 5165 goto fail; 5166 } 5167 gen_load_gpr(t0, rt); 5168 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5169 break; 5170 #endif 5171 default: 5172 fail: 5173 MIPS_INVAL("bitops"); 5174 gen_reserved_instruction(ctx); 5175 tcg_temp_free(t0); 5176 tcg_temp_free(t1); 5177 return; 5178 } 5179 gen_store_gpr(t0, rt); 5180 tcg_temp_free(t0); 5181 tcg_temp_free(t1); 5182 } 5183 5184 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5185 { 5186 TCGv t0; 5187 5188 if (rd == 0) { 5189 /* If no destination, treat it as a NOP. */ 5190 return; 5191 } 5192 5193 t0 = tcg_temp_new(); 5194 gen_load_gpr(t0, rt); 5195 switch (op2) { 5196 case OPC_WSBH: 5197 { 5198 TCGv t1 = tcg_temp_new(); 5199 TCGv t2 = tcg_const_tl(0x00FF00FF); 5200 5201 tcg_gen_shri_tl(t1, t0, 8); 5202 tcg_gen_and_tl(t1, t1, t2); 5203 tcg_gen_and_tl(t0, t0, t2); 5204 tcg_gen_shli_tl(t0, t0, 8); 5205 tcg_gen_or_tl(t0, t0, t1); 5206 tcg_temp_free(t2); 5207 tcg_temp_free(t1); 5208 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5209 } 5210 break; 5211 case OPC_SEB: 5212 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5213 break; 5214 case OPC_SEH: 5215 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5216 break; 5217 #if defined(TARGET_MIPS64) 5218 case OPC_DSBH: 5219 { 5220 TCGv t1 = tcg_temp_new(); 5221 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5222 5223 tcg_gen_shri_tl(t1, t0, 8); 5224 tcg_gen_and_tl(t1, t1, t2); 5225 tcg_gen_and_tl(t0, t0, t2); 5226 tcg_gen_shli_tl(t0, t0, 8); 5227 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5228 tcg_temp_free(t2); 5229 tcg_temp_free(t1); 5230 } 5231 break; 5232 case OPC_DSHD: 5233 { 5234 TCGv t1 = tcg_temp_new(); 5235 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5236 5237 tcg_gen_shri_tl(t1, t0, 16); 5238 tcg_gen_and_tl(t1, t1, t2); 5239 tcg_gen_and_tl(t0, t0, t2); 5240 tcg_gen_shli_tl(t0, t0, 16); 5241 tcg_gen_or_tl(t0, t0, t1); 5242 tcg_gen_shri_tl(t1, t0, 32); 5243 tcg_gen_shli_tl(t0, t0, 32); 5244 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5245 tcg_temp_free(t2); 5246 tcg_temp_free(t1); 5247 } 5248 break; 5249 #endif 5250 default: 5251 MIPS_INVAL("bsfhl"); 5252 gen_reserved_instruction(ctx); 5253 tcg_temp_free(t0); 5254 return; 5255 } 5256 tcg_temp_free(t0); 5257 } 5258 5259 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5260 int rt, int bits) 5261 { 5262 TCGv t0; 5263 if (rd == 0) { 5264 /* Treat as NOP. */ 5265 return; 5266 } 5267 t0 = tcg_temp_new(); 5268 if (bits == 0 || bits == wordsz) { 5269 if (bits == 0) { 5270 gen_load_gpr(t0, rt); 5271 } else { 5272 gen_load_gpr(t0, rs); 5273 } 5274 switch (wordsz) { 5275 case 32: 5276 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5277 break; 5278 #if defined(TARGET_MIPS64) 5279 case 64: 5280 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5281 break; 5282 #endif 5283 } 5284 } else { 5285 TCGv t1 = tcg_temp_new(); 5286 gen_load_gpr(t0, rt); 5287 gen_load_gpr(t1, rs); 5288 switch (wordsz) { 5289 case 32: 5290 { 5291 TCGv_i64 t2 = tcg_temp_new_i64(); 5292 tcg_gen_concat_tl_i64(t2, t1, t0); 5293 tcg_gen_shri_i64(t2, t2, 32 - bits); 5294 gen_move_low32(cpu_gpr[rd], t2); 5295 tcg_temp_free_i64(t2); 5296 } 5297 break; 5298 #if defined(TARGET_MIPS64) 5299 case 64: 5300 tcg_gen_shli_tl(t0, t0, bits); 5301 tcg_gen_shri_tl(t1, t1, 64 - bits); 5302 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5303 break; 5304 #endif 5305 } 5306 tcg_temp_free(t1); 5307 } 5308 5309 tcg_temp_free(t0); 5310 } 5311 5312 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5313 { 5314 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5315 } 5316 5317 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5318 { 5319 TCGv t0; 5320 if (rd == 0) { 5321 /* Treat as NOP. */ 5322 return; 5323 } 5324 t0 = tcg_temp_new(); 5325 gen_load_gpr(t0, rt); 5326 switch (opc) { 5327 case OPC_BITSWAP: 5328 gen_helper_bitswap(cpu_gpr[rd], t0); 5329 break; 5330 #if defined(TARGET_MIPS64) 5331 case OPC_DBITSWAP: 5332 gen_helper_dbitswap(cpu_gpr[rd], t0); 5333 break; 5334 #endif 5335 } 5336 tcg_temp_free(t0); 5337 } 5338 5339 #ifndef CONFIG_USER_ONLY 5340 /* CP0 (MMU and control) */ 5341 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5342 { 5343 TCGv_i64 t0 = tcg_temp_new_i64(); 5344 TCGv_i64 t1 = tcg_temp_new_i64(); 5345 5346 tcg_gen_ext_tl_i64(t0, arg); 5347 tcg_gen_ld_i64(t1, cpu_env, off); 5348 #if defined(TARGET_MIPS64) 5349 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5350 #else 5351 tcg_gen_concat32_i64(t1, t1, t0); 5352 #endif 5353 tcg_gen_st_i64(t1, cpu_env, off); 5354 tcg_temp_free_i64(t1); 5355 tcg_temp_free_i64(t0); 5356 } 5357 5358 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5359 { 5360 TCGv_i64 t0 = tcg_temp_new_i64(); 5361 TCGv_i64 t1 = tcg_temp_new_i64(); 5362 5363 tcg_gen_ext_tl_i64(t0, arg); 5364 tcg_gen_ld_i64(t1, cpu_env, off); 5365 tcg_gen_concat32_i64(t1, t1, t0); 5366 tcg_gen_st_i64(t1, cpu_env, off); 5367 tcg_temp_free_i64(t1); 5368 tcg_temp_free_i64(t0); 5369 } 5370 5371 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5372 { 5373 TCGv_i64 t0 = tcg_temp_new_i64(); 5374 5375 tcg_gen_ld_i64(t0, cpu_env, off); 5376 #if defined(TARGET_MIPS64) 5377 tcg_gen_shri_i64(t0, t0, 30); 5378 #else 5379 tcg_gen_shri_i64(t0, t0, 32); 5380 #endif 5381 gen_move_low32(arg, t0); 5382 tcg_temp_free_i64(t0); 5383 } 5384 5385 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5386 { 5387 TCGv_i64 t0 = tcg_temp_new_i64(); 5388 5389 tcg_gen_ld_i64(t0, cpu_env, off); 5390 tcg_gen_shri_i64(t0, t0, 32 + shift); 5391 gen_move_low32(arg, t0); 5392 tcg_temp_free_i64(t0); 5393 } 5394 5395 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5396 { 5397 TCGv_i32 t0 = tcg_temp_new_i32(); 5398 5399 tcg_gen_ld_i32(t0, cpu_env, off); 5400 tcg_gen_ext_i32_tl(arg, t0); 5401 tcg_temp_free_i32(t0); 5402 } 5403 5404 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5405 { 5406 tcg_gen_ld_tl(arg, cpu_env, off); 5407 tcg_gen_ext32s_tl(arg, arg); 5408 } 5409 5410 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5411 { 5412 TCGv_i32 t0 = tcg_temp_new_i32(); 5413 5414 tcg_gen_trunc_tl_i32(t0, arg); 5415 tcg_gen_st_i32(t0, cpu_env, off); 5416 tcg_temp_free_i32(t0); 5417 } 5418 5419 #define CP0_CHECK(c) \ 5420 do { \ 5421 if (!(c)) { \ 5422 goto cp0_unimplemented; \ 5423 } \ 5424 } while (0) 5425 5426 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5427 { 5428 const char *register_name = "invalid"; 5429 5430 switch (reg) { 5431 case CP0_REGISTER_02: 5432 switch (sel) { 5433 case 0: 5434 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5435 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5436 register_name = "EntryLo0"; 5437 break; 5438 default: 5439 goto cp0_unimplemented; 5440 } 5441 break; 5442 case CP0_REGISTER_03: 5443 switch (sel) { 5444 case CP0_REG03__ENTRYLO1: 5445 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5446 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5447 register_name = "EntryLo1"; 5448 break; 5449 default: 5450 goto cp0_unimplemented; 5451 } 5452 break; 5453 case CP0_REGISTER_09: 5454 switch (sel) { 5455 case CP0_REG09__SAAR: 5456 CP0_CHECK(ctx->saar); 5457 gen_helper_mfhc0_saar(arg, cpu_env); 5458 register_name = "SAAR"; 5459 break; 5460 default: 5461 goto cp0_unimplemented; 5462 } 5463 break; 5464 case CP0_REGISTER_17: 5465 switch (sel) { 5466 case CP0_REG17__LLADDR: 5467 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5468 ctx->CP0_LLAddr_shift); 5469 register_name = "LLAddr"; 5470 break; 5471 case CP0_REG17__MAAR: 5472 CP0_CHECK(ctx->mrp); 5473 gen_helper_mfhc0_maar(arg, cpu_env); 5474 register_name = "MAAR"; 5475 break; 5476 default: 5477 goto cp0_unimplemented; 5478 } 5479 break; 5480 case CP0_REGISTER_19: 5481 switch (sel) { 5482 case CP0_REG19__WATCHHI0: 5483 case CP0_REG19__WATCHHI1: 5484 case CP0_REG19__WATCHHI2: 5485 case CP0_REG19__WATCHHI3: 5486 case CP0_REG19__WATCHHI4: 5487 case CP0_REG19__WATCHHI5: 5488 case CP0_REG19__WATCHHI6: 5489 case CP0_REG19__WATCHHI7: 5490 /* upper 32 bits are only available when Config5MI != 0 */ 5491 CP0_CHECK(ctx->mi); 5492 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5493 register_name = "WatchHi"; 5494 break; 5495 default: 5496 goto cp0_unimplemented; 5497 } 5498 break; 5499 case CP0_REGISTER_28: 5500 switch (sel) { 5501 case 0: 5502 case 2: 5503 case 4: 5504 case 6: 5505 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5506 register_name = "TagLo"; 5507 break; 5508 default: 5509 goto cp0_unimplemented; 5510 } 5511 break; 5512 default: 5513 goto cp0_unimplemented; 5514 } 5515 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5516 return; 5517 5518 cp0_unimplemented: 5519 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5520 register_name, reg, sel); 5521 tcg_gen_movi_tl(arg, 0); 5522 } 5523 5524 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5525 { 5526 const char *register_name = "invalid"; 5527 uint64_t mask = ctx->PAMask >> 36; 5528 5529 switch (reg) { 5530 case CP0_REGISTER_02: 5531 switch (sel) { 5532 case 0: 5533 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5534 tcg_gen_andi_tl(arg, arg, mask); 5535 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5536 register_name = "EntryLo0"; 5537 break; 5538 default: 5539 goto cp0_unimplemented; 5540 } 5541 break; 5542 case CP0_REGISTER_03: 5543 switch (sel) { 5544 case CP0_REG03__ENTRYLO1: 5545 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5546 tcg_gen_andi_tl(arg, arg, mask); 5547 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5548 register_name = "EntryLo1"; 5549 break; 5550 default: 5551 goto cp0_unimplemented; 5552 } 5553 break; 5554 case CP0_REGISTER_09: 5555 switch (sel) { 5556 case CP0_REG09__SAAR: 5557 CP0_CHECK(ctx->saar); 5558 gen_helper_mthc0_saar(cpu_env, arg); 5559 register_name = "SAAR"; 5560 break; 5561 default: 5562 goto cp0_unimplemented; 5563 } 5564 break; 5565 case CP0_REGISTER_17: 5566 switch (sel) { 5567 case CP0_REG17__LLADDR: 5568 /* 5569 * LLAddr is read-only (the only exception is bit 0 if LLB is 5570 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5571 * relevant for modern MIPS cores supporting MTHC0, therefore 5572 * treating MTHC0 to LLAddr as NOP. 5573 */ 5574 register_name = "LLAddr"; 5575 break; 5576 case CP0_REG17__MAAR: 5577 CP0_CHECK(ctx->mrp); 5578 gen_helper_mthc0_maar(cpu_env, arg); 5579 register_name = "MAAR"; 5580 break; 5581 default: 5582 goto cp0_unimplemented; 5583 } 5584 break; 5585 case CP0_REGISTER_19: 5586 switch (sel) { 5587 case CP0_REG19__WATCHHI0: 5588 case CP0_REG19__WATCHHI1: 5589 case CP0_REG19__WATCHHI2: 5590 case CP0_REG19__WATCHHI3: 5591 case CP0_REG19__WATCHHI4: 5592 case CP0_REG19__WATCHHI5: 5593 case CP0_REG19__WATCHHI6: 5594 case CP0_REG19__WATCHHI7: 5595 /* upper 32 bits are only available when Config5MI != 0 */ 5596 CP0_CHECK(ctx->mi); 5597 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5598 register_name = "WatchHi"; 5599 break; 5600 default: 5601 goto cp0_unimplemented; 5602 } 5603 break; 5604 case CP0_REGISTER_28: 5605 switch (sel) { 5606 case 0: 5607 case 2: 5608 case 4: 5609 case 6: 5610 tcg_gen_andi_tl(arg, arg, mask); 5611 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5612 register_name = "TagLo"; 5613 break; 5614 default: 5615 goto cp0_unimplemented; 5616 } 5617 break; 5618 default: 5619 goto cp0_unimplemented; 5620 } 5621 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5622 return; 5623 5624 cp0_unimplemented: 5625 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5626 register_name, reg, sel); 5627 } 5628 5629 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5630 { 5631 if (ctx->insn_flags & ISA_MIPS_R6) { 5632 tcg_gen_movi_tl(arg, 0); 5633 } else { 5634 tcg_gen_movi_tl(arg, ~0); 5635 } 5636 } 5637 5638 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5639 { 5640 const char *register_name = "invalid"; 5641 5642 if (sel != 0) { 5643 check_insn(ctx, ISA_MIPS_R1); 5644 } 5645 5646 switch (reg) { 5647 case CP0_REGISTER_00: 5648 switch (sel) { 5649 case CP0_REG00__INDEX: 5650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5651 register_name = "Index"; 5652 break; 5653 case CP0_REG00__MVPCONTROL: 5654 CP0_CHECK(ctx->insn_flags & ASE_MT); 5655 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5656 register_name = "MVPControl"; 5657 break; 5658 case CP0_REG00__MVPCONF0: 5659 CP0_CHECK(ctx->insn_flags & ASE_MT); 5660 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5661 register_name = "MVPConf0"; 5662 break; 5663 case CP0_REG00__MVPCONF1: 5664 CP0_CHECK(ctx->insn_flags & ASE_MT); 5665 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5666 register_name = "MVPConf1"; 5667 break; 5668 case CP0_REG00__VPCONTROL: 5669 CP0_CHECK(ctx->vp); 5670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5671 register_name = "VPControl"; 5672 break; 5673 default: 5674 goto cp0_unimplemented; 5675 } 5676 break; 5677 case CP0_REGISTER_01: 5678 switch (sel) { 5679 case CP0_REG01__RANDOM: 5680 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5681 gen_helper_mfc0_random(arg, cpu_env); 5682 register_name = "Random"; 5683 break; 5684 case CP0_REG01__VPECONTROL: 5685 CP0_CHECK(ctx->insn_flags & ASE_MT); 5686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5687 register_name = "VPEControl"; 5688 break; 5689 case CP0_REG01__VPECONF0: 5690 CP0_CHECK(ctx->insn_flags & ASE_MT); 5691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5692 register_name = "VPEConf0"; 5693 break; 5694 case CP0_REG01__VPECONF1: 5695 CP0_CHECK(ctx->insn_flags & ASE_MT); 5696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5697 register_name = "VPEConf1"; 5698 break; 5699 case CP0_REG01__YQMASK: 5700 CP0_CHECK(ctx->insn_flags & ASE_MT); 5701 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5702 register_name = "YQMask"; 5703 break; 5704 case CP0_REG01__VPESCHEDULE: 5705 CP0_CHECK(ctx->insn_flags & ASE_MT); 5706 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5707 register_name = "VPESchedule"; 5708 break; 5709 case CP0_REG01__VPESCHEFBACK: 5710 CP0_CHECK(ctx->insn_flags & ASE_MT); 5711 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5712 register_name = "VPEScheFBack"; 5713 break; 5714 case CP0_REG01__VPEOPT: 5715 CP0_CHECK(ctx->insn_flags & ASE_MT); 5716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5717 register_name = "VPEOpt"; 5718 break; 5719 default: 5720 goto cp0_unimplemented; 5721 } 5722 break; 5723 case CP0_REGISTER_02: 5724 switch (sel) { 5725 case CP0_REG02__ENTRYLO0: 5726 { 5727 TCGv_i64 tmp = tcg_temp_new_i64(); 5728 tcg_gen_ld_i64(tmp, cpu_env, 5729 offsetof(CPUMIPSState, CP0_EntryLo0)); 5730 #if defined(TARGET_MIPS64) 5731 if (ctx->rxi) { 5732 /* Move RI/XI fields to bits 31:30 */ 5733 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5734 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5735 } 5736 #endif 5737 gen_move_low32(arg, tmp); 5738 tcg_temp_free_i64(tmp); 5739 } 5740 register_name = "EntryLo0"; 5741 break; 5742 case CP0_REG02__TCSTATUS: 5743 CP0_CHECK(ctx->insn_flags & ASE_MT); 5744 gen_helper_mfc0_tcstatus(arg, cpu_env); 5745 register_name = "TCStatus"; 5746 break; 5747 case CP0_REG02__TCBIND: 5748 CP0_CHECK(ctx->insn_flags & ASE_MT); 5749 gen_helper_mfc0_tcbind(arg, cpu_env); 5750 register_name = "TCBind"; 5751 break; 5752 case CP0_REG02__TCRESTART: 5753 CP0_CHECK(ctx->insn_flags & ASE_MT); 5754 gen_helper_mfc0_tcrestart(arg, cpu_env); 5755 register_name = "TCRestart"; 5756 break; 5757 case CP0_REG02__TCHALT: 5758 CP0_CHECK(ctx->insn_flags & ASE_MT); 5759 gen_helper_mfc0_tchalt(arg, cpu_env); 5760 register_name = "TCHalt"; 5761 break; 5762 case CP0_REG02__TCCONTEXT: 5763 CP0_CHECK(ctx->insn_flags & ASE_MT); 5764 gen_helper_mfc0_tccontext(arg, cpu_env); 5765 register_name = "TCContext"; 5766 break; 5767 case CP0_REG02__TCSCHEDULE: 5768 CP0_CHECK(ctx->insn_flags & ASE_MT); 5769 gen_helper_mfc0_tcschedule(arg, cpu_env); 5770 register_name = "TCSchedule"; 5771 break; 5772 case CP0_REG02__TCSCHEFBACK: 5773 CP0_CHECK(ctx->insn_flags & ASE_MT); 5774 gen_helper_mfc0_tcschefback(arg, cpu_env); 5775 register_name = "TCScheFBack"; 5776 break; 5777 default: 5778 goto cp0_unimplemented; 5779 } 5780 break; 5781 case CP0_REGISTER_03: 5782 switch (sel) { 5783 case CP0_REG03__ENTRYLO1: 5784 { 5785 TCGv_i64 tmp = tcg_temp_new_i64(); 5786 tcg_gen_ld_i64(tmp, cpu_env, 5787 offsetof(CPUMIPSState, CP0_EntryLo1)); 5788 #if defined(TARGET_MIPS64) 5789 if (ctx->rxi) { 5790 /* Move RI/XI fields to bits 31:30 */ 5791 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5792 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5793 } 5794 #endif 5795 gen_move_low32(arg, tmp); 5796 tcg_temp_free_i64(tmp); 5797 } 5798 register_name = "EntryLo1"; 5799 break; 5800 case CP0_REG03__GLOBALNUM: 5801 CP0_CHECK(ctx->vp); 5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5803 register_name = "GlobalNumber"; 5804 break; 5805 default: 5806 goto cp0_unimplemented; 5807 } 5808 break; 5809 case CP0_REGISTER_04: 5810 switch (sel) { 5811 case CP0_REG04__CONTEXT: 5812 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5813 tcg_gen_ext32s_tl(arg, arg); 5814 register_name = "Context"; 5815 break; 5816 case CP0_REG04__CONTEXTCONFIG: 5817 /* SmartMIPS ASE */ 5818 /* gen_helper_mfc0_contextconfig(arg); */ 5819 register_name = "ContextConfig"; 5820 goto cp0_unimplemented; 5821 case CP0_REG04__USERLOCAL: 5822 CP0_CHECK(ctx->ulri); 5823 tcg_gen_ld_tl(arg, cpu_env, 5824 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5825 tcg_gen_ext32s_tl(arg, arg); 5826 register_name = "UserLocal"; 5827 break; 5828 case CP0_REG04__MMID: 5829 CP0_CHECK(ctx->mi); 5830 gen_helper_mtc0_memorymapid(cpu_env, arg); 5831 register_name = "MMID"; 5832 break; 5833 default: 5834 goto cp0_unimplemented; 5835 } 5836 break; 5837 case CP0_REGISTER_05: 5838 switch (sel) { 5839 case CP0_REG05__PAGEMASK: 5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5841 register_name = "PageMask"; 5842 break; 5843 case CP0_REG05__PAGEGRAIN: 5844 check_insn(ctx, ISA_MIPS_R2); 5845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5846 register_name = "PageGrain"; 5847 break; 5848 case CP0_REG05__SEGCTL0: 5849 CP0_CHECK(ctx->sc); 5850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5851 tcg_gen_ext32s_tl(arg, arg); 5852 register_name = "SegCtl0"; 5853 break; 5854 case CP0_REG05__SEGCTL1: 5855 CP0_CHECK(ctx->sc); 5856 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5857 tcg_gen_ext32s_tl(arg, arg); 5858 register_name = "SegCtl1"; 5859 break; 5860 case CP0_REG05__SEGCTL2: 5861 CP0_CHECK(ctx->sc); 5862 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5863 tcg_gen_ext32s_tl(arg, arg); 5864 register_name = "SegCtl2"; 5865 break; 5866 case CP0_REG05__PWBASE: 5867 check_pw(ctx); 5868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5869 register_name = "PWBase"; 5870 break; 5871 case CP0_REG05__PWFIELD: 5872 check_pw(ctx); 5873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5874 register_name = "PWField"; 5875 break; 5876 case CP0_REG05__PWSIZE: 5877 check_pw(ctx); 5878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5879 register_name = "PWSize"; 5880 break; 5881 default: 5882 goto cp0_unimplemented; 5883 } 5884 break; 5885 case CP0_REGISTER_06: 5886 switch (sel) { 5887 case CP0_REG06__WIRED: 5888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5889 register_name = "Wired"; 5890 break; 5891 case CP0_REG06__SRSCONF0: 5892 check_insn(ctx, ISA_MIPS_R2); 5893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5894 register_name = "SRSConf0"; 5895 break; 5896 case CP0_REG06__SRSCONF1: 5897 check_insn(ctx, ISA_MIPS_R2); 5898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5899 register_name = "SRSConf1"; 5900 break; 5901 case CP0_REG06__SRSCONF2: 5902 check_insn(ctx, ISA_MIPS_R2); 5903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5904 register_name = "SRSConf2"; 5905 break; 5906 case CP0_REG06__SRSCONF3: 5907 check_insn(ctx, ISA_MIPS_R2); 5908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5909 register_name = "SRSConf3"; 5910 break; 5911 case CP0_REG06__SRSCONF4: 5912 check_insn(ctx, ISA_MIPS_R2); 5913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5914 register_name = "SRSConf4"; 5915 break; 5916 case CP0_REG06__PWCTL: 5917 check_pw(ctx); 5918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5919 register_name = "PWCtl"; 5920 break; 5921 default: 5922 goto cp0_unimplemented; 5923 } 5924 break; 5925 case CP0_REGISTER_07: 5926 switch (sel) { 5927 case CP0_REG07__HWRENA: 5928 check_insn(ctx, ISA_MIPS_R2); 5929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5930 register_name = "HWREna"; 5931 break; 5932 default: 5933 goto cp0_unimplemented; 5934 } 5935 break; 5936 case CP0_REGISTER_08: 5937 switch (sel) { 5938 case CP0_REG08__BADVADDR: 5939 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5940 tcg_gen_ext32s_tl(arg, arg); 5941 register_name = "BadVAddr"; 5942 break; 5943 case CP0_REG08__BADINSTR: 5944 CP0_CHECK(ctx->bi); 5945 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5946 register_name = "BadInstr"; 5947 break; 5948 case CP0_REG08__BADINSTRP: 5949 CP0_CHECK(ctx->bp); 5950 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5951 register_name = "BadInstrP"; 5952 break; 5953 case CP0_REG08__BADINSTRX: 5954 CP0_CHECK(ctx->bi); 5955 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5956 tcg_gen_andi_tl(arg, arg, ~0xffff); 5957 register_name = "BadInstrX"; 5958 break; 5959 default: 5960 goto cp0_unimplemented; 5961 } 5962 break; 5963 case CP0_REGISTER_09: 5964 switch (sel) { 5965 case CP0_REG09__COUNT: 5966 /* Mark as an IO operation because we read the time. */ 5967 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 5968 gen_io_start(); 5969 } 5970 gen_helper_mfc0_count(arg, cpu_env); 5971 /* 5972 * Break the TB to be able to take timer interrupts immediately 5973 * after reading count. DISAS_STOP isn't sufficient, we need to 5974 * ensure we break completely out of translated code. 5975 */ 5976 gen_save_pc(ctx->base.pc_next + 4); 5977 ctx->base.is_jmp = DISAS_EXIT; 5978 register_name = "Count"; 5979 break; 5980 case CP0_REG09__SAARI: 5981 CP0_CHECK(ctx->saar); 5982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 5983 register_name = "SAARI"; 5984 break; 5985 case CP0_REG09__SAAR: 5986 CP0_CHECK(ctx->saar); 5987 gen_helper_mfc0_saar(arg, cpu_env); 5988 register_name = "SAAR"; 5989 break; 5990 default: 5991 goto cp0_unimplemented; 5992 } 5993 break; 5994 case CP0_REGISTER_10: 5995 switch (sel) { 5996 case CP0_REG10__ENTRYHI: 5997 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5998 tcg_gen_ext32s_tl(arg, arg); 5999 register_name = "EntryHi"; 6000 break; 6001 default: 6002 goto cp0_unimplemented; 6003 } 6004 break; 6005 case CP0_REGISTER_11: 6006 switch (sel) { 6007 case CP0_REG11__COMPARE: 6008 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6009 register_name = "Compare"; 6010 break; 6011 /* 6,7 are implementation dependent */ 6012 default: 6013 goto cp0_unimplemented; 6014 } 6015 break; 6016 case CP0_REGISTER_12: 6017 switch (sel) { 6018 case CP0_REG12__STATUS: 6019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6020 register_name = "Status"; 6021 break; 6022 case CP0_REG12__INTCTL: 6023 check_insn(ctx, ISA_MIPS_R2); 6024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6025 register_name = "IntCtl"; 6026 break; 6027 case CP0_REG12__SRSCTL: 6028 check_insn(ctx, ISA_MIPS_R2); 6029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6030 register_name = "SRSCtl"; 6031 break; 6032 case CP0_REG12__SRSMAP: 6033 check_insn(ctx, ISA_MIPS_R2); 6034 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6035 register_name = "SRSMap"; 6036 break; 6037 default: 6038 goto cp0_unimplemented; 6039 } 6040 break; 6041 case CP0_REGISTER_13: 6042 switch (sel) { 6043 case CP0_REG13__CAUSE: 6044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6045 register_name = "Cause"; 6046 break; 6047 default: 6048 goto cp0_unimplemented; 6049 } 6050 break; 6051 case CP0_REGISTER_14: 6052 switch (sel) { 6053 case CP0_REG14__EPC: 6054 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6055 tcg_gen_ext32s_tl(arg, arg); 6056 register_name = "EPC"; 6057 break; 6058 default: 6059 goto cp0_unimplemented; 6060 } 6061 break; 6062 case CP0_REGISTER_15: 6063 switch (sel) { 6064 case CP0_REG15__PRID: 6065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6066 register_name = "PRid"; 6067 break; 6068 case CP0_REG15__EBASE: 6069 check_insn(ctx, ISA_MIPS_R2); 6070 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6071 tcg_gen_ext32s_tl(arg, arg); 6072 register_name = "EBase"; 6073 break; 6074 case CP0_REG15__CMGCRBASE: 6075 check_insn(ctx, ISA_MIPS_R2); 6076 CP0_CHECK(ctx->cmgcr); 6077 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6078 tcg_gen_ext32s_tl(arg, arg); 6079 register_name = "CMGCRBase"; 6080 break; 6081 default: 6082 goto cp0_unimplemented; 6083 } 6084 break; 6085 case CP0_REGISTER_16: 6086 switch (sel) { 6087 case CP0_REG16__CONFIG: 6088 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6089 register_name = "Config"; 6090 break; 6091 case CP0_REG16__CONFIG1: 6092 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6093 register_name = "Config1"; 6094 break; 6095 case CP0_REG16__CONFIG2: 6096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6097 register_name = "Config2"; 6098 break; 6099 case CP0_REG16__CONFIG3: 6100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6101 register_name = "Config3"; 6102 break; 6103 case CP0_REG16__CONFIG4: 6104 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6105 register_name = "Config4"; 6106 break; 6107 case CP0_REG16__CONFIG5: 6108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6109 register_name = "Config5"; 6110 break; 6111 /* 6,7 are implementation dependent */ 6112 case CP0_REG16__CONFIG6: 6113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6114 register_name = "Config6"; 6115 break; 6116 case CP0_REG16__CONFIG7: 6117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6118 register_name = "Config7"; 6119 break; 6120 default: 6121 goto cp0_unimplemented; 6122 } 6123 break; 6124 case CP0_REGISTER_17: 6125 switch (sel) { 6126 case CP0_REG17__LLADDR: 6127 gen_helper_mfc0_lladdr(arg, cpu_env); 6128 register_name = "LLAddr"; 6129 break; 6130 case CP0_REG17__MAAR: 6131 CP0_CHECK(ctx->mrp); 6132 gen_helper_mfc0_maar(arg, cpu_env); 6133 register_name = "MAAR"; 6134 break; 6135 case CP0_REG17__MAARI: 6136 CP0_CHECK(ctx->mrp); 6137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6138 register_name = "MAARI"; 6139 break; 6140 default: 6141 goto cp0_unimplemented; 6142 } 6143 break; 6144 case CP0_REGISTER_18: 6145 switch (sel) { 6146 case CP0_REG18__WATCHLO0: 6147 case CP0_REG18__WATCHLO1: 6148 case CP0_REG18__WATCHLO2: 6149 case CP0_REG18__WATCHLO3: 6150 case CP0_REG18__WATCHLO4: 6151 case CP0_REG18__WATCHLO5: 6152 case CP0_REG18__WATCHLO6: 6153 case CP0_REG18__WATCHLO7: 6154 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6155 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6156 register_name = "WatchLo"; 6157 break; 6158 default: 6159 goto cp0_unimplemented; 6160 } 6161 break; 6162 case CP0_REGISTER_19: 6163 switch (sel) { 6164 case CP0_REG19__WATCHHI0: 6165 case CP0_REG19__WATCHHI1: 6166 case CP0_REG19__WATCHHI2: 6167 case CP0_REG19__WATCHHI3: 6168 case CP0_REG19__WATCHHI4: 6169 case CP0_REG19__WATCHHI5: 6170 case CP0_REG19__WATCHHI6: 6171 case CP0_REG19__WATCHHI7: 6172 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6173 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6174 register_name = "WatchHi"; 6175 break; 6176 default: 6177 goto cp0_unimplemented; 6178 } 6179 break; 6180 case CP0_REGISTER_20: 6181 switch (sel) { 6182 case CP0_REG20__XCONTEXT: 6183 #if defined(TARGET_MIPS64) 6184 check_insn(ctx, ISA_MIPS3); 6185 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6186 tcg_gen_ext32s_tl(arg, arg); 6187 register_name = "XContext"; 6188 break; 6189 #endif 6190 default: 6191 goto cp0_unimplemented; 6192 } 6193 break; 6194 case CP0_REGISTER_21: 6195 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6196 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6197 switch (sel) { 6198 case 0: 6199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6200 register_name = "Framemask"; 6201 break; 6202 default: 6203 goto cp0_unimplemented; 6204 } 6205 break; 6206 case CP0_REGISTER_22: 6207 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6208 register_name = "'Diagnostic"; /* implementation dependent */ 6209 break; 6210 case CP0_REGISTER_23: 6211 switch (sel) { 6212 case CP0_REG23__DEBUG: 6213 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6214 register_name = "Debug"; 6215 break; 6216 case CP0_REG23__TRACECONTROL: 6217 /* PDtrace support */ 6218 /* gen_helper_mfc0_tracecontrol(arg); */ 6219 register_name = "TraceControl"; 6220 goto cp0_unimplemented; 6221 case CP0_REG23__TRACECONTROL2: 6222 /* PDtrace support */ 6223 /* gen_helper_mfc0_tracecontrol2(arg); */ 6224 register_name = "TraceControl2"; 6225 goto cp0_unimplemented; 6226 case CP0_REG23__USERTRACEDATA1: 6227 /* PDtrace support */ 6228 /* gen_helper_mfc0_usertracedata1(arg);*/ 6229 register_name = "UserTraceData1"; 6230 goto cp0_unimplemented; 6231 case CP0_REG23__TRACEIBPC: 6232 /* PDtrace support */ 6233 /* gen_helper_mfc0_traceibpc(arg); */ 6234 register_name = "TraceIBPC"; 6235 goto cp0_unimplemented; 6236 case CP0_REG23__TRACEDBPC: 6237 /* PDtrace support */ 6238 /* gen_helper_mfc0_tracedbpc(arg); */ 6239 register_name = "TraceDBPC"; 6240 goto cp0_unimplemented; 6241 default: 6242 goto cp0_unimplemented; 6243 } 6244 break; 6245 case CP0_REGISTER_24: 6246 switch (sel) { 6247 case CP0_REG24__DEPC: 6248 /* EJTAG support */ 6249 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6250 tcg_gen_ext32s_tl(arg, arg); 6251 register_name = "DEPC"; 6252 break; 6253 default: 6254 goto cp0_unimplemented; 6255 } 6256 break; 6257 case CP0_REGISTER_25: 6258 switch (sel) { 6259 case CP0_REG25__PERFCTL0: 6260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6261 register_name = "Performance0"; 6262 break; 6263 case CP0_REG25__PERFCNT0: 6264 /* gen_helper_mfc0_performance1(arg); */ 6265 register_name = "Performance1"; 6266 goto cp0_unimplemented; 6267 case CP0_REG25__PERFCTL1: 6268 /* gen_helper_mfc0_performance2(arg); */ 6269 register_name = "Performance2"; 6270 goto cp0_unimplemented; 6271 case CP0_REG25__PERFCNT1: 6272 /* gen_helper_mfc0_performance3(arg); */ 6273 register_name = "Performance3"; 6274 goto cp0_unimplemented; 6275 case CP0_REG25__PERFCTL2: 6276 /* gen_helper_mfc0_performance4(arg); */ 6277 register_name = "Performance4"; 6278 goto cp0_unimplemented; 6279 case CP0_REG25__PERFCNT2: 6280 /* gen_helper_mfc0_performance5(arg); */ 6281 register_name = "Performance5"; 6282 goto cp0_unimplemented; 6283 case CP0_REG25__PERFCTL3: 6284 /* gen_helper_mfc0_performance6(arg); */ 6285 register_name = "Performance6"; 6286 goto cp0_unimplemented; 6287 case CP0_REG25__PERFCNT3: 6288 /* gen_helper_mfc0_performance7(arg); */ 6289 register_name = "Performance7"; 6290 goto cp0_unimplemented; 6291 default: 6292 goto cp0_unimplemented; 6293 } 6294 break; 6295 case CP0_REGISTER_26: 6296 switch (sel) { 6297 case CP0_REG26__ERRCTL: 6298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6299 register_name = "ErrCtl"; 6300 break; 6301 default: 6302 goto cp0_unimplemented; 6303 } 6304 break; 6305 case CP0_REGISTER_27: 6306 switch (sel) { 6307 case CP0_REG27__CACHERR: 6308 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6309 register_name = "CacheErr"; 6310 break; 6311 default: 6312 goto cp0_unimplemented; 6313 } 6314 break; 6315 case CP0_REGISTER_28: 6316 switch (sel) { 6317 case CP0_REG28__TAGLO: 6318 case CP0_REG28__TAGLO1: 6319 case CP0_REG28__TAGLO2: 6320 case CP0_REG28__TAGLO3: 6321 { 6322 TCGv_i64 tmp = tcg_temp_new_i64(); 6323 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6324 gen_move_low32(arg, tmp); 6325 tcg_temp_free_i64(tmp); 6326 } 6327 register_name = "TagLo"; 6328 break; 6329 case CP0_REG28__DATALO: 6330 case CP0_REG28__DATALO1: 6331 case CP0_REG28__DATALO2: 6332 case CP0_REG28__DATALO3: 6333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6334 register_name = "DataLo"; 6335 break; 6336 default: 6337 goto cp0_unimplemented; 6338 } 6339 break; 6340 case CP0_REGISTER_29: 6341 switch (sel) { 6342 case CP0_REG29__TAGHI: 6343 case CP0_REG29__TAGHI1: 6344 case CP0_REG29__TAGHI2: 6345 case CP0_REG29__TAGHI3: 6346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6347 register_name = "TagHi"; 6348 break; 6349 case CP0_REG29__DATAHI: 6350 case CP0_REG29__DATAHI1: 6351 case CP0_REG29__DATAHI2: 6352 case CP0_REG29__DATAHI3: 6353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6354 register_name = "DataHi"; 6355 break; 6356 default: 6357 goto cp0_unimplemented; 6358 } 6359 break; 6360 case CP0_REGISTER_30: 6361 switch (sel) { 6362 case CP0_REG30__ERROREPC: 6363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6364 tcg_gen_ext32s_tl(arg, arg); 6365 register_name = "ErrorEPC"; 6366 break; 6367 default: 6368 goto cp0_unimplemented; 6369 } 6370 break; 6371 case CP0_REGISTER_31: 6372 switch (sel) { 6373 case CP0_REG31__DESAVE: 6374 /* EJTAG support */ 6375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6376 register_name = "DESAVE"; 6377 break; 6378 case CP0_REG31__KSCRATCH1: 6379 case CP0_REG31__KSCRATCH2: 6380 case CP0_REG31__KSCRATCH3: 6381 case CP0_REG31__KSCRATCH4: 6382 case CP0_REG31__KSCRATCH5: 6383 case CP0_REG31__KSCRATCH6: 6384 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6385 tcg_gen_ld_tl(arg, cpu_env, 6386 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6387 tcg_gen_ext32s_tl(arg, arg); 6388 register_name = "KScratch"; 6389 break; 6390 default: 6391 goto cp0_unimplemented; 6392 } 6393 break; 6394 default: 6395 goto cp0_unimplemented; 6396 } 6397 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6398 return; 6399 6400 cp0_unimplemented: 6401 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6402 register_name, reg, sel); 6403 gen_mfc0_unimplemented(ctx, arg); 6404 } 6405 6406 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6407 { 6408 const char *register_name = "invalid"; 6409 6410 if (sel != 0) { 6411 check_insn(ctx, ISA_MIPS_R1); 6412 } 6413 6414 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6415 gen_io_start(); 6416 } 6417 6418 switch (reg) { 6419 case CP0_REGISTER_00: 6420 switch (sel) { 6421 case CP0_REG00__INDEX: 6422 gen_helper_mtc0_index(cpu_env, arg); 6423 register_name = "Index"; 6424 break; 6425 case CP0_REG00__MVPCONTROL: 6426 CP0_CHECK(ctx->insn_flags & ASE_MT); 6427 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6428 register_name = "MVPControl"; 6429 break; 6430 case CP0_REG00__MVPCONF0: 6431 CP0_CHECK(ctx->insn_flags & ASE_MT); 6432 /* ignored */ 6433 register_name = "MVPConf0"; 6434 break; 6435 case CP0_REG00__MVPCONF1: 6436 CP0_CHECK(ctx->insn_flags & ASE_MT); 6437 /* ignored */ 6438 register_name = "MVPConf1"; 6439 break; 6440 case CP0_REG00__VPCONTROL: 6441 CP0_CHECK(ctx->vp); 6442 /* ignored */ 6443 register_name = "VPControl"; 6444 break; 6445 default: 6446 goto cp0_unimplemented; 6447 } 6448 break; 6449 case CP0_REGISTER_01: 6450 switch (sel) { 6451 case CP0_REG01__RANDOM: 6452 /* ignored */ 6453 register_name = "Random"; 6454 break; 6455 case CP0_REG01__VPECONTROL: 6456 CP0_CHECK(ctx->insn_flags & ASE_MT); 6457 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6458 register_name = "VPEControl"; 6459 break; 6460 case CP0_REG01__VPECONF0: 6461 CP0_CHECK(ctx->insn_flags & ASE_MT); 6462 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6463 register_name = "VPEConf0"; 6464 break; 6465 case CP0_REG01__VPECONF1: 6466 CP0_CHECK(ctx->insn_flags & ASE_MT); 6467 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6468 register_name = "VPEConf1"; 6469 break; 6470 case CP0_REG01__YQMASK: 6471 CP0_CHECK(ctx->insn_flags & ASE_MT); 6472 gen_helper_mtc0_yqmask(cpu_env, arg); 6473 register_name = "YQMask"; 6474 break; 6475 case CP0_REG01__VPESCHEDULE: 6476 CP0_CHECK(ctx->insn_flags & ASE_MT); 6477 tcg_gen_st_tl(arg, cpu_env, 6478 offsetof(CPUMIPSState, CP0_VPESchedule)); 6479 register_name = "VPESchedule"; 6480 break; 6481 case CP0_REG01__VPESCHEFBACK: 6482 CP0_CHECK(ctx->insn_flags & ASE_MT); 6483 tcg_gen_st_tl(arg, cpu_env, 6484 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6485 register_name = "VPEScheFBack"; 6486 break; 6487 case CP0_REG01__VPEOPT: 6488 CP0_CHECK(ctx->insn_flags & ASE_MT); 6489 gen_helper_mtc0_vpeopt(cpu_env, arg); 6490 register_name = "VPEOpt"; 6491 break; 6492 default: 6493 goto cp0_unimplemented; 6494 } 6495 break; 6496 case CP0_REGISTER_02: 6497 switch (sel) { 6498 case CP0_REG02__ENTRYLO0: 6499 gen_helper_mtc0_entrylo0(cpu_env, arg); 6500 register_name = "EntryLo0"; 6501 break; 6502 case CP0_REG02__TCSTATUS: 6503 CP0_CHECK(ctx->insn_flags & ASE_MT); 6504 gen_helper_mtc0_tcstatus(cpu_env, arg); 6505 register_name = "TCStatus"; 6506 break; 6507 case CP0_REG02__TCBIND: 6508 CP0_CHECK(ctx->insn_flags & ASE_MT); 6509 gen_helper_mtc0_tcbind(cpu_env, arg); 6510 register_name = "TCBind"; 6511 break; 6512 case CP0_REG02__TCRESTART: 6513 CP0_CHECK(ctx->insn_flags & ASE_MT); 6514 gen_helper_mtc0_tcrestart(cpu_env, arg); 6515 register_name = "TCRestart"; 6516 break; 6517 case CP0_REG02__TCHALT: 6518 CP0_CHECK(ctx->insn_flags & ASE_MT); 6519 gen_helper_mtc0_tchalt(cpu_env, arg); 6520 register_name = "TCHalt"; 6521 break; 6522 case CP0_REG02__TCCONTEXT: 6523 CP0_CHECK(ctx->insn_flags & ASE_MT); 6524 gen_helper_mtc0_tccontext(cpu_env, arg); 6525 register_name = "TCContext"; 6526 break; 6527 case CP0_REG02__TCSCHEDULE: 6528 CP0_CHECK(ctx->insn_flags & ASE_MT); 6529 gen_helper_mtc0_tcschedule(cpu_env, arg); 6530 register_name = "TCSchedule"; 6531 break; 6532 case CP0_REG02__TCSCHEFBACK: 6533 CP0_CHECK(ctx->insn_flags & ASE_MT); 6534 gen_helper_mtc0_tcschefback(cpu_env, arg); 6535 register_name = "TCScheFBack"; 6536 break; 6537 default: 6538 goto cp0_unimplemented; 6539 } 6540 break; 6541 case CP0_REGISTER_03: 6542 switch (sel) { 6543 case CP0_REG03__ENTRYLO1: 6544 gen_helper_mtc0_entrylo1(cpu_env, arg); 6545 register_name = "EntryLo1"; 6546 break; 6547 case CP0_REG03__GLOBALNUM: 6548 CP0_CHECK(ctx->vp); 6549 /* ignored */ 6550 register_name = "GlobalNumber"; 6551 break; 6552 default: 6553 goto cp0_unimplemented; 6554 } 6555 break; 6556 case CP0_REGISTER_04: 6557 switch (sel) { 6558 case CP0_REG04__CONTEXT: 6559 gen_helper_mtc0_context(cpu_env, arg); 6560 register_name = "Context"; 6561 break; 6562 case CP0_REG04__CONTEXTCONFIG: 6563 /* SmartMIPS ASE */ 6564 /* gen_helper_mtc0_contextconfig(arg); */ 6565 register_name = "ContextConfig"; 6566 goto cp0_unimplemented; 6567 case CP0_REG04__USERLOCAL: 6568 CP0_CHECK(ctx->ulri); 6569 tcg_gen_st_tl(arg, cpu_env, 6570 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6571 register_name = "UserLocal"; 6572 break; 6573 case CP0_REG04__MMID: 6574 CP0_CHECK(ctx->mi); 6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6576 register_name = "MMID"; 6577 break; 6578 default: 6579 goto cp0_unimplemented; 6580 } 6581 break; 6582 case CP0_REGISTER_05: 6583 switch (sel) { 6584 case CP0_REG05__PAGEMASK: 6585 gen_helper_mtc0_pagemask(cpu_env, arg); 6586 register_name = "PageMask"; 6587 break; 6588 case CP0_REG05__PAGEGRAIN: 6589 check_insn(ctx, ISA_MIPS_R2); 6590 gen_helper_mtc0_pagegrain(cpu_env, arg); 6591 register_name = "PageGrain"; 6592 ctx->base.is_jmp = DISAS_STOP; 6593 break; 6594 case CP0_REG05__SEGCTL0: 6595 CP0_CHECK(ctx->sc); 6596 gen_helper_mtc0_segctl0(cpu_env, arg); 6597 register_name = "SegCtl0"; 6598 break; 6599 case CP0_REG05__SEGCTL1: 6600 CP0_CHECK(ctx->sc); 6601 gen_helper_mtc0_segctl1(cpu_env, arg); 6602 register_name = "SegCtl1"; 6603 break; 6604 case CP0_REG05__SEGCTL2: 6605 CP0_CHECK(ctx->sc); 6606 gen_helper_mtc0_segctl2(cpu_env, arg); 6607 register_name = "SegCtl2"; 6608 break; 6609 case CP0_REG05__PWBASE: 6610 check_pw(ctx); 6611 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6612 register_name = "PWBase"; 6613 break; 6614 case CP0_REG05__PWFIELD: 6615 check_pw(ctx); 6616 gen_helper_mtc0_pwfield(cpu_env, arg); 6617 register_name = "PWField"; 6618 break; 6619 case CP0_REG05__PWSIZE: 6620 check_pw(ctx); 6621 gen_helper_mtc0_pwsize(cpu_env, arg); 6622 register_name = "PWSize"; 6623 break; 6624 default: 6625 goto cp0_unimplemented; 6626 } 6627 break; 6628 case CP0_REGISTER_06: 6629 switch (sel) { 6630 case CP0_REG06__WIRED: 6631 gen_helper_mtc0_wired(cpu_env, arg); 6632 register_name = "Wired"; 6633 break; 6634 case CP0_REG06__SRSCONF0: 6635 check_insn(ctx, ISA_MIPS_R2); 6636 gen_helper_mtc0_srsconf0(cpu_env, arg); 6637 register_name = "SRSConf0"; 6638 break; 6639 case CP0_REG06__SRSCONF1: 6640 check_insn(ctx, ISA_MIPS_R2); 6641 gen_helper_mtc0_srsconf1(cpu_env, arg); 6642 register_name = "SRSConf1"; 6643 break; 6644 case CP0_REG06__SRSCONF2: 6645 check_insn(ctx, ISA_MIPS_R2); 6646 gen_helper_mtc0_srsconf2(cpu_env, arg); 6647 register_name = "SRSConf2"; 6648 break; 6649 case CP0_REG06__SRSCONF3: 6650 check_insn(ctx, ISA_MIPS_R2); 6651 gen_helper_mtc0_srsconf3(cpu_env, arg); 6652 register_name = "SRSConf3"; 6653 break; 6654 case CP0_REG06__SRSCONF4: 6655 check_insn(ctx, ISA_MIPS_R2); 6656 gen_helper_mtc0_srsconf4(cpu_env, arg); 6657 register_name = "SRSConf4"; 6658 break; 6659 case CP0_REG06__PWCTL: 6660 check_pw(ctx); 6661 gen_helper_mtc0_pwctl(cpu_env, arg); 6662 register_name = "PWCtl"; 6663 break; 6664 default: 6665 goto cp0_unimplemented; 6666 } 6667 break; 6668 case CP0_REGISTER_07: 6669 switch (sel) { 6670 case CP0_REG07__HWRENA: 6671 check_insn(ctx, ISA_MIPS_R2); 6672 gen_helper_mtc0_hwrena(cpu_env, arg); 6673 ctx->base.is_jmp = DISAS_STOP; 6674 register_name = "HWREna"; 6675 break; 6676 default: 6677 goto cp0_unimplemented; 6678 } 6679 break; 6680 case CP0_REGISTER_08: 6681 switch (sel) { 6682 case CP0_REG08__BADVADDR: 6683 /* ignored */ 6684 register_name = "BadVAddr"; 6685 break; 6686 case CP0_REG08__BADINSTR: 6687 /* ignored */ 6688 register_name = "BadInstr"; 6689 break; 6690 case CP0_REG08__BADINSTRP: 6691 /* ignored */ 6692 register_name = "BadInstrP"; 6693 break; 6694 case CP0_REG08__BADINSTRX: 6695 /* ignored */ 6696 register_name = "BadInstrX"; 6697 break; 6698 default: 6699 goto cp0_unimplemented; 6700 } 6701 break; 6702 case CP0_REGISTER_09: 6703 switch (sel) { 6704 case CP0_REG09__COUNT: 6705 gen_helper_mtc0_count(cpu_env, arg); 6706 register_name = "Count"; 6707 break; 6708 case CP0_REG09__SAARI: 6709 CP0_CHECK(ctx->saar); 6710 gen_helper_mtc0_saari(cpu_env, arg); 6711 register_name = "SAARI"; 6712 break; 6713 case CP0_REG09__SAAR: 6714 CP0_CHECK(ctx->saar); 6715 gen_helper_mtc0_saar(cpu_env, arg); 6716 register_name = "SAAR"; 6717 break; 6718 default: 6719 goto cp0_unimplemented; 6720 } 6721 break; 6722 case CP0_REGISTER_10: 6723 switch (sel) { 6724 case CP0_REG10__ENTRYHI: 6725 gen_helper_mtc0_entryhi(cpu_env, arg); 6726 register_name = "EntryHi"; 6727 break; 6728 default: 6729 goto cp0_unimplemented; 6730 } 6731 break; 6732 case CP0_REGISTER_11: 6733 switch (sel) { 6734 case CP0_REG11__COMPARE: 6735 gen_helper_mtc0_compare(cpu_env, arg); 6736 register_name = "Compare"; 6737 break; 6738 /* 6,7 are implementation dependent */ 6739 default: 6740 goto cp0_unimplemented; 6741 } 6742 break; 6743 case CP0_REGISTER_12: 6744 switch (sel) { 6745 case CP0_REG12__STATUS: 6746 save_cpu_state(ctx, 1); 6747 gen_helper_mtc0_status(cpu_env, arg); 6748 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6749 gen_save_pc(ctx->base.pc_next + 4); 6750 ctx->base.is_jmp = DISAS_EXIT; 6751 register_name = "Status"; 6752 break; 6753 case CP0_REG12__INTCTL: 6754 check_insn(ctx, ISA_MIPS_R2); 6755 gen_helper_mtc0_intctl(cpu_env, arg); 6756 /* Stop translation as we may have switched the execution mode */ 6757 ctx->base.is_jmp = DISAS_STOP; 6758 register_name = "IntCtl"; 6759 break; 6760 case CP0_REG12__SRSCTL: 6761 check_insn(ctx, ISA_MIPS_R2); 6762 gen_helper_mtc0_srsctl(cpu_env, arg); 6763 /* Stop translation as we may have switched the execution mode */ 6764 ctx->base.is_jmp = DISAS_STOP; 6765 register_name = "SRSCtl"; 6766 break; 6767 case CP0_REG12__SRSMAP: 6768 check_insn(ctx, ISA_MIPS_R2); 6769 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6770 /* Stop translation as we may have switched the execution mode */ 6771 ctx->base.is_jmp = DISAS_STOP; 6772 register_name = "SRSMap"; 6773 break; 6774 default: 6775 goto cp0_unimplemented; 6776 } 6777 break; 6778 case CP0_REGISTER_13: 6779 switch (sel) { 6780 case CP0_REG13__CAUSE: 6781 save_cpu_state(ctx, 1); 6782 gen_helper_mtc0_cause(cpu_env, arg); 6783 /* 6784 * Stop translation as we may have triggered an interrupt. 6785 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6786 * translated code to check for pending interrupts. 6787 */ 6788 gen_save_pc(ctx->base.pc_next + 4); 6789 ctx->base.is_jmp = DISAS_EXIT; 6790 register_name = "Cause"; 6791 break; 6792 default: 6793 goto cp0_unimplemented; 6794 } 6795 break; 6796 case CP0_REGISTER_14: 6797 switch (sel) { 6798 case CP0_REG14__EPC: 6799 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6800 register_name = "EPC"; 6801 break; 6802 default: 6803 goto cp0_unimplemented; 6804 } 6805 break; 6806 case CP0_REGISTER_15: 6807 switch (sel) { 6808 case CP0_REG15__PRID: 6809 /* ignored */ 6810 register_name = "PRid"; 6811 break; 6812 case CP0_REG15__EBASE: 6813 check_insn(ctx, ISA_MIPS_R2); 6814 gen_helper_mtc0_ebase(cpu_env, arg); 6815 register_name = "EBase"; 6816 break; 6817 default: 6818 goto cp0_unimplemented; 6819 } 6820 break; 6821 case CP0_REGISTER_16: 6822 switch (sel) { 6823 case CP0_REG16__CONFIG: 6824 gen_helper_mtc0_config0(cpu_env, arg); 6825 register_name = "Config"; 6826 /* Stop translation as we may have switched the execution mode */ 6827 ctx->base.is_jmp = DISAS_STOP; 6828 break; 6829 case CP0_REG16__CONFIG1: 6830 /* ignored, read only */ 6831 register_name = "Config1"; 6832 break; 6833 case CP0_REG16__CONFIG2: 6834 gen_helper_mtc0_config2(cpu_env, arg); 6835 register_name = "Config2"; 6836 /* Stop translation as we may have switched the execution mode */ 6837 ctx->base.is_jmp = DISAS_STOP; 6838 break; 6839 case CP0_REG16__CONFIG3: 6840 gen_helper_mtc0_config3(cpu_env, arg); 6841 register_name = "Config3"; 6842 /* Stop translation as we may have switched the execution mode */ 6843 ctx->base.is_jmp = DISAS_STOP; 6844 break; 6845 case CP0_REG16__CONFIG4: 6846 gen_helper_mtc0_config4(cpu_env, arg); 6847 register_name = "Config4"; 6848 ctx->base.is_jmp = DISAS_STOP; 6849 break; 6850 case CP0_REG16__CONFIG5: 6851 gen_helper_mtc0_config5(cpu_env, arg); 6852 register_name = "Config5"; 6853 /* Stop translation as we may have switched the execution mode */ 6854 ctx->base.is_jmp = DISAS_STOP; 6855 break; 6856 /* 6,7 are implementation dependent */ 6857 case CP0_REG16__CONFIG6: 6858 /* ignored */ 6859 register_name = "Config6"; 6860 break; 6861 case CP0_REG16__CONFIG7: 6862 /* ignored */ 6863 register_name = "Config7"; 6864 break; 6865 default: 6866 register_name = "Invalid config selector"; 6867 goto cp0_unimplemented; 6868 } 6869 break; 6870 case CP0_REGISTER_17: 6871 switch (sel) { 6872 case CP0_REG17__LLADDR: 6873 gen_helper_mtc0_lladdr(cpu_env, arg); 6874 register_name = "LLAddr"; 6875 break; 6876 case CP0_REG17__MAAR: 6877 CP0_CHECK(ctx->mrp); 6878 gen_helper_mtc0_maar(cpu_env, arg); 6879 register_name = "MAAR"; 6880 break; 6881 case CP0_REG17__MAARI: 6882 CP0_CHECK(ctx->mrp); 6883 gen_helper_mtc0_maari(cpu_env, arg); 6884 register_name = "MAARI"; 6885 break; 6886 default: 6887 goto cp0_unimplemented; 6888 } 6889 break; 6890 case CP0_REGISTER_18: 6891 switch (sel) { 6892 case CP0_REG18__WATCHLO0: 6893 case CP0_REG18__WATCHLO1: 6894 case CP0_REG18__WATCHLO2: 6895 case CP0_REG18__WATCHLO3: 6896 case CP0_REG18__WATCHLO4: 6897 case CP0_REG18__WATCHLO5: 6898 case CP0_REG18__WATCHLO6: 6899 case CP0_REG18__WATCHLO7: 6900 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6901 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6902 register_name = "WatchLo"; 6903 break; 6904 default: 6905 goto cp0_unimplemented; 6906 } 6907 break; 6908 case CP0_REGISTER_19: 6909 switch (sel) { 6910 case CP0_REG19__WATCHHI0: 6911 case CP0_REG19__WATCHHI1: 6912 case CP0_REG19__WATCHHI2: 6913 case CP0_REG19__WATCHHI3: 6914 case CP0_REG19__WATCHHI4: 6915 case CP0_REG19__WATCHHI5: 6916 case CP0_REG19__WATCHHI6: 6917 case CP0_REG19__WATCHHI7: 6918 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6919 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6920 register_name = "WatchHi"; 6921 break; 6922 default: 6923 goto cp0_unimplemented; 6924 } 6925 break; 6926 case CP0_REGISTER_20: 6927 switch (sel) { 6928 case CP0_REG20__XCONTEXT: 6929 #if defined(TARGET_MIPS64) 6930 check_insn(ctx, ISA_MIPS3); 6931 gen_helper_mtc0_xcontext(cpu_env, arg); 6932 register_name = "XContext"; 6933 break; 6934 #endif 6935 default: 6936 goto cp0_unimplemented; 6937 } 6938 break; 6939 case CP0_REGISTER_21: 6940 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6941 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6942 switch (sel) { 6943 case 0: 6944 gen_helper_mtc0_framemask(cpu_env, arg); 6945 register_name = "Framemask"; 6946 break; 6947 default: 6948 goto cp0_unimplemented; 6949 } 6950 break; 6951 case CP0_REGISTER_22: 6952 /* ignored */ 6953 register_name = "Diagnostic"; /* implementation dependent */ 6954 break; 6955 case CP0_REGISTER_23: 6956 switch (sel) { 6957 case CP0_REG23__DEBUG: 6958 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 6959 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6960 gen_save_pc(ctx->base.pc_next + 4); 6961 ctx->base.is_jmp = DISAS_EXIT; 6962 register_name = "Debug"; 6963 break; 6964 case CP0_REG23__TRACECONTROL: 6965 /* PDtrace support */ 6966 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 6967 register_name = "TraceControl"; 6968 /* Stop translation as we may have switched the execution mode */ 6969 ctx->base.is_jmp = DISAS_STOP; 6970 goto cp0_unimplemented; 6971 case CP0_REG23__TRACECONTROL2: 6972 /* PDtrace support */ 6973 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 6974 register_name = "TraceControl2"; 6975 /* Stop translation as we may have switched the execution mode */ 6976 ctx->base.is_jmp = DISAS_STOP; 6977 goto cp0_unimplemented; 6978 case CP0_REG23__USERTRACEDATA1: 6979 /* Stop translation as we may have switched the execution mode */ 6980 ctx->base.is_jmp = DISAS_STOP; 6981 /* PDtrace support */ 6982 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 6983 register_name = "UserTraceData"; 6984 /* Stop translation as we may have switched the execution mode */ 6985 ctx->base.is_jmp = DISAS_STOP; 6986 goto cp0_unimplemented; 6987 case CP0_REG23__TRACEIBPC: 6988 /* PDtrace support */ 6989 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 6990 /* Stop translation as we may have switched the execution mode */ 6991 ctx->base.is_jmp = DISAS_STOP; 6992 register_name = "TraceIBPC"; 6993 goto cp0_unimplemented; 6994 case CP0_REG23__TRACEDBPC: 6995 /* PDtrace support */ 6996 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 6997 /* Stop translation as we may have switched the execution mode */ 6998 ctx->base.is_jmp = DISAS_STOP; 6999 register_name = "TraceDBPC"; 7000 goto cp0_unimplemented; 7001 default: 7002 goto cp0_unimplemented; 7003 } 7004 break; 7005 case CP0_REGISTER_24: 7006 switch (sel) { 7007 case CP0_REG24__DEPC: 7008 /* EJTAG support */ 7009 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7010 register_name = "DEPC"; 7011 break; 7012 default: 7013 goto cp0_unimplemented; 7014 } 7015 break; 7016 case CP0_REGISTER_25: 7017 switch (sel) { 7018 case CP0_REG25__PERFCTL0: 7019 gen_helper_mtc0_performance0(cpu_env, arg); 7020 register_name = "Performance0"; 7021 break; 7022 case CP0_REG25__PERFCNT0: 7023 /* gen_helper_mtc0_performance1(arg); */ 7024 register_name = "Performance1"; 7025 goto cp0_unimplemented; 7026 case CP0_REG25__PERFCTL1: 7027 /* gen_helper_mtc0_performance2(arg); */ 7028 register_name = "Performance2"; 7029 goto cp0_unimplemented; 7030 case CP0_REG25__PERFCNT1: 7031 /* gen_helper_mtc0_performance3(arg); */ 7032 register_name = "Performance3"; 7033 goto cp0_unimplemented; 7034 case CP0_REG25__PERFCTL2: 7035 /* gen_helper_mtc0_performance4(arg); */ 7036 register_name = "Performance4"; 7037 goto cp0_unimplemented; 7038 case CP0_REG25__PERFCNT2: 7039 /* gen_helper_mtc0_performance5(arg); */ 7040 register_name = "Performance5"; 7041 goto cp0_unimplemented; 7042 case CP0_REG25__PERFCTL3: 7043 /* gen_helper_mtc0_performance6(arg); */ 7044 register_name = "Performance6"; 7045 goto cp0_unimplemented; 7046 case CP0_REG25__PERFCNT3: 7047 /* gen_helper_mtc0_performance7(arg); */ 7048 register_name = "Performance7"; 7049 goto cp0_unimplemented; 7050 default: 7051 goto cp0_unimplemented; 7052 } 7053 break; 7054 case CP0_REGISTER_26: 7055 switch (sel) { 7056 case CP0_REG26__ERRCTL: 7057 gen_helper_mtc0_errctl(cpu_env, arg); 7058 ctx->base.is_jmp = DISAS_STOP; 7059 register_name = "ErrCtl"; 7060 break; 7061 default: 7062 goto cp0_unimplemented; 7063 } 7064 break; 7065 case CP0_REGISTER_27: 7066 switch (sel) { 7067 case CP0_REG27__CACHERR: 7068 /* ignored */ 7069 register_name = "CacheErr"; 7070 break; 7071 default: 7072 goto cp0_unimplemented; 7073 } 7074 break; 7075 case CP0_REGISTER_28: 7076 switch (sel) { 7077 case CP0_REG28__TAGLO: 7078 case CP0_REG28__TAGLO1: 7079 case CP0_REG28__TAGLO2: 7080 case CP0_REG28__TAGLO3: 7081 gen_helper_mtc0_taglo(cpu_env, arg); 7082 register_name = "TagLo"; 7083 break; 7084 case CP0_REG28__DATALO: 7085 case CP0_REG28__DATALO1: 7086 case CP0_REG28__DATALO2: 7087 case CP0_REG28__DATALO3: 7088 gen_helper_mtc0_datalo(cpu_env, arg); 7089 register_name = "DataLo"; 7090 break; 7091 default: 7092 goto cp0_unimplemented; 7093 } 7094 break; 7095 case CP0_REGISTER_29: 7096 switch (sel) { 7097 case CP0_REG29__TAGHI: 7098 case CP0_REG29__TAGHI1: 7099 case CP0_REG29__TAGHI2: 7100 case CP0_REG29__TAGHI3: 7101 gen_helper_mtc0_taghi(cpu_env, arg); 7102 register_name = "TagHi"; 7103 break; 7104 case CP0_REG29__DATAHI: 7105 case CP0_REG29__DATAHI1: 7106 case CP0_REG29__DATAHI2: 7107 case CP0_REG29__DATAHI3: 7108 gen_helper_mtc0_datahi(cpu_env, arg); 7109 register_name = "DataHi"; 7110 break; 7111 default: 7112 register_name = "invalid sel"; 7113 goto cp0_unimplemented; 7114 } 7115 break; 7116 case CP0_REGISTER_30: 7117 switch (sel) { 7118 case CP0_REG30__ERROREPC: 7119 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7120 register_name = "ErrorEPC"; 7121 break; 7122 default: 7123 goto cp0_unimplemented; 7124 } 7125 break; 7126 case CP0_REGISTER_31: 7127 switch (sel) { 7128 case CP0_REG31__DESAVE: 7129 /* EJTAG support */ 7130 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7131 register_name = "DESAVE"; 7132 break; 7133 case CP0_REG31__KSCRATCH1: 7134 case CP0_REG31__KSCRATCH2: 7135 case CP0_REG31__KSCRATCH3: 7136 case CP0_REG31__KSCRATCH4: 7137 case CP0_REG31__KSCRATCH5: 7138 case CP0_REG31__KSCRATCH6: 7139 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7140 tcg_gen_st_tl(arg, cpu_env, 7141 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7142 register_name = "KScratch"; 7143 break; 7144 default: 7145 goto cp0_unimplemented; 7146 } 7147 break; 7148 default: 7149 goto cp0_unimplemented; 7150 } 7151 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7152 7153 /* For simplicity assume that all writes can cause interrupts. */ 7154 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7155 /* 7156 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7157 * translated code to check for pending interrupts. 7158 */ 7159 gen_save_pc(ctx->base.pc_next + 4); 7160 ctx->base.is_jmp = DISAS_EXIT; 7161 } 7162 return; 7163 7164 cp0_unimplemented: 7165 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7166 register_name, reg, sel); 7167 } 7168 7169 #if defined(TARGET_MIPS64) 7170 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7171 { 7172 const char *register_name = "invalid"; 7173 7174 if (sel != 0) { 7175 check_insn(ctx, ISA_MIPS_R1); 7176 } 7177 7178 switch (reg) { 7179 case CP0_REGISTER_00: 7180 switch (sel) { 7181 case CP0_REG00__INDEX: 7182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7183 register_name = "Index"; 7184 break; 7185 case CP0_REG00__MVPCONTROL: 7186 CP0_CHECK(ctx->insn_flags & ASE_MT); 7187 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7188 register_name = "MVPControl"; 7189 break; 7190 case CP0_REG00__MVPCONF0: 7191 CP0_CHECK(ctx->insn_flags & ASE_MT); 7192 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7193 register_name = "MVPConf0"; 7194 break; 7195 case CP0_REG00__MVPCONF1: 7196 CP0_CHECK(ctx->insn_flags & ASE_MT); 7197 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7198 register_name = "MVPConf1"; 7199 break; 7200 case CP0_REG00__VPCONTROL: 7201 CP0_CHECK(ctx->vp); 7202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7203 register_name = "VPControl"; 7204 break; 7205 default: 7206 goto cp0_unimplemented; 7207 } 7208 break; 7209 case CP0_REGISTER_01: 7210 switch (sel) { 7211 case CP0_REG01__RANDOM: 7212 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7213 gen_helper_mfc0_random(arg, cpu_env); 7214 register_name = "Random"; 7215 break; 7216 case CP0_REG01__VPECONTROL: 7217 CP0_CHECK(ctx->insn_flags & ASE_MT); 7218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7219 register_name = "VPEControl"; 7220 break; 7221 case CP0_REG01__VPECONF0: 7222 CP0_CHECK(ctx->insn_flags & ASE_MT); 7223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7224 register_name = "VPEConf0"; 7225 break; 7226 case CP0_REG01__VPECONF1: 7227 CP0_CHECK(ctx->insn_flags & ASE_MT); 7228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7229 register_name = "VPEConf1"; 7230 break; 7231 case CP0_REG01__YQMASK: 7232 CP0_CHECK(ctx->insn_flags & ASE_MT); 7233 tcg_gen_ld_tl(arg, cpu_env, 7234 offsetof(CPUMIPSState, CP0_YQMask)); 7235 register_name = "YQMask"; 7236 break; 7237 case CP0_REG01__VPESCHEDULE: 7238 CP0_CHECK(ctx->insn_flags & ASE_MT); 7239 tcg_gen_ld_tl(arg, cpu_env, 7240 offsetof(CPUMIPSState, CP0_VPESchedule)); 7241 register_name = "VPESchedule"; 7242 break; 7243 case CP0_REG01__VPESCHEFBACK: 7244 CP0_CHECK(ctx->insn_flags & ASE_MT); 7245 tcg_gen_ld_tl(arg, cpu_env, 7246 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7247 register_name = "VPEScheFBack"; 7248 break; 7249 case CP0_REG01__VPEOPT: 7250 CP0_CHECK(ctx->insn_flags & ASE_MT); 7251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7252 register_name = "VPEOpt"; 7253 break; 7254 default: 7255 goto cp0_unimplemented; 7256 } 7257 break; 7258 case CP0_REGISTER_02: 7259 switch (sel) { 7260 case CP0_REG02__ENTRYLO0: 7261 tcg_gen_ld_tl(arg, cpu_env, 7262 offsetof(CPUMIPSState, CP0_EntryLo0)); 7263 register_name = "EntryLo0"; 7264 break; 7265 case CP0_REG02__TCSTATUS: 7266 CP0_CHECK(ctx->insn_flags & ASE_MT); 7267 gen_helper_mfc0_tcstatus(arg, cpu_env); 7268 register_name = "TCStatus"; 7269 break; 7270 case CP0_REG02__TCBIND: 7271 CP0_CHECK(ctx->insn_flags & ASE_MT); 7272 gen_helper_mfc0_tcbind(arg, cpu_env); 7273 register_name = "TCBind"; 7274 break; 7275 case CP0_REG02__TCRESTART: 7276 CP0_CHECK(ctx->insn_flags & ASE_MT); 7277 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7278 register_name = "TCRestart"; 7279 break; 7280 case CP0_REG02__TCHALT: 7281 CP0_CHECK(ctx->insn_flags & ASE_MT); 7282 gen_helper_dmfc0_tchalt(arg, cpu_env); 7283 register_name = "TCHalt"; 7284 break; 7285 case CP0_REG02__TCCONTEXT: 7286 CP0_CHECK(ctx->insn_flags & ASE_MT); 7287 gen_helper_dmfc0_tccontext(arg, cpu_env); 7288 register_name = "TCContext"; 7289 break; 7290 case CP0_REG02__TCSCHEDULE: 7291 CP0_CHECK(ctx->insn_flags & ASE_MT); 7292 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7293 register_name = "TCSchedule"; 7294 break; 7295 case CP0_REG02__TCSCHEFBACK: 7296 CP0_CHECK(ctx->insn_flags & ASE_MT); 7297 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7298 register_name = "TCScheFBack"; 7299 break; 7300 default: 7301 goto cp0_unimplemented; 7302 } 7303 break; 7304 case CP0_REGISTER_03: 7305 switch (sel) { 7306 case CP0_REG03__ENTRYLO1: 7307 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7308 register_name = "EntryLo1"; 7309 break; 7310 case CP0_REG03__GLOBALNUM: 7311 CP0_CHECK(ctx->vp); 7312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7313 register_name = "GlobalNumber"; 7314 break; 7315 default: 7316 goto cp0_unimplemented; 7317 } 7318 break; 7319 case CP0_REGISTER_04: 7320 switch (sel) { 7321 case CP0_REG04__CONTEXT: 7322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7323 register_name = "Context"; 7324 break; 7325 case CP0_REG04__CONTEXTCONFIG: 7326 /* SmartMIPS ASE */ 7327 /* gen_helper_dmfc0_contextconfig(arg); */ 7328 register_name = "ContextConfig"; 7329 goto cp0_unimplemented; 7330 case CP0_REG04__USERLOCAL: 7331 CP0_CHECK(ctx->ulri); 7332 tcg_gen_ld_tl(arg, cpu_env, 7333 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7334 register_name = "UserLocal"; 7335 break; 7336 case CP0_REG04__MMID: 7337 CP0_CHECK(ctx->mi); 7338 gen_helper_mtc0_memorymapid(cpu_env, arg); 7339 register_name = "MMID"; 7340 break; 7341 default: 7342 goto cp0_unimplemented; 7343 } 7344 break; 7345 case CP0_REGISTER_05: 7346 switch (sel) { 7347 case CP0_REG05__PAGEMASK: 7348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7349 register_name = "PageMask"; 7350 break; 7351 case CP0_REG05__PAGEGRAIN: 7352 check_insn(ctx, ISA_MIPS_R2); 7353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7354 register_name = "PageGrain"; 7355 break; 7356 case CP0_REG05__SEGCTL0: 7357 CP0_CHECK(ctx->sc); 7358 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7359 register_name = "SegCtl0"; 7360 break; 7361 case CP0_REG05__SEGCTL1: 7362 CP0_CHECK(ctx->sc); 7363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7364 register_name = "SegCtl1"; 7365 break; 7366 case CP0_REG05__SEGCTL2: 7367 CP0_CHECK(ctx->sc); 7368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7369 register_name = "SegCtl2"; 7370 break; 7371 case CP0_REG05__PWBASE: 7372 check_pw(ctx); 7373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7374 register_name = "PWBase"; 7375 break; 7376 case CP0_REG05__PWFIELD: 7377 check_pw(ctx); 7378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7379 register_name = "PWField"; 7380 break; 7381 case CP0_REG05__PWSIZE: 7382 check_pw(ctx); 7383 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7384 register_name = "PWSize"; 7385 break; 7386 default: 7387 goto cp0_unimplemented; 7388 } 7389 break; 7390 case CP0_REGISTER_06: 7391 switch (sel) { 7392 case CP0_REG06__WIRED: 7393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7394 register_name = "Wired"; 7395 break; 7396 case CP0_REG06__SRSCONF0: 7397 check_insn(ctx, ISA_MIPS_R2); 7398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7399 register_name = "SRSConf0"; 7400 break; 7401 case CP0_REG06__SRSCONF1: 7402 check_insn(ctx, ISA_MIPS_R2); 7403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7404 register_name = "SRSConf1"; 7405 break; 7406 case CP0_REG06__SRSCONF2: 7407 check_insn(ctx, ISA_MIPS_R2); 7408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7409 register_name = "SRSConf2"; 7410 break; 7411 case CP0_REG06__SRSCONF3: 7412 check_insn(ctx, ISA_MIPS_R2); 7413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7414 register_name = "SRSConf3"; 7415 break; 7416 case CP0_REG06__SRSCONF4: 7417 check_insn(ctx, ISA_MIPS_R2); 7418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7419 register_name = "SRSConf4"; 7420 break; 7421 case CP0_REG06__PWCTL: 7422 check_pw(ctx); 7423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7424 register_name = "PWCtl"; 7425 break; 7426 default: 7427 goto cp0_unimplemented; 7428 } 7429 break; 7430 case CP0_REGISTER_07: 7431 switch (sel) { 7432 case CP0_REG07__HWRENA: 7433 check_insn(ctx, ISA_MIPS_R2); 7434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7435 register_name = "HWREna"; 7436 break; 7437 default: 7438 goto cp0_unimplemented; 7439 } 7440 break; 7441 case CP0_REGISTER_08: 7442 switch (sel) { 7443 case CP0_REG08__BADVADDR: 7444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7445 register_name = "BadVAddr"; 7446 break; 7447 case CP0_REG08__BADINSTR: 7448 CP0_CHECK(ctx->bi); 7449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7450 register_name = "BadInstr"; 7451 break; 7452 case CP0_REG08__BADINSTRP: 7453 CP0_CHECK(ctx->bp); 7454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7455 register_name = "BadInstrP"; 7456 break; 7457 case CP0_REG08__BADINSTRX: 7458 CP0_CHECK(ctx->bi); 7459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7460 tcg_gen_andi_tl(arg, arg, ~0xffff); 7461 register_name = "BadInstrX"; 7462 break; 7463 default: 7464 goto cp0_unimplemented; 7465 } 7466 break; 7467 case CP0_REGISTER_09: 7468 switch (sel) { 7469 case CP0_REG09__COUNT: 7470 /* Mark as an IO operation because we read the time. */ 7471 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7472 gen_io_start(); 7473 } 7474 gen_helper_mfc0_count(arg, cpu_env); 7475 /* 7476 * Break the TB to be able to take timer interrupts immediately 7477 * after reading count. DISAS_STOP isn't sufficient, we need to 7478 * ensure we break completely out of translated code. 7479 */ 7480 gen_save_pc(ctx->base.pc_next + 4); 7481 ctx->base.is_jmp = DISAS_EXIT; 7482 register_name = "Count"; 7483 break; 7484 case CP0_REG09__SAARI: 7485 CP0_CHECK(ctx->saar); 7486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7487 register_name = "SAARI"; 7488 break; 7489 case CP0_REG09__SAAR: 7490 CP0_CHECK(ctx->saar); 7491 gen_helper_dmfc0_saar(arg, cpu_env); 7492 register_name = "SAAR"; 7493 break; 7494 default: 7495 goto cp0_unimplemented; 7496 } 7497 break; 7498 case CP0_REGISTER_10: 7499 switch (sel) { 7500 case CP0_REG10__ENTRYHI: 7501 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7502 register_name = "EntryHi"; 7503 break; 7504 default: 7505 goto cp0_unimplemented; 7506 } 7507 break; 7508 case CP0_REGISTER_11: 7509 switch (sel) { 7510 case CP0_REG11__COMPARE: 7511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7512 register_name = "Compare"; 7513 break; 7514 /* 6,7 are implementation dependent */ 7515 default: 7516 goto cp0_unimplemented; 7517 } 7518 break; 7519 case CP0_REGISTER_12: 7520 switch (sel) { 7521 case CP0_REG12__STATUS: 7522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7523 register_name = "Status"; 7524 break; 7525 case CP0_REG12__INTCTL: 7526 check_insn(ctx, ISA_MIPS_R2); 7527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7528 register_name = "IntCtl"; 7529 break; 7530 case CP0_REG12__SRSCTL: 7531 check_insn(ctx, ISA_MIPS_R2); 7532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7533 register_name = "SRSCtl"; 7534 break; 7535 case CP0_REG12__SRSMAP: 7536 check_insn(ctx, ISA_MIPS_R2); 7537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7538 register_name = "SRSMap"; 7539 break; 7540 default: 7541 goto cp0_unimplemented; 7542 } 7543 break; 7544 case CP0_REGISTER_13: 7545 switch (sel) { 7546 case CP0_REG13__CAUSE: 7547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7548 register_name = "Cause"; 7549 break; 7550 default: 7551 goto cp0_unimplemented; 7552 } 7553 break; 7554 case CP0_REGISTER_14: 7555 switch (sel) { 7556 case CP0_REG14__EPC: 7557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7558 register_name = "EPC"; 7559 break; 7560 default: 7561 goto cp0_unimplemented; 7562 } 7563 break; 7564 case CP0_REGISTER_15: 7565 switch (sel) { 7566 case CP0_REG15__PRID: 7567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7568 register_name = "PRid"; 7569 break; 7570 case CP0_REG15__EBASE: 7571 check_insn(ctx, ISA_MIPS_R2); 7572 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7573 register_name = "EBase"; 7574 break; 7575 case CP0_REG15__CMGCRBASE: 7576 check_insn(ctx, ISA_MIPS_R2); 7577 CP0_CHECK(ctx->cmgcr); 7578 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7579 register_name = "CMGCRBase"; 7580 break; 7581 default: 7582 goto cp0_unimplemented; 7583 } 7584 break; 7585 case CP0_REGISTER_16: 7586 switch (sel) { 7587 case CP0_REG16__CONFIG: 7588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7589 register_name = "Config"; 7590 break; 7591 case CP0_REG16__CONFIG1: 7592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7593 register_name = "Config1"; 7594 break; 7595 case CP0_REG16__CONFIG2: 7596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7597 register_name = "Config2"; 7598 break; 7599 case CP0_REG16__CONFIG3: 7600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7601 register_name = "Config3"; 7602 break; 7603 case CP0_REG16__CONFIG4: 7604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7605 register_name = "Config4"; 7606 break; 7607 case CP0_REG16__CONFIG5: 7608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7609 register_name = "Config5"; 7610 break; 7611 /* 6,7 are implementation dependent */ 7612 case CP0_REG16__CONFIG6: 7613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7614 register_name = "Config6"; 7615 break; 7616 case CP0_REG16__CONFIG7: 7617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7618 register_name = "Config7"; 7619 break; 7620 default: 7621 goto cp0_unimplemented; 7622 } 7623 break; 7624 case CP0_REGISTER_17: 7625 switch (sel) { 7626 case CP0_REG17__LLADDR: 7627 gen_helper_dmfc0_lladdr(arg, cpu_env); 7628 register_name = "LLAddr"; 7629 break; 7630 case CP0_REG17__MAAR: 7631 CP0_CHECK(ctx->mrp); 7632 gen_helper_dmfc0_maar(arg, cpu_env); 7633 register_name = "MAAR"; 7634 break; 7635 case CP0_REG17__MAARI: 7636 CP0_CHECK(ctx->mrp); 7637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7638 register_name = "MAARI"; 7639 break; 7640 default: 7641 goto cp0_unimplemented; 7642 } 7643 break; 7644 case CP0_REGISTER_18: 7645 switch (sel) { 7646 case CP0_REG18__WATCHLO0: 7647 case CP0_REG18__WATCHLO1: 7648 case CP0_REG18__WATCHLO2: 7649 case CP0_REG18__WATCHLO3: 7650 case CP0_REG18__WATCHLO4: 7651 case CP0_REG18__WATCHLO5: 7652 case CP0_REG18__WATCHLO6: 7653 case CP0_REG18__WATCHLO7: 7654 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7655 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7656 register_name = "WatchLo"; 7657 break; 7658 default: 7659 goto cp0_unimplemented; 7660 } 7661 break; 7662 case CP0_REGISTER_19: 7663 switch (sel) { 7664 case CP0_REG19__WATCHHI0: 7665 case CP0_REG19__WATCHHI1: 7666 case CP0_REG19__WATCHHI2: 7667 case CP0_REG19__WATCHHI3: 7668 case CP0_REG19__WATCHHI4: 7669 case CP0_REG19__WATCHHI5: 7670 case CP0_REG19__WATCHHI6: 7671 case CP0_REG19__WATCHHI7: 7672 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7673 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7674 register_name = "WatchHi"; 7675 break; 7676 default: 7677 goto cp0_unimplemented; 7678 } 7679 break; 7680 case CP0_REGISTER_20: 7681 switch (sel) { 7682 case CP0_REG20__XCONTEXT: 7683 check_insn(ctx, ISA_MIPS3); 7684 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7685 register_name = "XContext"; 7686 break; 7687 default: 7688 goto cp0_unimplemented; 7689 } 7690 break; 7691 case CP0_REGISTER_21: 7692 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7693 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7694 switch (sel) { 7695 case 0: 7696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7697 register_name = "Framemask"; 7698 break; 7699 default: 7700 goto cp0_unimplemented; 7701 } 7702 break; 7703 case CP0_REGISTER_22: 7704 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7705 register_name = "'Diagnostic"; /* implementation dependent */ 7706 break; 7707 case CP0_REGISTER_23: 7708 switch (sel) { 7709 case CP0_REG23__DEBUG: 7710 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7711 register_name = "Debug"; 7712 break; 7713 case CP0_REG23__TRACECONTROL: 7714 /* PDtrace support */ 7715 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7716 register_name = "TraceControl"; 7717 goto cp0_unimplemented; 7718 case CP0_REG23__TRACECONTROL2: 7719 /* PDtrace support */ 7720 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7721 register_name = "TraceControl2"; 7722 goto cp0_unimplemented; 7723 case CP0_REG23__USERTRACEDATA1: 7724 /* PDtrace support */ 7725 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7726 register_name = "UserTraceData1"; 7727 goto cp0_unimplemented; 7728 case CP0_REG23__TRACEIBPC: 7729 /* PDtrace support */ 7730 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7731 register_name = "TraceIBPC"; 7732 goto cp0_unimplemented; 7733 case CP0_REG23__TRACEDBPC: 7734 /* PDtrace support */ 7735 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7736 register_name = "TraceDBPC"; 7737 goto cp0_unimplemented; 7738 default: 7739 goto cp0_unimplemented; 7740 } 7741 break; 7742 case CP0_REGISTER_24: 7743 switch (sel) { 7744 case CP0_REG24__DEPC: 7745 /* EJTAG support */ 7746 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7747 register_name = "DEPC"; 7748 break; 7749 default: 7750 goto cp0_unimplemented; 7751 } 7752 break; 7753 case CP0_REGISTER_25: 7754 switch (sel) { 7755 case CP0_REG25__PERFCTL0: 7756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7757 register_name = "Performance0"; 7758 break; 7759 case CP0_REG25__PERFCNT0: 7760 /* gen_helper_dmfc0_performance1(arg); */ 7761 register_name = "Performance1"; 7762 goto cp0_unimplemented; 7763 case CP0_REG25__PERFCTL1: 7764 /* gen_helper_dmfc0_performance2(arg); */ 7765 register_name = "Performance2"; 7766 goto cp0_unimplemented; 7767 case CP0_REG25__PERFCNT1: 7768 /* gen_helper_dmfc0_performance3(arg); */ 7769 register_name = "Performance3"; 7770 goto cp0_unimplemented; 7771 case CP0_REG25__PERFCTL2: 7772 /* gen_helper_dmfc0_performance4(arg); */ 7773 register_name = "Performance4"; 7774 goto cp0_unimplemented; 7775 case CP0_REG25__PERFCNT2: 7776 /* gen_helper_dmfc0_performance5(arg); */ 7777 register_name = "Performance5"; 7778 goto cp0_unimplemented; 7779 case CP0_REG25__PERFCTL3: 7780 /* gen_helper_dmfc0_performance6(arg); */ 7781 register_name = "Performance6"; 7782 goto cp0_unimplemented; 7783 case CP0_REG25__PERFCNT3: 7784 /* gen_helper_dmfc0_performance7(arg); */ 7785 register_name = "Performance7"; 7786 goto cp0_unimplemented; 7787 default: 7788 goto cp0_unimplemented; 7789 } 7790 break; 7791 case CP0_REGISTER_26: 7792 switch (sel) { 7793 case CP0_REG26__ERRCTL: 7794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7795 register_name = "ErrCtl"; 7796 break; 7797 default: 7798 goto cp0_unimplemented; 7799 } 7800 break; 7801 case CP0_REGISTER_27: 7802 switch (sel) { 7803 /* ignored */ 7804 case CP0_REG27__CACHERR: 7805 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7806 register_name = "CacheErr"; 7807 break; 7808 default: 7809 goto cp0_unimplemented; 7810 } 7811 break; 7812 case CP0_REGISTER_28: 7813 switch (sel) { 7814 case CP0_REG28__TAGLO: 7815 case CP0_REG28__TAGLO1: 7816 case CP0_REG28__TAGLO2: 7817 case CP0_REG28__TAGLO3: 7818 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7819 register_name = "TagLo"; 7820 break; 7821 case CP0_REG28__DATALO: 7822 case CP0_REG28__DATALO1: 7823 case CP0_REG28__DATALO2: 7824 case CP0_REG28__DATALO3: 7825 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7826 register_name = "DataLo"; 7827 break; 7828 default: 7829 goto cp0_unimplemented; 7830 } 7831 break; 7832 case CP0_REGISTER_29: 7833 switch (sel) { 7834 case CP0_REG29__TAGHI: 7835 case CP0_REG29__TAGHI1: 7836 case CP0_REG29__TAGHI2: 7837 case CP0_REG29__TAGHI3: 7838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7839 register_name = "TagHi"; 7840 break; 7841 case CP0_REG29__DATAHI: 7842 case CP0_REG29__DATAHI1: 7843 case CP0_REG29__DATAHI2: 7844 case CP0_REG29__DATAHI3: 7845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7846 register_name = "DataHi"; 7847 break; 7848 default: 7849 goto cp0_unimplemented; 7850 } 7851 break; 7852 case CP0_REGISTER_30: 7853 switch (sel) { 7854 case CP0_REG30__ERROREPC: 7855 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7856 register_name = "ErrorEPC"; 7857 break; 7858 default: 7859 goto cp0_unimplemented; 7860 } 7861 break; 7862 case CP0_REGISTER_31: 7863 switch (sel) { 7864 case CP0_REG31__DESAVE: 7865 /* EJTAG support */ 7866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7867 register_name = "DESAVE"; 7868 break; 7869 case CP0_REG31__KSCRATCH1: 7870 case CP0_REG31__KSCRATCH2: 7871 case CP0_REG31__KSCRATCH3: 7872 case CP0_REG31__KSCRATCH4: 7873 case CP0_REG31__KSCRATCH5: 7874 case CP0_REG31__KSCRATCH6: 7875 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7876 tcg_gen_ld_tl(arg, cpu_env, 7877 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7878 register_name = "KScratch"; 7879 break; 7880 default: 7881 goto cp0_unimplemented; 7882 } 7883 break; 7884 default: 7885 goto cp0_unimplemented; 7886 } 7887 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7888 return; 7889 7890 cp0_unimplemented: 7891 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7892 register_name, reg, sel); 7893 gen_mfc0_unimplemented(ctx, arg); 7894 } 7895 7896 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7897 { 7898 const char *register_name = "invalid"; 7899 7900 if (sel != 0) { 7901 check_insn(ctx, ISA_MIPS_R1); 7902 } 7903 7904 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7905 gen_io_start(); 7906 } 7907 7908 switch (reg) { 7909 case CP0_REGISTER_00: 7910 switch (sel) { 7911 case CP0_REG00__INDEX: 7912 gen_helper_mtc0_index(cpu_env, arg); 7913 register_name = "Index"; 7914 break; 7915 case CP0_REG00__MVPCONTROL: 7916 CP0_CHECK(ctx->insn_flags & ASE_MT); 7917 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 7918 register_name = "MVPControl"; 7919 break; 7920 case CP0_REG00__MVPCONF0: 7921 CP0_CHECK(ctx->insn_flags & ASE_MT); 7922 /* ignored */ 7923 register_name = "MVPConf0"; 7924 break; 7925 case CP0_REG00__MVPCONF1: 7926 CP0_CHECK(ctx->insn_flags & ASE_MT); 7927 /* ignored */ 7928 register_name = "MVPConf1"; 7929 break; 7930 case CP0_REG00__VPCONTROL: 7931 CP0_CHECK(ctx->vp); 7932 /* ignored */ 7933 register_name = "VPControl"; 7934 break; 7935 default: 7936 goto cp0_unimplemented; 7937 } 7938 break; 7939 case CP0_REGISTER_01: 7940 switch (sel) { 7941 case CP0_REG01__RANDOM: 7942 /* ignored */ 7943 register_name = "Random"; 7944 break; 7945 case CP0_REG01__VPECONTROL: 7946 CP0_CHECK(ctx->insn_flags & ASE_MT); 7947 gen_helper_mtc0_vpecontrol(cpu_env, arg); 7948 register_name = "VPEControl"; 7949 break; 7950 case CP0_REG01__VPECONF0: 7951 CP0_CHECK(ctx->insn_flags & ASE_MT); 7952 gen_helper_mtc0_vpeconf0(cpu_env, arg); 7953 register_name = "VPEConf0"; 7954 break; 7955 case CP0_REG01__VPECONF1: 7956 CP0_CHECK(ctx->insn_flags & ASE_MT); 7957 gen_helper_mtc0_vpeconf1(cpu_env, arg); 7958 register_name = "VPEConf1"; 7959 break; 7960 case CP0_REG01__YQMASK: 7961 CP0_CHECK(ctx->insn_flags & ASE_MT); 7962 gen_helper_mtc0_yqmask(cpu_env, arg); 7963 register_name = "YQMask"; 7964 break; 7965 case CP0_REG01__VPESCHEDULE: 7966 CP0_CHECK(ctx->insn_flags & ASE_MT); 7967 tcg_gen_st_tl(arg, cpu_env, 7968 offsetof(CPUMIPSState, CP0_VPESchedule)); 7969 register_name = "VPESchedule"; 7970 break; 7971 case CP0_REG01__VPESCHEFBACK: 7972 CP0_CHECK(ctx->insn_flags & ASE_MT); 7973 tcg_gen_st_tl(arg, cpu_env, 7974 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7975 register_name = "VPEScheFBack"; 7976 break; 7977 case CP0_REG01__VPEOPT: 7978 CP0_CHECK(ctx->insn_flags & ASE_MT); 7979 gen_helper_mtc0_vpeopt(cpu_env, arg); 7980 register_name = "VPEOpt"; 7981 break; 7982 default: 7983 goto cp0_unimplemented; 7984 } 7985 break; 7986 case CP0_REGISTER_02: 7987 switch (sel) { 7988 case CP0_REG02__ENTRYLO0: 7989 gen_helper_dmtc0_entrylo0(cpu_env, arg); 7990 register_name = "EntryLo0"; 7991 break; 7992 case CP0_REG02__TCSTATUS: 7993 CP0_CHECK(ctx->insn_flags & ASE_MT); 7994 gen_helper_mtc0_tcstatus(cpu_env, arg); 7995 register_name = "TCStatus"; 7996 break; 7997 case CP0_REG02__TCBIND: 7998 CP0_CHECK(ctx->insn_flags & ASE_MT); 7999 gen_helper_mtc0_tcbind(cpu_env, arg); 8000 register_name = "TCBind"; 8001 break; 8002 case CP0_REG02__TCRESTART: 8003 CP0_CHECK(ctx->insn_flags & ASE_MT); 8004 gen_helper_mtc0_tcrestart(cpu_env, arg); 8005 register_name = "TCRestart"; 8006 break; 8007 case CP0_REG02__TCHALT: 8008 CP0_CHECK(ctx->insn_flags & ASE_MT); 8009 gen_helper_mtc0_tchalt(cpu_env, arg); 8010 register_name = "TCHalt"; 8011 break; 8012 case CP0_REG02__TCCONTEXT: 8013 CP0_CHECK(ctx->insn_flags & ASE_MT); 8014 gen_helper_mtc0_tccontext(cpu_env, arg); 8015 register_name = "TCContext"; 8016 break; 8017 case CP0_REG02__TCSCHEDULE: 8018 CP0_CHECK(ctx->insn_flags & ASE_MT); 8019 gen_helper_mtc0_tcschedule(cpu_env, arg); 8020 register_name = "TCSchedule"; 8021 break; 8022 case CP0_REG02__TCSCHEFBACK: 8023 CP0_CHECK(ctx->insn_flags & ASE_MT); 8024 gen_helper_mtc0_tcschefback(cpu_env, arg); 8025 register_name = "TCScheFBack"; 8026 break; 8027 default: 8028 goto cp0_unimplemented; 8029 } 8030 break; 8031 case CP0_REGISTER_03: 8032 switch (sel) { 8033 case CP0_REG03__ENTRYLO1: 8034 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8035 register_name = "EntryLo1"; 8036 break; 8037 case CP0_REG03__GLOBALNUM: 8038 CP0_CHECK(ctx->vp); 8039 /* ignored */ 8040 register_name = "GlobalNumber"; 8041 break; 8042 default: 8043 goto cp0_unimplemented; 8044 } 8045 break; 8046 case CP0_REGISTER_04: 8047 switch (sel) { 8048 case CP0_REG04__CONTEXT: 8049 gen_helper_mtc0_context(cpu_env, arg); 8050 register_name = "Context"; 8051 break; 8052 case CP0_REG04__CONTEXTCONFIG: 8053 /* SmartMIPS ASE */ 8054 /* gen_helper_dmtc0_contextconfig(arg); */ 8055 register_name = "ContextConfig"; 8056 goto cp0_unimplemented; 8057 case CP0_REG04__USERLOCAL: 8058 CP0_CHECK(ctx->ulri); 8059 tcg_gen_st_tl(arg, cpu_env, 8060 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8061 register_name = "UserLocal"; 8062 break; 8063 case CP0_REG04__MMID: 8064 CP0_CHECK(ctx->mi); 8065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8066 register_name = "MMID"; 8067 break; 8068 default: 8069 goto cp0_unimplemented; 8070 } 8071 break; 8072 case CP0_REGISTER_05: 8073 switch (sel) { 8074 case CP0_REG05__PAGEMASK: 8075 gen_helper_mtc0_pagemask(cpu_env, arg); 8076 register_name = "PageMask"; 8077 break; 8078 case CP0_REG05__PAGEGRAIN: 8079 check_insn(ctx, ISA_MIPS_R2); 8080 gen_helper_mtc0_pagegrain(cpu_env, arg); 8081 register_name = "PageGrain"; 8082 break; 8083 case CP0_REG05__SEGCTL0: 8084 CP0_CHECK(ctx->sc); 8085 gen_helper_mtc0_segctl0(cpu_env, arg); 8086 register_name = "SegCtl0"; 8087 break; 8088 case CP0_REG05__SEGCTL1: 8089 CP0_CHECK(ctx->sc); 8090 gen_helper_mtc0_segctl1(cpu_env, arg); 8091 register_name = "SegCtl1"; 8092 break; 8093 case CP0_REG05__SEGCTL2: 8094 CP0_CHECK(ctx->sc); 8095 gen_helper_mtc0_segctl2(cpu_env, arg); 8096 register_name = "SegCtl2"; 8097 break; 8098 case CP0_REG05__PWBASE: 8099 check_pw(ctx); 8100 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8101 register_name = "PWBase"; 8102 break; 8103 case CP0_REG05__PWFIELD: 8104 check_pw(ctx); 8105 gen_helper_mtc0_pwfield(cpu_env, arg); 8106 register_name = "PWField"; 8107 break; 8108 case CP0_REG05__PWSIZE: 8109 check_pw(ctx); 8110 gen_helper_mtc0_pwsize(cpu_env, arg); 8111 register_name = "PWSize"; 8112 break; 8113 default: 8114 goto cp0_unimplemented; 8115 } 8116 break; 8117 case CP0_REGISTER_06: 8118 switch (sel) { 8119 case CP0_REG06__WIRED: 8120 gen_helper_mtc0_wired(cpu_env, arg); 8121 register_name = "Wired"; 8122 break; 8123 case CP0_REG06__SRSCONF0: 8124 check_insn(ctx, ISA_MIPS_R2); 8125 gen_helper_mtc0_srsconf0(cpu_env, arg); 8126 register_name = "SRSConf0"; 8127 break; 8128 case CP0_REG06__SRSCONF1: 8129 check_insn(ctx, ISA_MIPS_R2); 8130 gen_helper_mtc0_srsconf1(cpu_env, arg); 8131 register_name = "SRSConf1"; 8132 break; 8133 case CP0_REG06__SRSCONF2: 8134 check_insn(ctx, ISA_MIPS_R2); 8135 gen_helper_mtc0_srsconf2(cpu_env, arg); 8136 register_name = "SRSConf2"; 8137 break; 8138 case CP0_REG06__SRSCONF3: 8139 check_insn(ctx, ISA_MIPS_R2); 8140 gen_helper_mtc0_srsconf3(cpu_env, arg); 8141 register_name = "SRSConf3"; 8142 break; 8143 case CP0_REG06__SRSCONF4: 8144 check_insn(ctx, ISA_MIPS_R2); 8145 gen_helper_mtc0_srsconf4(cpu_env, arg); 8146 register_name = "SRSConf4"; 8147 break; 8148 case CP0_REG06__PWCTL: 8149 check_pw(ctx); 8150 gen_helper_mtc0_pwctl(cpu_env, arg); 8151 register_name = "PWCtl"; 8152 break; 8153 default: 8154 goto cp0_unimplemented; 8155 } 8156 break; 8157 case CP0_REGISTER_07: 8158 switch (sel) { 8159 case CP0_REG07__HWRENA: 8160 check_insn(ctx, ISA_MIPS_R2); 8161 gen_helper_mtc0_hwrena(cpu_env, arg); 8162 ctx->base.is_jmp = DISAS_STOP; 8163 register_name = "HWREna"; 8164 break; 8165 default: 8166 goto cp0_unimplemented; 8167 } 8168 break; 8169 case CP0_REGISTER_08: 8170 switch (sel) { 8171 case CP0_REG08__BADVADDR: 8172 /* ignored */ 8173 register_name = "BadVAddr"; 8174 break; 8175 case CP0_REG08__BADINSTR: 8176 /* ignored */ 8177 register_name = "BadInstr"; 8178 break; 8179 case CP0_REG08__BADINSTRP: 8180 /* ignored */ 8181 register_name = "BadInstrP"; 8182 break; 8183 case CP0_REG08__BADINSTRX: 8184 /* ignored */ 8185 register_name = "BadInstrX"; 8186 break; 8187 default: 8188 goto cp0_unimplemented; 8189 } 8190 break; 8191 case CP0_REGISTER_09: 8192 switch (sel) { 8193 case CP0_REG09__COUNT: 8194 gen_helper_mtc0_count(cpu_env, arg); 8195 register_name = "Count"; 8196 break; 8197 case CP0_REG09__SAARI: 8198 CP0_CHECK(ctx->saar); 8199 gen_helper_mtc0_saari(cpu_env, arg); 8200 register_name = "SAARI"; 8201 break; 8202 case CP0_REG09__SAAR: 8203 CP0_CHECK(ctx->saar); 8204 gen_helper_mtc0_saar(cpu_env, arg); 8205 register_name = "SAAR"; 8206 break; 8207 default: 8208 goto cp0_unimplemented; 8209 } 8210 /* Stop translation as we may have switched the execution mode */ 8211 ctx->base.is_jmp = DISAS_STOP; 8212 break; 8213 case CP0_REGISTER_10: 8214 switch (sel) { 8215 case CP0_REG10__ENTRYHI: 8216 gen_helper_mtc0_entryhi(cpu_env, arg); 8217 register_name = "EntryHi"; 8218 break; 8219 default: 8220 goto cp0_unimplemented; 8221 } 8222 break; 8223 case CP0_REGISTER_11: 8224 switch (sel) { 8225 case CP0_REG11__COMPARE: 8226 gen_helper_mtc0_compare(cpu_env, arg); 8227 register_name = "Compare"; 8228 break; 8229 /* 6,7 are implementation dependent */ 8230 default: 8231 goto cp0_unimplemented; 8232 } 8233 /* Stop translation as we may have switched the execution mode */ 8234 ctx->base.is_jmp = DISAS_STOP; 8235 break; 8236 case CP0_REGISTER_12: 8237 switch (sel) { 8238 case CP0_REG12__STATUS: 8239 save_cpu_state(ctx, 1); 8240 gen_helper_mtc0_status(cpu_env, arg); 8241 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8242 gen_save_pc(ctx->base.pc_next + 4); 8243 ctx->base.is_jmp = DISAS_EXIT; 8244 register_name = "Status"; 8245 break; 8246 case CP0_REG12__INTCTL: 8247 check_insn(ctx, ISA_MIPS_R2); 8248 gen_helper_mtc0_intctl(cpu_env, arg); 8249 /* Stop translation as we may have switched the execution mode */ 8250 ctx->base.is_jmp = DISAS_STOP; 8251 register_name = "IntCtl"; 8252 break; 8253 case CP0_REG12__SRSCTL: 8254 check_insn(ctx, ISA_MIPS_R2); 8255 gen_helper_mtc0_srsctl(cpu_env, arg); 8256 /* Stop translation as we may have switched the execution mode */ 8257 ctx->base.is_jmp = DISAS_STOP; 8258 register_name = "SRSCtl"; 8259 break; 8260 case CP0_REG12__SRSMAP: 8261 check_insn(ctx, ISA_MIPS_R2); 8262 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8263 /* Stop translation as we may have switched the execution mode */ 8264 ctx->base.is_jmp = DISAS_STOP; 8265 register_name = "SRSMap"; 8266 break; 8267 default: 8268 goto cp0_unimplemented; 8269 } 8270 break; 8271 case CP0_REGISTER_13: 8272 switch (sel) { 8273 case CP0_REG13__CAUSE: 8274 save_cpu_state(ctx, 1); 8275 gen_helper_mtc0_cause(cpu_env, arg); 8276 /* 8277 * Stop translation as we may have triggered an interrupt. 8278 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8279 * translated code to check for pending interrupts. 8280 */ 8281 gen_save_pc(ctx->base.pc_next + 4); 8282 ctx->base.is_jmp = DISAS_EXIT; 8283 register_name = "Cause"; 8284 break; 8285 default: 8286 goto cp0_unimplemented; 8287 } 8288 break; 8289 case CP0_REGISTER_14: 8290 switch (sel) { 8291 case CP0_REG14__EPC: 8292 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8293 register_name = "EPC"; 8294 break; 8295 default: 8296 goto cp0_unimplemented; 8297 } 8298 break; 8299 case CP0_REGISTER_15: 8300 switch (sel) { 8301 case CP0_REG15__PRID: 8302 /* ignored */ 8303 register_name = "PRid"; 8304 break; 8305 case CP0_REG15__EBASE: 8306 check_insn(ctx, ISA_MIPS_R2); 8307 gen_helper_mtc0_ebase(cpu_env, arg); 8308 register_name = "EBase"; 8309 break; 8310 default: 8311 goto cp0_unimplemented; 8312 } 8313 break; 8314 case CP0_REGISTER_16: 8315 switch (sel) { 8316 case CP0_REG16__CONFIG: 8317 gen_helper_mtc0_config0(cpu_env, arg); 8318 register_name = "Config"; 8319 /* Stop translation as we may have switched the execution mode */ 8320 ctx->base.is_jmp = DISAS_STOP; 8321 break; 8322 case CP0_REG16__CONFIG1: 8323 /* ignored, read only */ 8324 register_name = "Config1"; 8325 break; 8326 case CP0_REG16__CONFIG2: 8327 gen_helper_mtc0_config2(cpu_env, arg); 8328 register_name = "Config2"; 8329 /* Stop translation as we may have switched the execution mode */ 8330 ctx->base.is_jmp = DISAS_STOP; 8331 break; 8332 case CP0_REG16__CONFIG3: 8333 gen_helper_mtc0_config3(cpu_env, arg); 8334 register_name = "Config3"; 8335 /* Stop translation as we may have switched the execution mode */ 8336 ctx->base.is_jmp = DISAS_STOP; 8337 break; 8338 case CP0_REG16__CONFIG4: 8339 /* currently ignored */ 8340 register_name = "Config4"; 8341 break; 8342 case CP0_REG16__CONFIG5: 8343 gen_helper_mtc0_config5(cpu_env, arg); 8344 register_name = "Config5"; 8345 /* Stop translation as we may have switched the execution mode */ 8346 ctx->base.is_jmp = DISAS_STOP; 8347 break; 8348 /* 6,7 are implementation dependent */ 8349 default: 8350 register_name = "Invalid config selector"; 8351 goto cp0_unimplemented; 8352 } 8353 break; 8354 case CP0_REGISTER_17: 8355 switch (sel) { 8356 case CP0_REG17__LLADDR: 8357 gen_helper_mtc0_lladdr(cpu_env, arg); 8358 register_name = "LLAddr"; 8359 break; 8360 case CP0_REG17__MAAR: 8361 CP0_CHECK(ctx->mrp); 8362 gen_helper_mtc0_maar(cpu_env, arg); 8363 register_name = "MAAR"; 8364 break; 8365 case CP0_REG17__MAARI: 8366 CP0_CHECK(ctx->mrp); 8367 gen_helper_mtc0_maari(cpu_env, arg); 8368 register_name = "MAARI"; 8369 break; 8370 default: 8371 goto cp0_unimplemented; 8372 } 8373 break; 8374 case CP0_REGISTER_18: 8375 switch (sel) { 8376 case CP0_REG18__WATCHLO0: 8377 case CP0_REG18__WATCHLO1: 8378 case CP0_REG18__WATCHLO2: 8379 case CP0_REG18__WATCHLO3: 8380 case CP0_REG18__WATCHLO4: 8381 case CP0_REG18__WATCHLO5: 8382 case CP0_REG18__WATCHLO6: 8383 case CP0_REG18__WATCHLO7: 8384 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8385 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8386 register_name = "WatchLo"; 8387 break; 8388 default: 8389 goto cp0_unimplemented; 8390 } 8391 break; 8392 case CP0_REGISTER_19: 8393 switch (sel) { 8394 case CP0_REG19__WATCHHI0: 8395 case CP0_REG19__WATCHHI1: 8396 case CP0_REG19__WATCHHI2: 8397 case CP0_REG19__WATCHHI3: 8398 case CP0_REG19__WATCHHI4: 8399 case CP0_REG19__WATCHHI5: 8400 case CP0_REG19__WATCHHI6: 8401 case CP0_REG19__WATCHHI7: 8402 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8403 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8404 register_name = "WatchHi"; 8405 break; 8406 default: 8407 goto cp0_unimplemented; 8408 } 8409 break; 8410 case CP0_REGISTER_20: 8411 switch (sel) { 8412 case CP0_REG20__XCONTEXT: 8413 check_insn(ctx, ISA_MIPS3); 8414 gen_helper_mtc0_xcontext(cpu_env, arg); 8415 register_name = "XContext"; 8416 break; 8417 default: 8418 goto cp0_unimplemented; 8419 } 8420 break; 8421 case CP0_REGISTER_21: 8422 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8423 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8424 switch (sel) { 8425 case 0: 8426 gen_helper_mtc0_framemask(cpu_env, arg); 8427 register_name = "Framemask"; 8428 break; 8429 default: 8430 goto cp0_unimplemented; 8431 } 8432 break; 8433 case CP0_REGISTER_22: 8434 /* ignored */ 8435 register_name = "Diagnostic"; /* implementation dependent */ 8436 break; 8437 case CP0_REGISTER_23: 8438 switch (sel) { 8439 case CP0_REG23__DEBUG: 8440 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8441 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8442 gen_save_pc(ctx->base.pc_next + 4); 8443 ctx->base.is_jmp = DISAS_EXIT; 8444 register_name = "Debug"; 8445 break; 8446 case CP0_REG23__TRACECONTROL: 8447 /* PDtrace support */ 8448 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8449 /* Stop translation as we may have switched the execution mode */ 8450 ctx->base.is_jmp = DISAS_STOP; 8451 register_name = "TraceControl"; 8452 goto cp0_unimplemented; 8453 case CP0_REG23__TRACECONTROL2: 8454 /* PDtrace support */ 8455 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8456 /* Stop translation as we may have switched the execution mode */ 8457 ctx->base.is_jmp = DISAS_STOP; 8458 register_name = "TraceControl2"; 8459 goto cp0_unimplemented; 8460 case CP0_REG23__USERTRACEDATA1: 8461 /* PDtrace support */ 8462 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8463 /* Stop translation as we may have switched the execution mode */ 8464 ctx->base.is_jmp = DISAS_STOP; 8465 register_name = "UserTraceData1"; 8466 goto cp0_unimplemented; 8467 case CP0_REG23__TRACEIBPC: 8468 /* PDtrace support */ 8469 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8470 /* Stop translation as we may have switched the execution mode */ 8471 ctx->base.is_jmp = DISAS_STOP; 8472 register_name = "TraceIBPC"; 8473 goto cp0_unimplemented; 8474 case CP0_REG23__TRACEDBPC: 8475 /* PDtrace support */ 8476 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8477 /* Stop translation as we may have switched the execution mode */ 8478 ctx->base.is_jmp = DISAS_STOP; 8479 register_name = "TraceDBPC"; 8480 goto cp0_unimplemented; 8481 default: 8482 goto cp0_unimplemented; 8483 } 8484 break; 8485 case CP0_REGISTER_24: 8486 switch (sel) { 8487 case CP0_REG24__DEPC: 8488 /* EJTAG support */ 8489 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8490 register_name = "DEPC"; 8491 break; 8492 default: 8493 goto cp0_unimplemented; 8494 } 8495 break; 8496 case CP0_REGISTER_25: 8497 switch (sel) { 8498 case CP0_REG25__PERFCTL0: 8499 gen_helper_mtc0_performance0(cpu_env, arg); 8500 register_name = "Performance0"; 8501 break; 8502 case CP0_REG25__PERFCNT0: 8503 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8504 register_name = "Performance1"; 8505 goto cp0_unimplemented; 8506 case CP0_REG25__PERFCTL1: 8507 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8508 register_name = "Performance2"; 8509 goto cp0_unimplemented; 8510 case CP0_REG25__PERFCNT1: 8511 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8512 register_name = "Performance3"; 8513 goto cp0_unimplemented; 8514 case CP0_REG25__PERFCTL2: 8515 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8516 register_name = "Performance4"; 8517 goto cp0_unimplemented; 8518 case CP0_REG25__PERFCNT2: 8519 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8520 register_name = "Performance5"; 8521 goto cp0_unimplemented; 8522 case CP0_REG25__PERFCTL3: 8523 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8524 register_name = "Performance6"; 8525 goto cp0_unimplemented; 8526 case CP0_REG25__PERFCNT3: 8527 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8528 register_name = "Performance7"; 8529 goto cp0_unimplemented; 8530 default: 8531 goto cp0_unimplemented; 8532 } 8533 break; 8534 case CP0_REGISTER_26: 8535 switch (sel) { 8536 case CP0_REG26__ERRCTL: 8537 gen_helper_mtc0_errctl(cpu_env, arg); 8538 ctx->base.is_jmp = DISAS_STOP; 8539 register_name = "ErrCtl"; 8540 break; 8541 default: 8542 goto cp0_unimplemented; 8543 } 8544 break; 8545 case CP0_REGISTER_27: 8546 switch (sel) { 8547 case CP0_REG27__CACHERR: 8548 /* ignored */ 8549 register_name = "CacheErr"; 8550 break; 8551 default: 8552 goto cp0_unimplemented; 8553 } 8554 break; 8555 case CP0_REGISTER_28: 8556 switch (sel) { 8557 case CP0_REG28__TAGLO: 8558 case CP0_REG28__TAGLO1: 8559 case CP0_REG28__TAGLO2: 8560 case CP0_REG28__TAGLO3: 8561 gen_helper_mtc0_taglo(cpu_env, arg); 8562 register_name = "TagLo"; 8563 break; 8564 case CP0_REG28__DATALO: 8565 case CP0_REG28__DATALO1: 8566 case CP0_REG28__DATALO2: 8567 case CP0_REG28__DATALO3: 8568 gen_helper_mtc0_datalo(cpu_env, arg); 8569 register_name = "DataLo"; 8570 break; 8571 default: 8572 goto cp0_unimplemented; 8573 } 8574 break; 8575 case CP0_REGISTER_29: 8576 switch (sel) { 8577 case CP0_REG29__TAGHI: 8578 case CP0_REG29__TAGHI1: 8579 case CP0_REG29__TAGHI2: 8580 case CP0_REG29__TAGHI3: 8581 gen_helper_mtc0_taghi(cpu_env, arg); 8582 register_name = "TagHi"; 8583 break; 8584 case CP0_REG29__DATAHI: 8585 case CP0_REG29__DATAHI1: 8586 case CP0_REG29__DATAHI2: 8587 case CP0_REG29__DATAHI3: 8588 gen_helper_mtc0_datahi(cpu_env, arg); 8589 register_name = "DataHi"; 8590 break; 8591 default: 8592 register_name = "invalid sel"; 8593 goto cp0_unimplemented; 8594 } 8595 break; 8596 case CP0_REGISTER_30: 8597 switch (sel) { 8598 case CP0_REG30__ERROREPC: 8599 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8600 register_name = "ErrorEPC"; 8601 break; 8602 default: 8603 goto cp0_unimplemented; 8604 } 8605 break; 8606 case CP0_REGISTER_31: 8607 switch (sel) { 8608 case CP0_REG31__DESAVE: 8609 /* EJTAG support */ 8610 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8611 register_name = "DESAVE"; 8612 break; 8613 case CP0_REG31__KSCRATCH1: 8614 case CP0_REG31__KSCRATCH2: 8615 case CP0_REG31__KSCRATCH3: 8616 case CP0_REG31__KSCRATCH4: 8617 case CP0_REG31__KSCRATCH5: 8618 case CP0_REG31__KSCRATCH6: 8619 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8620 tcg_gen_st_tl(arg, cpu_env, 8621 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8622 register_name = "KScratch"; 8623 break; 8624 default: 8625 goto cp0_unimplemented; 8626 } 8627 break; 8628 default: 8629 goto cp0_unimplemented; 8630 } 8631 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8632 8633 /* For simplicity assume that all writes can cause interrupts. */ 8634 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8635 /* 8636 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8637 * translated code to check for pending interrupts. 8638 */ 8639 gen_save_pc(ctx->base.pc_next + 4); 8640 ctx->base.is_jmp = DISAS_EXIT; 8641 } 8642 return; 8643 8644 cp0_unimplemented: 8645 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8646 register_name, reg, sel); 8647 } 8648 #endif /* TARGET_MIPS64 */ 8649 8650 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8651 int u, int sel, int h) 8652 { 8653 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8654 TCGv t0 = tcg_temp_local_new(); 8655 8656 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8657 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8658 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8659 tcg_gen_movi_tl(t0, -1); 8660 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8661 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8662 tcg_gen_movi_tl(t0, -1); 8663 } else if (u == 0) { 8664 switch (rt) { 8665 case 1: 8666 switch (sel) { 8667 case 1: 8668 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8669 break; 8670 case 2: 8671 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8672 break; 8673 default: 8674 goto die; 8675 break; 8676 } 8677 break; 8678 case 2: 8679 switch (sel) { 8680 case 1: 8681 gen_helper_mftc0_tcstatus(t0, cpu_env); 8682 break; 8683 case 2: 8684 gen_helper_mftc0_tcbind(t0, cpu_env); 8685 break; 8686 case 3: 8687 gen_helper_mftc0_tcrestart(t0, cpu_env); 8688 break; 8689 case 4: 8690 gen_helper_mftc0_tchalt(t0, cpu_env); 8691 break; 8692 case 5: 8693 gen_helper_mftc0_tccontext(t0, cpu_env); 8694 break; 8695 case 6: 8696 gen_helper_mftc0_tcschedule(t0, cpu_env); 8697 break; 8698 case 7: 8699 gen_helper_mftc0_tcschefback(t0, cpu_env); 8700 break; 8701 default: 8702 gen_mfc0(ctx, t0, rt, sel); 8703 break; 8704 } 8705 break; 8706 case 10: 8707 switch (sel) { 8708 case 0: 8709 gen_helper_mftc0_entryhi(t0, cpu_env); 8710 break; 8711 default: 8712 gen_mfc0(ctx, t0, rt, sel); 8713 break; 8714 } 8715 break; 8716 case 12: 8717 switch (sel) { 8718 case 0: 8719 gen_helper_mftc0_status(t0, cpu_env); 8720 break; 8721 default: 8722 gen_mfc0(ctx, t0, rt, sel); 8723 break; 8724 } 8725 break; 8726 case 13: 8727 switch (sel) { 8728 case 0: 8729 gen_helper_mftc0_cause(t0, cpu_env); 8730 break; 8731 default: 8732 goto die; 8733 break; 8734 } 8735 break; 8736 case 14: 8737 switch (sel) { 8738 case 0: 8739 gen_helper_mftc0_epc(t0, cpu_env); 8740 break; 8741 default: 8742 goto die; 8743 break; 8744 } 8745 break; 8746 case 15: 8747 switch (sel) { 8748 case 1: 8749 gen_helper_mftc0_ebase(t0, cpu_env); 8750 break; 8751 default: 8752 goto die; 8753 break; 8754 } 8755 break; 8756 case 16: 8757 switch (sel) { 8758 case 0: 8759 case 1: 8760 case 2: 8761 case 3: 8762 case 4: 8763 case 5: 8764 case 6: 8765 case 7: 8766 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 8767 break; 8768 default: 8769 goto die; 8770 break; 8771 } 8772 break; 8773 case 23: 8774 switch (sel) { 8775 case 0: 8776 gen_helper_mftc0_debug(t0, cpu_env); 8777 break; 8778 default: 8779 gen_mfc0(ctx, t0, rt, sel); 8780 break; 8781 } 8782 break; 8783 default: 8784 gen_mfc0(ctx, t0, rt, sel); 8785 } 8786 } else { 8787 switch (sel) { 8788 /* GPR registers. */ 8789 case 0: 8790 gen_helper_1e0i(mftgpr, t0, rt); 8791 break; 8792 /* Auxiliary CPU registers */ 8793 case 1: 8794 switch (rt) { 8795 case 0: 8796 gen_helper_1e0i(mftlo, t0, 0); 8797 break; 8798 case 1: 8799 gen_helper_1e0i(mfthi, t0, 0); 8800 break; 8801 case 2: 8802 gen_helper_1e0i(mftacx, t0, 0); 8803 break; 8804 case 4: 8805 gen_helper_1e0i(mftlo, t0, 1); 8806 break; 8807 case 5: 8808 gen_helper_1e0i(mfthi, t0, 1); 8809 break; 8810 case 6: 8811 gen_helper_1e0i(mftacx, t0, 1); 8812 break; 8813 case 8: 8814 gen_helper_1e0i(mftlo, t0, 2); 8815 break; 8816 case 9: 8817 gen_helper_1e0i(mfthi, t0, 2); 8818 break; 8819 case 10: 8820 gen_helper_1e0i(mftacx, t0, 2); 8821 break; 8822 case 12: 8823 gen_helper_1e0i(mftlo, t0, 3); 8824 break; 8825 case 13: 8826 gen_helper_1e0i(mfthi, t0, 3); 8827 break; 8828 case 14: 8829 gen_helper_1e0i(mftacx, t0, 3); 8830 break; 8831 case 16: 8832 gen_helper_mftdsp(t0, cpu_env); 8833 break; 8834 default: 8835 goto die; 8836 } 8837 break; 8838 /* Floating point (COP1). */ 8839 case 2: 8840 /* XXX: For now we support only a single FPU context. */ 8841 if (h == 0) { 8842 TCGv_i32 fp0 = tcg_temp_new_i32(); 8843 8844 gen_load_fpr32(ctx, fp0, rt); 8845 tcg_gen_ext_i32_tl(t0, fp0); 8846 tcg_temp_free_i32(fp0); 8847 } else { 8848 TCGv_i32 fp0 = tcg_temp_new_i32(); 8849 8850 gen_load_fpr32h(ctx, fp0, rt); 8851 tcg_gen_ext_i32_tl(t0, fp0); 8852 tcg_temp_free_i32(fp0); 8853 } 8854 break; 8855 case 3: 8856 /* XXX: For now we support only a single FPU context. */ 8857 gen_helper_1e0i(cfc1, t0, rt); 8858 break; 8859 /* COP2: Not implemented. */ 8860 case 4: 8861 case 5: 8862 /* fall through */ 8863 default: 8864 goto die; 8865 } 8866 } 8867 trace_mips_translate_tr("mftr", rt, u, sel, h); 8868 gen_store_gpr(t0, rd); 8869 tcg_temp_free(t0); 8870 return; 8871 8872 die: 8873 tcg_temp_free(t0); 8874 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8875 gen_reserved_instruction(ctx); 8876 } 8877 8878 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8879 int u, int sel, int h) 8880 { 8881 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8882 TCGv t0 = tcg_temp_local_new(); 8883 8884 gen_load_gpr(t0, rt); 8885 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8886 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8887 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8888 /* NOP */ 8889 ; 8890 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8891 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8892 /* NOP */ 8893 ; 8894 } else if (u == 0) { 8895 switch (rd) { 8896 case 1: 8897 switch (sel) { 8898 case 1: 8899 gen_helper_mttc0_vpecontrol(cpu_env, t0); 8900 break; 8901 case 2: 8902 gen_helper_mttc0_vpeconf0(cpu_env, t0); 8903 break; 8904 default: 8905 goto die; 8906 break; 8907 } 8908 break; 8909 case 2: 8910 switch (sel) { 8911 case 1: 8912 gen_helper_mttc0_tcstatus(cpu_env, t0); 8913 break; 8914 case 2: 8915 gen_helper_mttc0_tcbind(cpu_env, t0); 8916 break; 8917 case 3: 8918 gen_helper_mttc0_tcrestart(cpu_env, t0); 8919 break; 8920 case 4: 8921 gen_helper_mttc0_tchalt(cpu_env, t0); 8922 break; 8923 case 5: 8924 gen_helper_mttc0_tccontext(cpu_env, t0); 8925 break; 8926 case 6: 8927 gen_helper_mttc0_tcschedule(cpu_env, t0); 8928 break; 8929 case 7: 8930 gen_helper_mttc0_tcschefback(cpu_env, t0); 8931 break; 8932 default: 8933 gen_mtc0(ctx, t0, rd, sel); 8934 break; 8935 } 8936 break; 8937 case 10: 8938 switch (sel) { 8939 case 0: 8940 gen_helper_mttc0_entryhi(cpu_env, t0); 8941 break; 8942 default: 8943 gen_mtc0(ctx, t0, rd, sel); 8944 break; 8945 } 8946 break; 8947 case 12: 8948 switch (sel) { 8949 case 0: 8950 gen_helper_mttc0_status(cpu_env, t0); 8951 break; 8952 default: 8953 gen_mtc0(ctx, t0, rd, sel); 8954 break; 8955 } 8956 break; 8957 case 13: 8958 switch (sel) { 8959 case 0: 8960 gen_helper_mttc0_cause(cpu_env, t0); 8961 break; 8962 default: 8963 goto die; 8964 break; 8965 } 8966 break; 8967 case 15: 8968 switch (sel) { 8969 case 1: 8970 gen_helper_mttc0_ebase(cpu_env, t0); 8971 break; 8972 default: 8973 goto die; 8974 break; 8975 } 8976 break; 8977 case 23: 8978 switch (sel) { 8979 case 0: 8980 gen_helper_mttc0_debug(cpu_env, t0); 8981 break; 8982 default: 8983 gen_mtc0(ctx, t0, rd, sel); 8984 break; 8985 } 8986 break; 8987 default: 8988 gen_mtc0(ctx, t0, rd, sel); 8989 } 8990 } else { 8991 switch (sel) { 8992 /* GPR registers. */ 8993 case 0: 8994 gen_helper_0e1i(mttgpr, t0, rd); 8995 break; 8996 /* Auxiliary CPU registers */ 8997 case 1: 8998 switch (rd) { 8999 case 0: 9000 gen_helper_0e1i(mttlo, t0, 0); 9001 break; 9002 case 1: 9003 gen_helper_0e1i(mtthi, t0, 0); 9004 break; 9005 case 2: 9006 gen_helper_0e1i(mttacx, t0, 0); 9007 break; 9008 case 4: 9009 gen_helper_0e1i(mttlo, t0, 1); 9010 break; 9011 case 5: 9012 gen_helper_0e1i(mtthi, t0, 1); 9013 break; 9014 case 6: 9015 gen_helper_0e1i(mttacx, t0, 1); 9016 break; 9017 case 8: 9018 gen_helper_0e1i(mttlo, t0, 2); 9019 break; 9020 case 9: 9021 gen_helper_0e1i(mtthi, t0, 2); 9022 break; 9023 case 10: 9024 gen_helper_0e1i(mttacx, t0, 2); 9025 break; 9026 case 12: 9027 gen_helper_0e1i(mttlo, t0, 3); 9028 break; 9029 case 13: 9030 gen_helper_0e1i(mtthi, t0, 3); 9031 break; 9032 case 14: 9033 gen_helper_0e1i(mttacx, t0, 3); 9034 break; 9035 case 16: 9036 gen_helper_mttdsp(cpu_env, t0); 9037 break; 9038 default: 9039 goto die; 9040 } 9041 break; 9042 /* Floating point (COP1). */ 9043 case 2: 9044 /* XXX: For now we support only a single FPU context. */ 9045 if (h == 0) { 9046 TCGv_i32 fp0 = tcg_temp_new_i32(); 9047 9048 tcg_gen_trunc_tl_i32(fp0, t0); 9049 gen_store_fpr32(ctx, fp0, rd); 9050 tcg_temp_free_i32(fp0); 9051 } else { 9052 TCGv_i32 fp0 = tcg_temp_new_i32(); 9053 9054 tcg_gen_trunc_tl_i32(fp0, t0); 9055 gen_store_fpr32h(ctx, fp0, rd); 9056 tcg_temp_free_i32(fp0); 9057 } 9058 break; 9059 case 3: 9060 /* XXX: For now we support only a single FPU context. */ 9061 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 9062 /* Stop translation as we may have changed hflags */ 9063 ctx->base.is_jmp = DISAS_STOP; 9064 break; 9065 /* COP2: Not implemented. */ 9066 case 4: 9067 case 5: 9068 /* fall through */ 9069 default: 9070 goto die; 9071 } 9072 } 9073 trace_mips_translate_tr("mttr", rd, u, sel, h); 9074 tcg_temp_free(t0); 9075 return; 9076 9077 die: 9078 tcg_temp_free(t0); 9079 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9080 gen_reserved_instruction(ctx); 9081 } 9082 9083 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9084 int rt, int rd) 9085 { 9086 const char *opn = "ldst"; 9087 9088 check_cp0_enabled(ctx); 9089 switch (opc) { 9090 case OPC_MFC0: 9091 if (rt == 0) { 9092 /* Treat as NOP. */ 9093 return; 9094 } 9095 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9096 opn = "mfc0"; 9097 break; 9098 case OPC_MTC0: 9099 { 9100 TCGv t0 = tcg_temp_new(); 9101 9102 gen_load_gpr(t0, rt); 9103 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9104 tcg_temp_free(t0); 9105 } 9106 opn = "mtc0"; 9107 break; 9108 #if defined(TARGET_MIPS64) 9109 case OPC_DMFC0: 9110 check_insn(ctx, ISA_MIPS3); 9111 if (rt == 0) { 9112 /* Treat as NOP. */ 9113 return; 9114 } 9115 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9116 opn = "dmfc0"; 9117 break; 9118 case OPC_DMTC0: 9119 check_insn(ctx, ISA_MIPS3); 9120 { 9121 TCGv t0 = tcg_temp_new(); 9122 9123 gen_load_gpr(t0, rt); 9124 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9125 tcg_temp_free(t0); 9126 } 9127 opn = "dmtc0"; 9128 break; 9129 #endif 9130 case OPC_MFHC0: 9131 check_mvh(ctx); 9132 if (rt == 0) { 9133 /* Treat as NOP. */ 9134 return; 9135 } 9136 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9137 opn = "mfhc0"; 9138 break; 9139 case OPC_MTHC0: 9140 check_mvh(ctx); 9141 { 9142 TCGv t0 = tcg_temp_new(); 9143 gen_load_gpr(t0, rt); 9144 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9145 tcg_temp_free(t0); 9146 } 9147 opn = "mthc0"; 9148 break; 9149 case OPC_MFTR: 9150 check_cp0_enabled(ctx); 9151 if (rd == 0) { 9152 /* Treat as NOP. */ 9153 return; 9154 } 9155 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9156 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9157 opn = "mftr"; 9158 break; 9159 case OPC_MTTR: 9160 check_cp0_enabled(ctx); 9161 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9162 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9163 opn = "mttr"; 9164 break; 9165 case OPC_TLBWI: 9166 opn = "tlbwi"; 9167 if (!env->tlb->helper_tlbwi) { 9168 goto die; 9169 } 9170 gen_helper_tlbwi(cpu_env); 9171 break; 9172 case OPC_TLBINV: 9173 opn = "tlbinv"; 9174 if (ctx->ie >= 2) { 9175 if (!env->tlb->helper_tlbinv) { 9176 goto die; 9177 } 9178 gen_helper_tlbinv(cpu_env); 9179 } /* treat as nop if TLBINV not supported */ 9180 break; 9181 case OPC_TLBINVF: 9182 opn = "tlbinvf"; 9183 if (ctx->ie >= 2) { 9184 if (!env->tlb->helper_tlbinvf) { 9185 goto die; 9186 } 9187 gen_helper_tlbinvf(cpu_env); 9188 } /* treat as nop if TLBINV not supported */ 9189 break; 9190 case OPC_TLBWR: 9191 opn = "tlbwr"; 9192 if (!env->tlb->helper_tlbwr) { 9193 goto die; 9194 } 9195 gen_helper_tlbwr(cpu_env); 9196 break; 9197 case OPC_TLBP: 9198 opn = "tlbp"; 9199 if (!env->tlb->helper_tlbp) { 9200 goto die; 9201 } 9202 gen_helper_tlbp(cpu_env); 9203 break; 9204 case OPC_TLBR: 9205 opn = "tlbr"; 9206 if (!env->tlb->helper_tlbr) { 9207 goto die; 9208 } 9209 gen_helper_tlbr(cpu_env); 9210 break; 9211 case OPC_ERET: /* OPC_ERETNC */ 9212 if ((ctx->insn_flags & ISA_MIPS_R6) && 9213 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9214 goto die; 9215 } else { 9216 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9217 if (ctx->opcode & (1 << bit_shift)) { 9218 /* OPC_ERETNC */ 9219 opn = "eretnc"; 9220 check_insn(ctx, ISA_MIPS_R5); 9221 gen_helper_eretnc(cpu_env); 9222 } else { 9223 /* OPC_ERET */ 9224 opn = "eret"; 9225 check_insn(ctx, ISA_MIPS2); 9226 gen_helper_eret(cpu_env); 9227 } 9228 ctx->base.is_jmp = DISAS_EXIT; 9229 } 9230 break; 9231 case OPC_DERET: 9232 opn = "deret"; 9233 check_insn(ctx, ISA_MIPS_R1); 9234 if ((ctx->insn_flags & ISA_MIPS_R6) && 9235 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9236 goto die; 9237 } 9238 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9239 MIPS_INVAL(opn); 9240 gen_reserved_instruction(ctx); 9241 } else { 9242 gen_helper_deret(cpu_env); 9243 ctx->base.is_jmp = DISAS_EXIT; 9244 } 9245 break; 9246 case OPC_WAIT: 9247 opn = "wait"; 9248 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9249 if ((ctx->insn_flags & ISA_MIPS_R6) && 9250 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9251 goto die; 9252 } 9253 /* If we get an exception, we want to restart at next instruction */ 9254 ctx->base.pc_next += 4; 9255 save_cpu_state(ctx, 1); 9256 ctx->base.pc_next -= 4; 9257 gen_helper_wait(cpu_env); 9258 ctx->base.is_jmp = DISAS_NORETURN; 9259 break; 9260 default: 9261 die: 9262 MIPS_INVAL(opn); 9263 gen_reserved_instruction(ctx); 9264 return; 9265 } 9266 (void)opn; /* avoid a compiler warning */ 9267 } 9268 #endif /* !CONFIG_USER_ONLY */ 9269 9270 /* CP1 Branches (before delay slot) */ 9271 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9272 int32_t cc, int32_t offset) 9273 { 9274 target_ulong btarget; 9275 TCGv_i32 t0 = tcg_temp_new_i32(); 9276 9277 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9278 gen_reserved_instruction(ctx); 9279 goto out; 9280 } 9281 9282 if (cc != 0) { 9283 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9284 } 9285 9286 btarget = ctx->base.pc_next + 4 + offset; 9287 9288 switch (op) { 9289 case OPC_BC1F: 9290 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9291 tcg_gen_not_i32(t0, t0); 9292 tcg_gen_andi_i32(t0, t0, 1); 9293 tcg_gen_extu_i32_tl(bcond, t0); 9294 goto not_likely; 9295 case OPC_BC1FL: 9296 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9297 tcg_gen_not_i32(t0, t0); 9298 tcg_gen_andi_i32(t0, t0, 1); 9299 tcg_gen_extu_i32_tl(bcond, t0); 9300 goto likely; 9301 case OPC_BC1T: 9302 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9303 tcg_gen_andi_i32(t0, t0, 1); 9304 tcg_gen_extu_i32_tl(bcond, t0); 9305 goto not_likely; 9306 case OPC_BC1TL: 9307 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9308 tcg_gen_andi_i32(t0, t0, 1); 9309 tcg_gen_extu_i32_tl(bcond, t0); 9310 likely: 9311 ctx->hflags |= MIPS_HFLAG_BL; 9312 break; 9313 case OPC_BC1FANY2: 9314 { 9315 TCGv_i32 t1 = tcg_temp_new_i32(); 9316 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9317 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9318 tcg_gen_nand_i32(t0, t0, t1); 9319 tcg_temp_free_i32(t1); 9320 tcg_gen_andi_i32(t0, t0, 1); 9321 tcg_gen_extu_i32_tl(bcond, t0); 9322 } 9323 goto not_likely; 9324 case OPC_BC1TANY2: 9325 { 9326 TCGv_i32 t1 = tcg_temp_new_i32(); 9327 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9328 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9329 tcg_gen_or_i32(t0, t0, t1); 9330 tcg_temp_free_i32(t1); 9331 tcg_gen_andi_i32(t0, t0, 1); 9332 tcg_gen_extu_i32_tl(bcond, t0); 9333 } 9334 goto not_likely; 9335 case OPC_BC1FANY4: 9336 { 9337 TCGv_i32 t1 = tcg_temp_new_i32(); 9338 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9339 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9340 tcg_gen_and_i32(t0, t0, t1); 9341 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9342 tcg_gen_and_i32(t0, t0, t1); 9343 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9344 tcg_gen_nand_i32(t0, t0, t1); 9345 tcg_temp_free_i32(t1); 9346 tcg_gen_andi_i32(t0, t0, 1); 9347 tcg_gen_extu_i32_tl(bcond, t0); 9348 } 9349 goto not_likely; 9350 case OPC_BC1TANY4: 9351 { 9352 TCGv_i32 t1 = tcg_temp_new_i32(); 9353 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9354 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9355 tcg_gen_or_i32(t0, t0, t1); 9356 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9357 tcg_gen_or_i32(t0, t0, t1); 9358 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9359 tcg_gen_or_i32(t0, t0, t1); 9360 tcg_temp_free_i32(t1); 9361 tcg_gen_andi_i32(t0, t0, 1); 9362 tcg_gen_extu_i32_tl(bcond, t0); 9363 } 9364 not_likely: 9365 ctx->hflags |= MIPS_HFLAG_BC; 9366 break; 9367 default: 9368 MIPS_INVAL("cp1 cond branch"); 9369 gen_reserved_instruction(ctx); 9370 goto out; 9371 } 9372 ctx->btarget = btarget; 9373 ctx->hflags |= MIPS_HFLAG_BDS32; 9374 out: 9375 tcg_temp_free_i32(t0); 9376 } 9377 9378 /* R6 CP1 Branches */ 9379 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9380 int32_t ft, int32_t offset, 9381 int delayslot_size) 9382 { 9383 target_ulong btarget; 9384 TCGv_i64 t0 = tcg_temp_new_i64(); 9385 9386 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9387 #ifdef MIPS_DEBUG_DISAS 9388 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9389 "\n", ctx->base.pc_next); 9390 #endif 9391 gen_reserved_instruction(ctx); 9392 goto out; 9393 } 9394 9395 gen_load_fpr64(ctx, t0, ft); 9396 tcg_gen_andi_i64(t0, t0, 1); 9397 9398 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9399 9400 switch (op) { 9401 case OPC_BC1EQZ: 9402 tcg_gen_xori_i64(t0, t0, 1); 9403 ctx->hflags |= MIPS_HFLAG_BC; 9404 break; 9405 case OPC_BC1NEZ: 9406 /* t0 already set */ 9407 ctx->hflags |= MIPS_HFLAG_BC; 9408 break; 9409 default: 9410 MIPS_INVAL("cp1 cond branch"); 9411 gen_reserved_instruction(ctx); 9412 goto out; 9413 } 9414 9415 tcg_gen_trunc_i64_tl(bcond, t0); 9416 9417 ctx->btarget = btarget; 9418 9419 switch (delayslot_size) { 9420 case 2: 9421 ctx->hflags |= MIPS_HFLAG_BDS16; 9422 break; 9423 case 4: 9424 ctx->hflags |= MIPS_HFLAG_BDS32; 9425 break; 9426 } 9427 9428 out: 9429 tcg_temp_free_i64(t0); 9430 } 9431 9432 /* Coprocessor 1 (FPU) */ 9433 9434 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9435 9436 enum fopcode { 9437 OPC_ADD_S = FOP(0, FMT_S), 9438 OPC_SUB_S = FOP(1, FMT_S), 9439 OPC_MUL_S = FOP(2, FMT_S), 9440 OPC_DIV_S = FOP(3, FMT_S), 9441 OPC_SQRT_S = FOP(4, FMT_S), 9442 OPC_ABS_S = FOP(5, FMT_S), 9443 OPC_MOV_S = FOP(6, FMT_S), 9444 OPC_NEG_S = FOP(7, FMT_S), 9445 OPC_ROUND_L_S = FOP(8, FMT_S), 9446 OPC_TRUNC_L_S = FOP(9, FMT_S), 9447 OPC_CEIL_L_S = FOP(10, FMT_S), 9448 OPC_FLOOR_L_S = FOP(11, FMT_S), 9449 OPC_ROUND_W_S = FOP(12, FMT_S), 9450 OPC_TRUNC_W_S = FOP(13, FMT_S), 9451 OPC_CEIL_W_S = FOP(14, FMT_S), 9452 OPC_FLOOR_W_S = FOP(15, FMT_S), 9453 OPC_SEL_S = FOP(16, FMT_S), 9454 OPC_MOVCF_S = FOP(17, FMT_S), 9455 OPC_MOVZ_S = FOP(18, FMT_S), 9456 OPC_MOVN_S = FOP(19, FMT_S), 9457 OPC_SELEQZ_S = FOP(20, FMT_S), 9458 OPC_RECIP_S = FOP(21, FMT_S), 9459 OPC_RSQRT_S = FOP(22, FMT_S), 9460 OPC_SELNEZ_S = FOP(23, FMT_S), 9461 OPC_MADDF_S = FOP(24, FMT_S), 9462 OPC_MSUBF_S = FOP(25, FMT_S), 9463 OPC_RINT_S = FOP(26, FMT_S), 9464 OPC_CLASS_S = FOP(27, FMT_S), 9465 OPC_MIN_S = FOP(28, FMT_S), 9466 OPC_RECIP2_S = FOP(28, FMT_S), 9467 OPC_MINA_S = FOP(29, FMT_S), 9468 OPC_RECIP1_S = FOP(29, FMT_S), 9469 OPC_MAX_S = FOP(30, FMT_S), 9470 OPC_RSQRT1_S = FOP(30, FMT_S), 9471 OPC_MAXA_S = FOP(31, FMT_S), 9472 OPC_RSQRT2_S = FOP(31, FMT_S), 9473 OPC_CVT_D_S = FOP(33, FMT_S), 9474 OPC_CVT_W_S = FOP(36, FMT_S), 9475 OPC_CVT_L_S = FOP(37, FMT_S), 9476 OPC_CVT_PS_S = FOP(38, FMT_S), 9477 OPC_CMP_F_S = FOP(48, FMT_S), 9478 OPC_CMP_UN_S = FOP(49, FMT_S), 9479 OPC_CMP_EQ_S = FOP(50, FMT_S), 9480 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9481 OPC_CMP_OLT_S = FOP(52, FMT_S), 9482 OPC_CMP_ULT_S = FOP(53, FMT_S), 9483 OPC_CMP_OLE_S = FOP(54, FMT_S), 9484 OPC_CMP_ULE_S = FOP(55, FMT_S), 9485 OPC_CMP_SF_S = FOP(56, FMT_S), 9486 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9487 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9488 OPC_CMP_NGL_S = FOP(59, FMT_S), 9489 OPC_CMP_LT_S = FOP(60, FMT_S), 9490 OPC_CMP_NGE_S = FOP(61, FMT_S), 9491 OPC_CMP_LE_S = FOP(62, FMT_S), 9492 OPC_CMP_NGT_S = FOP(63, FMT_S), 9493 9494 OPC_ADD_D = FOP(0, FMT_D), 9495 OPC_SUB_D = FOP(1, FMT_D), 9496 OPC_MUL_D = FOP(2, FMT_D), 9497 OPC_DIV_D = FOP(3, FMT_D), 9498 OPC_SQRT_D = FOP(4, FMT_D), 9499 OPC_ABS_D = FOP(5, FMT_D), 9500 OPC_MOV_D = FOP(6, FMT_D), 9501 OPC_NEG_D = FOP(7, FMT_D), 9502 OPC_ROUND_L_D = FOP(8, FMT_D), 9503 OPC_TRUNC_L_D = FOP(9, FMT_D), 9504 OPC_CEIL_L_D = FOP(10, FMT_D), 9505 OPC_FLOOR_L_D = FOP(11, FMT_D), 9506 OPC_ROUND_W_D = FOP(12, FMT_D), 9507 OPC_TRUNC_W_D = FOP(13, FMT_D), 9508 OPC_CEIL_W_D = FOP(14, FMT_D), 9509 OPC_FLOOR_W_D = FOP(15, FMT_D), 9510 OPC_SEL_D = FOP(16, FMT_D), 9511 OPC_MOVCF_D = FOP(17, FMT_D), 9512 OPC_MOVZ_D = FOP(18, FMT_D), 9513 OPC_MOVN_D = FOP(19, FMT_D), 9514 OPC_SELEQZ_D = FOP(20, FMT_D), 9515 OPC_RECIP_D = FOP(21, FMT_D), 9516 OPC_RSQRT_D = FOP(22, FMT_D), 9517 OPC_SELNEZ_D = FOP(23, FMT_D), 9518 OPC_MADDF_D = FOP(24, FMT_D), 9519 OPC_MSUBF_D = FOP(25, FMT_D), 9520 OPC_RINT_D = FOP(26, FMT_D), 9521 OPC_CLASS_D = FOP(27, FMT_D), 9522 OPC_MIN_D = FOP(28, FMT_D), 9523 OPC_RECIP2_D = FOP(28, FMT_D), 9524 OPC_MINA_D = FOP(29, FMT_D), 9525 OPC_RECIP1_D = FOP(29, FMT_D), 9526 OPC_MAX_D = FOP(30, FMT_D), 9527 OPC_RSQRT1_D = FOP(30, FMT_D), 9528 OPC_MAXA_D = FOP(31, FMT_D), 9529 OPC_RSQRT2_D = FOP(31, FMT_D), 9530 OPC_CVT_S_D = FOP(32, FMT_D), 9531 OPC_CVT_W_D = FOP(36, FMT_D), 9532 OPC_CVT_L_D = FOP(37, FMT_D), 9533 OPC_CMP_F_D = FOP(48, FMT_D), 9534 OPC_CMP_UN_D = FOP(49, FMT_D), 9535 OPC_CMP_EQ_D = FOP(50, FMT_D), 9536 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9537 OPC_CMP_OLT_D = FOP(52, FMT_D), 9538 OPC_CMP_ULT_D = FOP(53, FMT_D), 9539 OPC_CMP_OLE_D = FOP(54, FMT_D), 9540 OPC_CMP_ULE_D = FOP(55, FMT_D), 9541 OPC_CMP_SF_D = FOP(56, FMT_D), 9542 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9543 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9544 OPC_CMP_NGL_D = FOP(59, FMT_D), 9545 OPC_CMP_LT_D = FOP(60, FMT_D), 9546 OPC_CMP_NGE_D = FOP(61, FMT_D), 9547 OPC_CMP_LE_D = FOP(62, FMT_D), 9548 OPC_CMP_NGT_D = FOP(63, FMT_D), 9549 9550 OPC_CVT_S_W = FOP(32, FMT_W), 9551 OPC_CVT_D_W = FOP(33, FMT_W), 9552 OPC_CVT_S_L = FOP(32, FMT_L), 9553 OPC_CVT_D_L = FOP(33, FMT_L), 9554 OPC_CVT_PS_PW = FOP(38, FMT_W), 9555 9556 OPC_ADD_PS = FOP(0, FMT_PS), 9557 OPC_SUB_PS = FOP(1, FMT_PS), 9558 OPC_MUL_PS = FOP(2, FMT_PS), 9559 OPC_DIV_PS = FOP(3, FMT_PS), 9560 OPC_ABS_PS = FOP(5, FMT_PS), 9561 OPC_MOV_PS = FOP(6, FMT_PS), 9562 OPC_NEG_PS = FOP(7, FMT_PS), 9563 OPC_MOVCF_PS = FOP(17, FMT_PS), 9564 OPC_MOVZ_PS = FOP(18, FMT_PS), 9565 OPC_MOVN_PS = FOP(19, FMT_PS), 9566 OPC_ADDR_PS = FOP(24, FMT_PS), 9567 OPC_MULR_PS = FOP(26, FMT_PS), 9568 OPC_RECIP2_PS = FOP(28, FMT_PS), 9569 OPC_RECIP1_PS = FOP(29, FMT_PS), 9570 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9571 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9572 9573 OPC_CVT_S_PU = FOP(32, FMT_PS), 9574 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9575 OPC_CVT_S_PL = FOP(40, FMT_PS), 9576 OPC_PLL_PS = FOP(44, FMT_PS), 9577 OPC_PLU_PS = FOP(45, FMT_PS), 9578 OPC_PUL_PS = FOP(46, FMT_PS), 9579 OPC_PUU_PS = FOP(47, FMT_PS), 9580 OPC_CMP_F_PS = FOP(48, FMT_PS), 9581 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9582 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9583 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9584 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9585 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9586 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9587 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9588 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9589 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9590 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9591 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9592 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9593 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9594 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9595 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9596 }; 9597 9598 enum r6_f_cmp_op { 9599 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9600 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9601 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9602 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9603 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9604 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9605 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9606 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9607 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9608 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9609 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9610 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9611 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9612 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9613 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9614 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9615 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9616 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9617 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9618 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9619 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9620 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9621 9622 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9623 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9624 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9625 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9626 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9627 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9628 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9629 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9630 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9631 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9632 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9633 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9634 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9635 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9636 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9637 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9638 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9639 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9640 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9641 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9642 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9643 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9644 }; 9645 9646 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9647 { 9648 TCGv t0 = tcg_temp_new(); 9649 9650 switch (opc) { 9651 case OPC_MFC1: 9652 { 9653 TCGv_i32 fp0 = tcg_temp_new_i32(); 9654 9655 gen_load_fpr32(ctx, fp0, fs); 9656 tcg_gen_ext_i32_tl(t0, fp0); 9657 tcg_temp_free_i32(fp0); 9658 } 9659 gen_store_gpr(t0, rt); 9660 break; 9661 case OPC_MTC1: 9662 gen_load_gpr(t0, rt); 9663 { 9664 TCGv_i32 fp0 = tcg_temp_new_i32(); 9665 9666 tcg_gen_trunc_tl_i32(fp0, t0); 9667 gen_store_fpr32(ctx, fp0, fs); 9668 tcg_temp_free_i32(fp0); 9669 } 9670 break; 9671 case OPC_CFC1: 9672 gen_helper_1e0i(cfc1, t0, fs); 9673 gen_store_gpr(t0, rt); 9674 break; 9675 case OPC_CTC1: 9676 gen_load_gpr(t0, rt); 9677 save_cpu_state(ctx, 0); 9678 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9679 /* Stop translation as we may have changed hflags */ 9680 ctx->base.is_jmp = DISAS_STOP; 9681 break; 9682 #if defined(TARGET_MIPS64) 9683 case OPC_DMFC1: 9684 gen_load_fpr64(ctx, t0, fs); 9685 gen_store_gpr(t0, rt); 9686 break; 9687 case OPC_DMTC1: 9688 gen_load_gpr(t0, rt); 9689 gen_store_fpr64(ctx, t0, fs); 9690 break; 9691 #endif 9692 case OPC_MFHC1: 9693 { 9694 TCGv_i32 fp0 = tcg_temp_new_i32(); 9695 9696 gen_load_fpr32h(ctx, fp0, fs); 9697 tcg_gen_ext_i32_tl(t0, fp0); 9698 tcg_temp_free_i32(fp0); 9699 } 9700 gen_store_gpr(t0, rt); 9701 break; 9702 case OPC_MTHC1: 9703 gen_load_gpr(t0, rt); 9704 { 9705 TCGv_i32 fp0 = tcg_temp_new_i32(); 9706 9707 tcg_gen_trunc_tl_i32(fp0, t0); 9708 gen_store_fpr32h(ctx, fp0, fs); 9709 tcg_temp_free_i32(fp0); 9710 } 9711 break; 9712 default: 9713 MIPS_INVAL("cp1 move"); 9714 gen_reserved_instruction(ctx); 9715 goto out; 9716 } 9717 9718 out: 9719 tcg_temp_free(t0); 9720 } 9721 9722 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9723 { 9724 TCGLabel *l1; 9725 TCGCond cond; 9726 TCGv_i32 t0; 9727 9728 if (rd == 0) { 9729 /* Treat as NOP. */ 9730 return; 9731 } 9732 9733 if (tf) { 9734 cond = TCG_COND_EQ; 9735 } else { 9736 cond = TCG_COND_NE; 9737 } 9738 9739 l1 = gen_new_label(); 9740 t0 = tcg_temp_new_i32(); 9741 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9742 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9743 tcg_temp_free_i32(t0); 9744 gen_load_gpr(cpu_gpr[rd], rs); 9745 gen_set_label(l1); 9746 } 9747 9748 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9749 int tf) 9750 { 9751 int cond; 9752 TCGv_i32 t0 = tcg_temp_new_i32(); 9753 TCGLabel *l1 = gen_new_label(); 9754 9755 if (tf) { 9756 cond = TCG_COND_EQ; 9757 } else { 9758 cond = TCG_COND_NE; 9759 } 9760 9761 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9762 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9763 gen_load_fpr32(ctx, t0, fs); 9764 gen_store_fpr32(ctx, t0, fd); 9765 gen_set_label(l1); 9766 tcg_temp_free_i32(t0); 9767 } 9768 9769 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9770 int tf) 9771 { 9772 int cond; 9773 TCGv_i32 t0 = tcg_temp_new_i32(); 9774 TCGv_i64 fp0; 9775 TCGLabel *l1 = gen_new_label(); 9776 9777 if (tf) { 9778 cond = TCG_COND_EQ; 9779 } else { 9780 cond = TCG_COND_NE; 9781 } 9782 9783 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9784 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9785 tcg_temp_free_i32(t0); 9786 fp0 = tcg_temp_new_i64(); 9787 gen_load_fpr64(ctx, fp0, fs); 9788 gen_store_fpr64(ctx, fp0, fd); 9789 tcg_temp_free_i64(fp0); 9790 gen_set_label(l1); 9791 } 9792 9793 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9794 int cc, int tf) 9795 { 9796 int cond; 9797 TCGv_i32 t0 = tcg_temp_new_i32(); 9798 TCGLabel *l1 = gen_new_label(); 9799 TCGLabel *l2 = gen_new_label(); 9800 9801 if (tf) { 9802 cond = TCG_COND_EQ; 9803 } else { 9804 cond = TCG_COND_NE; 9805 } 9806 9807 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9808 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9809 gen_load_fpr32(ctx, t0, fs); 9810 gen_store_fpr32(ctx, t0, fd); 9811 gen_set_label(l1); 9812 9813 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9814 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9815 gen_load_fpr32h(ctx, t0, fs); 9816 gen_store_fpr32h(ctx, t0, fd); 9817 tcg_temp_free_i32(t0); 9818 gen_set_label(l2); 9819 } 9820 9821 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9822 int fs) 9823 { 9824 TCGv_i32 t1 = tcg_const_i32(0); 9825 TCGv_i32 fp0 = tcg_temp_new_i32(); 9826 TCGv_i32 fp1 = tcg_temp_new_i32(); 9827 TCGv_i32 fp2 = tcg_temp_new_i32(); 9828 gen_load_fpr32(ctx, fp0, fd); 9829 gen_load_fpr32(ctx, fp1, ft); 9830 gen_load_fpr32(ctx, fp2, fs); 9831 9832 switch (op1) { 9833 case OPC_SEL_S: 9834 tcg_gen_andi_i32(fp0, fp0, 1); 9835 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9836 break; 9837 case OPC_SELEQZ_S: 9838 tcg_gen_andi_i32(fp1, fp1, 1); 9839 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9840 break; 9841 case OPC_SELNEZ_S: 9842 tcg_gen_andi_i32(fp1, fp1, 1); 9843 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9844 break; 9845 default: 9846 MIPS_INVAL("gen_sel_s"); 9847 gen_reserved_instruction(ctx); 9848 break; 9849 } 9850 9851 gen_store_fpr32(ctx, fp0, fd); 9852 tcg_temp_free_i32(fp2); 9853 tcg_temp_free_i32(fp1); 9854 tcg_temp_free_i32(fp0); 9855 tcg_temp_free_i32(t1); 9856 } 9857 9858 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9859 int fs) 9860 { 9861 TCGv_i64 t1 = tcg_const_i64(0); 9862 TCGv_i64 fp0 = tcg_temp_new_i64(); 9863 TCGv_i64 fp1 = tcg_temp_new_i64(); 9864 TCGv_i64 fp2 = tcg_temp_new_i64(); 9865 gen_load_fpr64(ctx, fp0, fd); 9866 gen_load_fpr64(ctx, fp1, ft); 9867 gen_load_fpr64(ctx, fp2, fs); 9868 9869 switch (op1) { 9870 case OPC_SEL_D: 9871 tcg_gen_andi_i64(fp0, fp0, 1); 9872 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9873 break; 9874 case OPC_SELEQZ_D: 9875 tcg_gen_andi_i64(fp1, fp1, 1); 9876 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9877 break; 9878 case OPC_SELNEZ_D: 9879 tcg_gen_andi_i64(fp1, fp1, 1); 9880 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9881 break; 9882 default: 9883 MIPS_INVAL("gen_sel_d"); 9884 gen_reserved_instruction(ctx); 9885 break; 9886 } 9887 9888 gen_store_fpr64(ctx, fp0, fd); 9889 tcg_temp_free_i64(fp2); 9890 tcg_temp_free_i64(fp1); 9891 tcg_temp_free_i64(fp0); 9892 tcg_temp_free_i64(t1); 9893 } 9894 9895 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9896 int ft, int fs, int fd, int cc) 9897 { 9898 uint32_t func = ctx->opcode & 0x3f; 9899 switch (op1) { 9900 case OPC_ADD_S: 9901 { 9902 TCGv_i32 fp0 = tcg_temp_new_i32(); 9903 TCGv_i32 fp1 = tcg_temp_new_i32(); 9904 9905 gen_load_fpr32(ctx, fp0, fs); 9906 gen_load_fpr32(ctx, fp1, ft); 9907 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 9908 tcg_temp_free_i32(fp1); 9909 gen_store_fpr32(ctx, fp0, fd); 9910 tcg_temp_free_i32(fp0); 9911 } 9912 break; 9913 case OPC_SUB_S: 9914 { 9915 TCGv_i32 fp0 = tcg_temp_new_i32(); 9916 TCGv_i32 fp1 = tcg_temp_new_i32(); 9917 9918 gen_load_fpr32(ctx, fp0, fs); 9919 gen_load_fpr32(ctx, fp1, ft); 9920 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 9921 tcg_temp_free_i32(fp1); 9922 gen_store_fpr32(ctx, fp0, fd); 9923 tcg_temp_free_i32(fp0); 9924 } 9925 break; 9926 case OPC_MUL_S: 9927 { 9928 TCGv_i32 fp0 = tcg_temp_new_i32(); 9929 TCGv_i32 fp1 = tcg_temp_new_i32(); 9930 9931 gen_load_fpr32(ctx, fp0, fs); 9932 gen_load_fpr32(ctx, fp1, ft); 9933 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 9934 tcg_temp_free_i32(fp1); 9935 gen_store_fpr32(ctx, fp0, fd); 9936 tcg_temp_free_i32(fp0); 9937 } 9938 break; 9939 case OPC_DIV_S: 9940 { 9941 TCGv_i32 fp0 = tcg_temp_new_i32(); 9942 TCGv_i32 fp1 = tcg_temp_new_i32(); 9943 9944 gen_load_fpr32(ctx, fp0, fs); 9945 gen_load_fpr32(ctx, fp1, ft); 9946 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 9947 tcg_temp_free_i32(fp1); 9948 gen_store_fpr32(ctx, fp0, fd); 9949 tcg_temp_free_i32(fp0); 9950 } 9951 break; 9952 case OPC_SQRT_S: 9953 { 9954 TCGv_i32 fp0 = tcg_temp_new_i32(); 9955 9956 gen_load_fpr32(ctx, fp0, fs); 9957 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 9958 gen_store_fpr32(ctx, fp0, fd); 9959 tcg_temp_free_i32(fp0); 9960 } 9961 break; 9962 case OPC_ABS_S: 9963 { 9964 TCGv_i32 fp0 = tcg_temp_new_i32(); 9965 9966 gen_load_fpr32(ctx, fp0, fs); 9967 if (ctx->abs2008) { 9968 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9969 } else { 9970 gen_helper_float_abs_s(fp0, fp0); 9971 } 9972 gen_store_fpr32(ctx, fp0, fd); 9973 tcg_temp_free_i32(fp0); 9974 } 9975 break; 9976 case OPC_MOV_S: 9977 { 9978 TCGv_i32 fp0 = tcg_temp_new_i32(); 9979 9980 gen_load_fpr32(ctx, fp0, fs); 9981 gen_store_fpr32(ctx, fp0, fd); 9982 tcg_temp_free_i32(fp0); 9983 } 9984 break; 9985 case OPC_NEG_S: 9986 { 9987 TCGv_i32 fp0 = tcg_temp_new_i32(); 9988 9989 gen_load_fpr32(ctx, fp0, fs); 9990 if (ctx->abs2008) { 9991 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9992 } else { 9993 gen_helper_float_chs_s(fp0, fp0); 9994 } 9995 gen_store_fpr32(ctx, fp0, fd); 9996 tcg_temp_free_i32(fp0); 9997 } 9998 break; 9999 case OPC_ROUND_L_S: 10000 check_cp1_64bitmode(ctx); 10001 { 10002 TCGv_i32 fp32 = tcg_temp_new_i32(); 10003 TCGv_i64 fp64 = tcg_temp_new_i64(); 10004 10005 gen_load_fpr32(ctx, fp32, fs); 10006 if (ctx->nan2008) { 10007 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10008 } else { 10009 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10010 } 10011 tcg_temp_free_i32(fp32); 10012 gen_store_fpr64(ctx, fp64, fd); 10013 tcg_temp_free_i64(fp64); 10014 } 10015 break; 10016 case OPC_TRUNC_L_S: 10017 check_cp1_64bitmode(ctx); 10018 { 10019 TCGv_i32 fp32 = tcg_temp_new_i32(); 10020 TCGv_i64 fp64 = tcg_temp_new_i64(); 10021 10022 gen_load_fpr32(ctx, fp32, fs); 10023 if (ctx->nan2008) { 10024 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10025 } else { 10026 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10027 } 10028 tcg_temp_free_i32(fp32); 10029 gen_store_fpr64(ctx, fp64, fd); 10030 tcg_temp_free_i64(fp64); 10031 } 10032 break; 10033 case OPC_CEIL_L_S: 10034 check_cp1_64bitmode(ctx); 10035 { 10036 TCGv_i32 fp32 = tcg_temp_new_i32(); 10037 TCGv_i64 fp64 = tcg_temp_new_i64(); 10038 10039 gen_load_fpr32(ctx, fp32, fs); 10040 if (ctx->nan2008) { 10041 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10042 } else { 10043 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10044 } 10045 tcg_temp_free_i32(fp32); 10046 gen_store_fpr64(ctx, fp64, fd); 10047 tcg_temp_free_i64(fp64); 10048 } 10049 break; 10050 case OPC_FLOOR_L_S: 10051 check_cp1_64bitmode(ctx); 10052 { 10053 TCGv_i32 fp32 = tcg_temp_new_i32(); 10054 TCGv_i64 fp64 = tcg_temp_new_i64(); 10055 10056 gen_load_fpr32(ctx, fp32, fs); 10057 if (ctx->nan2008) { 10058 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10059 } else { 10060 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10061 } 10062 tcg_temp_free_i32(fp32); 10063 gen_store_fpr64(ctx, fp64, fd); 10064 tcg_temp_free_i64(fp64); 10065 } 10066 break; 10067 case OPC_ROUND_W_S: 10068 { 10069 TCGv_i32 fp0 = tcg_temp_new_i32(); 10070 10071 gen_load_fpr32(ctx, fp0, fs); 10072 if (ctx->nan2008) { 10073 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10074 } else { 10075 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10076 } 10077 gen_store_fpr32(ctx, fp0, fd); 10078 tcg_temp_free_i32(fp0); 10079 } 10080 break; 10081 case OPC_TRUNC_W_S: 10082 { 10083 TCGv_i32 fp0 = tcg_temp_new_i32(); 10084 10085 gen_load_fpr32(ctx, fp0, fs); 10086 if (ctx->nan2008) { 10087 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10088 } else { 10089 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10090 } 10091 gen_store_fpr32(ctx, fp0, fd); 10092 tcg_temp_free_i32(fp0); 10093 } 10094 break; 10095 case OPC_CEIL_W_S: 10096 { 10097 TCGv_i32 fp0 = tcg_temp_new_i32(); 10098 10099 gen_load_fpr32(ctx, fp0, fs); 10100 if (ctx->nan2008) { 10101 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10102 } else { 10103 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10104 } 10105 gen_store_fpr32(ctx, fp0, fd); 10106 tcg_temp_free_i32(fp0); 10107 } 10108 break; 10109 case OPC_FLOOR_W_S: 10110 { 10111 TCGv_i32 fp0 = tcg_temp_new_i32(); 10112 10113 gen_load_fpr32(ctx, fp0, fs); 10114 if (ctx->nan2008) { 10115 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10116 } else { 10117 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10118 } 10119 gen_store_fpr32(ctx, fp0, fd); 10120 tcg_temp_free_i32(fp0); 10121 } 10122 break; 10123 case OPC_SEL_S: 10124 check_insn(ctx, ISA_MIPS_R6); 10125 gen_sel_s(ctx, op1, fd, ft, fs); 10126 break; 10127 case OPC_SELEQZ_S: 10128 check_insn(ctx, ISA_MIPS_R6); 10129 gen_sel_s(ctx, op1, fd, ft, fs); 10130 break; 10131 case OPC_SELNEZ_S: 10132 check_insn(ctx, ISA_MIPS_R6); 10133 gen_sel_s(ctx, op1, fd, ft, fs); 10134 break; 10135 case OPC_MOVCF_S: 10136 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10137 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10138 break; 10139 case OPC_MOVZ_S: 10140 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10141 { 10142 TCGLabel *l1 = gen_new_label(); 10143 TCGv_i32 fp0; 10144 10145 if (ft != 0) { 10146 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10147 } 10148 fp0 = tcg_temp_new_i32(); 10149 gen_load_fpr32(ctx, fp0, fs); 10150 gen_store_fpr32(ctx, fp0, fd); 10151 tcg_temp_free_i32(fp0); 10152 gen_set_label(l1); 10153 } 10154 break; 10155 case OPC_MOVN_S: 10156 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10157 { 10158 TCGLabel *l1 = gen_new_label(); 10159 TCGv_i32 fp0; 10160 10161 if (ft != 0) { 10162 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10163 fp0 = tcg_temp_new_i32(); 10164 gen_load_fpr32(ctx, fp0, fs); 10165 gen_store_fpr32(ctx, fp0, fd); 10166 tcg_temp_free_i32(fp0); 10167 gen_set_label(l1); 10168 } 10169 } 10170 break; 10171 case OPC_RECIP_S: 10172 { 10173 TCGv_i32 fp0 = tcg_temp_new_i32(); 10174 10175 gen_load_fpr32(ctx, fp0, fs); 10176 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10177 gen_store_fpr32(ctx, fp0, fd); 10178 tcg_temp_free_i32(fp0); 10179 } 10180 break; 10181 case OPC_RSQRT_S: 10182 { 10183 TCGv_i32 fp0 = tcg_temp_new_i32(); 10184 10185 gen_load_fpr32(ctx, fp0, fs); 10186 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10187 gen_store_fpr32(ctx, fp0, fd); 10188 tcg_temp_free_i32(fp0); 10189 } 10190 break; 10191 case OPC_MADDF_S: 10192 check_insn(ctx, ISA_MIPS_R6); 10193 { 10194 TCGv_i32 fp0 = tcg_temp_new_i32(); 10195 TCGv_i32 fp1 = tcg_temp_new_i32(); 10196 TCGv_i32 fp2 = tcg_temp_new_i32(); 10197 gen_load_fpr32(ctx, fp0, fs); 10198 gen_load_fpr32(ctx, fp1, ft); 10199 gen_load_fpr32(ctx, fp2, fd); 10200 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10201 gen_store_fpr32(ctx, fp2, fd); 10202 tcg_temp_free_i32(fp2); 10203 tcg_temp_free_i32(fp1); 10204 tcg_temp_free_i32(fp0); 10205 } 10206 break; 10207 case OPC_MSUBF_S: 10208 check_insn(ctx, ISA_MIPS_R6); 10209 { 10210 TCGv_i32 fp0 = tcg_temp_new_i32(); 10211 TCGv_i32 fp1 = tcg_temp_new_i32(); 10212 TCGv_i32 fp2 = tcg_temp_new_i32(); 10213 gen_load_fpr32(ctx, fp0, fs); 10214 gen_load_fpr32(ctx, fp1, ft); 10215 gen_load_fpr32(ctx, fp2, fd); 10216 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10217 gen_store_fpr32(ctx, fp2, fd); 10218 tcg_temp_free_i32(fp2); 10219 tcg_temp_free_i32(fp1); 10220 tcg_temp_free_i32(fp0); 10221 } 10222 break; 10223 case OPC_RINT_S: 10224 check_insn(ctx, ISA_MIPS_R6); 10225 { 10226 TCGv_i32 fp0 = tcg_temp_new_i32(); 10227 gen_load_fpr32(ctx, fp0, fs); 10228 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10229 gen_store_fpr32(ctx, fp0, fd); 10230 tcg_temp_free_i32(fp0); 10231 } 10232 break; 10233 case OPC_CLASS_S: 10234 check_insn(ctx, ISA_MIPS_R6); 10235 { 10236 TCGv_i32 fp0 = tcg_temp_new_i32(); 10237 gen_load_fpr32(ctx, fp0, fs); 10238 gen_helper_float_class_s(fp0, cpu_env, fp0); 10239 gen_store_fpr32(ctx, fp0, fd); 10240 tcg_temp_free_i32(fp0); 10241 } 10242 break; 10243 case OPC_MIN_S: /* OPC_RECIP2_S */ 10244 if (ctx->insn_flags & ISA_MIPS_R6) { 10245 /* OPC_MIN_S */ 10246 TCGv_i32 fp0 = tcg_temp_new_i32(); 10247 TCGv_i32 fp1 = tcg_temp_new_i32(); 10248 TCGv_i32 fp2 = tcg_temp_new_i32(); 10249 gen_load_fpr32(ctx, fp0, fs); 10250 gen_load_fpr32(ctx, fp1, ft); 10251 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10252 gen_store_fpr32(ctx, fp2, fd); 10253 tcg_temp_free_i32(fp2); 10254 tcg_temp_free_i32(fp1); 10255 tcg_temp_free_i32(fp0); 10256 } else { 10257 /* OPC_RECIP2_S */ 10258 check_cp1_64bitmode(ctx); 10259 { 10260 TCGv_i32 fp0 = tcg_temp_new_i32(); 10261 TCGv_i32 fp1 = tcg_temp_new_i32(); 10262 10263 gen_load_fpr32(ctx, fp0, fs); 10264 gen_load_fpr32(ctx, fp1, ft); 10265 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10266 tcg_temp_free_i32(fp1); 10267 gen_store_fpr32(ctx, fp0, fd); 10268 tcg_temp_free_i32(fp0); 10269 } 10270 } 10271 break; 10272 case OPC_MINA_S: /* OPC_RECIP1_S */ 10273 if (ctx->insn_flags & ISA_MIPS_R6) { 10274 /* OPC_MINA_S */ 10275 TCGv_i32 fp0 = tcg_temp_new_i32(); 10276 TCGv_i32 fp1 = tcg_temp_new_i32(); 10277 TCGv_i32 fp2 = tcg_temp_new_i32(); 10278 gen_load_fpr32(ctx, fp0, fs); 10279 gen_load_fpr32(ctx, fp1, ft); 10280 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10281 gen_store_fpr32(ctx, fp2, fd); 10282 tcg_temp_free_i32(fp2); 10283 tcg_temp_free_i32(fp1); 10284 tcg_temp_free_i32(fp0); 10285 } else { 10286 /* OPC_RECIP1_S */ 10287 check_cp1_64bitmode(ctx); 10288 { 10289 TCGv_i32 fp0 = tcg_temp_new_i32(); 10290 10291 gen_load_fpr32(ctx, fp0, fs); 10292 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10293 gen_store_fpr32(ctx, fp0, fd); 10294 tcg_temp_free_i32(fp0); 10295 } 10296 } 10297 break; 10298 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10299 if (ctx->insn_flags & ISA_MIPS_R6) { 10300 /* OPC_MAX_S */ 10301 TCGv_i32 fp0 = tcg_temp_new_i32(); 10302 TCGv_i32 fp1 = tcg_temp_new_i32(); 10303 gen_load_fpr32(ctx, fp0, fs); 10304 gen_load_fpr32(ctx, fp1, ft); 10305 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10306 gen_store_fpr32(ctx, fp1, fd); 10307 tcg_temp_free_i32(fp1); 10308 tcg_temp_free_i32(fp0); 10309 } else { 10310 /* OPC_RSQRT1_S */ 10311 check_cp1_64bitmode(ctx); 10312 { 10313 TCGv_i32 fp0 = tcg_temp_new_i32(); 10314 10315 gen_load_fpr32(ctx, fp0, fs); 10316 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10317 gen_store_fpr32(ctx, fp0, fd); 10318 tcg_temp_free_i32(fp0); 10319 } 10320 } 10321 break; 10322 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10323 if (ctx->insn_flags & ISA_MIPS_R6) { 10324 /* OPC_MAXA_S */ 10325 TCGv_i32 fp0 = tcg_temp_new_i32(); 10326 TCGv_i32 fp1 = tcg_temp_new_i32(); 10327 gen_load_fpr32(ctx, fp0, fs); 10328 gen_load_fpr32(ctx, fp1, ft); 10329 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10330 gen_store_fpr32(ctx, fp1, fd); 10331 tcg_temp_free_i32(fp1); 10332 tcg_temp_free_i32(fp0); 10333 } else { 10334 /* OPC_RSQRT2_S */ 10335 check_cp1_64bitmode(ctx); 10336 { 10337 TCGv_i32 fp0 = tcg_temp_new_i32(); 10338 TCGv_i32 fp1 = tcg_temp_new_i32(); 10339 10340 gen_load_fpr32(ctx, fp0, fs); 10341 gen_load_fpr32(ctx, fp1, ft); 10342 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10343 tcg_temp_free_i32(fp1); 10344 gen_store_fpr32(ctx, fp0, fd); 10345 tcg_temp_free_i32(fp0); 10346 } 10347 } 10348 break; 10349 case OPC_CVT_D_S: 10350 check_cp1_registers(ctx, fd); 10351 { 10352 TCGv_i32 fp32 = tcg_temp_new_i32(); 10353 TCGv_i64 fp64 = tcg_temp_new_i64(); 10354 10355 gen_load_fpr32(ctx, fp32, fs); 10356 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10357 tcg_temp_free_i32(fp32); 10358 gen_store_fpr64(ctx, fp64, fd); 10359 tcg_temp_free_i64(fp64); 10360 } 10361 break; 10362 case OPC_CVT_W_S: 10363 { 10364 TCGv_i32 fp0 = tcg_temp_new_i32(); 10365 10366 gen_load_fpr32(ctx, fp0, fs); 10367 if (ctx->nan2008) { 10368 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10369 } else { 10370 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10371 } 10372 gen_store_fpr32(ctx, fp0, fd); 10373 tcg_temp_free_i32(fp0); 10374 } 10375 break; 10376 case OPC_CVT_L_S: 10377 check_cp1_64bitmode(ctx); 10378 { 10379 TCGv_i32 fp32 = tcg_temp_new_i32(); 10380 TCGv_i64 fp64 = tcg_temp_new_i64(); 10381 10382 gen_load_fpr32(ctx, fp32, fs); 10383 if (ctx->nan2008) { 10384 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10385 } else { 10386 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10387 } 10388 tcg_temp_free_i32(fp32); 10389 gen_store_fpr64(ctx, fp64, fd); 10390 tcg_temp_free_i64(fp64); 10391 } 10392 break; 10393 case OPC_CVT_PS_S: 10394 check_ps(ctx); 10395 { 10396 TCGv_i64 fp64 = tcg_temp_new_i64(); 10397 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10398 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10399 10400 gen_load_fpr32(ctx, fp32_0, fs); 10401 gen_load_fpr32(ctx, fp32_1, ft); 10402 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10403 tcg_temp_free_i32(fp32_1); 10404 tcg_temp_free_i32(fp32_0); 10405 gen_store_fpr64(ctx, fp64, fd); 10406 tcg_temp_free_i64(fp64); 10407 } 10408 break; 10409 case OPC_CMP_F_S: 10410 case OPC_CMP_UN_S: 10411 case OPC_CMP_EQ_S: 10412 case OPC_CMP_UEQ_S: 10413 case OPC_CMP_OLT_S: 10414 case OPC_CMP_ULT_S: 10415 case OPC_CMP_OLE_S: 10416 case OPC_CMP_ULE_S: 10417 case OPC_CMP_SF_S: 10418 case OPC_CMP_NGLE_S: 10419 case OPC_CMP_SEQ_S: 10420 case OPC_CMP_NGL_S: 10421 case OPC_CMP_LT_S: 10422 case OPC_CMP_NGE_S: 10423 case OPC_CMP_LE_S: 10424 case OPC_CMP_NGT_S: 10425 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10426 if (ctx->opcode & (1 << 6)) { 10427 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10428 } else { 10429 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10430 } 10431 break; 10432 case OPC_ADD_D: 10433 check_cp1_registers(ctx, fs | ft | fd); 10434 { 10435 TCGv_i64 fp0 = tcg_temp_new_i64(); 10436 TCGv_i64 fp1 = tcg_temp_new_i64(); 10437 10438 gen_load_fpr64(ctx, fp0, fs); 10439 gen_load_fpr64(ctx, fp1, ft); 10440 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10441 tcg_temp_free_i64(fp1); 10442 gen_store_fpr64(ctx, fp0, fd); 10443 tcg_temp_free_i64(fp0); 10444 } 10445 break; 10446 case OPC_SUB_D: 10447 check_cp1_registers(ctx, fs | ft | fd); 10448 { 10449 TCGv_i64 fp0 = tcg_temp_new_i64(); 10450 TCGv_i64 fp1 = tcg_temp_new_i64(); 10451 10452 gen_load_fpr64(ctx, fp0, fs); 10453 gen_load_fpr64(ctx, fp1, ft); 10454 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10455 tcg_temp_free_i64(fp1); 10456 gen_store_fpr64(ctx, fp0, fd); 10457 tcg_temp_free_i64(fp0); 10458 } 10459 break; 10460 case OPC_MUL_D: 10461 check_cp1_registers(ctx, fs | ft | fd); 10462 { 10463 TCGv_i64 fp0 = tcg_temp_new_i64(); 10464 TCGv_i64 fp1 = tcg_temp_new_i64(); 10465 10466 gen_load_fpr64(ctx, fp0, fs); 10467 gen_load_fpr64(ctx, fp1, ft); 10468 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10469 tcg_temp_free_i64(fp1); 10470 gen_store_fpr64(ctx, fp0, fd); 10471 tcg_temp_free_i64(fp0); 10472 } 10473 break; 10474 case OPC_DIV_D: 10475 check_cp1_registers(ctx, fs | ft | fd); 10476 { 10477 TCGv_i64 fp0 = tcg_temp_new_i64(); 10478 TCGv_i64 fp1 = tcg_temp_new_i64(); 10479 10480 gen_load_fpr64(ctx, fp0, fs); 10481 gen_load_fpr64(ctx, fp1, ft); 10482 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10483 tcg_temp_free_i64(fp1); 10484 gen_store_fpr64(ctx, fp0, fd); 10485 tcg_temp_free_i64(fp0); 10486 } 10487 break; 10488 case OPC_SQRT_D: 10489 check_cp1_registers(ctx, fs | fd); 10490 { 10491 TCGv_i64 fp0 = tcg_temp_new_i64(); 10492 10493 gen_load_fpr64(ctx, fp0, fs); 10494 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10495 gen_store_fpr64(ctx, fp0, fd); 10496 tcg_temp_free_i64(fp0); 10497 } 10498 break; 10499 case OPC_ABS_D: 10500 check_cp1_registers(ctx, fs | fd); 10501 { 10502 TCGv_i64 fp0 = tcg_temp_new_i64(); 10503 10504 gen_load_fpr64(ctx, fp0, fs); 10505 if (ctx->abs2008) { 10506 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10507 } else { 10508 gen_helper_float_abs_d(fp0, fp0); 10509 } 10510 gen_store_fpr64(ctx, fp0, fd); 10511 tcg_temp_free_i64(fp0); 10512 } 10513 break; 10514 case OPC_MOV_D: 10515 check_cp1_registers(ctx, fs | fd); 10516 { 10517 TCGv_i64 fp0 = tcg_temp_new_i64(); 10518 10519 gen_load_fpr64(ctx, fp0, fs); 10520 gen_store_fpr64(ctx, fp0, fd); 10521 tcg_temp_free_i64(fp0); 10522 } 10523 break; 10524 case OPC_NEG_D: 10525 check_cp1_registers(ctx, fs | fd); 10526 { 10527 TCGv_i64 fp0 = tcg_temp_new_i64(); 10528 10529 gen_load_fpr64(ctx, fp0, fs); 10530 if (ctx->abs2008) { 10531 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10532 } else { 10533 gen_helper_float_chs_d(fp0, fp0); 10534 } 10535 gen_store_fpr64(ctx, fp0, fd); 10536 tcg_temp_free_i64(fp0); 10537 } 10538 break; 10539 case OPC_ROUND_L_D: 10540 check_cp1_64bitmode(ctx); 10541 { 10542 TCGv_i64 fp0 = tcg_temp_new_i64(); 10543 10544 gen_load_fpr64(ctx, fp0, fs); 10545 if (ctx->nan2008) { 10546 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10547 } else { 10548 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10549 } 10550 gen_store_fpr64(ctx, fp0, fd); 10551 tcg_temp_free_i64(fp0); 10552 } 10553 break; 10554 case OPC_TRUNC_L_D: 10555 check_cp1_64bitmode(ctx); 10556 { 10557 TCGv_i64 fp0 = tcg_temp_new_i64(); 10558 10559 gen_load_fpr64(ctx, fp0, fs); 10560 if (ctx->nan2008) { 10561 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10562 } else { 10563 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10564 } 10565 gen_store_fpr64(ctx, fp0, fd); 10566 tcg_temp_free_i64(fp0); 10567 } 10568 break; 10569 case OPC_CEIL_L_D: 10570 check_cp1_64bitmode(ctx); 10571 { 10572 TCGv_i64 fp0 = tcg_temp_new_i64(); 10573 10574 gen_load_fpr64(ctx, fp0, fs); 10575 if (ctx->nan2008) { 10576 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10577 } else { 10578 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10579 } 10580 gen_store_fpr64(ctx, fp0, fd); 10581 tcg_temp_free_i64(fp0); 10582 } 10583 break; 10584 case OPC_FLOOR_L_D: 10585 check_cp1_64bitmode(ctx); 10586 { 10587 TCGv_i64 fp0 = tcg_temp_new_i64(); 10588 10589 gen_load_fpr64(ctx, fp0, fs); 10590 if (ctx->nan2008) { 10591 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10592 } else { 10593 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10594 } 10595 gen_store_fpr64(ctx, fp0, fd); 10596 tcg_temp_free_i64(fp0); 10597 } 10598 break; 10599 case OPC_ROUND_W_D: 10600 check_cp1_registers(ctx, fs); 10601 { 10602 TCGv_i32 fp32 = tcg_temp_new_i32(); 10603 TCGv_i64 fp64 = tcg_temp_new_i64(); 10604 10605 gen_load_fpr64(ctx, fp64, fs); 10606 if (ctx->nan2008) { 10607 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10608 } else { 10609 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10610 } 10611 tcg_temp_free_i64(fp64); 10612 gen_store_fpr32(ctx, fp32, fd); 10613 tcg_temp_free_i32(fp32); 10614 } 10615 break; 10616 case OPC_TRUNC_W_D: 10617 check_cp1_registers(ctx, fs); 10618 { 10619 TCGv_i32 fp32 = tcg_temp_new_i32(); 10620 TCGv_i64 fp64 = tcg_temp_new_i64(); 10621 10622 gen_load_fpr64(ctx, fp64, fs); 10623 if (ctx->nan2008) { 10624 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10625 } else { 10626 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10627 } 10628 tcg_temp_free_i64(fp64); 10629 gen_store_fpr32(ctx, fp32, fd); 10630 tcg_temp_free_i32(fp32); 10631 } 10632 break; 10633 case OPC_CEIL_W_D: 10634 check_cp1_registers(ctx, fs); 10635 { 10636 TCGv_i32 fp32 = tcg_temp_new_i32(); 10637 TCGv_i64 fp64 = tcg_temp_new_i64(); 10638 10639 gen_load_fpr64(ctx, fp64, fs); 10640 if (ctx->nan2008) { 10641 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10642 } else { 10643 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10644 } 10645 tcg_temp_free_i64(fp64); 10646 gen_store_fpr32(ctx, fp32, fd); 10647 tcg_temp_free_i32(fp32); 10648 } 10649 break; 10650 case OPC_FLOOR_W_D: 10651 check_cp1_registers(ctx, fs); 10652 { 10653 TCGv_i32 fp32 = tcg_temp_new_i32(); 10654 TCGv_i64 fp64 = tcg_temp_new_i64(); 10655 10656 gen_load_fpr64(ctx, fp64, fs); 10657 if (ctx->nan2008) { 10658 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10659 } else { 10660 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10661 } 10662 tcg_temp_free_i64(fp64); 10663 gen_store_fpr32(ctx, fp32, fd); 10664 tcg_temp_free_i32(fp32); 10665 } 10666 break; 10667 case OPC_SEL_D: 10668 check_insn(ctx, ISA_MIPS_R6); 10669 gen_sel_d(ctx, op1, fd, ft, fs); 10670 break; 10671 case OPC_SELEQZ_D: 10672 check_insn(ctx, ISA_MIPS_R6); 10673 gen_sel_d(ctx, op1, fd, ft, fs); 10674 break; 10675 case OPC_SELNEZ_D: 10676 check_insn(ctx, ISA_MIPS_R6); 10677 gen_sel_d(ctx, op1, fd, ft, fs); 10678 break; 10679 case OPC_MOVCF_D: 10680 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10681 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10682 break; 10683 case OPC_MOVZ_D: 10684 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10685 { 10686 TCGLabel *l1 = gen_new_label(); 10687 TCGv_i64 fp0; 10688 10689 if (ft != 0) { 10690 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10691 } 10692 fp0 = tcg_temp_new_i64(); 10693 gen_load_fpr64(ctx, fp0, fs); 10694 gen_store_fpr64(ctx, fp0, fd); 10695 tcg_temp_free_i64(fp0); 10696 gen_set_label(l1); 10697 } 10698 break; 10699 case OPC_MOVN_D: 10700 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10701 { 10702 TCGLabel *l1 = gen_new_label(); 10703 TCGv_i64 fp0; 10704 10705 if (ft != 0) { 10706 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10707 fp0 = tcg_temp_new_i64(); 10708 gen_load_fpr64(ctx, fp0, fs); 10709 gen_store_fpr64(ctx, fp0, fd); 10710 tcg_temp_free_i64(fp0); 10711 gen_set_label(l1); 10712 } 10713 } 10714 break; 10715 case OPC_RECIP_D: 10716 check_cp1_registers(ctx, fs | fd); 10717 { 10718 TCGv_i64 fp0 = tcg_temp_new_i64(); 10719 10720 gen_load_fpr64(ctx, fp0, fs); 10721 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10722 gen_store_fpr64(ctx, fp0, fd); 10723 tcg_temp_free_i64(fp0); 10724 } 10725 break; 10726 case OPC_RSQRT_D: 10727 check_cp1_registers(ctx, fs | fd); 10728 { 10729 TCGv_i64 fp0 = tcg_temp_new_i64(); 10730 10731 gen_load_fpr64(ctx, fp0, fs); 10732 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10733 gen_store_fpr64(ctx, fp0, fd); 10734 tcg_temp_free_i64(fp0); 10735 } 10736 break; 10737 case OPC_MADDF_D: 10738 check_insn(ctx, ISA_MIPS_R6); 10739 { 10740 TCGv_i64 fp0 = tcg_temp_new_i64(); 10741 TCGv_i64 fp1 = tcg_temp_new_i64(); 10742 TCGv_i64 fp2 = tcg_temp_new_i64(); 10743 gen_load_fpr64(ctx, fp0, fs); 10744 gen_load_fpr64(ctx, fp1, ft); 10745 gen_load_fpr64(ctx, fp2, fd); 10746 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10747 gen_store_fpr64(ctx, fp2, fd); 10748 tcg_temp_free_i64(fp2); 10749 tcg_temp_free_i64(fp1); 10750 tcg_temp_free_i64(fp0); 10751 } 10752 break; 10753 case OPC_MSUBF_D: 10754 check_insn(ctx, ISA_MIPS_R6); 10755 { 10756 TCGv_i64 fp0 = tcg_temp_new_i64(); 10757 TCGv_i64 fp1 = tcg_temp_new_i64(); 10758 TCGv_i64 fp2 = tcg_temp_new_i64(); 10759 gen_load_fpr64(ctx, fp0, fs); 10760 gen_load_fpr64(ctx, fp1, ft); 10761 gen_load_fpr64(ctx, fp2, fd); 10762 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10763 gen_store_fpr64(ctx, fp2, fd); 10764 tcg_temp_free_i64(fp2); 10765 tcg_temp_free_i64(fp1); 10766 tcg_temp_free_i64(fp0); 10767 } 10768 break; 10769 case OPC_RINT_D: 10770 check_insn(ctx, ISA_MIPS_R6); 10771 { 10772 TCGv_i64 fp0 = tcg_temp_new_i64(); 10773 gen_load_fpr64(ctx, fp0, fs); 10774 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10775 gen_store_fpr64(ctx, fp0, fd); 10776 tcg_temp_free_i64(fp0); 10777 } 10778 break; 10779 case OPC_CLASS_D: 10780 check_insn(ctx, ISA_MIPS_R6); 10781 { 10782 TCGv_i64 fp0 = tcg_temp_new_i64(); 10783 gen_load_fpr64(ctx, fp0, fs); 10784 gen_helper_float_class_d(fp0, cpu_env, fp0); 10785 gen_store_fpr64(ctx, fp0, fd); 10786 tcg_temp_free_i64(fp0); 10787 } 10788 break; 10789 case OPC_MIN_D: /* OPC_RECIP2_D */ 10790 if (ctx->insn_flags & ISA_MIPS_R6) { 10791 /* OPC_MIN_D */ 10792 TCGv_i64 fp0 = tcg_temp_new_i64(); 10793 TCGv_i64 fp1 = tcg_temp_new_i64(); 10794 gen_load_fpr64(ctx, fp0, fs); 10795 gen_load_fpr64(ctx, fp1, ft); 10796 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10797 gen_store_fpr64(ctx, fp1, fd); 10798 tcg_temp_free_i64(fp1); 10799 tcg_temp_free_i64(fp0); 10800 } else { 10801 /* OPC_RECIP2_D */ 10802 check_cp1_64bitmode(ctx); 10803 { 10804 TCGv_i64 fp0 = tcg_temp_new_i64(); 10805 TCGv_i64 fp1 = tcg_temp_new_i64(); 10806 10807 gen_load_fpr64(ctx, fp0, fs); 10808 gen_load_fpr64(ctx, fp1, ft); 10809 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10810 tcg_temp_free_i64(fp1); 10811 gen_store_fpr64(ctx, fp0, fd); 10812 tcg_temp_free_i64(fp0); 10813 } 10814 } 10815 break; 10816 case OPC_MINA_D: /* OPC_RECIP1_D */ 10817 if (ctx->insn_flags & ISA_MIPS_R6) { 10818 /* OPC_MINA_D */ 10819 TCGv_i64 fp0 = tcg_temp_new_i64(); 10820 TCGv_i64 fp1 = tcg_temp_new_i64(); 10821 gen_load_fpr64(ctx, fp0, fs); 10822 gen_load_fpr64(ctx, fp1, ft); 10823 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10824 gen_store_fpr64(ctx, fp1, fd); 10825 tcg_temp_free_i64(fp1); 10826 tcg_temp_free_i64(fp0); 10827 } else { 10828 /* OPC_RECIP1_D */ 10829 check_cp1_64bitmode(ctx); 10830 { 10831 TCGv_i64 fp0 = tcg_temp_new_i64(); 10832 10833 gen_load_fpr64(ctx, fp0, fs); 10834 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10835 gen_store_fpr64(ctx, fp0, fd); 10836 tcg_temp_free_i64(fp0); 10837 } 10838 } 10839 break; 10840 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10841 if (ctx->insn_flags & ISA_MIPS_R6) { 10842 /* OPC_MAX_D */ 10843 TCGv_i64 fp0 = tcg_temp_new_i64(); 10844 TCGv_i64 fp1 = tcg_temp_new_i64(); 10845 gen_load_fpr64(ctx, fp0, fs); 10846 gen_load_fpr64(ctx, fp1, ft); 10847 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10848 gen_store_fpr64(ctx, fp1, fd); 10849 tcg_temp_free_i64(fp1); 10850 tcg_temp_free_i64(fp0); 10851 } else { 10852 /* OPC_RSQRT1_D */ 10853 check_cp1_64bitmode(ctx); 10854 { 10855 TCGv_i64 fp0 = tcg_temp_new_i64(); 10856 10857 gen_load_fpr64(ctx, fp0, fs); 10858 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10859 gen_store_fpr64(ctx, fp0, fd); 10860 tcg_temp_free_i64(fp0); 10861 } 10862 } 10863 break; 10864 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10865 if (ctx->insn_flags & ISA_MIPS_R6) { 10866 /* OPC_MAXA_D */ 10867 TCGv_i64 fp0 = tcg_temp_new_i64(); 10868 TCGv_i64 fp1 = tcg_temp_new_i64(); 10869 gen_load_fpr64(ctx, fp0, fs); 10870 gen_load_fpr64(ctx, fp1, ft); 10871 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 10872 gen_store_fpr64(ctx, fp1, fd); 10873 tcg_temp_free_i64(fp1); 10874 tcg_temp_free_i64(fp0); 10875 } else { 10876 /* OPC_RSQRT2_D */ 10877 check_cp1_64bitmode(ctx); 10878 { 10879 TCGv_i64 fp0 = tcg_temp_new_i64(); 10880 TCGv_i64 fp1 = tcg_temp_new_i64(); 10881 10882 gen_load_fpr64(ctx, fp0, fs); 10883 gen_load_fpr64(ctx, fp1, ft); 10884 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 10885 tcg_temp_free_i64(fp1); 10886 gen_store_fpr64(ctx, fp0, fd); 10887 tcg_temp_free_i64(fp0); 10888 } 10889 } 10890 break; 10891 case OPC_CMP_F_D: 10892 case OPC_CMP_UN_D: 10893 case OPC_CMP_EQ_D: 10894 case OPC_CMP_UEQ_D: 10895 case OPC_CMP_OLT_D: 10896 case OPC_CMP_ULT_D: 10897 case OPC_CMP_OLE_D: 10898 case OPC_CMP_ULE_D: 10899 case OPC_CMP_SF_D: 10900 case OPC_CMP_NGLE_D: 10901 case OPC_CMP_SEQ_D: 10902 case OPC_CMP_NGL_D: 10903 case OPC_CMP_LT_D: 10904 case OPC_CMP_NGE_D: 10905 case OPC_CMP_LE_D: 10906 case OPC_CMP_NGT_D: 10907 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10908 if (ctx->opcode & (1 << 6)) { 10909 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10910 } else { 10911 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10912 } 10913 break; 10914 case OPC_CVT_S_D: 10915 check_cp1_registers(ctx, fs); 10916 { 10917 TCGv_i32 fp32 = tcg_temp_new_i32(); 10918 TCGv_i64 fp64 = tcg_temp_new_i64(); 10919 10920 gen_load_fpr64(ctx, fp64, fs); 10921 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 10922 tcg_temp_free_i64(fp64); 10923 gen_store_fpr32(ctx, fp32, fd); 10924 tcg_temp_free_i32(fp32); 10925 } 10926 break; 10927 case OPC_CVT_W_D: 10928 check_cp1_registers(ctx, fs); 10929 { 10930 TCGv_i32 fp32 = tcg_temp_new_i32(); 10931 TCGv_i64 fp64 = tcg_temp_new_i64(); 10932 10933 gen_load_fpr64(ctx, fp64, fs); 10934 if (ctx->nan2008) { 10935 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 10936 } else { 10937 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 10938 } 10939 tcg_temp_free_i64(fp64); 10940 gen_store_fpr32(ctx, fp32, fd); 10941 tcg_temp_free_i32(fp32); 10942 } 10943 break; 10944 case OPC_CVT_L_D: 10945 check_cp1_64bitmode(ctx); 10946 { 10947 TCGv_i64 fp0 = tcg_temp_new_i64(); 10948 10949 gen_load_fpr64(ctx, fp0, fs); 10950 if (ctx->nan2008) { 10951 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 10952 } else { 10953 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 10954 } 10955 gen_store_fpr64(ctx, fp0, fd); 10956 tcg_temp_free_i64(fp0); 10957 } 10958 break; 10959 case OPC_CVT_S_W: 10960 { 10961 TCGv_i32 fp0 = tcg_temp_new_i32(); 10962 10963 gen_load_fpr32(ctx, fp0, fs); 10964 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 10965 gen_store_fpr32(ctx, fp0, fd); 10966 tcg_temp_free_i32(fp0); 10967 } 10968 break; 10969 case OPC_CVT_D_W: 10970 check_cp1_registers(ctx, fd); 10971 { 10972 TCGv_i32 fp32 = tcg_temp_new_i32(); 10973 TCGv_i64 fp64 = tcg_temp_new_i64(); 10974 10975 gen_load_fpr32(ctx, fp32, fs); 10976 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 10977 tcg_temp_free_i32(fp32); 10978 gen_store_fpr64(ctx, fp64, fd); 10979 tcg_temp_free_i64(fp64); 10980 } 10981 break; 10982 case OPC_CVT_S_L: 10983 check_cp1_64bitmode(ctx); 10984 { 10985 TCGv_i32 fp32 = tcg_temp_new_i32(); 10986 TCGv_i64 fp64 = tcg_temp_new_i64(); 10987 10988 gen_load_fpr64(ctx, fp64, fs); 10989 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 10990 tcg_temp_free_i64(fp64); 10991 gen_store_fpr32(ctx, fp32, fd); 10992 tcg_temp_free_i32(fp32); 10993 } 10994 break; 10995 case OPC_CVT_D_L: 10996 check_cp1_64bitmode(ctx); 10997 { 10998 TCGv_i64 fp0 = tcg_temp_new_i64(); 10999 11000 gen_load_fpr64(ctx, fp0, fs); 11001 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11002 gen_store_fpr64(ctx, fp0, fd); 11003 tcg_temp_free_i64(fp0); 11004 } 11005 break; 11006 case OPC_CVT_PS_PW: 11007 check_ps(ctx); 11008 { 11009 TCGv_i64 fp0 = tcg_temp_new_i64(); 11010 11011 gen_load_fpr64(ctx, fp0, fs); 11012 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11013 gen_store_fpr64(ctx, fp0, fd); 11014 tcg_temp_free_i64(fp0); 11015 } 11016 break; 11017 case OPC_ADD_PS: 11018 check_ps(ctx); 11019 { 11020 TCGv_i64 fp0 = tcg_temp_new_i64(); 11021 TCGv_i64 fp1 = tcg_temp_new_i64(); 11022 11023 gen_load_fpr64(ctx, fp0, fs); 11024 gen_load_fpr64(ctx, fp1, ft); 11025 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11026 tcg_temp_free_i64(fp1); 11027 gen_store_fpr64(ctx, fp0, fd); 11028 tcg_temp_free_i64(fp0); 11029 } 11030 break; 11031 case OPC_SUB_PS: 11032 check_ps(ctx); 11033 { 11034 TCGv_i64 fp0 = tcg_temp_new_i64(); 11035 TCGv_i64 fp1 = tcg_temp_new_i64(); 11036 11037 gen_load_fpr64(ctx, fp0, fs); 11038 gen_load_fpr64(ctx, fp1, ft); 11039 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11040 tcg_temp_free_i64(fp1); 11041 gen_store_fpr64(ctx, fp0, fd); 11042 tcg_temp_free_i64(fp0); 11043 } 11044 break; 11045 case OPC_MUL_PS: 11046 check_ps(ctx); 11047 { 11048 TCGv_i64 fp0 = tcg_temp_new_i64(); 11049 TCGv_i64 fp1 = tcg_temp_new_i64(); 11050 11051 gen_load_fpr64(ctx, fp0, fs); 11052 gen_load_fpr64(ctx, fp1, ft); 11053 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11054 tcg_temp_free_i64(fp1); 11055 gen_store_fpr64(ctx, fp0, fd); 11056 tcg_temp_free_i64(fp0); 11057 } 11058 break; 11059 case OPC_ABS_PS: 11060 check_ps(ctx); 11061 { 11062 TCGv_i64 fp0 = tcg_temp_new_i64(); 11063 11064 gen_load_fpr64(ctx, fp0, fs); 11065 gen_helper_float_abs_ps(fp0, fp0); 11066 gen_store_fpr64(ctx, fp0, fd); 11067 tcg_temp_free_i64(fp0); 11068 } 11069 break; 11070 case OPC_MOV_PS: 11071 check_ps(ctx); 11072 { 11073 TCGv_i64 fp0 = tcg_temp_new_i64(); 11074 11075 gen_load_fpr64(ctx, fp0, fs); 11076 gen_store_fpr64(ctx, fp0, fd); 11077 tcg_temp_free_i64(fp0); 11078 } 11079 break; 11080 case OPC_NEG_PS: 11081 check_ps(ctx); 11082 { 11083 TCGv_i64 fp0 = tcg_temp_new_i64(); 11084 11085 gen_load_fpr64(ctx, fp0, fs); 11086 gen_helper_float_chs_ps(fp0, fp0); 11087 gen_store_fpr64(ctx, fp0, fd); 11088 tcg_temp_free_i64(fp0); 11089 } 11090 break; 11091 case OPC_MOVCF_PS: 11092 check_ps(ctx); 11093 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11094 break; 11095 case OPC_MOVZ_PS: 11096 check_ps(ctx); 11097 { 11098 TCGLabel *l1 = gen_new_label(); 11099 TCGv_i64 fp0; 11100 11101 if (ft != 0) { 11102 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11103 } 11104 fp0 = tcg_temp_new_i64(); 11105 gen_load_fpr64(ctx, fp0, fs); 11106 gen_store_fpr64(ctx, fp0, fd); 11107 tcg_temp_free_i64(fp0); 11108 gen_set_label(l1); 11109 } 11110 break; 11111 case OPC_MOVN_PS: 11112 check_ps(ctx); 11113 { 11114 TCGLabel *l1 = gen_new_label(); 11115 TCGv_i64 fp0; 11116 11117 if (ft != 0) { 11118 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11119 fp0 = tcg_temp_new_i64(); 11120 gen_load_fpr64(ctx, fp0, fs); 11121 gen_store_fpr64(ctx, fp0, fd); 11122 tcg_temp_free_i64(fp0); 11123 gen_set_label(l1); 11124 } 11125 } 11126 break; 11127 case OPC_ADDR_PS: 11128 check_ps(ctx); 11129 { 11130 TCGv_i64 fp0 = tcg_temp_new_i64(); 11131 TCGv_i64 fp1 = tcg_temp_new_i64(); 11132 11133 gen_load_fpr64(ctx, fp0, ft); 11134 gen_load_fpr64(ctx, fp1, fs); 11135 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11136 tcg_temp_free_i64(fp1); 11137 gen_store_fpr64(ctx, fp0, fd); 11138 tcg_temp_free_i64(fp0); 11139 } 11140 break; 11141 case OPC_MULR_PS: 11142 check_ps(ctx); 11143 { 11144 TCGv_i64 fp0 = tcg_temp_new_i64(); 11145 TCGv_i64 fp1 = tcg_temp_new_i64(); 11146 11147 gen_load_fpr64(ctx, fp0, ft); 11148 gen_load_fpr64(ctx, fp1, fs); 11149 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11150 tcg_temp_free_i64(fp1); 11151 gen_store_fpr64(ctx, fp0, fd); 11152 tcg_temp_free_i64(fp0); 11153 } 11154 break; 11155 case OPC_RECIP2_PS: 11156 check_ps(ctx); 11157 { 11158 TCGv_i64 fp0 = tcg_temp_new_i64(); 11159 TCGv_i64 fp1 = tcg_temp_new_i64(); 11160 11161 gen_load_fpr64(ctx, fp0, fs); 11162 gen_load_fpr64(ctx, fp1, ft); 11163 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11164 tcg_temp_free_i64(fp1); 11165 gen_store_fpr64(ctx, fp0, fd); 11166 tcg_temp_free_i64(fp0); 11167 } 11168 break; 11169 case OPC_RECIP1_PS: 11170 check_ps(ctx); 11171 { 11172 TCGv_i64 fp0 = tcg_temp_new_i64(); 11173 11174 gen_load_fpr64(ctx, fp0, fs); 11175 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11176 gen_store_fpr64(ctx, fp0, fd); 11177 tcg_temp_free_i64(fp0); 11178 } 11179 break; 11180 case OPC_RSQRT1_PS: 11181 check_ps(ctx); 11182 { 11183 TCGv_i64 fp0 = tcg_temp_new_i64(); 11184 11185 gen_load_fpr64(ctx, fp0, fs); 11186 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11187 gen_store_fpr64(ctx, fp0, fd); 11188 tcg_temp_free_i64(fp0); 11189 } 11190 break; 11191 case OPC_RSQRT2_PS: 11192 check_ps(ctx); 11193 { 11194 TCGv_i64 fp0 = tcg_temp_new_i64(); 11195 TCGv_i64 fp1 = tcg_temp_new_i64(); 11196 11197 gen_load_fpr64(ctx, fp0, fs); 11198 gen_load_fpr64(ctx, fp1, ft); 11199 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11200 tcg_temp_free_i64(fp1); 11201 gen_store_fpr64(ctx, fp0, fd); 11202 tcg_temp_free_i64(fp0); 11203 } 11204 break; 11205 case OPC_CVT_S_PU: 11206 check_cp1_64bitmode(ctx); 11207 { 11208 TCGv_i32 fp0 = tcg_temp_new_i32(); 11209 11210 gen_load_fpr32h(ctx, fp0, fs); 11211 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11212 gen_store_fpr32(ctx, fp0, fd); 11213 tcg_temp_free_i32(fp0); 11214 } 11215 break; 11216 case OPC_CVT_PW_PS: 11217 check_ps(ctx); 11218 { 11219 TCGv_i64 fp0 = tcg_temp_new_i64(); 11220 11221 gen_load_fpr64(ctx, fp0, fs); 11222 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11223 gen_store_fpr64(ctx, fp0, fd); 11224 tcg_temp_free_i64(fp0); 11225 } 11226 break; 11227 case OPC_CVT_S_PL: 11228 check_cp1_64bitmode(ctx); 11229 { 11230 TCGv_i32 fp0 = tcg_temp_new_i32(); 11231 11232 gen_load_fpr32(ctx, fp0, fs); 11233 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11234 gen_store_fpr32(ctx, fp0, fd); 11235 tcg_temp_free_i32(fp0); 11236 } 11237 break; 11238 case OPC_PLL_PS: 11239 check_ps(ctx); 11240 { 11241 TCGv_i32 fp0 = tcg_temp_new_i32(); 11242 TCGv_i32 fp1 = tcg_temp_new_i32(); 11243 11244 gen_load_fpr32(ctx, fp0, fs); 11245 gen_load_fpr32(ctx, fp1, ft); 11246 gen_store_fpr32h(ctx, fp0, fd); 11247 gen_store_fpr32(ctx, fp1, fd); 11248 tcg_temp_free_i32(fp0); 11249 tcg_temp_free_i32(fp1); 11250 } 11251 break; 11252 case OPC_PLU_PS: 11253 check_ps(ctx); 11254 { 11255 TCGv_i32 fp0 = tcg_temp_new_i32(); 11256 TCGv_i32 fp1 = tcg_temp_new_i32(); 11257 11258 gen_load_fpr32(ctx, fp0, fs); 11259 gen_load_fpr32h(ctx, fp1, ft); 11260 gen_store_fpr32(ctx, fp1, fd); 11261 gen_store_fpr32h(ctx, fp0, fd); 11262 tcg_temp_free_i32(fp0); 11263 tcg_temp_free_i32(fp1); 11264 } 11265 break; 11266 case OPC_PUL_PS: 11267 check_ps(ctx); 11268 { 11269 TCGv_i32 fp0 = tcg_temp_new_i32(); 11270 TCGv_i32 fp1 = tcg_temp_new_i32(); 11271 11272 gen_load_fpr32h(ctx, fp0, fs); 11273 gen_load_fpr32(ctx, fp1, ft); 11274 gen_store_fpr32(ctx, fp1, fd); 11275 gen_store_fpr32h(ctx, fp0, fd); 11276 tcg_temp_free_i32(fp0); 11277 tcg_temp_free_i32(fp1); 11278 } 11279 break; 11280 case OPC_PUU_PS: 11281 check_ps(ctx); 11282 { 11283 TCGv_i32 fp0 = tcg_temp_new_i32(); 11284 TCGv_i32 fp1 = tcg_temp_new_i32(); 11285 11286 gen_load_fpr32h(ctx, fp0, fs); 11287 gen_load_fpr32h(ctx, fp1, ft); 11288 gen_store_fpr32(ctx, fp1, fd); 11289 gen_store_fpr32h(ctx, fp0, fd); 11290 tcg_temp_free_i32(fp0); 11291 tcg_temp_free_i32(fp1); 11292 } 11293 break; 11294 case OPC_CMP_F_PS: 11295 case OPC_CMP_UN_PS: 11296 case OPC_CMP_EQ_PS: 11297 case OPC_CMP_UEQ_PS: 11298 case OPC_CMP_OLT_PS: 11299 case OPC_CMP_ULT_PS: 11300 case OPC_CMP_OLE_PS: 11301 case OPC_CMP_ULE_PS: 11302 case OPC_CMP_SF_PS: 11303 case OPC_CMP_NGLE_PS: 11304 case OPC_CMP_SEQ_PS: 11305 case OPC_CMP_NGL_PS: 11306 case OPC_CMP_LT_PS: 11307 case OPC_CMP_NGE_PS: 11308 case OPC_CMP_LE_PS: 11309 case OPC_CMP_NGT_PS: 11310 if (ctx->opcode & (1 << 6)) { 11311 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11312 } else { 11313 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11314 } 11315 break; 11316 default: 11317 MIPS_INVAL("farith"); 11318 gen_reserved_instruction(ctx); 11319 return; 11320 } 11321 } 11322 11323 /* Coprocessor 3 (FPU) */ 11324 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11325 int fd, int fs, int base, int index) 11326 { 11327 TCGv t0 = tcg_temp_new(); 11328 11329 if (base == 0) { 11330 gen_load_gpr(t0, index); 11331 } else if (index == 0) { 11332 gen_load_gpr(t0, base); 11333 } else { 11334 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11335 } 11336 /* 11337 * Don't do NOP if destination is zero: we must perform the actual 11338 * memory access. 11339 */ 11340 switch (opc) { 11341 case OPC_LWXC1: 11342 check_cop1x(ctx); 11343 { 11344 TCGv_i32 fp0 = tcg_temp_new_i32(); 11345 11346 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11347 tcg_gen_trunc_tl_i32(fp0, t0); 11348 gen_store_fpr32(ctx, fp0, fd); 11349 tcg_temp_free_i32(fp0); 11350 } 11351 break; 11352 case OPC_LDXC1: 11353 check_cop1x(ctx); 11354 check_cp1_registers(ctx, fd); 11355 { 11356 TCGv_i64 fp0 = tcg_temp_new_i64(); 11357 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11358 gen_store_fpr64(ctx, fp0, fd); 11359 tcg_temp_free_i64(fp0); 11360 } 11361 break; 11362 case OPC_LUXC1: 11363 check_cp1_64bitmode(ctx); 11364 tcg_gen_andi_tl(t0, t0, ~0x7); 11365 { 11366 TCGv_i64 fp0 = tcg_temp_new_i64(); 11367 11368 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11369 gen_store_fpr64(ctx, fp0, fd); 11370 tcg_temp_free_i64(fp0); 11371 } 11372 break; 11373 case OPC_SWXC1: 11374 check_cop1x(ctx); 11375 { 11376 TCGv_i32 fp0 = tcg_temp_new_i32(); 11377 gen_load_fpr32(ctx, fp0, fs); 11378 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11379 tcg_temp_free_i32(fp0); 11380 } 11381 break; 11382 case OPC_SDXC1: 11383 check_cop1x(ctx); 11384 check_cp1_registers(ctx, fs); 11385 { 11386 TCGv_i64 fp0 = tcg_temp_new_i64(); 11387 gen_load_fpr64(ctx, fp0, fs); 11388 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11389 tcg_temp_free_i64(fp0); 11390 } 11391 break; 11392 case OPC_SUXC1: 11393 check_cp1_64bitmode(ctx); 11394 tcg_gen_andi_tl(t0, t0, ~0x7); 11395 { 11396 TCGv_i64 fp0 = tcg_temp_new_i64(); 11397 gen_load_fpr64(ctx, fp0, fs); 11398 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ); 11399 tcg_temp_free_i64(fp0); 11400 } 11401 break; 11402 } 11403 tcg_temp_free(t0); 11404 } 11405 11406 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11407 int fd, int fr, int fs, int ft) 11408 { 11409 switch (opc) { 11410 case OPC_ALNV_PS: 11411 check_ps(ctx); 11412 { 11413 TCGv t0 = tcg_temp_local_new(); 11414 TCGv_i32 fp = tcg_temp_new_i32(); 11415 TCGv_i32 fph = tcg_temp_new_i32(); 11416 TCGLabel *l1 = gen_new_label(); 11417 TCGLabel *l2 = gen_new_label(); 11418 11419 gen_load_gpr(t0, fr); 11420 tcg_gen_andi_tl(t0, t0, 0x7); 11421 11422 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11423 gen_load_fpr32(ctx, fp, fs); 11424 gen_load_fpr32h(ctx, fph, fs); 11425 gen_store_fpr32(ctx, fp, fd); 11426 gen_store_fpr32h(ctx, fph, fd); 11427 tcg_gen_br(l2); 11428 gen_set_label(l1); 11429 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11430 tcg_temp_free(t0); 11431 if (cpu_is_bigendian(ctx)) { 11432 gen_load_fpr32(ctx, fp, fs); 11433 gen_load_fpr32h(ctx, fph, ft); 11434 gen_store_fpr32h(ctx, fp, fd); 11435 gen_store_fpr32(ctx, fph, fd); 11436 } else { 11437 gen_load_fpr32h(ctx, fph, fs); 11438 gen_load_fpr32(ctx, fp, ft); 11439 gen_store_fpr32(ctx, fph, fd); 11440 gen_store_fpr32h(ctx, fp, fd); 11441 } 11442 gen_set_label(l2); 11443 tcg_temp_free_i32(fp); 11444 tcg_temp_free_i32(fph); 11445 } 11446 break; 11447 case OPC_MADD_S: 11448 check_cop1x(ctx); 11449 { 11450 TCGv_i32 fp0 = tcg_temp_new_i32(); 11451 TCGv_i32 fp1 = tcg_temp_new_i32(); 11452 TCGv_i32 fp2 = tcg_temp_new_i32(); 11453 11454 gen_load_fpr32(ctx, fp0, fs); 11455 gen_load_fpr32(ctx, fp1, ft); 11456 gen_load_fpr32(ctx, fp2, fr); 11457 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11458 tcg_temp_free_i32(fp0); 11459 tcg_temp_free_i32(fp1); 11460 gen_store_fpr32(ctx, fp2, fd); 11461 tcg_temp_free_i32(fp2); 11462 } 11463 break; 11464 case OPC_MADD_D: 11465 check_cop1x(ctx); 11466 check_cp1_registers(ctx, fd | fs | ft | fr); 11467 { 11468 TCGv_i64 fp0 = tcg_temp_new_i64(); 11469 TCGv_i64 fp1 = tcg_temp_new_i64(); 11470 TCGv_i64 fp2 = tcg_temp_new_i64(); 11471 11472 gen_load_fpr64(ctx, fp0, fs); 11473 gen_load_fpr64(ctx, fp1, ft); 11474 gen_load_fpr64(ctx, fp2, fr); 11475 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11476 tcg_temp_free_i64(fp0); 11477 tcg_temp_free_i64(fp1); 11478 gen_store_fpr64(ctx, fp2, fd); 11479 tcg_temp_free_i64(fp2); 11480 } 11481 break; 11482 case OPC_MADD_PS: 11483 check_ps(ctx); 11484 { 11485 TCGv_i64 fp0 = tcg_temp_new_i64(); 11486 TCGv_i64 fp1 = tcg_temp_new_i64(); 11487 TCGv_i64 fp2 = tcg_temp_new_i64(); 11488 11489 gen_load_fpr64(ctx, fp0, fs); 11490 gen_load_fpr64(ctx, fp1, ft); 11491 gen_load_fpr64(ctx, fp2, fr); 11492 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11493 tcg_temp_free_i64(fp0); 11494 tcg_temp_free_i64(fp1); 11495 gen_store_fpr64(ctx, fp2, fd); 11496 tcg_temp_free_i64(fp2); 11497 } 11498 break; 11499 case OPC_MSUB_S: 11500 check_cop1x(ctx); 11501 { 11502 TCGv_i32 fp0 = tcg_temp_new_i32(); 11503 TCGv_i32 fp1 = tcg_temp_new_i32(); 11504 TCGv_i32 fp2 = tcg_temp_new_i32(); 11505 11506 gen_load_fpr32(ctx, fp0, fs); 11507 gen_load_fpr32(ctx, fp1, ft); 11508 gen_load_fpr32(ctx, fp2, fr); 11509 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11510 tcg_temp_free_i32(fp0); 11511 tcg_temp_free_i32(fp1); 11512 gen_store_fpr32(ctx, fp2, fd); 11513 tcg_temp_free_i32(fp2); 11514 } 11515 break; 11516 case OPC_MSUB_D: 11517 check_cop1x(ctx); 11518 check_cp1_registers(ctx, fd | fs | ft | fr); 11519 { 11520 TCGv_i64 fp0 = tcg_temp_new_i64(); 11521 TCGv_i64 fp1 = tcg_temp_new_i64(); 11522 TCGv_i64 fp2 = tcg_temp_new_i64(); 11523 11524 gen_load_fpr64(ctx, fp0, fs); 11525 gen_load_fpr64(ctx, fp1, ft); 11526 gen_load_fpr64(ctx, fp2, fr); 11527 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11528 tcg_temp_free_i64(fp0); 11529 tcg_temp_free_i64(fp1); 11530 gen_store_fpr64(ctx, fp2, fd); 11531 tcg_temp_free_i64(fp2); 11532 } 11533 break; 11534 case OPC_MSUB_PS: 11535 check_ps(ctx); 11536 { 11537 TCGv_i64 fp0 = tcg_temp_new_i64(); 11538 TCGv_i64 fp1 = tcg_temp_new_i64(); 11539 TCGv_i64 fp2 = tcg_temp_new_i64(); 11540 11541 gen_load_fpr64(ctx, fp0, fs); 11542 gen_load_fpr64(ctx, fp1, ft); 11543 gen_load_fpr64(ctx, fp2, fr); 11544 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11545 tcg_temp_free_i64(fp0); 11546 tcg_temp_free_i64(fp1); 11547 gen_store_fpr64(ctx, fp2, fd); 11548 tcg_temp_free_i64(fp2); 11549 } 11550 break; 11551 case OPC_NMADD_S: 11552 check_cop1x(ctx); 11553 { 11554 TCGv_i32 fp0 = tcg_temp_new_i32(); 11555 TCGv_i32 fp1 = tcg_temp_new_i32(); 11556 TCGv_i32 fp2 = tcg_temp_new_i32(); 11557 11558 gen_load_fpr32(ctx, fp0, fs); 11559 gen_load_fpr32(ctx, fp1, ft); 11560 gen_load_fpr32(ctx, fp2, fr); 11561 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11562 tcg_temp_free_i32(fp0); 11563 tcg_temp_free_i32(fp1); 11564 gen_store_fpr32(ctx, fp2, fd); 11565 tcg_temp_free_i32(fp2); 11566 } 11567 break; 11568 case OPC_NMADD_D: 11569 check_cop1x(ctx); 11570 check_cp1_registers(ctx, fd | fs | ft | fr); 11571 { 11572 TCGv_i64 fp0 = tcg_temp_new_i64(); 11573 TCGv_i64 fp1 = tcg_temp_new_i64(); 11574 TCGv_i64 fp2 = tcg_temp_new_i64(); 11575 11576 gen_load_fpr64(ctx, fp0, fs); 11577 gen_load_fpr64(ctx, fp1, ft); 11578 gen_load_fpr64(ctx, fp2, fr); 11579 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11580 tcg_temp_free_i64(fp0); 11581 tcg_temp_free_i64(fp1); 11582 gen_store_fpr64(ctx, fp2, fd); 11583 tcg_temp_free_i64(fp2); 11584 } 11585 break; 11586 case OPC_NMADD_PS: 11587 check_ps(ctx); 11588 { 11589 TCGv_i64 fp0 = tcg_temp_new_i64(); 11590 TCGv_i64 fp1 = tcg_temp_new_i64(); 11591 TCGv_i64 fp2 = tcg_temp_new_i64(); 11592 11593 gen_load_fpr64(ctx, fp0, fs); 11594 gen_load_fpr64(ctx, fp1, ft); 11595 gen_load_fpr64(ctx, fp2, fr); 11596 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11597 tcg_temp_free_i64(fp0); 11598 tcg_temp_free_i64(fp1); 11599 gen_store_fpr64(ctx, fp2, fd); 11600 tcg_temp_free_i64(fp2); 11601 } 11602 break; 11603 case OPC_NMSUB_S: 11604 check_cop1x(ctx); 11605 { 11606 TCGv_i32 fp0 = tcg_temp_new_i32(); 11607 TCGv_i32 fp1 = tcg_temp_new_i32(); 11608 TCGv_i32 fp2 = tcg_temp_new_i32(); 11609 11610 gen_load_fpr32(ctx, fp0, fs); 11611 gen_load_fpr32(ctx, fp1, ft); 11612 gen_load_fpr32(ctx, fp2, fr); 11613 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11614 tcg_temp_free_i32(fp0); 11615 tcg_temp_free_i32(fp1); 11616 gen_store_fpr32(ctx, fp2, fd); 11617 tcg_temp_free_i32(fp2); 11618 } 11619 break; 11620 case OPC_NMSUB_D: 11621 check_cop1x(ctx); 11622 check_cp1_registers(ctx, fd | fs | ft | fr); 11623 { 11624 TCGv_i64 fp0 = tcg_temp_new_i64(); 11625 TCGv_i64 fp1 = tcg_temp_new_i64(); 11626 TCGv_i64 fp2 = tcg_temp_new_i64(); 11627 11628 gen_load_fpr64(ctx, fp0, fs); 11629 gen_load_fpr64(ctx, fp1, ft); 11630 gen_load_fpr64(ctx, fp2, fr); 11631 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11632 tcg_temp_free_i64(fp0); 11633 tcg_temp_free_i64(fp1); 11634 gen_store_fpr64(ctx, fp2, fd); 11635 tcg_temp_free_i64(fp2); 11636 } 11637 break; 11638 case OPC_NMSUB_PS: 11639 check_ps(ctx); 11640 { 11641 TCGv_i64 fp0 = tcg_temp_new_i64(); 11642 TCGv_i64 fp1 = tcg_temp_new_i64(); 11643 TCGv_i64 fp2 = tcg_temp_new_i64(); 11644 11645 gen_load_fpr64(ctx, fp0, fs); 11646 gen_load_fpr64(ctx, fp1, ft); 11647 gen_load_fpr64(ctx, fp2, fr); 11648 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11649 tcg_temp_free_i64(fp0); 11650 tcg_temp_free_i64(fp1); 11651 gen_store_fpr64(ctx, fp2, fd); 11652 tcg_temp_free_i64(fp2); 11653 } 11654 break; 11655 default: 11656 MIPS_INVAL("flt3_arith"); 11657 gen_reserved_instruction(ctx); 11658 return; 11659 } 11660 } 11661 11662 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11663 { 11664 TCGv t0; 11665 11666 #if !defined(CONFIG_USER_ONLY) 11667 /* 11668 * The Linux kernel will emulate rdhwr if it's not supported natively. 11669 * Therefore only check the ISA in system mode. 11670 */ 11671 check_insn(ctx, ISA_MIPS_R2); 11672 #endif 11673 t0 = tcg_temp_new(); 11674 11675 switch (rd) { 11676 case 0: 11677 gen_helper_rdhwr_cpunum(t0, cpu_env); 11678 gen_store_gpr(t0, rt); 11679 break; 11680 case 1: 11681 gen_helper_rdhwr_synci_step(t0, cpu_env); 11682 gen_store_gpr(t0, rt); 11683 break; 11684 case 2: 11685 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11686 gen_io_start(); 11687 } 11688 gen_helper_rdhwr_cc(t0, cpu_env); 11689 gen_store_gpr(t0, rt); 11690 /* 11691 * Break the TB to be able to take timer interrupts immediately 11692 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11693 * we break completely out of translated code. 11694 */ 11695 gen_save_pc(ctx->base.pc_next + 4); 11696 ctx->base.is_jmp = DISAS_EXIT; 11697 break; 11698 case 3: 11699 gen_helper_rdhwr_ccres(t0, cpu_env); 11700 gen_store_gpr(t0, rt); 11701 break; 11702 case 4: 11703 check_insn(ctx, ISA_MIPS_R6); 11704 if (sel != 0) { 11705 /* 11706 * Performance counter registers are not implemented other than 11707 * control register 0. 11708 */ 11709 generate_exception(ctx, EXCP_RI); 11710 } 11711 gen_helper_rdhwr_performance(t0, cpu_env); 11712 gen_store_gpr(t0, rt); 11713 break; 11714 case 5: 11715 check_insn(ctx, ISA_MIPS_R6); 11716 gen_helper_rdhwr_xnp(t0, cpu_env); 11717 gen_store_gpr(t0, rt); 11718 break; 11719 case 29: 11720 #if defined(CONFIG_USER_ONLY) 11721 tcg_gen_ld_tl(t0, cpu_env, 11722 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11723 gen_store_gpr(t0, rt); 11724 break; 11725 #else 11726 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11727 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11728 tcg_gen_ld_tl(t0, cpu_env, 11729 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11730 gen_store_gpr(t0, rt); 11731 } else { 11732 gen_reserved_instruction(ctx); 11733 } 11734 break; 11735 #endif 11736 default: /* Invalid */ 11737 MIPS_INVAL("rdhwr"); 11738 gen_reserved_instruction(ctx); 11739 break; 11740 } 11741 tcg_temp_free(t0); 11742 } 11743 11744 static inline void clear_branch_hflags(DisasContext *ctx) 11745 { 11746 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11747 if (ctx->base.is_jmp == DISAS_NEXT) { 11748 save_cpu_state(ctx, 0); 11749 } else { 11750 /* 11751 * It is not safe to save ctx->hflags as hflags may be changed 11752 * in execution time by the instruction in delay / forbidden slot. 11753 */ 11754 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11755 } 11756 } 11757 11758 static void gen_branch(DisasContext *ctx, int insn_bytes) 11759 { 11760 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11761 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11762 /* Branches completion */ 11763 clear_branch_hflags(ctx); 11764 ctx->base.is_jmp = DISAS_NORETURN; 11765 /* FIXME: Need to clear can_do_io. */ 11766 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11767 case MIPS_HFLAG_FBNSLOT: 11768 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11769 break; 11770 case MIPS_HFLAG_B: 11771 /* unconditional branch */ 11772 if (proc_hflags & MIPS_HFLAG_BX) { 11773 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11774 } 11775 gen_goto_tb(ctx, 0, ctx->btarget); 11776 break; 11777 case MIPS_HFLAG_BL: 11778 /* blikely taken case */ 11779 gen_goto_tb(ctx, 0, ctx->btarget); 11780 break; 11781 case MIPS_HFLAG_BC: 11782 /* Conditional branch */ 11783 { 11784 TCGLabel *l1 = gen_new_label(); 11785 11786 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11787 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11788 gen_set_label(l1); 11789 gen_goto_tb(ctx, 0, ctx->btarget); 11790 } 11791 break; 11792 case MIPS_HFLAG_BR: 11793 /* unconditional branch to register */ 11794 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11795 TCGv t0 = tcg_temp_new(); 11796 TCGv_i32 t1 = tcg_temp_new_i32(); 11797 11798 tcg_gen_andi_tl(t0, btarget, 0x1); 11799 tcg_gen_trunc_tl_i32(t1, t0); 11800 tcg_temp_free(t0); 11801 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11802 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11803 tcg_gen_or_i32(hflags, hflags, t1); 11804 tcg_temp_free_i32(t1); 11805 11806 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11807 } else { 11808 tcg_gen_mov_tl(cpu_PC, btarget); 11809 } 11810 tcg_gen_lookup_and_goto_ptr(); 11811 break; 11812 default: 11813 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11814 gen_reserved_instruction(ctx); 11815 } 11816 } 11817 } 11818 11819 /* Compact Branches */ 11820 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11821 int rs, int rt, int32_t offset) 11822 { 11823 int bcond_compute = 0; 11824 TCGv t0 = tcg_temp_new(); 11825 TCGv t1 = tcg_temp_new(); 11826 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11827 11828 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11829 #ifdef MIPS_DEBUG_DISAS 11830 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11831 "\n", ctx->base.pc_next); 11832 #endif 11833 gen_reserved_instruction(ctx); 11834 goto out; 11835 } 11836 11837 /* Load needed operands and calculate btarget */ 11838 switch (opc) { 11839 /* compact branch */ 11840 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11841 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11842 gen_load_gpr(t0, rs); 11843 gen_load_gpr(t1, rt); 11844 bcond_compute = 1; 11845 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11846 if (rs <= rt && rs == 0) { 11847 /* OPC_BEQZALC, OPC_BNEZALC */ 11848 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11849 } 11850 break; 11851 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11852 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11853 gen_load_gpr(t0, rs); 11854 gen_load_gpr(t1, rt); 11855 bcond_compute = 1; 11856 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11857 break; 11858 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11859 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11860 if (rs == 0 || rs == rt) { 11861 /* OPC_BLEZALC, OPC_BGEZALC */ 11862 /* OPC_BGTZALC, OPC_BLTZALC */ 11863 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11864 } 11865 gen_load_gpr(t0, rs); 11866 gen_load_gpr(t1, rt); 11867 bcond_compute = 1; 11868 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11869 break; 11870 case OPC_BC: 11871 case OPC_BALC: 11872 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11873 break; 11874 case OPC_BEQZC: 11875 case OPC_BNEZC: 11876 if (rs != 0) { 11877 /* OPC_BEQZC, OPC_BNEZC */ 11878 gen_load_gpr(t0, rs); 11879 bcond_compute = 1; 11880 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11881 } else { 11882 /* OPC_JIC, OPC_JIALC */ 11883 TCGv tbase = tcg_temp_new(); 11884 TCGv toffset = tcg_constant_tl(offset); 11885 11886 gen_load_gpr(tbase, rt); 11887 gen_op_addr_add(ctx, btarget, tbase, toffset); 11888 tcg_temp_free(tbase); 11889 } 11890 break; 11891 default: 11892 MIPS_INVAL("Compact branch/jump"); 11893 gen_reserved_instruction(ctx); 11894 goto out; 11895 } 11896 11897 if (bcond_compute == 0) { 11898 /* Unconditional compact branch */ 11899 switch (opc) { 11900 case OPC_JIALC: 11901 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11902 /* Fallthrough */ 11903 case OPC_JIC: 11904 ctx->hflags |= MIPS_HFLAG_BR; 11905 break; 11906 case OPC_BALC: 11907 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11908 /* Fallthrough */ 11909 case OPC_BC: 11910 ctx->hflags |= MIPS_HFLAG_B; 11911 break; 11912 default: 11913 MIPS_INVAL("Compact branch/jump"); 11914 gen_reserved_instruction(ctx); 11915 goto out; 11916 } 11917 11918 /* Generating branch here as compact branches don't have delay slot */ 11919 gen_branch(ctx, 4); 11920 } else { 11921 /* Conditional compact branch */ 11922 TCGLabel *fs = gen_new_label(); 11923 save_cpu_state(ctx, 0); 11924 11925 switch (opc) { 11926 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11927 if (rs == 0 && rt != 0) { 11928 /* OPC_BLEZALC */ 11929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11930 } else if (rs != 0 && rt != 0 && rs == rt) { 11931 /* OPC_BGEZALC */ 11932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11933 } else { 11934 /* OPC_BGEUC */ 11935 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11936 } 11937 break; 11938 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11939 if (rs == 0 && rt != 0) { 11940 /* OPC_BGTZALC */ 11941 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11942 } else if (rs != 0 && rt != 0 && rs == rt) { 11943 /* OPC_BLTZALC */ 11944 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11945 } else { 11946 /* OPC_BLTUC */ 11947 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11948 } 11949 break; 11950 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11951 if (rs == 0 && rt != 0) { 11952 /* OPC_BLEZC */ 11953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11954 } else if (rs != 0 && rt != 0 && rs == rt) { 11955 /* OPC_BGEZC */ 11956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11957 } else { 11958 /* OPC_BGEC */ 11959 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11960 } 11961 break; 11962 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11963 if (rs == 0 && rt != 0) { 11964 /* OPC_BGTZC */ 11965 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11966 } else if (rs != 0 && rt != 0 && rs == rt) { 11967 /* OPC_BLTZC */ 11968 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11969 } else { 11970 /* OPC_BLTC */ 11971 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11972 } 11973 break; 11974 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11975 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11976 if (rs >= rt) { 11977 /* OPC_BOVC, OPC_BNVC */ 11978 TCGv t2 = tcg_temp_new(); 11979 TCGv t3 = tcg_temp_new(); 11980 TCGv t4 = tcg_temp_new(); 11981 TCGv input_overflow = tcg_temp_new(); 11982 11983 gen_load_gpr(t0, rs); 11984 gen_load_gpr(t1, rt); 11985 tcg_gen_ext32s_tl(t2, t0); 11986 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11987 tcg_gen_ext32s_tl(t3, t1); 11988 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11989 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11990 11991 tcg_gen_add_tl(t4, t2, t3); 11992 tcg_gen_ext32s_tl(t4, t4); 11993 tcg_gen_xor_tl(t2, t2, t3); 11994 tcg_gen_xor_tl(t3, t4, t3); 11995 tcg_gen_andc_tl(t2, t3, t2); 11996 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11997 tcg_gen_or_tl(t4, t4, input_overflow); 11998 if (opc == OPC_BOVC) { 11999 /* OPC_BOVC */ 12000 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12001 } else { 12002 /* OPC_BNVC */ 12003 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12004 } 12005 tcg_temp_free(input_overflow); 12006 tcg_temp_free(t4); 12007 tcg_temp_free(t3); 12008 tcg_temp_free(t2); 12009 } else if (rs < rt && rs == 0) { 12010 /* OPC_BEQZALC, OPC_BNEZALC */ 12011 if (opc == OPC_BEQZALC) { 12012 /* OPC_BEQZALC */ 12013 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12014 } else { 12015 /* OPC_BNEZALC */ 12016 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12017 } 12018 } else { 12019 /* OPC_BEQC, OPC_BNEC */ 12020 if (opc == OPC_BEQC) { 12021 /* OPC_BEQC */ 12022 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12023 } else { 12024 /* OPC_BNEC */ 12025 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12026 } 12027 } 12028 break; 12029 case OPC_BEQZC: 12030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12031 break; 12032 case OPC_BNEZC: 12033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12034 break; 12035 default: 12036 MIPS_INVAL("Compact conditional branch/jump"); 12037 gen_reserved_instruction(ctx); 12038 goto out; 12039 } 12040 12041 /* Generating branch here as compact branches don't have delay slot */ 12042 gen_goto_tb(ctx, 1, ctx->btarget); 12043 gen_set_label(fs); 12044 12045 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12046 } 12047 12048 out: 12049 tcg_temp_free(t0); 12050 tcg_temp_free(t1); 12051 } 12052 12053 void gen_addiupc(DisasContext *ctx, int rx, int imm, 12054 int is_64_bit, int extended) 12055 { 12056 TCGv t0; 12057 12058 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12059 gen_reserved_instruction(ctx); 12060 return; 12061 } 12062 12063 t0 = tcg_temp_new(); 12064 12065 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12066 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12067 if (!is_64_bit) { 12068 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12069 } 12070 12071 tcg_temp_free(t0); 12072 } 12073 12074 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12075 int16_t offset) 12076 { 12077 TCGv_i32 t0 = tcg_const_i32(op); 12078 TCGv t1 = tcg_temp_new(); 12079 gen_base_offset_addr(ctx, t1, base, offset); 12080 gen_helper_cache(cpu_env, t1, t0); 12081 tcg_temp_free(t1); 12082 tcg_temp_free_i32(t0); 12083 } 12084 12085 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 12086 { 12087 #ifdef CONFIG_USER_ONLY 12088 return false; 12089 #else 12090 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 12091 return semihosting_enabled(is_user) && sdbbp_code == 1; 12092 #endif 12093 } 12094 12095 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 12096 { 12097 TCGv t0 = tcg_temp_new(); 12098 TCGv t1 = tcg_temp_new(); 12099 12100 gen_load_gpr(t0, base); 12101 12102 if (index != 0) { 12103 gen_load_gpr(t1, index); 12104 tcg_gen_shli_tl(t1, t1, 2); 12105 gen_op_addr_add(ctx, t0, t1, t0); 12106 } 12107 12108 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 12109 gen_store_gpr(t1, rd); 12110 12111 tcg_temp_free(t0); 12112 tcg_temp_free(t1); 12113 } 12114 12115 static void gen_sync(int stype) 12116 { 12117 TCGBar tcg_mo = TCG_BAR_SC; 12118 12119 switch (stype) { 12120 case 0x4: /* SYNC_WMB */ 12121 tcg_mo |= TCG_MO_ST_ST; 12122 break; 12123 case 0x10: /* SYNC_MB */ 12124 tcg_mo |= TCG_MO_ALL; 12125 break; 12126 case 0x11: /* SYNC_ACQUIRE */ 12127 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 12128 break; 12129 case 0x12: /* SYNC_RELEASE */ 12130 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 12131 break; 12132 case 0x13: /* SYNC_RMB */ 12133 tcg_mo |= TCG_MO_LD_LD; 12134 break; 12135 default: 12136 tcg_mo |= TCG_MO_ALL; 12137 break; 12138 } 12139 12140 tcg_gen_mb(tcg_mo); 12141 } 12142 12143 /* ISA extensions (ASEs) */ 12144 12145 /* MIPS16 extension to MIPS32 */ 12146 #include "mips16e_translate.c.inc" 12147 12148 /* microMIPS extension to MIPS32/MIPS64 */ 12149 12150 /* 12151 * Values for microMIPS fmt field. Variable-width, depending on which 12152 * formats the instruction supports. 12153 */ 12154 enum { 12155 FMT_SD_S = 0, 12156 FMT_SD_D = 1, 12157 12158 FMT_SDPS_S = 0, 12159 FMT_SDPS_D = 1, 12160 FMT_SDPS_PS = 2, 12161 12162 FMT_SWL_S = 0, 12163 FMT_SWL_W = 1, 12164 FMT_SWL_L = 2, 12165 12166 FMT_DWL_D = 0, 12167 FMT_DWL_W = 1, 12168 FMT_DWL_L = 2 12169 }; 12170 12171 #include "micromips_translate.c.inc" 12172 12173 #include "nanomips_translate.c.inc" 12174 12175 /* MIPSDSP functions. */ 12176 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, 12177 int rd, int base, int offset) 12178 { 12179 TCGv t0; 12180 12181 check_dsp(ctx); 12182 t0 = tcg_temp_new(); 12183 12184 if (base == 0) { 12185 gen_load_gpr(t0, offset); 12186 } else if (offset == 0) { 12187 gen_load_gpr(t0, base); 12188 } else { 12189 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 12190 } 12191 12192 switch (opc) { 12193 case OPC_LBUX: 12194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 12195 gen_store_gpr(t0, rd); 12196 break; 12197 case OPC_LHX: 12198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 12199 gen_store_gpr(t0, rd); 12200 break; 12201 case OPC_LWX: 12202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 12203 gen_store_gpr(t0, rd); 12204 break; 12205 #if defined(TARGET_MIPS64) 12206 case OPC_LDX: 12207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ); 12208 gen_store_gpr(t0, rd); 12209 break; 12210 #endif 12211 } 12212 tcg_temp_free(t0); 12213 } 12214 12215 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 12216 int ret, int v1, int v2) 12217 { 12218 TCGv v1_t; 12219 TCGv v2_t; 12220 12221 if (ret == 0) { 12222 /* Treat as NOP. */ 12223 return; 12224 } 12225 12226 v1_t = tcg_temp_new(); 12227 v2_t = tcg_temp_new(); 12228 12229 gen_load_gpr(v1_t, v1); 12230 gen_load_gpr(v2_t, v2); 12231 12232 switch (op1) { 12233 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 12234 case OPC_MULT_G_2E: 12235 check_dsp_r2(ctx); 12236 switch (op2) { 12237 case OPC_ADDUH_QB: 12238 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 12239 break; 12240 case OPC_ADDUH_R_QB: 12241 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12242 break; 12243 case OPC_ADDQH_PH: 12244 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 12245 break; 12246 case OPC_ADDQH_R_PH: 12247 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12248 break; 12249 case OPC_ADDQH_W: 12250 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 12251 break; 12252 case OPC_ADDQH_R_W: 12253 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12254 break; 12255 case OPC_SUBUH_QB: 12256 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 12257 break; 12258 case OPC_SUBUH_R_QB: 12259 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12260 break; 12261 case OPC_SUBQH_PH: 12262 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 12263 break; 12264 case OPC_SUBQH_R_PH: 12265 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12266 break; 12267 case OPC_SUBQH_W: 12268 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 12269 break; 12270 case OPC_SUBQH_R_W: 12271 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12272 break; 12273 } 12274 break; 12275 case OPC_ABSQ_S_PH_DSP: 12276 switch (op2) { 12277 case OPC_ABSQ_S_QB: 12278 check_dsp_r2(ctx); 12279 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 12280 break; 12281 case OPC_ABSQ_S_PH: 12282 check_dsp(ctx); 12283 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 12284 break; 12285 case OPC_ABSQ_S_W: 12286 check_dsp(ctx); 12287 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 12288 break; 12289 case OPC_PRECEQ_W_PHL: 12290 check_dsp(ctx); 12291 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 12292 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12293 break; 12294 case OPC_PRECEQ_W_PHR: 12295 check_dsp(ctx); 12296 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 12297 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 12298 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12299 break; 12300 case OPC_PRECEQU_PH_QBL: 12301 check_dsp(ctx); 12302 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 12303 break; 12304 case OPC_PRECEQU_PH_QBR: 12305 check_dsp(ctx); 12306 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 12307 break; 12308 case OPC_PRECEQU_PH_QBLA: 12309 check_dsp(ctx); 12310 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 12311 break; 12312 case OPC_PRECEQU_PH_QBRA: 12313 check_dsp(ctx); 12314 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 12315 break; 12316 case OPC_PRECEU_PH_QBL: 12317 check_dsp(ctx); 12318 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 12319 break; 12320 case OPC_PRECEU_PH_QBR: 12321 check_dsp(ctx); 12322 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 12323 break; 12324 case OPC_PRECEU_PH_QBLA: 12325 check_dsp(ctx); 12326 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 12327 break; 12328 case OPC_PRECEU_PH_QBRA: 12329 check_dsp(ctx); 12330 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 12331 break; 12332 } 12333 break; 12334 case OPC_ADDU_QB_DSP: 12335 switch (op2) { 12336 case OPC_ADDQ_PH: 12337 check_dsp(ctx); 12338 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12339 break; 12340 case OPC_ADDQ_S_PH: 12341 check_dsp(ctx); 12342 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12343 break; 12344 case OPC_ADDQ_S_W: 12345 check_dsp(ctx); 12346 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12347 break; 12348 case OPC_ADDU_QB: 12349 check_dsp(ctx); 12350 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12351 break; 12352 case OPC_ADDU_S_QB: 12353 check_dsp(ctx); 12354 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12355 break; 12356 case OPC_ADDU_PH: 12357 check_dsp_r2(ctx); 12358 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12359 break; 12360 case OPC_ADDU_S_PH: 12361 check_dsp_r2(ctx); 12362 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12363 break; 12364 case OPC_SUBQ_PH: 12365 check_dsp(ctx); 12366 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12367 break; 12368 case OPC_SUBQ_S_PH: 12369 check_dsp(ctx); 12370 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12371 break; 12372 case OPC_SUBQ_S_W: 12373 check_dsp(ctx); 12374 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12375 break; 12376 case OPC_SUBU_QB: 12377 check_dsp(ctx); 12378 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12379 break; 12380 case OPC_SUBU_S_QB: 12381 check_dsp(ctx); 12382 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12383 break; 12384 case OPC_SUBU_PH: 12385 check_dsp_r2(ctx); 12386 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12387 break; 12388 case OPC_SUBU_S_PH: 12389 check_dsp_r2(ctx); 12390 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12391 break; 12392 case OPC_ADDSC: 12393 check_dsp(ctx); 12394 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12395 break; 12396 case OPC_ADDWC: 12397 check_dsp(ctx); 12398 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12399 break; 12400 case OPC_MODSUB: 12401 check_dsp(ctx); 12402 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 12403 break; 12404 case OPC_RADDU_W_QB: 12405 check_dsp(ctx); 12406 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 12407 break; 12408 } 12409 break; 12410 case OPC_CMPU_EQ_QB_DSP: 12411 switch (op2) { 12412 case OPC_PRECR_QB_PH: 12413 check_dsp_r2(ctx); 12414 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12415 break; 12416 case OPC_PRECRQ_QB_PH: 12417 check_dsp(ctx); 12418 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12419 break; 12420 case OPC_PRECR_SRA_PH_W: 12421 check_dsp_r2(ctx); 12422 { 12423 TCGv_i32 sa_t = tcg_const_i32(v2); 12424 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 12425 cpu_gpr[ret]); 12426 tcg_temp_free_i32(sa_t); 12427 break; 12428 } 12429 case OPC_PRECR_SRA_R_PH_W: 12430 check_dsp_r2(ctx); 12431 { 12432 TCGv_i32 sa_t = tcg_const_i32(v2); 12433 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 12434 cpu_gpr[ret]); 12435 tcg_temp_free_i32(sa_t); 12436 break; 12437 } 12438 case OPC_PRECRQ_PH_W: 12439 check_dsp(ctx); 12440 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 12441 break; 12442 case OPC_PRECRQ_RS_PH_W: 12443 check_dsp(ctx); 12444 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12445 break; 12446 case OPC_PRECRQU_S_QB_PH: 12447 check_dsp(ctx); 12448 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12449 break; 12450 } 12451 break; 12452 #ifdef TARGET_MIPS64 12453 case OPC_ABSQ_S_QH_DSP: 12454 switch (op2) { 12455 case OPC_PRECEQ_L_PWL: 12456 check_dsp(ctx); 12457 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 12458 break; 12459 case OPC_PRECEQ_L_PWR: 12460 check_dsp(ctx); 12461 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 12462 break; 12463 case OPC_PRECEQ_PW_QHL: 12464 check_dsp(ctx); 12465 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 12466 break; 12467 case OPC_PRECEQ_PW_QHR: 12468 check_dsp(ctx); 12469 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 12470 break; 12471 case OPC_PRECEQ_PW_QHLA: 12472 check_dsp(ctx); 12473 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 12474 break; 12475 case OPC_PRECEQ_PW_QHRA: 12476 check_dsp(ctx); 12477 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 12478 break; 12479 case OPC_PRECEQU_QH_OBL: 12480 check_dsp(ctx); 12481 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 12482 break; 12483 case OPC_PRECEQU_QH_OBR: 12484 check_dsp(ctx); 12485 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 12486 break; 12487 case OPC_PRECEQU_QH_OBLA: 12488 check_dsp(ctx); 12489 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 12490 break; 12491 case OPC_PRECEQU_QH_OBRA: 12492 check_dsp(ctx); 12493 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 12494 break; 12495 case OPC_PRECEU_QH_OBL: 12496 check_dsp(ctx); 12497 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 12498 break; 12499 case OPC_PRECEU_QH_OBR: 12500 check_dsp(ctx); 12501 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 12502 break; 12503 case OPC_PRECEU_QH_OBLA: 12504 check_dsp(ctx); 12505 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 12506 break; 12507 case OPC_PRECEU_QH_OBRA: 12508 check_dsp(ctx); 12509 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 12510 break; 12511 case OPC_ABSQ_S_OB: 12512 check_dsp_r2(ctx); 12513 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 12514 break; 12515 case OPC_ABSQ_S_PW: 12516 check_dsp(ctx); 12517 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 12518 break; 12519 case OPC_ABSQ_S_QH: 12520 check_dsp(ctx); 12521 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 12522 break; 12523 } 12524 break; 12525 case OPC_ADDU_OB_DSP: 12526 switch (op2) { 12527 case OPC_RADDU_L_OB: 12528 check_dsp(ctx); 12529 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 12530 break; 12531 case OPC_SUBQ_PW: 12532 check_dsp(ctx); 12533 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12534 break; 12535 case OPC_SUBQ_S_PW: 12536 check_dsp(ctx); 12537 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12538 break; 12539 case OPC_SUBQ_QH: 12540 check_dsp(ctx); 12541 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12542 break; 12543 case OPC_SUBQ_S_QH: 12544 check_dsp(ctx); 12545 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12546 break; 12547 case OPC_SUBU_OB: 12548 check_dsp(ctx); 12549 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12550 break; 12551 case OPC_SUBU_S_OB: 12552 check_dsp(ctx); 12553 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12554 break; 12555 case OPC_SUBU_QH: 12556 check_dsp_r2(ctx); 12557 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12558 break; 12559 case OPC_SUBU_S_QH: 12560 check_dsp_r2(ctx); 12561 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12562 break; 12563 case OPC_SUBUH_OB: 12564 check_dsp_r2(ctx); 12565 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12566 break; 12567 case OPC_SUBUH_R_OB: 12568 check_dsp_r2(ctx); 12569 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12570 break; 12571 case OPC_ADDQ_PW: 12572 check_dsp(ctx); 12573 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12574 break; 12575 case OPC_ADDQ_S_PW: 12576 check_dsp(ctx); 12577 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12578 break; 12579 case OPC_ADDQ_QH: 12580 check_dsp(ctx); 12581 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12582 break; 12583 case OPC_ADDQ_S_QH: 12584 check_dsp(ctx); 12585 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12586 break; 12587 case OPC_ADDU_OB: 12588 check_dsp(ctx); 12589 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12590 break; 12591 case OPC_ADDU_S_OB: 12592 check_dsp(ctx); 12593 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12594 break; 12595 case OPC_ADDU_QH: 12596 check_dsp_r2(ctx); 12597 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12598 break; 12599 case OPC_ADDU_S_QH: 12600 check_dsp_r2(ctx); 12601 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12602 break; 12603 case OPC_ADDUH_OB: 12604 check_dsp_r2(ctx); 12605 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12606 break; 12607 case OPC_ADDUH_R_OB: 12608 check_dsp_r2(ctx); 12609 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12610 break; 12611 } 12612 break; 12613 case OPC_CMPU_EQ_OB_DSP: 12614 switch (op2) { 12615 case OPC_PRECR_OB_QH: 12616 check_dsp_r2(ctx); 12617 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12618 break; 12619 case OPC_PRECR_SRA_QH_PW: 12620 check_dsp_r2(ctx); 12621 { 12622 TCGv_i32 ret_t = tcg_const_i32(ret); 12623 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12624 tcg_temp_free_i32(ret_t); 12625 break; 12626 } 12627 case OPC_PRECR_SRA_R_QH_PW: 12628 check_dsp_r2(ctx); 12629 { 12630 TCGv_i32 sa_v = tcg_const_i32(ret); 12631 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12632 tcg_temp_free_i32(sa_v); 12633 break; 12634 } 12635 case OPC_PRECRQ_OB_QH: 12636 check_dsp(ctx); 12637 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12638 break; 12639 case OPC_PRECRQ_PW_L: 12640 check_dsp(ctx); 12641 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12642 break; 12643 case OPC_PRECRQ_QH_PW: 12644 check_dsp(ctx); 12645 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12646 break; 12647 case OPC_PRECRQ_RS_QH_PW: 12648 check_dsp(ctx); 12649 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12650 break; 12651 case OPC_PRECRQU_S_OB_QH: 12652 check_dsp(ctx); 12653 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12654 break; 12655 } 12656 break; 12657 #endif 12658 } 12659 12660 tcg_temp_free(v1_t); 12661 tcg_temp_free(v2_t); 12662 } 12663 12664 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12665 int ret, int v1, int v2) 12666 { 12667 uint32_t op2; 12668 TCGv t0; 12669 TCGv v1_t; 12670 TCGv v2_t; 12671 12672 if (ret == 0) { 12673 /* Treat as NOP. */ 12674 return; 12675 } 12676 12677 t0 = tcg_temp_new(); 12678 v1_t = tcg_temp_new(); 12679 v2_t = tcg_temp_new(); 12680 12681 tcg_gen_movi_tl(t0, v1); 12682 gen_load_gpr(v1_t, v1); 12683 gen_load_gpr(v2_t, v2); 12684 12685 switch (opc) { 12686 case OPC_SHLL_QB_DSP: 12687 { 12688 op2 = MASK_SHLL_QB(ctx->opcode); 12689 switch (op2) { 12690 case OPC_SHLL_QB: 12691 check_dsp(ctx); 12692 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12693 break; 12694 case OPC_SHLLV_QB: 12695 check_dsp(ctx); 12696 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12697 break; 12698 case OPC_SHLL_PH: 12699 check_dsp(ctx); 12700 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12701 break; 12702 case OPC_SHLLV_PH: 12703 check_dsp(ctx); 12704 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12705 break; 12706 case OPC_SHLL_S_PH: 12707 check_dsp(ctx); 12708 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12709 break; 12710 case OPC_SHLLV_S_PH: 12711 check_dsp(ctx); 12712 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12713 break; 12714 case OPC_SHLL_S_W: 12715 check_dsp(ctx); 12716 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12717 break; 12718 case OPC_SHLLV_S_W: 12719 check_dsp(ctx); 12720 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12721 break; 12722 case OPC_SHRL_QB: 12723 check_dsp(ctx); 12724 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12725 break; 12726 case OPC_SHRLV_QB: 12727 check_dsp(ctx); 12728 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12729 break; 12730 case OPC_SHRL_PH: 12731 check_dsp_r2(ctx); 12732 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12733 break; 12734 case OPC_SHRLV_PH: 12735 check_dsp_r2(ctx); 12736 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12737 break; 12738 case OPC_SHRA_QB: 12739 check_dsp_r2(ctx); 12740 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12741 break; 12742 case OPC_SHRA_R_QB: 12743 check_dsp_r2(ctx); 12744 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12745 break; 12746 case OPC_SHRAV_QB: 12747 check_dsp_r2(ctx); 12748 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12749 break; 12750 case OPC_SHRAV_R_QB: 12751 check_dsp_r2(ctx); 12752 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12753 break; 12754 case OPC_SHRA_PH: 12755 check_dsp(ctx); 12756 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12757 break; 12758 case OPC_SHRA_R_PH: 12759 check_dsp(ctx); 12760 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12761 break; 12762 case OPC_SHRAV_PH: 12763 check_dsp(ctx); 12764 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12765 break; 12766 case OPC_SHRAV_R_PH: 12767 check_dsp(ctx); 12768 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12769 break; 12770 case OPC_SHRA_R_W: 12771 check_dsp(ctx); 12772 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12773 break; 12774 case OPC_SHRAV_R_W: 12775 check_dsp(ctx); 12776 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12777 break; 12778 default: /* Invalid */ 12779 MIPS_INVAL("MASK SHLL.QB"); 12780 gen_reserved_instruction(ctx); 12781 break; 12782 } 12783 break; 12784 } 12785 #ifdef TARGET_MIPS64 12786 case OPC_SHLL_OB_DSP: 12787 op2 = MASK_SHLL_OB(ctx->opcode); 12788 switch (op2) { 12789 case OPC_SHLL_PW: 12790 check_dsp(ctx); 12791 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12792 break; 12793 case OPC_SHLLV_PW: 12794 check_dsp(ctx); 12795 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12796 break; 12797 case OPC_SHLL_S_PW: 12798 check_dsp(ctx); 12799 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12800 break; 12801 case OPC_SHLLV_S_PW: 12802 check_dsp(ctx); 12803 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12804 break; 12805 case OPC_SHLL_OB: 12806 check_dsp(ctx); 12807 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12808 break; 12809 case OPC_SHLLV_OB: 12810 check_dsp(ctx); 12811 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12812 break; 12813 case OPC_SHLL_QH: 12814 check_dsp(ctx); 12815 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12816 break; 12817 case OPC_SHLLV_QH: 12818 check_dsp(ctx); 12819 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12820 break; 12821 case OPC_SHLL_S_QH: 12822 check_dsp(ctx); 12823 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12824 break; 12825 case OPC_SHLLV_S_QH: 12826 check_dsp(ctx); 12827 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12828 break; 12829 case OPC_SHRA_OB: 12830 check_dsp_r2(ctx); 12831 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12832 break; 12833 case OPC_SHRAV_OB: 12834 check_dsp_r2(ctx); 12835 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12836 break; 12837 case OPC_SHRA_R_OB: 12838 check_dsp_r2(ctx); 12839 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12840 break; 12841 case OPC_SHRAV_R_OB: 12842 check_dsp_r2(ctx); 12843 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12844 break; 12845 case OPC_SHRA_PW: 12846 check_dsp(ctx); 12847 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12848 break; 12849 case OPC_SHRAV_PW: 12850 check_dsp(ctx); 12851 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12852 break; 12853 case OPC_SHRA_R_PW: 12854 check_dsp(ctx); 12855 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12856 break; 12857 case OPC_SHRAV_R_PW: 12858 check_dsp(ctx); 12859 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12860 break; 12861 case OPC_SHRA_QH: 12862 check_dsp(ctx); 12863 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12864 break; 12865 case OPC_SHRAV_QH: 12866 check_dsp(ctx); 12867 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12868 break; 12869 case OPC_SHRA_R_QH: 12870 check_dsp(ctx); 12871 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12872 break; 12873 case OPC_SHRAV_R_QH: 12874 check_dsp(ctx); 12875 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12876 break; 12877 case OPC_SHRL_OB: 12878 check_dsp(ctx); 12879 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12880 break; 12881 case OPC_SHRLV_OB: 12882 check_dsp(ctx); 12883 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12884 break; 12885 case OPC_SHRL_QH: 12886 check_dsp_r2(ctx); 12887 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12888 break; 12889 case OPC_SHRLV_QH: 12890 check_dsp_r2(ctx); 12891 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12892 break; 12893 default: /* Invalid */ 12894 MIPS_INVAL("MASK SHLL.OB"); 12895 gen_reserved_instruction(ctx); 12896 break; 12897 } 12898 break; 12899 #endif 12900 } 12901 12902 tcg_temp_free(t0); 12903 tcg_temp_free(v1_t); 12904 tcg_temp_free(v2_t); 12905 } 12906 12907 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12908 int ret, int v1, int v2, int check_ret) 12909 { 12910 TCGv_i32 t0; 12911 TCGv v1_t; 12912 TCGv v2_t; 12913 12914 if ((ret == 0) && (check_ret == 1)) { 12915 /* Treat as NOP. */ 12916 return; 12917 } 12918 12919 t0 = tcg_temp_new_i32(); 12920 v1_t = tcg_temp_new(); 12921 v2_t = tcg_temp_new(); 12922 12923 tcg_gen_movi_i32(t0, ret); 12924 gen_load_gpr(v1_t, v1); 12925 gen_load_gpr(v2_t, v2); 12926 12927 switch (op1) { 12928 /* 12929 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 12930 * the same mask and op1. 12931 */ 12932 case OPC_MULT_G_2E: 12933 check_dsp_r2(ctx); 12934 switch (op2) { 12935 case OPC_MUL_PH: 12936 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12937 break; 12938 case OPC_MUL_S_PH: 12939 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12940 break; 12941 case OPC_MULQ_S_W: 12942 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12943 break; 12944 case OPC_MULQ_RS_W: 12945 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12946 break; 12947 } 12948 break; 12949 case OPC_DPA_W_PH_DSP: 12950 switch (op2) { 12951 case OPC_DPAU_H_QBL: 12952 check_dsp(ctx); 12953 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 12954 break; 12955 case OPC_DPAU_H_QBR: 12956 check_dsp(ctx); 12957 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 12958 break; 12959 case OPC_DPSU_H_QBL: 12960 check_dsp(ctx); 12961 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 12962 break; 12963 case OPC_DPSU_H_QBR: 12964 check_dsp(ctx); 12965 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 12966 break; 12967 case OPC_DPA_W_PH: 12968 check_dsp_r2(ctx); 12969 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 12970 break; 12971 case OPC_DPAX_W_PH: 12972 check_dsp_r2(ctx); 12973 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 12974 break; 12975 case OPC_DPAQ_S_W_PH: 12976 check_dsp(ctx); 12977 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12978 break; 12979 case OPC_DPAQX_S_W_PH: 12980 check_dsp_r2(ctx); 12981 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 12982 break; 12983 case OPC_DPAQX_SA_W_PH: 12984 check_dsp_r2(ctx); 12985 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 12986 break; 12987 case OPC_DPS_W_PH: 12988 check_dsp_r2(ctx); 12989 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 12990 break; 12991 case OPC_DPSX_W_PH: 12992 check_dsp_r2(ctx); 12993 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 12994 break; 12995 case OPC_DPSQ_S_W_PH: 12996 check_dsp(ctx); 12997 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 12998 break; 12999 case OPC_DPSQX_S_W_PH: 13000 check_dsp_r2(ctx); 13001 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13002 break; 13003 case OPC_DPSQX_SA_W_PH: 13004 check_dsp_r2(ctx); 13005 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13006 break; 13007 case OPC_MULSAQ_S_W_PH: 13008 check_dsp(ctx); 13009 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13010 break; 13011 case OPC_DPAQ_SA_L_W: 13012 check_dsp(ctx); 13013 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13014 break; 13015 case OPC_DPSQ_SA_L_W: 13016 check_dsp(ctx); 13017 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13018 break; 13019 case OPC_MAQ_S_W_PHL: 13020 check_dsp(ctx); 13021 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 13022 break; 13023 case OPC_MAQ_S_W_PHR: 13024 check_dsp(ctx); 13025 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 13026 break; 13027 case OPC_MAQ_SA_W_PHL: 13028 check_dsp(ctx); 13029 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 13030 break; 13031 case OPC_MAQ_SA_W_PHR: 13032 check_dsp(ctx); 13033 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 13034 break; 13035 case OPC_MULSA_W_PH: 13036 check_dsp_r2(ctx); 13037 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 13038 break; 13039 } 13040 break; 13041 #ifdef TARGET_MIPS64 13042 case OPC_DPAQ_W_QH_DSP: 13043 { 13044 int ac = ret & 0x03; 13045 tcg_gen_movi_i32(t0, ac); 13046 13047 switch (op2) { 13048 case OPC_DMADD: 13049 check_dsp(ctx); 13050 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 13051 break; 13052 case OPC_DMADDU: 13053 check_dsp(ctx); 13054 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 13055 break; 13056 case OPC_DMSUB: 13057 check_dsp(ctx); 13058 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 13059 break; 13060 case OPC_DMSUBU: 13061 check_dsp(ctx); 13062 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 13063 break; 13064 case OPC_DPA_W_QH: 13065 check_dsp_r2(ctx); 13066 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 13067 break; 13068 case OPC_DPAQ_S_W_QH: 13069 check_dsp(ctx); 13070 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13071 break; 13072 case OPC_DPAQ_SA_L_PW: 13073 check_dsp(ctx); 13074 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13075 break; 13076 case OPC_DPAU_H_OBL: 13077 check_dsp(ctx); 13078 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 13079 break; 13080 case OPC_DPAU_H_OBR: 13081 check_dsp(ctx); 13082 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 13083 break; 13084 case OPC_DPS_W_QH: 13085 check_dsp_r2(ctx); 13086 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 13087 break; 13088 case OPC_DPSQ_S_W_QH: 13089 check_dsp(ctx); 13090 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13091 break; 13092 case OPC_DPSQ_SA_L_PW: 13093 check_dsp(ctx); 13094 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13095 break; 13096 case OPC_DPSU_H_OBL: 13097 check_dsp(ctx); 13098 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 13099 break; 13100 case OPC_DPSU_H_OBR: 13101 check_dsp(ctx); 13102 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 13103 break; 13104 case OPC_MAQ_S_L_PWL: 13105 check_dsp(ctx); 13106 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 13107 break; 13108 case OPC_MAQ_S_L_PWR: 13109 check_dsp(ctx); 13110 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 13111 break; 13112 case OPC_MAQ_S_W_QHLL: 13113 check_dsp(ctx); 13114 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 13115 break; 13116 case OPC_MAQ_SA_W_QHLL: 13117 check_dsp(ctx); 13118 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 13119 break; 13120 case OPC_MAQ_S_W_QHLR: 13121 check_dsp(ctx); 13122 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 13123 break; 13124 case OPC_MAQ_SA_W_QHLR: 13125 check_dsp(ctx); 13126 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 13127 break; 13128 case OPC_MAQ_S_W_QHRL: 13129 check_dsp(ctx); 13130 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 13131 break; 13132 case OPC_MAQ_SA_W_QHRL: 13133 check_dsp(ctx); 13134 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 13135 break; 13136 case OPC_MAQ_S_W_QHRR: 13137 check_dsp(ctx); 13138 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 13139 break; 13140 case OPC_MAQ_SA_W_QHRR: 13141 check_dsp(ctx); 13142 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 13143 break; 13144 case OPC_MULSAQ_S_L_PW: 13145 check_dsp(ctx); 13146 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 13147 break; 13148 case OPC_MULSAQ_S_W_QH: 13149 check_dsp(ctx); 13150 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13151 break; 13152 } 13153 } 13154 break; 13155 #endif 13156 case OPC_ADDU_QB_DSP: 13157 switch (op2) { 13158 case OPC_MULEU_S_PH_QBL: 13159 check_dsp(ctx); 13160 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13161 break; 13162 case OPC_MULEU_S_PH_QBR: 13163 check_dsp(ctx); 13164 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13165 break; 13166 case OPC_MULQ_RS_PH: 13167 check_dsp(ctx); 13168 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13169 break; 13170 case OPC_MULEQ_S_W_PHL: 13171 check_dsp(ctx); 13172 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13173 break; 13174 case OPC_MULEQ_S_W_PHR: 13175 check_dsp(ctx); 13176 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13177 break; 13178 case OPC_MULQ_S_PH: 13179 check_dsp_r2(ctx); 13180 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13181 break; 13182 } 13183 break; 13184 #ifdef TARGET_MIPS64 13185 case OPC_ADDU_OB_DSP: 13186 switch (op2) { 13187 case OPC_MULEQ_S_PW_QHL: 13188 check_dsp(ctx); 13189 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13190 break; 13191 case OPC_MULEQ_S_PW_QHR: 13192 check_dsp(ctx); 13193 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13194 break; 13195 case OPC_MULEU_S_QH_OBL: 13196 check_dsp(ctx); 13197 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13198 break; 13199 case OPC_MULEU_S_QH_OBR: 13200 check_dsp(ctx); 13201 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13202 break; 13203 case OPC_MULQ_RS_QH: 13204 check_dsp(ctx); 13205 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13206 break; 13207 } 13208 break; 13209 #endif 13210 } 13211 13212 tcg_temp_free_i32(t0); 13213 tcg_temp_free(v1_t); 13214 tcg_temp_free(v2_t); 13215 } 13216 13217 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13218 int ret, int val) 13219 { 13220 int16_t imm; 13221 TCGv t0; 13222 TCGv val_t; 13223 13224 if (ret == 0) { 13225 /* Treat as NOP. */ 13226 return; 13227 } 13228 13229 t0 = tcg_temp_new(); 13230 val_t = tcg_temp_new(); 13231 gen_load_gpr(val_t, val); 13232 13233 switch (op1) { 13234 case OPC_ABSQ_S_PH_DSP: 13235 switch (op2) { 13236 case OPC_BITREV: 13237 check_dsp(ctx); 13238 gen_helper_bitrev(cpu_gpr[ret], val_t); 13239 break; 13240 case OPC_REPL_QB: 13241 check_dsp(ctx); 13242 { 13243 target_long result; 13244 imm = (ctx->opcode >> 16) & 0xFF; 13245 result = (uint32_t)imm << 24 | 13246 (uint32_t)imm << 16 | 13247 (uint32_t)imm << 8 | 13248 (uint32_t)imm; 13249 result = (int32_t)result; 13250 tcg_gen_movi_tl(cpu_gpr[ret], result); 13251 } 13252 break; 13253 case OPC_REPLV_QB: 13254 check_dsp(ctx); 13255 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13256 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13257 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13258 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13259 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13260 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13261 break; 13262 case OPC_REPL_PH: 13263 check_dsp(ctx); 13264 { 13265 imm = (ctx->opcode >> 16) & 0x03FF; 13266 imm = (int16_t)(imm << 6) >> 6; 13267 tcg_gen_movi_tl(cpu_gpr[ret], \ 13268 (target_long)((int32_t)imm << 16 | \ 13269 (uint16_t)imm)); 13270 } 13271 break; 13272 case OPC_REPLV_PH: 13273 check_dsp(ctx); 13274 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13275 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13276 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13277 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13278 break; 13279 } 13280 break; 13281 #ifdef TARGET_MIPS64 13282 case OPC_ABSQ_S_QH_DSP: 13283 switch (op2) { 13284 case OPC_REPL_OB: 13285 check_dsp(ctx); 13286 { 13287 target_long temp; 13288 13289 imm = (ctx->opcode >> 16) & 0xFF; 13290 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 13291 temp = (temp << 16) | temp; 13292 temp = (temp << 32) | temp; 13293 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13294 break; 13295 } 13296 case OPC_REPL_PW: 13297 check_dsp(ctx); 13298 { 13299 target_long temp; 13300 13301 imm = (ctx->opcode >> 16) & 0x03FF; 13302 imm = (int16_t)(imm << 6) >> 6; 13303 temp = ((target_long)imm << 32) \ 13304 | ((target_long)imm & 0xFFFFFFFF); 13305 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13306 break; 13307 } 13308 case OPC_REPL_QH: 13309 check_dsp(ctx); 13310 { 13311 target_long temp; 13312 13313 imm = (ctx->opcode >> 16) & 0x03FF; 13314 imm = (int16_t)(imm << 6) >> 6; 13315 13316 temp = ((uint64_t)(uint16_t)imm << 48) | 13317 ((uint64_t)(uint16_t)imm << 32) | 13318 ((uint64_t)(uint16_t)imm << 16) | 13319 (uint64_t)(uint16_t)imm; 13320 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13321 break; 13322 } 13323 case OPC_REPLV_OB: 13324 check_dsp(ctx); 13325 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13326 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13327 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13328 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13329 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13330 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13331 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13332 break; 13333 case OPC_REPLV_PW: 13334 check_dsp(ctx); 13335 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 13336 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13337 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13338 break; 13339 case OPC_REPLV_QH: 13340 check_dsp(ctx); 13341 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13342 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13343 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13344 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13345 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13346 break; 13347 } 13348 break; 13349 #endif 13350 } 13351 tcg_temp_free(t0); 13352 tcg_temp_free(val_t); 13353 } 13354 13355 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 13356 uint32_t op1, uint32_t op2, 13357 int ret, int v1, int v2, int check_ret) 13358 { 13359 TCGv t1; 13360 TCGv v1_t; 13361 TCGv v2_t; 13362 13363 if ((ret == 0) && (check_ret == 1)) { 13364 /* Treat as NOP. */ 13365 return; 13366 } 13367 13368 t1 = tcg_temp_new(); 13369 v1_t = tcg_temp_new(); 13370 v2_t = tcg_temp_new(); 13371 13372 gen_load_gpr(v1_t, v1); 13373 gen_load_gpr(v2_t, v2); 13374 13375 switch (op1) { 13376 case OPC_CMPU_EQ_QB_DSP: 13377 switch (op2) { 13378 case OPC_CMPU_EQ_QB: 13379 check_dsp(ctx); 13380 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 13381 break; 13382 case OPC_CMPU_LT_QB: 13383 check_dsp(ctx); 13384 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 13385 break; 13386 case OPC_CMPU_LE_QB: 13387 check_dsp(ctx); 13388 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 13389 break; 13390 case OPC_CMPGU_EQ_QB: 13391 check_dsp(ctx); 13392 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 13393 break; 13394 case OPC_CMPGU_LT_QB: 13395 check_dsp(ctx); 13396 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 13397 break; 13398 case OPC_CMPGU_LE_QB: 13399 check_dsp(ctx); 13400 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 13401 break; 13402 case OPC_CMPGDU_EQ_QB: 13403 check_dsp_r2(ctx); 13404 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 13405 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13406 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13407 tcg_gen_shli_tl(t1, t1, 24); 13408 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13409 break; 13410 case OPC_CMPGDU_LT_QB: 13411 check_dsp_r2(ctx); 13412 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 13413 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13414 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13415 tcg_gen_shli_tl(t1, t1, 24); 13416 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13417 break; 13418 case OPC_CMPGDU_LE_QB: 13419 check_dsp_r2(ctx); 13420 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 13421 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13422 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13423 tcg_gen_shli_tl(t1, t1, 24); 13424 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13425 break; 13426 case OPC_CMP_EQ_PH: 13427 check_dsp(ctx); 13428 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 13429 break; 13430 case OPC_CMP_LT_PH: 13431 check_dsp(ctx); 13432 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 13433 break; 13434 case OPC_CMP_LE_PH: 13435 check_dsp(ctx); 13436 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 13437 break; 13438 case OPC_PICK_QB: 13439 check_dsp(ctx); 13440 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13441 break; 13442 case OPC_PICK_PH: 13443 check_dsp(ctx); 13444 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13445 break; 13446 case OPC_PACKRL_PH: 13447 check_dsp(ctx); 13448 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 13449 break; 13450 } 13451 break; 13452 #ifdef TARGET_MIPS64 13453 case OPC_CMPU_EQ_OB_DSP: 13454 switch (op2) { 13455 case OPC_CMP_EQ_PW: 13456 check_dsp(ctx); 13457 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 13458 break; 13459 case OPC_CMP_LT_PW: 13460 check_dsp(ctx); 13461 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 13462 break; 13463 case OPC_CMP_LE_PW: 13464 check_dsp(ctx); 13465 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 13466 break; 13467 case OPC_CMP_EQ_QH: 13468 check_dsp(ctx); 13469 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 13470 break; 13471 case OPC_CMP_LT_QH: 13472 check_dsp(ctx); 13473 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 13474 break; 13475 case OPC_CMP_LE_QH: 13476 check_dsp(ctx); 13477 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 13478 break; 13479 case OPC_CMPGDU_EQ_OB: 13480 check_dsp_r2(ctx); 13481 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13482 break; 13483 case OPC_CMPGDU_LT_OB: 13484 check_dsp_r2(ctx); 13485 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13486 break; 13487 case OPC_CMPGDU_LE_OB: 13488 check_dsp_r2(ctx); 13489 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13490 break; 13491 case OPC_CMPGU_EQ_OB: 13492 check_dsp(ctx); 13493 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 13494 break; 13495 case OPC_CMPGU_LT_OB: 13496 check_dsp(ctx); 13497 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 13498 break; 13499 case OPC_CMPGU_LE_OB: 13500 check_dsp(ctx); 13501 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 13502 break; 13503 case OPC_CMPU_EQ_OB: 13504 check_dsp(ctx); 13505 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 13506 break; 13507 case OPC_CMPU_LT_OB: 13508 check_dsp(ctx); 13509 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 13510 break; 13511 case OPC_CMPU_LE_OB: 13512 check_dsp(ctx); 13513 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 13514 break; 13515 case OPC_PACKRL_PW: 13516 check_dsp(ctx); 13517 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 13518 break; 13519 case OPC_PICK_OB: 13520 check_dsp(ctx); 13521 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13522 break; 13523 case OPC_PICK_PW: 13524 check_dsp(ctx); 13525 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13526 break; 13527 case OPC_PICK_QH: 13528 check_dsp(ctx); 13529 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13530 break; 13531 } 13532 break; 13533 #endif 13534 } 13535 13536 tcg_temp_free(t1); 13537 tcg_temp_free(v1_t); 13538 tcg_temp_free(v2_t); 13539 } 13540 13541 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 13542 uint32_t op1, int rt, int rs, int sa) 13543 { 13544 TCGv t0; 13545 13546 check_dsp_r2(ctx); 13547 13548 if (rt == 0) { 13549 /* Treat as NOP. */ 13550 return; 13551 } 13552 13553 t0 = tcg_temp_new(); 13554 gen_load_gpr(t0, rs); 13555 13556 switch (op1) { 13557 case OPC_APPEND_DSP: 13558 switch (MASK_APPEND(ctx->opcode)) { 13559 case OPC_APPEND: 13560 if (sa != 0) { 13561 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 13562 } 13563 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13564 break; 13565 case OPC_PREPEND: 13566 if (sa != 0) { 13567 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 13568 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13569 tcg_gen_shli_tl(t0, t0, 32 - sa); 13570 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13571 } 13572 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13573 break; 13574 case OPC_BALIGN: 13575 sa &= 3; 13576 if (sa != 0 && sa != 2) { 13577 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13578 tcg_gen_ext32u_tl(t0, t0); 13579 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13580 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13581 } 13582 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13583 break; 13584 default: /* Invalid */ 13585 MIPS_INVAL("MASK APPEND"); 13586 gen_reserved_instruction(ctx); 13587 break; 13588 } 13589 break; 13590 #ifdef TARGET_MIPS64 13591 case OPC_DAPPEND_DSP: 13592 switch (MASK_DAPPEND(ctx->opcode)) { 13593 case OPC_DAPPEND: 13594 if (sa != 0) { 13595 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13596 } 13597 break; 13598 case OPC_PREPENDD: 13599 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13600 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13601 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13602 break; 13603 case OPC_PREPENDW: 13604 if (sa != 0) { 13605 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13606 tcg_gen_shli_tl(t0, t0, 64 - sa); 13607 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13608 } 13609 break; 13610 case OPC_DBALIGN: 13611 sa &= 7; 13612 if (sa != 0 && sa != 2 && sa != 4) { 13613 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13614 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13615 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13616 } 13617 break; 13618 default: /* Invalid */ 13619 MIPS_INVAL("MASK DAPPEND"); 13620 gen_reserved_instruction(ctx); 13621 break; 13622 } 13623 break; 13624 #endif 13625 } 13626 tcg_temp_free(t0); 13627 } 13628 13629 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13630 int ret, int v1, int v2, int check_ret) 13631 13632 { 13633 TCGv t0; 13634 TCGv t1; 13635 TCGv v1_t; 13636 int16_t imm; 13637 13638 if ((ret == 0) && (check_ret == 1)) { 13639 /* Treat as NOP. */ 13640 return; 13641 } 13642 13643 t0 = tcg_temp_new(); 13644 t1 = tcg_temp_new(); 13645 v1_t = tcg_temp_new(); 13646 13647 gen_load_gpr(v1_t, v1); 13648 13649 switch (op1) { 13650 case OPC_EXTR_W_DSP: 13651 check_dsp(ctx); 13652 switch (op2) { 13653 case OPC_EXTR_W: 13654 tcg_gen_movi_tl(t0, v2); 13655 tcg_gen_movi_tl(t1, v1); 13656 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13657 break; 13658 case OPC_EXTR_R_W: 13659 tcg_gen_movi_tl(t0, v2); 13660 tcg_gen_movi_tl(t1, v1); 13661 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13662 break; 13663 case OPC_EXTR_RS_W: 13664 tcg_gen_movi_tl(t0, v2); 13665 tcg_gen_movi_tl(t1, v1); 13666 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13667 break; 13668 case OPC_EXTR_S_H: 13669 tcg_gen_movi_tl(t0, v2); 13670 tcg_gen_movi_tl(t1, v1); 13671 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13672 break; 13673 case OPC_EXTRV_S_H: 13674 tcg_gen_movi_tl(t0, v2); 13675 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13676 break; 13677 case OPC_EXTRV_W: 13678 tcg_gen_movi_tl(t0, v2); 13679 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13680 break; 13681 case OPC_EXTRV_R_W: 13682 tcg_gen_movi_tl(t0, v2); 13683 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13684 break; 13685 case OPC_EXTRV_RS_W: 13686 tcg_gen_movi_tl(t0, v2); 13687 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13688 break; 13689 case OPC_EXTP: 13690 tcg_gen_movi_tl(t0, v2); 13691 tcg_gen_movi_tl(t1, v1); 13692 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13693 break; 13694 case OPC_EXTPV: 13695 tcg_gen_movi_tl(t0, v2); 13696 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13697 break; 13698 case OPC_EXTPDP: 13699 tcg_gen_movi_tl(t0, v2); 13700 tcg_gen_movi_tl(t1, v1); 13701 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13702 break; 13703 case OPC_EXTPDPV: 13704 tcg_gen_movi_tl(t0, v2); 13705 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13706 break; 13707 case OPC_SHILO: 13708 imm = (ctx->opcode >> 20) & 0x3F; 13709 tcg_gen_movi_tl(t0, ret); 13710 tcg_gen_movi_tl(t1, imm); 13711 gen_helper_shilo(t0, t1, cpu_env); 13712 break; 13713 case OPC_SHILOV: 13714 tcg_gen_movi_tl(t0, ret); 13715 gen_helper_shilo(t0, v1_t, cpu_env); 13716 break; 13717 case OPC_MTHLIP: 13718 tcg_gen_movi_tl(t0, ret); 13719 gen_helper_mthlip(t0, v1_t, cpu_env); 13720 break; 13721 case OPC_WRDSP: 13722 imm = (ctx->opcode >> 11) & 0x3FF; 13723 tcg_gen_movi_tl(t0, imm); 13724 gen_helper_wrdsp(v1_t, t0, cpu_env); 13725 break; 13726 case OPC_RDDSP: 13727 imm = (ctx->opcode >> 16) & 0x03FF; 13728 tcg_gen_movi_tl(t0, imm); 13729 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13730 break; 13731 } 13732 break; 13733 #ifdef TARGET_MIPS64 13734 case OPC_DEXTR_W_DSP: 13735 check_dsp(ctx); 13736 switch (op2) { 13737 case OPC_DMTHLIP: 13738 tcg_gen_movi_tl(t0, ret); 13739 gen_helper_dmthlip(v1_t, t0, cpu_env); 13740 break; 13741 case OPC_DSHILO: 13742 { 13743 int shift = (ctx->opcode >> 19) & 0x7F; 13744 int ac = (ctx->opcode >> 11) & 0x03; 13745 tcg_gen_movi_tl(t0, shift); 13746 tcg_gen_movi_tl(t1, ac); 13747 gen_helper_dshilo(t0, t1, cpu_env); 13748 break; 13749 } 13750 case OPC_DSHILOV: 13751 { 13752 int ac = (ctx->opcode >> 11) & 0x03; 13753 tcg_gen_movi_tl(t0, ac); 13754 gen_helper_dshilo(v1_t, t0, cpu_env); 13755 break; 13756 } 13757 case OPC_DEXTP: 13758 tcg_gen_movi_tl(t0, v2); 13759 tcg_gen_movi_tl(t1, v1); 13760 13761 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13762 break; 13763 case OPC_DEXTPV: 13764 tcg_gen_movi_tl(t0, v2); 13765 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13766 break; 13767 case OPC_DEXTPDP: 13768 tcg_gen_movi_tl(t0, v2); 13769 tcg_gen_movi_tl(t1, v1); 13770 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13771 break; 13772 case OPC_DEXTPDPV: 13773 tcg_gen_movi_tl(t0, v2); 13774 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13775 break; 13776 case OPC_DEXTR_L: 13777 tcg_gen_movi_tl(t0, v2); 13778 tcg_gen_movi_tl(t1, v1); 13779 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13780 break; 13781 case OPC_DEXTR_R_L: 13782 tcg_gen_movi_tl(t0, v2); 13783 tcg_gen_movi_tl(t1, v1); 13784 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13785 break; 13786 case OPC_DEXTR_RS_L: 13787 tcg_gen_movi_tl(t0, v2); 13788 tcg_gen_movi_tl(t1, v1); 13789 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13790 break; 13791 case OPC_DEXTR_W: 13792 tcg_gen_movi_tl(t0, v2); 13793 tcg_gen_movi_tl(t1, v1); 13794 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13795 break; 13796 case OPC_DEXTR_R_W: 13797 tcg_gen_movi_tl(t0, v2); 13798 tcg_gen_movi_tl(t1, v1); 13799 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13800 break; 13801 case OPC_DEXTR_RS_W: 13802 tcg_gen_movi_tl(t0, v2); 13803 tcg_gen_movi_tl(t1, v1); 13804 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13805 break; 13806 case OPC_DEXTR_S_H: 13807 tcg_gen_movi_tl(t0, v2); 13808 tcg_gen_movi_tl(t1, v1); 13809 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13810 break; 13811 case OPC_DEXTRV_S_H: 13812 tcg_gen_movi_tl(t0, v2); 13813 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13814 break; 13815 case OPC_DEXTRV_L: 13816 tcg_gen_movi_tl(t0, v2); 13817 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13818 break; 13819 case OPC_DEXTRV_R_L: 13820 tcg_gen_movi_tl(t0, v2); 13821 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13822 break; 13823 case OPC_DEXTRV_RS_L: 13824 tcg_gen_movi_tl(t0, v2); 13825 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13826 break; 13827 case OPC_DEXTRV_W: 13828 tcg_gen_movi_tl(t0, v2); 13829 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13830 break; 13831 case OPC_DEXTRV_R_W: 13832 tcg_gen_movi_tl(t0, v2); 13833 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13834 break; 13835 case OPC_DEXTRV_RS_W: 13836 tcg_gen_movi_tl(t0, v2); 13837 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13838 break; 13839 } 13840 break; 13841 #endif 13842 } 13843 13844 tcg_temp_free(t0); 13845 tcg_temp_free(t1); 13846 tcg_temp_free(v1_t); 13847 } 13848 13849 /* End MIPSDSP functions. */ 13850 13851 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13852 { 13853 int rs, rt, rd, sa; 13854 uint32_t op1, op2; 13855 13856 rs = (ctx->opcode >> 21) & 0x1f; 13857 rt = (ctx->opcode >> 16) & 0x1f; 13858 rd = (ctx->opcode >> 11) & 0x1f; 13859 sa = (ctx->opcode >> 6) & 0x1f; 13860 13861 op1 = MASK_SPECIAL(ctx->opcode); 13862 switch (op1) { 13863 case OPC_MULT: 13864 case OPC_MULTU: 13865 case OPC_DIV: 13866 case OPC_DIVU: 13867 op2 = MASK_R6_MULDIV(ctx->opcode); 13868 switch (op2) { 13869 case R6_OPC_MUL: 13870 case R6_OPC_MUH: 13871 case R6_OPC_MULU: 13872 case R6_OPC_MUHU: 13873 case R6_OPC_DIV: 13874 case R6_OPC_MOD: 13875 case R6_OPC_DIVU: 13876 case R6_OPC_MODU: 13877 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13878 break; 13879 default: 13880 MIPS_INVAL("special_r6 muldiv"); 13881 gen_reserved_instruction(ctx); 13882 break; 13883 } 13884 break; 13885 case OPC_SELEQZ: 13886 case OPC_SELNEZ: 13887 gen_cond_move(ctx, op1, rd, rs, rt); 13888 break; 13889 case R6_OPC_CLO: 13890 case R6_OPC_CLZ: 13891 if (rt == 0 && sa == 1) { 13892 /* 13893 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13894 * We need additionally to check other fields. 13895 */ 13896 gen_cl(ctx, op1, rd, rs); 13897 } else { 13898 gen_reserved_instruction(ctx); 13899 } 13900 break; 13901 case R6_OPC_SDBBP: 13902 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13903 ctx->base.is_jmp = DISAS_SEMIHOST; 13904 } else { 13905 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13906 gen_reserved_instruction(ctx); 13907 } else { 13908 generate_exception_end(ctx, EXCP_DBp); 13909 } 13910 } 13911 break; 13912 #if defined(TARGET_MIPS64) 13913 case R6_OPC_DCLO: 13914 case R6_OPC_DCLZ: 13915 if (rt == 0 && sa == 1) { 13916 /* 13917 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13918 * We need additionally to check other fields. 13919 */ 13920 check_mips_64(ctx); 13921 gen_cl(ctx, op1, rd, rs); 13922 } else { 13923 gen_reserved_instruction(ctx); 13924 } 13925 break; 13926 case OPC_DMULT: 13927 case OPC_DMULTU: 13928 case OPC_DDIV: 13929 case OPC_DDIVU: 13930 13931 op2 = MASK_R6_MULDIV(ctx->opcode); 13932 switch (op2) { 13933 case R6_OPC_DMUL: 13934 case R6_OPC_DMUH: 13935 case R6_OPC_DMULU: 13936 case R6_OPC_DMUHU: 13937 case R6_OPC_DDIV: 13938 case R6_OPC_DMOD: 13939 case R6_OPC_DDIVU: 13940 case R6_OPC_DMODU: 13941 check_mips_64(ctx); 13942 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13943 break; 13944 default: 13945 MIPS_INVAL("special_r6 muldiv"); 13946 gen_reserved_instruction(ctx); 13947 break; 13948 } 13949 break; 13950 #endif 13951 default: /* Invalid */ 13952 MIPS_INVAL("special_r6"); 13953 gen_reserved_instruction(ctx); 13954 break; 13955 } 13956 } 13957 13958 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13959 { 13960 int rs = extract32(ctx->opcode, 21, 5); 13961 int rt = extract32(ctx->opcode, 16, 5); 13962 int rd = extract32(ctx->opcode, 11, 5); 13963 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13964 13965 switch (op1) { 13966 case OPC_MOVN: /* Conditional move */ 13967 case OPC_MOVZ: 13968 gen_cond_move(ctx, op1, rd, rs, rt); 13969 break; 13970 case OPC_MFHI: /* Move from HI/LO */ 13971 case OPC_MFLO: 13972 gen_HILO(ctx, op1, 0, rd); 13973 break; 13974 case OPC_MTHI: 13975 case OPC_MTLO: /* Move to HI/LO */ 13976 gen_HILO(ctx, op1, 0, rs); 13977 break; 13978 case OPC_MULT: 13979 case OPC_MULTU: 13980 gen_mul_txx9(ctx, op1, rd, rs, rt); 13981 break; 13982 case OPC_DIV: 13983 case OPC_DIVU: 13984 gen_muldiv(ctx, op1, 0, rs, rt); 13985 break; 13986 #if defined(TARGET_MIPS64) 13987 case OPC_DMULT: 13988 case OPC_DMULTU: 13989 case OPC_DDIV: 13990 case OPC_DDIVU: 13991 check_insn_opc_user_only(ctx, INSN_R5900); 13992 gen_muldiv(ctx, op1, 0, rs, rt); 13993 break; 13994 #endif 13995 case OPC_JR: 13996 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13997 break; 13998 default: /* Invalid */ 13999 MIPS_INVAL("special_tx79"); 14000 gen_reserved_instruction(ctx); 14001 break; 14002 } 14003 } 14004 14005 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 14006 { 14007 int rs, rt, rd; 14008 uint32_t op1; 14009 14010 rs = (ctx->opcode >> 21) & 0x1f; 14011 rt = (ctx->opcode >> 16) & 0x1f; 14012 rd = (ctx->opcode >> 11) & 0x1f; 14013 14014 op1 = MASK_SPECIAL(ctx->opcode); 14015 switch (op1) { 14016 case OPC_MOVN: /* Conditional move */ 14017 case OPC_MOVZ: 14018 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 14019 INSN_LOONGSON2E | INSN_LOONGSON2F); 14020 gen_cond_move(ctx, op1, rd, rs, rt); 14021 break; 14022 case OPC_MFHI: /* Move from HI/LO */ 14023 case OPC_MFLO: 14024 gen_HILO(ctx, op1, rs & 3, rd); 14025 break; 14026 case OPC_MTHI: 14027 case OPC_MTLO: /* Move to HI/LO */ 14028 gen_HILO(ctx, op1, rd & 3, rs); 14029 break; 14030 case OPC_MOVCI: 14031 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 14032 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 14033 check_cp1_enabled(ctx); 14034 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 14035 (ctx->opcode >> 16) & 1); 14036 } else { 14037 generate_exception_err(ctx, EXCP_CpU, 1); 14038 } 14039 break; 14040 case OPC_MULT: 14041 case OPC_MULTU: 14042 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14043 break; 14044 case OPC_DIV: 14045 case OPC_DIVU: 14046 gen_muldiv(ctx, op1, 0, rs, rt); 14047 break; 14048 #if defined(TARGET_MIPS64) 14049 case OPC_DMULT: 14050 case OPC_DMULTU: 14051 case OPC_DDIV: 14052 case OPC_DDIVU: 14053 check_insn(ctx, ISA_MIPS3); 14054 check_mips_64(ctx); 14055 gen_muldiv(ctx, op1, 0, rs, rt); 14056 break; 14057 #endif 14058 case OPC_JR: 14059 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14060 break; 14061 case OPC_SPIM: 14062 #ifdef MIPS_STRICT_STANDARD 14063 MIPS_INVAL("SPIM"); 14064 gen_reserved_instruction(ctx); 14065 #else 14066 /* Implemented as RI exception for now. */ 14067 MIPS_INVAL("spim (unofficial)"); 14068 gen_reserved_instruction(ctx); 14069 #endif 14070 break; 14071 default: /* Invalid */ 14072 MIPS_INVAL("special_legacy"); 14073 gen_reserved_instruction(ctx); 14074 break; 14075 } 14076 } 14077 14078 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 14079 { 14080 int rs, rt, rd, sa; 14081 uint32_t op1; 14082 14083 rs = (ctx->opcode >> 21) & 0x1f; 14084 rt = (ctx->opcode >> 16) & 0x1f; 14085 rd = (ctx->opcode >> 11) & 0x1f; 14086 sa = (ctx->opcode >> 6) & 0x1f; 14087 14088 op1 = MASK_SPECIAL(ctx->opcode); 14089 switch (op1) { 14090 case OPC_SLL: /* Shift with immediate */ 14091 if (sa == 5 && rd == 0 && 14092 rs == 0 && rt == 0) { /* PAUSE */ 14093 if ((ctx->insn_flags & ISA_MIPS_R6) && 14094 (ctx->hflags & MIPS_HFLAG_BMASK)) { 14095 gen_reserved_instruction(ctx); 14096 break; 14097 } 14098 } 14099 /* Fallthrough */ 14100 case OPC_SRA: 14101 gen_shift_imm(ctx, op1, rd, rt, sa); 14102 break; 14103 case OPC_SRL: 14104 switch ((ctx->opcode >> 21) & 0x1f) { 14105 case 1: 14106 /* rotr is decoded as srl on non-R2 CPUs */ 14107 if (ctx->insn_flags & ISA_MIPS_R2) { 14108 op1 = OPC_ROTR; 14109 } 14110 /* Fallthrough */ 14111 case 0: 14112 gen_shift_imm(ctx, op1, rd, rt, sa); 14113 break; 14114 default: 14115 gen_reserved_instruction(ctx); 14116 break; 14117 } 14118 break; 14119 case OPC_ADD: 14120 case OPC_ADDU: 14121 case OPC_SUB: 14122 case OPC_SUBU: 14123 gen_arith(ctx, op1, rd, rs, rt); 14124 break; 14125 case OPC_SLLV: /* Shifts */ 14126 case OPC_SRAV: 14127 gen_shift(ctx, op1, rd, rs, rt); 14128 break; 14129 case OPC_SRLV: 14130 switch ((ctx->opcode >> 6) & 0x1f) { 14131 case 1: 14132 /* rotrv is decoded as srlv on non-R2 CPUs */ 14133 if (ctx->insn_flags & ISA_MIPS_R2) { 14134 op1 = OPC_ROTRV; 14135 } 14136 /* Fallthrough */ 14137 case 0: 14138 gen_shift(ctx, op1, rd, rs, rt); 14139 break; 14140 default: 14141 gen_reserved_instruction(ctx); 14142 break; 14143 } 14144 break; 14145 case OPC_SLT: /* Set on less than */ 14146 case OPC_SLTU: 14147 gen_slt(ctx, op1, rd, rs, rt); 14148 break; 14149 case OPC_AND: /* Logic*/ 14150 case OPC_OR: 14151 case OPC_NOR: 14152 case OPC_XOR: 14153 gen_logic(ctx, op1, rd, rs, rt); 14154 break; 14155 case OPC_JALR: 14156 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14157 break; 14158 case OPC_TGE: /* Traps */ 14159 case OPC_TGEU: 14160 case OPC_TLT: 14161 case OPC_TLTU: 14162 case OPC_TEQ: 14163 case OPC_TNE: 14164 check_insn(ctx, ISA_MIPS2); 14165 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 14166 break; 14167 case OPC_PMON: 14168 /* Pmon entry point, also R4010 selsl */ 14169 #ifdef MIPS_STRICT_STANDARD 14170 MIPS_INVAL("PMON / selsl"); 14171 gen_reserved_instruction(ctx); 14172 #else 14173 gen_helper_pmon(cpu_env, tcg_constant_i32(sa)); 14174 #endif 14175 break; 14176 case OPC_SYSCALL: 14177 generate_exception_end(ctx, EXCP_SYSCALL); 14178 break; 14179 case OPC_BREAK: 14180 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 14181 break; 14182 case OPC_SYNC: 14183 check_insn(ctx, ISA_MIPS2); 14184 gen_sync(extract32(ctx->opcode, 6, 5)); 14185 break; 14186 14187 #if defined(TARGET_MIPS64) 14188 /* MIPS64 specific opcodes */ 14189 case OPC_DSLL: 14190 case OPC_DSRA: 14191 case OPC_DSLL32: 14192 case OPC_DSRA32: 14193 check_insn(ctx, ISA_MIPS3); 14194 check_mips_64(ctx); 14195 gen_shift_imm(ctx, op1, rd, rt, sa); 14196 break; 14197 case OPC_DSRL: 14198 switch ((ctx->opcode >> 21) & 0x1f) { 14199 case 1: 14200 /* drotr is decoded as dsrl on non-R2 CPUs */ 14201 if (ctx->insn_flags & ISA_MIPS_R2) { 14202 op1 = OPC_DROTR; 14203 } 14204 /* Fallthrough */ 14205 case 0: 14206 check_insn(ctx, ISA_MIPS3); 14207 check_mips_64(ctx); 14208 gen_shift_imm(ctx, op1, rd, rt, sa); 14209 break; 14210 default: 14211 gen_reserved_instruction(ctx); 14212 break; 14213 } 14214 break; 14215 case OPC_DSRL32: 14216 switch ((ctx->opcode >> 21) & 0x1f) { 14217 case 1: 14218 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 14219 if (ctx->insn_flags & ISA_MIPS_R2) { 14220 op1 = OPC_DROTR32; 14221 } 14222 /* Fallthrough */ 14223 case 0: 14224 check_insn(ctx, ISA_MIPS3); 14225 check_mips_64(ctx); 14226 gen_shift_imm(ctx, op1, rd, rt, sa); 14227 break; 14228 default: 14229 gen_reserved_instruction(ctx); 14230 break; 14231 } 14232 break; 14233 case OPC_DADD: 14234 case OPC_DADDU: 14235 case OPC_DSUB: 14236 case OPC_DSUBU: 14237 check_insn(ctx, ISA_MIPS3); 14238 check_mips_64(ctx); 14239 gen_arith(ctx, op1, rd, rs, rt); 14240 break; 14241 case OPC_DSLLV: 14242 case OPC_DSRAV: 14243 check_insn(ctx, ISA_MIPS3); 14244 check_mips_64(ctx); 14245 gen_shift(ctx, op1, rd, rs, rt); 14246 break; 14247 case OPC_DSRLV: 14248 switch ((ctx->opcode >> 6) & 0x1f) { 14249 case 1: 14250 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 14251 if (ctx->insn_flags & ISA_MIPS_R2) { 14252 op1 = OPC_DROTRV; 14253 } 14254 /* Fallthrough */ 14255 case 0: 14256 check_insn(ctx, ISA_MIPS3); 14257 check_mips_64(ctx); 14258 gen_shift(ctx, op1, rd, rs, rt); 14259 break; 14260 default: 14261 gen_reserved_instruction(ctx); 14262 break; 14263 } 14264 break; 14265 #endif 14266 default: 14267 if (ctx->insn_flags & ISA_MIPS_R6) { 14268 decode_opc_special_r6(env, ctx); 14269 } else if (ctx->insn_flags & INSN_R5900) { 14270 decode_opc_special_tx79(env, ctx); 14271 } else { 14272 decode_opc_special_legacy(env, ctx); 14273 } 14274 } 14275 } 14276 14277 14278 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 14279 { 14280 int rs, rt, rd; 14281 uint32_t op1; 14282 14283 rs = (ctx->opcode >> 21) & 0x1f; 14284 rt = (ctx->opcode >> 16) & 0x1f; 14285 rd = (ctx->opcode >> 11) & 0x1f; 14286 14287 op1 = MASK_SPECIAL2(ctx->opcode); 14288 switch (op1) { 14289 case OPC_MADD: /* Multiply and add/sub */ 14290 case OPC_MADDU: 14291 case OPC_MSUB: 14292 case OPC_MSUBU: 14293 check_insn(ctx, ISA_MIPS_R1); 14294 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14295 break; 14296 case OPC_MUL: 14297 gen_arith(ctx, op1, rd, rs, rt); 14298 break; 14299 case OPC_DIV_G_2F: 14300 case OPC_DIVU_G_2F: 14301 case OPC_MULT_G_2F: 14302 case OPC_MULTU_G_2F: 14303 case OPC_MOD_G_2F: 14304 case OPC_MODU_G_2F: 14305 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14306 gen_loongson_integer(ctx, op1, rd, rs, rt); 14307 break; 14308 case OPC_CLO: 14309 case OPC_CLZ: 14310 check_insn(ctx, ISA_MIPS_R1); 14311 gen_cl(ctx, op1, rd, rs); 14312 break; 14313 case OPC_SDBBP: 14314 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 14315 ctx->base.is_jmp = DISAS_SEMIHOST; 14316 } else { 14317 /* 14318 * XXX: not clear which exception should be raised 14319 * when in debug mode... 14320 */ 14321 check_insn(ctx, ISA_MIPS_R1); 14322 generate_exception_end(ctx, EXCP_DBp); 14323 } 14324 break; 14325 #if defined(TARGET_MIPS64) 14326 case OPC_DCLO: 14327 case OPC_DCLZ: 14328 check_insn(ctx, ISA_MIPS_R1); 14329 check_mips_64(ctx); 14330 gen_cl(ctx, op1, rd, rs); 14331 break; 14332 case OPC_DMULT_G_2F: 14333 case OPC_DMULTU_G_2F: 14334 case OPC_DDIV_G_2F: 14335 case OPC_DDIVU_G_2F: 14336 case OPC_DMOD_G_2F: 14337 case OPC_DMODU_G_2F: 14338 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14339 gen_loongson_integer(ctx, op1, rd, rs, rt); 14340 break; 14341 #endif 14342 default: /* Invalid */ 14343 MIPS_INVAL("special2_legacy"); 14344 gen_reserved_instruction(ctx); 14345 break; 14346 } 14347 } 14348 14349 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 14350 { 14351 int rs, rt, rd, sa; 14352 uint32_t op1, op2; 14353 int16_t imm; 14354 14355 rs = (ctx->opcode >> 21) & 0x1f; 14356 rt = (ctx->opcode >> 16) & 0x1f; 14357 rd = (ctx->opcode >> 11) & 0x1f; 14358 sa = (ctx->opcode >> 6) & 0x1f; 14359 imm = (int16_t)ctx->opcode >> 7; 14360 14361 op1 = MASK_SPECIAL3(ctx->opcode); 14362 switch (op1) { 14363 case R6_OPC_PREF: 14364 if (rt >= 24) { 14365 /* hint codes 24-31 are reserved and signal RI */ 14366 gen_reserved_instruction(ctx); 14367 } 14368 /* Treat as NOP. */ 14369 break; 14370 case R6_OPC_CACHE: 14371 check_cp0_enabled(ctx); 14372 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14373 gen_cache_operation(ctx, rt, rs, imm); 14374 } 14375 break; 14376 case R6_OPC_SC: 14377 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14378 break; 14379 case R6_OPC_LL: 14380 gen_ld(ctx, op1, rt, rs, imm); 14381 break; 14382 case OPC_BSHFL: 14383 { 14384 if (rd == 0) { 14385 /* Treat as NOP. */ 14386 break; 14387 } 14388 op2 = MASK_BSHFL(ctx->opcode); 14389 switch (op2) { 14390 case OPC_ALIGN: 14391 case OPC_ALIGN_1: 14392 case OPC_ALIGN_2: 14393 case OPC_ALIGN_3: 14394 gen_align(ctx, 32, rd, rs, rt, sa & 3); 14395 break; 14396 case OPC_BITSWAP: 14397 gen_bitswap(ctx, op2, rd, rt); 14398 break; 14399 } 14400 } 14401 break; 14402 #ifndef CONFIG_USER_ONLY 14403 case OPC_GINV: 14404 if (unlikely(ctx->gi <= 1)) { 14405 gen_reserved_instruction(ctx); 14406 } 14407 check_cp0_enabled(ctx); 14408 switch ((ctx->opcode >> 6) & 3) { 14409 case 0: /* GINVI */ 14410 /* Treat as NOP. */ 14411 break; 14412 case 2: /* GINVT */ 14413 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 14414 break; 14415 default: 14416 gen_reserved_instruction(ctx); 14417 break; 14418 } 14419 break; 14420 #endif 14421 #if defined(TARGET_MIPS64) 14422 case R6_OPC_SCD: 14423 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 14424 break; 14425 case R6_OPC_LLD: 14426 gen_ld(ctx, op1, rt, rs, imm); 14427 break; 14428 case OPC_DBSHFL: 14429 check_mips_64(ctx); 14430 { 14431 if (rd == 0) { 14432 /* Treat as NOP. */ 14433 break; 14434 } 14435 op2 = MASK_DBSHFL(ctx->opcode); 14436 switch (op2) { 14437 case OPC_DALIGN: 14438 case OPC_DALIGN_1: 14439 case OPC_DALIGN_2: 14440 case OPC_DALIGN_3: 14441 case OPC_DALIGN_4: 14442 case OPC_DALIGN_5: 14443 case OPC_DALIGN_6: 14444 case OPC_DALIGN_7: 14445 gen_align(ctx, 64, rd, rs, rt, sa & 7); 14446 break; 14447 case OPC_DBITSWAP: 14448 gen_bitswap(ctx, op2, rd, rt); 14449 break; 14450 } 14451 14452 } 14453 break; 14454 #endif 14455 default: /* Invalid */ 14456 MIPS_INVAL("special3_r6"); 14457 gen_reserved_instruction(ctx); 14458 break; 14459 } 14460 } 14461 14462 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 14463 { 14464 int rs, rt, rd; 14465 uint32_t op1, op2; 14466 14467 rs = (ctx->opcode >> 21) & 0x1f; 14468 rt = (ctx->opcode >> 16) & 0x1f; 14469 rd = (ctx->opcode >> 11) & 0x1f; 14470 14471 op1 = MASK_SPECIAL3(ctx->opcode); 14472 switch (op1) { 14473 case OPC_DIV_G_2E: 14474 case OPC_DIVU_G_2E: 14475 case OPC_MOD_G_2E: 14476 case OPC_MODU_G_2E: 14477 case OPC_MULT_G_2E: 14478 case OPC_MULTU_G_2E: 14479 /* 14480 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 14481 * the same mask and op1. 14482 */ 14483 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 14484 op2 = MASK_ADDUH_QB(ctx->opcode); 14485 switch (op2) { 14486 case OPC_ADDUH_QB: 14487 case OPC_ADDUH_R_QB: 14488 case OPC_ADDQH_PH: 14489 case OPC_ADDQH_R_PH: 14490 case OPC_ADDQH_W: 14491 case OPC_ADDQH_R_W: 14492 case OPC_SUBUH_QB: 14493 case OPC_SUBUH_R_QB: 14494 case OPC_SUBQH_PH: 14495 case OPC_SUBQH_R_PH: 14496 case OPC_SUBQH_W: 14497 case OPC_SUBQH_R_W: 14498 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14499 break; 14500 case OPC_MUL_PH: 14501 case OPC_MUL_S_PH: 14502 case OPC_MULQ_S_W: 14503 case OPC_MULQ_RS_W: 14504 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14505 break; 14506 default: 14507 MIPS_INVAL("MASK ADDUH.QB"); 14508 gen_reserved_instruction(ctx); 14509 break; 14510 } 14511 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 14512 gen_loongson_integer(ctx, op1, rd, rs, rt); 14513 } else { 14514 gen_reserved_instruction(ctx); 14515 } 14516 break; 14517 case OPC_LX_DSP: 14518 op2 = MASK_LX(ctx->opcode); 14519 switch (op2) { 14520 #if defined(TARGET_MIPS64) 14521 case OPC_LDX: 14522 #endif 14523 case OPC_LBUX: 14524 case OPC_LHX: 14525 case OPC_LWX: 14526 gen_mipsdsp_ld(ctx, op2, rd, rs, rt); 14527 break; 14528 default: /* Invalid */ 14529 MIPS_INVAL("MASK LX"); 14530 gen_reserved_instruction(ctx); 14531 break; 14532 } 14533 break; 14534 case OPC_ABSQ_S_PH_DSP: 14535 op2 = MASK_ABSQ_S_PH(ctx->opcode); 14536 switch (op2) { 14537 case OPC_ABSQ_S_QB: 14538 case OPC_ABSQ_S_PH: 14539 case OPC_ABSQ_S_W: 14540 case OPC_PRECEQ_W_PHL: 14541 case OPC_PRECEQ_W_PHR: 14542 case OPC_PRECEQU_PH_QBL: 14543 case OPC_PRECEQU_PH_QBR: 14544 case OPC_PRECEQU_PH_QBLA: 14545 case OPC_PRECEQU_PH_QBRA: 14546 case OPC_PRECEU_PH_QBL: 14547 case OPC_PRECEU_PH_QBR: 14548 case OPC_PRECEU_PH_QBLA: 14549 case OPC_PRECEU_PH_QBRA: 14550 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14551 break; 14552 case OPC_BITREV: 14553 case OPC_REPL_QB: 14554 case OPC_REPLV_QB: 14555 case OPC_REPL_PH: 14556 case OPC_REPLV_PH: 14557 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14558 break; 14559 default: 14560 MIPS_INVAL("MASK ABSQ_S.PH"); 14561 gen_reserved_instruction(ctx); 14562 break; 14563 } 14564 break; 14565 case OPC_ADDU_QB_DSP: 14566 op2 = MASK_ADDU_QB(ctx->opcode); 14567 switch (op2) { 14568 case OPC_ADDQ_PH: 14569 case OPC_ADDQ_S_PH: 14570 case OPC_ADDQ_S_W: 14571 case OPC_ADDU_QB: 14572 case OPC_ADDU_S_QB: 14573 case OPC_ADDU_PH: 14574 case OPC_ADDU_S_PH: 14575 case OPC_SUBQ_PH: 14576 case OPC_SUBQ_S_PH: 14577 case OPC_SUBQ_S_W: 14578 case OPC_SUBU_QB: 14579 case OPC_SUBU_S_QB: 14580 case OPC_SUBU_PH: 14581 case OPC_SUBU_S_PH: 14582 case OPC_ADDSC: 14583 case OPC_ADDWC: 14584 case OPC_MODSUB: 14585 case OPC_RADDU_W_QB: 14586 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14587 break; 14588 case OPC_MULEU_S_PH_QBL: 14589 case OPC_MULEU_S_PH_QBR: 14590 case OPC_MULQ_RS_PH: 14591 case OPC_MULEQ_S_W_PHL: 14592 case OPC_MULEQ_S_W_PHR: 14593 case OPC_MULQ_S_PH: 14594 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14595 break; 14596 default: /* Invalid */ 14597 MIPS_INVAL("MASK ADDU.QB"); 14598 gen_reserved_instruction(ctx); 14599 break; 14600 14601 } 14602 break; 14603 case OPC_CMPU_EQ_QB_DSP: 14604 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14605 switch (op2) { 14606 case OPC_PRECR_SRA_PH_W: 14607 case OPC_PRECR_SRA_R_PH_W: 14608 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14609 break; 14610 case OPC_PRECR_QB_PH: 14611 case OPC_PRECRQ_QB_PH: 14612 case OPC_PRECRQ_PH_W: 14613 case OPC_PRECRQ_RS_PH_W: 14614 case OPC_PRECRQU_S_QB_PH: 14615 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14616 break; 14617 case OPC_CMPU_EQ_QB: 14618 case OPC_CMPU_LT_QB: 14619 case OPC_CMPU_LE_QB: 14620 case OPC_CMP_EQ_PH: 14621 case OPC_CMP_LT_PH: 14622 case OPC_CMP_LE_PH: 14623 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14624 break; 14625 case OPC_CMPGU_EQ_QB: 14626 case OPC_CMPGU_LT_QB: 14627 case OPC_CMPGU_LE_QB: 14628 case OPC_CMPGDU_EQ_QB: 14629 case OPC_CMPGDU_LT_QB: 14630 case OPC_CMPGDU_LE_QB: 14631 case OPC_PICK_QB: 14632 case OPC_PICK_PH: 14633 case OPC_PACKRL_PH: 14634 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14635 break; 14636 default: /* Invalid */ 14637 MIPS_INVAL("MASK CMPU.EQ.QB"); 14638 gen_reserved_instruction(ctx); 14639 break; 14640 } 14641 break; 14642 case OPC_SHLL_QB_DSP: 14643 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14644 break; 14645 case OPC_DPA_W_PH_DSP: 14646 op2 = MASK_DPA_W_PH(ctx->opcode); 14647 switch (op2) { 14648 case OPC_DPAU_H_QBL: 14649 case OPC_DPAU_H_QBR: 14650 case OPC_DPSU_H_QBL: 14651 case OPC_DPSU_H_QBR: 14652 case OPC_DPA_W_PH: 14653 case OPC_DPAX_W_PH: 14654 case OPC_DPAQ_S_W_PH: 14655 case OPC_DPAQX_S_W_PH: 14656 case OPC_DPAQX_SA_W_PH: 14657 case OPC_DPS_W_PH: 14658 case OPC_DPSX_W_PH: 14659 case OPC_DPSQ_S_W_PH: 14660 case OPC_DPSQX_S_W_PH: 14661 case OPC_DPSQX_SA_W_PH: 14662 case OPC_MULSAQ_S_W_PH: 14663 case OPC_DPAQ_SA_L_W: 14664 case OPC_DPSQ_SA_L_W: 14665 case OPC_MAQ_S_W_PHL: 14666 case OPC_MAQ_S_W_PHR: 14667 case OPC_MAQ_SA_W_PHL: 14668 case OPC_MAQ_SA_W_PHR: 14669 case OPC_MULSA_W_PH: 14670 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14671 break; 14672 default: /* Invalid */ 14673 MIPS_INVAL("MASK DPAW.PH"); 14674 gen_reserved_instruction(ctx); 14675 break; 14676 } 14677 break; 14678 case OPC_INSV_DSP: 14679 op2 = MASK_INSV(ctx->opcode); 14680 switch (op2) { 14681 case OPC_INSV: 14682 check_dsp(ctx); 14683 { 14684 TCGv t0, t1; 14685 14686 if (rt == 0) { 14687 break; 14688 } 14689 14690 t0 = tcg_temp_new(); 14691 t1 = tcg_temp_new(); 14692 14693 gen_load_gpr(t0, rt); 14694 gen_load_gpr(t1, rs); 14695 14696 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14697 14698 tcg_temp_free(t0); 14699 tcg_temp_free(t1); 14700 break; 14701 } 14702 default: /* Invalid */ 14703 MIPS_INVAL("MASK INSV"); 14704 gen_reserved_instruction(ctx); 14705 break; 14706 } 14707 break; 14708 case OPC_APPEND_DSP: 14709 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14710 break; 14711 case OPC_EXTR_W_DSP: 14712 op2 = MASK_EXTR_W(ctx->opcode); 14713 switch (op2) { 14714 case OPC_EXTR_W: 14715 case OPC_EXTR_R_W: 14716 case OPC_EXTR_RS_W: 14717 case OPC_EXTR_S_H: 14718 case OPC_EXTRV_S_H: 14719 case OPC_EXTRV_W: 14720 case OPC_EXTRV_R_W: 14721 case OPC_EXTRV_RS_W: 14722 case OPC_EXTP: 14723 case OPC_EXTPV: 14724 case OPC_EXTPDP: 14725 case OPC_EXTPDPV: 14726 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14727 break; 14728 case OPC_RDDSP: 14729 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14730 break; 14731 case OPC_SHILO: 14732 case OPC_SHILOV: 14733 case OPC_MTHLIP: 14734 case OPC_WRDSP: 14735 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14736 break; 14737 default: /* Invalid */ 14738 MIPS_INVAL("MASK EXTR.W"); 14739 gen_reserved_instruction(ctx); 14740 break; 14741 } 14742 break; 14743 #if defined(TARGET_MIPS64) 14744 case OPC_DDIV_G_2E: 14745 case OPC_DDIVU_G_2E: 14746 case OPC_DMULT_G_2E: 14747 case OPC_DMULTU_G_2E: 14748 case OPC_DMOD_G_2E: 14749 case OPC_DMODU_G_2E: 14750 check_insn(ctx, INSN_LOONGSON2E); 14751 gen_loongson_integer(ctx, op1, rd, rs, rt); 14752 break; 14753 case OPC_ABSQ_S_QH_DSP: 14754 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14755 switch (op2) { 14756 case OPC_PRECEQ_L_PWL: 14757 case OPC_PRECEQ_L_PWR: 14758 case OPC_PRECEQ_PW_QHL: 14759 case OPC_PRECEQ_PW_QHR: 14760 case OPC_PRECEQ_PW_QHLA: 14761 case OPC_PRECEQ_PW_QHRA: 14762 case OPC_PRECEQU_QH_OBL: 14763 case OPC_PRECEQU_QH_OBR: 14764 case OPC_PRECEQU_QH_OBLA: 14765 case OPC_PRECEQU_QH_OBRA: 14766 case OPC_PRECEU_QH_OBL: 14767 case OPC_PRECEU_QH_OBR: 14768 case OPC_PRECEU_QH_OBLA: 14769 case OPC_PRECEU_QH_OBRA: 14770 case OPC_ABSQ_S_OB: 14771 case OPC_ABSQ_S_PW: 14772 case OPC_ABSQ_S_QH: 14773 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14774 break; 14775 case OPC_REPL_OB: 14776 case OPC_REPL_PW: 14777 case OPC_REPL_QH: 14778 case OPC_REPLV_OB: 14779 case OPC_REPLV_PW: 14780 case OPC_REPLV_QH: 14781 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14782 break; 14783 default: /* Invalid */ 14784 MIPS_INVAL("MASK ABSQ_S.QH"); 14785 gen_reserved_instruction(ctx); 14786 break; 14787 } 14788 break; 14789 case OPC_ADDU_OB_DSP: 14790 op2 = MASK_ADDU_OB(ctx->opcode); 14791 switch (op2) { 14792 case OPC_RADDU_L_OB: 14793 case OPC_SUBQ_PW: 14794 case OPC_SUBQ_S_PW: 14795 case OPC_SUBQ_QH: 14796 case OPC_SUBQ_S_QH: 14797 case OPC_SUBU_OB: 14798 case OPC_SUBU_S_OB: 14799 case OPC_SUBU_QH: 14800 case OPC_SUBU_S_QH: 14801 case OPC_SUBUH_OB: 14802 case OPC_SUBUH_R_OB: 14803 case OPC_ADDQ_PW: 14804 case OPC_ADDQ_S_PW: 14805 case OPC_ADDQ_QH: 14806 case OPC_ADDQ_S_QH: 14807 case OPC_ADDU_OB: 14808 case OPC_ADDU_S_OB: 14809 case OPC_ADDU_QH: 14810 case OPC_ADDU_S_QH: 14811 case OPC_ADDUH_OB: 14812 case OPC_ADDUH_R_OB: 14813 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14814 break; 14815 case OPC_MULEQ_S_PW_QHL: 14816 case OPC_MULEQ_S_PW_QHR: 14817 case OPC_MULEU_S_QH_OBL: 14818 case OPC_MULEU_S_QH_OBR: 14819 case OPC_MULQ_RS_QH: 14820 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14821 break; 14822 default: /* Invalid */ 14823 MIPS_INVAL("MASK ADDU.OB"); 14824 gen_reserved_instruction(ctx); 14825 break; 14826 } 14827 break; 14828 case OPC_CMPU_EQ_OB_DSP: 14829 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14830 switch (op2) { 14831 case OPC_PRECR_SRA_QH_PW: 14832 case OPC_PRECR_SRA_R_QH_PW: 14833 /* Return value is rt. */ 14834 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14835 break; 14836 case OPC_PRECR_OB_QH: 14837 case OPC_PRECRQ_OB_QH: 14838 case OPC_PRECRQ_PW_L: 14839 case OPC_PRECRQ_QH_PW: 14840 case OPC_PRECRQ_RS_QH_PW: 14841 case OPC_PRECRQU_S_OB_QH: 14842 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14843 break; 14844 case OPC_CMPU_EQ_OB: 14845 case OPC_CMPU_LT_OB: 14846 case OPC_CMPU_LE_OB: 14847 case OPC_CMP_EQ_QH: 14848 case OPC_CMP_LT_QH: 14849 case OPC_CMP_LE_QH: 14850 case OPC_CMP_EQ_PW: 14851 case OPC_CMP_LT_PW: 14852 case OPC_CMP_LE_PW: 14853 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14854 break; 14855 case OPC_CMPGDU_EQ_OB: 14856 case OPC_CMPGDU_LT_OB: 14857 case OPC_CMPGDU_LE_OB: 14858 case OPC_CMPGU_EQ_OB: 14859 case OPC_CMPGU_LT_OB: 14860 case OPC_CMPGU_LE_OB: 14861 case OPC_PACKRL_PW: 14862 case OPC_PICK_OB: 14863 case OPC_PICK_PW: 14864 case OPC_PICK_QH: 14865 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14866 break; 14867 default: /* Invalid */ 14868 MIPS_INVAL("MASK CMPU_EQ.OB"); 14869 gen_reserved_instruction(ctx); 14870 break; 14871 } 14872 break; 14873 case OPC_DAPPEND_DSP: 14874 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14875 break; 14876 case OPC_DEXTR_W_DSP: 14877 op2 = MASK_DEXTR_W(ctx->opcode); 14878 switch (op2) { 14879 case OPC_DEXTP: 14880 case OPC_DEXTPDP: 14881 case OPC_DEXTPDPV: 14882 case OPC_DEXTPV: 14883 case OPC_DEXTR_L: 14884 case OPC_DEXTR_R_L: 14885 case OPC_DEXTR_RS_L: 14886 case OPC_DEXTR_W: 14887 case OPC_DEXTR_R_W: 14888 case OPC_DEXTR_RS_W: 14889 case OPC_DEXTR_S_H: 14890 case OPC_DEXTRV_L: 14891 case OPC_DEXTRV_R_L: 14892 case OPC_DEXTRV_RS_L: 14893 case OPC_DEXTRV_S_H: 14894 case OPC_DEXTRV_W: 14895 case OPC_DEXTRV_R_W: 14896 case OPC_DEXTRV_RS_W: 14897 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14898 break; 14899 case OPC_DMTHLIP: 14900 case OPC_DSHILO: 14901 case OPC_DSHILOV: 14902 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14903 break; 14904 default: /* Invalid */ 14905 MIPS_INVAL("MASK EXTR.W"); 14906 gen_reserved_instruction(ctx); 14907 break; 14908 } 14909 break; 14910 case OPC_DPAQ_W_QH_DSP: 14911 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14912 switch (op2) { 14913 case OPC_DPAU_H_OBL: 14914 case OPC_DPAU_H_OBR: 14915 case OPC_DPSU_H_OBL: 14916 case OPC_DPSU_H_OBR: 14917 case OPC_DPA_W_QH: 14918 case OPC_DPAQ_S_W_QH: 14919 case OPC_DPS_W_QH: 14920 case OPC_DPSQ_S_W_QH: 14921 case OPC_MULSAQ_S_W_QH: 14922 case OPC_DPAQ_SA_L_PW: 14923 case OPC_DPSQ_SA_L_PW: 14924 case OPC_MULSAQ_S_L_PW: 14925 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14926 break; 14927 case OPC_MAQ_S_W_QHLL: 14928 case OPC_MAQ_S_W_QHLR: 14929 case OPC_MAQ_S_W_QHRL: 14930 case OPC_MAQ_S_W_QHRR: 14931 case OPC_MAQ_SA_W_QHLL: 14932 case OPC_MAQ_SA_W_QHLR: 14933 case OPC_MAQ_SA_W_QHRL: 14934 case OPC_MAQ_SA_W_QHRR: 14935 case OPC_MAQ_S_L_PWL: 14936 case OPC_MAQ_S_L_PWR: 14937 case OPC_DMADD: 14938 case OPC_DMADDU: 14939 case OPC_DMSUB: 14940 case OPC_DMSUBU: 14941 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14942 break; 14943 default: /* Invalid */ 14944 MIPS_INVAL("MASK DPAQ.W.QH"); 14945 gen_reserved_instruction(ctx); 14946 break; 14947 } 14948 break; 14949 case OPC_DINSV_DSP: 14950 op2 = MASK_INSV(ctx->opcode); 14951 switch (op2) { 14952 case OPC_DINSV: 14953 { 14954 TCGv t0, t1; 14955 14956 check_dsp(ctx); 14957 14958 if (rt == 0) { 14959 break; 14960 } 14961 14962 t0 = tcg_temp_new(); 14963 t1 = tcg_temp_new(); 14964 14965 gen_load_gpr(t0, rt); 14966 gen_load_gpr(t1, rs); 14967 14968 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 14969 14970 tcg_temp_free(t0); 14971 tcg_temp_free(t1); 14972 break; 14973 } 14974 default: /* Invalid */ 14975 MIPS_INVAL("MASK DINSV"); 14976 gen_reserved_instruction(ctx); 14977 break; 14978 } 14979 break; 14980 case OPC_SHLL_OB_DSP: 14981 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14982 break; 14983 #endif 14984 default: /* Invalid */ 14985 MIPS_INVAL("special3_legacy"); 14986 gen_reserved_instruction(ctx); 14987 break; 14988 } 14989 } 14990 14991 14992 #if defined(TARGET_MIPS64) 14993 14994 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14995 { 14996 uint32_t opc = MASK_MMI(ctx->opcode); 14997 int rs = extract32(ctx->opcode, 21, 5); 14998 int rt = extract32(ctx->opcode, 16, 5); 14999 int rd = extract32(ctx->opcode, 11, 5); 15000 15001 switch (opc) { 15002 case MMI_OPC_MULT1: 15003 case MMI_OPC_MULTU1: 15004 case MMI_OPC_MADD: 15005 case MMI_OPC_MADDU: 15006 case MMI_OPC_MADD1: 15007 case MMI_OPC_MADDU1: 15008 gen_mul_txx9(ctx, opc, rd, rs, rt); 15009 break; 15010 case MMI_OPC_DIV1: 15011 case MMI_OPC_DIVU1: 15012 gen_div1_tx79(ctx, opc, rs, rt); 15013 break; 15014 default: 15015 MIPS_INVAL("TX79 MMI class"); 15016 gen_reserved_instruction(ctx); 15017 break; 15018 } 15019 } 15020 15021 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 15022 { 15023 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 15024 } 15025 15026 /* 15027 * The TX79-specific instruction Store Quadword 15028 * 15029 * +--------+-------+-------+------------------------+ 15030 * | 011111 | base | rt | offset | SQ 15031 * +--------+-------+-------+------------------------+ 15032 * 6 5 5 16 15033 * 15034 * has the same opcode as the Read Hardware Register instruction 15035 * 15036 * +--------+-------+-------+-------+-------+--------+ 15037 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 15038 * +--------+-------+-------+-------+-------+--------+ 15039 * 6 5 5 5 5 6 15040 * 15041 * that is required, trapped and emulated by the Linux kernel. However, all 15042 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 15043 * offset is odd. Therefore all valid SQ instructions can execute normally. 15044 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 15045 * between SQ and RDHWR, as the Linux kernel does. 15046 */ 15047 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 15048 { 15049 int base = extract32(ctx->opcode, 21, 5); 15050 int rt = extract32(ctx->opcode, 16, 5); 15051 int offset = extract32(ctx->opcode, 0, 16); 15052 15053 #ifdef CONFIG_USER_ONLY 15054 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 15055 uint32_t op2 = extract32(ctx->opcode, 6, 5); 15056 15057 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 15058 int rd = extract32(ctx->opcode, 11, 5); 15059 15060 gen_rdhwr(ctx, rt, rd, 0); 15061 return; 15062 } 15063 #endif 15064 15065 gen_mmi_sq(ctx, base, rt, offset); 15066 } 15067 15068 #endif 15069 15070 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 15071 { 15072 int rs, rt, rd, sa; 15073 uint32_t op1, op2; 15074 int16_t imm; 15075 15076 rs = (ctx->opcode >> 21) & 0x1f; 15077 rt = (ctx->opcode >> 16) & 0x1f; 15078 rd = (ctx->opcode >> 11) & 0x1f; 15079 sa = (ctx->opcode >> 6) & 0x1f; 15080 imm = sextract32(ctx->opcode, 7, 9); 15081 15082 op1 = MASK_SPECIAL3(ctx->opcode); 15083 15084 /* 15085 * EVA loads and stores overlap Loongson 2E instructions decoded by 15086 * decode_opc_special3_legacy(), so be careful to allow their decoding when 15087 * EVA is absent. 15088 */ 15089 if (ctx->eva) { 15090 switch (op1) { 15091 case OPC_LWLE: 15092 case OPC_LWRE: 15093 case OPC_LBUE: 15094 case OPC_LHUE: 15095 case OPC_LBE: 15096 case OPC_LHE: 15097 case OPC_LLE: 15098 case OPC_LWE: 15099 check_cp0_enabled(ctx); 15100 gen_ld(ctx, op1, rt, rs, imm); 15101 return; 15102 case OPC_SWLE: 15103 case OPC_SWRE: 15104 case OPC_SBE: 15105 case OPC_SHE: 15106 case OPC_SWE: 15107 check_cp0_enabled(ctx); 15108 gen_st(ctx, op1, rt, rs, imm); 15109 return; 15110 case OPC_SCE: 15111 check_cp0_enabled(ctx); 15112 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 15113 return; 15114 case OPC_CACHEE: 15115 check_eva(ctx); 15116 check_cp0_enabled(ctx); 15117 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15118 gen_cache_operation(ctx, rt, rs, imm); 15119 } 15120 return; 15121 case OPC_PREFE: 15122 check_cp0_enabled(ctx); 15123 /* Treat as NOP. */ 15124 return; 15125 } 15126 } 15127 15128 switch (op1) { 15129 case OPC_EXT: 15130 case OPC_INS: 15131 check_insn(ctx, ISA_MIPS_R2); 15132 gen_bitops(ctx, op1, rt, rs, sa, rd); 15133 break; 15134 case OPC_BSHFL: 15135 op2 = MASK_BSHFL(ctx->opcode); 15136 switch (op2) { 15137 case OPC_ALIGN: 15138 case OPC_ALIGN_1: 15139 case OPC_ALIGN_2: 15140 case OPC_ALIGN_3: 15141 case OPC_BITSWAP: 15142 check_insn(ctx, ISA_MIPS_R6); 15143 decode_opc_special3_r6(env, ctx); 15144 break; 15145 default: 15146 check_insn(ctx, ISA_MIPS_R2); 15147 gen_bshfl(ctx, op2, rt, rd); 15148 break; 15149 } 15150 break; 15151 #if defined(TARGET_MIPS64) 15152 case OPC_DEXTM: 15153 case OPC_DEXTU: 15154 case OPC_DEXT: 15155 case OPC_DINSM: 15156 case OPC_DINSU: 15157 case OPC_DINS: 15158 check_insn(ctx, ISA_MIPS_R2); 15159 check_mips_64(ctx); 15160 gen_bitops(ctx, op1, rt, rs, sa, rd); 15161 break; 15162 case OPC_DBSHFL: 15163 op2 = MASK_DBSHFL(ctx->opcode); 15164 switch (op2) { 15165 case OPC_DALIGN: 15166 case OPC_DALIGN_1: 15167 case OPC_DALIGN_2: 15168 case OPC_DALIGN_3: 15169 case OPC_DALIGN_4: 15170 case OPC_DALIGN_5: 15171 case OPC_DALIGN_6: 15172 case OPC_DALIGN_7: 15173 case OPC_DBITSWAP: 15174 check_insn(ctx, ISA_MIPS_R6); 15175 decode_opc_special3_r6(env, ctx); 15176 break; 15177 default: 15178 check_insn(ctx, ISA_MIPS_R2); 15179 check_mips_64(ctx); 15180 op2 = MASK_DBSHFL(ctx->opcode); 15181 gen_bshfl(ctx, op2, rt, rd); 15182 break; 15183 } 15184 break; 15185 #endif 15186 case OPC_RDHWR: 15187 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 15188 break; 15189 case OPC_FORK: 15190 check_mt(ctx); 15191 { 15192 TCGv t0 = tcg_temp_new(); 15193 TCGv t1 = tcg_temp_new(); 15194 15195 gen_load_gpr(t0, rt); 15196 gen_load_gpr(t1, rs); 15197 gen_helper_fork(t0, t1); 15198 tcg_temp_free(t0); 15199 tcg_temp_free(t1); 15200 } 15201 break; 15202 case OPC_YIELD: 15203 check_mt(ctx); 15204 { 15205 TCGv t0 = tcg_temp_new(); 15206 15207 gen_load_gpr(t0, rs); 15208 gen_helper_yield(t0, cpu_env, t0); 15209 gen_store_gpr(t0, rd); 15210 tcg_temp_free(t0); 15211 } 15212 break; 15213 default: 15214 if (ctx->insn_flags & ISA_MIPS_R6) { 15215 decode_opc_special3_r6(env, ctx); 15216 } else { 15217 decode_opc_special3_legacy(env, ctx); 15218 } 15219 } 15220 } 15221 15222 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 15223 { 15224 int32_t offset; 15225 int rs, rt, rd, sa; 15226 uint32_t op, op1; 15227 int16_t imm; 15228 15229 op = MASK_OP_MAJOR(ctx->opcode); 15230 rs = (ctx->opcode >> 21) & 0x1f; 15231 rt = (ctx->opcode >> 16) & 0x1f; 15232 rd = (ctx->opcode >> 11) & 0x1f; 15233 sa = (ctx->opcode >> 6) & 0x1f; 15234 imm = (int16_t)ctx->opcode; 15235 switch (op) { 15236 case OPC_SPECIAL: 15237 decode_opc_special(env, ctx); 15238 break; 15239 case OPC_SPECIAL2: 15240 #if defined(TARGET_MIPS64) 15241 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 15242 decode_mmi(env, ctx); 15243 break; 15244 } 15245 #endif 15246 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 15247 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 15248 gen_arith(ctx, OPC_MUL, rd, rs, rt); 15249 } else { 15250 decode_ase_mxu(ctx, ctx->opcode); 15251 } 15252 break; 15253 } 15254 decode_opc_special2_legacy(env, ctx); 15255 break; 15256 case OPC_SPECIAL3: 15257 #if defined(TARGET_MIPS64) 15258 if (ctx->insn_flags & INSN_R5900) { 15259 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 15260 } else { 15261 decode_opc_special3(env, ctx); 15262 } 15263 #else 15264 decode_opc_special3(env, ctx); 15265 #endif 15266 break; 15267 case OPC_REGIMM: 15268 op1 = MASK_REGIMM(ctx->opcode); 15269 switch (op1) { 15270 case OPC_BLTZL: /* REGIMM branches */ 15271 case OPC_BGEZL: 15272 case OPC_BLTZALL: 15273 case OPC_BGEZALL: 15274 check_insn(ctx, ISA_MIPS2); 15275 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15276 /* Fallthrough */ 15277 case OPC_BLTZ: 15278 case OPC_BGEZ: 15279 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15280 break; 15281 case OPC_BLTZAL: 15282 case OPC_BGEZAL: 15283 if (ctx->insn_flags & ISA_MIPS_R6) { 15284 if (rs == 0) { 15285 /* OPC_NAL, OPC_BAL */ 15286 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 15287 } else { 15288 gen_reserved_instruction(ctx); 15289 } 15290 } else { 15291 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15292 } 15293 break; 15294 case OPC_TGEI: /* REGIMM traps */ 15295 case OPC_TGEIU: 15296 case OPC_TLTI: 15297 case OPC_TLTIU: 15298 case OPC_TEQI: 15299 case OPC_TNEI: 15300 check_insn(ctx, ISA_MIPS2); 15301 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15302 gen_trap(ctx, op1, rs, -1, imm, 0); 15303 break; 15304 case OPC_SIGRIE: 15305 check_insn(ctx, ISA_MIPS_R6); 15306 gen_reserved_instruction(ctx); 15307 break; 15308 case OPC_SYNCI: 15309 check_insn(ctx, ISA_MIPS_R2); 15310 /* 15311 * Break the TB to be able to sync copied instructions 15312 * immediately. 15313 */ 15314 ctx->base.is_jmp = DISAS_STOP; 15315 break; 15316 case OPC_BPOSGE32: /* MIPS DSP branch */ 15317 #if defined(TARGET_MIPS64) 15318 case OPC_BPOSGE64: 15319 #endif 15320 check_dsp(ctx); 15321 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 15322 break; 15323 #if defined(TARGET_MIPS64) 15324 case OPC_DAHI: 15325 check_insn(ctx, ISA_MIPS_R6); 15326 check_mips_64(ctx); 15327 if (rs != 0) { 15328 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 15329 } 15330 break; 15331 case OPC_DATI: 15332 check_insn(ctx, ISA_MIPS_R6); 15333 check_mips_64(ctx); 15334 if (rs != 0) { 15335 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 15336 } 15337 break; 15338 #endif 15339 default: /* Invalid */ 15340 MIPS_INVAL("regimm"); 15341 gen_reserved_instruction(ctx); 15342 break; 15343 } 15344 break; 15345 case OPC_CP0: 15346 check_cp0_enabled(ctx); 15347 op1 = MASK_CP0(ctx->opcode); 15348 switch (op1) { 15349 case OPC_MFC0: 15350 case OPC_MTC0: 15351 case OPC_MFTR: 15352 case OPC_MTTR: 15353 case OPC_MFHC0: 15354 case OPC_MTHC0: 15355 #if defined(TARGET_MIPS64) 15356 case OPC_DMFC0: 15357 case OPC_DMTC0: 15358 #endif 15359 #ifndef CONFIG_USER_ONLY 15360 gen_cp0(env, ctx, op1, rt, rd); 15361 #endif /* !CONFIG_USER_ONLY */ 15362 break; 15363 case OPC_C0: 15364 case OPC_C0_1: 15365 case OPC_C0_2: 15366 case OPC_C0_3: 15367 case OPC_C0_4: 15368 case OPC_C0_5: 15369 case OPC_C0_6: 15370 case OPC_C0_7: 15371 case OPC_C0_8: 15372 case OPC_C0_9: 15373 case OPC_C0_A: 15374 case OPC_C0_B: 15375 case OPC_C0_C: 15376 case OPC_C0_D: 15377 case OPC_C0_E: 15378 case OPC_C0_F: 15379 #ifndef CONFIG_USER_ONLY 15380 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 15381 #endif /* !CONFIG_USER_ONLY */ 15382 break; 15383 case OPC_MFMC0: 15384 #ifndef CONFIG_USER_ONLY 15385 { 15386 uint32_t op2; 15387 TCGv t0 = tcg_temp_new(); 15388 15389 op2 = MASK_MFMC0(ctx->opcode); 15390 switch (op2) { 15391 case OPC_DMT: 15392 check_cp0_mt(ctx); 15393 gen_helper_dmt(t0); 15394 gen_store_gpr(t0, rt); 15395 break; 15396 case OPC_EMT: 15397 check_cp0_mt(ctx); 15398 gen_helper_emt(t0); 15399 gen_store_gpr(t0, rt); 15400 break; 15401 case OPC_DVPE: 15402 check_cp0_mt(ctx); 15403 gen_helper_dvpe(t0, cpu_env); 15404 gen_store_gpr(t0, rt); 15405 break; 15406 case OPC_EVPE: 15407 check_cp0_mt(ctx); 15408 gen_helper_evpe(t0, cpu_env); 15409 gen_store_gpr(t0, rt); 15410 break; 15411 case OPC_DVP: 15412 check_insn(ctx, ISA_MIPS_R6); 15413 if (ctx->vp) { 15414 gen_helper_dvp(t0, cpu_env); 15415 gen_store_gpr(t0, rt); 15416 } 15417 break; 15418 case OPC_EVP: 15419 check_insn(ctx, ISA_MIPS_R6); 15420 if (ctx->vp) { 15421 gen_helper_evp(t0, cpu_env); 15422 gen_store_gpr(t0, rt); 15423 } 15424 break; 15425 case OPC_DI: 15426 check_insn(ctx, ISA_MIPS_R2); 15427 save_cpu_state(ctx, 1); 15428 gen_helper_di(t0, cpu_env); 15429 gen_store_gpr(t0, rt); 15430 /* 15431 * Stop translation as we may have switched 15432 * the execution mode. 15433 */ 15434 ctx->base.is_jmp = DISAS_STOP; 15435 break; 15436 case OPC_EI: 15437 check_insn(ctx, ISA_MIPS_R2); 15438 save_cpu_state(ctx, 1); 15439 gen_helper_ei(t0, cpu_env); 15440 gen_store_gpr(t0, rt); 15441 /* 15442 * DISAS_STOP isn't sufficient, we need to ensure we break 15443 * out of translated code to check for pending interrupts. 15444 */ 15445 gen_save_pc(ctx->base.pc_next + 4); 15446 ctx->base.is_jmp = DISAS_EXIT; 15447 break; 15448 default: /* Invalid */ 15449 MIPS_INVAL("mfmc0"); 15450 gen_reserved_instruction(ctx); 15451 break; 15452 } 15453 tcg_temp_free(t0); 15454 } 15455 #endif /* !CONFIG_USER_ONLY */ 15456 break; 15457 case OPC_RDPGPR: 15458 check_insn(ctx, ISA_MIPS_R2); 15459 gen_load_srsgpr(rt, rd); 15460 break; 15461 case OPC_WRPGPR: 15462 check_insn(ctx, ISA_MIPS_R2); 15463 gen_store_srsgpr(rt, rd); 15464 break; 15465 default: 15466 MIPS_INVAL("cp0"); 15467 gen_reserved_instruction(ctx); 15468 break; 15469 } 15470 break; 15471 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 15472 if (ctx->insn_flags & ISA_MIPS_R6) { 15473 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 15474 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15475 } else { 15476 /* OPC_ADDI */ 15477 /* Arithmetic with immediate opcode */ 15478 gen_arith_imm(ctx, op, rt, rs, imm); 15479 } 15480 break; 15481 case OPC_ADDIU: 15482 gen_arith_imm(ctx, op, rt, rs, imm); 15483 break; 15484 case OPC_SLTI: /* Set on less than with immediate opcode */ 15485 case OPC_SLTIU: 15486 gen_slt_imm(ctx, op, rt, rs, imm); 15487 break; 15488 case OPC_ANDI: /* Arithmetic with immediate opcode */ 15489 case OPC_LUI: /* OPC_AUI */ 15490 case OPC_ORI: 15491 case OPC_XORI: 15492 gen_logic_imm(ctx, op, rt, rs, imm); 15493 break; 15494 case OPC_J: /* Jump */ 15495 case OPC_JAL: 15496 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15497 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15498 break; 15499 /* Branch */ 15500 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 15501 if (ctx->insn_flags & ISA_MIPS_R6) { 15502 if (rt == 0) { 15503 gen_reserved_instruction(ctx); 15504 break; 15505 } 15506 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 15507 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15508 } else { 15509 /* OPC_BLEZL */ 15510 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15511 } 15512 break; 15513 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 15514 if (ctx->insn_flags & ISA_MIPS_R6) { 15515 if (rt == 0) { 15516 gen_reserved_instruction(ctx); 15517 break; 15518 } 15519 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 15520 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15521 } else { 15522 /* OPC_BGTZL */ 15523 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15524 } 15525 break; 15526 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 15527 if (rt == 0) { 15528 /* OPC_BLEZ */ 15529 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15530 } else { 15531 check_insn(ctx, ISA_MIPS_R6); 15532 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 15533 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15534 } 15535 break; 15536 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 15537 if (rt == 0) { 15538 /* OPC_BGTZ */ 15539 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15540 } else { 15541 check_insn(ctx, ISA_MIPS_R6); 15542 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 15543 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15544 } 15545 break; 15546 case OPC_BEQL: 15547 case OPC_BNEL: 15548 check_insn(ctx, ISA_MIPS2); 15549 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15550 /* Fallthrough */ 15551 case OPC_BEQ: 15552 case OPC_BNE: 15553 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15554 break; 15555 case OPC_LL: /* Load and stores */ 15556 check_insn(ctx, ISA_MIPS2); 15557 if (ctx->insn_flags & INSN_R5900) { 15558 check_insn_opc_user_only(ctx, INSN_R5900); 15559 } 15560 /* Fallthrough */ 15561 case OPC_LWL: 15562 case OPC_LWR: 15563 case OPC_LB: 15564 case OPC_LH: 15565 case OPC_LW: 15566 case OPC_LWPC: 15567 case OPC_LBU: 15568 case OPC_LHU: 15569 gen_ld(ctx, op, rt, rs, imm); 15570 break; 15571 case OPC_SWL: 15572 case OPC_SWR: 15573 case OPC_SB: 15574 case OPC_SH: 15575 case OPC_SW: 15576 gen_st(ctx, op, rt, rs, imm); 15577 break; 15578 case OPC_SC: 15579 check_insn(ctx, ISA_MIPS2); 15580 if (ctx->insn_flags & INSN_R5900) { 15581 check_insn_opc_user_only(ctx, INSN_R5900); 15582 } 15583 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 15584 break; 15585 case OPC_CACHE: 15586 check_cp0_enabled(ctx); 15587 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 15588 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15589 gen_cache_operation(ctx, rt, rs, imm); 15590 } 15591 /* Treat as NOP. */ 15592 break; 15593 case OPC_PREF: 15594 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 15595 /* Treat as NOP. */ 15596 break; 15597 15598 /* Floating point (COP1). */ 15599 case OPC_LWC1: 15600 case OPC_LDC1: 15601 case OPC_SWC1: 15602 case OPC_SDC1: 15603 gen_cop1_ldst(ctx, op, rt, rs, imm); 15604 break; 15605 15606 case OPC_CP1: 15607 op1 = MASK_CP1(ctx->opcode); 15608 15609 switch (op1) { 15610 case OPC_MFHC1: 15611 case OPC_MTHC1: 15612 check_cp1_enabled(ctx); 15613 check_insn(ctx, ISA_MIPS_R2); 15614 /* fall through */ 15615 case OPC_MFC1: 15616 case OPC_CFC1: 15617 case OPC_MTC1: 15618 case OPC_CTC1: 15619 check_cp1_enabled(ctx); 15620 gen_cp1(ctx, op1, rt, rd); 15621 break; 15622 #if defined(TARGET_MIPS64) 15623 case OPC_DMFC1: 15624 case OPC_DMTC1: 15625 check_cp1_enabled(ctx); 15626 check_insn(ctx, ISA_MIPS3); 15627 check_mips_64(ctx); 15628 gen_cp1(ctx, op1, rt, rd); 15629 break; 15630 #endif 15631 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15632 check_cp1_enabled(ctx); 15633 if (ctx->insn_flags & ISA_MIPS_R6) { 15634 /* OPC_BC1EQZ */ 15635 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15636 rt, imm << 2, 4); 15637 } else { 15638 /* OPC_BC1ANY2 */ 15639 check_cop1x(ctx); 15640 check_insn(ctx, ASE_MIPS3D); 15641 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15642 (rt >> 2) & 0x7, imm << 2); 15643 } 15644 break; 15645 case OPC_BC1NEZ: 15646 check_cp1_enabled(ctx); 15647 check_insn(ctx, ISA_MIPS_R6); 15648 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15649 rt, imm << 2, 4); 15650 break; 15651 case OPC_BC1ANY4: 15652 check_cp1_enabled(ctx); 15653 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15654 check_cop1x(ctx); 15655 check_insn(ctx, ASE_MIPS3D); 15656 /* fall through */ 15657 case OPC_BC1: 15658 check_cp1_enabled(ctx); 15659 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15660 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15661 (rt >> 2) & 0x7, imm << 2); 15662 break; 15663 case OPC_PS_FMT: 15664 check_ps(ctx); 15665 /* fall through */ 15666 case OPC_S_FMT: 15667 case OPC_D_FMT: 15668 check_cp1_enabled(ctx); 15669 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15670 (imm >> 8) & 0x7); 15671 break; 15672 case OPC_W_FMT: 15673 case OPC_L_FMT: 15674 { 15675 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15676 check_cp1_enabled(ctx); 15677 if (ctx->insn_flags & ISA_MIPS_R6) { 15678 switch (r6_op) { 15679 case R6_OPC_CMP_AF_S: 15680 case R6_OPC_CMP_UN_S: 15681 case R6_OPC_CMP_EQ_S: 15682 case R6_OPC_CMP_UEQ_S: 15683 case R6_OPC_CMP_LT_S: 15684 case R6_OPC_CMP_ULT_S: 15685 case R6_OPC_CMP_LE_S: 15686 case R6_OPC_CMP_ULE_S: 15687 case R6_OPC_CMP_SAF_S: 15688 case R6_OPC_CMP_SUN_S: 15689 case R6_OPC_CMP_SEQ_S: 15690 case R6_OPC_CMP_SEUQ_S: 15691 case R6_OPC_CMP_SLT_S: 15692 case R6_OPC_CMP_SULT_S: 15693 case R6_OPC_CMP_SLE_S: 15694 case R6_OPC_CMP_SULE_S: 15695 case R6_OPC_CMP_OR_S: 15696 case R6_OPC_CMP_UNE_S: 15697 case R6_OPC_CMP_NE_S: 15698 case R6_OPC_CMP_SOR_S: 15699 case R6_OPC_CMP_SUNE_S: 15700 case R6_OPC_CMP_SNE_S: 15701 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15702 break; 15703 case R6_OPC_CMP_AF_D: 15704 case R6_OPC_CMP_UN_D: 15705 case R6_OPC_CMP_EQ_D: 15706 case R6_OPC_CMP_UEQ_D: 15707 case R6_OPC_CMP_LT_D: 15708 case R6_OPC_CMP_ULT_D: 15709 case R6_OPC_CMP_LE_D: 15710 case R6_OPC_CMP_ULE_D: 15711 case R6_OPC_CMP_SAF_D: 15712 case R6_OPC_CMP_SUN_D: 15713 case R6_OPC_CMP_SEQ_D: 15714 case R6_OPC_CMP_SEUQ_D: 15715 case R6_OPC_CMP_SLT_D: 15716 case R6_OPC_CMP_SULT_D: 15717 case R6_OPC_CMP_SLE_D: 15718 case R6_OPC_CMP_SULE_D: 15719 case R6_OPC_CMP_OR_D: 15720 case R6_OPC_CMP_UNE_D: 15721 case R6_OPC_CMP_NE_D: 15722 case R6_OPC_CMP_SOR_D: 15723 case R6_OPC_CMP_SUNE_D: 15724 case R6_OPC_CMP_SNE_D: 15725 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15726 break; 15727 default: 15728 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15729 rt, rd, sa, (imm >> 8) & 0x7); 15730 15731 break; 15732 } 15733 } else { 15734 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15735 (imm >> 8) & 0x7); 15736 } 15737 break; 15738 } 15739 default: 15740 MIPS_INVAL("cp1"); 15741 gen_reserved_instruction(ctx); 15742 break; 15743 } 15744 break; 15745 15746 /* Compact branches [R6] and COP2 [non-R6] */ 15747 case OPC_BC: /* OPC_LWC2 */ 15748 case OPC_BALC: /* OPC_SWC2 */ 15749 if (ctx->insn_flags & ISA_MIPS_R6) { 15750 /* OPC_BC, OPC_BALC */ 15751 gen_compute_compact_branch(ctx, op, 0, 0, 15752 sextract32(ctx->opcode << 2, 0, 28)); 15753 } else if (ctx->insn_flags & ASE_LEXT) { 15754 gen_loongson_lswc2(ctx, rt, rs, rd); 15755 } else { 15756 /* OPC_LWC2, OPC_SWC2 */ 15757 /* COP2: Not implemented. */ 15758 generate_exception_err(ctx, EXCP_CpU, 2); 15759 } 15760 break; 15761 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15762 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15763 if (ctx->insn_flags & ISA_MIPS_R6) { 15764 if (rs != 0) { 15765 /* OPC_BEQZC, OPC_BNEZC */ 15766 gen_compute_compact_branch(ctx, op, rs, 0, 15767 sextract32(ctx->opcode << 2, 0, 23)); 15768 } else { 15769 /* OPC_JIC, OPC_JIALC */ 15770 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15771 } 15772 } else if (ctx->insn_flags & ASE_LEXT) { 15773 gen_loongson_lsdc2(ctx, rt, rs, rd); 15774 } else { 15775 /* OPC_LWC2, OPC_SWC2 */ 15776 /* COP2: Not implemented. */ 15777 generate_exception_err(ctx, EXCP_CpU, 2); 15778 } 15779 break; 15780 case OPC_CP2: 15781 check_insn(ctx, ASE_LMMI); 15782 /* Note that these instructions use different fields. */ 15783 gen_loongson_multimedia(ctx, sa, rd, rt); 15784 break; 15785 15786 case OPC_CP3: 15787 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15788 check_cp1_enabled(ctx); 15789 op1 = MASK_CP3(ctx->opcode); 15790 switch (op1) { 15791 case OPC_LUXC1: 15792 case OPC_SUXC1: 15793 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15794 /* Fallthrough */ 15795 case OPC_LWXC1: 15796 case OPC_LDXC1: 15797 case OPC_SWXC1: 15798 case OPC_SDXC1: 15799 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15800 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15801 break; 15802 case OPC_PREFX: 15803 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15804 /* Treat as NOP. */ 15805 break; 15806 case OPC_ALNV_PS: 15807 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15808 /* Fallthrough */ 15809 case OPC_MADD_S: 15810 case OPC_MADD_D: 15811 case OPC_MADD_PS: 15812 case OPC_MSUB_S: 15813 case OPC_MSUB_D: 15814 case OPC_MSUB_PS: 15815 case OPC_NMADD_S: 15816 case OPC_NMADD_D: 15817 case OPC_NMADD_PS: 15818 case OPC_NMSUB_S: 15819 case OPC_NMSUB_D: 15820 case OPC_NMSUB_PS: 15821 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15822 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15823 break; 15824 default: 15825 MIPS_INVAL("cp3"); 15826 gen_reserved_instruction(ctx); 15827 break; 15828 } 15829 } else { 15830 generate_exception_err(ctx, EXCP_CpU, 1); 15831 } 15832 break; 15833 15834 #if defined(TARGET_MIPS64) 15835 /* MIPS64 opcodes */ 15836 case OPC_LLD: 15837 if (ctx->insn_flags & INSN_R5900) { 15838 check_insn_opc_user_only(ctx, INSN_R5900); 15839 } 15840 /* fall through */ 15841 case OPC_LDL: 15842 case OPC_LDR: 15843 case OPC_LWU: 15844 case OPC_LD: 15845 check_insn(ctx, ISA_MIPS3); 15846 check_mips_64(ctx); 15847 gen_ld(ctx, op, rt, rs, imm); 15848 break; 15849 case OPC_SDL: 15850 case OPC_SDR: 15851 case OPC_SD: 15852 check_insn(ctx, ISA_MIPS3); 15853 check_mips_64(ctx); 15854 gen_st(ctx, op, rt, rs, imm); 15855 break; 15856 case OPC_SCD: 15857 check_insn(ctx, ISA_MIPS3); 15858 if (ctx->insn_flags & INSN_R5900) { 15859 check_insn_opc_user_only(ctx, INSN_R5900); 15860 } 15861 check_mips_64(ctx); 15862 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false); 15863 break; 15864 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 15865 if (ctx->insn_flags & ISA_MIPS_R6) { 15866 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 15867 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15868 } else { 15869 /* OPC_DADDI */ 15870 check_insn(ctx, ISA_MIPS3); 15871 check_mips_64(ctx); 15872 gen_arith_imm(ctx, op, rt, rs, imm); 15873 } 15874 break; 15875 case OPC_DADDIU: 15876 check_insn(ctx, ISA_MIPS3); 15877 check_mips_64(ctx); 15878 gen_arith_imm(ctx, op, rt, rs, imm); 15879 break; 15880 #else 15881 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 15882 if (ctx->insn_flags & ISA_MIPS_R6) { 15883 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15884 } else { 15885 MIPS_INVAL("major opcode"); 15886 gen_reserved_instruction(ctx); 15887 } 15888 break; 15889 #endif 15890 case OPC_DAUI: /* OPC_JALX */ 15891 if (ctx->insn_flags & ISA_MIPS_R6) { 15892 #if defined(TARGET_MIPS64) 15893 /* OPC_DAUI */ 15894 check_mips_64(ctx); 15895 if (rs == 0) { 15896 generate_exception(ctx, EXCP_RI); 15897 } else if (rt != 0) { 15898 TCGv t0 = tcg_temp_new(); 15899 gen_load_gpr(t0, rs); 15900 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 15901 tcg_temp_free(t0); 15902 } 15903 #else 15904 gen_reserved_instruction(ctx); 15905 MIPS_INVAL("major opcode"); 15906 #endif 15907 } else { 15908 /* OPC_JALX */ 15909 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 15910 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15911 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15912 } 15913 break; 15914 case OPC_MDMX: 15915 /* MDMX: Not implemented. */ 15916 break; 15917 case OPC_PCREL: 15918 check_insn(ctx, ISA_MIPS_R6); 15919 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15920 break; 15921 default: /* Invalid */ 15922 MIPS_INVAL("major opcode"); 15923 return false; 15924 } 15925 return true; 15926 } 15927 15928 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15929 { 15930 /* make sure instructions are on a word boundary */ 15931 if (ctx->base.pc_next & 0x3) { 15932 env->CP0_BadVAddr = ctx->base.pc_next; 15933 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15934 return; 15935 } 15936 15937 /* Handle blikely not taken case */ 15938 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15939 TCGLabel *l1 = gen_new_label(); 15940 15941 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15942 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15943 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15944 gen_set_label(l1); 15945 } 15946 15947 /* Transition to the auto-generated decoder. */ 15948 15949 /* Vendor specific extensions */ 15950 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15951 return; 15952 } 15953 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15954 return; 15955 } 15956 #if defined(TARGET_MIPS64) 15957 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15958 return; 15959 } 15960 #endif 15961 15962 /* ISA extensions */ 15963 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15964 return; 15965 } 15966 15967 /* ISA (from latest to oldest) */ 15968 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15969 return; 15970 } 15971 15972 if (decode_opc_legacy(env, ctx)) { 15973 return; 15974 } 15975 15976 gen_reserved_instruction(ctx); 15977 } 15978 15979 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15980 { 15981 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15982 CPUMIPSState *env = cs->env_ptr; 15983 15984 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15985 ctx->saved_pc = -1; 15986 ctx->insn_flags = env->insn_flags; 15987 ctx->CP0_Config0 = env->CP0_Config0; 15988 ctx->CP0_Config1 = env->CP0_Config1; 15989 ctx->CP0_Config2 = env->CP0_Config2; 15990 ctx->CP0_Config3 = env->CP0_Config3; 15991 ctx->CP0_Config5 = env->CP0_Config5; 15992 ctx->btarget = 0; 15993 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15994 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15995 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15996 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15997 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15998 ctx->PAMask = env->PAMask; 15999 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 16000 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 16001 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 16002 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 16003 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 16004 /* Restore delay slot state from the tb context. */ 16005 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 16006 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 16007 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 16008 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 16009 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 16010 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 16011 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 16012 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 16013 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 16014 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 16015 restore_cpu_state(env, ctx); 16016 #ifdef CONFIG_USER_ONLY 16017 ctx->mem_idx = MIPS_HFLAG_UM; 16018 #else 16019 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 16020 #endif 16021 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 16022 (ctx->insn_flags & (ISA_MIPS_R6 | 16023 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 16024 16025 /* 16026 * Execute a branch and its delay slot as a single instruction. 16027 * This is what GDB expects and is consistent with what the 16028 * hardware does (e.g. if a delay slot instruction faults, the 16029 * reported PC is the PC of the branch). 16030 */ 16031 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) { 16032 ctx->base.max_insns = 2; 16033 } 16034 16035 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 16036 ctx->hflags); 16037 } 16038 16039 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 16040 { 16041 } 16042 16043 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 16044 { 16045 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16046 16047 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 16048 ctx->btarget); 16049 } 16050 16051 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 16052 { 16053 CPUMIPSState *env = cs->env_ptr; 16054 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16055 int insn_bytes; 16056 int is_slot; 16057 16058 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 16059 if (ctx->insn_flags & ISA_NANOMIPS32) { 16060 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16061 insn_bytes = decode_isa_nanomips(env, ctx); 16062 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 16063 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 16064 insn_bytes = 4; 16065 decode_opc(env, ctx); 16066 } else if (ctx->insn_flags & ASE_MICROMIPS) { 16067 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16068 insn_bytes = decode_isa_micromips(env, ctx); 16069 } else if (ctx->insn_flags & ASE_MIPS16) { 16070 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 16071 insn_bytes = decode_ase_mips16e(env, ctx); 16072 } else { 16073 gen_reserved_instruction(ctx); 16074 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 16075 return; 16076 } 16077 16078 if (ctx->hflags & MIPS_HFLAG_BMASK) { 16079 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 16080 MIPS_HFLAG_FBNSLOT))) { 16081 /* 16082 * Force to generate branch as there is neither delay nor 16083 * forbidden slot. 16084 */ 16085 is_slot = 1; 16086 } 16087 if ((ctx->hflags & MIPS_HFLAG_M16) && 16088 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 16089 /* 16090 * Force to generate branch as microMIPS R6 doesn't restrict 16091 * branches in the forbidden slot. 16092 */ 16093 is_slot = 1; 16094 } 16095 } 16096 if (is_slot) { 16097 gen_branch(ctx, insn_bytes); 16098 } 16099 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 16100 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 16101 } 16102 ctx->base.pc_next += insn_bytes; 16103 16104 if (ctx->base.is_jmp != DISAS_NEXT) { 16105 return; 16106 } 16107 16108 /* 16109 * End the TB on (most) page crossings. 16110 * See mips_tr_init_disas_context about single-stepping a branch 16111 * together with its delay slot. 16112 */ 16113 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 16114 && !ctx->base.singlestep_enabled) { 16115 ctx->base.is_jmp = DISAS_TOO_MANY; 16116 } 16117 } 16118 16119 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 16120 { 16121 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16122 16123 switch (ctx->base.is_jmp) { 16124 case DISAS_STOP: 16125 gen_save_pc(ctx->base.pc_next); 16126 tcg_gen_lookup_and_goto_ptr(); 16127 break; 16128 case DISAS_NEXT: 16129 case DISAS_TOO_MANY: 16130 save_cpu_state(ctx, 0); 16131 gen_goto_tb(ctx, 0, ctx->base.pc_next); 16132 break; 16133 case DISAS_EXIT: 16134 tcg_gen_exit_tb(NULL, 0); 16135 break; 16136 case DISAS_NORETURN: 16137 break; 16138 default: 16139 g_assert_not_reached(); 16140 } 16141 } 16142 16143 static void mips_tr_disas_log(const DisasContextBase *dcbase, 16144 CPUState *cs, FILE *logfile) 16145 { 16146 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first)); 16147 target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size); 16148 } 16149 16150 static const TranslatorOps mips_tr_ops = { 16151 .init_disas_context = mips_tr_init_disas_context, 16152 .tb_start = mips_tr_tb_start, 16153 .insn_start = mips_tr_insn_start, 16154 .translate_insn = mips_tr_translate_insn, 16155 .tb_stop = mips_tr_tb_stop, 16156 .disas_log = mips_tr_disas_log, 16157 }; 16158 16159 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, 16160 target_ulong pc, void *host_pc) 16161 { 16162 DisasContext ctx; 16163 16164 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 16165 } 16166 16167 void mips_tcg_init(void) 16168 { 16169 int i; 16170 16171 cpu_gpr[0] = NULL; 16172 for (i = 1; i < 32; i++) 16173 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 16174 offsetof(CPUMIPSState, 16175 active_tc.gpr[i]), 16176 regnames[i]); 16177 #if defined(TARGET_MIPS64) 16178 cpu_gpr_hi[0] = NULL; 16179 16180 for (unsigned i = 1; i < 32; i++) { 16181 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 16182 16183 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 16184 offsetof(CPUMIPSState, 16185 active_tc.gpr_hi[i]), 16186 rname); 16187 } 16188 #endif /* !TARGET_MIPS64 */ 16189 for (i = 0; i < 32; i++) { 16190 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 16191 16192 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 16193 } 16194 msa_translate_init(); 16195 cpu_PC = tcg_global_mem_new(cpu_env, 16196 offsetof(CPUMIPSState, active_tc.PC), "PC"); 16197 for (i = 0; i < MIPS_DSP_ACC; i++) { 16198 cpu_HI[i] = tcg_global_mem_new(cpu_env, 16199 offsetof(CPUMIPSState, active_tc.HI[i]), 16200 regnames_HI[i]); 16201 cpu_LO[i] = tcg_global_mem_new(cpu_env, 16202 offsetof(CPUMIPSState, active_tc.LO[i]), 16203 regnames_LO[i]); 16204 } 16205 cpu_dspctrl = tcg_global_mem_new(cpu_env, 16206 offsetof(CPUMIPSState, 16207 active_tc.DSPControl), 16208 "DSPControl"); 16209 bcond = tcg_global_mem_new(cpu_env, 16210 offsetof(CPUMIPSState, bcond), "bcond"); 16211 btarget = tcg_global_mem_new(cpu_env, 16212 offsetof(CPUMIPSState, btarget), "btarget"); 16213 hflags = tcg_global_mem_new_i32(cpu_env, 16214 offsetof(CPUMIPSState, hflags), "hflags"); 16215 16216 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 16217 offsetof(CPUMIPSState, active_fpu.fcr0), 16218 "fcr0"); 16219 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 16220 offsetof(CPUMIPSState, active_fpu.fcr31), 16221 "fcr31"); 16222 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 16223 "lladdr"); 16224 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 16225 "llval"); 16226 16227 if (TARGET_LONG_BITS == 32) { 16228 mxu_translate_init(); 16229 } 16230 } 16231 16232 void mips_restore_state_to_opc(CPUState *cs, 16233 const TranslationBlock *tb, 16234 const uint64_t *data) 16235 { 16236 MIPSCPU *cpu = MIPS_CPU(cs); 16237 CPUMIPSState *env = &cpu->env; 16238 16239 env->active_tc.PC = data[0]; 16240 env->hflags &= ~MIPS_HFLAG_BMASK; 16241 env->hflags |= data[1]; 16242 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 16243 case MIPS_HFLAG_BR: 16244 break; 16245 case MIPS_HFLAG_BC: 16246 case MIPS_HFLAG_BL: 16247 case MIPS_HFLAG_B: 16248 env->btarget = data[2]; 16249 break; 16250 } 16251 } 16252