1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_MIPS_CONSTANTS_H_ 6 #define V8_MIPS_CONSTANTS_H_ 7 8 #include "src/base/logging.h" 9 #include "src/base/macros.h" 10 #include "src/globals.h" 11 12 // UNIMPLEMENTED_ macro for MIPS. 13 #ifdef DEBUG 14 #define UNIMPLEMENTED_MIPS() \ 15 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ 16 __FILE__, __LINE__, __func__) 17 #else 18 #define UNIMPLEMENTED_MIPS() 19 #endif 20 21 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") 22 23 enum ArchVariants { 24 kMips64r2, 25 kMips64r6 26 }; 27 28 29 #ifdef _MIPS_ARCH_MIPS64R2 30 static const ArchVariants kArchVariant = kMips64r2; 31 #elif _MIPS_ARCH_MIPS64R6 32 static const ArchVariants kArchVariant = kMips64r6; 33 #else 34 static const ArchVariants kArchVariant = kMips64r2; 35 #endif 36 37 38 enum Endianness { kLittle, kBig }; 39 40 #if defined(V8_TARGET_LITTLE_ENDIAN) 41 static const Endianness kArchEndian = kLittle; 42 #elif defined(V8_TARGET_BIG_ENDIAN) 43 static const Endianness kArchEndian = kBig; 44 #else 45 #error Unknown endianness 46 #endif 47 48 49 // TODO(plind): consider renaming these ... 50 #if(defined(__mips_hard_float) && __mips_hard_float != 0) 51 // Use floating-point coprocessor instructions. This flag is raised when 52 // -mhard-float is passed to the compiler. 53 const bool IsMipsSoftFloatABI = false; 54 #elif(defined(__mips_soft_float) && __mips_soft_float != 0) 55 // This flag is raised when -msoft-float is passed to the compiler. 56 // Although FPU is a base requirement for v8, soft-float ABI is used 57 // on soft-float systems with FPU kernel emulation. 58 const bool IsMipsSoftFloatABI = true; 59 #else 60 const bool IsMipsSoftFloatABI = true; 61 #endif 62 63 #if defined(V8_TARGET_LITTLE_ENDIAN) 64 const uint32_t kMipsLwrOffset = 0; 65 const uint32_t kMipsLwlOffset = 3; 66 const uint32_t kMipsSwrOffset = 0; 67 const uint32_t kMipsSwlOffset = 3; 68 const uint32_t kMipsLdrOffset = 0; 69 const uint32_t kMipsLdlOffset = 7; 70 const uint32_t kMipsSdrOffset = 0; 71 const uint32_t kMipsSdlOffset = 7; 72 #elif defined(V8_TARGET_BIG_ENDIAN) 73 const uint32_t kMipsLwrOffset = 3; 74 const uint32_t kMipsLwlOffset = 0; 75 const uint32_t kMipsSwrOffset = 3; 76 const uint32_t kMipsSwlOffset = 0; 77 const uint32_t kMipsLdrOffset = 7; 78 const uint32_t kMipsLdlOffset = 0; 79 const uint32_t kMipsSdrOffset = 7; 80 const uint32_t kMipsSdlOffset = 0; 81 #else 82 #error Unknown endianness 83 #endif 84 85 #ifndef __STDC_FORMAT_MACROS 86 #define __STDC_FORMAT_MACROS 87 #endif 88 #include <inttypes.h> 89 90 91 // Defines constants and accessor classes to assemble, disassemble and 92 // simulate MIPS32 instructions. 93 // 94 // See: MIPS32 Architecture For Programmers 95 // Volume II: The MIPS32 Instruction Set 96 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 97 98 namespace v8 { 99 namespace internal { 100 101 // ----------------------------------------------------------------------------- 102 // Registers and FPURegisters. 103 104 // Number of general purpose registers. 105 const int kNumRegisters = 32; 106 const int kInvalidRegister = -1; 107 108 // Number of registers with HI, LO, and pc. 109 const int kNumSimuRegisters = 35; 110 111 // In the simulator, the PC register is simulated as the 34th register. 112 const int kPCRegister = 34; 113 114 // Number coprocessor registers. 115 const int kNumFPURegisters = 32; 116 const int kInvalidFPURegister = -1; 117 118 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 119 const int kFCSRRegister = 31; 120 const int kInvalidFPUControlRegister = -1; 121 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1 << 31) - 1; 122 const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1 << 31); 123 const uint64_t kFPU64InvalidResult = 124 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1; 125 const int64_t kFPU64InvalidResultNegative = 126 static_cast<int64_t>(static_cast<uint64_t>(1) << 63); 127 128 // FCSR constants. 129 const uint32_t kFCSRInexactFlagBit = 2; 130 const uint32_t kFCSRUnderflowFlagBit = 3; 131 const uint32_t kFCSROverflowFlagBit = 4; 132 const uint32_t kFCSRDivideByZeroFlagBit = 5; 133 const uint32_t kFCSRInvalidOpFlagBit = 6; 134 const uint32_t kFCSRNaN2008FlagBit = 18; 135 136 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit; 137 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit; 138 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit; 139 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit; 140 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit; 141 const uint32_t kFCSRNaN2008FlagMask = 1 << kFCSRNaN2008FlagBit; 142 143 const uint32_t kFCSRFlagMask = 144 kFCSRInexactFlagMask | 145 kFCSRUnderflowFlagMask | 146 kFCSROverflowFlagMask | 147 kFCSRDivideByZeroFlagMask | 148 kFCSRInvalidOpFlagMask; 149 150 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; 151 152 // 'pref' instruction hints 153 const int32_t kPrefHintLoad = 0; 154 const int32_t kPrefHintStore = 1; 155 const int32_t kPrefHintLoadStreamed = 4; 156 const int32_t kPrefHintStoreStreamed = 5; 157 const int32_t kPrefHintLoadRetained = 6; 158 const int32_t kPrefHintStoreRetained = 7; 159 const int32_t kPrefHintWritebackInvalidate = 25; 160 const int32_t kPrefHintPrepareForStore = 30; 161 162 // Helper functions for converting between register numbers and names. 163 class Registers { 164 public: 165 // Return the name of the register. 166 static const char* Name(int reg); 167 168 // Lookup the register number for the name provided. 169 static int Number(const char* name); 170 171 struct RegisterAlias { 172 int reg; 173 const char* name; 174 }; 175 176 static const int64_t kMaxValue = 0x7fffffffffffffffl; 177 static const int64_t kMinValue = 0x8000000000000000l; 178 179 private: 180 static const char* names_[kNumSimuRegisters]; 181 static const RegisterAlias aliases_[]; 182 }; 183 184 // Helper functions for converting between register numbers and names. 185 class FPURegisters { 186 public: 187 // Return the name of the register. 188 static const char* Name(int reg); 189 190 // Lookup the register number for the name provided. 191 static int Number(const char* name); 192 193 struct RegisterAlias { 194 int creg; 195 const char* name; 196 }; 197 198 private: 199 static const char* names_[kNumFPURegisters]; 200 static const RegisterAlias aliases_[]; 201 }; 202 203 204 // ----------------------------------------------------------------------------- 205 // Instructions encoding constants. 206 207 // On MIPS all instructions are 32 bits. 208 typedef int32_t Instr; 209 210 // Special Software Interrupt codes when used in the presence of the MIPS 211 // simulator. 212 enum SoftwareInterruptCodes { 213 // Transition to C code. 214 call_rt_redirected = 0xfffff 215 }; 216 217 // On MIPS Simulator breakpoints can have different codes: 218 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints, 219 // the simulator will run through them and print the registers. 220 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop() 221 // instructions (see Assembler::stop()). 222 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the 223 // debugger. 224 const uint32_t kMaxWatchpointCode = 31; 225 const uint32_t kMaxStopCode = 127; 226 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode); 227 228 229 // ----- Fields offset and length. 230 const int kOpcodeShift = 26; 231 const int kOpcodeBits = 6; 232 const int kRsShift = 21; 233 const int kRsBits = 5; 234 const int kRtShift = 16; 235 const int kRtBits = 5; 236 const int kRdShift = 11; 237 const int kRdBits = 5; 238 const int kSaShift = 6; 239 const int kSaBits = 5; 240 const int kLsaSaBits = 2; 241 const int kFunctionShift = 0; 242 const int kFunctionBits = 6; 243 const int kLuiShift = 16; 244 const int kBp2Shift = 6; 245 const int kBp2Bits = 2; 246 const int kBp3Shift = 6; 247 const int kBp3Bits = 3; 248 249 const int kImm16Shift = 0; 250 const int kImm16Bits = 16; 251 const int kImm18Shift = 0; 252 const int kImm18Bits = 18; 253 const int kImm19Shift = 0; 254 const int kImm19Bits = 19; 255 const int kImm21Shift = 0; 256 const int kImm21Bits = 21; 257 const int kImm26Shift = 0; 258 const int kImm26Bits = 26; 259 const int kImm28Shift = 0; 260 const int kImm28Bits = 28; 261 const int kImm32Shift = 0; 262 const int kImm32Bits = 32; 263 264 // In branches and jumps immediate fields point to words, not bytes, 265 // and are therefore shifted by 2. 266 const int kImmFieldShift = 2; 267 268 const int kFrBits = 5; 269 const int kFrShift = 21; 270 const int kFsShift = 11; 271 const int kFsBits = 5; 272 const int kFtShift = 16; 273 const int kFtBits = 5; 274 const int kFdShift = 6; 275 const int kFdBits = 5; 276 const int kFCccShift = 8; 277 const int kFCccBits = 3; 278 const int kFBccShift = 18; 279 const int kFBccBits = 3; 280 const int kFBtrueShift = 16; 281 const int kFBtrueBits = 1; 282 283 // ----- Miscellaneous useful masks. 284 // Instruction bit masks. 285 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 286 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 287 const int kImm18Mask = ((1 << kImm18Bits) - 1) << kImm18Shift; 288 const int kImm19Mask = ((1 << kImm19Bits) - 1) << kImm19Shift; 289 const int kImm21Mask = ((1 << kImm21Bits) - 1) << kImm21Shift; 290 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 291 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift; 292 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 293 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 294 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 295 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 296 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; 297 // Misc masks. 298 const int kHiMask = 0xffff << 16; 299 const int kLoMask = 0xffff; 300 const int kSignMask = 0x80000000; 301 const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1; 302 const int64_t kHi16MaskOf64 = (int64_t)0xffff << 48; 303 const int64_t kSe16MaskOf64 = (int64_t)0xffff << 32; 304 const int64_t kTh16MaskOf64 = (int64_t)0xffff << 16; 305 const int32_t kJalRawMark = 0x00000000; 306 const int32_t kJRawMark = 0xf0000000; 307 const int32_t kJumpRawMask = 0xf0000000; 308 309 // ----- MIPS Opcodes and Function Fields. 310 // We use this presentation to stay close to the table representation in 311 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 312 enum Opcode : uint32_t { 313 SPECIAL = 0U << kOpcodeShift, 314 REGIMM = 1U << kOpcodeShift, 315 316 J = ((0U << 3) + 2) << kOpcodeShift, 317 JAL = ((0U << 3) + 3) << kOpcodeShift, 318 BEQ = ((0U << 3) + 4) << kOpcodeShift, 319 BNE = ((0U << 3) + 5) << kOpcodeShift, 320 BLEZ = ((0U << 3) + 6) << kOpcodeShift, 321 BGTZ = ((0U << 3) + 7) << kOpcodeShift, 322 323 ADDI = ((1U << 3) + 0) << kOpcodeShift, 324 ADDIU = ((1U << 3) + 1) << kOpcodeShift, 325 SLTI = ((1U << 3) + 2) << kOpcodeShift, 326 SLTIU = ((1U << 3) + 3) << kOpcodeShift, 327 ANDI = ((1U << 3) + 4) << kOpcodeShift, 328 ORI = ((1U << 3) + 5) << kOpcodeShift, 329 XORI = ((1U << 3) + 6) << kOpcodeShift, 330 LUI = ((1U << 3) + 7) << kOpcodeShift, // LUI/AUI family. 331 DAUI = ((3U << 3) + 5) << kOpcodeShift, 332 333 BEQC = ((2U << 3) + 0) << kOpcodeShift, 334 COP1 = ((2U << 3) + 1) << kOpcodeShift, // Coprocessor 1 class. 335 BEQL = ((2U << 3) + 4) << kOpcodeShift, 336 BNEL = ((2U << 3) + 5) << kOpcodeShift, 337 BLEZL = ((2U << 3) + 6) << kOpcodeShift, 338 BGTZL = ((2U << 3) + 7) << kOpcodeShift, 339 340 DADDI = ((3U << 3) + 0) << kOpcodeShift, // This is also BNEC. 341 DADDIU = ((3U << 3) + 1) << kOpcodeShift, 342 LDL = ((3U << 3) + 2) << kOpcodeShift, 343 LDR = ((3U << 3) + 3) << kOpcodeShift, 344 SPECIAL2 = ((3U << 3) + 4) << kOpcodeShift, 345 SPECIAL3 = ((3U << 3) + 7) << kOpcodeShift, 346 347 LB = ((4U << 3) + 0) << kOpcodeShift, 348 LH = ((4U << 3) + 1) << kOpcodeShift, 349 LWL = ((4U << 3) + 2) << kOpcodeShift, 350 LW = ((4U << 3) + 3) << kOpcodeShift, 351 LBU = ((4U << 3) + 4) << kOpcodeShift, 352 LHU = ((4U << 3) + 5) << kOpcodeShift, 353 LWR = ((4U << 3) + 6) << kOpcodeShift, 354 LWU = ((4U << 3) + 7) << kOpcodeShift, 355 356 SB = ((5U << 3) + 0) << kOpcodeShift, 357 SH = ((5U << 3) + 1) << kOpcodeShift, 358 SWL = ((5U << 3) + 2) << kOpcodeShift, 359 SW = ((5U << 3) + 3) << kOpcodeShift, 360 SDL = ((5U << 3) + 4) << kOpcodeShift, 361 SDR = ((5U << 3) + 5) << kOpcodeShift, 362 SWR = ((5U << 3) + 6) << kOpcodeShift, 363 364 LWC1 = ((6U << 3) + 1) << kOpcodeShift, 365 BC = ((6U << 3) + 2) << kOpcodeShift, 366 LLD = ((6U << 3) + 4) << kOpcodeShift, 367 LDC1 = ((6U << 3) + 5) << kOpcodeShift, 368 POP66 = ((6U << 3) + 6) << kOpcodeShift, 369 LD = ((6U << 3) + 7) << kOpcodeShift, 370 371 PREF = ((6U << 3) + 3) << kOpcodeShift, 372 373 SWC1 = ((7U << 3) + 1) << kOpcodeShift, 374 BALC = ((7U << 3) + 2) << kOpcodeShift, 375 PCREL = ((7U << 3) + 3) << kOpcodeShift, 376 SCD = ((7U << 3) + 4) << kOpcodeShift, 377 SDC1 = ((7U << 3) + 5) << kOpcodeShift, 378 POP76 = ((7U << 3) + 6) << kOpcodeShift, 379 SD = ((7U << 3) + 7) << kOpcodeShift, 380 381 COP1X = ((1U << 4) + 3) << kOpcodeShift, 382 383 // New r6 instruction. 384 POP06 = BLEZ, // bgeuc/bleuc, blezalc, bgezalc 385 POP07 = BGTZ, // bltuc/bgtuc, bgtzalc, bltzalc 386 POP10 = ADDI, // beqzalc, bovc, beqc 387 POP26 = BLEZL, // bgezc, blezc, bgec/blec 388 POP27 = BGTZL, // bgtzc, bltzc, bltc/bgtc 389 POP30 = DADDI, // bnezalc, bnvc, bnec 390 }; 391 392 enum SecondaryField : uint32_t { 393 // SPECIAL Encoding of Function Field. 394 SLL = ((0U << 3) + 0), 395 MOVCI = ((0U << 3) + 1), 396 SRL = ((0U << 3) + 2), 397 SRA = ((0U << 3) + 3), 398 SLLV = ((0U << 3) + 4), 399 LSA = ((0U << 3) + 5), 400 SRLV = ((0U << 3) + 6), 401 SRAV = ((0U << 3) + 7), 402 403 JR = ((1U << 3) + 0), 404 JALR = ((1U << 3) + 1), 405 MOVZ = ((1U << 3) + 2), 406 MOVN = ((1U << 3) + 3), 407 BREAK = ((1U << 3) + 5), 408 SYNC = ((1U << 3) + 7), 409 410 MFHI = ((2U << 3) + 0), 411 CLZ_R6 = ((2U << 3) + 0), 412 CLO_R6 = ((2U << 3) + 1), 413 MFLO = ((2U << 3) + 2), 414 DCLZ_R6 = ((2U << 3) + 2), 415 DCLO_R6 = ((2U << 3) + 3), 416 DSLLV = ((2U << 3) + 4), 417 DLSA = ((2U << 3) + 5), 418 DSRLV = ((2U << 3) + 6), 419 DSRAV = ((2U << 3) + 7), 420 421 MULT = ((3U << 3) + 0), 422 MULTU = ((3U << 3) + 1), 423 DIV = ((3U << 3) + 2), 424 DIVU = ((3U << 3) + 3), 425 DMULT = ((3U << 3) + 4), 426 DMULTU = ((3U << 3) + 5), 427 DDIV = ((3U << 3) + 6), 428 DDIVU = ((3U << 3) + 7), 429 430 ADD = ((4U << 3) + 0), 431 ADDU = ((4U << 3) + 1), 432 SUB = ((4U << 3) + 2), 433 SUBU = ((4U << 3) + 3), 434 AND = ((4U << 3) + 4), 435 OR = ((4U << 3) + 5), 436 XOR = ((4U << 3) + 6), 437 NOR = ((4U << 3) + 7), 438 439 SLT = ((5U << 3) + 2), 440 SLTU = ((5U << 3) + 3), 441 DADD = ((5U << 3) + 4), 442 DADDU = ((5U << 3) + 5), 443 DSUB = ((5U << 3) + 6), 444 DSUBU = ((5U << 3) + 7), 445 446 TGE = ((6U << 3) + 0), 447 TGEU = ((6U << 3) + 1), 448 TLT = ((6U << 3) + 2), 449 TLTU = ((6U << 3) + 3), 450 TEQ = ((6U << 3) + 4), 451 SELEQZ_S = ((6U << 3) + 5), 452 TNE = ((6U << 3) + 6), 453 SELNEZ_S = ((6U << 3) + 7), 454 455 DSLL = ((7U << 3) + 0), 456 DSRL = ((7U << 3) + 2), 457 DSRA = ((7U << 3) + 3), 458 DSLL32 = ((7U << 3) + 4), 459 DSRL32 = ((7U << 3) + 6), 460 DSRA32 = ((7U << 3) + 7), 461 462 // Multiply integers in r6. 463 MUL_MUH = ((3U << 3) + 0), // MUL, MUH. 464 MUL_MUH_U = ((3U << 3) + 1), // MUL_U, MUH_U. 465 D_MUL_MUH = ((7U << 2) + 0), // DMUL, DMUH. 466 D_MUL_MUH_U = ((7U << 2) + 1), // DMUL_U, DMUH_U. 467 RINT = ((3U << 3) + 2), 468 469 MUL_OP = ((0U << 3) + 2), 470 MUH_OP = ((0U << 3) + 3), 471 DIV_OP = ((0U << 3) + 2), 472 MOD_OP = ((0U << 3) + 3), 473 474 DIV_MOD = ((3U << 3) + 2), 475 DIV_MOD_U = ((3U << 3) + 3), 476 D_DIV_MOD = ((3U << 3) + 6), 477 D_DIV_MOD_U = ((3U << 3) + 7), 478 479 // drotr in special4? 480 481 // SPECIAL2 Encoding of Function Field. 482 MUL = ((0U << 3) + 2), 483 CLZ = ((4U << 3) + 0), 484 CLO = ((4U << 3) + 1), 485 DCLZ = ((4U << 3) + 4), 486 DCLO = ((4U << 3) + 5), 487 488 // SPECIAL3 Encoding of Function Field. 489 EXT = ((0U << 3) + 0), 490 DEXTM = ((0U << 3) + 1), 491 DEXTU = ((0U << 3) + 2), 492 DEXT = ((0U << 3) + 3), 493 INS = ((0U << 3) + 4), 494 DINSM = ((0U << 3) + 5), 495 DINSU = ((0U << 3) + 6), 496 DINS = ((0U << 3) + 7), 497 498 BSHFL = ((4U << 3) + 0), 499 DBSHFL = ((4U << 3) + 4), 500 501 // SPECIAL3 Encoding of sa Field. 502 BITSWAP = ((0U << 3) + 0), 503 ALIGN = ((0U << 3) + 2), 504 WSBH = ((0U << 3) + 2), 505 SEB = ((2U << 3) + 0), 506 SEH = ((3U << 3) + 0), 507 508 DBITSWAP = ((0U << 3) + 0), 509 DALIGN = ((0U << 3) + 1), 510 DBITSWAP_SA = ((0U << 3) + 0) << kSaShift, 511 DSBH = ((0U << 3) + 2), 512 DSHD = ((0U << 3) + 5), 513 514 // REGIMM encoding of rt Field. 515 BLTZ = ((0U << 3) + 0) << 16, 516 BGEZ = ((0U << 3) + 1) << 16, 517 BLTZAL = ((2U << 3) + 0) << 16, 518 BGEZAL = ((2U << 3) + 1) << 16, 519 BGEZALL = ((2U << 3) + 3) << 16, 520 DAHI = ((0U << 3) + 6) << 16, 521 DATI = ((3U << 3) + 6) << 16, 522 523 // COP1 Encoding of rs Field. 524 MFC1 = ((0U << 3) + 0) << 21, 525 DMFC1 = ((0U << 3) + 1) << 21, 526 CFC1 = ((0U << 3) + 2) << 21, 527 MFHC1 = ((0U << 3) + 3) << 21, 528 MTC1 = ((0U << 3) + 4) << 21, 529 DMTC1 = ((0U << 3) + 5) << 21, 530 CTC1 = ((0U << 3) + 6) << 21, 531 MTHC1 = ((0U << 3) + 7) << 21, 532 BC1 = ((1U << 3) + 0) << 21, 533 S = ((2U << 3) + 0) << 21, 534 D = ((2U << 3) + 1) << 21, 535 W = ((2U << 3) + 4) << 21, 536 L = ((2U << 3) + 5) << 21, 537 PS = ((2U << 3) + 6) << 21, 538 // COP1 Encoding of Function Field When rs=S. 539 540 ADD_S = ((0U << 3) + 0), 541 SUB_S = ((0U << 3) + 1), 542 MUL_S = ((0U << 3) + 2), 543 DIV_S = ((0U << 3) + 3), 544 ABS_S = ((0U << 3) + 5), 545 SQRT_S = ((0U << 3) + 4), 546 MOV_S = ((0U << 3) + 6), 547 NEG_S = ((0U << 3) + 7), 548 ROUND_L_S = ((1U << 3) + 0), 549 TRUNC_L_S = ((1U << 3) + 1), 550 CEIL_L_S = ((1U << 3) + 2), 551 FLOOR_L_S = ((1U << 3) + 3), 552 ROUND_W_S = ((1U << 3) + 4), 553 TRUNC_W_S = ((1U << 3) + 5), 554 CEIL_W_S = ((1U << 3) + 6), 555 FLOOR_W_S = ((1U << 3) + 7), 556 RECIP_S = ((2U << 3) + 5), 557 RSQRT_S = ((2U << 3) + 6), 558 MADDF_S = ((3U << 3) + 0), 559 MSUBF_S = ((3U << 3) + 1), 560 CLASS_S = ((3U << 3) + 3), 561 CVT_D_S = ((4U << 3) + 1), 562 CVT_W_S = ((4U << 3) + 4), 563 CVT_L_S = ((4U << 3) + 5), 564 CVT_PS_S = ((4U << 3) + 6), 565 // COP1 Encoding of Function Field When rs=D. 566 ADD_D = ((0U << 3) + 0), 567 SUB_D = ((0U << 3) + 1), 568 MUL_D = ((0U << 3) + 2), 569 DIV_D = ((0U << 3) + 3), 570 SQRT_D = ((0U << 3) + 4), 571 ABS_D = ((0U << 3) + 5), 572 MOV_D = ((0U << 3) + 6), 573 NEG_D = ((0U << 3) + 7), 574 ROUND_L_D = ((1U << 3) + 0), 575 TRUNC_L_D = ((1U << 3) + 1), 576 CEIL_L_D = ((1U << 3) + 2), 577 FLOOR_L_D = ((1U << 3) + 3), 578 ROUND_W_D = ((1U << 3) + 4), 579 TRUNC_W_D = ((1U << 3) + 5), 580 CEIL_W_D = ((1U << 3) + 6), 581 FLOOR_W_D = ((1U << 3) + 7), 582 RECIP_D = ((2U << 3) + 5), 583 RSQRT_D = ((2U << 3) + 6), 584 MADDF_D = ((3U << 3) + 0), 585 MSUBF_D = ((3U << 3) + 1), 586 CLASS_D = ((3U << 3) + 3), 587 MIN = ((3U << 3) + 4), 588 MINA = ((3U << 3) + 5), 589 MAX = ((3U << 3) + 6), 590 MAXA = ((3U << 3) + 7), 591 CVT_S_D = ((4U << 3) + 0), 592 CVT_W_D = ((4U << 3) + 4), 593 CVT_L_D = ((4U << 3) + 5), 594 C_F_D = ((6U << 3) + 0), 595 C_UN_D = ((6U << 3) + 1), 596 C_EQ_D = ((6U << 3) + 2), 597 C_UEQ_D = ((6U << 3) + 3), 598 C_OLT_D = ((6U << 3) + 4), 599 C_ULT_D = ((6U << 3) + 5), 600 C_OLE_D = ((6U << 3) + 6), 601 C_ULE_D = ((6U << 3) + 7), 602 603 // COP1 Encoding of Function Field When rs=W or L. 604 CVT_S_W = ((4U << 3) + 0), 605 CVT_D_W = ((4U << 3) + 1), 606 CVT_S_L = ((4U << 3) + 0), 607 CVT_D_L = ((4U << 3) + 1), 608 BC1EQZ = ((2U << 2) + 1) << 21, 609 BC1NEZ = ((3U << 2) + 1) << 21, 610 // COP1 CMP positive predicates Bit 5..4 = 00. 611 CMP_AF = ((0U << 3) + 0), 612 CMP_UN = ((0U << 3) + 1), 613 CMP_EQ = ((0U << 3) + 2), 614 CMP_UEQ = ((0U << 3) + 3), 615 CMP_LT = ((0U << 3) + 4), 616 CMP_ULT = ((0U << 3) + 5), 617 CMP_LE = ((0U << 3) + 6), 618 CMP_ULE = ((0U << 3) + 7), 619 CMP_SAF = ((1U << 3) + 0), 620 CMP_SUN = ((1U << 3) + 1), 621 CMP_SEQ = ((1U << 3) + 2), 622 CMP_SUEQ = ((1U << 3) + 3), 623 CMP_SSLT = ((1U << 3) + 4), 624 CMP_SSULT = ((1U << 3) + 5), 625 CMP_SLE = ((1U << 3) + 6), 626 CMP_SULE = ((1U << 3) + 7), 627 // COP1 CMP negative predicates Bit 5..4 = 01. 628 CMP_AT = ((2U << 3) + 0), // Reserved, not implemented. 629 CMP_OR = ((2U << 3) + 1), 630 CMP_UNE = ((2U << 3) + 2), 631 CMP_NE = ((2U << 3) + 3), 632 CMP_UGE = ((2U << 3) + 4), // Reserved, not implemented. 633 CMP_OGE = ((2U << 3) + 5), // Reserved, not implemented. 634 CMP_UGT = ((2U << 3) + 6), // Reserved, not implemented. 635 CMP_OGT = ((2U << 3) + 7), // Reserved, not implemented. 636 CMP_SAT = ((3U << 3) + 0), // Reserved, not implemented. 637 CMP_SOR = ((3U << 3) + 1), 638 CMP_SUNE = ((3U << 3) + 2), 639 CMP_SNE = ((3U << 3) + 3), 640 CMP_SUGE = ((3U << 3) + 4), // Reserved, not implemented. 641 CMP_SOGE = ((3U << 3) + 5), // Reserved, not implemented. 642 CMP_SUGT = ((3U << 3) + 6), // Reserved, not implemented. 643 CMP_SOGT = ((3U << 3) + 7), // Reserved, not implemented. 644 645 SEL = ((2U << 3) + 0), 646 MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt 647 MOVZ_C = ((2U << 3) + 2), // COP1 on FPR registers. 648 MOVN_C = ((2U << 3) + 3), // COP1 on FPR registers. 649 SELEQZ_C = ((2U << 3) + 4), // COP1 on FPR registers. 650 SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers. 651 652 // COP1 Encoding of Function Field When rs=PS. 653 654 // COP1X Encoding of Function Field. 655 MADD_S = ((4U << 3) + 0), 656 MADD_D = ((4U << 3) + 1), 657 MSUB_S = ((5U << 3) + 0), 658 MSUB_D = ((5U << 3) + 1), 659 660 // PCREL Encoding of rt Field. 661 ADDIUPC = ((0U << 2) + 0), 662 LWPC = ((0U << 2) + 1), 663 LWUPC = ((0U << 2) + 2), 664 LDPC = ((0U << 3) + 6), 665 // reserved ((1U << 3) + 6), 666 AUIPC = ((3U << 3) + 6), 667 ALUIPC = ((3U << 3) + 7), 668 669 // POP66 Encoding of rs Field. 670 JIC = ((0U << 5) + 0), 671 672 // POP76 Encoding of rs Field. 673 JIALC = ((0U << 5) + 0), 674 675 NULLSF = 0U 676 }; 677 678 // ----- Emulated conditions. 679 // On MIPS we use this enum to abstract from conditional branch instructions. 680 // The 'U' prefix is used to specify unsigned comparisons. 681 // Opposite conditions must be paired as odd/even numbers 682 // because 'NegateCondition' function flips LSB to negate condition. 683 enum Condition { 684 // Any value < 0 is considered no_condition. 685 kNoCondition = -1, 686 overflow = 0, 687 no_overflow = 1, 688 Uless = 2, 689 Ugreater_equal = 3, 690 Uless_equal = 4, 691 Ugreater = 5, 692 equal = 6, 693 not_equal = 7, // Unordered or Not Equal. 694 negative = 8, 695 positive = 9, 696 parity_even = 10, 697 parity_odd = 11, 698 less = 12, 699 greater_equal = 13, 700 less_equal = 14, 701 greater = 15, 702 ueq = 16, // Unordered or Equal. 703 ogl = 17, // Ordered and Not Equal. 704 cc_always = 18, 705 706 // Aliases. 707 carry = Uless, 708 not_carry = Ugreater_equal, 709 zero = equal, 710 eq = equal, 711 not_zero = not_equal, 712 ne = not_equal, 713 nz = not_equal, 714 sign = negative, 715 not_sign = positive, 716 mi = negative, 717 pl = positive, 718 hi = Ugreater, 719 ls = Uless_equal, 720 ge = greater_equal, 721 lt = less, 722 gt = greater, 723 le = less_equal, 724 hs = Ugreater_equal, 725 lo = Uless, 726 al = cc_always, 727 ult = Uless, 728 uge = Ugreater_equal, 729 ule = Uless_equal, 730 ugt = Ugreater, 731 cc_default = kNoCondition 732 }; 733 734 735 // Returns the equivalent of !cc. 736 // Negation of the default kNoCondition (-1) results in a non-default 737 // no_condition value (-2). As long as tests for no_condition check 738 // for condition < 0, this will work as expected. 739 inline Condition NegateCondition(Condition cc) { 740 DCHECK(cc != cc_always); 741 return static_cast<Condition>(cc ^ 1); 742 } 743 744 745 inline Condition NegateFpuCondition(Condition cc) { 746 DCHECK(cc != cc_always); 747 switch (cc) { 748 case ult: 749 return ge; 750 case ugt: 751 return le; 752 case uge: 753 return lt; 754 case ule: 755 return gt; 756 case lt: 757 return uge; 758 case gt: 759 return ule; 760 case ge: 761 return ult; 762 case le: 763 return ugt; 764 case eq: 765 return ne; 766 case ne: 767 return eq; 768 case ueq: 769 return ogl; 770 case ogl: 771 return ueq; 772 default: 773 return cc; 774 } 775 } 776 777 778 // Commute a condition such that {a cond b == b cond' a}. 779 inline Condition CommuteCondition(Condition cc) { 780 switch (cc) { 781 case Uless: 782 return Ugreater; 783 case Ugreater: 784 return Uless; 785 case Ugreater_equal: 786 return Uless_equal; 787 case Uless_equal: 788 return Ugreater_equal; 789 case less: 790 return greater; 791 case greater: 792 return less; 793 case greater_equal: 794 return less_equal; 795 case less_equal: 796 return greater_equal; 797 default: 798 return cc; 799 } 800 } 801 802 803 // ----- Coprocessor conditions. 804 enum FPUCondition { 805 kNoFPUCondition = -1, 806 807 F = 0x00, // False. 808 UN = 0x01, // Unordered. 809 EQ = 0x02, // Equal. 810 UEQ = 0x03, // Unordered or Equal. 811 OLT = 0x04, // Ordered or Less Than, on Mips release < 6. 812 LT = 0x04, // Ordered or Less Than, on Mips release >= 6. 813 ULT = 0x05, // Unordered or Less Than. 814 OLE = 0x06, // Ordered or Less Than or Equal, on Mips release < 6. 815 LE = 0x06, // Ordered or Less Than or Equal, on Mips release >= 6. 816 ULE = 0x07, // Unordered or Less Than or Equal. 817 818 // Following constants are available on Mips release >= 6 only. 819 ORD = 0x11, // Ordered, on Mips release >= 6. 820 UNE = 0x12, // Not equal, on Mips release >= 6. 821 NE = 0x13, // Ordered Greater Than or Less Than. on Mips >= 6 only. 822 }; 823 824 825 // FPU rounding modes. 826 enum FPURoundingMode { 827 RN = 0 << 0, // Round to Nearest. 828 RZ = 1 << 0, // Round towards zero. 829 RP = 2 << 0, // Round towards Plus Infinity. 830 RM = 3 << 0, // Round towards Minus Infinity. 831 832 // Aliases. 833 kRoundToNearest = RN, 834 kRoundToZero = RZ, 835 kRoundToPlusInf = RP, 836 kRoundToMinusInf = RM, 837 838 mode_round = RN, 839 mode_ceil = RP, 840 mode_floor = RM, 841 mode_trunc = RZ 842 }; 843 844 const uint32_t kFPURoundingModeMask = 3 << 0; 845 846 enum CheckForInexactConversion { 847 kCheckForInexactConversion, 848 kDontCheckForInexactConversion 849 }; 850 851 enum class MaxMinKind : int { kMin = 0, kMax = 1 }; 852 853 // ----------------------------------------------------------------------------- 854 // Hints. 855 856 // Branch hints are not used on the MIPS. They are defined so that they can 857 // appear in shared function signatures, but will be ignored in MIPS 858 // implementations. 859 enum Hint { 860 no_hint = 0 861 }; 862 863 864 inline Hint NegateHint(Hint hint) { 865 return no_hint; 866 } 867 868 869 // ----------------------------------------------------------------------------- 870 // Specific instructions, constants, and masks. 871 // These constants are declared in assembler-mips.cc, as they use named 872 // registers and other constants. 873 874 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 875 // operations as post-increment of sp. 876 extern const Instr kPopInstruction; 877 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 878 extern const Instr kPushInstruction; 879 // sw(r, MemOperand(sp, 0)) 880 extern const Instr kPushRegPattern; 881 // lw(r, MemOperand(sp, 0)) 882 extern const Instr kPopRegPattern; 883 extern const Instr kLwRegFpOffsetPattern; 884 extern const Instr kSwRegFpOffsetPattern; 885 extern const Instr kLwRegFpNegOffsetPattern; 886 extern const Instr kSwRegFpNegOffsetPattern; 887 // A mask for the Rt register for push, pop, lw, sw instructions. 888 extern const Instr kRtMask; 889 extern const Instr kLwSwInstrTypeMask; 890 extern const Instr kLwSwInstrArgumentMask; 891 extern const Instr kLwSwOffsetMask; 892 893 // Break 0xfffff, reserved for redirected real time call. 894 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 895 // A nop instruction. (Encoding of sll 0 0 0). 896 const Instr nopInstr = 0; 897 898 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { 899 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); 900 } 901 902 class InstructionBase { 903 public: 904 enum { 905 kInstrSize = 4, 906 kInstrSizeLog2 = 2, 907 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 908 // always the value of the current instruction being executed. 909 kPCReadOffset = 0 910 }; 911 912 // Instruction type. 913 enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 }; 914 915 // Get the raw instruction bits. 916 inline Instr InstructionBits() const { 917 return *reinterpret_cast<const Instr*>(this); 918 } 919 920 // Set the raw instruction bits to value. 921 inline void SetInstructionBits(Instr value) { 922 *reinterpret_cast<Instr*>(this) = value; 923 } 924 925 // Read one particular bit out of the instruction bits. 926 inline int Bit(int nr) const { 927 return (InstructionBits() >> nr) & 1; 928 } 929 930 // Read a bit field out of the instruction bits. 931 inline int Bits(int hi, int lo) const { 932 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); 933 } 934 935 static constexpr uint64_t kOpcodeImmediateTypeMask = 936 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | 937 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | 938 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | 939 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | 940 OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) | 941 OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) | 942 OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) | 943 OpcodeToBitNumber(LUI) | OpcodeToBitNumber(BEQL) | 944 OpcodeToBitNumber(BNEL) | OpcodeToBitNumber(BLEZL) | 945 OpcodeToBitNumber(BGTZL) | OpcodeToBitNumber(POP66) | 946 OpcodeToBitNumber(POP76) | OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | 947 OpcodeToBitNumber(LWL) | OpcodeToBitNumber(LW) | OpcodeToBitNumber(LWU) | 948 OpcodeToBitNumber(LD) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) | 949 OpcodeToBitNumber(LDL) | OpcodeToBitNumber(LDR) | OpcodeToBitNumber(LWR) | 950 OpcodeToBitNumber(SDL) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) | 951 OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SD) | 952 OpcodeToBitNumber(SWR) | OpcodeToBitNumber(SDR) | 953 OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) | 954 OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) | 955 OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(DAUI) | 956 OpcodeToBitNumber(BC) | OpcodeToBitNumber(BALC); 957 958 #define FunctionFieldToBitNumber(function) (1ULL << function) 959 960 // On r6, DCLZ_R6 aliases to existing MFLO. 961 static const uint64_t kFunctionFieldRegisterTypeMask = 962 FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) | 963 FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) | 964 FunctionFieldToBitNumber(DSLL) | FunctionFieldToBitNumber(DSLL32) | 965 FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(DSRL) | 966 FunctionFieldToBitNumber(DSRL32) | FunctionFieldToBitNumber(SRA) | 967 FunctionFieldToBitNumber(DSRA) | FunctionFieldToBitNumber(DSRA32) | 968 FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(DSLLV) | 969 FunctionFieldToBitNumber(SRLV) | FunctionFieldToBitNumber(DSRLV) | 970 FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(DSRAV) | 971 FunctionFieldToBitNumber(LSA) | FunctionFieldToBitNumber(DLSA) | 972 FunctionFieldToBitNumber(MFHI) | FunctionFieldToBitNumber(MFLO) | 973 FunctionFieldToBitNumber(MULT) | FunctionFieldToBitNumber(DMULT) | 974 FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DMULTU) | 975 FunctionFieldToBitNumber(DIV) | FunctionFieldToBitNumber(DDIV) | 976 FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(DDIVU) | 977 FunctionFieldToBitNumber(ADD) | FunctionFieldToBitNumber(DADD) | 978 FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(DADDU) | 979 FunctionFieldToBitNumber(SUB) | FunctionFieldToBitNumber(DSUB) | 980 FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(DSUBU) | 981 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | 982 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | 983 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | 984 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | 985 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | 986 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | 987 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | 988 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | 989 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); 990 991 992 // Accessors for the different named fields used in the MIPS encoding. 993 inline Opcode OpcodeValue() const { 994 return static_cast<Opcode>( 995 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 996 } 997 998 inline int FunctionFieldRaw() const { 999 return InstructionBits() & kFunctionFieldMask; 1000 } 1001 1002 // Return the fields at their original place in the instruction encoding. 1003 inline Opcode OpcodeFieldRaw() const { 1004 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 1005 } 1006 1007 // Safe to call within InstructionType(). 1008 inline int RsFieldRawNoAssert() const { 1009 return InstructionBits() & kRsFieldMask; 1010 } 1011 1012 inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; } 1013 1014 // Get the encoding type of the instruction. 1015 inline Type InstructionType() const; 1016 1017 protected: 1018 InstructionBase() {} 1019 }; 1020 1021 template <class T> 1022 class InstructionGetters : public T { 1023 public: 1024 inline int RsValue() const { 1025 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1026 this->InstructionType() == InstructionBase::kImmediateType); 1027 return this->Bits(kRsShift + kRsBits - 1, kRsShift); 1028 } 1029 1030 inline int RtValue() const { 1031 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1032 this->InstructionType() == InstructionBase::kImmediateType); 1033 return this->Bits(kRtShift + kRtBits - 1, kRtShift); 1034 } 1035 1036 inline int RdValue() const { 1037 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1038 return this->Bits(kRdShift + kRdBits - 1, kRdShift); 1039 } 1040 1041 inline int SaValue() const { 1042 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1043 return this->Bits(kSaShift + kSaBits - 1, kSaShift); 1044 } 1045 1046 inline int LsaSaValue() const { 1047 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1048 return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift); 1049 } 1050 1051 inline int FunctionValue() const { 1052 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1053 this->InstructionType() == InstructionBase::kImmediateType); 1054 return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 1055 } 1056 1057 inline int FdValue() const { 1058 return this->Bits(kFdShift + kFdBits - 1, kFdShift); 1059 } 1060 1061 inline int FsValue() const { 1062 return this->Bits(kFsShift + kFsBits - 1, kFsShift); 1063 } 1064 1065 inline int FtValue() const { 1066 return this->Bits(kFtShift + kFtBits - 1, kFtShift); 1067 } 1068 1069 inline int FrValue() const { 1070 return this->Bits(kFrShift + kFrBits - 1, kFrShift); 1071 } 1072 1073 inline int Bp2Value() const { 1074 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1075 return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); 1076 } 1077 1078 inline int Bp3Value() const { 1079 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1080 return this->Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift); 1081 } 1082 1083 // Float Compare condition code instruction bits. 1084 inline int FCccValue() const { 1085 return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift); 1086 } 1087 1088 // Float Branch condition code instruction bits. 1089 inline int FBccValue() const { 1090 return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift); 1091 } 1092 1093 // Float Branch true/false instruction bit. 1094 inline int FBtrueValue() const { 1095 return this->Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 1096 } 1097 1098 // Return the fields at their original place in the instruction encoding. 1099 inline Opcode OpcodeFieldRaw() const { 1100 return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask); 1101 } 1102 1103 inline int RsFieldRaw() const { 1104 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1105 this->InstructionType() == InstructionBase::kImmediateType); 1106 return this->InstructionBits() & kRsFieldMask; 1107 } 1108 1109 // Same as above function, but safe to call within InstructionType(). 1110 inline int RsFieldRawNoAssert() const { 1111 return this->InstructionBits() & kRsFieldMask; 1112 } 1113 1114 inline int RtFieldRaw() const { 1115 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || 1116 this->InstructionType() == InstructionBase::kImmediateType); 1117 return this->InstructionBits() & kRtFieldMask; 1118 } 1119 1120 inline int RdFieldRaw() const { 1121 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); 1122 return this->InstructionBits() & kRdFieldMask; 1123 } 1124 1125 inline int SaFieldRaw() const { 1126 return this->InstructionBits() & kSaFieldMask; 1127 } 1128 1129 inline int FunctionFieldRaw() const { 1130 return this->InstructionBits() & kFunctionFieldMask; 1131 } 1132 1133 // Get the secondary field according to the opcode. 1134 inline int SecondaryValue() const { 1135 Opcode op = this->OpcodeFieldRaw(); 1136 switch (op) { 1137 case SPECIAL: 1138 case SPECIAL2: 1139 return FunctionValue(); 1140 case COP1: 1141 return RsValue(); 1142 case REGIMM: 1143 return RtValue(); 1144 default: 1145 return NULLSF; 1146 } 1147 } 1148 1149 inline int32_t ImmValue(int bits) const { 1150 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); 1151 return this->Bits(bits - 1, 0); 1152 } 1153 1154 inline int32_t Imm16Value() const { 1155 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); 1156 return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 1157 } 1158 1159 inline int32_t Imm18Value() const { 1160 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); 1161 return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); 1162 } 1163 1164 inline int32_t Imm19Value() const { 1165 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); 1166 return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); 1167 } 1168 1169 inline int32_t Imm21Value() const { 1170 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); 1171 return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); 1172 } 1173 1174 inline int32_t Imm26Value() const { 1175 DCHECK((this->InstructionType() == InstructionBase::kJumpType) || 1176 (this->InstructionType() == InstructionBase::kImmediateType)); 1177 return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); 1178 } 1179 1180 static bool IsForbiddenAfterBranchInstr(Instr instr); 1181 1182 // Say if the instruction should not be used in a branch delay slot or 1183 // immediately after a compact branch. 1184 inline bool IsForbiddenAfterBranch() const { 1185 return IsForbiddenAfterBranchInstr(this->InstructionBits()); 1186 } 1187 1188 inline bool IsForbiddenInBranchDelay() const { 1189 return IsForbiddenAfterBranch(); 1190 } 1191 1192 // Say if the instruction 'links'. e.g. jal, bal. 1193 bool IsLinkingInstruction() const; 1194 // Say if the instruction is a break or a trap. 1195 bool IsTrap() const; 1196 }; 1197 1198 class Instruction : public InstructionGetters<InstructionBase> { 1199 public: 1200 // Instructions are read of out a code stream. The only way to get a 1201 // reference to an instruction is to convert a pointer. There is no way 1202 // to allocate or create instances of class Instruction. 1203 // Use the At(pc) function to create references to Instruction. 1204 static Instruction* At(byte* pc) { 1205 return reinterpret_cast<Instruction*>(pc); 1206 } 1207 1208 private: 1209 // We need to prevent the creation of instances of class Instruction. 1210 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 1211 }; 1212 1213 1214 // ----------------------------------------------------------------------------- 1215 // MIPS assembly various constants. 1216 1217 // C/C++ argument slots size. 1218 const int kCArgSlotCount = 0; 1219 1220 // TODO(plind): below should be based on kPointerSize 1221 // TODO(plind): find all usages and remove the needless instructions for n64. 1222 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2; 1223 1224 const int kInvalidStackOffset = -1; 1225 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 1226 1227 InstructionBase::Type InstructionBase::InstructionType() const { 1228 switch (OpcodeFieldRaw()) { 1229 case SPECIAL: 1230 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & 1231 kFunctionFieldRegisterTypeMask) { 1232 return kRegisterType; 1233 } 1234 return kUnsupported; 1235 case SPECIAL2: 1236 switch (FunctionFieldRaw()) { 1237 case MUL: 1238 case CLZ: 1239 case DCLZ: 1240 return kRegisterType; 1241 default: 1242 return kUnsupported; 1243 } 1244 break; 1245 case SPECIAL3: 1246 switch (FunctionFieldRaw()) { 1247 case INS: 1248 case DINS: 1249 case EXT: 1250 case DEXT: 1251 case DEXTM: 1252 case DEXTU: 1253 return kRegisterType; 1254 case BSHFL: { 1255 int sa = SaFieldRaw() >> kSaShift; 1256 switch (sa) { 1257 case BITSWAP: 1258 case WSBH: 1259 case SEB: 1260 case SEH: 1261 return kRegisterType; 1262 } 1263 sa >>= kBp2Bits; 1264 switch (sa) { 1265 case ALIGN: 1266 return kRegisterType; 1267 default: 1268 return kUnsupported; 1269 } 1270 } 1271 case DBSHFL: { 1272 int sa = SaFieldRaw() >> kSaShift; 1273 switch (sa) { 1274 case DBITSWAP: 1275 case DSBH: 1276 case DSHD: 1277 return kRegisterType; 1278 } 1279 sa = SaFieldRaw() >> kSaShift; 1280 sa >>= kBp3Bits; 1281 switch (sa) { 1282 case DALIGN: 1283 return kRegisterType; 1284 default: 1285 return kUnsupported; 1286 } 1287 } 1288 default: 1289 return kUnsupported; 1290 } 1291 break; 1292 case COP1: // Coprocessor instructions. 1293 switch (RsFieldRawNoAssert()) { 1294 case BC1: // Branch on coprocessor condition. 1295 case BC1EQZ: 1296 case BC1NEZ: 1297 return kImmediateType; 1298 default: 1299 return kRegisterType; 1300 } 1301 break; 1302 case COP1X: 1303 return kRegisterType; 1304 1305 // 26 bits immediate type instructions. e.g.: j imm26. 1306 case J: 1307 case JAL: 1308 return kJumpType; 1309 1310 default: 1311 return kImmediateType; 1312 } 1313 return kUnsupported; 1314 } 1315 #undef OpcodeToBitNumber 1316 #undef FunctionFieldToBitNumber 1317 1318 // ----------------------------------------------------------------------------- 1319 // Instructions. 1320 1321 template <class P> 1322 bool InstructionGetters<P>::IsLinkingInstruction() const { 1323 switch (OpcodeFieldRaw()) { 1324 case JAL: 1325 return true; 1326 case POP76: 1327 if (RsFieldRawNoAssert() == JIALC) 1328 return true; // JIALC 1329 else 1330 return false; // BNEZC 1331 case REGIMM: 1332 switch (RtFieldRaw()) { 1333 case BGEZAL: 1334 case BLTZAL: 1335 return true; 1336 default: 1337 return false; 1338 } 1339 case SPECIAL: 1340 switch (FunctionFieldRaw()) { 1341 case JALR: 1342 return true; 1343 default: 1344 return false; 1345 } 1346 default: 1347 return false; 1348 } 1349 } 1350 1351 template <class P> 1352 bool InstructionGetters<P>::IsTrap() const { 1353 if (OpcodeFieldRaw() != SPECIAL) { 1354 return false; 1355 } else { 1356 switch (FunctionFieldRaw()) { 1357 case BREAK: 1358 case TGE: 1359 case TGEU: 1360 case TLT: 1361 case TLTU: 1362 case TEQ: 1363 case TNE: 1364 return true; 1365 default: 1366 return false; 1367 } 1368 } 1369 } 1370 1371 // static 1372 template <class T> 1373 bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) { 1374 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask); 1375 switch (opcode) { 1376 case J: 1377 case JAL: 1378 case BEQ: 1379 case BNE: 1380 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc 1381 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc 1382 case BEQL: 1383 case BNEL: 1384 case BLEZL: // POP26 bgezc, blezc, bgec/blec 1385 case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc 1386 case BC: 1387 case BALC: 1388 case POP10: // beqzalc, bovc, beqc 1389 case POP30: // bnezalc, bnvc, bnec 1390 case POP66: // beqzc, jic 1391 case POP76: // bnezc, jialc 1392 return true; 1393 case REGIMM: 1394 switch (instr & kRtFieldMask) { 1395 case BLTZ: 1396 case BGEZ: 1397 case BLTZAL: 1398 case BGEZAL: 1399 return true; 1400 default: 1401 return false; 1402 } 1403 break; 1404 case SPECIAL: 1405 switch (instr & kFunctionFieldMask) { 1406 case JR: 1407 case JALR: 1408 return true; 1409 default: 1410 return false; 1411 } 1412 break; 1413 case COP1: 1414 switch (instr & kRsFieldMask) { 1415 case BC1: 1416 case BC1EQZ: 1417 case BC1NEZ: 1418 return true; 1419 break; 1420 default: 1421 return false; 1422 } 1423 break; 1424 default: 1425 return false; 1426 } 1427 } 1428 } // namespace internal 1429 } // namespace v8 1430 1431 #endif // #ifndef V8_MIPS_CONSTANTS_H_ 1432