translate.c revision fed223d2bab55eda155e3463b9cb6966e69dd73c
1/* 2 * MIPS32 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 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22#include <stdarg.h> 23#include <stdlib.h> 24#include <stdio.h> 25#include <string.h> 26#include <inttypes.h> 27 28#include "cpu.h" 29#include "disas/disas.h" 30#include "tcg-op.h" 31#include "qemu-common.h" 32 33#include "helper.h" 34#define GEN_HELPER 1 35#include "helper.h" 36 37//#define MIPS_DEBUG_DISAS 38//#define MIPS_DEBUG_SIGN_EXTENSIONS 39 40/* MIPS major opcodes */ 41#define MASK_OP_MAJOR(op) (op & (0x3F << 26)) 42 43enum { 44 /* indirect opcode tables */ 45 OPC_SPECIAL = (0x00 << 26), 46 OPC_REGIMM = (0x01 << 26), 47 OPC_CP0 = (0x10 << 26), 48 OPC_CP1 = (0x11 << 26), 49 OPC_CP2 = (0x12 << 26), 50 OPC_CP3 = (0x13 << 26), 51 OPC_SPECIAL2 = (0x1C << 26), 52 OPC_SPECIAL3 = (0x1F << 26), 53 /* arithmetic with immediate */ 54 OPC_ADDI = (0x08 << 26), 55 OPC_ADDIU = (0x09 << 26), 56 OPC_SLTI = (0x0A << 26), 57 OPC_SLTIU = (0x0B << 26), 58 /* logic with immediate */ 59 OPC_ANDI = (0x0C << 26), 60 OPC_ORI = (0x0D << 26), 61 OPC_XORI = (0x0E << 26), 62 OPC_LUI = (0x0F << 26), 63 /* arithmetic with immediate */ 64 OPC_DADDI = (0x18 << 26), 65 OPC_DADDIU = (0x19 << 26), 66 /* Jump and branches */ 67 OPC_J = (0x02 << 26), 68 OPC_JAL = (0x03 << 26), 69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 70 OPC_BEQL = (0x14 << 26), 71 OPC_BNE = (0x05 << 26), 72 OPC_BNEL = (0x15 << 26), 73 OPC_BLEZ = (0x06 << 26), 74 OPC_BLEZL = (0x16 << 26), 75 OPC_BGTZ = (0x07 << 26), 76 OPC_BGTZL = (0x17 << 26), 77 OPC_JALX = (0x1D << 26), /* MIPS 16 only */ 78 /* Load and stores */ 79 OPC_LDL = (0x1A << 26), 80 OPC_LDR = (0x1B << 26), 81 OPC_LB = (0x20 << 26), 82 OPC_LH = (0x21 << 26), 83 OPC_LWL = (0x22 << 26), 84 OPC_LW = (0x23 << 26), 85 OPC_LBU = (0x24 << 26), 86 OPC_LHU = (0x25 << 26), 87 OPC_LWR = (0x26 << 26), 88 OPC_LWU = (0x27 << 26), 89 OPC_SB = (0x28 << 26), 90 OPC_SH = (0x29 << 26), 91 OPC_SWL = (0x2A << 26), 92 OPC_SW = (0x2B << 26), 93 OPC_SDL = (0x2C << 26), 94 OPC_SDR = (0x2D << 26), 95 OPC_SWR = (0x2E << 26), 96 OPC_LL = (0x30 << 26), 97 OPC_LLD = (0x34 << 26), 98 OPC_LD = (0x37 << 26), 99 OPC_SC = (0x38 << 26), 100 OPC_SCD = (0x3C << 26), 101 OPC_SD = (0x3F << 26), 102 /* Floating point load/store */ 103 OPC_LWC1 = (0x31 << 26), 104 OPC_LWC2 = (0x32 << 26), 105 OPC_LDC1 = (0x35 << 26), 106 OPC_LDC2 = (0x36 << 26), 107 OPC_SWC1 = (0x39 << 26), 108 OPC_SWC2 = (0x3A << 26), 109 OPC_SDC1 = (0x3D << 26), 110 OPC_SDC2 = (0x3E << 26), 111 /* MDMX ASE specific */ 112 OPC_MDMX = (0x1E << 26), 113 /* Cache and prefetch */ 114 OPC_CACHE = (0x2F << 26), 115 OPC_PREF = (0x33 << 26), 116 /* Reserved major opcode */ 117 OPC_MAJOR3B_RESERVED = (0x3B << 26), 118}; 119 120/* MIPS special opcodes */ 121#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F) 122 123enum { 124 /* Shifts */ 125 OPC_SLL = 0x00 | OPC_SPECIAL, 126 /* NOP is SLL r0, r0, 0 */ 127 /* SSNOP is SLL r0, r0, 1 */ 128 /* EHB is SLL r0, r0, 3 */ 129 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 130 OPC_SRA = 0x03 | OPC_SPECIAL, 131 OPC_SLLV = 0x04 | OPC_SPECIAL, 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 133 OPC_SRAV = 0x07 | OPC_SPECIAL, 134 OPC_DSLLV = 0x14 | OPC_SPECIAL, 135 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 136 OPC_DSRAV = 0x17 | OPC_SPECIAL, 137 OPC_DSLL = 0x38 | OPC_SPECIAL, 138 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 139 OPC_DSRA = 0x3B | OPC_SPECIAL, 140 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 141 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 142 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 143 /* Multiplication / division */ 144 OPC_MULT = 0x18 | OPC_SPECIAL, 145 OPC_MULTU = 0x19 | OPC_SPECIAL, 146 OPC_DIV = 0x1A | OPC_SPECIAL, 147 OPC_DIVU = 0x1B | OPC_SPECIAL, 148 OPC_DMULT = 0x1C | OPC_SPECIAL, 149 OPC_DMULTU = 0x1D | OPC_SPECIAL, 150 OPC_DDIV = 0x1E | OPC_SPECIAL, 151 OPC_DDIVU = 0x1F | OPC_SPECIAL, 152 /* 2 registers arithmetic / logic */ 153 OPC_ADD = 0x20 | OPC_SPECIAL, 154 OPC_ADDU = 0x21 | OPC_SPECIAL, 155 OPC_SUB = 0x22 | OPC_SPECIAL, 156 OPC_SUBU = 0x23 | OPC_SPECIAL, 157 OPC_AND = 0x24 | OPC_SPECIAL, 158 OPC_OR = 0x25 | OPC_SPECIAL, 159 OPC_XOR = 0x26 | OPC_SPECIAL, 160 OPC_NOR = 0x27 | OPC_SPECIAL, 161 OPC_SLT = 0x2A | OPC_SPECIAL, 162 OPC_SLTU = 0x2B | OPC_SPECIAL, 163 OPC_DADD = 0x2C | OPC_SPECIAL, 164 OPC_DADDU = 0x2D | OPC_SPECIAL, 165 OPC_DSUB = 0x2E | OPC_SPECIAL, 166 OPC_DSUBU = 0x2F | OPC_SPECIAL, 167 /* Jumps */ 168 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 169 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 170 /* Traps */ 171 OPC_TGE = 0x30 | OPC_SPECIAL, 172 OPC_TGEU = 0x31 | OPC_SPECIAL, 173 OPC_TLT = 0x32 | OPC_SPECIAL, 174 OPC_TLTU = 0x33 | OPC_SPECIAL, 175 OPC_TEQ = 0x34 | OPC_SPECIAL, 176 OPC_TNE = 0x36 | OPC_SPECIAL, 177 /* HI / LO registers load & stores */ 178 OPC_MFHI = 0x10 | OPC_SPECIAL, 179 OPC_MTHI = 0x11 | OPC_SPECIAL, 180 OPC_MFLO = 0x12 | OPC_SPECIAL, 181 OPC_MTLO = 0x13 | OPC_SPECIAL, 182 /* Conditional moves */ 183 OPC_MOVZ = 0x0A | OPC_SPECIAL, 184 OPC_MOVN = 0x0B | OPC_SPECIAL, 185 186 OPC_MOVCI = 0x01 | OPC_SPECIAL, 187 188 /* Special */ 189 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 190 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 191 OPC_BREAK = 0x0D | OPC_SPECIAL, 192 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 193 OPC_SYNC = 0x0F | OPC_SPECIAL, 194 195 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL, 196 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 197 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 198 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL, 199 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL, 200 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 201 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 202}; 203 204/* Multiplication variants of the vr54xx. */ 205#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6)) 206 207enum { 208 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, 209 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, 210 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, 211 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, 212 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, 213 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, 214 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, 215 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, 216 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, 217 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, 218 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, 219 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, 220 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, 221 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, 222}; 223 224/* REGIMM (rt field) opcodes */ 225#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16)) 226 227enum { 228 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 229 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 230 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 231 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 232 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 233 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 234 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 235 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 236 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 237 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 238 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 239 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 240 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 241 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 242 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 243}; 244 245/* Special2 opcodes */ 246#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F) 247 248enum { 249 /* Multiply & xxx operations */ 250 OPC_MADD = 0x00 | OPC_SPECIAL2, 251 OPC_MADDU = 0x01 | OPC_SPECIAL2, 252 OPC_MUL = 0x02 | OPC_SPECIAL2, 253 OPC_MSUB = 0x04 | OPC_SPECIAL2, 254 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 255 /* Misc */ 256 OPC_CLZ = 0x20 | OPC_SPECIAL2, 257 OPC_CLO = 0x21 | OPC_SPECIAL2, 258 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 259 OPC_DCLO = 0x25 | OPC_SPECIAL2, 260 /* Special */ 261 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 262}; 263 264/* Special3 opcodes */ 265#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F) 266 267enum { 268 OPC_EXT = 0x00 | OPC_SPECIAL3, 269 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 270 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 271 OPC_DEXT = 0x03 | OPC_SPECIAL3, 272 OPC_INS = 0x04 | OPC_SPECIAL3, 273 OPC_DINSM = 0x05 | OPC_SPECIAL3, 274 OPC_DINSU = 0x06 | OPC_SPECIAL3, 275 OPC_DINS = 0x07 | OPC_SPECIAL3, 276 OPC_FORK = 0x08 | OPC_SPECIAL3, 277 OPC_YIELD = 0x09 | OPC_SPECIAL3, 278 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 279 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 280 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 281}; 282 283/* BSHFL opcodes */ 284#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6)) 285 286enum { 287 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 288 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 289 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 290}; 291 292/* DBSHFL opcodes */ 293#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6)) 294 295enum { 296 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 297 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 298}; 299 300/* Coprocessor 0 (rs field) */ 301#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 302 303enum { 304 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 305 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 306 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 307 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 308 OPC_MFTR = (0x08 << 21) | OPC_CP0, 309 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 310 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 311 OPC_MTTR = (0x0C << 21) | OPC_CP0, 312 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 313 OPC_C0 = (0x10 << 21) | OPC_CP0, 314 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0, 315 OPC_C0_LAST = (0x1F << 21) | OPC_CP0, 316}; 317 318/* MFMC0 opcodes */ 319#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF) 320 321enum { 322 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 323 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 324 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 325 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 326 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 327 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 328}; 329 330/* Coprocessor 0 (with rs == C0) */ 331#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F) 332 333enum { 334 OPC_TLBR = 0x01 | OPC_C0, 335 OPC_TLBWI = 0x02 | OPC_C0, 336 OPC_TLBWR = 0x06 | OPC_C0, 337 OPC_TLBP = 0x08 | OPC_C0, 338 OPC_RFE = 0x10 | OPC_C0, 339 OPC_ERET = 0x18 | OPC_C0, 340 OPC_DERET = 0x1F | OPC_C0, 341 OPC_WAIT = 0x20 | OPC_C0, 342}; 343 344/* Coprocessor 1 (rs field) */ 345#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 346 347enum { 348 OPC_MFC1 = (0x00 << 21) | OPC_CP1, 349 OPC_DMFC1 = (0x01 << 21) | OPC_CP1, 350 OPC_CFC1 = (0x02 << 21) | OPC_CP1, 351 OPC_MFHC1 = (0x03 << 21) | OPC_CP1, 352 OPC_MTC1 = (0x04 << 21) | OPC_CP1, 353 OPC_DMTC1 = (0x05 << 21) | OPC_CP1, 354 OPC_CTC1 = (0x06 << 21) | OPC_CP1, 355 OPC_MTHC1 = (0x07 << 21) | OPC_CP1, 356 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */ 357 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1, 358 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1, 359 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */ 360 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */ 361 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */ 362 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */ 363 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */ 364 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */ 365 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */ 366}; 367 368#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F) 369#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16)) 370 371enum { 372 OPC_BC1F = (0x00 << 16) | OPC_BC1, 373 OPC_BC1T = (0x01 << 16) | OPC_BC1, 374 OPC_BC1FL = (0x02 << 16) | OPC_BC1, 375 OPC_BC1TL = (0x03 << 16) | OPC_BC1, 376}; 377 378enum { 379 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2, 380 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2, 381}; 382 383enum { 384 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4, 385 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4, 386}; 387 388#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) 389 390enum { 391 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 392 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 393 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 394 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 395 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 396 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 397 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 398 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 399 OPC_BC2 = (0x08 << 21) | OPC_CP2, 400}; 401 402#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F) 403 404enum { 405 OPC_LWXC1 = 0x00 | OPC_CP3, 406 OPC_LDXC1 = 0x01 | OPC_CP3, 407 OPC_LUXC1 = 0x05 | OPC_CP3, 408 OPC_SWXC1 = 0x08 | OPC_CP3, 409 OPC_SDXC1 = 0x09 | OPC_CP3, 410 OPC_SUXC1 = 0x0D | OPC_CP3, 411 OPC_PREFX = 0x0F | OPC_CP3, 412 OPC_ALNV_PS = 0x1E | OPC_CP3, 413 OPC_MADD_S = 0x20 | OPC_CP3, 414 OPC_MADD_D = 0x21 | OPC_CP3, 415 OPC_MADD_PS = 0x26 | OPC_CP3, 416 OPC_MSUB_S = 0x28 | OPC_CP3, 417 OPC_MSUB_D = 0x29 | OPC_CP3, 418 OPC_MSUB_PS = 0x2E | OPC_CP3, 419 OPC_NMADD_S = 0x30 | OPC_CP3, 420 OPC_NMADD_D = 0x31 | OPC_CP3, 421 OPC_NMADD_PS= 0x36 | OPC_CP3, 422 OPC_NMSUB_S = 0x38 | OPC_CP3, 423 OPC_NMSUB_D = 0x39 | OPC_CP3, 424 OPC_NMSUB_PS= 0x3E | OPC_CP3, 425}; 426 427/* global register indices */ 428static TCGv_ptr cpu_env; 429static TCGv cpu_gpr[32], cpu_PC; 430static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC]; 431static TCGv cpu_dspctrl, btarget, bcond; 432static TCGv_i32 hflags; 433static TCGv_i32 fpu_fcr0, fpu_fcr31; 434 435#include "exec/gen-icount.h" 436 437#define gen_helper_0i(name, arg) do { \ 438 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 439 gen_helper_##name(helper_tmp); \ 440 tcg_temp_free_i32(helper_tmp); \ 441 } while(0) 442 443#define gen_helper_1i(name, arg1, arg2) do { \ 444 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 445 gen_helper_##name(arg1, helper_tmp); \ 446 tcg_temp_free_i32(helper_tmp); \ 447 } while(0) 448 449#define gen_helper_2i(name, arg1, arg2, arg3) do { \ 450 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 451 gen_helper_##name(arg1, arg2, helper_tmp); \ 452 tcg_temp_free_i32(helper_tmp); \ 453 } while(0) 454 455#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \ 456 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 457 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \ 458 tcg_temp_free_i32(helper_tmp); \ 459 } while(0) 460 461#define gen_helper_4i(name, arg1, arg2, arg3, arg4, arg5) do { \ 462 TCGv_i32 helper_tmp = tcg_const_i32(arg5); \ 463 gen_helper_##name(arg1, arg2, arg3, arg4, helper_tmp); \ 464 tcg_temp_free_i32(helper_tmp); \ 465 } while(0) 466 467typedef struct DisasContext { 468 struct TranslationBlock *tb; 469 target_ulong pc, saved_pc; 470 uint32_t opcode; 471 int singlestep_enabled; 472 /* Routine used to access memory */ 473 int mem_idx; 474 uint32_t hflags, saved_hflags; 475 int bstate; 476 target_ulong btarget; 477} DisasContext; 478 479enum { 480 BS_NONE = 0, /* We go out of the TB without reaching a branch or an 481 * exception condition */ 482 BS_STOP = 1, /* We want to stop translation for any reason */ 483 BS_BRANCH = 2, /* We reached a branch condition */ 484 BS_EXCP = 3, /* We reached an exception condition */ 485}; 486 487static const char *regnames[] = 488 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", 489 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 490 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 491 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", }; 492 493static const char *regnames_HI[] = 494 { "HI0", "HI1", "HI2", "HI3", }; 495 496static const char *regnames_LO[] = 497 { "LO0", "LO1", "LO2", "LO3", }; 498 499static const char *regnames_ACX[] = 500 { "ACX0", "ACX1", "ACX2", "ACX3", }; 501 502static const char *fregnames[] = 503 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 504 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 505 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 506 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; 507 508#ifdef MIPS_DEBUG_DISAS 509#define MIPS_DEBUG(fmt, ...) \ 510 qemu_log_mask(CPU_LOG_TB_IN_ASM, \ 511 TARGET_FMT_lx ": %08x " fmt "\n", \ 512 ctx->pc, ctx->opcode , ## __VA_ARGS__) 513#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 514#else 515#define MIPS_DEBUG(fmt, ...) do { } while(0) 516#define LOG_DISAS(...) do { } while (0) 517#endif 518 519#define MIPS_INVAL(op) \ 520do { \ 521 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \ 522 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \ 523} while (0) 524 525/* General purpose registers moves. */ 526static inline void gen_load_gpr (TCGv t, int reg) 527{ 528 if (reg == 0) 529 tcg_gen_movi_tl(t, 0); 530 else 531 tcg_gen_mov_tl(t, cpu_gpr[reg]); 532} 533 534static inline void gen_store_gpr (TCGv t, int reg) 535{ 536 if (reg != 0) 537 tcg_gen_mov_tl(cpu_gpr[reg], t); 538} 539 540/* Moves to/from ACX register. */ 541static inline void gen_load_ACX (TCGv t, int reg) 542{ 543 tcg_gen_mov_tl(t, cpu_ACX[reg]); 544} 545 546static inline void gen_store_ACX (TCGv t, int reg) 547{ 548 tcg_gen_mov_tl(cpu_ACX[reg], t); 549} 550 551/* Moves to/from shadow registers. */ 552static inline void gen_load_srsgpr (int from, int to) 553{ 554 TCGv t0 = tcg_temp_new(); 555 556 if (from == 0) 557 tcg_gen_movi_tl(t0, 0); 558 else { 559 TCGv_i32 t2 = tcg_temp_new_i32(); 560 TCGv_ptr addr = tcg_temp_new_ptr(); 561 562 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 563 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 564 tcg_gen_andi_i32(t2, t2, 0xf); 565 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 566 tcg_gen_ext_i32_ptr(addr, t2); 567 tcg_gen_add_ptr(addr, cpu_env, addr); 568 569 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 570 tcg_temp_free_ptr(addr); 571 tcg_temp_free_i32(t2); 572 } 573 gen_store_gpr(t0, to); 574 tcg_temp_free(t0); 575} 576 577static inline void gen_store_srsgpr (int from, int to) 578{ 579 if (to != 0) { 580 TCGv t0 = tcg_temp_new(); 581 TCGv_i32 t2 = tcg_temp_new_i32(); 582 TCGv_ptr addr = tcg_temp_new_ptr(); 583 584 gen_load_gpr(t0, from); 585 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 586 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 587 tcg_gen_andi_i32(t2, t2, 0xf); 588 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 589 tcg_gen_ext_i32_ptr(addr, t2); 590 tcg_gen_add_ptr(addr, cpu_env, addr); 591 592 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 593 tcg_temp_free_ptr(addr); 594 tcg_temp_free_i32(t2); 595 tcg_temp_free(t0); 596 } 597} 598 599/* Floating point register moves. */ 600static inline void gen_load_fpr32 (TCGv_i32 t, int reg) 601{ 602 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); 603} 604 605static inline void gen_store_fpr32 (TCGv_i32 t, int reg) 606{ 607 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); 608} 609 610static inline void gen_load_fpr32h (TCGv_i32 t, int reg) 611{ 612 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); 613} 614 615static inline void gen_store_fpr32h (TCGv_i32 t, int reg) 616{ 617 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); 618} 619 620static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) 621{ 622 if (ctx->hflags & MIPS_HFLAG_F64) { 623 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d)); 624 } else { 625 TCGv_i32 t0 = tcg_temp_new_i32(); 626 TCGv_i32 t1 = tcg_temp_new_i32(); 627 gen_load_fpr32(t0, reg & ~1); 628 gen_load_fpr32(t1, reg | 1); 629 tcg_gen_concat_i32_i64(t, t0, t1); 630 tcg_temp_free_i32(t0); 631 tcg_temp_free_i32(t1); 632 } 633} 634 635static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) 636{ 637 if (ctx->hflags & MIPS_HFLAG_F64) { 638 tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d)); 639 } else { 640 TCGv_i64 t0 = tcg_temp_new_i64(); 641 TCGv_i32 t1 = tcg_temp_new_i32(); 642 tcg_gen_trunc_i64_i32(t1, t); 643 gen_store_fpr32(t1, reg & ~1); 644 tcg_gen_shri_i64(t0, t, 32); 645 tcg_gen_trunc_i64_i32(t1, t0); 646 gen_store_fpr32(t1, reg | 1); 647 tcg_temp_free_i32(t1); 648 tcg_temp_free_i64(t0); 649 } 650} 651 652static inline int get_fp_bit (int cc) 653{ 654 if (cc) 655 return 24 + cc; 656 else 657 return 23; 658} 659 660#define FOP_CONDS(type, fmt, bits) \ 661static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \ 662 TCGv_i##bits b, int cc) \ 663{ \ 664 switch (n) { \ 665 case 0: gen_helper_3i(cmp ## type ## _ ## fmt ## _f, cpu_env, a, b, cc); break;\ 666 case 1: gen_helper_3i(cmp ## type ## _ ## fmt ## _un, cpu_env, a, b, cc); break;\ 667 case 2: gen_helper_3i(cmp ## type ## _ ## fmt ## _eq, cpu_env, a, b, cc); break;\ 668 case 3: gen_helper_3i(cmp ## type ## _ ## fmt ## _ueq, cpu_env, a, b, cc); break;\ 669 case 4: gen_helper_3i(cmp ## type ## _ ## fmt ## _olt, cpu_env, a, b, cc); break;\ 670 case 5: gen_helper_3i(cmp ## type ## _ ## fmt ## _ult, cpu_env, a, b, cc); break;\ 671 case 6: gen_helper_3i(cmp ## type ## _ ## fmt ## _ole, cpu_env, a, b, cc); break;\ 672 case 7: gen_helper_3i(cmp ## type ## _ ## fmt ## _ule, cpu_env, a, b, cc); break;\ 673 case 8: gen_helper_3i(cmp ## type ## _ ## fmt ## _sf, cpu_env, a, b, cc); break;\ 674 case 9: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngle, cpu_env, a, b, cc); break;\ 675 case 10: gen_helper_3i(cmp ## type ## _ ## fmt ## _seq, cpu_env, a, b, cc); break;\ 676 case 11: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngl, cpu_env, a, b, cc); break;\ 677 case 12: gen_helper_3i(cmp ## type ## _ ## fmt ## _lt, cpu_env, a, b, cc); break;\ 678 case 13: gen_helper_3i(cmp ## type ## _ ## fmt ## _nge, cpu_env, a, b, cc); break;\ 679 case 14: gen_helper_3i(cmp ## type ## _ ## fmt ## _le, cpu_env, a, b, cc); break;\ 680 case 15: gen_helper_3i(cmp ## type ## _ ## fmt ## _ngt, cpu_env, a, b, cc); break;\ 681 default: abort(); \ 682 } \ 683} 684 685FOP_CONDS(, d, 64) 686FOP_CONDS(abs, d, 64) 687FOP_CONDS(, s, 32) 688FOP_CONDS(abs, s, 32) 689FOP_CONDS(, ps, 64) 690FOP_CONDS(abs, ps, 64) 691#undef FOP_CONDS 692 693/* Tests */ 694#define OP_COND(name, cond) \ 695static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \ 696{ \ 697 int l1 = gen_new_label(); \ 698 int l2 = gen_new_label(); \ 699 \ 700 tcg_gen_brcond_tl(cond, t0, t1, l1); \ 701 tcg_gen_movi_tl(ret, 0); \ 702 tcg_gen_br(l2); \ 703 gen_set_label(l1); \ 704 tcg_gen_movi_tl(ret, 1); \ 705 gen_set_label(l2); \ 706} 707OP_COND(eq, TCG_COND_EQ); 708OP_COND(ne, TCG_COND_NE); 709OP_COND(ge, TCG_COND_GE); 710OP_COND(geu, TCG_COND_GEU); 711OP_COND(lt, TCG_COND_LT); 712OP_COND(ltu, TCG_COND_LTU); 713#undef OP_COND 714 715#define OP_CONDI(name, cond) \ 716static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \ 717{ \ 718 int l1 = gen_new_label(); \ 719 int l2 = gen_new_label(); \ 720 \ 721 tcg_gen_brcondi_tl(cond, t0, val, l1); \ 722 tcg_gen_movi_tl(ret, 0); \ 723 tcg_gen_br(l2); \ 724 gen_set_label(l1); \ 725 tcg_gen_movi_tl(ret, 1); \ 726 gen_set_label(l2); \ 727} 728OP_CONDI(lti, TCG_COND_LT); 729OP_CONDI(ltiu, TCG_COND_LTU); 730#undef OP_CONDI 731 732#define OP_CONDZ(name, cond) \ 733static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \ 734{ \ 735 int l1 = gen_new_label(); \ 736 int l2 = gen_new_label(); \ 737 \ 738 tcg_gen_brcondi_tl(cond, t0, 0, l1); \ 739 tcg_gen_movi_tl(ret, 0); \ 740 tcg_gen_br(l2); \ 741 gen_set_label(l1); \ 742 tcg_gen_movi_tl(ret, 1); \ 743 gen_set_label(l2); \ 744} 745OP_CONDZ(gez, TCG_COND_GE); 746OP_CONDZ(gtz, TCG_COND_GT); 747OP_CONDZ(lez, TCG_COND_LE); 748OP_CONDZ(ltz, TCG_COND_LT); 749#undef OP_CONDZ 750 751static inline void gen_save_pc(target_ulong pc) 752{ 753 tcg_gen_movi_tl(cpu_PC, pc); 754} 755 756static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) 757{ 758 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 759 if (do_save_pc && ctx->pc != ctx->saved_pc) { 760 gen_save_pc(ctx->pc); 761 ctx->saved_pc = ctx->pc; 762 } 763 if (ctx->hflags != ctx->saved_hflags) { 764 tcg_gen_movi_i32(hflags, ctx->hflags); 765 ctx->saved_hflags = ctx->hflags; 766 switch (ctx->hflags & MIPS_HFLAG_BMASK) { 767 case MIPS_HFLAG_BR: 768 break; 769 case MIPS_HFLAG_BC: 770 case MIPS_HFLAG_BL: 771 case MIPS_HFLAG_B: 772 tcg_gen_movi_tl(btarget, ctx->btarget); 773 break; 774 } 775 } 776} 777 778static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx) 779{ 780 ctx->saved_hflags = ctx->hflags; 781 switch (ctx->hflags & MIPS_HFLAG_BMASK) { 782 case MIPS_HFLAG_BR: 783 break; 784 case MIPS_HFLAG_BC: 785 case MIPS_HFLAG_BL: 786 case MIPS_HFLAG_B: 787 ctx->btarget = env->btarget; 788 break; 789 } 790} 791 792static inline void 793generate_exception_err (DisasContext *ctx, int excp, int err) 794{ 795 TCGv_i32 texcp = tcg_const_i32(excp); 796 TCGv_i32 terr = tcg_const_i32(err); 797 save_cpu_state(ctx, 1); 798 gen_helper_raise_exception_err(cpu_env, texcp, terr); 799 tcg_temp_free_i32(terr); 800 tcg_temp_free_i32(texcp); 801} 802 803static inline void 804generate_exception (DisasContext *ctx, int excp) 805{ 806 save_cpu_state(ctx, 1); 807 gen_helper_1i(raise_exception, cpu_env, excp); 808} 809 810/* Addresses computation */ 811static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 812{ 813 tcg_gen_add_tl(ret, arg0, arg1); 814 815#if defined(TARGET_MIPS64) 816 /* For compatibility with 32-bit code, data reference in user mode 817 with Status_UX = 0 should be casted to 32-bit and sign extended. 818 See the MIPS64 PRA manual, section 4.10. */ 819 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && 820 !(ctx->hflags & MIPS_HFLAG_UX)) { 821 tcg_gen_ext32s_i64(ret, ret); 822 } 823#endif 824} 825 826static inline void check_cp0_enabled(DisasContext *ctx) 827{ 828 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) 829 generate_exception_err(ctx, EXCP_CpU, 0); 830} 831 832static inline void check_cp1_enabled(DisasContext *ctx) 833{ 834 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) 835 generate_exception_err(ctx, EXCP_CpU, 1); 836} 837 838/* Verify that the processor is running with COP1X instructions enabled. 839 This is associated with the nabla symbol in the MIPS32 and MIPS64 840 opcode tables. */ 841 842static inline void check_cop1x(DisasContext *ctx) 843{ 844 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) 845 generate_exception(ctx, EXCP_RI); 846} 847 848/* Verify that the processor is running with 64-bit floating-point 849 operations enabled. */ 850 851static inline void check_cp1_64bitmode(DisasContext *ctx) 852{ 853 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) 854 generate_exception(ctx, EXCP_RI); 855} 856 857/* 858 * Verify if floating point register is valid; an operation is not defined 859 * if bit 0 of any register specification is set and the FR bit in the 860 * Status register equals zero, since the register numbers specify an 861 * even-odd pair of adjacent coprocessor general registers. When the FR bit 862 * in the Status register equals one, both even and odd register numbers 863 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 864 * 865 * Multiple 64 bit wide registers can be checked by calling 866 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 867 */ 868static inline void check_cp1_registers(DisasContext *ctx, int regs) 869{ 870 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) 871 generate_exception(ctx, EXCP_RI); 872} 873 874/* This code generates a "reserved instruction" exception if the 875 CPU does not support the instruction set corresponding to flags. */ 876static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags) 877{ 878 if (unlikely(!(env->insn_flags & flags))) 879 generate_exception(ctx, EXCP_RI); 880} 881 882/* This code generates a "reserved instruction" exception if 64-bit 883 instructions are not enabled. */ 884static inline void check_mips_64(DisasContext *ctx) 885{ 886 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) 887 generate_exception(ctx, EXCP_RI); 888} 889 890/* load/store instructions. */ 891#define OP_LD(insn,fname) \ 892static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 893{ \ 894 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 895} 896OP_LD(lb,ld8s); 897OP_LD(lbu,ld8u); 898OP_LD(lh,ld16s); 899OP_LD(lhu,ld16u); 900OP_LD(lw,ld32s); 901#if defined(TARGET_MIPS64) 902OP_LD(lwu,ld32u); 903OP_LD(ld,ld64); 904#endif 905#undef OP_LD 906 907#define OP_ST(insn,fname) \ 908static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \ 909{ \ 910 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \ 911} 912OP_ST(sb,st8); 913OP_ST(sh,st16); 914OP_ST(sw,st32); 915#if defined(TARGET_MIPS64) 916OP_ST(sd,st64); 917#endif 918#undef OP_ST 919 920#ifdef CONFIG_USER_ONLY 921#define OP_LD_ATOMIC(insn,fname) \ 922static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 923{ \ 924 TCGv t0 = tcg_temp_new(); \ 925 tcg_gen_mov_tl(t0, arg1); \ 926 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 927 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 928 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 929 tcg_temp_free(t0); \ 930} 931#else 932#define OP_LD_ATOMIC(insn,fname) \ 933static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \ 934{ \ 935 gen_helper_3i(insn, ret, cpu_env, arg1, ctx->mem_idx); \ 936} 937#endif 938OP_LD_ATOMIC(ll,ld32s); 939#if defined(TARGET_MIPS64) 940OP_LD_ATOMIC(lld,ld64); 941#endif 942#undef OP_LD_ATOMIC 943 944#ifdef CONFIG_USER_ONLY 945#define OP_ST_ATOMIC(insn,fname,ldname,almask) \ 946static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \ 947{ \ 948 TCGv t0 = tcg_temp_new(); \ 949 int l1 = gen_new_label(); \ 950 int l2 = gen_new_label(); \ 951 \ 952 tcg_gen_andi_tl(t0, arg2, almask); \ 953 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \ 954 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \ 955 generate_exception(ctx, EXCP_AdES); \ 956 gen_set_label(l1); \ 957 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 958 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \ 959 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \ 960 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \ 961 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \ 962 gen_helper_1i(raise_exception, cpu_env, EXCP_SC); \ 963 gen_set_label(l2); \ 964 tcg_gen_movi_tl(t0, 0); \ 965 gen_store_gpr(t0, rt); \ 966 tcg_temp_free(t0); \ 967} 968#else 969#define OP_ST_ATOMIC(insn,fname,ldname,almask) \ 970static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \ 971{ \ 972 TCGv t0 = tcg_temp_new(); \ 973 gen_helper_4i(insn, t0, cpu_env, arg1, arg2, ctx->mem_idx); \ 974 gen_store_gpr(t0, rt); \ 975 tcg_temp_free(t0); \ 976} 977#endif 978OP_ST_ATOMIC(sc,st32,ld32s,0x3); 979#if defined(TARGET_MIPS64) 980OP_ST_ATOMIC(scd,st64,ld64,0x7); 981#endif 982#undef OP_ST_ATOMIC 983 984/* Load and store */ 985static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, 986 int base, int16_t offset) 987{ 988 const char * __attribute__((unused)) opn = "ldst"; 989 TCGv t0 = tcg_temp_new(); 990 TCGv t1 = tcg_temp_new(); 991 992 if (base == 0) { 993 tcg_gen_movi_tl(t0, offset); 994 } else if (offset == 0) { 995 gen_load_gpr(t0, base); 996 } else { 997 tcg_gen_movi_tl(t0, offset); 998 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 999 } 1000 /* Don't do NOP if destination is zero: we must perform the actual 1001 memory access. */ 1002 switch (opc) { 1003#if defined(TARGET_MIPS64) 1004 case OPC_LWU: 1005 save_cpu_state(ctx, 0); 1006 op_ldst_lwu(t0, t0, ctx); 1007 gen_store_gpr(t0, rt); 1008 opn = "lwu"; 1009 break; 1010 case OPC_LD: 1011 save_cpu_state(ctx, 0); 1012 op_ldst_ld(t0, t0, ctx); 1013 gen_store_gpr(t0, rt); 1014 opn = "ld"; 1015 break; 1016 case OPC_LLD: 1017 save_cpu_state(ctx, 0); 1018 op_ldst_lld(t0, t0, ctx); 1019 gen_store_gpr(t0, rt); 1020 opn = "lld"; 1021 break; 1022 case OPC_SD: 1023 save_cpu_state(ctx, 0); 1024 gen_load_gpr(t1, rt); 1025 op_ldst_sd(t1, t0, ctx); 1026 opn = "sd"; 1027 break; 1028 case OPC_LDL: 1029 save_cpu_state(ctx, 1); 1030 gen_load_gpr(t1, rt); 1031 gen_helper_4i(ldl, t1, cpu_env, t1, t0, ctx->mem_idx); 1032 gen_store_gpr(t1, rt); 1033 opn = "ldl"; 1034 break; 1035 case OPC_SDL: 1036 save_cpu_state(ctx, 1); 1037 gen_load_gpr(t1, rt); 1038 gen_helper_3i(sdl, cpu_env, t1, t0, ctx->mem_idx); 1039 opn = "sdl"; 1040 break; 1041 case OPC_LDR: 1042 save_cpu_state(ctx, 1); 1043 gen_load_gpr(t1, rt); 1044 gen_helper_4i(ldr, t1, cpu_env, t1, t0, ctx->mem_idx); 1045 gen_store_gpr(t1, rt); 1046 opn = "ldr"; 1047 break; 1048 case OPC_SDR: 1049 save_cpu_state(ctx, 1); 1050 gen_load_gpr(t1, rt); 1051 gen_helper_3i(sdr, cpu_env, t1, t0, ctx->mem_idx); 1052 opn = "sdr"; 1053 break; 1054#endif 1055 case OPC_LW: 1056 save_cpu_state(ctx, 0); 1057 op_ldst_lw(t0, t0, ctx); 1058 gen_store_gpr(t0, rt); 1059 opn = "lw"; 1060 break; 1061 case OPC_SW: 1062 save_cpu_state(ctx, 0); 1063 gen_load_gpr(t1, rt); 1064 op_ldst_sw(t1, t0, ctx); 1065 opn = "sw"; 1066 break; 1067 case OPC_LH: 1068 save_cpu_state(ctx, 0); 1069 op_ldst_lh(t0, t0, ctx); 1070 gen_store_gpr(t0, rt); 1071 opn = "lh"; 1072 break; 1073 case OPC_SH: 1074 save_cpu_state(ctx, 0); 1075 gen_load_gpr(t1, rt); 1076 op_ldst_sh(t1, t0, ctx); 1077 opn = "sh"; 1078 break; 1079 case OPC_LHU: 1080 save_cpu_state(ctx, 0); 1081 op_ldst_lhu(t0, t0, ctx); 1082 gen_store_gpr(t0, rt); 1083 opn = "lhu"; 1084 break; 1085 case OPC_LB: 1086 save_cpu_state(ctx, 0); 1087 op_ldst_lb(t0, t0, ctx); 1088 gen_store_gpr(t0, rt); 1089 opn = "lb"; 1090 break; 1091 case OPC_SB: 1092 save_cpu_state(ctx, 0); 1093 gen_load_gpr(t1, rt); 1094 op_ldst_sb(t1, t0, ctx); 1095 opn = "sb"; 1096 break; 1097 case OPC_LBU: 1098 save_cpu_state(ctx, 0); 1099 op_ldst_lbu(t0, t0, ctx); 1100 gen_store_gpr(t0, rt); 1101 opn = "lbu"; 1102 break; 1103 case OPC_LWL: 1104 save_cpu_state(ctx, 1); 1105 gen_load_gpr(t1, rt); 1106 gen_helper_4i(lwl, t1, cpu_env, t1, t0, ctx->mem_idx); 1107 gen_store_gpr(t1, rt); 1108 opn = "lwl"; 1109 break; 1110 case OPC_SWL: 1111 save_cpu_state(ctx, 1); 1112 gen_load_gpr(t1, rt); 1113 gen_helper_3i(swl, cpu_env, t1, t0, ctx->mem_idx); 1114 opn = "swl"; 1115 break; 1116 case OPC_LWR: 1117 save_cpu_state(ctx, 1); 1118 gen_load_gpr(t1, rt); 1119 gen_helper_4i(lwr, t1, cpu_env, t1, t0, ctx->mem_idx); 1120 gen_store_gpr(t1, rt); 1121 opn = "lwr"; 1122 break; 1123 case OPC_SWR: 1124 save_cpu_state(ctx, 1); 1125 gen_load_gpr(t1, rt); 1126 gen_helper_3i(swr, cpu_env, t1, t0, ctx->mem_idx); 1127 opn = "swr"; 1128 break; 1129 case OPC_LL: 1130 save_cpu_state(ctx, 1); 1131 op_ldst_ll(t0, t0, ctx); 1132 gen_store_gpr(t0, rt); 1133 opn = "ll"; 1134 break; 1135 } 1136 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 1137 tcg_temp_free(t0); 1138 tcg_temp_free(t1); 1139} 1140 1141/* Store conditional */ 1142static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, 1143 int base, int16_t offset) 1144{ 1145 const char * __attribute__((unused)) opn = "st_cond"; 1146 TCGv t0, t1; 1147 1148 t0 = tcg_temp_local_new(); 1149 1150 if (base == 0) { 1151 tcg_gen_movi_tl(t0, offset); 1152 } else if (offset == 0) { 1153 gen_load_gpr(t0, base); 1154 } else { 1155 tcg_gen_movi_tl(t0, offset); 1156 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 1157 } 1158 /* Don't do NOP if destination is zero: we must perform the actual 1159 memory access. */ 1160 1161 t1 = tcg_temp_local_new(); 1162 gen_load_gpr(t1, rt); 1163 switch (opc) { 1164#if defined(TARGET_MIPS64) 1165 case OPC_SCD: 1166 save_cpu_state(ctx, 0); 1167 op_ldst_scd(t1, t0, rt, ctx); 1168 opn = "scd"; 1169 break; 1170#endif 1171 case OPC_SC: 1172 save_cpu_state(ctx, 1); 1173 op_ldst_sc(t1, t0, rt, ctx); 1174 opn = "sc"; 1175 break; 1176 } 1177 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 1178 tcg_temp_free(t1); 1179 tcg_temp_free(t0); 1180} 1181 1182/* Load and store */ 1183static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, 1184 int base, int16_t offset) 1185{ 1186 const char * __attribute__((unused)) opn = "flt_ldst"; 1187 TCGv t0 = tcg_temp_new(); 1188 1189 if (base == 0) { 1190 tcg_gen_movi_tl(t0, offset); 1191 } else if (offset == 0) { 1192 gen_load_gpr(t0, base); 1193 } else { 1194 tcg_gen_movi_tl(t0, offset); 1195 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 1196 } 1197 /* Don't do NOP if destination is zero: we must perform the actual 1198 memory access. */ 1199 switch (opc) { 1200 case OPC_LWC1: 1201 { 1202 TCGv_i32 fp0 = tcg_temp_new_i32(); 1203 1204 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx); 1205 tcg_gen_trunc_tl_i32(fp0, t0); 1206 gen_store_fpr32(fp0, ft); 1207 tcg_temp_free_i32(fp0); 1208 } 1209 opn = "lwc1"; 1210 break; 1211 case OPC_SWC1: 1212 { 1213 TCGv_i32 fp0 = tcg_temp_new_i32(); 1214 TCGv t1 = tcg_temp_new(); 1215 1216 gen_load_fpr32(fp0, ft); 1217 tcg_gen_extu_i32_tl(t1, fp0); 1218 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); 1219 tcg_temp_free(t1); 1220 tcg_temp_free_i32(fp0); 1221 } 1222 opn = "swc1"; 1223 break; 1224 case OPC_LDC1: 1225 { 1226 TCGv_i64 fp0 = tcg_temp_new_i64(); 1227 1228 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 1229 gen_store_fpr64(ctx, fp0, ft); 1230 tcg_temp_free_i64(fp0); 1231 } 1232 opn = "ldc1"; 1233 break; 1234 case OPC_SDC1: 1235 { 1236 TCGv_i64 fp0 = tcg_temp_new_i64(); 1237 1238 gen_load_fpr64(ctx, fp0, ft); 1239 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 1240 tcg_temp_free_i64(fp0); 1241 } 1242 opn = "sdc1"; 1243 break; 1244 default: 1245 MIPS_INVAL(opn); 1246 generate_exception(ctx, EXCP_RI); 1247 goto out; 1248 } 1249 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); 1250 out: 1251 tcg_temp_free(t0); 1252} 1253 1254/* Arithmetic with immediate operand */ 1255static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1256 int rt, int rs, int16_t imm) 1257{ 1258 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 1259 const char * __attribute__((unused)) opn = "imm arith"; 1260 1261 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 1262 /* If no destination, treat it as a NOP. 1263 For addi, we must generate the overflow exception when needed. */ 1264 MIPS_DEBUG("NOP"); 1265 return; 1266 } 1267 switch (opc) { 1268 case OPC_ADDI: 1269 { 1270 TCGv t0 = tcg_temp_local_new(); 1271 TCGv t1 = tcg_temp_new(); 1272 TCGv t2 = tcg_temp_new(); 1273 int l1 = gen_new_label(); 1274 1275 gen_load_gpr(t1, rs); 1276 tcg_gen_addi_tl(t0, t1, uimm); 1277 tcg_gen_ext32s_tl(t0, t0); 1278 1279 tcg_gen_xori_tl(t1, t1, ~uimm); 1280 tcg_gen_xori_tl(t2, t0, uimm); 1281 tcg_gen_and_tl(t1, t1, t2); 1282 tcg_temp_free(t2); 1283 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1284 tcg_temp_free(t1); 1285 /* operands of same sign, result different sign */ 1286 generate_exception(ctx, EXCP_OVERFLOW); 1287 gen_set_label(l1); 1288 tcg_gen_ext32s_tl(t0, t0); 1289 gen_store_gpr(t0, rt); 1290 tcg_temp_free(t0); 1291 } 1292 opn = "addi"; 1293 break; 1294 case OPC_ADDIU: 1295 if (rs != 0) { 1296 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1297 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 1298 } else { 1299 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1300 } 1301 opn = "addiu"; 1302 break; 1303#if defined(TARGET_MIPS64) 1304 case OPC_DADDI: 1305 { 1306 TCGv t0 = tcg_temp_local_new(); 1307 TCGv t1 = tcg_temp_new(); 1308 TCGv t2 = tcg_temp_new(); 1309 int l1 = gen_new_label(); 1310 1311 gen_load_gpr(t1, rs); 1312 tcg_gen_addi_tl(t0, t1, uimm); 1313 1314 tcg_gen_xori_tl(t1, t1, ~uimm); 1315 tcg_gen_xori_tl(t2, t0, uimm); 1316 tcg_gen_and_tl(t1, t1, t2); 1317 tcg_temp_free(t2); 1318 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1319 tcg_temp_free(t1); 1320 /* operands of same sign, result different sign */ 1321 generate_exception(ctx, EXCP_OVERFLOW); 1322 gen_set_label(l1); 1323 gen_store_gpr(t0, rt); 1324 tcg_temp_free(t0); 1325 } 1326 opn = "daddi"; 1327 break; 1328 case OPC_DADDIU: 1329 if (rs != 0) { 1330 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1331 } else { 1332 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1333 } 1334 opn = "daddiu"; 1335 break; 1336#endif 1337 } 1338 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1339} 1340 1341/* Logic with immediate operand */ 1342static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm) 1343{ 1344 target_ulong uimm; 1345 const char * __attribute__((unused)) opn = "imm logic"; 1346 1347 if (rt == 0) { 1348 /* If no destination, treat it as a NOP. */ 1349 MIPS_DEBUG("NOP"); 1350 return; 1351 } 1352 uimm = (uint16_t)imm; 1353 switch (opc) { 1354 case OPC_ANDI: 1355 if (likely(rs != 0)) 1356 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1357 else 1358 tcg_gen_movi_tl(cpu_gpr[rt], 0); 1359 opn = "andi"; 1360 break; 1361 case OPC_ORI: 1362 if (rs != 0) 1363 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1364 else 1365 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1366 opn = "ori"; 1367 break; 1368 case OPC_XORI: 1369 if (likely(rs != 0)) 1370 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 1371 else 1372 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 1373 opn = "xori"; 1374 break; 1375 case OPC_LUI: 1376 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 1377 opn = "lui"; 1378 break; 1379 } 1380 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1381} 1382 1383/* Set on less than with immediate operand */ 1384static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm) 1385{ 1386 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 1387 const char * __attribute__((unused)) opn = "imm arith"; 1388 TCGv t0; 1389 1390 if (rt == 0) { 1391 /* If no destination, treat it as a NOP. */ 1392 MIPS_DEBUG("NOP"); 1393 return; 1394 } 1395 t0 = tcg_temp_new(); 1396 gen_load_gpr(t0, rs); 1397 switch (opc) { 1398 case OPC_SLTI: 1399 gen_op_lti(cpu_gpr[rt], t0, uimm); 1400 opn = "slti"; 1401 break; 1402 case OPC_SLTIU: 1403 gen_op_ltiu(cpu_gpr[rt], t0, uimm); 1404 opn = "sltiu"; 1405 break; 1406 } 1407 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1408 tcg_temp_free(t0); 1409} 1410 1411/* Shifts with immediate operand */ 1412static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1413 int rt, int rs, int16_t imm) 1414{ 1415 target_ulong uimm = ((uint16_t)imm) & 0x1f; 1416 const char* __attribute__((unused)) opn = "imm shift"; 1417 TCGv t0; 1418 1419 if (rt == 0) { 1420 /* If no destination, treat it as a NOP. */ 1421 MIPS_DEBUG("NOP"); 1422 return; 1423 } 1424 1425 t0 = tcg_temp_new(); 1426 gen_load_gpr(t0, rs); 1427 switch (opc) { 1428 case OPC_SLL: 1429 tcg_gen_shli_tl(t0, t0, uimm); 1430 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1431 opn = "sll"; 1432 break; 1433 case OPC_SRA: 1434 tcg_gen_ext32s_tl(t0, t0); 1435 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 1436 opn = "sra"; 1437 break; 1438 case OPC_SRL: 1439 switch ((ctx->opcode >> 21) & 0x1f) { 1440 case 0: 1441 if (uimm != 0) { 1442 tcg_gen_ext32u_tl(t0, t0); 1443 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1444 } else { 1445 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1446 } 1447 opn = "srl"; 1448 break; 1449 case 1: 1450 /* rotr is decoded as srl on non-R2 CPUs */ 1451 if (env->insn_flags & ISA_MIPS32R2) { 1452 if (uimm != 0) { 1453 TCGv_i32 t1 = tcg_temp_new_i32(); 1454 1455 tcg_gen_trunc_tl_i32(t1, t0); 1456 tcg_gen_rotri_i32(t1, t1, uimm); 1457 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 1458 tcg_temp_free_i32(t1); 1459 } else { 1460 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1461 } 1462 opn = "rotr"; 1463 } else { 1464 if (uimm != 0) { 1465 tcg_gen_ext32u_tl(t0, t0); 1466 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1467 } else { 1468 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 1469 } 1470 opn = "srl"; 1471 } 1472 break; 1473 default: 1474 MIPS_INVAL("invalid srl flag"); 1475 generate_exception(ctx, EXCP_RI); 1476 break; 1477 } 1478 break; 1479#if defined(TARGET_MIPS64) 1480 case OPC_DSLL: 1481 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 1482 opn = "dsll"; 1483 break; 1484 case OPC_DSRA: 1485 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 1486 opn = "dsra"; 1487 break; 1488 case OPC_DSRL: 1489 switch ((ctx->opcode >> 21) & 0x1f) { 1490 case 0: 1491 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1492 opn = "dsrl"; 1493 break; 1494 case 1: 1495 /* drotr is decoded as dsrl on non-R2 CPUs */ 1496 if (env->insn_flags & ISA_MIPS32R2) { 1497 if (uimm != 0) { 1498 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 1499 } else { 1500 tcg_gen_mov_tl(cpu_gpr[rt], t0); 1501 } 1502 opn = "drotr"; 1503 } else { 1504 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 1505 opn = "dsrl"; 1506 } 1507 break; 1508 default: 1509 MIPS_INVAL("invalid dsrl flag"); 1510 generate_exception(ctx, EXCP_RI); 1511 break; 1512 } 1513 break; 1514 case OPC_DSLL32: 1515 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 1516 opn = "dsll32"; 1517 break; 1518 case OPC_DSRA32: 1519 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 1520 opn = "dsra32"; 1521 break; 1522 case OPC_DSRL32: 1523 switch ((ctx->opcode >> 21) & 0x1f) { 1524 case 0: 1525 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 1526 opn = "dsrl32"; 1527 break; 1528 case 1: 1529 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 1530 if (env->insn_flags & ISA_MIPS32R2) { 1531 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 1532 opn = "drotr32"; 1533 } else { 1534 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 1535 opn = "dsrl32"; 1536 } 1537 break; 1538 default: 1539 MIPS_INVAL("invalid dsrl32 flag"); 1540 generate_exception(ctx, EXCP_RI); 1541 break; 1542 } 1543 break; 1544#endif 1545 } 1546 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); 1547 tcg_temp_free(t0); 1548} 1549 1550/* Arithmetic */ 1551static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1552 int rd, int rs, int rt) 1553{ 1554 const char* __attribute__((unused)) opn = "arith"; 1555 1556 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 1557 && opc != OPC_DADD && opc != OPC_DSUB) { 1558 /* If no destination, treat it as a NOP. 1559 For add & sub, we must generate the overflow exception when needed. */ 1560 MIPS_DEBUG("NOP"); 1561 return; 1562 } 1563 1564 switch (opc) { 1565 case OPC_ADD: 1566 { 1567 TCGv t0 = tcg_temp_local_new(); 1568 TCGv t1 = tcg_temp_new(); 1569 TCGv t2 = tcg_temp_new(); 1570 int l1 = gen_new_label(); 1571 1572 gen_load_gpr(t1, rs); 1573 gen_load_gpr(t2, rt); 1574 tcg_gen_add_tl(t0, t1, t2); 1575 tcg_gen_ext32s_tl(t0, t0); 1576 tcg_gen_xor_tl(t1, t1, t2); 1577 tcg_gen_not_tl(t1, t1); 1578 tcg_gen_xor_tl(t2, t0, t2); 1579 tcg_gen_and_tl(t1, t1, t2); 1580 tcg_temp_free(t2); 1581 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1582 tcg_temp_free(t1); 1583 /* operands of same sign, result different sign */ 1584 generate_exception(ctx, EXCP_OVERFLOW); 1585 gen_set_label(l1); 1586 gen_store_gpr(t0, rd); 1587 tcg_temp_free(t0); 1588 } 1589 opn = "add"; 1590 break; 1591 case OPC_ADDU: 1592 if (rs != 0 && rt != 0) { 1593 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1594 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1595 } else if (rs == 0 && rt != 0) { 1596 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1597 } else if (rs != 0 && rt == 0) { 1598 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1599 } else { 1600 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1601 } 1602 opn = "addu"; 1603 break; 1604 case OPC_SUB: 1605 { 1606 TCGv t0 = tcg_temp_local_new(); 1607 TCGv t1 = tcg_temp_new(); 1608 TCGv t2 = tcg_temp_new(); 1609 int l1 = gen_new_label(); 1610 1611 gen_load_gpr(t1, rs); 1612 gen_load_gpr(t2, rt); 1613 tcg_gen_sub_tl(t0, t1, t2); 1614 tcg_gen_ext32s_tl(t0, t0); 1615 tcg_gen_xor_tl(t2, t1, t2); 1616 tcg_gen_xor_tl(t1, t0, t1); 1617 tcg_gen_and_tl(t1, t1, t2); 1618 tcg_temp_free(t2); 1619 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1620 tcg_temp_free(t1); 1621 /* operands of different sign, first operand and result different sign */ 1622 generate_exception(ctx, EXCP_OVERFLOW); 1623 gen_set_label(l1); 1624 gen_store_gpr(t0, rd); 1625 tcg_temp_free(t0); 1626 } 1627 opn = "sub"; 1628 break; 1629 case OPC_SUBU: 1630 if (rs != 0 && rt != 0) { 1631 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1632 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1633 } else if (rs == 0 && rt != 0) { 1634 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 1635 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1636 } else if (rs != 0 && rt == 0) { 1637 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1638 } else { 1639 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1640 } 1641 opn = "subu"; 1642 break; 1643#if defined(TARGET_MIPS64) 1644 case OPC_DADD: 1645 { 1646 TCGv t0 = tcg_temp_local_new(); 1647 TCGv t1 = tcg_temp_new(); 1648 TCGv t2 = tcg_temp_new(); 1649 int l1 = gen_new_label(); 1650 1651 gen_load_gpr(t1, rs); 1652 gen_load_gpr(t2, rt); 1653 tcg_gen_add_tl(t0, t1, t2); 1654 tcg_gen_xor_tl(t1, t1, t2); 1655 tcg_gen_not_tl(t1, t1); 1656 tcg_gen_xor_tl(t2, t0, t2); 1657 tcg_gen_and_tl(t1, t1, t2); 1658 tcg_temp_free(t2); 1659 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1660 tcg_temp_free(t1); 1661 /* operands of same sign, result different sign */ 1662 generate_exception(ctx, EXCP_OVERFLOW); 1663 gen_set_label(l1); 1664 gen_store_gpr(t0, rd); 1665 tcg_temp_free(t0); 1666 } 1667 opn = "dadd"; 1668 break; 1669 case OPC_DADDU: 1670 if (rs != 0 && rt != 0) { 1671 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1672 } else if (rs == 0 && rt != 0) { 1673 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1674 } else if (rs != 0 && rt == 0) { 1675 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1676 } else { 1677 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1678 } 1679 opn = "daddu"; 1680 break; 1681 case OPC_DSUB: 1682 { 1683 TCGv t0 = tcg_temp_local_new(); 1684 TCGv t1 = tcg_temp_new(); 1685 TCGv t2 = tcg_temp_new(); 1686 int l1 = gen_new_label(); 1687 1688 gen_load_gpr(t1, rs); 1689 gen_load_gpr(t2, rt); 1690 tcg_gen_sub_tl(t0, t1, t2); 1691 tcg_gen_xor_tl(t2, t1, t2); 1692 tcg_gen_xor_tl(t1, t0, t1); 1693 tcg_gen_and_tl(t1, t1, t2); 1694 tcg_temp_free(t2); 1695 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 1696 tcg_temp_free(t1); 1697 /* operands of different sign, first operand and result different sign */ 1698 generate_exception(ctx, EXCP_OVERFLOW); 1699 gen_set_label(l1); 1700 gen_store_gpr(t0, rd); 1701 tcg_temp_free(t0); 1702 } 1703 opn = "dsub"; 1704 break; 1705 case OPC_DSUBU: 1706 if (rs != 0 && rt != 0) { 1707 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1708 } else if (rs == 0 && rt != 0) { 1709 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 1710 } else if (rs != 0 && rt == 0) { 1711 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1712 } else { 1713 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1714 } 1715 opn = "dsubu"; 1716 break; 1717#endif 1718 case OPC_MUL: 1719 if (likely(rs != 0 && rt != 0)) { 1720 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1721 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 1722 } else { 1723 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1724 } 1725 opn = "mul"; 1726 break; 1727 } 1728 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1729} 1730 1731/* Conditional move */ 1732static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1733{ 1734 const char* __attribute__((unused)) opn = "cond move"; 1735 int l1; 1736 1737 if (rd == 0) { 1738 /* If no destination, treat it as a NOP. 1739 For add & sub, we must generate the overflow exception when needed. */ 1740 MIPS_DEBUG("NOP"); 1741 return; 1742 } 1743 1744 l1 = gen_new_label(); 1745 switch (opc) { 1746 case OPC_MOVN: 1747 if (likely(rt != 0)) 1748 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1); 1749 else 1750 tcg_gen_br(l1); 1751 opn = "movn"; 1752 break; 1753 case OPC_MOVZ: 1754 if (likely(rt != 0)) 1755 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1); 1756 opn = "movz"; 1757 break; 1758 } 1759 if (rs != 0) 1760 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1761 else 1762 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1763 gen_set_label(l1); 1764 1765 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1766} 1767 1768/* Logic */ 1769static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1770{ 1771 const char* __attribute__((unused)) opn = "logic"; 1772 1773 if (rd == 0) { 1774 /* If no destination, treat it as a NOP. */ 1775 MIPS_DEBUG("NOP"); 1776 return; 1777 } 1778 1779 switch (opc) { 1780 case OPC_AND: 1781 if (likely(rs != 0 && rt != 0)) { 1782 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1783 } else { 1784 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1785 } 1786 opn = "and"; 1787 break; 1788 case OPC_NOR: 1789 if (rs != 0 && rt != 0) { 1790 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1791 } else if (rs == 0 && rt != 0) { 1792 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 1793 } else if (rs != 0 && rt == 0) { 1794 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 1795 } else { 1796 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 1797 } 1798 opn = "nor"; 1799 break; 1800 case OPC_OR: 1801 if (likely(rs != 0 && rt != 0)) { 1802 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1803 } else if (rs == 0 && rt != 0) { 1804 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1805 } else if (rs != 0 && rt == 0) { 1806 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1807 } else { 1808 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1809 } 1810 opn = "or"; 1811 break; 1812 case OPC_XOR: 1813 if (likely(rs != 0 && rt != 0)) { 1814 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 1815 } else if (rs == 0 && rt != 0) { 1816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 1817 } else if (rs != 0 && rt == 0) { 1818 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 1819 } else { 1820 tcg_gen_movi_tl(cpu_gpr[rd], 0); 1821 } 1822 opn = "xor"; 1823 break; 1824 } 1825 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1826} 1827 1828/* Set on lower than */ 1829static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt) 1830{ 1831 const char* __attribute__((unused)) opn = "slt"; 1832 TCGv t0, t1; 1833 1834 if (rd == 0) { 1835 /* If no destination, treat it as a NOP. */ 1836 MIPS_DEBUG("NOP"); 1837 return; 1838 } 1839 1840 t0 = tcg_temp_new(); 1841 t1 = tcg_temp_new(); 1842 gen_load_gpr(t0, rs); 1843 gen_load_gpr(t1, rt); 1844 switch (opc) { 1845 case OPC_SLT: 1846 gen_op_lt(cpu_gpr[rd], t0, t1); 1847 opn = "slt"; 1848 break; 1849 case OPC_SLTU: 1850 gen_op_ltu(cpu_gpr[rd], t0, t1); 1851 opn = "sltu"; 1852 break; 1853 } 1854 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1855 tcg_temp_free(t0); 1856 tcg_temp_free(t1); 1857} 1858 1859/* Shifts */ 1860static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 1861 int rd, int rs, int rt) 1862{ 1863 const char* __attribute__((unused)) opn = "shifts"; 1864 TCGv t0, t1; 1865 1866 if (rd == 0) { 1867 /* If no destination, treat it as a NOP. 1868 For add & sub, we must generate the overflow exception when needed. */ 1869 MIPS_DEBUG("NOP"); 1870 return; 1871 } 1872 1873 t0 = tcg_temp_new(); 1874 t1 = tcg_temp_new(); 1875 gen_load_gpr(t0, rs); 1876 gen_load_gpr(t1, rt); 1877 switch (opc) { 1878 case OPC_SLLV: 1879 tcg_gen_andi_tl(t0, t0, 0x1f); 1880 tcg_gen_shl_tl(t0, t1, t0); 1881 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1882 opn = "sllv"; 1883 break; 1884 case OPC_SRAV: 1885 tcg_gen_ext32s_tl(t1, t1); 1886 tcg_gen_andi_tl(t0, t0, 0x1f); 1887 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 1888 opn = "srav"; 1889 break; 1890 case OPC_SRLV: 1891 switch ((ctx->opcode >> 6) & 0x1f) { 1892 case 0: 1893 tcg_gen_ext32u_tl(t1, t1); 1894 tcg_gen_andi_tl(t0, t0, 0x1f); 1895 tcg_gen_shr_tl(t0, t1, t0); 1896 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1897 opn = "srlv"; 1898 break; 1899 case 1: 1900 /* rotrv is decoded as srlv on non-R2 CPUs */ 1901 if (env->insn_flags & ISA_MIPS32R2) { 1902 TCGv_i32 t2 = tcg_temp_new_i32(); 1903 TCGv_i32 t3 = tcg_temp_new_i32(); 1904 1905 tcg_gen_trunc_tl_i32(t2, t0); 1906 tcg_gen_trunc_tl_i32(t3, t1); 1907 tcg_gen_andi_i32(t2, t2, 0x1f); 1908 tcg_gen_rotr_i32(t2, t3, t2); 1909 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 1910 tcg_temp_free_i32(t2); 1911 tcg_temp_free_i32(t3); 1912 opn = "rotrv"; 1913 } else { 1914 tcg_gen_ext32u_tl(t1, t1); 1915 tcg_gen_andi_tl(t0, t0, 0x1f); 1916 tcg_gen_shr_tl(t0, t1, t0); 1917 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 1918 opn = "srlv"; 1919 } 1920 break; 1921 default: 1922 MIPS_INVAL("invalid srlv flag"); 1923 generate_exception(ctx, EXCP_RI); 1924 break; 1925 } 1926 break; 1927#if defined(TARGET_MIPS64) 1928 case OPC_DSLLV: 1929 tcg_gen_andi_tl(t0, t0, 0x3f); 1930 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 1931 opn = "dsllv"; 1932 break; 1933 case OPC_DSRAV: 1934 tcg_gen_andi_tl(t0, t0, 0x3f); 1935 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 1936 opn = "dsrav"; 1937 break; 1938 case OPC_DSRLV: 1939 switch ((ctx->opcode >> 6) & 0x1f) { 1940 case 0: 1941 tcg_gen_andi_tl(t0, t0, 0x3f); 1942 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 1943 opn = "dsrlv"; 1944 break; 1945 case 1: 1946 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 1947 if (env->insn_flags & ISA_MIPS32R2) { 1948 tcg_gen_andi_tl(t0, t0, 0x3f); 1949 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 1950 opn = "drotrv"; 1951 } else { 1952 tcg_gen_andi_tl(t0, t0, 0x3f); 1953 tcg_gen_shr_tl(t0, t1, t0); 1954 opn = "dsrlv"; 1955 } 1956 break; 1957 default: 1958 MIPS_INVAL("invalid dsrlv flag"); 1959 generate_exception(ctx, EXCP_RI); 1960 break; 1961 } 1962 break; 1963#endif 1964 } 1965 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 1966 tcg_temp_free(t0); 1967 tcg_temp_free(t1); 1968} 1969 1970/* Arithmetic on HI/LO registers */ 1971static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) 1972{ 1973 const char* __attribute__((unused)) opn = "hilo"; 1974 1975 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 1976 /* Treat as NOP. */ 1977 MIPS_DEBUG("NOP"); 1978 return; 1979 } 1980 switch (opc) { 1981 case OPC_MFHI: 1982 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]); 1983 opn = "mfhi"; 1984 break; 1985 case OPC_MFLO: 1986 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]); 1987 opn = "mflo"; 1988 break; 1989 case OPC_MTHI: 1990 if (reg != 0) 1991 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]); 1992 else 1993 tcg_gen_movi_tl(cpu_HI[0], 0); 1994 opn = "mthi"; 1995 break; 1996 case OPC_MTLO: 1997 if (reg != 0) 1998 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]); 1999 else 2000 tcg_gen_movi_tl(cpu_LO[0], 0); 2001 opn = "mtlo"; 2002 break; 2003 } 2004 MIPS_DEBUG("%s %s", opn, regnames[reg]); 2005} 2006 2007static void gen_muldiv (DisasContext *ctx, uint32_t opc, 2008 int rs, int rt) 2009{ 2010 const char* __attribute__((unused)) opn = "mul/div"; 2011 TCGv t0, t1; 2012 2013 switch (opc) { 2014 case OPC_DIV: 2015 case OPC_DIVU: 2016#if defined(TARGET_MIPS64) 2017 case OPC_DDIV: 2018 case OPC_DDIVU: 2019#endif 2020 t0 = tcg_temp_local_new(); 2021 t1 = tcg_temp_local_new(); 2022 break; 2023 default: 2024 t0 = tcg_temp_new(); 2025 t1 = tcg_temp_new(); 2026 break; 2027 } 2028 2029 gen_load_gpr(t0, rs); 2030 gen_load_gpr(t1, rt); 2031 switch (opc) { 2032 case OPC_DIV: 2033 { 2034 int l1 = gen_new_label(); 2035 int l2 = gen_new_label(); 2036 2037 tcg_gen_ext32s_tl(t0, t0); 2038 tcg_gen_ext32s_tl(t1, t1); 2039 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2040 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 2041 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 2042 2043 tcg_gen_mov_tl(cpu_LO[0], t0); 2044 tcg_gen_movi_tl(cpu_HI[0], 0); 2045 tcg_gen_br(l1); 2046 gen_set_label(l2); 2047 tcg_gen_div_tl(cpu_LO[0], t0, t1); 2048 tcg_gen_rem_tl(cpu_HI[0], t0, t1); 2049 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); 2050 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); 2051 gen_set_label(l1); 2052 } 2053 opn = "div"; 2054 break; 2055 case OPC_DIVU: 2056 { 2057 int l1 = gen_new_label(); 2058 2059 tcg_gen_ext32u_tl(t0, t0); 2060 tcg_gen_ext32u_tl(t1, t1); 2061 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2062 tcg_gen_divu_tl(cpu_LO[0], t0, t1); 2063 tcg_gen_remu_tl(cpu_HI[0], t0, t1); 2064 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]); 2065 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]); 2066 gen_set_label(l1); 2067 } 2068 opn = "divu"; 2069 break; 2070 case OPC_MULT: 2071 { 2072 TCGv_i64 t2 = tcg_temp_new_i64(); 2073 TCGv_i64 t3 = tcg_temp_new_i64(); 2074 2075 tcg_gen_ext_tl_i64(t2, t0); 2076 tcg_gen_ext_tl_i64(t3, t1); 2077 tcg_gen_mul_i64(t2, t2, t3); 2078 tcg_temp_free_i64(t3); 2079 tcg_gen_trunc_i64_tl(t0, t2); 2080 tcg_gen_shri_i64(t2, t2, 32); 2081 tcg_gen_trunc_i64_tl(t1, t2); 2082 tcg_temp_free_i64(t2); 2083 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2084 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2085 } 2086 opn = "mult"; 2087 break; 2088 case OPC_MULTU: 2089 { 2090 TCGv_i64 t2 = tcg_temp_new_i64(); 2091 TCGv_i64 t3 = tcg_temp_new_i64(); 2092 2093 tcg_gen_ext32u_tl(t0, t0); 2094 tcg_gen_ext32u_tl(t1, t1); 2095 tcg_gen_extu_tl_i64(t2, t0); 2096 tcg_gen_extu_tl_i64(t3, t1); 2097 tcg_gen_mul_i64(t2, t2, t3); 2098 tcg_temp_free_i64(t3); 2099 tcg_gen_trunc_i64_tl(t0, t2); 2100 tcg_gen_shri_i64(t2, t2, 32); 2101 tcg_gen_trunc_i64_tl(t1, t2); 2102 tcg_temp_free_i64(t2); 2103 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2104 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2105 } 2106 opn = "multu"; 2107 break; 2108#if defined(TARGET_MIPS64) 2109 case OPC_DDIV: 2110 { 2111 int l1 = gen_new_label(); 2112 int l2 = gen_new_label(); 2113 2114 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2115 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 2116 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 2117 tcg_gen_mov_tl(cpu_LO[0], t0); 2118 tcg_gen_movi_tl(cpu_HI[0], 0); 2119 tcg_gen_br(l1); 2120 gen_set_label(l2); 2121 tcg_gen_div_i64(cpu_LO[0], t0, t1); 2122 tcg_gen_rem_i64(cpu_HI[0], t0, t1); 2123 gen_set_label(l1); 2124 } 2125 opn = "ddiv"; 2126 break; 2127 case OPC_DDIVU: 2128 { 2129 int l1 = gen_new_label(); 2130 2131 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 2132 tcg_gen_divu_i64(cpu_LO[0], t0, t1); 2133 tcg_gen_remu_i64(cpu_HI[0], t0, t1); 2134 gen_set_label(l1); 2135 } 2136 opn = "ddivu"; 2137 break; 2138 case OPC_DMULT: 2139 gen_helper_dmult(t0, t1); 2140 opn = "dmult"; 2141 break; 2142 case OPC_DMULTU: 2143 gen_helper_dmultu(t0, t1); 2144 opn = "dmultu"; 2145 break; 2146#endif 2147 case OPC_MADD: 2148 { 2149 TCGv_i64 t2 = tcg_temp_new_i64(); 2150 TCGv_i64 t3 = tcg_temp_new_i64(); 2151 2152 tcg_gen_ext_tl_i64(t2, t0); 2153 tcg_gen_ext_tl_i64(t3, t1); 2154 tcg_gen_mul_i64(t2, t2, t3); 2155 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2156 tcg_gen_add_i64(t2, t2, t3); 2157 tcg_temp_free_i64(t3); 2158 tcg_gen_trunc_i64_tl(t0, t2); 2159 tcg_gen_shri_i64(t2, t2, 32); 2160 tcg_gen_trunc_i64_tl(t1, t2); 2161 tcg_temp_free_i64(t2); 2162 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2163 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2164 } 2165 opn = "madd"; 2166 break; 2167 case OPC_MADDU: 2168 { 2169 TCGv_i64 t2 = tcg_temp_new_i64(); 2170 TCGv_i64 t3 = tcg_temp_new_i64(); 2171 2172 tcg_gen_ext32u_tl(t0, t0); 2173 tcg_gen_ext32u_tl(t1, t1); 2174 tcg_gen_extu_tl_i64(t2, t0); 2175 tcg_gen_extu_tl_i64(t3, t1); 2176 tcg_gen_mul_i64(t2, t2, t3); 2177 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2178 tcg_gen_add_i64(t2, t2, t3); 2179 tcg_temp_free_i64(t3); 2180 tcg_gen_trunc_i64_tl(t0, t2); 2181 tcg_gen_shri_i64(t2, t2, 32); 2182 tcg_gen_trunc_i64_tl(t1, t2); 2183 tcg_temp_free_i64(t2); 2184 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2185 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2186 } 2187 opn = "maddu"; 2188 break; 2189 case OPC_MSUB: 2190 { 2191 TCGv_i64 t2 = tcg_temp_new_i64(); 2192 TCGv_i64 t3 = tcg_temp_new_i64(); 2193 2194 tcg_gen_ext_tl_i64(t2, t0); 2195 tcg_gen_ext_tl_i64(t3, t1); 2196 tcg_gen_mul_i64(t2, t2, t3); 2197 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2198 tcg_gen_sub_i64(t2, t3, t2); 2199 tcg_temp_free_i64(t3); 2200 tcg_gen_trunc_i64_tl(t0, t2); 2201 tcg_gen_shri_i64(t2, t2, 32); 2202 tcg_gen_trunc_i64_tl(t1, t2); 2203 tcg_temp_free_i64(t2); 2204 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2205 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2206 } 2207 opn = "msub"; 2208 break; 2209 case OPC_MSUBU: 2210 { 2211 TCGv_i64 t2 = tcg_temp_new_i64(); 2212 TCGv_i64 t3 = tcg_temp_new_i64(); 2213 2214 tcg_gen_ext32u_tl(t0, t0); 2215 tcg_gen_ext32u_tl(t1, t1); 2216 tcg_gen_extu_tl_i64(t2, t0); 2217 tcg_gen_extu_tl_i64(t3, t1); 2218 tcg_gen_mul_i64(t2, t2, t3); 2219 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]); 2220 tcg_gen_sub_i64(t2, t3, t2); 2221 tcg_temp_free_i64(t3); 2222 tcg_gen_trunc_i64_tl(t0, t2); 2223 tcg_gen_shri_i64(t2, t2, 32); 2224 tcg_gen_trunc_i64_tl(t1, t2); 2225 tcg_temp_free_i64(t2); 2226 tcg_gen_ext32s_tl(cpu_LO[0], t0); 2227 tcg_gen_ext32s_tl(cpu_HI[0], t1); 2228 } 2229 opn = "msubu"; 2230 break; 2231 default: 2232 MIPS_INVAL(opn); 2233 generate_exception(ctx, EXCP_RI); 2234 goto out; 2235 } 2236 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); 2237 out: 2238 tcg_temp_free(t0); 2239 tcg_temp_free(t1); 2240} 2241 2242static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, 2243 int rd, int rs, int rt) 2244{ 2245 const char* __attribute__((unused)) opn = "mul vr54xx"; 2246 TCGv t0 = tcg_temp_new(); 2247 TCGv t1 = tcg_temp_new(); 2248 2249 gen_load_gpr(t0, rs); 2250 gen_load_gpr(t1, rt); 2251 2252 switch (opc) { 2253 case OPC_VR54XX_MULS: 2254 gen_helper_muls(t0, cpu_env, t0, t1); 2255 opn = "muls"; 2256 break; 2257 case OPC_VR54XX_MULSU: 2258 gen_helper_mulsu(t0, cpu_env, t0, t1); 2259 opn = "mulsu"; 2260 break; 2261 case OPC_VR54XX_MACC: 2262 gen_helper_macc(t0, cpu_env, t0, t1); 2263 opn = "macc"; 2264 break; 2265 case OPC_VR54XX_MACCU: 2266 gen_helper_maccu(t0, cpu_env, t0, t1); 2267 opn = "maccu"; 2268 break; 2269 case OPC_VR54XX_MSAC: 2270 gen_helper_msac(t0, cpu_env, t0, t1); 2271 opn = "msac"; 2272 break; 2273 case OPC_VR54XX_MSACU: 2274 gen_helper_msacu(t0, cpu_env, t0, t1); 2275 opn = "msacu"; 2276 break; 2277 case OPC_VR54XX_MULHI: 2278 gen_helper_mulhi(t0, cpu_env, t0, t1); 2279 opn = "mulhi"; 2280 break; 2281 case OPC_VR54XX_MULHIU: 2282 gen_helper_mulhiu(t0, cpu_env, t0, t1); 2283 opn = "mulhiu"; 2284 break; 2285 case OPC_VR54XX_MULSHI: 2286 gen_helper_mulshi(t0, cpu_env, t0, t1); 2287 opn = "mulshi"; 2288 break; 2289 case OPC_VR54XX_MULSHIU: 2290 gen_helper_mulshiu(t0, cpu_env, t0, t1); 2291 opn = "mulshiu"; 2292 break; 2293 case OPC_VR54XX_MACCHI: 2294 gen_helper_macchi(t0, cpu_env, t0, t1); 2295 opn = "macchi"; 2296 break; 2297 case OPC_VR54XX_MACCHIU: 2298 gen_helper_macchiu(t0, cpu_env, t0, t1); 2299 opn = "macchiu"; 2300 break; 2301 case OPC_VR54XX_MSACHI: 2302 gen_helper_msachi(t0, cpu_env, t0, t1); 2303 opn = "msachi"; 2304 break; 2305 case OPC_VR54XX_MSACHIU: 2306 gen_helper_msachiu(t0, cpu_env, t0, t1); 2307 opn = "msachiu"; 2308 break; 2309 default: 2310 MIPS_INVAL("mul vr54xx"); 2311 generate_exception(ctx, EXCP_RI); 2312 goto out; 2313 } 2314 gen_store_gpr(t0, rd); 2315 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); 2316 2317 out: 2318 tcg_temp_free(t0); 2319 tcg_temp_free(t1); 2320} 2321 2322static void gen_cl (DisasContext *ctx, uint32_t opc, 2323 int rd, int rs) 2324{ 2325 const char* __attribute__((unused)) opn = "CLx"; 2326 TCGv t0; 2327 2328 if (rd == 0) { 2329 /* Treat as NOP. */ 2330 MIPS_DEBUG("NOP"); 2331 return; 2332 } 2333 t0 = tcg_temp_new(); 2334 gen_load_gpr(t0, rs); 2335 switch (opc) { 2336 case OPC_CLO: 2337 gen_helper_clo(cpu_gpr[rd], t0); 2338 opn = "clo"; 2339 break; 2340 case OPC_CLZ: 2341 gen_helper_clz(cpu_gpr[rd], t0); 2342 opn = "clz"; 2343 break; 2344#if defined(TARGET_MIPS64) 2345 case OPC_DCLO: 2346 gen_helper_dclo(cpu_gpr[rd], t0); 2347 opn = "dclo"; 2348 break; 2349 case OPC_DCLZ: 2350 gen_helper_dclz(cpu_gpr[rd], t0); 2351 opn = "dclz"; 2352 break; 2353#endif 2354 } 2355 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]); 2356 tcg_temp_free(t0); 2357} 2358 2359/* Traps */ 2360static void gen_trap (DisasContext *ctx, uint32_t opc, 2361 int rs, int rt, int16_t imm) 2362{ 2363 int cond; 2364 TCGv t0 = tcg_temp_new(); 2365 TCGv t1 = tcg_temp_new(); 2366 2367 cond = 0; 2368 /* Load needed operands */ 2369 switch (opc) { 2370 case OPC_TEQ: 2371 case OPC_TGE: 2372 case OPC_TGEU: 2373 case OPC_TLT: 2374 case OPC_TLTU: 2375 case OPC_TNE: 2376 /* Compare two registers */ 2377 if (rs != rt) { 2378 gen_load_gpr(t0, rs); 2379 gen_load_gpr(t1, rt); 2380 cond = 1; 2381 } 2382 break; 2383 case OPC_TEQI: 2384 case OPC_TGEI: 2385 case OPC_TGEIU: 2386 case OPC_TLTI: 2387 case OPC_TLTIU: 2388 case OPC_TNEI: 2389 /* Compare register to immediate */ 2390 if (rs != 0 || imm != 0) { 2391 gen_load_gpr(t0, rs); 2392 tcg_gen_movi_tl(t1, (int32_t)imm); 2393 cond = 1; 2394 } 2395 break; 2396 } 2397 if (cond == 0) { 2398 switch (opc) { 2399 case OPC_TEQ: /* rs == rs */ 2400 case OPC_TEQI: /* r0 == 0 */ 2401 case OPC_TGE: /* rs >= rs */ 2402 case OPC_TGEI: /* r0 >= 0 */ 2403 case OPC_TGEU: /* rs >= rs unsigned */ 2404 case OPC_TGEIU: /* r0 >= 0 unsigned */ 2405 /* Always trap */ 2406 generate_exception(ctx, EXCP_TRAP); 2407 break; 2408 case OPC_TLT: /* rs < rs */ 2409 case OPC_TLTI: /* r0 < 0 */ 2410 case OPC_TLTU: /* rs < rs unsigned */ 2411 case OPC_TLTIU: /* r0 < 0 unsigned */ 2412 case OPC_TNE: /* rs != rs */ 2413 case OPC_TNEI: /* r0 != 0 */ 2414 /* Never trap: treat as NOP. */ 2415 break; 2416 } 2417 } else { 2418 int l1 = gen_new_label(); 2419 2420 switch (opc) { 2421 case OPC_TEQ: 2422 case OPC_TEQI: 2423 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 2424 break; 2425 case OPC_TGE: 2426 case OPC_TGEI: 2427 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 2428 break; 2429 case OPC_TGEU: 2430 case OPC_TGEIU: 2431 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 2432 break; 2433 case OPC_TLT: 2434 case OPC_TLTI: 2435 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 2436 break; 2437 case OPC_TLTU: 2438 case OPC_TLTIU: 2439 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 2440 break; 2441 case OPC_TNE: 2442 case OPC_TNEI: 2443 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 2444 break; 2445 } 2446 generate_exception(ctx, EXCP_TRAP); 2447 gen_set_label(l1); 2448 } 2449 tcg_temp_free(t0); 2450 tcg_temp_free(t1); 2451} 2452 2453static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 2454{ 2455 TranslationBlock *tb; 2456 tb = ctx->tb; 2457 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && 2458 likely(!ctx->singlestep_enabled)) { 2459 tcg_gen_goto_tb(n); 2460 gen_save_pc(dest); 2461 tcg_gen_exit_tb((long)tb + n); 2462 } else { 2463 gen_save_pc(dest); 2464 if (ctx->singlestep_enabled) { 2465 save_cpu_state(ctx, 0); 2466 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 2467 } 2468 tcg_gen_exit_tb(0); 2469 } 2470} 2471 2472/* Branches (before delay slot) */ 2473static void gen_compute_branch (DisasContext *ctx, uint32_t opc, 2474 int rs, int rt, int32_t offset) 2475{ 2476 target_ulong btgt = -1; 2477 int blink = 0; 2478 int bcond_compute = 0; 2479 TCGv t0 = tcg_temp_new(); 2480 TCGv t1 = tcg_temp_new(); 2481 2482 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2483#ifdef MIPS_DEBUG_DISAS 2484 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc); 2485#endif 2486 generate_exception(ctx, EXCP_RI); 2487 goto out; 2488 } 2489 2490 /* Load needed operands */ 2491 switch (opc) { 2492 case OPC_BEQ: 2493 case OPC_BEQL: 2494 case OPC_BNE: 2495 case OPC_BNEL: 2496 /* Compare two registers */ 2497 if (rs != rt) { 2498 gen_load_gpr(t0, rs); 2499 gen_load_gpr(t1, rt); 2500 bcond_compute = 1; 2501 } 2502 btgt = ctx->pc + 4 + offset; 2503 break; 2504 case OPC_BGEZ: 2505 case OPC_BGEZAL: 2506 case OPC_BGEZALL: 2507 case OPC_BGEZL: 2508 case OPC_BGTZ: 2509 case OPC_BGTZL: 2510 case OPC_BLEZ: 2511 case OPC_BLEZL: 2512 case OPC_BLTZ: 2513 case OPC_BLTZAL: 2514 case OPC_BLTZALL: 2515 case OPC_BLTZL: 2516 /* Compare to zero */ 2517 if (rs != 0) { 2518 gen_load_gpr(t0, rs); 2519 bcond_compute = 1; 2520 } 2521 btgt = ctx->pc + 4 + offset; 2522 break; 2523 case OPC_J: 2524 case OPC_JAL: 2525 /* Jump to immediate */ 2526 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset; 2527 break; 2528 case OPC_JR: 2529 case OPC_JALR: 2530 /* Jump to register */ 2531 if (offset != 0 && offset != 16) { 2532 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 2533 others are reserved. */ 2534 MIPS_INVAL("jump hint"); 2535 generate_exception(ctx, EXCP_RI); 2536 goto out; 2537 } 2538 gen_load_gpr(btarget, rs); 2539 break; 2540 default: 2541 MIPS_INVAL("branch/jump"); 2542 generate_exception(ctx, EXCP_RI); 2543 goto out; 2544 } 2545 if (bcond_compute == 0) { 2546 /* No condition to be computed */ 2547 switch (opc) { 2548 case OPC_BEQ: /* rx == rx */ 2549 case OPC_BEQL: /* rx == rx likely */ 2550 case OPC_BGEZ: /* 0 >= 0 */ 2551 case OPC_BGEZL: /* 0 >= 0 likely */ 2552 case OPC_BLEZ: /* 0 <= 0 */ 2553 case OPC_BLEZL: /* 0 <= 0 likely */ 2554 /* Always take */ 2555 ctx->hflags |= MIPS_HFLAG_B; 2556 MIPS_DEBUG("balways"); 2557 break; 2558 case OPC_BGEZAL: /* 0 >= 0 */ 2559 case OPC_BGEZALL: /* 0 >= 0 likely */ 2560 /* Always take and link */ 2561 blink = 31; 2562 ctx->hflags |= MIPS_HFLAG_B; 2563 MIPS_DEBUG("balways and link"); 2564 break; 2565 case OPC_BNE: /* rx != rx */ 2566 case OPC_BGTZ: /* 0 > 0 */ 2567 case OPC_BLTZ: /* 0 < 0 */ 2568 /* Treat as NOP. */ 2569 MIPS_DEBUG("bnever (NOP)"); 2570 goto out; 2571 case OPC_BLTZAL: /* 0 < 0 */ 2572 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); 2573 MIPS_DEBUG("bnever and link"); 2574 goto out; 2575 case OPC_BLTZALL: /* 0 < 0 likely */ 2576 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8); 2577 /* Skip the instruction in the delay slot */ 2578 MIPS_DEBUG("bnever, link and skip"); 2579 ctx->pc += 4; 2580 goto out; 2581 case OPC_BNEL: /* rx != rx likely */ 2582 case OPC_BGTZL: /* 0 > 0 likely */ 2583 case OPC_BLTZL: /* 0 < 0 likely */ 2584 /* Skip the instruction in the delay slot */ 2585 MIPS_DEBUG("bnever and skip"); 2586 ctx->pc += 4; 2587 goto out; 2588 case OPC_J: 2589 ctx->hflags |= MIPS_HFLAG_B; 2590 MIPS_DEBUG("j " TARGET_FMT_lx, btgt); 2591 break; 2592 case OPC_JAL: 2593 blink = 31; 2594 ctx->hflags |= MIPS_HFLAG_B; 2595 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt); 2596 break; 2597 case OPC_JR: 2598 ctx->hflags |= MIPS_HFLAG_BR; 2599 MIPS_DEBUG("jr %s", regnames[rs]); 2600 break; 2601 case OPC_JALR: 2602 blink = rt; 2603 ctx->hflags |= MIPS_HFLAG_BR; 2604 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]); 2605 break; 2606 default: 2607 MIPS_INVAL("branch/jump"); 2608 generate_exception(ctx, EXCP_RI); 2609 goto out; 2610 } 2611 } else { 2612 switch (opc) { 2613 case OPC_BEQ: 2614 gen_op_eq(bcond, t0, t1); 2615 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, 2616 regnames[rs], regnames[rt], btgt); 2617 goto not_likely; 2618 case OPC_BEQL: 2619 gen_op_eq(bcond, t0, t1); 2620 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, 2621 regnames[rs], regnames[rt], btgt); 2622 goto likely; 2623 case OPC_BNE: 2624 gen_op_ne(bcond, t0, t1); 2625 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, 2626 regnames[rs], regnames[rt], btgt); 2627 goto not_likely; 2628 case OPC_BNEL: 2629 gen_op_ne(bcond, t0, t1); 2630 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, 2631 regnames[rs], regnames[rt], btgt); 2632 goto likely; 2633 case OPC_BGEZ: 2634 gen_op_gez(bcond, t0); 2635 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt); 2636 goto not_likely; 2637 case OPC_BGEZL: 2638 gen_op_gez(bcond, t0); 2639 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2640 goto likely; 2641 case OPC_BGEZAL: 2642 gen_op_gez(bcond, t0); 2643 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt); 2644 blink = 31; 2645 goto not_likely; 2646 case OPC_BGEZALL: 2647 gen_op_gez(bcond, t0); 2648 blink = 31; 2649 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt); 2650 goto likely; 2651 case OPC_BGTZ: 2652 gen_op_gtz(bcond, t0); 2653 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt); 2654 goto not_likely; 2655 case OPC_BGTZL: 2656 gen_op_gtz(bcond, t0); 2657 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2658 goto likely; 2659 case OPC_BLEZ: 2660 gen_op_lez(bcond, t0); 2661 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt); 2662 goto not_likely; 2663 case OPC_BLEZL: 2664 gen_op_lez(bcond, t0); 2665 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2666 goto likely; 2667 case OPC_BLTZ: 2668 gen_op_ltz(bcond, t0); 2669 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt); 2670 goto not_likely; 2671 case OPC_BLTZL: 2672 gen_op_ltz(bcond, t0); 2673 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt); 2674 goto likely; 2675 case OPC_BLTZAL: 2676 gen_op_ltz(bcond, t0); 2677 blink = 31; 2678 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt); 2679 not_likely: 2680 ctx->hflags |= MIPS_HFLAG_BC; 2681 break; 2682 case OPC_BLTZALL: 2683 gen_op_ltz(bcond, t0); 2684 blink = 31; 2685 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt); 2686 likely: 2687 ctx->hflags |= MIPS_HFLAG_BL; 2688 break; 2689 default: 2690 MIPS_INVAL("conditional branch/jump"); 2691 generate_exception(ctx, EXCP_RI); 2692 goto out; 2693 } 2694 } 2695 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, 2696 blink, ctx->hflags, btgt); 2697 2698 ctx->btarget = btgt; 2699 if (blink > 0) { 2700 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8); 2701 } 2702 2703 out: 2704 tcg_temp_free(t0); 2705 tcg_temp_free(t1); 2706} 2707 2708/* special3 bitfield operations */ 2709static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, 2710 int rs, int lsb, int msb) 2711{ 2712 TCGv t0 = tcg_temp_new(); 2713 TCGv t1 = tcg_temp_new(); 2714 target_ulong mask; 2715 2716 gen_load_gpr(t1, rs); 2717 switch (opc) { 2718 case OPC_EXT: 2719 if (lsb + msb > 31) 2720 goto fail; 2721 tcg_gen_shri_tl(t0, t1, lsb); 2722 if (msb != 31) { 2723 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1); 2724 } else { 2725 tcg_gen_ext32s_tl(t0, t0); 2726 } 2727 break; 2728#if defined(TARGET_MIPS64) 2729 case OPC_DEXTM: 2730 tcg_gen_shri_tl(t0, t1, lsb); 2731 if (msb != 31) { 2732 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1); 2733 } 2734 break; 2735 case OPC_DEXTU: 2736 tcg_gen_shri_tl(t0, t1, lsb + 32); 2737 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); 2738 break; 2739 case OPC_DEXT: 2740 tcg_gen_shri_tl(t0, t1, lsb); 2741 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); 2742 break; 2743#endif 2744 case OPC_INS: 2745 if (lsb > msb) 2746 goto fail; 2747 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb; 2748 gen_load_gpr(t0, rt); 2749 tcg_gen_andi_tl(t0, t0, ~mask); 2750 tcg_gen_shli_tl(t1, t1, lsb); 2751 tcg_gen_andi_tl(t1, t1, mask); 2752 tcg_gen_or_tl(t0, t0, t1); 2753 tcg_gen_ext32s_tl(t0, t0); 2754 break; 2755#if defined(TARGET_MIPS64) 2756 case OPC_DINSM: 2757 if (lsb > msb) 2758 goto fail; 2759 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb; 2760 gen_load_gpr(t0, rt); 2761 tcg_gen_andi_tl(t0, t0, ~mask); 2762 tcg_gen_shli_tl(t1, t1, lsb); 2763 tcg_gen_andi_tl(t1, t1, mask); 2764 tcg_gen_or_tl(t0, t0, t1); 2765 break; 2766 case OPC_DINSU: 2767 if (lsb > msb) 2768 goto fail; 2769 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32); 2770 gen_load_gpr(t0, rt); 2771 tcg_gen_andi_tl(t0, t0, ~mask); 2772 tcg_gen_shli_tl(t1, t1, lsb + 32); 2773 tcg_gen_andi_tl(t1, t1, mask); 2774 tcg_gen_or_tl(t0, t0, t1); 2775 break; 2776 case OPC_DINS: 2777 if (lsb > msb) 2778 goto fail; 2779 gen_load_gpr(t0, rt); 2780 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb; 2781 gen_load_gpr(t0, rt); 2782 tcg_gen_andi_tl(t0, t0, ~mask); 2783 tcg_gen_shli_tl(t1, t1, lsb); 2784 tcg_gen_andi_tl(t1, t1, mask); 2785 tcg_gen_or_tl(t0, t0, t1); 2786 break; 2787#endif 2788 default: 2789fail: 2790 MIPS_INVAL("bitops"); 2791 generate_exception(ctx, EXCP_RI); 2792 tcg_temp_free(t0); 2793 tcg_temp_free(t1); 2794 return; 2795 } 2796 gen_store_gpr(t0, rt); 2797 tcg_temp_free(t0); 2798 tcg_temp_free(t1); 2799} 2800 2801static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd) 2802{ 2803 TCGv t0; 2804 2805 if (rd == 0) { 2806 /* If no destination, treat it as a NOP. */ 2807 MIPS_DEBUG("NOP"); 2808 return; 2809 } 2810 2811 t0 = tcg_temp_new(); 2812 gen_load_gpr(t0, rt); 2813 switch (op2) { 2814 case OPC_WSBH: 2815 { 2816 TCGv t1 = tcg_temp_new(); 2817 2818 tcg_gen_shri_tl(t1, t0, 8); 2819 tcg_gen_andi_tl(t1, t1, 0x00FF00FF); 2820 tcg_gen_shli_tl(t0, t0, 8); 2821 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF); 2822 tcg_gen_or_tl(t0, t0, t1); 2823 tcg_temp_free(t1); 2824 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2825 } 2826 break; 2827 case OPC_SEB: 2828 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 2829 break; 2830 case OPC_SEH: 2831 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 2832 break; 2833#if defined(TARGET_MIPS64) 2834 case OPC_DSBH: 2835 { 2836 TCGv t1 = tcg_temp_new(); 2837 2838 tcg_gen_shri_tl(t1, t0, 8); 2839 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL); 2840 tcg_gen_shli_tl(t0, t0, 8); 2841 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL); 2842 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 2843 tcg_temp_free(t1); 2844 } 2845 break; 2846 case OPC_DSHD: 2847 { 2848 TCGv t1 = tcg_temp_new(); 2849 2850 tcg_gen_shri_tl(t1, t0, 16); 2851 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL); 2852 tcg_gen_shli_tl(t0, t0, 16); 2853 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL); 2854 tcg_gen_or_tl(t0, t0, t1); 2855 tcg_gen_shri_tl(t1, t0, 32); 2856 tcg_gen_shli_tl(t0, t0, 32); 2857 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 2858 tcg_temp_free(t1); 2859 } 2860 break; 2861#endif 2862 default: 2863 MIPS_INVAL("bsfhl"); 2864 generate_exception(ctx, EXCP_RI); 2865 tcg_temp_free(t0); 2866 return; 2867 } 2868 tcg_temp_free(t0); 2869} 2870 2871#ifndef CONFIG_USER_ONLY 2872/* CP0 (MMU and control) */ 2873static inline void gen_mfc0_load32 (TCGv arg, target_ulong off) 2874{ 2875 TCGv_i32 t0 = tcg_temp_new_i32(); 2876 2877 tcg_gen_ld_i32(t0, cpu_env, off); 2878 tcg_gen_ext_i32_tl(arg, t0); 2879 tcg_temp_free_i32(t0); 2880} 2881 2882static inline void gen_mfc0_load64 (TCGv arg, target_ulong off) 2883{ 2884 tcg_gen_ld_tl(arg, cpu_env, off); 2885 tcg_gen_ext32s_tl(arg, arg); 2886} 2887 2888static inline void gen_mtc0_store32 (TCGv arg, target_ulong off) 2889{ 2890 TCGv_i32 t0 = tcg_temp_new_i32(); 2891 2892 tcg_gen_trunc_tl_i32(t0, arg); 2893 tcg_gen_st_i32(t0, cpu_env, off); 2894 tcg_temp_free_i32(t0); 2895} 2896 2897static inline void gen_mtc0_store64 (TCGv arg, target_ulong off) 2898{ 2899 tcg_gen_ext32s_tl(arg, arg); 2900 tcg_gen_st_tl(arg, cpu_env, off); 2901} 2902 2903static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 2904{ 2905 const char * __attribute__((unused)) rn = "invalid"; 2906 2907 if (sel != 0) 2908 check_insn(env, ctx, ISA_MIPS32); 2909 2910 switch (reg) { 2911 case 0: 2912 switch (sel) { 2913 case 0: 2914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 2915 rn = "Index"; 2916 break; 2917 case 1: 2918 check_insn(env, ctx, ASE_MT); 2919 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 2920 rn = "MVPControl"; 2921 break; 2922 case 2: 2923 check_insn(env, ctx, ASE_MT); 2924 gen_helper_mfc0_mvpconf0(arg, cpu_env); 2925 rn = "MVPConf0"; 2926 break; 2927 case 3: 2928 check_insn(env, ctx, ASE_MT); 2929 gen_helper_mfc0_mvpconf1(arg, cpu_env); 2930 rn = "MVPConf1"; 2931 break; 2932 default: 2933 goto die; 2934 } 2935 break; 2936 case 1: 2937 switch (sel) { 2938 case 0: 2939 gen_helper_mfc0_random(arg, cpu_env); 2940 rn = "Random"; 2941 break; 2942 case 1: 2943 check_insn(env, ctx, ASE_MT); 2944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 2945 rn = "VPEControl"; 2946 break; 2947 case 2: 2948 check_insn(env, ctx, ASE_MT); 2949 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 2950 rn = "VPEConf0"; 2951 break; 2952 case 3: 2953 check_insn(env, ctx, ASE_MT); 2954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 2955 rn = "VPEConf1"; 2956 break; 2957 case 4: 2958 check_insn(env, ctx, ASE_MT); 2959 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 2960 rn = "YQMask"; 2961 break; 2962 case 5: 2963 check_insn(env, ctx, ASE_MT); 2964 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 2965 rn = "VPESchedule"; 2966 break; 2967 case 6: 2968 check_insn(env, ctx, ASE_MT); 2969 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 2970 rn = "VPEScheFBack"; 2971 break; 2972 case 7: 2973 check_insn(env, ctx, ASE_MT); 2974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 2975 rn = "VPEOpt"; 2976 break; 2977 default: 2978 goto die; 2979 } 2980 break; 2981 case 2: 2982 switch (sel) { 2983 case 0: 2984 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); 2985 tcg_gen_ext32s_tl(arg, arg); 2986 rn = "EntryLo0"; 2987 break; 2988 case 1: 2989 check_insn(env, ctx, ASE_MT); 2990 gen_helper_mfc0_tcstatus(arg, cpu_env); 2991 rn = "TCStatus"; 2992 break; 2993 case 2: 2994 check_insn(env, ctx, ASE_MT); 2995 gen_helper_mfc0_tcbind(arg, cpu_env); 2996 rn = "TCBind"; 2997 break; 2998 case 3: 2999 check_insn(env, ctx, ASE_MT); 3000 gen_helper_mfc0_tcrestart(arg, cpu_env); 3001 rn = "TCRestart"; 3002 break; 3003 case 4: 3004 check_insn(env, ctx, ASE_MT); 3005 gen_helper_mfc0_tchalt(arg, cpu_env); 3006 rn = "TCHalt"; 3007 break; 3008 case 5: 3009 check_insn(env, ctx, ASE_MT); 3010 gen_helper_mfc0_tccontext(arg, cpu_env); 3011 rn = "TCContext"; 3012 break; 3013 case 6: 3014 check_insn(env, ctx, ASE_MT); 3015 gen_helper_mfc0_tcschedule(arg, cpu_env); 3016 rn = "TCSchedule"; 3017 break; 3018 case 7: 3019 check_insn(env, ctx, ASE_MT); 3020 gen_helper_mfc0_tcschefback(arg, cpu_env); 3021 rn = "TCScheFBack"; 3022 break; 3023 default: 3024 goto die; 3025 } 3026 break; 3027 case 3: 3028 switch (sel) { 3029 case 0: 3030 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 3031 tcg_gen_ext32s_tl(arg, arg); 3032 rn = "EntryLo1"; 3033 break; 3034 default: 3035 goto die; 3036 } 3037 break; 3038 case 4: 3039 switch (sel) { 3040 case 0: 3041 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 3042 tcg_gen_ext32s_tl(arg, arg); 3043 rn = "Context"; 3044 break; 3045 case 1: 3046// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */ 3047 rn = "ContextConfig"; 3048// break; 3049 default: 3050 goto die; 3051 } 3052 break; 3053 case 5: 3054 switch (sel) { 3055 case 0: 3056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 3057 rn = "PageMask"; 3058 break; 3059 case 1: 3060 check_insn(env, ctx, ISA_MIPS32R2); 3061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 3062 rn = "PageGrain"; 3063 break; 3064 default: 3065 goto die; 3066 } 3067 break; 3068 case 6: 3069 switch (sel) { 3070 case 0: 3071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 3072 rn = "Wired"; 3073 break; 3074 case 1: 3075 check_insn(env, ctx, ISA_MIPS32R2); 3076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 3077 rn = "SRSConf0"; 3078 break; 3079 case 2: 3080 check_insn(env, ctx, ISA_MIPS32R2); 3081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 3082 rn = "SRSConf1"; 3083 break; 3084 case 3: 3085 check_insn(env, ctx, ISA_MIPS32R2); 3086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 3087 rn = "SRSConf2"; 3088 break; 3089 case 4: 3090 check_insn(env, ctx, ISA_MIPS32R2); 3091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 3092 rn = "SRSConf3"; 3093 break; 3094 case 5: 3095 check_insn(env, ctx, ISA_MIPS32R2); 3096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 3097 rn = "SRSConf4"; 3098 break; 3099 default: 3100 goto die; 3101 } 3102 break; 3103 case 7: 3104 switch (sel) { 3105 case 0: 3106 check_insn(env, ctx, ISA_MIPS32R2); 3107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 3108 rn = "HWREna"; 3109 break; 3110 default: 3111 goto die; 3112 } 3113 break; 3114 case 8: 3115 switch (sel) { 3116 case 0: 3117 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 3118 tcg_gen_ext32s_tl(arg, arg); 3119 rn = "BadVAddr"; 3120 break; 3121 default: 3122 goto die; 3123 } 3124 break; 3125 case 9: 3126 switch (sel) { 3127 case 0: 3128 /* Mark as an IO operation because we read the time. */ 3129 if (use_icount) 3130 gen_io_start(); 3131 gen_helper_mfc0_count(arg, cpu_env); 3132 if (use_icount) { 3133 gen_io_end(); 3134 ctx->bstate = BS_STOP; 3135 } 3136 rn = "Count"; 3137 break; 3138 /* 6,7 are implementation dependent */ 3139 default: 3140 goto die; 3141 } 3142 break; 3143 case 10: 3144 switch (sel) { 3145 case 0: 3146 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 3147 tcg_gen_ext32s_tl(arg, arg); 3148 rn = "EntryHi"; 3149 break; 3150 default: 3151 goto die; 3152 } 3153 break; 3154 case 11: 3155 switch (sel) { 3156 case 0: 3157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 3158 rn = "Compare"; 3159 break; 3160 /* 6,7 are implementation dependent */ 3161 default: 3162 goto die; 3163 } 3164 break; 3165 case 12: 3166 switch (sel) { 3167 case 0: 3168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 3169 rn = "Status"; 3170 break; 3171 case 1: 3172 check_insn(env, ctx, ISA_MIPS32R2); 3173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 3174 rn = "IntCtl"; 3175 break; 3176 case 2: 3177 check_insn(env, ctx, ISA_MIPS32R2); 3178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 3179 rn = "SRSCtl"; 3180 break; 3181 case 3: 3182 check_insn(env, ctx, ISA_MIPS32R2); 3183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 3184 rn = "SRSMap"; 3185 break; 3186 default: 3187 goto die; 3188 } 3189 break; 3190 case 13: 3191 switch (sel) { 3192 case 0: 3193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 3194 rn = "Cause"; 3195 break; 3196 default: 3197 goto die; 3198 } 3199 break; 3200 case 14: 3201 switch (sel) { 3202 case 0: 3203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 3204 tcg_gen_ext32s_tl(arg, arg); 3205 rn = "EPC"; 3206 break; 3207 default: 3208 goto die; 3209 } 3210 break; 3211 case 15: 3212 switch (sel) { 3213 case 0: 3214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 3215 rn = "PRid"; 3216 break; 3217 case 1: 3218 check_insn(env, ctx, ISA_MIPS32R2); 3219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase)); 3220 rn = "EBase"; 3221 break; 3222 default: 3223 goto die; 3224 } 3225 break; 3226 case 16: 3227 switch (sel) { 3228 case 0: 3229 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 3230 rn = "Config"; 3231 break; 3232 case 1: 3233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 3234 rn = "Config1"; 3235 break; 3236 case 2: 3237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 3238 rn = "Config2"; 3239 break; 3240 case 3: 3241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 3242 rn = "Config3"; 3243 break; 3244 /* 4,5 are reserved */ 3245 /* 6,7 are implementation dependent */ 3246 case 6: 3247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 3248 rn = "Config6"; 3249 break; 3250 case 7: 3251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 3252 rn = "Config7"; 3253 break; 3254 default: 3255 goto die; 3256 } 3257 break; 3258 case 17: 3259 switch (sel) { 3260 case 0: 3261 gen_helper_mfc0_lladdr(arg, cpu_env); 3262 rn = "LLAddr"; 3263 break; 3264 default: 3265 goto die; 3266 } 3267 break; 3268 case 18: 3269 switch (sel) { 3270 case 0 ... 7: 3271 gen_helper_2i(mfc0_watchlo, arg, cpu_env, sel); 3272 rn = "WatchLo"; 3273 break; 3274 default: 3275 goto die; 3276 } 3277 break; 3278 case 19: 3279 switch (sel) { 3280 case 0 ...7: 3281 gen_helper_2i(mfc0_watchhi, arg, cpu_env, sel); 3282 rn = "WatchHi"; 3283 break; 3284 default: 3285 goto die; 3286 } 3287 break; 3288 case 20: 3289 switch (sel) { 3290 case 0: 3291#if defined(TARGET_MIPS64) 3292 check_insn(env, ctx, ISA_MIPS3); 3293 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 3294 tcg_gen_ext32s_tl(arg, arg); 3295 rn = "XContext"; 3296 break; 3297#endif 3298 default: 3299 goto die; 3300 } 3301 break; 3302 case 21: 3303 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 3304 switch (sel) { 3305 case 0: 3306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 3307 rn = "Framemask"; 3308 break; 3309 default: 3310 goto die; 3311 } 3312 break; 3313 case 22: 3314 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3315 rn = "'Diagnostic"; /* implementation dependent */ 3316 break; 3317 case 23: 3318 switch (sel) { 3319 case 0: 3320 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 3321 rn = "Debug"; 3322 break; 3323 case 1: 3324// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */ 3325 rn = "TraceControl"; 3326// break; 3327 case 2: 3328// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */ 3329 rn = "TraceControl2"; 3330// break; 3331 case 3: 3332// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */ 3333 rn = "UserTraceData"; 3334// break; 3335 case 4: 3336// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */ 3337 rn = "TraceBPC"; 3338// break; 3339 default: 3340 goto die; 3341 } 3342 break; 3343 case 24: 3344 switch (sel) { 3345 case 0: 3346 /* EJTAG support */ 3347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 3348 tcg_gen_ext32s_tl(arg, arg); 3349 rn = "DEPC"; 3350 break; 3351 default: 3352 goto die; 3353 } 3354 break; 3355 case 25: 3356 switch (sel) { 3357 case 0: 3358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 3359 rn = "Performance0"; 3360 break; 3361 case 1: 3362// gen_helper_mfc0_performance1(arg); 3363 rn = "Performance1"; 3364// break; 3365 case 2: 3366// gen_helper_mfc0_performance2(arg); 3367 rn = "Performance2"; 3368// break; 3369 case 3: 3370// gen_helper_mfc0_performance3(arg); 3371 rn = "Performance3"; 3372// break; 3373 case 4: 3374// gen_helper_mfc0_performance4(arg); 3375 rn = "Performance4"; 3376// break; 3377 case 5: 3378// gen_helper_mfc0_performance5(arg); 3379 rn = "Performance5"; 3380// break; 3381 case 6: 3382// gen_helper_mfc0_performance6(arg); 3383 rn = "Performance6"; 3384// break; 3385 case 7: 3386// gen_helper_mfc0_performance7(arg); 3387 rn = "Performance7"; 3388// break; 3389 default: 3390 goto die; 3391 } 3392 break; 3393 case 26: 3394 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3395 rn = "ECC"; 3396 break; 3397 case 27: 3398 switch (sel) { 3399 case 0 ... 3: 3400 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 3401 rn = "CacheErr"; 3402 break; 3403 default: 3404 goto die; 3405 } 3406 break; 3407 case 28: 3408 switch (sel) { 3409 case 0: 3410 case 2: 3411 case 4: 3412 case 6: 3413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 3414 rn = "TagLo"; 3415 break; 3416 case 1: 3417 case 3: 3418 case 5: 3419 case 7: 3420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 3421 rn = "DataLo"; 3422 break; 3423 default: 3424 goto die; 3425 } 3426 break; 3427 case 29: 3428 switch (sel) { 3429 case 0: 3430 case 2: 3431 case 4: 3432 case 6: 3433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 3434 rn = "TagHi"; 3435 break; 3436 case 1: 3437 case 3: 3438 case 5: 3439 case 7: 3440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 3441 rn = "DataHi"; 3442 break; 3443 default: 3444 goto die; 3445 } 3446 break; 3447 case 30: 3448 switch (sel) { 3449 case 0: 3450 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 3451 tcg_gen_ext32s_tl(arg, arg); 3452 rn = "ErrorEPC"; 3453 break; 3454 default: 3455 goto die; 3456 } 3457 break; 3458 case 31: 3459 switch (sel) { 3460 case 0: 3461 /* EJTAG support */ 3462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 3463 rn = "DESAVE"; 3464 break; 3465 default: 3466 goto die; 3467 } 3468 break; 3469 default: 3470 goto die; 3471 } 3472 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel); 3473 return; 3474 3475die: 3476 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel); 3477 generate_exception(ctx, EXCP_RI); 3478} 3479 3480static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 3481{ 3482 const char * __attribute__((unused)) rn = "invalid"; 3483 3484 if (sel != 0) 3485 check_insn(env, ctx, ISA_MIPS32); 3486 3487 if (use_icount) 3488 gen_io_start(); 3489 3490 switch (reg) { 3491 case 0: 3492 switch (sel) { 3493 case 0: 3494 gen_helper_mtc0_index(cpu_env, arg); 3495 rn = "Index"; 3496 break; 3497 case 1: 3498 check_insn(env, ctx, ASE_MT); 3499 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 3500 rn = "MVPControl"; 3501 break; 3502 case 2: 3503 check_insn(env, ctx, ASE_MT); 3504 /* ignored */ 3505 rn = "MVPConf0"; 3506 break; 3507 case 3: 3508 check_insn(env, ctx, ASE_MT); 3509 /* ignored */ 3510 rn = "MVPConf1"; 3511 break; 3512 default: 3513 goto die; 3514 } 3515 break; 3516 case 1: 3517 switch (sel) { 3518 case 0: 3519 /* ignored */ 3520 rn = "Random"; 3521 break; 3522 case 1: 3523 check_insn(env, ctx, ASE_MT); 3524 gen_helper_mtc0_vpecontrol(cpu_env, arg); 3525 rn = "VPEControl"; 3526 break; 3527 case 2: 3528 check_insn(env, ctx, ASE_MT); 3529 gen_helper_mtc0_vpeconf0(cpu_env, arg); 3530 rn = "VPEConf0"; 3531 break; 3532 case 3: 3533 check_insn(env, ctx, ASE_MT); 3534 gen_helper_mtc0_vpeconf1(cpu_env, arg); 3535 rn = "VPEConf1"; 3536 break; 3537 case 4: 3538 check_insn(env, ctx, ASE_MT); 3539 gen_helper_mtc0_yqmask(cpu_env, arg); 3540 rn = "YQMask"; 3541 break; 3542 case 5: 3543 check_insn(env, ctx, ASE_MT); 3544 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 3545 rn = "VPESchedule"; 3546 break; 3547 case 6: 3548 check_insn(env, ctx, ASE_MT); 3549 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 3550 rn = "VPEScheFBack"; 3551 break; 3552 case 7: 3553 check_insn(env, ctx, ASE_MT); 3554 gen_helper_mtc0_vpeopt(cpu_env, arg); 3555 rn = "VPEOpt"; 3556 break; 3557 default: 3558 goto die; 3559 } 3560 break; 3561 case 2: 3562 switch (sel) { 3563 case 0: 3564 gen_helper_mtc0_entrylo0(cpu_env, arg); 3565 rn = "EntryLo0"; 3566 break; 3567 case 1: 3568 check_insn(env, ctx, ASE_MT); 3569 gen_helper_mtc0_tcstatus(cpu_env, arg); 3570 rn = "TCStatus"; 3571 break; 3572 case 2: 3573 check_insn(env, ctx, ASE_MT); 3574 gen_helper_mtc0_tcbind(cpu_env, arg); 3575 rn = "TCBind"; 3576 break; 3577 case 3: 3578 check_insn(env, ctx, ASE_MT); 3579 gen_helper_mtc0_tcrestart(cpu_env, arg); 3580 rn = "TCRestart"; 3581 break; 3582 case 4: 3583 check_insn(env, ctx, ASE_MT); 3584 gen_helper_mtc0_tchalt(cpu_env, arg); 3585 rn = "TCHalt"; 3586 break; 3587 case 5: 3588 check_insn(env, ctx, ASE_MT); 3589 gen_helper_mtc0_tccontext(cpu_env, arg); 3590 rn = "TCContext"; 3591 break; 3592 case 6: 3593 check_insn(env, ctx, ASE_MT); 3594 gen_helper_mtc0_tcschedule(cpu_env, arg); 3595 rn = "TCSchedule"; 3596 break; 3597 case 7: 3598 check_insn(env, ctx, ASE_MT); 3599 gen_helper_mtc0_tcschefback(cpu_env, arg); 3600 rn = "TCScheFBack"; 3601 break; 3602 default: 3603 goto die; 3604 } 3605 break; 3606 case 3: 3607 switch (sel) { 3608 case 0: 3609 gen_helper_mtc0_entrylo1(cpu_env, arg); 3610 rn = "EntryLo1"; 3611 break; 3612 default: 3613 goto die; 3614 } 3615 break; 3616 case 4: 3617 switch (sel) { 3618 case 0: 3619 gen_helper_mtc0_context(cpu_env, arg); 3620 rn = "Context"; 3621 break; 3622 case 1: 3623// gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */ 3624 rn = "ContextConfig"; 3625// break; 3626 default: 3627 goto die; 3628 } 3629 break; 3630 case 5: 3631 switch (sel) { 3632 case 0: 3633 gen_helper_mtc0_pagemask(cpu_env, arg); 3634 rn = "PageMask"; 3635 break; 3636 case 1: 3637 check_insn(env, ctx, ISA_MIPS32R2); 3638 gen_helper_mtc0_pagegrain(cpu_env, arg); 3639 rn = "PageGrain"; 3640 break; 3641 default: 3642 goto die; 3643 } 3644 break; 3645 case 6: 3646 switch (sel) { 3647 case 0: 3648 gen_helper_mtc0_wired(cpu_env, arg); 3649 rn = "Wired"; 3650 break; 3651 case 1: 3652 check_insn(env, ctx, ISA_MIPS32R2); 3653 gen_helper_mtc0_srsconf0(cpu_env, arg); 3654 rn = "SRSConf0"; 3655 break; 3656 case 2: 3657 check_insn(env, ctx, ISA_MIPS32R2); 3658 gen_helper_mtc0_srsconf1(cpu_env, arg); 3659 rn = "SRSConf1"; 3660 break; 3661 case 3: 3662 check_insn(env, ctx, ISA_MIPS32R2); 3663 gen_helper_mtc0_srsconf2(cpu_env, arg); 3664 rn = "SRSConf2"; 3665 break; 3666 case 4: 3667 check_insn(env, ctx, ISA_MIPS32R2); 3668 gen_helper_mtc0_srsconf3(cpu_env, arg); 3669 rn = "SRSConf3"; 3670 break; 3671 case 5: 3672 check_insn(env, ctx, ISA_MIPS32R2); 3673 gen_helper_mtc0_srsconf4(cpu_env, arg); 3674 rn = "SRSConf4"; 3675 break; 3676 default: 3677 goto die; 3678 } 3679 break; 3680 case 7: 3681 switch (sel) { 3682 case 0: 3683 check_insn(env, ctx, ISA_MIPS32R2); 3684 gen_helper_mtc0_hwrena(cpu_env, arg); 3685 rn = "HWREna"; 3686 break; 3687 default: 3688 goto die; 3689 } 3690 break; 3691 case 8: 3692 /* ignored */ 3693 rn = "BadVAddr"; 3694 break; 3695 case 9: 3696 switch (sel) { 3697 case 0: 3698 gen_helper_mtc0_count(cpu_env, arg); 3699 rn = "Count"; 3700 break; 3701 /* 6,7 are implementation dependent */ 3702 default: 3703 goto die; 3704 } 3705 break; 3706 case 10: 3707 switch (sel) { 3708 case 0: 3709 gen_helper_mtc0_entryhi(cpu_env, arg); 3710 rn = "EntryHi"; 3711 break; 3712 default: 3713 goto die; 3714 } 3715 break; 3716 case 11: 3717 switch (sel) { 3718 case 0: 3719 gen_helper_mtc0_compare(cpu_env, arg); 3720 rn = "Compare"; 3721 break; 3722 /* 6,7 are implementation dependent */ 3723 default: 3724 goto die; 3725 } 3726 break; 3727 case 12: 3728 switch (sel) { 3729 case 0: 3730 save_cpu_state(ctx, 1); 3731 gen_helper_mtc0_status(cpu_env, arg); 3732 /* BS_STOP isn't good enough here, hflags may have changed. */ 3733 gen_save_pc(ctx->pc + 4); 3734 ctx->bstate = BS_EXCP; 3735 rn = "Status"; 3736 break; 3737 case 1: 3738 check_insn(env, ctx, ISA_MIPS32R2); 3739 gen_helper_mtc0_intctl(cpu_env, arg); 3740 /* Stop translation as we may have switched the execution mode */ 3741 ctx->bstate = BS_STOP; 3742 rn = "IntCtl"; 3743 break; 3744 case 2: 3745 check_insn(env, ctx, ISA_MIPS32R2); 3746 gen_helper_mtc0_srsctl(cpu_env, arg); 3747 /* Stop translation as we may have switched the execution mode */ 3748 ctx->bstate = BS_STOP; 3749 rn = "SRSCtl"; 3750 break; 3751 case 3: 3752 check_insn(env, ctx, ISA_MIPS32R2); 3753 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 3754 /* Stop translation as we may have switched the execution mode */ 3755 ctx->bstate = BS_STOP; 3756 rn = "SRSMap"; 3757 break; 3758 default: 3759 goto die; 3760 } 3761 break; 3762 case 13: 3763 switch (sel) { 3764 case 0: 3765 save_cpu_state(ctx, 1); 3766 gen_helper_mtc0_cause(cpu_env, arg); 3767 rn = "Cause"; 3768 break; 3769 default: 3770 goto die; 3771 } 3772 break; 3773 case 14: 3774 switch (sel) { 3775 case 0: 3776 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC)); 3777 rn = "EPC"; 3778 break; 3779 default: 3780 goto die; 3781 } 3782 break; 3783 case 15: 3784 switch (sel) { 3785 case 0: 3786 /* ignored */ 3787 rn = "PRid"; 3788 break; 3789 case 1: 3790 check_insn(env, ctx, ISA_MIPS32R2); 3791 gen_helper_mtc0_ebase(cpu_env, arg); 3792 rn = "EBase"; 3793 break; 3794 default: 3795 goto die; 3796 } 3797 break; 3798 case 16: 3799 switch (sel) { 3800 case 0: 3801 gen_helper_mtc0_config0(cpu_env, arg); 3802 rn = "Config"; 3803 /* Stop translation as we may have switched the execution mode */ 3804 ctx->bstate = BS_STOP; 3805 break; 3806 case 1: 3807 /* ignored, read only */ 3808 rn = "Config1"; 3809 break; 3810 case 2: 3811 gen_helper_mtc0_config2(cpu_env, arg); 3812 rn = "Config2"; 3813 /* Stop translation as we may have switched the execution mode */ 3814 ctx->bstate = BS_STOP; 3815 break; 3816 case 3: 3817 /* ignored, read only */ 3818 rn = "Config3"; 3819 break; 3820 /* 4,5 are reserved */ 3821 /* 6,7 are implementation dependent */ 3822 case 6: 3823 /* ignored */ 3824 rn = "Config6"; 3825 break; 3826 case 7: 3827 /* ignored */ 3828 rn = "Config7"; 3829 break; 3830 default: 3831 rn = "Invalid config selector"; 3832 goto die; 3833 } 3834 break; 3835 case 17: 3836 switch (sel) { 3837 case 0: 3838 gen_helper_mtc0_lladdr(cpu_env, arg); 3839 rn = "LLAddr"; 3840 break; 3841 default: 3842 goto die; 3843 } 3844 break; 3845 case 18: 3846 switch (sel) { 3847 case 0 ... 7: 3848 gen_helper_2i(mtc0_watchlo, cpu_env, arg, sel); 3849 rn = "WatchLo"; 3850 break; 3851 default: 3852 goto die; 3853 } 3854 break; 3855 case 19: 3856 switch (sel) { 3857 case 0 ... 7: 3858 gen_helper_2i(mtc0_watchhi, cpu_env, arg, sel); 3859 rn = "WatchHi"; 3860 break; 3861 default: 3862 goto die; 3863 } 3864 break; 3865 case 20: 3866 switch (sel) { 3867 case 0: 3868#if defined(TARGET_MIPS64) 3869 check_insn(env, ctx, ISA_MIPS3); 3870 gen_helper_mtc0_xcontext(cpu_env, arg); 3871 rn = "XContext"; 3872 break; 3873#endif 3874 default: 3875 goto die; 3876 } 3877 break; 3878 case 21: 3879 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 3880 switch (sel) { 3881 case 0: 3882 gen_helper_mtc0_framemask(cpu_env, arg); 3883 rn = "Framemask"; 3884 break; 3885 default: 3886 goto die; 3887 } 3888 break; 3889 case 22: 3890 /* ignored */ 3891 rn = "Diagnostic"; /* implementation dependent */ 3892 break; 3893 case 23: 3894 switch (sel) { 3895 case 0: 3896 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 3897 /* BS_STOP isn't good enough here, hflags may have changed. */ 3898 gen_save_pc(ctx->pc + 4); 3899 ctx->bstate = BS_EXCP; 3900 rn = "Debug"; 3901 break; 3902 case 1: 3903// gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */ 3904 rn = "TraceControl"; 3905 /* Stop translation as we may have switched the execution mode */ 3906 ctx->bstate = BS_STOP; 3907// break; 3908 case 2: 3909// gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */ 3910 rn = "TraceControl2"; 3911 /* Stop translation as we may have switched the execution mode */ 3912 ctx->bstate = BS_STOP; 3913// break; 3914 case 3: 3915 /* Stop translation as we may have switched the execution mode */ 3916 ctx->bstate = BS_STOP; 3917// gen_helper_mtc0_usertracedata(arg); /* PDtrace support */ 3918 rn = "UserTraceData"; 3919 /* Stop translation as we may have switched the execution mode */ 3920 ctx->bstate = BS_STOP; 3921// break; 3922 case 4: 3923// gen_helper_mtc0_tracebpc(arg); /* PDtrace support */ 3924 /* Stop translation as we may have switched the execution mode */ 3925 ctx->bstate = BS_STOP; 3926 rn = "TraceBPC"; 3927// break; 3928 default: 3929 goto die; 3930 } 3931 break; 3932 case 24: 3933 switch (sel) { 3934 case 0: 3935 /* EJTAG support */ 3936 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC)); 3937 rn = "DEPC"; 3938 break; 3939 default: 3940 goto die; 3941 } 3942 break; 3943 case 25: 3944 switch (sel) { 3945 case 0: 3946 gen_helper_mtc0_performance0(cpu_env, arg); 3947 rn = "Performance0"; 3948 break; 3949 case 1: 3950// gen_helper_mtc0_performance1(cpu_env, arg); 3951 rn = "Performance1"; 3952// break; 3953 case 2: 3954// gen_helper_mtc0_performance2(cpu_env, arg); 3955 rn = "Performance2"; 3956// break; 3957 case 3: 3958// gen_helper_mtc0_performance3(cpu_env, arg); 3959 rn = "Performance3"; 3960// break; 3961 case 4: 3962// gen_helper_mtc0_performance4(cpu_env, arg); 3963 rn = "Performance4"; 3964// break; 3965 case 5: 3966// gen_helper_mtc0_performance5(cpu_env, arg); 3967 rn = "Performance5"; 3968// break; 3969 case 6: 3970// gen_helper_mtc0_performance6(cpu_env, arg); 3971 rn = "Performance6"; 3972// break; 3973 case 7: 3974// gen_helper_mtc0_performance7(cpu_env, arg); 3975 rn = "Performance7"; 3976// break; 3977 default: 3978 goto die; 3979 } 3980 break; 3981 case 26: 3982 /* ignored */ 3983 rn = "ECC"; 3984 break; 3985 case 27: 3986 switch (sel) { 3987 case 0 ... 3: 3988 /* ignored */ 3989 rn = "CacheErr"; 3990 break; 3991 default: 3992 goto die; 3993 } 3994 break; 3995 case 28: 3996 switch (sel) { 3997 case 0: 3998 case 2: 3999 case 4: 4000 case 6: 4001 gen_helper_mtc0_taglo(cpu_env, arg); 4002 rn = "TagLo"; 4003 break; 4004 case 1: 4005 case 3: 4006 case 5: 4007 case 7: 4008 gen_helper_mtc0_datalo(cpu_env, arg); 4009 rn = "DataLo"; 4010 break; 4011 default: 4012 goto die; 4013 } 4014 break; 4015 case 29: 4016 switch (sel) { 4017 case 0: 4018 case 2: 4019 case 4: 4020 case 6: 4021 gen_helper_mtc0_taghi(cpu_env, arg); 4022 rn = "TagHi"; 4023 break; 4024 case 1: 4025 case 3: 4026 case 5: 4027 case 7: 4028 gen_helper_mtc0_datahi(cpu_env, arg); 4029 rn = "DataHi"; 4030 break; 4031 default: 4032 rn = "invalid sel"; 4033 goto die; 4034 } 4035 break; 4036 case 30: 4037 switch (sel) { 4038 case 0: 4039 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC)); 4040 rn = "ErrorEPC"; 4041 break; 4042 default: 4043 goto die; 4044 } 4045 break; 4046 case 31: 4047 switch (sel) { 4048 case 0: 4049 /* EJTAG support */ 4050 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 4051 rn = "DESAVE"; 4052 break; 4053 default: 4054 goto die; 4055 } 4056 /* Stop translation as we may have switched the execution mode */ 4057 ctx->bstate = BS_STOP; 4058 break; 4059 default: 4060 goto die; 4061 } 4062 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel); 4063 /* For simplicity assume that all writes can cause interrupts. */ 4064 if (use_icount) { 4065 gen_io_end(); 4066 ctx->bstate = BS_STOP; 4067 } 4068 return; 4069 4070die: 4071 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel); 4072 generate_exception(ctx, EXCP_RI); 4073} 4074 4075#if defined(TARGET_MIPS64) 4076static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 4077{ 4078 const char *rn = "invalid"; 4079 4080 if (sel != 0) 4081 check_insn(env, ctx, ISA_MIPS64); 4082 4083 switch (reg) { 4084 case 0: 4085 switch (sel) { 4086 case 0: 4087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 4088 rn = "Index"; 4089 break; 4090 case 1: 4091 check_insn(env, ctx, ASE_MT); 4092 gen_helper_mfc0_mvpcontrol(arg); 4093 rn = "MVPControl"; 4094 break; 4095 case 2: 4096 check_insn(env, ctx, ASE_MT); 4097 gen_helper_mfc0_mvpconf0(arg); 4098 rn = "MVPConf0"; 4099 break; 4100 case 3: 4101 check_insn(env, ctx, ASE_MT); 4102 gen_helper_mfc0_mvpconf1(arg); 4103 rn = "MVPConf1"; 4104 break; 4105 default: 4106 goto die; 4107 } 4108 break; 4109 case 1: 4110 switch (sel) { 4111 case 0: 4112 gen_helper_mfc0_random(arg); 4113 rn = "Random"; 4114 break; 4115 case 1: 4116 check_insn(env, ctx, ASE_MT); 4117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 4118 rn = "VPEControl"; 4119 break; 4120 case 2: 4121 check_insn(env, ctx, ASE_MT); 4122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 4123 rn = "VPEConf0"; 4124 break; 4125 case 3: 4126 check_insn(env, ctx, ASE_MT); 4127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 4128 rn = "VPEConf1"; 4129 break; 4130 case 4: 4131 check_insn(env, ctx, ASE_MT); 4132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask)); 4133 rn = "YQMask"; 4134 break; 4135 case 5: 4136 check_insn(env, ctx, ASE_MT); 4137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); 4138 rn = "VPESchedule"; 4139 break; 4140 case 6: 4141 check_insn(env, ctx, ASE_MT); 4142 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 4143 rn = "VPEScheFBack"; 4144 break; 4145 case 7: 4146 check_insn(env, ctx, ASE_MT); 4147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 4148 rn = "VPEOpt"; 4149 break; 4150 default: 4151 goto die; 4152 } 4153 break; 4154 case 2: 4155 switch (sel) { 4156 case 0: 4157 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); 4158 rn = "EntryLo0"; 4159 break; 4160 case 1: 4161 check_insn(env, ctx, ASE_MT); 4162 gen_helper_mfc0_tcstatus(arg); 4163 rn = "TCStatus"; 4164 break; 4165 case 2: 4166 check_insn(env, ctx, ASE_MT); 4167 gen_helper_mfc0_tcbind(arg); 4168 rn = "TCBind"; 4169 break; 4170 case 3: 4171 check_insn(env, ctx, ASE_MT); 4172 gen_helper_dmfc0_tcrestart(arg, cpu_env); 4173 rn = "TCRestart"; 4174 break; 4175 case 4: 4176 check_insn(env, ctx, ASE_MT); 4177 gen_helper_dmfc0_tchalt(arg, cpu_env); 4178 rn = "TCHalt"; 4179 break; 4180 case 5: 4181 check_insn(env, ctx, ASE_MT); 4182 gen_helper_dmfc0_tccontext(arg, cpu_env); 4183 rn = "TCContext"; 4184 break; 4185 case 6: 4186 check_insn(env, ctx, ASE_MT); 4187 gen_helper_dmfc0_tcschedule(arg, cpu_env); 4188 rn = "TCSchedule"; 4189 break; 4190 case 7: 4191 check_insn(env, ctx, ASE_MT); 4192 gen_helper_dmfc0_tcschefback(arg, cpu_env); 4193 rn = "TCScheFBack"; 4194 break; 4195 default: 4196 goto die; 4197 } 4198 break; 4199 case 3: 4200 switch (sel) { 4201 case 0: 4202 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 4203 rn = "EntryLo1"; 4204 break; 4205 default: 4206 goto die; 4207 } 4208 break; 4209 case 4: 4210 switch (sel) { 4211 case 0: 4212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 4213 rn = "Context"; 4214 break; 4215 case 1: 4216// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */ 4217 rn = "ContextConfig"; 4218// break; 4219 default: 4220 goto die; 4221 } 4222 break; 4223 case 5: 4224 switch (sel) { 4225 case 0: 4226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 4227 rn = "PageMask"; 4228 break; 4229 case 1: 4230 check_insn(env, ctx, ISA_MIPS32R2); 4231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 4232 rn = "PageGrain"; 4233 break; 4234 default: 4235 goto die; 4236 } 4237 break; 4238 case 6: 4239 switch (sel) { 4240 case 0: 4241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 4242 rn = "Wired"; 4243 break; 4244 case 1: 4245 check_insn(env, ctx, ISA_MIPS32R2); 4246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 4247 rn = "SRSConf0"; 4248 break; 4249 case 2: 4250 check_insn(env, ctx, ISA_MIPS32R2); 4251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 4252 rn = "SRSConf1"; 4253 break; 4254 case 3: 4255 check_insn(env, ctx, ISA_MIPS32R2); 4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 4257 rn = "SRSConf2"; 4258 break; 4259 case 4: 4260 check_insn(env, ctx, ISA_MIPS32R2); 4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 4262 rn = "SRSConf3"; 4263 break; 4264 case 5: 4265 check_insn(env, ctx, ISA_MIPS32R2); 4266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 4267 rn = "SRSConf4"; 4268 break; 4269 default: 4270 goto die; 4271 } 4272 break; 4273 case 7: 4274 switch (sel) { 4275 case 0: 4276 check_insn(env, ctx, ISA_MIPS32R2); 4277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 4278 rn = "HWREna"; 4279 break; 4280 default: 4281 goto die; 4282 } 4283 break; 4284 case 8: 4285 switch (sel) { 4286 case 0: 4287 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 4288 rn = "BadVAddr"; 4289 break; 4290 default: 4291 goto die; 4292 } 4293 break; 4294 case 9: 4295 switch (sel) { 4296 case 0: 4297 /* Mark as an IO operation because we read the time. */ 4298 if (use_icount) 4299 gen_io_start(); 4300 gen_helper_mfc0_count(arg); 4301 if (use_icount) { 4302 gen_io_end(); 4303 ctx->bstate = BS_STOP; 4304 } 4305 rn = "Count"; 4306 break; 4307 /* 6,7 are implementation dependent */ 4308 default: 4309 goto die; 4310 } 4311 break; 4312 case 10: 4313 switch (sel) { 4314 case 0: 4315 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 4316 rn = "EntryHi"; 4317 break; 4318 default: 4319 goto die; 4320 } 4321 break; 4322 case 11: 4323 switch (sel) { 4324 case 0: 4325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 4326 rn = "Compare"; 4327 break; 4328 /* 6,7 are implementation dependent */ 4329 default: 4330 goto die; 4331 } 4332 break; 4333 case 12: 4334 switch (sel) { 4335 case 0: 4336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 4337 rn = "Status"; 4338 break; 4339 case 1: 4340 check_insn(env, ctx, ISA_MIPS32R2); 4341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 4342 rn = "IntCtl"; 4343 break; 4344 case 2: 4345 check_insn(env, ctx, ISA_MIPS32R2); 4346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 4347 rn = "SRSCtl"; 4348 break; 4349 case 3: 4350 check_insn(env, ctx, ISA_MIPS32R2); 4351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 4352 rn = "SRSMap"; 4353 break; 4354 default: 4355 goto die; 4356 } 4357 break; 4358 case 13: 4359 switch (sel) { 4360 case 0: 4361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 4362 rn = "Cause"; 4363 break; 4364 default: 4365 goto die; 4366 } 4367 break; 4368 case 14: 4369 switch (sel) { 4370 case 0: 4371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 4372 rn = "EPC"; 4373 break; 4374 default: 4375 goto die; 4376 } 4377 break; 4378 case 15: 4379 switch (sel) { 4380 case 0: 4381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 4382 rn = "PRid"; 4383 break; 4384 case 1: 4385 check_insn(env, ctx, ISA_MIPS32R2); 4386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase)); 4387 rn = "EBase"; 4388 break; 4389 default: 4390 goto die; 4391 } 4392 break; 4393 case 16: 4394 switch (sel) { 4395 case 0: 4396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 4397 rn = "Config"; 4398 break; 4399 case 1: 4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 4401 rn = "Config1"; 4402 break; 4403 case 2: 4404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 4405 rn = "Config2"; 4406 break; 4407 case 3: 4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 4409 rn = "Config3"; 4410 break; 4411 /* 6,7 are implementation dependent */ 4412 case 6: 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 4414 rn = "Config6"; 4415 break; 4416 case 7: 4417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 4418 rn = "Config7"; 4419 break; 4420 default: 4421 goto die; 4422 } 4423 break; 4424 case 17: 4425 switch (sel) { 4426 case 0: 4427 gen_helper_dmfc0_lladdr(arg, cpu_env); 4428 rn = "LLAddr"; 4429 break; 4430 default: 4431 goto die; 4432 } 4433 break; 4434 case 18: 4435 switch (sel) { 4436 case 0 ... 7: 4437 gen_helper_1i(dmfc0_watchlo, arg, sel); 4438 rn = "WatchLo"; 4439 break; 4440 default: 4441 goto die; 4442 } 4443 break; 4444 case 19: 4445 switch (sel) { 4446 case 0 ... 7: 4447 gen_helper_1i(mfc0_watchhi, arg, sel); 4448 rn = "WatchHi"; 4449 break; 4450 default: 4451 goto die; 4452 } 4453 break; 4454 case 20: 4455 switch (sel) { 4456 case 0: 4457 check_insn(env, ctx, ISA_MIPS3); 4458 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 4459 rn = "XContext"; 4460 break; 4461 default: 4462 goto die; 4463 } 4464 break; 4465 case 21: 4466 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 4467 switch (sel) { 4468 case 0: 4469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 4470 rn = "Framemask"; 4471 break; 4472 default: 4473 goto die; 4474 } 4475 break; 4476 case 22: 4477 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4478 rn = "'Diagnostic"; /* implementation dependent */ 4479 break; 4480 case 23: 4481 switch (sel) { 4482 case 0: 4483 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 4484 rn = "Debug"; 4485 break; 4486 case 1: 4487// gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */ 4488 rn = "TraceControl"; 4489// break; 4490 case 2: 4491// gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */ 4492 rn = "TraceControl2"; 4493// break; 4494 case 3: 4495// gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */ 4496 rn = "UserTraceData"; 4497// break; 4498 case 4: 4499// gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */ 4500 rn = "TraceBPC"; 4501// break; 4502 default: 4503 goto die; 4504 } 4505 break; 4506 case 24: 4507 switch (sel) { 4508 case 0: 4509 /* EJTAG support */ 4510 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 4511 rn = "DEPC"; 4512 break; 4513 default: 4514 goto die; 4515 } 4516 break; 4517 case 25: 4518 switch (sel) { 4519 case 0: 4520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 4521 rn = "Performance0"; 4522 break; 4523 case 1: 4524// gen_helper_dmfc0_performance1(arg); 4525 rn = "Performance1"; 4526// break; 4527 case 2: 4528// gen_helper_dmfc0_performance2(arg); 4529 rn = "Performance2"; 4530// break; 4531 case 3: 4532// gen_helper_dmfc0_performance3(arg); 4533 rn = "Performance3"; 4534// break; 4535 case 4: 4536// gen_helper_dmfc0_performance4(arg); 4537 rn = "Performance4"; 4538// break; 4539 case 5: 4540// gen_helper_dmfc0_performance5(arg); 4541 rn = "Performance5"; 4542// break; 4543 case 6: 4544// gen_helper_dmfc0_performance6(arg); 4545 rn = "Performance6"; 4546// break; 4547 case 7: 4548// gen_helper_dmfc0_performance7(arg); 4549 rn = "Performance7"; 4550// break; 4551 default: 4552 goto die; 4553 } 4554 break; 4555 case 26: 4556 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4557 rn = "ECC"; 4558 break; 4559 case 27: 4560 switch (sel) { 4561 /* ignored */ 4562 case 0 ... 3: 4563 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 4564 rn = "CacheErr"; 4565 break; 4566 default: 4567 goto die; 4568 } 4569 break; 4570 case 28: 4571 switch (sel) { 4572 case 0: 4573 case 2: 4574 case 4: 4575 case 6: 4576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 4577 rn = "TagLo"; 4578 break; 4579 case 1: 4580 case 3: 4581 case 5: 4582 case 7: 4583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 4584 rn = "DataLo"; 4585 break; 4586 default: 4587 goto die; 4588 } 4589 break; 4590 case 29: 4591 switch (sel) { 4592 case 0: 4593 case 2: 4594 case 4: 4595 case 6: 4596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 4597 rn = "TagHi"; 4598 break; 4599 case 1: 4600 case 3: 4601 case 5: 4602 case 7: 4603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 4604 rn = "DataHi"; 4605 break; 4606 default: 4607 goto die; 4608 } 4609 break; 4610 case 30: 4611 switch (sel) { 4612 case 0: 4613 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 4614 rn = "ErrorEPC"; 4615 break; 4616 default: 4617 goto die; 4618 } 4619 break; 4620 case 31: 4621 switch (sel) { 4622 case 0: 4623 /* EJTAG support */ 4624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 4625 rn = "DESAVE"; 4626 break; 4627 default: 4628 goto die; 4629 } 4630 break; 4631 default: 4632 goto die; 4633 } 4634 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel); 4635 return; 4636 4637die: 4638 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel); 4639 generate_exception(ctx, EXCP_RI); 4640} 4641 4642static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel) 4643{ 4644 const char *rn = "invalid"; 4645 4646 if (sel != 0) 4647 check_insn(env, ctx, ISA_MIPS64); 4648 4649 if (use_icount) 4650 gen_io_start(); 4651 4652 switch (reg) { 4653 case 0: 4654 switch (sel) { 4655 case 0: 4656 gen_helper_mtc0_index(cpu_env, arg); 4657 rn = "Index"; 4658 break; 4659 case 1: 4660 check_insn(env, ctx, ASE_MT); 4661 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 4662 rn = "MVPControl"; 4663 break; 4664 case 2: 4665 check_insn(env, ctx, ASE_MT); 4666 /* ignored */ 4667 rn = "MVPConf0"; 4668 break; 4669 case 3: 4670 check_insn(env, ctx, ASE_MT); 4671 /* ignored */ 4672 rn = "MVPConf1"; 4673 break; 4674 default: 4675 goto die; 4676 } 4677 break; 4678 case 1: 4679 switch (sel) { 4680 case 0: 4681 /* ignored */ 4682 rn = "Random"; 4683 break; 4684 case 1: 4685 check_insn(env, ctx, ASE_MT); 4686 gen_helper_mtc0_vpecontrol(cpu_env, arg); 4687 rn = "VPEControl"; 4688 break; 4689 case 2: 4690 check_insn(env, ctx, ASE_MT); 4691 gen_helper_mtc0_vpeconf0(cpu_env, arg); 4692 rn = "VPEConf0"; 4693 break; 4694 case 3: 4695 check_insn(env, ctx, ASE_MT); 4696 gen_helper_mtc0_vpeconf1(cpu_env, arg); 4697 rn = "VPEConf1"; 4698 break; 4699 case 4: 4700 check_insn(env, ctx, ASE_MT); 4701 gen_helper_mtc0_yqmask(cpu_env, arg); 4702 rn = "YQMask"; 4703 break; 4704 case 5: 4705 check_insn(env, ctx, ASE_MT); 4706 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); 4707 rn = "VPESchedule"; 4708 break; 4709 case 6: 4710 check_insn(env, ctx, ASE_MT); 4711 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 4712 rn = "VPEScheFBack"; 4713 break; 4714 case 7: 4715 check_insn(env, ctx, ASE_MT); 4716 gen_helper_mtc0_vpeopt(cpu_env, arg); 4717 rn = "VPEOpt"; 4718 break; 4719 default: 4720 goto die; 4721 } 4722 break; 4723 case 2: 4724 switch (sel) { 4725 case 0: 4726 gen_helper_mtc0_entrylo0(cpu_env, arg); 4727 rn = "EntryLo0"; 4728 break; 4729 case 1: 4730 check_insn(env, ctx, ASE_MT); 4731 gen_helper_mtc0_tcstatus(cpu_env, arg); 4732 rn = "TCStatus"; 4733 break; 4734 case 2: 4735 check_insn(env, ctx, ASE_MT); 4736 gen_helper_mtc0_tcbind(cpu_env, arg); 4737 rn = "TCBind"; 4738 break; 4739 case 3: 4740 check_insn(env, ctx, ASE_MT); 4741 gen_helper_mtc0_tcrestart(cpu_env, arg); 4742 rn = "TCRestart"; 4743 break; 4744 case 4: 4745 check_insn(env, ctx, ASE_MT); 4746 gen_helper_mtc0_tchalt(cpu_env, arg); 4747 rn = "TCHalt"; 4748 break; 4749 case 5: 4750 check_insn(env, ctx, ASE_MT); 4751 gen_helper_mtc0_tccontext(cpu_env, arg); 4752 rn = "TCContext"; 4753 break; 4754 case 6: 4755 check_insn(env, ctx, ASE_MT); 4756 gen_helper_mtc0_tcschedule(cpu_env, arg); 4757 rn = "TCSchedule"; 4758 break; 4759 case 7: 4760 check_insn(env, ctx, ASE_MT); 4761 gen_helper_mtc0_tcschefback(cpu_env, arg); 4762 rn = "TCScheFBack"; 4763 break; 4764 default: 4765 goto die; 4766 } 4767 break; 4768 case 3: 4769 switch (sel) { 4770 case 0: 4771 gen_helper_mtc0_entrylo1(cpu_env, arg); 4772 rn = "EntryLo1"; 4773 break; 4774 default: 4775 goto die; 4776 } 4777 break; 4778 case 4: 4779 switch (sel) { 4780 case 0: 4781 gen_helper_mtc0_context(cpu_env, arg); 4782 rn = "Context"; 4783 break; 4784 case 1: 4785// gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */ 4786 rn = "ContextConfig"; 4787// break; 4788 default: 4789 goto die; 4790 } 4791 break; 4792 case 5: 4793 switch (sel) { 4794 case 0: 4795 gen_helper_mtc0_pagemask(cpu_env, arg); 4796 rn = "PageMask"; 4797 break; 4798 case 1: 4799 check_insn(env, ctx, ISA_MIPS32R2); 4800 gen_helper_mtc0_pagegrain(cpu_env, arg); 4801 rn = "PageGrain"; 4802 break; 4803 default: 4804 goto die; 4805 } 4806 break; 4807 case 6: 4808 switch (sel) { 4809 case 0: 4810 gen_helper_mtc0_wired(cpu_env, arg); 4811 rn = "Wired"; 4812 break; 4813 case 1: 4814 check_insn(env, ctx, ISA_MIPS32R2); 4815 gen_helper_mtc0_srsconf0(cpu_env, arg); 4816 rn = "SRSConf0"; 4817 break; 4818 case 2: 4819 check_insn(env, ctx, ISA_MIPS32R2); 4820 gen_helper_mtc0_srsconf1(cpu_env, arg); 4821 rn = "SRSConf1"; 4822 break; 4823 case 3: 4824 check_insn(env, ctx, ISA_MIPS32R2); 4825 gen_helper_mtc0_srsconf2(cpu_env, arg); 4826 rn = "SRSConf2"; 4827 break; 4828 case 4: 4829 check_insn(env, ctx, ISA_MIPS32R2); 4830 gen_helper_mtc0_srsconf3(cpu_env, arg); 4831 rn = "SRSConf3"; 4832 break; 4833 case 5: 4834 check_insn(env, ctx, ISA_MIPS32R2); 4835 gen_helper_mtc0_srsconf4(cpu_env, arg); 4836 rn = "SRSConf4"; 4837 break; 4838 default: 4839 goto die; 4840 } 4841 break; 4842 case 7: 4843 switch (sel) { 4844 case 0: 4845 check_insn(env, ctx, ISA_MIPS32R2); 4846 gen_helper_mtc0_hwrena(cpu_env, arg); 4847 rn = "HWREna"; 4848 break; 4849 default: 4850 goto die; 4851 } 4852 break; 4853 case 8: 4854 /* ignored */ 4855 rn = "BadVAddr"; 4856 break; 4857 case 9: 4858 switch (sel) { 4859 case 0: 4860 gen_helper_mtc0_count(cpu_env, arg); 4861 rn = "Count"; 4862 break; 4863 /* 6,7 are implementation dependent */ 4864 default: 4865 goto die; 4866 } 4867 /* Stop translation as we may have switched the execution mode */ 4868 ctx->bstate = BS_STOP; 4869 break; 4870 case 10: 4871 switch (sel) { 4872 case 0: 4873 gen_helper_mtc0_entryhi(cpu_env, arg); 4874 rn = "EntryHi"; 4875 break; 4876 default: 4877 goto die; 4878 } 4879 break; 4880 case 11: 4881 switch (sel) { 4882 case 0: 4883 gen_helper_mtc0_compare(cpu_env, arg); 4884 rn = "Compare"; 4885 break; 4886 /* 6,7 are implementation dependent */ 4887 default: 4888 goto die; 4889 } 4890 /* Stop translation as we may have switched the execution mode */ 4891 ctx->bstate = BS_STOP; 4892 break; 4893 case 12: 4894 switch (sel) { 4895 case 0: 4896 save_cpu_state(ctx, 1); 4897 gen_helper_mtc0_status(cpu_env, arg); 4898 /* BS_STOP isn't good enough here, hflags may have changed. */ 4899 gen_save_pc(ctx->pc + 4); 4900 ctx->bstate = BS_EXCP; 4901 rn = "Status"; 4902 break; 4903 case 1: 4904 check_insn(env, ctx, ISA_MIPS32R2); 4905 gen_helper_mtc0_intctl(cpu_env, arg); 4906 /* Stop translation as we may have switched the execution mode */ 4907 ctx->bstate = BS_STOP; 4908 rn = "IntCtl"; 4909 break; 4910 case 2: 4911 check_insn(env, ctx, ISA_MIPS32R2); 4912 gen_helper_mtc0_srsctl(cpu_env, arg); 4913 /* Stop translation as we may have switched the execution mode */ 4914 ctx->bstate = BS_STOP; 4915 rn = "SRSCtl"; 4916 break; 4917 case 3: 4918 check_insn(env, ctx, ISA_MIPS32R2); 4919 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 4920 /* Stop translation as we may have switched the execution mode */ 4921 ctx->bstate = BS_STOP; 4922 rn = "SRSMap"; 4923 break; 4924 default: 4925 goto die; 4926 } 4927 break; 4928 case 13: 4929 switch (sel) { 4930 case 0: 4931 save_cpu_state(ctx, 1); 4932 gen_helper_mtc0_cause(cpu_env, arg); 4933 rn = "Cause"; 4934 break; 4935 default: 4936 goto die; 4937 } 4938 break; 4939 case 14: 4940 switch (sel) { 4941 case 0: 4942 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 4943 rn = "EPC"; 4944 break; 4945 default: 4946 goto die; 4947 } 4948 break; 4949 case 15: 4950 switch (sel) { 4951 case 0: 4952 /* ignored */ 4953 rn = "PRid"; 4954 break; 4955 case 1: 4956 check_insn(env, ctx, ISA_MIPS32R2); 4957 gen_helper_mtc0_ebase(cpu_env, arg); 4958 rn = "EBase"; 4959 break; 4960 default: 4961 goto die; 4962 } 4963 break; 4964 case 16: 4965 switch (sel) { 4966 case 0: 4967 gen_helper_mtc0_config0(cpu_env, arg); 4968 rn = "Config"; 4969 /* Stop translation as we may have switched the execution mode */ 4970 ctx->bstate = BS_STOP; 4971 break; 4972 case 1: 4973 /* ignored, read only */ 4974 rn = "Config1"; 4975 break; 4976 case 2: 4977 gen_helper_mtc0_config2(cpu_env, arg); 4978 rn = "Config2"; 4979 /* Stop translation as we may have switched the execution mode */ 4980 ctx->bstate = BS_STOP; 4981 break; 4982 case 3: 4983 /* ignored */ 4984 rn = "Config3"; 4985 break; 4986 /* 6,7 are implementation dependent */ 4987 default: 4988 rn = "Invalid config selector"; 4989 goto die; 4990 } 4991 break; 4992 case 17: 4993 switch (sel) { 4994 case 0: 4995 gen_helper_mtc0_lladdr(cpu_env, arg); 4996 rn = "LLAddr"; 4997 break; 4998 default: 4999 goto die; 5000 } 5001 break; 5002 case 18: 5003 switch (sel) { 5004 case 0 ... 7: 5005 gen_helper_2i(mtc0_watchlo, cpu_env, arg, sel); 5006 rn = "WatchLo"; 5007 break; 5008 default: 5009 goto die; 5010 } 5011 break; 5012 case 19: 5013 switch (sel) { 5014 case 0 ... 7: 5015 gen_helper_2i(mtc0_watchhi, cpu_env, arg, sel); 5016 rn = "WatchHi"; 5017 break; 5018 default: 5019 goto die; 5020 } 5021 break; 5022 case 20: 5023 switch (sel) { 5024 case 0: 5025 check_insn(env, ctx, ISA_MIPS3); 5026 gen_helper_mtc0_xcontext(cpu_env, arg); 5027 rn = "XContext"; 5028 break; 5029 default: 5030 goto die; 5031 } 5032 break; 5033 case 21: 5034 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5035 switch (sel) { 5036 case 0: 5037 gen_helper_mtc0_framemask(cpu_env, arg); 5038 rn = "Framemask"; 5039 break; 5040 default: 5041 goto die; 5042 } 5043 break; 5044 case 22: 5045 /* ignored */ 5046 rn = "Diagnostic"; /* implementation dependent */ 5047 break; 5048 case 23: 5049 switch (sel) { 5050 case 0: 5051 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 5052 /* BS_STOP isn't good enough here, hflags may have changed. */ 5053 gen_save_pc(ctx->pc + 4); 5054 ctx->bstate = BS_EXCP; 5055 rn = "Debug"; 5056 break; 5057 case 1: 5058// gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */ 5059 /* Stop translation as we may have switched the execution mode */ 5060 ctx->bstate = BS_STOP; 5061 rn = "TraceControl"; 5062// break; 5063 case 2: 5064// gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */ 5065 /* Stop translation as we may have switched the execution mode */ 5066 ctx->bstate = BS_STOP; 5067 rn = "TraceControl2"; 5068// break; 5069 case 3: 5070// gen_helper_mtc0_usertracedata(arg); /* PDtrace support */ 5071 /* Stop translation as we may have switched the execution mode */ 5072 ctx->bstate = BS_STOP; 5073 rn = "UserTraceData"; 5074// break; 5075 case 4: 5076// gen_helper_mtc0_tracebpc(arg); /* PDtrace support */ 5077 /* Stop translation as we may have switched the execution mode */ 5078 ctx->bstate = BS_STOP; 5079 rn = "TraceBPC"; 5080// break; 5081 default: 5082 goto die; 5083 } 5084 break; 5085 case 24: 5086 switch (sel) { 5087 case 0: 5088 /* EJTAG support */ 5089 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 5090 rn = "DEPC"; 5091 break; 5092 default: 5093 goto die; 5094 } 5095 break; 5096 case 25: 5097 switch (sel) { 5098 case 0: 5099 gen_helper_mtc0_performance0(cpu_env, arg); 5100 rn = "Performance0"; 5101 break; 5102 case 1: 5103// gen_helper_mtc0_performance1(cpu_env, arg); 5104 rn = "Performance1"; 5105// break; 5106 case 2: 5107// gen_helper_mtc0_performance2(cpu_env, arg); 5108 rn = "Performance2"; 5109// break; 5110 case 3: 5111// gen_helper_mtc0_performance3(cpu_env, arg); 5112 rn = "Performance3"; 5113// break; 5114 case 4: 5115// gen_helper_mtc0_performance4(cpu_env, arg); 5116 rn = "Performance4"; 5117// break; 5118 case 5: 5119// gen_helper_mtc0_performance5(cpu_env, arg); 5120 rn = "Performance5"; 5121// break; 5122 case 6: 5123// gen_helper_mtc0_performance6(cpu_env, arg); 5124 rn = "Performance6"; 5125// break; 5126 case 7: 5127// gen_helper_mtc0_performance7(cpu_env, arg); 5128 rn = "Performance7"; 5129// break; 5130 default: 5131 goto die; 5132 } 5133 break; 5134 case 26: 5135 /* ignored */ 5136 rn = "ECC"; 5137 break; 5138 case 27: 5139 switch (sel) { 5140 case 0 ... 3: 5141 /* ignored */ 5142 rn = "CacheErr"; 5143 break; 5144 default: 5145 goto die; 5146 } 5147 break; 5148 case 28: 5149 switch (sel) { 5150 case 0: 5151 case 2: 5152 case 4: 5153 case 6: 5154 gen_helper_mtc0_taglo(cpu_env, arg); 5155 rn = "TagLo"; 5156 break; 5157 case 1: 5158 case 3: 5159 case 5: 5160 case 7: 5161 gen_helper_mtc0_datalo(cpu_env, arg); 5162 rn = "DataLo"; 5163 break; 5164 default: 5165 goto die; 5166 } 5167 break; 5168 case 29: 5169 switch (sel) { 5170 case 0: 5171 case 2: 5172 case 4: 5173 case 6: 5174 gen_helper_mtc0_taghi(cpu_env, arg); 5175 rn = "TagHi"; 5176 break; 5177 case 1: 5178 case 3: 5179 case 5: 5180 case 7: 5181 gen_helper_mtc0_datahi(cpu_env, arg); 5182 rn = "DataHi"; 5183 break; 5184 default: 5185 rn = "invalid sel"; 5186 goto die; 5187 } 5188 break; 5189 case 30: 5190 switch (sel) { 5191 case 0: 5192 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5193 rn = "ErrorEPC"; 5194 break; 5195 default: 5196 goto die; 5197 } 5198 break; 5199 case 31: 5200 switch (sel) { 5201 case 0: 5202 /* EJTAG support */ 5203 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5204 rn = "DESAVE"; 5205 break; 5206 default: 5207 goto die; 5208 } 5209 /* Stop translation as we may have switched the execution mode */ 5210 ctx->bstate = BS_STOP; 5211 break; 5212 default: 5213 goto die; 5214 } 5215 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel); 5216 /* For simplicity assume that all writes can cause interrupts. */ 5217 if (use_icount) { 5218 gen_io_end(); 5219 ctx->bstate = BS_STOP; 5220 } 5221 return; 5222 5223die: 5224 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel); 5225 generate_exception(ctx, EXCP_RI); 5226} 5227#endif /* TARGET_MIPS64 */ 5228 5229static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 5230 int u, int sel, int h) 5231{ 5232 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 5233 TCGv t0 = tcg_temp_local_new(); 5234 5235 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 5236 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 5237 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) 5238 tcg_gen_movi_tl(t0, -1); 5239 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 5240 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) 5241 tcg_gen_movi_tl(t0, -1); 5242 else if (u == 0) { 5243 switch (rt) { 5244 case 2: 5245 switch (sel) { 5246 case 1: 5247 gen_helper_mftc0_tcstatus(t0, cpu_env); 5248 break; 5249 case 2: 5250 gen_helper_mftc0_tcbind(t0, cpu_env); 5251 break; 5252 case 3: 5253 gen_helper_mftc0_tcrestart(t0, cpu_env); 5254 break; 5255 case 4: 5256 gen_helper_mftc0_tchalt(t0, cpu_env); 5257 break; 5258 case 5: 5259 gen_helper_mftc0_tccontext(t0, cpu_env); 5260 break; 5261 case 6: 5262 gen_helper_mftc0_tcschedule(t0, cpu_env); 5263 break; 5264 case 7: 5265 gen_helper_mftc0_tcschefback(t0, cpu_env); 5266 break; 5267 default: 5268 gen_mfc0(env, ctx, t0, rt, sel); 5269 break; 5270 } 5271 break; 5272 case 10: 5273 switch (sel) { 5274 case 0: 5275 gen_helper_mftc0_entryhi(t0, cpu_env); 5276 break; 5277 default: 5278 gen_mfc0(env, ctx, t0, rt, sel); 5279 break; 5280 } 5281 case 12: 5282 switch (sel) { 5283 case 0: 5284 gen_helper_mftc0_status(t0, cpu_env); 5285 break; 5286 default: 5287 gen_mfc0(env, ctx, t0, rt, sel); 5288 break; 5289 } 5290 case 23: 5291 switch (sel) { 5292 case 0: 5293 gen_helper_mftc0_debug(t0, cpu_env); 5294 break; 5295 default: 5296 gen_mfc0(env, ctx, t0, rt, sel); 5297 break; 5298 } 5299 break; 5300 default: 5301 gen_mfc0(env, ctx, t0, rt, sel); 5302 } 5303 } else switch (sel) { 5304 /* GPR registers. */ 5305 case 0: 5306 gen_helper_2i(mftgpr, t0, cpu_env, rt); 5307 break; 5308 /* Auxiliary CPU registers */ 5309 case 1: 5310 switch (rt) { 5311 case 0: 5312 gen_helper_2i(mftlo, t0, cpu_env, 0); 5313 break; 5314 case 1: 5315 gen_helper_2i(mfthi, t0, cpu_env, 0); 5316 break; 5317 case 2: 5318 gen_helper_2i(mftacx, t0, cpu_env, 0); 5319 break; 5320 case 4: 5321 gen_helper_2i(mftlo, t0, cpu_env, 1); 5322 break; 5323 case 5: 5324 gen_helper_2i(mfthi, t0, cpu_env, 1); 5325 break; 5326 case 6: 5327 gen_helper_2i(mftacx, t0, cpu_env, 1); 5328 break; 5329 case 8: 5330 gen_helper_2i(mftlo, t0, cpu_env, 2); 5331 break; 5332 case 9: 5333 gen_helper_2i(mfthi, t0, cpu_env, 2); 5334 break; 5335 case 10: 5336 gen_helper_2i(mftacx, t0, cpu_env, 2); 5337 break; 5338 case 12: 5339 gen_helper_2i(mftlo, t0, cpu_env, 3); 5340 break; 5341 case 13: 5342 gen_helper_2i(mfthi, t0, cpu_env, 3); 5343 break; 5344 case 14: 5345 gen_helper_2i(mftacx, t0, cpu_env, 3); 5346 break; 5347 case 16: 5348 gen_helper_mftdsp(t0, cpu_env); 5349 break; 5350 default: 5351 goto die; 5352 } 5353 break; 5354 /* Floating point (COP1). */ 5355 case 2: 5356 /* XXX: For now we support only a single FPU context. */ 5357 if (h == 0) { 5358 TCGv_i32 fp0 = tcg_temp_new_i32(); 5359 5360 gen_load_fpr32(fp0, rt); 5361 tcg_gen_ext_i32_tl(t0, fp0); 5362 tcg_temp_free_i32(fp0); 5363 } else { 5364 TCGv_i32 fp0 = tcg_temp_new_i32(); 5365 5366 gen_load_fpr32h(fp0, rt); 5367 tcg_gen_ext_i32_tl(t0, fp0); 5368 tcg_temp_free_i32(fp0); 5369 } 5370 break; 5371 case 3: 5372 /* XXX: For now we support only a single FPU context. */ 5373 gen_helper_2i(cfc1, t0, cpu_env, rt); 5374 break; 5375 /* COP2: Not implemented. */ 5376 case 4: 5377 case 5: 5378 /* fall through */ 5379 default: 5380 goto die; 5381 } 5382 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 5383 gen_store_gpr(t0, rd); 5384 tcg_temp_free(t0); 5385 return; 5386 5387die: 5388 tcg_temp_free(t0); 5389 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 5390 generate_exception(ctx, EXCP_RI); 5391} 5392 5393static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 5394 int u, int sel, int h) 5395{ 5396 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 5397 TCGv t0 = tcg_temp_local_new(); 5398 5399 gen_load_gpr(t0, rt); 5400 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 5401 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 5402 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) 5403 /* NOP */ ; 5404 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 5405 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) 5406 /* NOP */ ; 5407 else if (u == 0) { 5408 switch (rd) { 5409 case 2: 5410 switch (sel) { 5411 case 1: 5412 gen_helper_mttc0_tcstatus(cpu_env, t0); 5413 break; 5414 case 2: 5415 gen_helper_mttc0_tcbind(cpu_env, t0); 5416 break; 5417 case 3: 5418 gen_helper_mttc0_tcrestart(cpu_env, t0); 5419 break; 5420 case 4: 5421 gen_helper_mttc0_tchalt(cpu_env, t0); 5422 break; 5423 case 5: 5424 gen_helper_mttc0_tccontext(cpu_env, t0); 5425 break; 5426 case 6: 5427 gen_helper_mttc0_tcschedule(cpu_env, t0); 5428 break; 5429 case 7: 5430 gen_helper_mttc0_tcschefback(cpu_env, t0); 5431 break; 5432 default: 5433 gen_mtc0(env, ctx, t0, rd, sel); 5434 break; 5435 } 5436 break; 5437 case 10: 5438 switch (sel) { 5439 case 0: 5440 gen_helper_mttc0_entryhi(cpu_env, t0); 5441 break; 5442 default: 5443 gen_mtc0(env, ctx, t0, rd, sel); 5444 break; 5445 } 5446 case 12: 5447 switch (sel) { 5448 case 0: 5449 gen_helper_mttc0_status(cpu_env, t0); 5450 break; 5451 default: 5452 gen_mtc0(env, ctx, t0, rd, sel); 5453 break; 5454 } 5455 case 23: 5456 switch (sel) { 5457 case 0: 5458 gen_helper_mttc0_debug(cpu_env, t0); 5459 break; 5460 default: 5461 gen_mtc0(env, ctx, t0, rd, sel); 5462 break; 5463 } 5464 break; 5465 default: 5466 gen_mtc0(env, ctx, t0, rd, sel); 5467 } 5468 } else switch (sel) { 5469 /* GPR registers. */ 5470 case 0: 5471 gen_helper_2i(mttgpr, cpu_env, t0, rd); 5472 break; 5473 /* Auxiliary CPU registers */ 5474 case 1: 5475 switch (rd) { 5476 case 0: 5477 gen_helper_2i(mttlo, cpu_env, t0, 0); 5478 break; 5479 case 1: 5480 gen_helper_2i(mtthi, cpu_env, t0, 0); 5481 break; 5482 case 2: 5483 gen_helper_2i(mttacx, cpu_env, t0, 0); 5484 break; 5485 case 4: 5486 gen_helper_2i(mttlo, cpu_env, t0, 1); 5487 break; 5488 case 5: 5489 gen_helper_2i(mtthi, cpu_env, t0, 1); 5490 break; 5491 case 6: 5492 gen_helper_2i(mttacx, cpu_env, t0, 1); 5493 break; 5494 case 8: 5495 gen_helper_2i(mttlo, cpu_env, t0, 2); 5496 break; 5497 case 9: 5498 gen_helper_2i(mtthi, cpu_env, t0, 2); 5499 break; 5500 case 10: 5501 gen_helper_2i(mttacx, cpu_env, t0, 2); 5502 break; 5503 case 12: 5504 gen_helper_2i(mttlo, cpu_env, t0, 3); 5505 break; 5506 case 13: 5507 gen_helper_2i(mtthi, cpu_env, t0, 3); 5508 break; 5509 case 14: 5510 gen_helper_2i(mttacx, cpu_env, t0, 3); 5511 break; 5512 case 16: 5513 gen_helper_mttdsp(cpu_env, t0); 5514 break; 5515 default: 5516 goto die; 5517 } 5518 break; 5519 /* Floating point (COP1). */ 5520 case 2: 5521 /* XXX: For now we support only a single FPU context. */ 5522 if (h == 0) { 5523 TCGv_i32 fp0 = tcg_temp_new_i32(); 5524 5525 tcg_gen_trunc_tl_i32(fp0, t0); 5526 gen_store_fpr32(fp0, rd); 5527 tcg_temp_free_i32(fp0); 5528 } else { 5529 TCGv_i32 fp0 = tcg_temp_new_i32(); 5530 5531 tcg_gen_trunc_tl_i32(fp0, t0); 5532 gen_store_fpr32h(fp0, rd); 5533 tcg_temp_free_i32(fp0); 5534 } 5535 break; 5536 case 3: 5537 /* XXX: For now we support only a single FPU context. */ 5538 gen_helper_2i(ctc1, cpu_env, t0, rd); 5539 break; 5540 /* COP2: Not implemented. */ 5541 case 4: 5542 case 5: 5543 /* fall through */ 5544 default: 5545 goto die; 5546 } 5547 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 5548 tcg_temp_free(t0); 5549 return; 5550 5551die: 5552 tcg_temp_free(t0); 5553 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 5554 generate_exception(ctx, EXCP_RI); 5555} 5556 5557static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd) 5558{ 5559 const char* __attribute__((unused)) opn = "ldst"; 5560 5561 switch (opc) { 5562 case OPC_MFC0: 5563 if (rt == 0) { 5564 /* Treat as NOP. */ 5565 return; 5566 } 5567 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 5568 opn = "mfc0"; 5569 break; 5570 case OPC_MTC0: 5571 { 5572 TCGv t0 = tcg_temp_new(); 5573 5574 gen_load_gpr(t0, rt); 5575 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7); 5576 tcg_temp_free(t0); 5577 } 5578 opn = "mtc0"; 5579 break; 5580#if defined(TARGET_MIPS64) 5581 case OPC_DMFC0: 5582 check_insn(env, ctx, ISA_MIPS3); 5583 if (rt == 0) { 5584 /* Treat as NOP. */ 5585 return; 5586 } 5587 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 5588 opn = "dmfc0"; 5589 break; 5590 case OPC_DMTC0: 5591 check_insn(env, ctx, ISA_MIPS3); 5592 { 5593 TCGv t0 = tcg_temp_new(); 5594 5595 gen_load_gpr(t0, rt); 5596 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7); 5597 tcg_temp_free(t0); 5598 } 5599 opn = "dmtc0"; 5600 break; 5601#endif 5602 case OPC_MFTR: 5603 check_insn(env, ctx, ASE_MT); 5604 if (rd == 0) { 5605 /* Treat as NOP. */ 5606 return; 5607 } 5608 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 5609 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 5610 opn = "mftr"; 5611 break; 5612 case OPC_MTTR: 5613 check_insn(env, ctx, ASE_MT); 5614 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 5615 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 5616 opn = "mttr"; 5617 break; 5618 case OPC_TLBWI: 5619 opn = "tlbwi"; 5620 if (!env->tlb->helper_tlbwi) 5621 goto die; 5622 gen_helper_tlbwi(cpu_env); 5623 break; 5624 case OPC_TLBWR: 5625 opn = "tlbwr"; 5626 if (!env->tlb->helper_tlbwr) 5627 goto die; 5628 gen_helper_tlbwr(cpu_env); 5629 break; 5630 case OPC_TLBP: 5631 opn = "tlbp"; 5632 if (!env->tlb->helper_tlbp) 5633 goto die; 5634 gen_helper_tlbp(cpu_env); 5635 break; 5636 case OPC_TLBR: 5637 opn = "tlbr"; 5638 if (!env->tlb->helper_tlbr) 5639 goto die; 5640 gen_helper_tlbr(cpu_env); 5641 break; 5642 case OPC_ERET: 5643 opn = "eret"; 5644 check_insn(env, ctx, ISA_MIPS2); 5645 gen_helper_eret(cpu_env); 5646 ctx->bstate = BS_EXCP; 5647 break; 5648 case OPC_DERET: 5649 opn = "deret"; 5650 check_insn(env, ctx, ISA_MIPS32); 5651 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 5652 MIPS_INVAL(opn); 5653 generate_exception(ctx, EXCP_RI); 5654 } else { 5655 gen_helper_deret(cpu_env); 5656 ctx->bstate = BS_EXCP; 5657 } 5658 break; 5659 case OPC_WAIT: 5660 opn = "wait"; 5661 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); 5662 /* If we get an exception, we want to restart at next instruction */ 5663 ctx->pc += 4; 5664 save_cpu_state(ctx, 1); 5665 ctx->pc -= 4; 5666 gen_helper_wait(cpu_env); 5667 ctx->bstate = BS_EXCP; 5668 break; 5669 default: 5670 die: 5671 MIPS_INVAL(opn); 5672 generate_exception(ctx, EXCP_RI); 5673 return; 5674 } 5675 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); 5676} 5677#endif /* !CONFIG_USER_ONLY */ 5678 5679/* CP1 Branches (before delay slot) */ 5680static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op, 5681 int32_t cc, int32_t offset) 5682{ 5683 target_ulong btarget; 5684 const char* __attribute__((unused)) opn = "cp1 cond branch"; 5685 TCGv_i32 t0 = tcg_temp_new_i32(); 5686 5687 if (cc != 0) 5688 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 5689 5690 btarget = ctx->pc + 4 + offset; 5691 5692 switch (op) { 5693 case OPC_BC1F: 5694 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5695 tcg_gen_not_i32(t0, t0); 5696 tcg_gen_andi_i32(t0, t0, 1); 5697 tcg_gen_extu_i32_tl(bcond, t0); 5698 opn = "bc1f"; 5699 goto not_likely; 5700 case OPC_BC1FL: 5701 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5702 tcg_gen_not_i32(t0, t0); 5703 tcg_gen_andi_i32(t0, t0, 1); 5704 tcg_gen_extu_i32_tl(bcond, t0); 5705 opn = "bc1fl"; 5706 goto likely; 5707 case OPC_BC1T: 5708 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5709 tcg_gen_andi_i32(t0, t0, 1); 5710 tcg_gen_extu_i32_tl(bcond, t0); 5711 opn = "bc1t"; 5712 goto not_likely; 5713 case OPC_BC1TL: 5714 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5715 tcg_gen_andi_i32(t0, t0, 1); 5716 tcg_gen_extu_i32_tl(bcond, t0); 5717 opn = "bc1tl"; 5718 likely: 5719 ctx->hflags |= MIPS_HFLAG_BL; 5720 break; 5721 case OPC_BC1FANY2: 5722 { 5723 TCGv_i32 t1 = tcg_temp_new_i32(); 5724 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5725 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5726 tcg_gen_or_i32(t0, t0, t1); 5727 tcg_temp_free_i32(t1); 5728 tcg_gen_not_i32(t0, t0); 5729 tcg_gen_andi_i32(t0, t0, 1); 5730 tcg_gen_extu_i32_tl(bcond, t0); 5731 } 5732 opn = "bc1any2f"; 5733 goto not_likely; 5734 case OPC_BC1TANY2: 5735 { 5736 TCGv_i32 t1 = tcg_temp_new_i32(); 5737 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5738 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5739 tcg_gen_or_i32(t0, t0, t1); 5740 tcg_temp_free_i32(t1); 5741 tcg_gen_andi_i32(t0, t0, 1); 5742 tcg_gen_extu_i32_tl(bcond, t0); 5743 } 5744 opn = "bc1any2t"; 5745 goto not_likely; 5746 case OPC_BC1FANY4: 5747 { 5748 TCGv_i32 t1 = tcg_temp_new_i32(); 5749 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5750 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5751 tcg_gen_or_i32(t0, t0, t1); 5752 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); 5753 tcg_gen_or_i32(t0, t0, t1); 5754 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); 5755 tcg_gen_or_i32(t0, t0, t1); 5756 tcg_temp_free_i32(t1); 5757 tcg_gen_not_i32(t0, t0); 5758 tcg_gen_andi_i32(t0, t0, 1); 5759 tcg_gen_extu_i32_tl(bcond, t0); 5760 } 5761 opn = "bc1any4f"; 5762 goto not_likely; 5763 case OPC_BC1TANY4: 5764 { 5765 TCGv_i32 t1 = tcg_temp_new_i32(); 5766 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 5767 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); 5768 tcg_gen_or_i32(t0, t0, t1); 5769 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); 5770 tcg_gen_or_i32(t0, t0, t1); 5771 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); 5772 tcg_gen_or_i32(t0, t0, t1); 5773 tcg_temp_free_i32(t1); 5774 tcg_gen_andi_i32(t0, t0, 1); 5775 tcg_gen_extu_i32_tl(bcond, t0); 5776 } 5777 opn = "bc1any4t"; 5778 not_likely: 5779 ctx->hflags |= MIPS_HFLAG_BC; 5780 break; 5781 default: 5782 MIPS_INVAL(opn); 5783 generate_exception (ctx, EXCP_RI); 5784 goto out; 5785 } 5786 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn, 5787 ctx->hflags, btarget); 5788 ctx->btarget = btarget; 5789 5790 out: 5791 tcg_temp_free_i32(t0); 5792} 5793 5794/* Coprocessor 1 (FPU) */ 5795 5796#define FOP(func, fmt) (((fmt) << 21) | (func)) 5797 5798static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) 5799{ 5800 const char* __attribute__((unused)) opn = "cp1 move"; 5801 TCGv t0 = tcg_temp_new(); 5802 5803 switch (opc) { 5804 case OPC_MFC1: 5805 { 5806 TCGv_i32 fp0 = tcg_temp_new_i32(); 5807 5808 gen_load_fpr32(fp0, fs); 5809 tcg_gen_ext_i32_tl(t0, fp0); 5810 tcg_temp_free_i32(fp0); 5811 } 5812 gen_store_gpr(t0, rt); 5813 opn = "mfc1"; 5814 break; 5815 case OPC_MTC1: 5816 gen_load_gpr(t0, rt); 5817 { 5818 TCGv_i32 fp0 = tcg_temp_new_i32(); 5819 5820 tcg_gen_trunc_tl_i32(fp0, t0); 5821 gen_store_fpr32(fp0, fs); 5822 tcg_temp_free_i32(fp0); 5823 } 5824 opn = "mtc1"; 5825 break; 5826 case OPC_CFC1: 5827 gen_helper_2i(cfc1, t0, cpu_env, fs); 5828 gen_store_gpr(t0, rt); 5829 opn = "cfc1"; 5830 break; 5831 case OPC_CTC1: 5832 gen_load_gpr(t0, rt); 5833 gen_helper_2i(ctc1, cpu_env, t0, fs); 5834 opn = "ctc1"; 5835 break; 5836#if defined(TARGET_MIPS64) 5837 case OPC_DMFC1: 5838 gen_load_fpr64(ctx, t0, fs); 5839 gen_store_gpr(t0, rt); 5840 opn = "dmfc1"; 5841 break; 5842 case OPC_DMTC1: 5843 gen_load_gpr(t0, rt); 5844 gen_store_fpr64(ctx, t0, fs); 5845 opn = "dmtc1"; 5846 break; 5847#endif 5848 case OPC_MFHC1: 5849 { 5850 TCGv_i32 fp0 = tcg_temp_new_i32(); 5851 5852 gen_load_fpr32h(fp0, fs); 5853 tcg_gen_ext_i32_tl(t0, fp0); 5854 tcg_temp_free_i32(fp0); 5855 } 5856 gen_store_gpr(t0, rt); 5857 opn = "mfhc1"; 5858 break; 5859 case OPC_MTHC1: 5860 gen_load_gpr(t0, rt); 5861 { 5862 TCGv_i32 fp0 = tcg_temp_new_i32(); 5863 5864 tcg_gen_trunc_tl_i32(fp0, t0); 5865 gen_store_fpr32h(fp0, fs); 5866 tcg_temp_free_i32(fp0); 5867 } 5868 opn = "mthc1"; 5869 break; 5870 default: 5871 MIPS_INVAL(opn); 5872 generate_exception (ctx, EXCP_RI); 5873 goto out; 5874 } 5875 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); 5876 5877 out: 5878 tcg_temp_free(t0); 5879} 5880 5881static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) 5882{ 5883 int l1; 5884 TCGCond cond; 5885 TCGv_i32 t0; 5886 5887 if (rd == 0) { 5888 /* Treat as NOP. */ 5889 return; 5890 } 5891 5892 if (tf) 5893 cond = TCG_COND_EQ; 5894 else 5895 cond = TCG_COND_NE; 5896 5897 l1 = gen_new_label(); 5898 t0 = tcg_temp_new_i32(); 5899 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5900 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5901 tcg_temp_free_i32(t0); 5902 if (rs == 0) { 5903 tcg_gen_movi_tl(cpu_gpr[rd], 0); 5904 } else { 5905 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 5906 } 5907 gen_set_label(l1); 5908} 5909 5910static inline void gen_movcf_s (int fs, int fd, int cc, int tf) 5911{ 5912 int cond; 5913 TCGv_i32 t0 = tcg_temp_new_i32(); 5914 int l1 = gen_new_label(); 5915 5916 if (tf) 5917 cond = TCG_COND_EQ; 5918 else 5919 cond = TCG_COND_NE; 5920 5921 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5922 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5923 gen_load_fpr32(t0, fs); 5924 gen_store_fpr32(t0, fd); 5925 gen_set_label(l1); 5926 tcg_temp_free_i32(t0); 5927} 5928 5929static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf) 5930{ 5931 int cond; 5932 TCGv_i32 t0 = tcg_temp_new_i32(); 5933 TCGv_i64 fp0; 5934 int l1 = gen_new_label(); 5935 5936 if (tf) 5937 cond = TCG_COND_EQ; 5938 else 5939 cond = TCG_COND_NE; 5940 5941 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5942 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5943 tcg_temp_free_i32(t0); 5944 fp0 = tcg_temp_new_i64(); 5945 gen_load_fpr64(ctx, fp0, fs); 5946 gen_store_fpr64(ctx, fp0, fd); 5947 tcg_temp_free_i64(fp0); 5948 gen_set_label(l1); 5949} 5950 5951static inline void gen_movcf_ps (int fs, int fd, int cc, int tf) 5952{ 5953 int cond; 5954 TCGv_i32 t0 = tcg_temp_new_i32(); 5955 int l1 = gen_new_label(); 5956 int l2 = gen_new_label(); 5957 5958 if (tf) 5959 cond = TCG_COND_EQ; 5960 else 5961 cond = TCG_COND_NE; 5962 5963 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 5964 tcg_gen_brcondi_i32(cond, t0, 0, l1); 5965 gen_load_fpr32(t0, fs); 5966 gen_store_fpr32(t0, fd); 5967 gen_set_label(l1); 5968 5969 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1)); 5970 tcg_gen_brcondi_i32(cond, t0, 0, l2); 5971 gen_load_fpr32h(t0, fs); 5972 gen_store_fpr32h(t0, fd); 5973 tcg_temp_free_i32(t0); 5974 gen_set_label(l2); 5975} 5976 5977 5978static void gen_farith (DisasContext *ctx, uint32_t op1, 5979 int ft, int fs, int fd, int cc) 5980{ 5981 const char* __attribute__((unused)) opn = "farith"; 5982 const char *condnames[] = { 5983 "c.f", 5984 "c.un", 5985 "c.eq", 5986 "c.ueq", 5987 "c.olt", 5988 "c.ult", 5989 "c.ole", 5990 "c.ule", 5991 "c.sf", 5992 "c.ngle", 5993 "c.seq", 5994 "c.ngl", 5995 "c.lt", 5996 "c.nge", 5997 "c.le", 5998 "c.ngt", 5999 }; 6000 const char *condnames_abs[] = { 6001 "cabs.f", 6002 "cabs.un", 6003 "cabs.eq", 6004 "cabs.ueq", 6005 "cabs.olt", 6006 "cabs.ult", 6007 "cabs.ole", 6008 "cabs.ule", 6009 "cabs.sf", 6010 "cabs.ngle", 6011 "cabs.seq", 6012 "cabs.ngl", 6013 "cabs.lt", 6014 "cabs.nge", 6015 "cabs.le", 6016 "cabs.ngt", 6017 }; 6018 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP; 6019 uint32_t func = ctx->opcode & 0x3f; 6020 6021 switch (ctx->opcode & FOP(0x3f, 0x1f)) { 6022 case FOP(0, 16): 6023 { 6024 TCGv_i32 fp0 = tcg_temp_new_i32(); 6025 TCGv_i32 fp1 = tcg_temp_new_i32(); 6026 6027 gen_load_fpr32(fp0, fs); 6028 gen_load_fpr32(fp1, ft); 6029 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 6030 tcg_temp_free_i32(fp1); 6031 gen_store_fpr32(fp0, fd); 6032 tcg_temp_free_i32(fp0); 6033 } 6034 opn = "add.s"; 6035 optype = BINOP; 6036 break; 6037 case FOP(1, 16): 6038 { 6039 TCGv_i32 fp0 = tcg_temp_new_i32(); 6040 TCGv_i32 fp1 = tcg_temp_new_i32(); 6041 6042 gen_load_fpr32(fp0, fs); 6043 gen_load_fpr32(fp1, ft); 6044 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 6045 tcg_temp_free_i32(fp1); 6046 gen_store_fpr32(fp0, fd); 6047 tcg_temp_free_i32(fp0); 6048 } 6049 opn = "sub.s"; 6050 optype = BINOP; 6051 break; 6052 case FOP(2, 16): 6053 { 6054 TCGv_i32 fp0 = tcg_temp_new_i32(); 6055 TCGv_i32 fp1 = tcg_temp_new_i32(); 6056 6057 gen_load_fpr32(fp0, fs); 6058 gen_load_fpr32(fp1, ft); 6059 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 6060 tcg_temp_free_i32(fp1); 6061 gen_store_fpr32(fp0, fd); 6062 tcg_temp_free_i32(fp0); 6063 } 6064 opn = "mul.s"; 6065 optype = BINOP; 6066 break; 6067 case FOP(3, 16): 6068 { 6069 TCGv_i32 fp0 = tcg_temp_new_i32(); 6070 TCGv_i32 fp1 = tcg_temp_new_i32(); 6071 6072 gen_load_fpr32(fp0, fs); 6073 gen_load_fpr32(fp1, ft); 6074 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 6075 tcg_temp_free_i32(fp1); 6076 gen_store_fpr32(fp0, fd); 6077 tcg_temp_free_i32(fp0); 6078 } 6079 opn = "div.s"; 6080 optype = BINOP; 6081 break; 6082 case FOP(4, 16): 6083 { 6084 TCGv_i32 fp0 = tcg_temp_new_i32(); 6085 6086 gen_load_fpr32(fp0, fs); 6087 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 6088 gen_store_fpr32(fp0, fd); 6089 tcg_temp_free_i32(fp0); 6090 } 6091 opn = "sqrt.s"; 6092 break; 6093 case FOP(5, 16): 6094 { 6095 TCGv_i32 fp0 = tcg_temp_new_i32(); 6096 6097 gen_load_fpr32(fp0, fs); 6098 gen_helper_float_abs_s(fp0, fp0); 6099 gen_store_fpr32(fp0, fd); 6100 tcg_temp_free_i32(fp0); 6101 } 6102 opn = "abs.s"; 6103 break; 6104 case FOP(6, 16): 6105 { 6106 TCGv_i32 fp0 = tcg_temp_new_i32(); 6107 6108 gen_load_fpr32(fp0, fs); 6109 gen_store_fpr32(fp0, fd); 6110 tcg_temp_free_i32(fp0); 6111 } 6112 opn = "mov.s"; 6113 break; 6114 case FOP(7, 16): 6115 { 6116 TCGv_i32 fp0 = tcg_temp_new_i32(); 6117 6118 gen_load_fpr32(fp0, fs); 6119 gen_helper_float_chs_s(fp0, fp0); 6120 gen_store_fpr32(fp0, fd); 6121 tcg_temp_free_i32(fp0); 6122 } 6123 opn = "neg.s"; 6124 break; 6125 case FOP(8, 16): 6126 check_cp1_64bitmode(ctx); 6127 { 6128 TCGv_i32 fp32 = tcg_temp_new_i32(); 6129 TCGv_i64 fp64 = tcg_temp_new_i64(); 6130 6131 gen_load_fpr32(fp32, fs); 6132 gen_helper_float_roundl_s(fp64, cpu_env, fp32); 6133 tcg_temp_free_i32(fp32); 6134 gen_store_fpr64(ctx, fp64, fd); 6135 tcg_temp_free_i64(fp64); 6136 } 6137 opn = "round.l.s"; 6138 break; 6139 case FOP(9, 16): 6140 check_cp1_64bitmode(ctx); 6141 { 6142 TCGv_i32 fp32 = tcg_temp_new_i32(); 6143 TCGv_i64 fp64 = tcg_temp_new_i64(); 6144 6145 gen_load_fpr32(fp32, fs); 6146 gen_helper_float_truncl_s(fp64, cpu_env, fp32); 6147 tcg_temp_free_i32(fp32); 6148 gen_store_fpr64(ctx, fp64, fd); 6149 tcg_temp_free_i64(fp64); 6150 } 6151 opn = "trunc.l.s"; 6152 break; 6153 case FOP(10, 16): 6154 check_cp1_64bitmode(ctx); 6155 { 6156 TCGv_i32 fp32 = tcg_temp_new_i32(); 6157 TCGv_i64 fp64 = tcg_temp_new_i64(); 6158 6159 gen_load_fpr32(fp32, fs); 6160 gen_helper_float_ceill_s(fp64, cpu_env, fp32); 6161 tcg_temp_free_i32(fp32); 6162 gen_store_fpr64(ctx, fp64, fd); 6163 tcg_temp_free_i64(fp64); 6164 } 6165 opn = "ceil.l.s"; 6166 break; 6167 case FOP(11, 16): 6168 check_cp1_64bitmode(ctx); 6169 { 6170 TCGv_i32 fp32 = tcg_temp_new_i32(); 6171 TCGv_i64 fp64 = tcg_temp_new_i64(); 6172 6173 gen_load_fpr32(fp32, fs); 6174 gen_helper_float_floorl_s(fp64, cpu_env, fp32); 6175 tcg_temp_free_i32(fp32); 6176 gen_store_fpr64(ctx, fp64, fd); 6177 tcg_temp_free_i64(fp64); 6178 } 6179 opn = "floor.l.s"; 6180 break; 6181 case FOP(12, 16): 6182 { 6183 TCGv_i32 fp0 = tcg_temp_new_i32(); 6184 6185 gen_load_fpr32(fp0, fs); 6186 gen_helper_float_roundw_s(fp0, cpu_env, fp0); 6187 gen_store_fpr32(fp0, fd); 6188 tcg_temp_free_i32(fp0); 6189 } 6190 opn = "round.w.s"; 6191 break; 6192 case FOP(13, 16): 6193 { 6194 TCGv_i32 fp0 = tcg_temp_new_i32(); 6195 6196 gen_load_fpr32(fp0, fs); 6197 gen_helper_float_truncw_s(fp0, cpu_env, fp0); 6198 gen_store_fpr32(fp0, fd); 6199 tcg_temp_free_i32(fp0); 6200 } 6201 opn = "trunc.w.s"; 6202 break; 6203 case FOP(14, 16): 6204 { 6205 TCGv_i32 fp0 = tcg_temp_new_i32(); 6206 6207 gen_load_fpr32(fp0, fs); 6208 gen_helper_float_ceilw_s(fp0, cpu_env, fp0); 6209 gen_store_fpr32(fp0, fd); 6210 tcg_temp_free_i32(fp0); 6211 } 6212 opn = "ceil.w.s"; 6213 break; 6214 case FOP(15, 16): 6215 { 6216 TCGv_i32 fp0 = tcg_temp_new_i32(); 6217 6218 gen_load_fpr32(fp0, fs); 6219 gen_helper_float_floorw_s(fp0, cpu_env, fp0); 6220 gen_store_fpr32(fp0, fd); 6221 tcg_temp_free_i32(fp0); 6222 } 6223 opn = "floor.w.s"; 6224 break; 6225 case FOP(17, 16): 6226 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6227 opn = "movcf.s"; 6228 break; 6229 case FOP(18, 16): 6230 { 6231 int l1 = gen_new_label(); 6232 TCGv_i32 fp0; 6233 6234 if (ft != 0) { 6235 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6236 } 6237 fp0 = tcg_temp_new_i32(); 6238 gen_load_fpr32(fp0, fs); 6239 gen_store_fpr32(fp0, fd); 6240 tcg_temp_free_i32(fp0); 6241 gen_set_label(l1); 6242 } 6243 opn = "movz.s"; 6244 break; 6245 case FOP(19, 16): 6246 { 6247 int l1 = gen_new_label(); 6248 TCGv_i32 fp0; 6249 6250 if (ft != 0) { 6251 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 6252 fp0 = tcg_temp_new_i32(); 6253 gen_load_fpr32(fp0, fs); 6254 gen_store_fpr32(fp0, fd); 6255 tcg_temp_free_i32(fp0); 6256 gen_set_label(l1); 6257 } 6258 } 6259 opn = "movn.s"; 6260 break; 6261 case FOP(21, 16): 6262 check_cop1x(ctx); 6263 { 6264 TCGv_i32 fp0 = tcg_temp_new_i32(); 6265 6266 gen_load_fpr32(fp0, fs); 6267 gen_helper_float_recip_s(fp0, cpu_env, fp0); 6268 gen_store_fpr32(fp0, fd); 6269 tcg_temp_free_i32(fp0); 6270 } 6271 opn = "recip.s"; 6272 break; 6273 case FOP(22, 16): 6274 check_cop1x(ctx); 6275 { 6276 TCGv_i32 fp0 = tcg_temp_new_i32(); 6277 6278 gen_load_fpr32(fp0, fs); 6279 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 6280 gen_store_fpr32(fp0, fd); 6281 tcg_temp_free_i32(fp0); 6282 } 6283 opn = "rsqrt.s"; 6284 break; 6285 case FOP(28, 16): 6286 check_cp1_64bitmode(ctx); 6287 { 6288 TCGv_i32 fp0 = tcg_temp_new_i32(); 6289 TCGv_i32 fp1 = tcg_temp_new_i32(); 6290 6291 gen_load_fpr32(fp0, fs); 6292 gen_load_fpr32(fp1, fd); 6293 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 6294 tcg_temp_free_i32(fp1); 6295 gen_store_fpr32(fp0, fd); 6296 tcg_temp_free_i32(fp0); 6297 } 6298 opn = "recip2.s"; 6299 break; 6300 case FOP(29, 16): 6301 check_cp1_64bitmode(ctx); 6302 { 6303 TCGv_i32 fp0 = tcg_temp_new_i32(); 6304 6305 gen_load_fpr32(fp0, fs); 6306 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 6307 gen_store_fpr32(fp0, fd); 6308 tcg_temp_free_i32(fp0); 6309 } 6310 opn = "recip1.s"; 6311 break; 6312 case FOP(30, 16): 6313 check_cp1_64bitmode(ctx); 6314 { 6315 TCGv_i32 fp0 = tcg_temp_new_i32(); 6316 6317 gen_load_fpr32(fp0, fs); 6318 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 6319 gen_store_fpr32(fp0, fd); 6320 tcg_temp_free_i32(fp0); 6321 } 6322 opn = "rsqrt1.s"; 6323 break; 6324 case FOP(31, 16): 6325 check_cp1_64bitmode(ctx); 6326 { 6327 TCGv_i32 fp0 = tcg_temp_new_i32(); 6328 TCGv_i32 fp1 = tcg_temp_new_i32(); 6329 6330 gen_load_fpr32(fp0, fs); 6331 gen_load_fpr32(fp1, ft); 6332 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 6333 tcg_temp_free_i32(fp1); 6334 gen_store_fpr32(fp0, fd); 6335 tcg_temp_free_i32(fp0); 6336 } 6337 opn = "rsqrt2.s"; 6338 break; 6339 case FOP(33, 16): 6340 check_cp1_registers(ctx, fd); 6341 { 6342 TCGv_i32 fp32 = tcg_temp_new_i32(); 6343 TCGv_i64 fp64 = tcg_temp_new_i64(); 6344 6345 gen_load_fpr32(fp32, fs); 6346 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 6347 tcg_temp_free_i32(fp32); 6348 gen_store_fpr64(ctx, fp64, fd); 6349 tcg_temp_free_i64(fp64); 6350 } 6351 opn = "cvt.d.s"; 6352 break; 6353 case FOP(36, 16): 6354 { 6355 TCGv_i32 fp0 = tcg_temp_new_i32(); 6356 6357 gen_load_fpr32(fp0, fs); 6358 gen_helper_float_cvtw_s(fp0, cpu_env, fp0); 6359 gen_store_fpr32(fp0, fd); 6360 tcg_temp_free_i32(fp0); 6361 } 6362 opn = "cvt.w.s"; 6363 break; 6364 case FOP(37, 16): 6365 check_cp1_64bitmode(ctx); 6366 { 6367 TCGv_i32 fp32 = tcg_temp_new_i32(); 6368 TCGv_i64 fp64 = tcg_temp_new_i64(); 6369 6370 gen_load_fpr32(fp32, fs); 6371 gen_helper_float_cvtl_s(fp64, cpu_env, fp32); 6372 tcg_temp_free_i32(fp32); 6373 gen_store_fpr64(ctx, fp64, fd); 6374 tcg_temp_free_i64(fp64); 6375 } 6376 opn = "cvt.l.s"; 6377 break; 6378 case FOP(38, 16): 6379 check_cp1_64bitmode(ctx); 6380 { 6381 TCGv_i64 fp64 = tcg_temp_new_i64(); 6382 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 6383 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 6384 6385 gen_load_fpr32(fp32_0, fs); 6386 gen_load_fpr32(fp32_1, ft); 6387 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1); 6388 tcg_temp_free_i32(fp32_1); 6389 tcg_temp_free_i32(fp32_0); 6390 gen_store_fpr64(ctx, fp64, fd); 6391 tcg_temp_free_i64(fp64); 6392 } 6393 opn = "cvt.ps.s"; 6394 break; 6395 case FOP(48, 16): 6396 case FOP(49, 16): 6397 case FOP(50, 16): 6398 case FOP(51, 16): 6399 case FOP(52, 16): 6400 case FOP(53, 16): 6401 case FOP(54, 16): 6402 case FOP(55, 16): 6403 case FOP(56, 16): 6404 case FOP(57, 16): 6405 case FOP(58, 16): 6406 case FOP(59, 16): 6407 case FOP(60, 16): 6408 case FOP(61, 16): 6409 case FOP(62, 16): 6410 case FOP(63, 16): 6411 { 6412 TCGv_i32 fp0 = tcg_temp_new_i32(); 6413 TCGv_i32 fp1 = tcg_temp_new_i32(); 6414 6415 gen_load_fpr32(fp0, fs); 6416 gen_load_fpr32(fp1, ft); 6417 if (ctx->opcode & (1 << 6)) { 6418 check_cop1x(ctx); 6419 gen_cmpabs_s(func-48, fp0, fp1, cc); 6420 opn = condnames_abs[func-48]; 6421 } else { 6422 gen_cmp_s(func-48, fp0, fp1, cc); 6423 opn = condnames[func-48]; 6424 } 6425 tcg_temp_free_i32(fp0); 6426 tcg_temp_free_i32(fp1); 6427 } 6428 break; 6429 case FOP(0, 17): 6430 check_cp1_registers(ctx, fs | ft | fd); 6431 { 6432 TCGv_i64 fp0 = tcg_temp_new_i64(); 6433 TCGv_i64 fp1 = tcg_temp_new_i64(); 6434 6435 gen_load_fpr64(ctx, fp0, fs); 6436 gen_load_fpr64(ctx, fp1, ft); 6437 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 6438 tcg_temp_free_i64(fp1); 6439 gen_store_fpr64(ctx, fp0, fd); 6440 tcg_temp_free_i64(fp0); 6441 } 6442 opn = "add.d"; 6443 optype = BINOP; 6444 break; 6445 case FOP(1, 17): 6446 check_cp1_registers(ctx, fs | ft | fd); 6447 { 6448 TCGv_i64 fp0 = tcg_temp_new_i64(); 6449 TCGv_i64 fp1 = tcg_temp_new_i64(); 6450 6451 gen_load_fpr64(ctx, fp0, fs); 6452 gen_load_fpr64(ctx, fp1, ft); 6453 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 6454 tcg_temp_free_i64(fp1); 6455 gen_store_fpr64(ctx, fp0, fd); 6456 tcg_temp_free_i64(fp0); 6457 } 6458 opn = "sub.d"; 6459 optype = BINOP; 6460 break; 6461 case FOP(2, 17): 6462 check_cp1_registers(ctx, fs | ft | fd); 6463 { 6464 TCGv_i64 fp0 = tcg_temp_new_i64(); 6465 TCGv_i64 fp1 = tcg_temp_new_i64(); 6466 6467 gen_load_fpr64(ctx, fp0, fs); 6468 gen_load_fpr64(ctx, fp1, ft); 6469 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 6470 tcg_temp_free_i64(fp1); 6471 gen_store_fpr64(ctx, fp0, fd); 6472 tcg_temp_free_i64(fp0); 6473 } 6474 opn = "mul.d"; 6475 optype = BINOP; 6476 break; 6477 case FOP(3, 17): 6478 check_cp1_registers(ctx, fs | ft | fd); 6479 { 6480 TCGv_i64 fp0 = tcg_temp_new_i64(); 6481 TCGv_i64 fp1 = tcg_temp_new_i64(); 6482 6483 gen_load_fpr64(ctx, fp0, fs); 6484 gen_load_fpr64(ctx, fp1, ft); 6485 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 6486 tcg_temp_free_i64(fp1); 6487 gen_store_fpr64(ctx, fp0, fd); 6488 tcg_temp_free_i64(fp0); 6489 } 6490 opn = "div.d"; 6491 optype = BINOP; 6492 break; 6493 case FOP(4, 17): 6494 check_cp1_registers(ctx, fs | fd); 6495 { 6496 TCGv_i64 fp0 = tcg_temp_new_i64(); 6497 6498 gen_load_fpr64(ctx, fp0, fs); 6499 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 6500 gen_store_fpr64(ctx, fp0, fd); 6501 tcg_temp_free_i64(fp0); 6502 } 6503 opn = "sqrt.d"; 6504 break; 6505 case FOP(5, 17): 6506 check_cp1_registers(ctx, fs | fd); 6507 { 6508 TCGv_i64 fp0 = tcg_temp_new_i64(); 6509 6510 gen_load_fpr64(ctx, fp0, fs); 6511 gen_helper_float_abs_d(fp0, fp0); 6512 gen_store_fpr64(ctx, fp0, fd); 6513 tcg_temp_free_i64(fp0); 6514 } 6515 opn = "abs.d"; 6516 break; 6517 case FOP(6, 17): 6518 check_cp1_registers(ctx, fs | fd); 6519 { 6520 TCGv_i64 fp0 = tcg_temp_new_i64(); 6521 6522 gen_load_fpr64(ctx, fp0, fs); 6523 gen_store_fpr64(ctx, fp0, fd); 6524 tcg_temp_free_i64(fp0); 6525 } 6526 opn = "mov.d"; 6527 break; 6528 case FOP(7, 17): 6529 check_cp1_registers(ctx, fs | fd); 6530 { 6531 TCGv_i64 fp0 = tcg_temp_new_i64(); 6532 6533 gen_load_fpr64(ctx, fp0, fs); 6534 gen_helper_float_chs_d(fp0, fp0); 6535 gen_store_fpr64(ctx, fp0, fd); 6536 tcg_temp_free_i64(fp0); 6537 } 6538 opn = "neg.d"; 6539 break; 6540 case FOP(8, 17): 6541 check_cp1_64bitmode(ctx); 6542 { 6543 TCGv_i64 fp0 = tcg_temp_new_i64(); 6544 6545 gen_load_fpr64(ctx, fp0, fs); 6546 gen_helper_float_roundl_d(fp0, cpu_env, fp0); 6547 gen_store_fpr64(ctx, fp0, fd); 6548 tcg_temp_free_i64(fp0); 6549 } 6550 opn = "round.l.d"; 6551 break; 6552 case FOP(9, 17): 6553 check_cp1_64bitmode(ctx); 6554 { 6555 TCGv_i64 fp0 = tcg_temp_new_i64(); 6556 6557 gen_load_fpr64(ctx, fp0, fs); 6558 gen_helper_float_truncl_d(fp0, cpu_env, fp0); 6559 gen_store_fpr64(ctx, fp0, fd); 6560 tcg_temp_free_i64(fp0); 6561 } 6562 opn = "trunc.l.d"; 6563 break; 6564 case FOP(10, 17): 6565 check_cp1_64bitmode(ctx); 6566 { 6567 TCGv_i64 fp0 = tcg_temp_new_i64(); 6568 6569 gen_load_fpr64(ctx, fp0, fs); 6570 gen_helper_float_ceill_d(fp0, cpu_env, fp0); 6571 gen_store_fpr64(ctx, fp0, fd); 6572 tcg_temp_free_i64(fp0); 6573 } 6574 opn = "ceil.l.d"; 6575 break; 6576 case FOP(11, 17): 6577 check_cp1_64bitmode(ctx); 6578 { 6579 TCGv_i64 fp0 = tcg_temp_new_i64(); 6580 6581 gen_load_fpr64(ctx, fp0, fs); 6582 gen_helper_float_floorl_d(fp0, cpu_env, fp0); 6583 gen_store_fpr64(ctx, fp0, fd); 6584 tcg_temp_free_i64(fp0); 6585 } 6586 opn = "floor.l.d"; 6587 break; 6588 case FOP(12, 17): 6589 check_cp1_registers(ctx, fs); 6590 { 6591 TCGv_i32 fp32 = tcg_temp_new_i32(); 6592 TCGv_i64 fp64 = tcg_temp_new_i64(); 6593 6594 gen_load_fpr64(ctx, fp64, fs); 6595 gen_helper_float_roundw_d(fp32, cpu_env, fp64); 6596 tcg_temp_free_i64(fp64); 6597 gen_store_fpr32(fp32, fd); 6598 tcg_temp_free_i32(fp32); 6599 } 6600 opn = "round.w.d"; 6601 break; 6602 case FOP(13, 17): 6603 check_cp1_registers(ctx, fs); 6604 { 6605 TCGv_i32 fp32 = tcg_temp_new_i32(); 6606 TCGv_i64 fp64 = tcg_temp_new_i64(); 6607 6608 gen_load_fpr64(ctx, fp64, fs); 6609 gen_helper_float_truncw_d(fp32, cpu_env, fp64); 6610 tcg_temp_free_i64(fp64); 6611 gen_store_fpr32(fp32, fd); 6612 tcg_temp_free_i32(fp32); 6613 } 6614 opn = "trunc.w.d"; 6615 break; 6616 case FOP(14, 17): 6617 check_cp1_registers(ctx, fs); 6618 { 6619 TCGv_i32 fp32 = tcg_temp_new_i32(); 6620 TCGv_i64 fp64 = tcg_temp_new_i64(); 6621 6622 gen_load_fpr64(ctx, fp64, fs); 6623 gen_helper_float_ceilw_d(fp32, cpu_env, fp64); 6624 tcg_temp_free_i64(fp64); 6625 gen_store_fpr32(fp32, fd); 6626 tcg_temp_free_i32(fp32); 6627 } 6628 opn = "ceil.w.d"; 6629 break; 6630 case FOP(15, 17): 6631 check_cp1_registers(ctx, fs); 6632 { 6633 TCGv_i32 fp32 = tcg_temp_new_i32(); 6634 TCGv_i64 fp64 = tcg_temp_new_i64(); 6635 6636 gen_load_fpr64(ctx, fp64, fs); 6637 gen_helper_float_floorw_d(fp32, cpu_env, fp64); 6638 tcg_temp_free_i64(fp64); 6639 gen_store_fpr32(fp32, fd); 6640 tcg_temp_free_i32(fp32); 6641 } 6642 opn = "floor.w.d"; 6643 break; 6644 case FOP(17, 17): 6645 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6646 opn = "movcf.d"; 6647 break; 6648 case FOP(18, 17): 6649 { 6650 int l1 = gen_new_label(); 6651 TCGv_i64 fp0; 6652 6653 if (ft != 0) { 6654 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6655 } 6656 fp0 = tcg_temp_new_i64(); 6657 gen_load_fpr64(ctx, fp0, fs); 6658 gen_store_fpr64(ctx, fp0, fd); 6659 tcg_temp_free_i64(fp0); 6660 gen_set_label(l1); 6661 } 6662 opn = "movz.d"; 6663 break; 6664 case FOP(19, 17): 6665 { 6666 int l1 = gen_new_label(); 6667 TCGv_i64 fp0; 6668 6669 if (ft != 0) { 6670 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 6671 fp0 = tcg_temp_new_i64(); 6672 gen_load_fpr64(ctx, fp0, fs); 6673 gen_store_fpr64(ctx, fp0, fd); 6674 tcg_temp_free_i64(fp0); 6675 gen_set_label(l1); 6676 } 6677 } 6678 opn = "movn.d"; 6679 break; 6680 case FOP(21, 17): 6681 check_cp1_64bitmode(ctx); 6682 { 6683 TCGv_i64 fp0 = tcg_temp_new_i64(); 6684 6685 gen_load_fpr64(ctx, fp0, fs); 6686 gen_helper_float_recip_d(fp0, cpu_env, fp0); 6687 gen_store_fpr64(ctx, fp0, fd); 6688 tcg_temp_free_i64(fp0); 6689 } 6690 opn = "recip.d"; 6691 break; 6692 case FOP(22, 17): 6693 check_cp1_64bitmode(ctx); 6694 { 6695 TCGv_i64 fp0 = tcg_temp_new_i64(); 6696 6697 gen_load_fpr64(ctx, fp0, fs); 6698 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 6699 gen_store_fpr64(ctx, fp0, fd); 6700 tcg_temp_free_i64(fp0); 6701 } 6702 opn = "rsqrt.d"; 6703 break; 6704 case FOP(28, 17): 6705 check_cp1_64bitmode(ctx); 6706 { 6707 TCGv_i64 fp0 = tcg_temp_new_i64(); 6708 TCGv_i64 fp1 = tcg_temp_new_i64(); 6709 6710 gen_load_fpr64(ctx, fp0, fs); 6711 gen_load_fpr64(ctx, fp1, ft); 6712 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 6713 tcg_temp_free_i64(fp1); 6714 gen_store_fpr64(ctx, fp0, fd); 6715 tcg_temp_free_i64(fp0); 6716 } 6717 opn = "recip2.d"; 6718 break; 6719 case FOP(29, 17): 6720 check_cp1_64bitmode(ctx); 6721 { 6722 TCGv_i64 fp0 = tcg_temp_new_i64(); 6723 6724 gen_load_fpr64(ctx, fp0, fs); 6725 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 6726 gen_store_fpr64(ctx, fp0, fd); 6727 tcg_temp_free_i64(fp0); 6728 } 6729 opn = "recip1.d"; 6730 break; 6731 case FOP(30, 17): 6732 check_cp1_64bitmode(ctx); 6733 { 6734 TCGv_i64 fp0 = tcg_temp_new_i64(); 6735 6736 gen_load_fpr64(ctx, fp0, fs); 6737 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 6738 gen_store_fpr64(ctx, fp0, fd); 6739 tcg_temp_free_i64(fp0); 6740 } 6741 opn = "rsqrt1.d"; 6742 break; 6743 case FOP(31, 17): 6744 check_cp1_64bitmode(ctx); 6745 { 6746 TCGv_i64 fp0 = tcg_temp_new_i64(); 6747 TCGv_i64 fp1 = tcg_temp_new_i64(); 6748 6749 gen_load_fpr64(ctx, fp0, fs); 6750 gen_load_fpr64(ctx, fp1, ft); 6751 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 6752 tcg_temp_free_i64(fp1); 6753 gen_store_fpr64(ctx, fp0, fd); 6754 tcg_temp_free_i64(fp0); 6755 } 6756 opn = "rsqrt2.d"; 6757 break; 6758 case FOP(48, 17): 6759 case FOP(49, 17): 6760 case FOP(50, 17): 6761 case FOP(51, 17): 6762 case FOP(52, 17): 6763 case FOP(53, 17): 6764 case FOP(54, 17): 6765 case FOP(55, 17): 6766 case FOP(56, 17): 6767 case FOP(57, 17): 6768 case FOP(58, 17): 6769 case FOP(59, 17): 6770 case FOP(60, 17): 6771 case FOP(61, 17): 6772 case FOP(62, 17): 6773 case FOP(63, 17): 6774 { 6775 TCGv_i64 fp0 = tcg_temp_new_i64(); 6776 TCGv_i64 fp1 = tcg_temp_new_i64(); 6777 6778 gen_load_fpr64(ctx, fp0, fs); 6779 gen_load_fpr64(ctx, fp1, ft); 6780 if (ctx->opcode & (1 << 6)) { 6781 check_cop1x(ctx); 6782 check_cp1_registers(ctx, fs | ft); 6783 gen_cmpabs_d(func-48, fp0, fp1, cc); 6784 opn = condnames_abs[func-48]; 6785 } else { 6786 check_cp1_registers(ctx, fs | ft); 6787 gen_cmp_d(func-48, fp0, fp1, cc); 6788 opn = condnames[func-48]; 6789 } 6790 tcg_temp_free_i64(fp0); 6791 tcg_temp_free_i64(fp1); 6792 } 6793 break; 6794 case FOP(32, 17): 6795 check_cp1_registers(ctx, fs); 6796 { 6797 TCGv_i32 fp32 = tcg_temp_new_i32(); 6798 TCGv_i64 fp64 = tcg_temp_new_i64(); 6799 6800 gen_load_fpr64(ctx, fp64, fs); 6801 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 6802 tcg_temp_free_i64(fp64); 6803 gen_store_fpr32(fp32, fd); 6804 tcg_temp_free_i32(fp32); 6805 } 6806 opn = "cvt.s.d"; 6807 break; 6808 case FOP(36, 17): 6809 check_cp1_registers(ctx, fs); 6810 { 6811 TCGv_i32 fp32 = tcg_temp_new_i32(); 6812 TCGv_i64 fp64 = tcg_temp_new_i64(); 6813 6814 gen_load_fpr64(ctx, fp64, fs); 6815 gen_helper_float_cvtw_d(fp32, cpu_env, fp64); 6816 tcg_temp_free_i64(fp64); 6817 gen_store_fpr32(fp32, fd); 6818 tcg_temp_free_i32(fp32); 6819 } 6820 opn = "cvt.w.d"; 6821 break; 6822 case FOP(37, 17): 6823 check_cp1_64bitmode(ctx); 6824 { 6825 TCGv_i64 fp0 = tcg_temp_new_i64(); 6826 6827 gen_load_fpr64(ctx, fp0, fs); 6828 gen_helper_float_cvtl_d(fp0, cpu_env, fp0); 6829 gen_store_fpr64(ctx, fp0, fd); 6830 tcg_temp_free_i64(fp0); 6831 } 6832 opn = "cvt.l.d"; 6833 break; 6834 case FOP(32, 20): 6835 { 6836 TCGv_i32 fp0 = tcg_temp_new_i32(); 6837 6838 gen_load_fpr32(fp0, fs); 6839 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 6840 gen_store_fpr32(fp0, fd); 6841 tcg_temp_free_i32(fp0); 6842 } 6843 opn = "cvt.s.w"; 6844 break; 6845 case FOP(33, 20): 6846 check_cp1_registers(ctx, fd); 6847 { 6848 TCGv_i32 fp32 = tcg_temp_new_i32(); 6849 TCGv_i64 fp64 = tcg_temp_new_i64(); 6850 6851 gen_load_fpr32(fp32, fs); 6852 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 6853 tcg_temp_free_i32(fp32); 6854 gen_store_fpr64(ctx, fp64, fd); 6855 tcg_temp_free_i64(fp64); 6856 } 6857 opn = "cvt.d.w"; 6858 break; 6859 case FOP(32, 21): 6860 check_cp1_64bitmode(ctx); 6861 { 6862 TCGv_i32 fp32 = tcg_temp_new_i32(); 6863 TCGv_i64 fp64 = tcg_temp_new_i64(); 6864 6865 gen_load_fpr64(ctx, fp64, fs); 6866 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 6867 tcg_temp_free_i64(fp64); 6868 gen_store_fpr32(fp32, fd); 6869 tcg_temp_free_i32(fp32); 6870 } 6871 opn = "cvt.s.l"; 6872 break; 6873 case FOP(33, 21): 6874 check_cp1_64bitmode(ctx); 6875 { 6876 TCGv_i64 fp0 = tcg_temp_new_i64(); 6877 6878 gen_load_fpr64(ctx, fp0, fs); 6879 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 6880 gen_store_fpr64(ctx, fp0, fd); 6881 tcg_temp_free_i64(fp0); 6882 } 6883 opn = "cvt.d.l"; 6884 break; 6885 case FOP(38, 20): 6886 check_cp1_64bitmode(ctx); 6887 { 6888 TCGv_i64 fp0 = tcg_temp_new_i64(); 6889 6890 gen_load_fpr64(ctx, fp0, fs); 6891 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 6892 gen_store_fpr64(ctx, fp0, fd); 6893 tcg_temp_free_i64(fp0); 6894 } 6895 opn = "cvt.ps.pw"; 6896 break; 6897 case FOP(0, 22): 6898 check_cp1_64bitmode(ctx); 6899 { 6900 TCGv_i64 fp0 = tcg_temp_new_i64(); 6901 TCGv_i64 fp1 = tcg_temp_new_i64(); 6902 6903 gen_load_fpr64(ctx, fp0, fs); 6904 gen_load_fpr64(ctx, fp1, ft); 6905 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 6906 tcg_temp_free_i64(fp1); 6907 gen_store_fpr64(ctx, fp0, fd); 6908 tcg_temp_free_i64(fp0); 6909 } 6910 opn = "add.ps"; 6911 break; 6912 case FOP(1, 22): 6913 check_cp1_64bitmode(ctx); 6914 { 6915 TCGv_i64 fp0 = tcg_temp_new_i64(); 6916 TCGv_i64 fp1 = tcg_temp_new_i64(); 6917 6918 gen_load_fpr64(ctx, fp0, fs); 6919 gen_load_fpr64(ctx, fp1, ft); 6920 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 6921 tcg_temp_free_i64(fp1); 6922 gen_store_fpr64(ctx, fp0, fd); 6923 tcg_temp_free_i64(fp0); 6924 } 6925 opn = "sub.ps"; 6926 break; 6927 case FOP(2, 22): 6928 check_cp1_64bitmode(ctx); 6929 { 6930 TCGv_i64 fp0 = tcg_temp_new_i64(); 6931 TCGv_i64 fp1 = tcg_temp_new_i64(); 6932 6933 gen_load_fpr64(ctx, fp0, fs); 6934 gen_load_fpr64(ctx, fp1, ft); 6935 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 6936 tcg_temp_free_i64(fp1); 6937 gen_store_fpr64(ctx, fp0, fd); 6938 tcg_temp_free_i64(fp0); 6939 } 6940 opn = "mul.ps"; 6941 break; 6942 case FOP(5, 22): 6943 check_cp1_64bitmode(ctx); 6944 { 6945 TCGv_i64 fp0 = tcg_temp_new_i64(); 6946 6947 gen_load_fpr64(ctx, fp0, fs); 6948 gen_helper_float_abs_ps(fp0, fp0); 6949 gen_store_fpr64(ctx, fp0, fd); 6950 tcg_temp_free_i64(fp0); 6951 } 6952 opn = "abs.ps"; 6953 break; 6954 case FOP(6, 22): 6955 check_cp1_64bitmode(ctx); 6956 { 6957 TCGv_i64 fp0 = tcg_temp_new_i64(); 6958 6959 gen_load_fpr64(ctx, fp0, fs); 6960 gen_store_fpr64(ctx, fp0, fd); 6961 tcg_temp_free_i64(fp0); 6962 } 6963 opn = "mov.ps"; 6964 break; 6965 case FOP(7, 22): 6966 check_cp1_64bitmode(ctx); 6967 { 6968 TCGv_i64 fp0 = tcg_temp_new_i64(); 6969 6970 gen_load_fpr64(ctx, fp0, fs); 6971 gen_helper_float_chs_ps(fp0, fp0); 6972 gen_store_fpr64(ctx, fp0, fd); 6973 tcg_temp_free_i64(fp0); 6974 } 6975 opn = "neg.ps"; 6976 break; 6977 case FOP(17, 22): 6978 check_cp1_64bitmode(ctx); 6979 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1); 6980 opn = "movcf.ps"; 6981 break; 6982 case FOP(18, 22): 6983 check_cp1_64bitmode(ctx); 6984 { 6985 int l1 = gen_new_label(); 6986 TCGv_i64 fp0; 6987 6988 if (ft != 0) 6989 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 6990 fp0 = tcg_temp_new_i64(); 6991 gen_load_fpr64(ctx, fp0, fs); 6992 gen_store_fpr64(ctx, fp0, fd); 6993 tcg_temp_free_i64(fp0); 6994 gen_set_label(l1); 6995 } 6996 opn = "movz.ps"; 6997 break; 6998 case FOP(19, 22): 6999 check_cp1_64bitmode(ctx); 7000 { 7001 int l1 = gen_new_label(); 7002 TCGv_i64 fp0; 7003 7004 if (ft != 0) { 7005 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 7006 fp0 = tcg_temp_new_i64(); 7007 gen_load_fpr64(ctx, fp0, fs); 7008 gen_store_fpr64(ctx, fp0, fd); 7009 tcg_temp_free_i64(fp0); 7010 gen_set_label(l1); 7011 } 7012 } 7013 opn = "movn.ps"; 7014 break; 7015 case FOP(24, 22): 7016 check_cp1_64bitmode(ctx); 7017 { 7018 TCGv_i64 fp0 = tcg_temp_new_i64(); 7019 TCGv_i64 fp1 = tcg_temp_new_i64(); 7020 7021 gen_load_fpr64(ctx, fp0, ft); 7022 gen_load_fpr64(ctx, fp1, fs); 7023 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 7024 tcg_temp_free_i64(fp1); 7025 gen_store_fpr64(ctx, fp0, fd); 7026 tcg_temp_free_i64(fp0); 7027 } 7028 opn = "addr.ps"; 7029 break; 7030 case FOP(26, 22): 7031 check_cp1_64bitmode(ctx); 7032 { 7033 TCGv_i64 fp0 = tcg_temp_new_i64(); 7034 TCGv_i64 fp1 = tcg_temp_new_i64(); 7035 7036 gen_load_fpr64(ctx, fp0, ft); 7037 gen_load_fpr64(ctx, fp1, fs); 7038 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 7039 tcg_temp_free_i64(fp1); 7040 gen_store_fpr64(ctx, fp0, fd); 7041 tcg_temp_free_i64(fp0); 7042 } 7043 opn = "mulr.ps"; 7044 break; 7045 case FOP(28, 22): 7046 check_cp1_64bitmode(ctx); 7047 { 7048 TCGv_i64 fp0 = tcg_temp_new_i64(); 7049 TCGv_i64 fp1 = tcg_temp_new_i64(); 7050 7051 gen_load_fpr64(ctx, fp0, fs); 7052 gen_load_fpr64(ctx, fp1, fd); 7053 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 7054 tcg_temp_free_i64(fp1); 7055 gen_store_fpr64(ctx, fp0, fd); 7056 tcg_temp_free_i64(fp0); 7057 } 7058 opn = "recip2.ps"; 7059 break; 7060 case FOP(29, 22): 7061 check_cp1_64bitmode(ctx); 7062 { 7063 TCGv_i64 fp0 = tcg_temp_new_i64(); 7064 7065 gen_load_fpr64(ctx, fp0, fs); 7066 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 7067 gen_store_fpr64(ctx, fp0, fd); 7068 tcg_temp_free_i64(fp0); 7069 } 7070 opn = "recip1.ps"; 7071 break; 7072 case FOP(30, 22): 7073 check_cp1_64bitmode(ctx); 7074 { 7075 TCGv_i64 fp0 = tcg_temp_new_i64(); 7076 7077 gen_load_fpr64(ctx, fp0, fs); 7078 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 7079 gen_store_fpr64(ctx, fp0, fd); 7080 tcg_temp_free_i64(fp0); 7081 } 7082 opn = "rsqrt1.ps"; 7083 break; 7084 case FOP(31, 22): 7085 check_cp1_64bitmode(ctx); 7086 { 7087 TCGv_i64 fp0 = tcg_temp_new_i64(); 7088 TCGv_i64 fp1 = tcg_temp_new_i64(); 7089 7090 gen_load_fpr64(ctx, fp0, fs); 7091 gen_load_fpr64(ctx, fp1, ft); 7092 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 7093 tcg_temp_free_i64(fp1); 7094 gen_store_fpr64(ctx, fp0, fd); 7095 tcg_temp_free_i64(fp0); 7096 } 7097 opn = "rsqrt2.ps"; 7098 break; 7099 case FOP(32, 22): 7100 check_cp1_64bitmode(ctx); 7101 { 7102 TCGv_i32 fp0 = tcg_temp_new_i32(); 7103 7104 gen_load_fpr32h(fp0, fs); 7105 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 7106 gen_store_fpr32(fp0, fd); 7107 tcg_temp_free_i32(fp0); 7108 } 7109 opn = "cvt.s.pu"; 7110 break; 7111 case FOP(36, 22): 7112 check_cp1_64bitmode(ctx); 7113 { 7114 TCGv_i64 fp0 = tcg_temp_new_i64(); 7115 7116 gen_load_fpr64(ctx, fp0, fs); 7117 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 7118 gen_store_fpr64(ctx, fp0, fd); 7119 tcg_temp_free_i64(fp0); 7120 } 7121 opn = "cvt.pw.ps"; 7122 break; 7123 case FOP(40, 22): 7124 check_cp1_64bitmode(ctx); 7125 { 7126 TCGv_i32 fp0 = tcg_temp_new_i32(); 7127 7128 gen_load_fpr32(fp0, fs); 7129 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 7130 gen_store_fpr32(fp0, fd); 7131 tcg_temp_free_i32(fp0); 7132 } 7133 opn = "cvt.s.pl"; 7134 break; 7135 case FOP(44, 22): 7136 check_cp1_64bitmode(ctx); 7137 { 7138 TCGv_i32 fp0 = tcg_temp_new_i32(); 7139 TCGv_i32 fp1 = tcg_temp_new_i32(); 7140 7141 gen_load_fpr32(fp0, fs); 7142 gen_load_fpr32(fp1, ft); 7143 gen_store_fpr32h(fp0, fd); 7144 gen_store_fpr32(fp1, fd); 7145 tcg_temp_free_i32(fp0); 7146 tcg_temp_free_i32(fp1); 7147 } 7148 opn = "pll.ps"; 7149 break; 7150 case FOP(45, 22): 7151 check_cp1_64bitmode(ctx); 7152 { 7153 TCGv_i32 fp0 = tcg_temp_new_i32(); 7154 TCGv_i32 fp1 = tcg_temp_new_i32(); 7155 7156 gen_load_fpr32(fp0, fs); 7157 gen_load_fpr32h(fp1, ft); 7158 gen_store_fpr32(fp1, fd); 7159 gen_store_fpr32h(fp0, fd); 7160 tcg_temp_free_i32(fp0); 7161 tcg_temp_free_i32(fp1); 7162 } 7163 opn = "plu.ps"; 7164 break; 7165 case FOP(46, 22): 7166 check_cp1_64bitmode(ctx); 7167 { 7168 TCGv_i32 fp0 = tcg_temp_new_i32(); 7169 TCGv_i32 fp1 = tcg_temp_new_i32(); 7170 7171 gen_load_fpr32h(fp0, fs); 7172 gen_load_fpr32(fp1, ft); 7173 gen_store_fpr32(fp1, fd); 7174 gen_store_fpr32h(fp0, fd); 7175 tcg_temp_free_i32(fp0); 7176 tcg_temp_free_i32(fp1); 7177 } 7178 opn = "pul.ps"; 7179 break; 7180 case FOP(47, 22): 7181 check_cp1_64bitmode(ctx); 7182 { 7183 TCGv_i32 fp0 = tcg_temp_new_i32(); 7184 TCGv_i32 fp1 = tcg_temp_new_i32(); 7185 7186 gen_load_fpr32h(fp0, fs); 7187 gen_load_fpr32h(fp1, ft); 7188 gen_store_fpr32(fp1, fd); 7189 gen_store_fpr32h(fp0, fd); 7190 tcg_temp_free_i32(fp0); 7191 tcg_temp_free_i32(fp1); 7192 } 7193 opn = "puu.ps"; 7194 break; 7195 case FOP(48, 22): 7196 case FOP(49, 22): 7197 case FOP(50, 22): 7198 case FOP(51, 22): 7199 case FOP(52, 22): 7200 case FOP(53, 22): 7201 case FOP(54, 22): 7202 case FOP(55, 22): 7203 case FOP(56, 22): 7204 case FOP(57, 22): 7205 case FOP(58, 22): 7206 case FOP(59, 22): 7207 case FOP(60, 22): 7208 case FOP(61, 22): 7209 case FOP(62, 22): 7210 case FOP(63, 22): 7211 check_cp1_64bitmode(ctx); 7212 { 7213 TCGv_i64 fp0 = tcg_temp_new_i64(); 7214 TCGv_i64 fp1 = tcg_temp_new_i64(); 7215 7216 gen_load_fpr64(ctx, fp0, fs); 7217 gen_load_fpr64(ctx, fp1, ft); 7218 if (ctx->opcode & (1 << 6)) { 7219 gen_cmpabs_ps(func-48, fp0, fp1, cc); 7220 opn = condnames_abs[func-48]; 7221 } else { 7222 gen_cmp_ps(func-48, fp0, fp1, cc); 7223 opn = condnames[func-48]; 7224 } 7225 tcg_temp_free_i64(fp0); 7226 tcg_temp_free_i64(fp1); 7227 } 7228 break; 7229 default: 7230 MIPS_INVAL(opn); 7231 generate_exception (ctx, EXCP_RI); 7232 return; 7233 } 7234 switch (optype) { 7235 case BINOP: 7236 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]); 7237 break; 7238 case CMPOP: 7239 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]); 7240 break; 7241 default: 7242 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]); 7243 break; 7244 } 7245} 7246 7247/* Coprocessor 3 (FPU) */ 7248static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, 7249 int fd, int fs, int base, int index) 7250{ 7251 const char* __attribute__((unused)) opn = "extended float load/store"; 7252 int __attribute__((unused)) store = 0; 7253 TCGv t0 = tcg_temp_new(); 7254 7255 if (base == 0) { 7256 gen_load_gpr(t0, index); 7257 } else if (index == 0) { 7258 gen_load_gpr(t0, base); 7259 } else { 7260 gen_load_gpr(t0, index); 7261 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0); 7262 } 7263 /* Don't do NOP if destination is zero: we must perform the actual 7264 memory access. */ 7265 save_cpu_state(ctx, 0); 7266 switch (opc) { 7267 case OPC_LWXC1: 7268 check_cop1x(ctx); 7269 { 7270 TCGv_i32 fp0 = tcg_temp_new_i32(); 7271 7272 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx); 7273 tcg_gen_trunc_tl_i32(fp0, t0); 7274 gen_store_fpr32(fp0, fd); 7275 tcg_temp_free_i32(fp0); 7276 } 7277 opn = "lwxc1"; 7278 break; 7279 case OPC_LDXC1: 7280 check_cop1x(ctx); 7281 check_cp1_registers(ctx, fd); 7282 { 7283 TCGv_i64 fp0 = tcg_temp_new_i64(); 7284 7285 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 7286 gen_store_fpr64(ctx, fp0, fd); 7287 tcg_temp_free_i64(fp0); 7288 } 7289 opn = "ldxc1"; 7290 break; 7291 case OPC_LUXC1: 7292 check_cp1_64bitmode(ctx); 7293 tcg_gen_andi_tl(t0, t0, ~0x7); 7294 { 7295 TCGv_i64 fp0 = tcg_temp_new_i64(); 7296 7297 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx); 7298 gen_store_fpr64(ctx, fp0, fd); 7299 tcg_temp_free_i64(fp0); 7300 } 7301 opn = "luxc1"; 7302 break; 7303 case OPC_SWXC1: 7304 check_cop1x(ctx); 7305 { 7306 TCGv_i32 fp0 = tcg_temp_new_i32(); 7307 TCGv t1 = tcg_temp_new(); 7308 7309 gen_load_fpr32(fp0, fs); 7310 tcg_gen_extu_i32_tl(t1, fp0); 7311 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); 7312 tcg_temp_free_i32(fp0); 7313 tcg_temp_free(t1); 7314 } 7315 opn = "swxc1"; 7316 store = 1; 7317 break; 7318 case OPC_SDXC1: 7319 check_cop1x(ctx); 7320 check_cp1_registers(ctx, fs); 7321 { 7322 TCGv_i64 fp0 = tcg_temp_new_i64(); 7323 7324 gen_load_fpr64(ctx, fp0, fs); 7325 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 7326 tcg_temp_free_i64(fp0); 7327 } 7328 opn = "sdxc1"; 7329 store = 1; 7330 break; 7331 case OPC_SUXC1: 7332 check_cp1_64bitmode(ctx); 7333 tcg_gen_andi_tl(t0, t0, ~0x7); 7334 { 7335 TCGv_i64 fp0 = tcg_temp_new_i64(); 7336 7337 gen_load_fpr64(ctx, fp0, fs); 7338 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx); 7339 tcg_temp_free_i64(fp0); 7340 } 7341 opn = "suxc1"; 7342 store = 1; 7343 break; 7344 } 7345 tcg_temp_free(t0); 7346 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd], 7347 regnames[index], regnames[base]); 7348} 7349 7350static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, 7351 int fd, int fr, int fs, int ft) 7352{ 7353 const char* __attribute__((unused)) opn = "flt3_arith"; 7354 7355 switch (opc) { 7356 case OPC_ALNV_PS: 7357 check_cp1_64bitmode(ctx); 7358 { 7359 TCGv t0 = tcg_temp_local_new(); 7360 TCGv_i32 fp = tcg_temp_new_i32(); 7361 TCGv_i32 fph = tcg_temp_new_i32(); 7362 int l1 = gen_new_label(); 7363 int l2 = gen_new_label(); 7364 7365 gen_load_gpr(t0, fr); 7366 tcg_gen_andi_tl(t0, t0, 0x7); 7367 7368 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 7369 gen_load_fpr32(fp, fs); 7370 gen_load_fpr32h(fph, fs); 7371 gen_store_fpr32(fp, fd); 7372 gen_store_fpr32h(fph, fd); 7373 tcg_gen_br(l2); 7374 gen_set_label(l1); 7375 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 7376 tcg_temp_free(t0); 7377#ifdef TARGET_WORDS_BIGENDIAN 7378 gen_load_fpr32(fp, fs); 7379 gen_load_fpr32h(fph, ft); 7380 gen_store_fpr32h(fp, fd); 7381 gen_store_fpr32(fph, fd); 7382#else 7383 gen_load_fpr32h(fph, fs); 7384 gen_load_fpr32(fp, ft); 7385 gen_store_fpr32(fph, fd); 7386 gen_store_fpr32h(fp, fd); 7387#endif 7388 gen_set_label(l2); 7389 tcg_temp_free_i32(fp); 7390 tcg_temp_free_i32(fph); 7391 } 7392 opn = "alnv.ps"; 7393 break; 7394 case OPC_MADD_S: 7395 check_cop1x(ctx); 7396 { 7397 TCGv_i32 fp0 = tcg_temp_new_i32(); 7398 TCGv_i32 fp1 = tcg_temp_new_i32(); 7399 TCGv_i32 fp2 = tcg_temp_new_i32(); 7400 7401 gen_load_fpr32(fp0, fs); 7402 gen_load_fpr32(fp1, ft); 7403 gen_load_fpr32(fp2, fr); 7404 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2); 7405 tcg_temp_free_i32(fp0); 7406 tcg_temp_free_i32(fp1); 7407 gen_store_fpr32(fp2, fd); 7408 tcg_temp_free_i32(fp2); 7409 } 7410 opn = "madd.s"; 7411 break; 7412 case OPC_MADD_D: 7413 check_cop1x(ctx); 7414 check_cp1_registers(ctx, fd | fs | ft | fr); 7415 { 7416 TCGv_i64 fp0 = tcg_temp_new_i64(); 7417 TCGv_i64 fp1 = tcg_temp_new_i64(); 7418 TCGv_i64 fp2 = tcg_temp_new_i64(); 7419 7420 gen_load_fpr64(ctx, fp0, fs); 7421 gen_load_fpr64(ctx, fp1, ft); 7422 gen_load_fpr64(ctx, fp2, fr); 7423 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2); 7424 tcg_temp_free_i64(fp0); 7425 tcg_temp_free_i64(fp1); 7426 gen_store_fpr64(ctx, fp2, fd); 7427 tcg_temp_free_i64(fp2); 7428 } 7429 opn = "madd.d"; 7430 break; 7431 case OPC_MADD_PS: 7432 check_cp1_64bitmode(ctx); 7433 { 7434 TCGv_i64 fp0 = tcg_temp_new_i64(); 7435 TCGv_i64 fp1 = tcg_temp_new_i64(); 7436 TCGv_i64 fp2 = tcg_temp_new_i64(); 7437 7438 gen_load_fpr64(ctx, fp0, fs); 7439 gen_load_fpr64(ctx, fp1, ft); 7440 gen_load_fpr64(ctx, fp2, fr); 7441 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2); 7442 tcg_temp_free_i64(fp0); 7443 tcg_temp_free_i64(fp1); 7444 gen_store_fpr64(ctx, fp2, fd); 7445 tcg_temp_free_i64(fp2); 7446 } 7447 opn = "madd.ps"; 7448 break; 7449 case OPC_MSUB_S: 7450 check_cop1x(ctx); 7451 { 7452 TCGv_i32 fp0 = tcg_temp_new_i32(); 7453 TCGv_i32 fp1 = tcg_temp_new_i32(); 7454 TCGv_i32 fp2 = tcg_temp_new_i32(); 7455 7456 gen_load_fpr32(fp0, fs); 7457 gen_load_fpr32(fp1, ft); 7458 gen_load_fpr32(fp2, fr); 7459 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2); 7460 tcg_temp_free_i32(fp0); 7461 tcg_temp_free_i32(fp1); 7462 gen_store_fpr32(fp2, fd); 7463 tcg_temp_free_i32(fp2); 7464 } 7465 opn = "msub.s"; 7466 break; 7467 case OPC_MSUB_D: 7468 check_cop1x(ctx); 7469 check_cp1_registers(ctx, fd | fs | ft | fr); 7470 { 7471 TCGv_i64 fp0 = tcg_temp_new_i64(); 7472 TCGv_i64 fp1 = tcg_temp_new_i64(); 7473 TCGv_i64 fp2 = tcg_temp_new_i64(); 7474 7475 gen_load_fpr64(ctx, fp0, fs); 7476 gen_load_fpr64(ctx, fp1, ft); 7477 gen_load_fpr64(ctx, fp2, fr); 7478 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2); 7479 tcg_temp_free_i64(fp0); 7480 tcg_temp_free_i64(fp1); 7481 gen_store_fpr64(ctx, fp2, fd); 7482 tcg_temp_free_i64(fp2); 7483 } 7484 opn = "msub.d"; 7485 break; 7486 case OPC_MSUB_PS: 7487 check_cp1_64bitmode(ctx); 7488 { 7489 TCGv_i64 fp0 = tcg_temp_new_i64(); 7490 TCGv_i64 fp1 = tcg_temp_new_i64(); 7491 TCGv_i64 fp2 = tcg_temp_new_i64(); 7492 7493 gen_load_fpr64(ctx, fp0, fs); 7494 gen_load_fpr64(ctx, fp1, ft); 7495 gen_load_fpr64(ctx, fp2, fr); 7496 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2); 7497 tcg_temp_free_i64(fp0); 7498 tcg_temp_free_i64(fp1); 7499 gen_store_fpr64(ctx, fp2, fd); 7500 tcg_temp_free_i64(fp2); 7501 } 7502 opn = "msub.ps"; 7503 break; 7504 case OPC_NMADD_S: 7505 check_cop1x(ctx); 7506 { 7507 TCGv_i32 fp0 = tcg_temp_new_i32(); 7508 TCGv_i32 fp1 = tcg_temp_new_i32(); 7509 TCGv_i32 fp2 = tcg_temp_new_i32(); 7510 7511 gen_load_fpr32(fp0, fs); 7512 gen_load_fpr32(fp1, ft); 7513 gen_load_fpr32(fp2, fr); 7514 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2); 7515 tcg_temp_free_i32(fp0); 7516 tcg_temp_free_i32(fp1); 7517 gen_store_fpr32(fp2, fd); 7518 tcg_temp_free_i32(fp2); 7519 } 7520 opn = "nmadd.s"; 7521 break; 7522 case OPC_NMADD_D: 7523 check_cop1x(ctx); 7524 check_cp1_registers(ctx, fd | fs | ft | fr); 7525 { 7526 TCGv_i64 fp0 = tcg_temp_new_i64(); 7527 TCGv_i64 fp1 = tcg_temp_new_i64(); 7528 TCGv_i64 fp2 = tcg_temp_new_i64(); 7529 7530 gen_load_fpr64(ctx, fp0, fs); 7531 gen_load_fpr64(ctx, fp1, ft); 7532 gen_load_fpr64(ctx, fp2, fr); 7533 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2); 7534 tcg_temp_free_i64(fp0); 7535 tcg_temp_free_i64(fp1); 7536 gen_store_fpr64(ctx, fp2, fd); 7537 tcg_temp_free_i64(fp2); 7538 } 7539 opn = "nmadd.d"; 7540 break; 7541 case OPC_NMADD_PS: 7542 check_cp1_64bitmode(ctx); 7543 { 7544 TCGv_i64 fp0 = tcg_temp_new_i64(); 7545 TCGv_i64 fp1 = tcg_temp_new_i64(); 7546 TCGv_i64 fp2 = tcg_temp_new_i64(); 7547 7548 gen_load_fpr64(ctx, fp0, fs); 7549 gen_load_fpr64(ctx, fp1, ft); 7550 gen_load_fpr64(ctx, fp2, fr); 7551 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2); 7552 tcg_temp_free_i64(fp0); 7553 tcg_temp_free_i64(fp1); 7554 gen_store_fpr64(ctx, fp2, fd); 7555 tcg_temp_free_i64(fp2); 7556 } 7557 opn = "nmadd.ps"; 7558 break; 7559 case OPC_NMSUB_S: 7560 check_cop1x(ctx); 7561 { 7562 TCGv_i32 fp0 = tcg_temp_new_i32(); 7563 TCGv_i32 fp1 = tcg_temp_new_i32(); 7564 TCGv_i32 fp2 = tcg_temp_new_i32(); 7565 7566 gen_load_fpr32(fp0, fs); 7567 gen_load_fpr32(fp1, ft); 7568 gen_load_fpr32(fp2, fr); 7569 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2); 7570 tcg_temp_free_i32(fp0); 7571 tcg_temp_free_i32(fp1); 7572 gen_store_fpr32(fp2, fd); 7573 tcg_temp_free_i32(fp2); 7574 } 7575 opn = "nmsub.s"; 7576 break; 7577 case OPC_NMSUB_D: 7578 check_cop1x(ctx); 7579 check_cp1_registers(ctx, fd | fs | ft | fr); 7580 { 7581 TCGv_i64 fp0 = tcg_temp_new_i64(); 7582 TCGv_i64 fp1 = tcg_temp_new_i64(); 7583 TCGv_i64 fp2 = tcg_temp_new_i64(); 7584 7585 gen_load_fpr64(ctx, fp0, fs); 7586 gen_load_fpr64(ctx, fp1, ft); 7587 gen_load_fpr64(ctx, fp2, fr); 7588 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2); 7589 tcg_temp_free_i64(fp0); 7590 tcg_temp_free_i64(fp1); 7591 gen_store_fpr64(ctx, fp2, fd); 7592 tcg_temp_free_i64(fp2); 7593 } 7594 opn = "nmsub.d"; 7595 break; 7596 case OPC_NMSUB_PS: 7597 check_cp1_64bitmode(ctx); 7598 { 7599 TCGv_i64 fp0 = tcg_temp_new_i64(); 7600 TCGv_i64 fp1 = tcg_temp_new_i64(); 7601 TCGv_i64 fp2 = tcg_temp_new_i64(); 7602 7603 gen_load_fpr64(ctx, fp0, fs); 7604 gen_load_fpr64(ctx, fp1, ft); 7605 gen_load_fpr64(ctx, fp2, fr); 7606 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2); 7607 tcg_temp_free_i64(fp0); 7608 tcg_temp_free_i64(fp1); 7609 gen_store_fpr64(ctx, fp2, fd); 7610 tcg_temp_free_i64(fp2); 7611 } 7612 opn = "nmsub.ps"; 7613 break; 7614 default: 7615 MIPS_INVAL(opn); 7616 generate_exception (ctx, EXCP_RI); 7617 return; 7618 } 7619 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr], 7620 fregnames[fs], fregnames[ft]); 7621} 7622 7623/* ISA extensions (ASEs) */ 7624/* MIPS16 extension to MIPS32 */ 7625/* SmartMIPS extension to MIPS32 */ 7626 7627#if defined(TARGET_MIPS64) 7628 7629/* MDMX extension to MIPS64 */ 7630 7631#endif 7632 7633static void decode_opc (CPUMIPSState *env, DisasContext *ctx) 7634{ 7635 int32_t offset; 7636 int rs, rt, rd, sa; 7637 uint32_t op, op1, op2; 7638 int16_t imm; 7639 7640 /* make sure instructions are on a word boundary */ 7641 if (ctx->pc & 0x3) { 7642 env->CP0_BadVAddr = ctx->pc; 7643 generate_exception(ctx, EXCP_AdEL); 7644 return; 7645 } 7646 7647 /* Handle blikely not taken case */ 7648 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { 7649 int l1 = gen_new_label(); 7650 7651 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4); 7652 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 7653 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 7654 gen_goto_tb(ctx, 1, ctx->pc + 4); 7655 gen_set_label(l1); 7656 } 7657 7658 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) 7659 tcg_gen_debug_insn_start(ctx->pc); 7660 7661 op = MASK_OP_MAJOR(ctx->opcode); 7662 rs = (ctx->opcode >> 21) & 0x1f; 7663 rt = (ctx->opcode >> 16) & 0x1f; 7664 rd = (ctx->opcode >> 11) & 0x1f; 7665 sa = (ctx->opcode >> 6) & 0x1f; 7666 imm = (int16_t)ctx->opcode; 7667 switch (op) { 7668 case OPC_SPECIAL: 7669 op1 = MASK_SPECIAL(ctx->opcode); 7670 switch (op1) { 7671 case OPC_SLL: /* Shift with immediate */ 7672 case OPC_SRA: 7673 case OPC_SRL: 7674 gen_shift_imm(env, ctx, op1, rd, rt, sa); 7675 break; 7676 case OPC_MOVN: /* Conditional move */ 7677 case OPC_MOVZ: 7678 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 7679 gen_cond_move(env, op1, rd, rs, rt); 7680 break; 7681 case OPC_ADD ... OPC_SUBU: 7682 gen_arith(env, ctx, op1, rd, rs, rt); 7683 break; 7684 case OPC_SLLV: /* Shifts */ 7685 case OPC_SRLV: 7686 case OPC_SRAV: 7687 gen_shift(env, ctx, op1, rd, rs, rt); 7688 break; 7689 case OPC_SLT: /* Set on less than */ 7690 case OPC_SLTU: 7691 gen_slt(env, op1, rd, rs, rt); 7692 break; 7693 case OPC_AND: /* Logic*/ 7694 case OPC_OR: 7695 case OPC_NOR: 7696 case OPC_XOR: 7697 gen_logic(env, op1, rd, rs, rt); 7698 break; 7699 case OPC_MULT ... OPC_DIVU: 7700 if (sa) { 7701 check_insn(env, ctx, INSN_VR54XX); 7702 op1 = MASK_MUL_VR54XX(ctx->opcode); 7703 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 7704 } else 7705 gen_muldiv(ctx, op1, rs, rt); 7706 break; 7707 case OPC_JR ... OPC_JALR: 7708 gen_compute_branch(ctx, op1, rs, rd, sa); 7709 return; 7710 case OPC_TGE ... OPC_TEQ: /* Traps */ 7711 case OPC_TNE: 7712 gen_trap(ctx, op1, rs, rt, -1); 7713 break; 7714 case OPC_MFHI: /* Move from HI/LO */ 7715 case OPC_MFLO: 7716 gen_HILO(ctx, op1, rd); 7717 break; 7718 case OPC_MTHI: 7719 case OPC_MTLO: /* Move to HI/LO */ 7720 gen_HILO(ctx, op1, rs); 7721 break; 7722 case OPC_PMON: /* Pmon entry point, also R4010 selsl */ 7723#ifdef MIPS_STRICT_STANDARD 7724 MIPS_INVAL("PMON / selsl"); 7725 generate_exception(ctx, EXCP_RI); 7726#else 7727 gen_helper_1i(pmon, cpu_env, sa); 7728#endif 7729 break; 7730 case OPC_SYSCALL: 7731 generate_exception(ctx, EXCP_SYSCALL); 7732 ctx->bstate = BS_STOP; 7733 break; 7734 case OPC_BREAK: 7735 generate_exception(ctx, EXCP_BREAK); 7736 break; 7737 case OPC_SPIM: 7738#ifdef MIPS_STRICT_STANDARD 7739 MIPS_INVAL("SPIM"); 7740 generate_exception(ctx, EXCP_RI); 7741#else 7742 /* Implemented as RI exception for now. */ 7743 MIPS_INVAL("spim (unofficial)"); 7744 generate_exception(ctx, EXCP_RI); 7745#endif 7746 break; 7747 case OPC_SYNC: 7748 /* Treat as NOP. */ 7749 break; 7750 7751 case OPC_MOVCI: 7752 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 7753 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 7754 check_cp1_enabled(ctx); 7755 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 7756 (ctx->opcode >> 16) & 1); 7757 } else { 7758 generate_exception_err(ctx, EXCP_CpU, 1); 7759 } 7760 break; 7761 7762#if defined(TARGET_MIPS64) 7763 /* MIPS64 specific opcodes */ 7764 case OPC_DSLL: 7765 case OPC_DSRA: 7766 case OPC_DSRL: 7767 case OPC_DSLL32: 7768 case OPC_DSRA32: 7769 case OPC_DSRL32: 7770 check_insn(env, ctx, ISA_MIPS3); 7771 check_mips_64(ctx); 7772 gen_shift_imm(env, ctx, op1, rd, rt, sa); 7773 break; 7774 case OPC_DADD ... OPC_DSUBU: 7775 check_insn(env, ctx, ISA_MIPS3); 7776 check_mips_64(ctx); 7777 gen_arith(env, ctx, op1, rd, rs, rt); 7778 break; 7779 case OPC_DSLLV: 7780 case OPC_DSRAV: 7781 case OPC_DSRLV: 7782 check_insn(env, ctx, ISA_MIPS3); 7783 check_mips_64(ctx); 7784 gen_shift(env, ctx, op1, rd, rs, rt); 7785 break; 7786 case OPC_DMULT ... OPC_DDIVU: 7787 check_insn(env, ctx, ISA_MIPS3); 7788 check_mips_64(ctx); 7789 gen_muldiv(ctx, op1, rs, rt); 7790 break; 7791#endif 7792 default: /* Invalid */ 7793 MIPS_INVAL("special"); 7794 generate_exception(ctx, EXCP_RI); 7795 break; 7796 } 7797 break; 7798 case OPC_SPECIAL2: 7799 op1 = MASK_SPECIAL2(ctx->opcode); 7800 switch (op1) { 7801 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ 7802 case OPC_MSUB ... OPC_MSUBU: 7803 check_insn(env, ctx, ISA_MIPS32); 7804 gen_muldiv(ctx, op1, rs, rt); 7805 break; 7806 case OPC_MUL: 7807 gen_arith(env, ctx, op1, rd, rs, rt); 7808 break; 7809 case OPC_CLO: 7810 case OPC_CLZ: 7811 check_insn(env, ctx, ISA_MIPS32); 7812 gen_cl(ctx, op1, rd, rs); 7813 break; 7814 case OPC_SDBBP: 7815 /* XXX: not clear which exception should be raised 7816 * when in debug mode... 7817 */ 7818 check_insn(env, ctx, ISA_MIPS32); 7819 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 7820 generate_exception(ctx, EXCP_DBp); 7821 } else { 7822 generate_exception(ctx, EXCP_DBp); 7823 } 7824 /* Treat as NOP. */ 7825 break; 7826#if defined(TARGET_MIPS64) 7827 case OPC_DCLO: 7828 case OPC_DCLZ: 7829 check_insn(env, ctx, ISA_MIPS64); 7830 check_mips_64(ctx); 7831 gen_cl(ctx, op1, rd, rs); 7832 break; 7833#endif 7834 default: /* Invalid */ 7835 MIPS_INVAL("special2"); 7836 generate_exception(ctx, EXCP_RI); 7837 break; 7838 } 7839 break; 7840 case OPC_SPECIAL3: 7841 op1 = MASK_SPECIAL3(ctx->opcode); 7842 switch (op1) { 7843 case OPC_EXT: 7844 case OPC_INS: 7845 check_insn(env, ctx, ISA_MIPS32R2); 7846 gen_bitops(ctx, op1, rt, rs, sa, rd); 7847 break; 7848 case OPC_BSHFL: 7849 check_insn(env, ctx, ISA_MIPS32R2); 7850 op2 = MASK_BSHFL(ctx->opcode); 7851 gen_bshfl(ctx, op2, rt, rd); 7852 break; 7853 case OPC_RDHWR: 7854 check_insn(env, ctx, ISA_MIPS32R2); 7855 { 7856 TCGv t0 = tcg_temp_new(); 7857 7858 switch (rd) { 7859 case 0: 7860 save_cpu_state(ctx, 1); 7861 gen_helper_rdhwr_cpunum(t0, cpu_env); 7862 gen_store_gpr(t0, rt); 7863 break; 7864 case 1: 7865 save_cpu_state(ctx, 1); 7866 gen_helper_rdhwr_synci_step(t0, cpu_env); 7867 gen_store_gpr(t0, rt); 7868 break; 7869 case 2: 7870 save_cpu_state(ctx, 1); 7871 gen_helper_rdhwr_cc(t0, cpu_env); 7872 gen_store_gpr(t0, rt); 7873 break; 7874 case 3: 7875 save_cpu_state(ctx, 1); 7876 gen_helper_rdhwr_ccres(t0, cpu_env); 7877 gen_store_gpr(t0, rt); 7878 break; 7879 case 29: 7880#if defined(CONFIG_USER_ONLY) 7881 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value)); 7882 gen_store_gpr(t0, rt); 7883 break; 7884#else 7885 /* XXX: Some CPUs implement this in hardware. 7886 Not supported yet. */ 7887#endif 7888 default: /* Invalid */ 7889 MIPS_INVAL("rdhwr"); 7890 generate_exception(ctx, EXCP_RI); 7891 break; 7892 } 7893 tcg_temp_free(t0); 7894 } 7895 break; 7896 case OPC_FORK: 7897 check_insn(env, ctx, ASE_MT); 7898 { 7899 TCGv t0 = tcg_temp_new(); 7900 TCGv t1 = tcg_temp_new(); 7901 7902 gen_load_gpr(t0, rt); 7903 gen_load_gpr(t1, rs); 7904 gen_helper_fork(t0, t1); 7905 tcg_temp_free(t0); 7906 tcg_temp_free(t1); 7907 } 7908 break; 7909 case OPC_YIELD: 7910 check_insn(env, ctx, ASE_MT); 7911 { 7912 TCGv t0 = tcg_temp_new(); 7913 7914 save_cpu_state(ctx, 1); 7915 gen_load_gpr(t0, rs); 7916 gen_helper_yield(t0, cpu_env, t0); 7917 gen_store_gpr(t0, rd); 7918 tcg_temp_free(t0); 7919 } 7920 break; 7921#if defined(TARGET_MIPS64) 7922 case OPC_DEXTM ... OPC_DEXT: 7923 case OPC_DINSM ... OPC_DINS: 7924 check_insn(env, ctx, ISA_MIPS64R2); 7925 check_mips_64(ctx); 7926 gen_bitops(ctx, op1, rt, rs, sa, rd); 7927 break; 7928 case OPC_DBSHFL: 7929 check_insn(env, ctx, ISA_MIPS64R2); 7930 check_mips_64(ctx); 7931 op2 = MASK_DBSHFL(ctx->opcode); 7932 gen_bshfl(ctx, op2, rt, rd); 7933 break; 7934#endif 7935 default: /* Invalid */ 7936 MIPS_INVAL("special3"); 7937 generate_exception(ctx, EXCP_RI); 7938 break; 7939 } 7940 break; 7941 case OPC_REGIMM: 7942 op1 = MASK_REGIMM(ctx->opcode); 7943 switch (op1) { 7944 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */ 7945 case OPC_BLTZAL ... OPC_BGEZALL: 7946 gen_compute_branch(ctx, op1, rs, -1, imm << 2); 7947 return; 7948 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ 7949 case OPC_TNEI: 7950 gen_trap(ctx, op1, rs, -1, imm); 7951 break; 7952 case OPC_SYNCI: 7953 check_insn(env, ctx, ISA_MIPS32R2); 7954 /* Treat as NOP. */ 7955 break; 7956 default: /* Invalid */ 7957 MIPS_INVAL("regimm"); 7958 generate_exception(ctx, EXCP_RI); 7959 break; 7960 } 7961 break; 7962 case OPC_CP0: 7963 check_cp0_enabled(ctx); 7964 op1 = MASK_CP0(ctx->opcode); 7965 switch (op1) { 7966 case OPC_MFC0: 7967 case OPC_MTC0: 7968 case OPC_MFTR: 7969 case OPC_MTTR: 7970#if defined(TARGET_MIPS64) 7971 case OPC_DMFC0: 7972 case OPC_DMTC0: 7973#endif 7974#ifndef CONFIG_USER_ONLY 7975 gen_cp0(env, ctx, op1, rt, rd); 7976#endif /* !CONFIG_USER_ONLY */ 7977 break; 7978 case OPC_C0_FIRST ... OPC_C0_LAST: 7979#ifndef CONFIG_USER_ONLY 7980 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 7981#endif /* !CONFIG_USER_ONLY */ 7982 break; 7983 case OPC_MFMC0: 7984#ifndef CONFIG_USER_ONLY 7985 { 7986 TCGv t0 = tcg_temp_new(); 7987 7988 op2 = MASK_MFMC0(ctx->opcode); 7989 switch (op2) { 7990 case OPC_DMT: 7991 check_insn(env, ctx, ASE_MT); 7992 gen_helper_dmt(t0); 7993 gen_store_gpr(t0, rt); 7994 break; 7995 case OPC_EMT: 7996 check_insn(env, ctx, ASE_MT); 7997 gen_helper_emt(t0); 7998 gen_store_gpr(t0, rt); 7999 break; 8000 case OPC_DVPE: 8001 check_insn(env, ctx, ASE_MT); 8002 gen_helper_dvpe(t0, cpu_env); 8003 gen_store_gpr(t0, rt); 8004 break; 8005 case OPC_EVPE: 8006 check_insn(env, ctx, ASE_MT); 8007 gen_helper_evpe(t0, cpu_env); 8008 gen_store_gpr(t0, rt); 8009 break; 8010 case OPC_DI: 8011 check_insn(env, ctx, ISA_MIPS32R2); 8012 save_cpu_state(ctx, 1); 8013 gen_helper_di(t0, cpu_env); 8014 gen_store_gpr(t0, rt); 8015 /* Stop translation as we may have switched the execution mode */ 8016 ctx->bstate = BS_STOP; 8017 break; 8018 case OPC_EI: 8019 check_insn(env, ctx, ISA_MIPS32R2); 8020 save_cpu_state(ctx, 1); 8021 gen_helper_ei(t0, cpu_env); 8022 gen_store_gpr(t0, rt); 8023 /* Stop translation as we may have switched the execution mode */ 8024 ctx->bstate = BS_STOP; 8025 break; 8026 default: /* Invalid */ 8027 MIPS_INVAL("mfmc0"); 8028 generate_exception(ctx, EXCP_RI); 8029 break; 8030 } 8031 tcg_temp_free(t0); 8032 } 8033#endif /* !CONFIG_USER_ONLY */ 8034 break; 8035 case OPC_RDPGPR: 8036 check_insn(env, ctx, ISA_MIPS32R2); 8037 gen_load_srsgpr(rt, rd); 8038 break; 8039 case OPC_WRPGPR: 8040 check_insn(env, ctx, ISA_MIPS32R2); 8041 gen_store_srsgpr(rt, rd); 8042 break; 8043 default: 8044 MIPS_INVAL("cp0"); 8045 generate_exception(ctx, EXCP_RI); 8046 break; 8047 } 8048 break; 8049 case OPC_ADDI: /* Arithmetic with immediate opcode */ 8050 case OPC_ADDIU: 8051 gen_arith_imm(env, ctx, op, rt, rs, imm); 8052 break; 8053 case OPC_SLTI: /* Set on less than with immediate opcode */ 8054 case OPC_SLTIU: 8055 gen_slt_imm(env, op, rt, rs, imm); 8056 break; 8057 case OPC_ANDI: /* Arithmetic with immediate opcode */ 8058 case OPC_LUI: 8059 case OPC_ORI: 8060 case OPC_XORI: 8061 gen_logic_imm(env, op, rt, rs, imm); 8062 break; 8063 case OPC_J ... OPC_JAL: /* Jump */ 8064 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 8065 gen_compute_branch(ctx, op, rs, rt, offset); 8066 return; 8067 case OPC_BEQ ... OPC_BGTZ: /* Branch */ 8068 case OPC_BEQL ... OPC_BGTZL: 8069 gen_compute_branch(ctx, op, rs, rt, imm << 2); 8070 return; 8071 case OPC_LB ... OPC_LWR: /* Load and stores */ 8072 case OPC_SB ... OPC_SW: 8073 case OPC_SWR: 8074 case OPC_LL: 8075 gen_ldst(ctx, op, rt, rs, imm); 8076 break; 8077 case OPC_SC: 8078 gen_st_cond(ctx, op, rt, rs, imm); 8079 break; 8080 case OPC_CACHE: 8081 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); 8082 /* Treat as NOP. */ 8083 break; 8084 case OPC_PREF: 8085 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); 8086 /* Treat as NOP. */ 8087 break; 8088 8089 /* Floating point (COP1). */ 8090 case OPC_LWC1: 8091 case OPC_LDC1: 8092 case OPC_SWC1: 8093 case OPC_SDC1: 8094 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8095 check_cp1_enabled(ctx); 8096 gen_flt_ldst(ctx, op, rt, rs, imm); 8097 } else { 8098 generate_exception_err(ctx, EXCP_CpU, 1); 8099 } 8100 break; 8101 8102 case OPC_CP1: 8103 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8104 check_cp1_enabled(ctx); 8105 op1 = MASK_CP1(ctx->opcode); 8106 switch (op1) { 8107 case OPC_MFHC1: 8108 case OPC_MTHC1: 8109 check_insn(env, ctx, ISA_MIPS32R2); 8110 case OPC_MFC1: 8111 case OPC_CFC1: 8112 case OPC_MTC1: 8113 case OPC_CTC1: 8114 gen_cp1(ctx, op1, rt, rd); 8115 break; 8116#if defined(TARGET_MIPS64) 8117 case OPC_DMFC1: 8118 case OPC_DMTC1: 8119 check_insn(env, ctx, ISA_MIPS3); 8120 gen_cp1(ctx, op1, rt, rd); 8121 break; 8122#endif 8123 case OPC_BC1ANY2: 8124 case OPC_BC1ANY4: 8125 check_cop1x(ctx); 8126 check_insn(env, ctx, ASE_MIPS3D); 8127 /* fall through */ 8128 case OPC_BC1: 8129 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode), 8130 (rt >> 2) & 0x7, imm << 2); 8131 return; 8132 case OPC_S_FMT: 8133 case OPC_D_FMT: 8134 case OPC_W_FMT: 8135 case OPC_L_FMT: 8136 case OPC_PS_FMT: 8137 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa, 8138 (imm >> 8) & 0x7); 8139 break; 8140 default: 8141 MIPS_INVAL("cp1"); 8142 generate_exception (ctx, EXCP_RI); 8143 break; 8144 } 8145 } else { 8146 generate_exception_err(ctx, EXCP_CpU, 1); 8147 } 8148 break; 8149 8150 /* COP2. */ 8151 case OPC_LWC2: 8152 case OPC_LDC2: 8153 case OPC_SWC2: 8154 case OPC_SDC2: 8155 case OPC_CP2: 8156 /* COP2: Not implemented. */ 8157 generate_exception_err(ctx, EXCP_CpU, 2); 8158 break; 8159 8160 case OPC_CP3: 8161 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8162 check_cp1_enabled(ctx); 8163 op1 = MASK_CP3(ctx->opcode); 8164 switch (op1) { 8165 case OPC_LWXC1: 8166 case OPC_LDXC1: 8167 case OPC_LUXC1: 8168 case OPC_SWXC1: 8169 case OPC_SDXC1: 8170 case OPC_SUXC1: 8171 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 8172 break; 8173 case OPC_PREFX: 8174 /* Treat as NOP. */ 8175 break; 8176 case OPC_ALNV_PS: 8177 case OPC_MADD_S: 8178 case OPC_MADD_D: 8179 case OPC_MADD_PS: 8180 case OPC_MSUB_S: 8181 case OPC_MSUB_D: 8182 case OPC_MSUB_PS: 8183 case OPC_NMADD_S: 8184 case OPC_NMADD_D: 8185 case OPC_NMADD_PS: 8186 case OPC_NMSUB_S: 8187 case OPC_NMSUB_D: 8188 case OPC_NMSUB_PS: 8189 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 8190 break; 8191 default: 8192 MIPS_INVAL("cp3"); 8193 generate_exception (ctx, EXCP_RI); 8194 break; 8195 } 8196 } else { 8197 generate_exception_err(ctx, EXCP_CpU, 1); 8198 } 8199 break; 8200 8201#if defined(TARGET_MIPS64) 8202 /* MIPS64 opcodes */ 8203 case OPC_LWU: 8204 case OPC_LDL ... OPC_LDR: 8205 case OPC_SDL ... OPC_SDR: 8206 case OPC_LLD: 8207 case OPC_LD: 8208 case OPC_SD: 8209 check_insn(env, ctx, ISA_MIPS3); 8210 check_mips_64(ctx); 8211 gen_ldst(ctx, op, rt, rs, imm); 8212 break; 8213 case OPC_SCD: 8214 check_insn(env, ctx, ISA_MIPS3); 8215 check_mips_64(ctx); 8216 gen_st_cond(ctx, op, rt, rs, imm); 8217 break; 8218 case OPC_DADDI: 8219 case OPC_DADDIU: 8220 check_insn(env, ctx, ISA_MIPS3); 8221 check_mips_64(ctx); 8222 gen_arith_imm(env, ctx, op, rt, rs, imm); 8223 break; 8224#endif 8225 case OPC_JALX: 8226 check_insn(env, ctx, ASE_MIPS16); 8227 /* MIPS16: Not implemented. */ 8228 case OPC_MDMX: 8229 check_insn(env, ctx, ASE_MDMX); 8230 /* MDMX: Not implemented. */ 8231 default: /* Invalid */ 8232 MIPS_INVAL("major opcode"); 8233 generate_exception(ctx, EXCP_RI); 8234 break; 8235 } 8236 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8237 int hflags = ctx->hflags & MIPS_HFLAG_BMASK; 8238 /* Branches completion */ 8239 ctx->hflags &= ~MIPS_HFLAG_BMASK; 8240 ctx->bstate = BS_BRANCH; 8241 save_cpu_state(ctx, 0); 8242 /* FIXME: Need to clear can_do_io. */ 8243 switch (hflags) { 8244 case MIPS_HFLAG_B: 8245 /* unconditional branch */ 8246 MIPS_DEBUG("unconditional branch"); 8247 gen_goto_tb(ctx, 0, ctx->btarget); 8248 break; 8249 case MIPS_HFLAG_BL: 8250 /* blikely taken case */ 8251 MIPS_DEBUG("blikely branch taken"); 8252 gen_goto_tb(ctx, 0, ctx->btarget); 8253 break; 8254 case MIPS_HFLAG_BC: 8255 /* Conditional branch */ 8256 MIPS_DEBUG("conditional branch"); 8257 { 8258 int l1 = gen_new_label(); 8259 8260 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 8261 gen_goto_tb(ctx, 1, ctx->pc + 4); 8262 gen_set_label(l1); 8263 gen_goto_tb(ctx, 0, ctx->btarget); 8264 } 8265 break; 8266 case MIPS_HFLAG_BR: 8267 /* unconditional branch to register */ 8268 MIPS_DEBUG("branch to register"); 8269 tcg_gen_mov_tl(cpu_PC, btarget); 8270 if (ctx->singlestep_enabled) { 8271 save_cpu_state(ctx, 0); 8272 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8273 } 8274 tcg_gen_exit_tb(0); 8275 break; 8276 default: 8277 MIPS_DEBUG("unknown branch"); 8278 break; 8279 } 8280 } 8281} 8282 8283static inline void 8284gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb, 8285 int search_pc) 8286{ 8287 DisasContext ctx; 8288 target_ulong pc_start; 8289 uint16_t *gen_opc_end; 8290 CPUBreakpoint *bp; 8291 int j, lj = -1; 8292 int num_insns; 8293 int max_insns; 8294 8295 if (search_pc) 8296 qemu_log("search pc %d\n", search_pc); 8297 8298 pc_start = tb->pc; 8299 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; 8300 ctx.pc = pc_start; 8301 ctx.saved_pc = -1; 8302 ctx.singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled; 8303 ctx.tb = tb; 8304 ctx.bstate = BS_NONE; 8305 /* Restore delay slot state from the tb context. */ 8306 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */ 8307 restore_cpu_state(env, &ctx); 8308#ifdef CONFIG_USER_ONLY 8309 ctx.mem_idx = MIPS_HFLAG_UM; 8310#else 8311 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; 8312#endif 8313 num_insns = 0; 8314 max_insns = tb->cflags & CF_COUNT_MASK; 8315 if (max_insns == 0) 8316 max_insns = CF_COUNT_MASK; 8317#ifdef DEBUG_DISAS 8318 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n"); 8319 /* FIXME: This may print out stale hflags from env... */ 8320 log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0); 8321#endif 8322 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); 8323 gen_icount_start(); 8324 while (ctx.bstate == BS_NONE) { 8325 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { 8326 QTAILQ_FOREACH(bp, &env->breakpoints, entry) { 8327 if (bp->pc == ctx.pc) { 8328 save_cpu_state(&ctx, 1); 8329 ctx.bstate = BS_BRANCH; 8330 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8331 /* Include the breakpoint location or the tb won't 8332 * be flushed when it must be. */ 8333 ctx.pc += 4; 8334 goto done_generating; 8335 } 8336 } 8337 } 8338 8339 if (search_pc) { 8340 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 8341 if (lj < j) { 8342 lj++; 8343 while (lj < j) 8344 tcg_ctx.gen_opc_instr_start[lj++] = 0; 8345 } 8346 tcg_ctx.gen_opc_pc[lj] = ctx.pc; 8347 tcg_ctx.gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK; 8348 tcg_ctx.gen_opc_instr_start[lj] = 1; 8349 tcg_ctx.gen_opc_icount[lj] = num_insns; 8350 } 8351 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) 8352 gen_io_start(); 8353 ctx.opcode = cpu_ldl_code(env, ctx.pc); 8354 decode_opc(env, &ctx); 8355 ctx.pc += 4; 8356 num_insns++; 8357 8358 /* Execute a branch and its delay slot as a single instruction. 8359 This is what GDB expects and is consistent with what the 8360 hardware does (e.g. if a delay slot instruction faults, the 8361 reported PC is the PC of the branch). */ 8362 if (ENV_GET_CPU(env)->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) 8363 break; 8364 8365 /* Do not split a branch instruction and its delay slot into two 8366 TB's when a page boundary is crossed. This causes TB's to be 8367 invalidated incorrectly if branch target is patched. */ 8368 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) 8369 break; 8370 8371 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) 8372 break; 8373 8374 if (num_insns >= max_insns) 8375 break; 8376 8377 if (singlestep) 8378 break; 8379 } 8380 if (tb->cflags & CF_LAST_IO) 8381 gen_io_end(); 8382 if (ENV_GET_CPU(env)->singlestep_enabled && ctx.bstate != BS_BRANCH) { 8383 save_cpu_state(&ctx, ctx.bstate == BS_NONE); 8384 gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG); 8385 } else { 8386 switch (ctx.bstate) { 8387 case BS_STOP: 8388 gen_helper_interrupt_restart(cpu_env); 8389 gen_goto_tb(&ctx, 0, ctx.pc); 8390 break; 8391 case BS_NONE: 8392 save_cpu_state(&ctx, 0); 8393 gen_goto_tb(&ctx, 0, ctx.pc); 8394 break; 8395 case BS_EXCP: 8396 gen_helper_interrupt_restart(cpu_env); 8397 tcg_gen_exit_tb(0); 8398 break; 8399 case BS_BRANCH: 8400 default: 8401 break; 8402 } 8403 } 8404done_generating: 8405 gen_icount_end(tb, num_insns); 8406 *tcg_ctx.gen_opc_ptr = INDEX_op_end; 8407 if (search_pc) { 8408 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; 8409 lj++; 8410 while (lj <= j) 8411 tcg_ctx.gen_opc_instr_start[lj++] = 0; 8412 } else { 8413 tb->size = ctx.pc - pc_start; 8414 tb->icount = num_insns; 8415 } 8416#ifdef DEBUG_DISAS 8417 LOG_DISAS("\n"); 8418 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { 8419 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 8420 log_target_disas(env, pc_start, ctx.pc - pc_start, 0); 8421 qemu_log("\n"); 8422 } 8423 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags); 8424#endif 8425} 8426 8427void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb) 8428{ 8429 gen_intermediate_code_internal(env, tb, 0); 8430} 8431 8432void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb) 8433{ 8434 gen_intermediate_code_internal(env, tb, 1); 8435} 8436 8437static void fpu_dump_state(CPUMIPSState *env, FILE *f, 8438 int (*fpu_fprintf)(FILE *f, const char *fmt, ...), 8439 int flags) 8440{ 8441 int i; 8442 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64); 8443 8444#define printfpr(fp) \ 8445 do { \ 8446 if (is_fpu64) \ 8447 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \ 8448 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \ 8449 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \ 8450 else { \ 8451 fpr_t tmp; \ 8452 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ 8453 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ 8454 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \ 8455 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \ 8456 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \ 8457 } \ 8458 } while(0) 8459 8460 8461 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n", 8462 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status, 8463 get_float_exception_flags(&env->active_fpu.fp_status)); 8464 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { 8465 fpu_fprintf(f, "%3s: ", fregnames[i]); 8466 printfpr(&env->active_fpu.fpr[i]); 8467 } 8468 8469#undef printfpr 8470} 8471 8472#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) 8473/* Debug help: The architecture requires 32bit code to maintain proper 8474 sign-extended values on 64bit machines. */ 8475 8476#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff)) 8477 8478static void 8479cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f, 8480 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 8481 int flags) 8482{ 8483 int i; 8484 8485 if (!SIGN_EXT_P(env->active_tc.PC)) 8486 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC); 8487 if (!SIGN_EXT_P(env->active_tc.HI[0])) 8488 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]); 8489 if (!SIGN_EXT_P(env->active_tc.LO[0])) 8490 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]); 8491 if (!SIGN_EXT_P(env->btarget)) 8492 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget); 8493 8494 for (i = 0; i < 32; i++) { 8495 if (!SIGN_EXT_P(env->active_tc.gpr[i])) 8496 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]); 8497 } 8498 8499 if (!SIGN_EXT_P(env->CP0_EPC)) 8500 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC); 8501 if (!SIGN_EXT_P(env->lladdr)) 8502 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr); 8503} 8504#endif 8505 8506void cpu_dump_state (CPUMIPSState *env, FILE *f, 8507 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 8508 int flags) 8509{ 8510 int i; 8511 8512 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", 8513 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0], 8514 env->hflags, env->btarget, env->bcond); 8515 for (i = 0; i < 32; i++) { 8516 if ((i & 3) == 0) 8517 cpu_fprintf(f, "GPR%02d:", i); 8518 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]); 8519 if ((i & 3) == 3) 8520 cpu_fprintf(f, "\n"); 8521 } 8522 8523 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", 8524 env->CP0_Status, env->CP0_Cause, env->CP0_EPC); 8525 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", 8526 env->CP0_Config0, env->CP0_Config1, env->lladdr); 8527 if (env->hflags & MIPS_HFLAG_FPU) 8528 fpu_dump_state(env, f, cpu_fprintf, flags); 8529#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) 8530 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); 8531#endif 8532} 8533 8534static void mips_tcg_init(void) 8535{ 8536 int i; 8537 static int inited; 8538 8539 /* Initialize various static tables. */ 8540 if (inited) 8541 return; 8542 8543 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 8544 TCGV_UNUSED(cpu_gpr[0]); 8545 for (i = 1; i < 32; i++) 8546 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, 8547 offsetof(CPUMIPSState, active_tc.gpr[i]), 8548 regnames[i]); 8549 cpu_PC = tcg_global_mem_new(TCG_AREG0, 8550 offsetof(CPUMIPSState, active_tc.PC), "PC"); 8551 for (i = 0; i < MIPS_DSP_ACC; i++) { 8552 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0, 8553 offsetof(CPUMIPSState, active_tc.HI[i]), 8554 regnames_HI[i]); 8555 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0, 8556 offsetof(CPUMIPSState, active_tc.LO[i]), 8557 regnames_LO[i]); 8558 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0, 8559 offsetof(CPUMIPSState, active_tc.ACX[i]), 8560 regnames_ACX[i]); 8561 } 8562 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0, 8563 offsetof(CPUMIPSState, active_tc.DSPControl), 8564 "DSPControl"); 8565 bcond = tcg_global_mem_new(TCG_AREG0, 8566 offsetof(CPUMIPSState, bcond), "bcond"); 8567 btarget = tcg_global_mem_new(TCG_AREG0, 8568 offsetof(CPUMIPSState, btarget), "btarget"); 8569 hflags = tcg_global_mem_new_i32(TCG_AREG0, 8570 offsetof(CPUMIPSState, hflags), "hflags"); 8571 8572 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0, 8573 offsetof(CPUMIPSState, active_fpu.fcr0), 8574 "fcr0"); 8575 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0, 8576 offsetof(CPUMIPSState, active_fpu.fcr31), 8577 "fcr31"); 8578 inited = 1; 8579} 8580 8581#include "translate_init.c" 8582 8583CPUMIPSState *cpu_mips_init (const char *cpu_model) 8584{ 8585 MIPSCPU *mips_cpu; 8586 CPUMIPSState *env; 8587 CPUState *cpu; 8588 const mips_def_t *def; 8589 8590 def = cpu_mips_find_by_name(cpu_model); 8591 if (!def) 8592 return NULL; 8593 mips_cpu = g_malloc0(sizeof(MIPSCPU)); 8594 env = &mips_cpu->env; 8595 ENV_GET_CPU(env)->env_ptr = env; 8596 8597 cpu = ENV_GET_CPU(env); 8598 env->cpu_model = def; 8599 cpu->cpu_model_str = cpu_model; 8600 8601 cpu_exec_init(env); 8602#ifndef CONFIG_USER_ONLY 8603 mmu_init(env, def); 8604#endif 8605 mvp_init(env, def); 8606 mips_tcg_init(); 8607 cpu_reset(env); 8608 qemu_init_vcpu(env); 8609 return env; 8610} 8611 8612void cpu_reset (CPUMIPSState *env) 8613{ 8614 if (qemu_loglevel_mask(CPU_LOG_RESET)) { 8615 qemu_log("CPU Reset (CPU %d)\n", ENV_GET_CPU(env)->cpu_index); 8616 log_cpu_state(env, 0); 8617 } 8618 8619 memset(env, 0, offsetof(CPUMIPSState, breakpoints)); 8620 tlb_flush(env, 1); 8621 8622 /* Reset registers to their default values */ 8623 env->CP0_PRid = env->cpu_model->CP0_PRid; 8624 env->CP0_Config0 = env->cpu_model->CP0_Config0; 8625#ifdef TARGET_WORDS_BIGENDIAN 8626 env->CP0_Config0 |= (1 << CP0C0_BE); 8627#endif 8628 env->CP0_Config1 = env->cpu_model->CP0_Config1; 8629 env->CP0_Config2 = env->cpu_model->CP0_Config2; 8630 env->CP0_Config3 = env->cpu_model->CP0_Config3; 8631 env->CP0_Config6 = env->cpu_model->CP0_Config6; 8632 env->CP0_Config7 = env->cpu_model->CP0_Config7; 8633 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask 8634 << env->cpu_model->CP0_LLAddr_shift; 8635 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift; 8636 env->SYNCI_Step = env->cpu_model->SYNCI_Step; 8637 env->CCRes = env->cpu_model->CCRes; 8638 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask; 8639 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask; 8640 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl; 8641 env->current_tc = 0; 8642 env->SEGBITS = env->cpu_model->SEGBITS; 8643 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1); 8644#if defined(TARGET_MIPS64) 8645 if (env->cpu_model->insn_flags & ISA_MIPS3) { 8646 env->SEGMask |= 3ULL << 62; 8647 } 8648#endif 8649 env->PABITS = env->cpu_model->PABITS; 8650 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1); 8651 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; 8652 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; 8653 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask; 8654 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1; 8655 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask; 8656 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2; 8657 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask; 8658 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3; 8659 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask; 8660 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4; 8661 env->insn_flags = env->cpu_model->insn_flags; 8662 8663 fpu_init(env, env->cpu_model); 8664 8665#if defined(CONFIG_USER_ONLY) 8666 env->hflags = MIPS_HFLAG_UM; 8667 /* Enable access to the SYNCI_Step register. */ 8668 env->CP0_HWREna |= (1 << 1); 8669 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 8670 env->hflags |= MIPS_HFLAG_FPU; 8671 } 8672#ifdef TARGET_MIPS64 8673 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { 8674 env->hflags |= MIPS_HFLAG_F64; 8675 } 8676#endif 8677#else 8678 if (env->hflags & MIPS_HFLAG_BMASK) { 8679 /* If the exception was raised from a delay slot, 8680 come back to the jump. */ 8681 env->CP0_ErrorEPC = env->active_tc.PC - 4; 8682 } else { 8683 env->CP0_ErrorEPC = env->active_tc.PC; 8684 } 8685 env->active_tc.PC = (int32_t)0xBFC00000; 8686 env->CP0_Random = env->tlb->nb_tlb - 1; 8687 env->CP0_Wired = 0; 8688 /* SMP not implemented */ 8689 env->CP0_EBase = 0x80000000; 8690 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); 8691 /* vectored interrupts not implemented, timer on int 7, 8692 no performance counters. */ 8693 env->CP0_IntCtl = 0xe0000000; 8694 { 8695 int i; 8696 8697 for (i = 0; i < 7; i++) { 8698 env->CP0_WatchLo[i] = 0; 8699 env->CP0_WatchHi[i] = 0x80000000; 8700 } 8701 env->CP0_WatchLo[7] = 0; 8702 env->CP0_WatchHi[7] = 0; 8703 } 8704 /* Count register increments in debug mode, EJTAG version 1 */ 8705 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); 8706 env->hflags = MIPS_HFLAG_CP0; 8707#endif 8708#if defined(TARGET_MIPS64) 8709 if (env->cpu_model->insn_flags & ISA_MIPS3) { 8710 env->hflags |= MIPS_HFLAG_64; 8711 } 8712#endif 8713 env->exception_index = EXCP_NONE; 8714} 8715 8716void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos) 8717{ 8718 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos]; 8719 env->hflags &= ~MIPS_HFLAG_BMASK; 8720 env->hflags |= tcg_ctx.gen_opc_hflags[pc_pos]; 8721} 8722