1 // Copyright 2010 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_MIPS_CONSTANTS_H_ 29 #define V8_MIPS_CONSTANTS_H_ 30 31 // UNIMPLEMENTED_ macro for MIPS. 32 #ifdef DEBUG 33 #define UNIMPLEMENTED_MIPS() \ 34 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ 35 __FILE__, __LINE__, __func__) 36 #else 37 #define UNIMPLEMENTED_MIPS() 38 #endif 39 40 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") 41 42 43 #ifdef _MIPS_ARCH_MIPS32R2 44 #define mips32r2 1 45 #else 46 #define mips32r2 0 47 #endif 48 49 50 // Defines constants and accessor classes to assemble, disassemble and 51 // simulate MIPS32 instructions. 52 // 53 // See: MIPS32 Architecture For Programmers 54 // Volume II: The MIPS32 Instruction Set 55 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. 56 57 namespace v8 { 58 namespace internal { 59 60 // ----------------------------------------------------------------------------- 61 // Registers and FPURegister. 62 63 // Number of general purpose registers. 64 static const int kNumRegisters = 32; 65 static const int kInvalidRegister = -1; 66 67 // Number of registers with HI, LO, and pc. 68 static const int kNumSimuRegisters = 35; 69 70 // In the simulator, the PC register is simulated as the 34th register. 71 static const int kPCRegister = 34; 72 73 // Number coprocessor registers. 74 static const int kNumFPURegisters = 32; 75 static const int kInvalidFPURegister = -1; 76 77 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented. 78 static const int kFCSRRegister = 31; 79 static const int kInvalidFPUControlRegister = -1; 80 static const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1; 81 82 // FCSR constants. 83 static const uint32_t kFCSRFlagMask = (1 << 6) - 1; 84 static const uint32_t kFCSRFlagShift = 2; 85 86 // Helper functions for converting between register numbers and names. 87 class Registers { 88 public: 89 // Return the name of the register. 90 static const char* Name(int reg); 91 92 // Lookup the register number for the name provided. 93 static int Number(const char* name); 94 95 struct RegisterAlias { 96 int reg; 97 const char *name; 98 }; 99 100 static const int32_t kMaxValue = 0x7fffffff; 101 static const int32_t kMinValue = 0x80000000; 102 103 private: 104 105 static const char* names_[kNumSimuRegisters]; 106 static const RegisterAlias aliases_[]; 107 }; 108 109 // Helper functions for converting between register numbers and names. 110 class FPURegisters { 111 public: 112 // Return the name of the register. 113 static const char* Name(int reg); 114 115 // Lookup the register number for the name provided. 116 static int Number(const char* name); 117 118 struct RegisterAlias { 119 int creg; 120 const char *name; 121 }; 122 123 private: 124 125 static const char* names_[kNumFPURegisters]; 126 static const RegisterAlias aliases_[]; 127 }; 128 129 130 // ----------------------------------------------------------------------------- 131 // Instructions encoding constants. 132 133 // On MIPS all instructions are 32 bits. 134 typedef int32_t Instr; 135 136 typedef unsigned char byte_; 137 138 // Special Software Interrupt codes when used in the presence of the MIPS 139 // simulator. 140 enum SoftwareInterruptCodes { 141 // Transition to C code. 142 call_rt_redirected = 0xfffff 143 }; 144 145 // ----- Fields offset and length. 146 static const int kOpcodeShift = 26; 147 static const int kOpcodeBits = 6; 148 static const int kRsShift = 21; 149 static const int kRsBits = 5; 150 static const int kRtShift = 16; 151 static const int kRtBits = 5; 152 static const int kRdShift = 11; 153 static const int kRdBits = 5; 154 static const int kSaShift = 6; 155 static const int kSaBits = 5; 156 static const int kFunctionShift = 0; 157 static const int kFunctionBits = 6; 158 static const int kLuiShift = 16; 159 160 static const int kImm16Shift = 0; 161 static const int kImm16Bits = 16; 162 static const int kImm26Shift = 0; 163 static const int kImm26Bits = 26; 164 165 static const int kFsShift = 11; 166 static const int kFsBits = 5; 167 static const int kFtShift = 16; 168 static const int kFtBits = 5; 169 static const int kFdShift = 6; 170 static const int kFdBits = 5; 171 static const int kFCccShift = 8; 172 static const int kFCccBits = 3; 173 static const int kFBccShift = 18; 174 static const int kFBccBits = 3; 175 static const int kFBtrueShift = 16; 176 static const int kFBtrueBits = 1; 177 178 // ----- Miscellianous useful masks. 179 // Instruction bit masks. 180 static const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; 181 static const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; 182 static const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift; 183 static const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift; 184 static const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift; 185 static const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; 186 static const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; 187 static const int kFunctionFieldMask = 188 ((1 << kFunctionBits) - 1) << kFunctionShift; 189 // Misc masks. 190 static const int kHiMask = 0xffff << 16; 191 static const int kLoMask = 0xffff; 192 static const int kSignMask = 0x80000000; 193 194 195 // ----- MIPS Opcodes and Function Fields. 196 // We use this presentation to stay close to the table representation in 197 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. 198 enum Opcode { 199 SPECIAL = 0 << kOpcodeShift, 200 REGIMM = 1 << kOpcodeShift, 201 202 J = ((0 << 3) + 2) << kOpcodeShift, 203 JAL = ((0 << 3) + 3) << kOpcodeShift, 204 BEQ = ((0 << 3) + 4) << kOpcodeShift, 205 BNE = ((0 << 3) + 5) << kOpcodeShift, 206 BLEZ = ((0 << 3) + 6) << kOpcodeShift, 207 BGTZ = ((0 << 3) + 7) << kOpcodeShift, 208 209 ADDI = ((1 << 3) + 0) << kOpcodeShift, 210 ADDIU = ((1 << 3) + 1) << kOpcodeShift, 211 SLTI = ((1 << 3) + 2) << kOpcodeShift, 212 SLTIU = ((1 << 3) + 3) << kOpcodeShift, 213 ANDI = ((1 << 3) + 4) << kOpcodeShift, 214 ORI = ((1 << 3) + 5) << kOpcodeShift, 215 XORI = ((1 << 3) + 6) << kOpcodeShift, 216 LUI = ((1 << 3) + 7) << kOpcodeShift, 217 218 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class 219 BEQL = ((2 << 3) + 4) << kOpcodeShift, 220 BNEL = ((2 << 3) + 5) << kOpcodeShift, 221 BLEZL = ((2 << 3) + 6) << kOpcodeShift, 222 BGTZL = ((2 << 3) + 7) << kOpcodeShift, 223 224 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, 225 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift, 226 227 LB = ((4 << 3) + 0) << kOpcodeShift, 228 LH = ((4 << 3) + 1) << kOpcodeShift, 229 LWL = ((4 << 3) + 2) << kOpcodeShift, 230 LW = ((4 << 3) + 3) << kOpcodeShift, 231 LBU = ((4 << 3) + 4) << kOpcodeShift, 232 LHU = ((4 << 3) + 5) << kOpcodeShift, 233 LWR = ((4 << 3) + 6) << kOpcodeShift, 234 SB = ((5 << 3) + 0) << kOpcodeShift, 235 SH = ((5 << 3) + 1) << kOpcodeShift, 236 SWL = ((5 << 3) + 2) << kOpcodeShift, 237 SW = ((5 << 3) + 3) << kOpcodeShift, 238 SWR = ((5 << 3) + 6) << kOpcodeShift, 239 240 LWC1 = ((6 << 3) + 1) << kOpcodeShift, 241 LDC1 = ((6 << 3) + 5) << kOpcodeShift, 242 243 SWC1 = ((7 << 3) + 1) << kOpcodeShift, 244 SDC1 = ((7 << 3) + 5) << kOpcodeShift 245 }; 246 247 enum SecondaryField { 248 // SPECIAL Encoding of Function Field. 249 SLL = ((0 << 3) + 0), 250 SRL = ((0 << 3) + 2), 251 SRA = ((0 << 3) + 3), 252 SLLV = ((0 << 3) + 4), 253 SRLV = ((0 << 3) + 6), 254 SRAV = ((0 << 3) + 7), 255 MOVCI = ((0 << 3) + 1), 256 257 JR = ((1 << 3) + 0), 258 JALR = ((1 << 3) + 1), 259 MOVZ = ((1 << 3) + 2), 260 MOVN = ((1 << 3) + 3), 261 BREAK = ((1 << 3) + 5), 262 263 MFHI = ((2 << 3) + 0), 264 MFLO = ((2 << 3) + 2), 265 266 MULT = ((3 << 3) + 0), 267 MULTU = ((3 << 3) + 1), 268 DIV = ((3 << 3) + 2), 269 DIVU = ((3 << 3) + 3), 270 271 ADD = ((4 << 3) + 0), 272 ADDU = ((4 << 3) + 1), 273 SUB = ((4 << 3) + 2), 274 SUBU = ((4 << 3) + 3), 275 AND = ((4 << 3) + 4), 276 OR = ((4 << 3) + 5), 277 XOR = ((4 << 3) + 6), 278 NOR = ((4 << 3) + 7), 279 280 SLT = ((5 << 3) + 2), 281 SLTU = ((5 << 3) + 3), 282 283 TGE = ((6 << 3) + 0), 284 TGEU = ((6 << 3) + 1), 285 TLT = ((6 << 3) + 2), 286 TLTU = ((6 << 3) + 3), 287 TEQ = ((6 << 3) + 4), 288 TNE = ((6 << 3) + 6), 289 290 // SPECIAL2 Encoding of Function Field. 291 MUL = ((0 << 3) + 2), 292 CLZ = ((4 << 3) + 0), 293 CLO = ((4 << 3) + 1), 294 295 // SPECIAL3 Encoding of Function Field. 296 EXT = ((0 << 3) + 0), 297 INS = ((0 << 3) + 4), 298 299 // REGIMM encoding of rt Field. 300 BLTZ = ((0 << 3) + 0) << 16, 301 BGEZ = ((0 << 3) + 1) << 16, 302 BLTZAL = ((2 << 3) + 0) << 16, 303 BGEZAL = ((2 << 3) + 1) << 16, 304 305 // COP1 Encoding of rs Field. 306 MFC1 = ((0 << 3) + 0) << 21, 307 CFC1 = ((0 << 3) + 2) << 21, 308 MFHC1 = ((0 << 3) + 3) << 21, 309 MTC1 = ((0 << 3) + 4) << 21, 310 CTC1 = ((0 << 3) + 6) << 21, 311 MTHC1 = ((0 << 3) + 7) << 21, 312 BC1 = ((1 << 3) + 0) << 21, 313 S = ((2 << 3) + 0) << 21, 314 D = ((2 << 3) + 1) << 21, 315 W = ((2 << 3) + 4) << 21, 316 L = ((2 << 3) + 5) << 21, 317 PS = ((2 << 3) + 6) << 21, 318 // COP1 Encoding of Function Field When rs=S. 319 ROUND_L_S = ((1 << 3) + 0), 320 TRUNC_L_S = ((1 << 3) + 1), 321 CEIL_L_S = ((1 << 3) + 2), 322 FLOOR_L_S = ((1 << 3) + 3), 323 ROUND_W_S = ((1 << 3) + 4), 324 TRUNC_W_S = ((1 << 3) + 5), 325 CEIL_W_S = ((1 << 3) + 6), 326 FLOOR_W_S = ((1 << 3) + 7), 327 CVT_D_S = ((4 << 3) + 1), 328 CVT_W_S = ((4 << 3) + 4), 329 CVT_L_S = ((4 << 3) + 5), 330 CVT_PS_S = ((4 << 3) + 6), 331 // COP1 Encoding of Function Field When rs=D. 332 ADD_D = ((0 << 3) + 0), 333 SUB_D = ((0 << 3) + 1), 334 MUL_D = ((0 << 3) + 2), 335 DIV_D = ((0 << 3) + 3), 336 SQRT_D = ((0 << 3) + 4), 337 ABS_D = ((0 << 3) + 5), 338 MOV_D = ((0 << 3) + 6), 339 NEG_D = ((0 << 3) + 7), 340 ROUND_L_D = ((1 << 3) + 0), 341 TRUNC_L_D = ((1 << 3) + 1), 342 CEIL_L_D = ((1 << 3) + 2), 343 FLOOR_L_D = ((1 << 3) + 3), 344 ROUND_W_D = ((1 << 3) + 4), 345 TRUNC_W_D = ((1 << 3) + 5), 346 CEIL_W_D = ((1 << 3) + 6), 347 FLOOR_W_D = ((1 << 3) + 7), 348 CVT_S_D = ((4 << 3) + 0), 349 CVT_W_D = ((4 << 3) + 4), 350 CVT_L_D = ((4 << 3) + 5), 351 C_F_D = ((6 << 3) + 0), 352 C_UN_D = ((6 << 3) + 1), 353 C_EQ_D = ((6 << 3) + 2), 354 C_UEQ_D = ((6 << 3) + 3), 355 C_OLT_D = ((6 << 3) + 4), 356 C_ULT_D = ((6 << 3) + 5), 357 C_OLE_D = ((6 << 3) + 6), 358 C_ULE_D = ((6 << 3) + 7), 359 // COP1 Encoding of Function Field When rs=W or L. 360 CVT_S_W = ((4 << 3) + 0), 361 CVT_D_W = ((4 << 3) + 1), 362 CVT_S_L = ((4 << 3) + 0), 363 CVT_D_L = ((4 << 3) + 1), 364 // COP1 Encoding of Function Field When rs=PS. 365 366 NULLSF = 0 367 }; 368 369 370 // ----- Emulated conditions. 371 // On MIPS we use this enum to abstract from conditionnal branch instructions. 372 // the 'U' prefix is used to specify unsigned comparisons. 373 enum Condition { 374 // Any value < 0 is considered no_condition. 375 kNoCondition = -1, 376 377 overflow = 0, 378 no_overflow = 1, 379 Uless = 2, 380 Ugreater_equal= 3, 381 equal = 4, 382 not_equal = 5, 383 Uless_equal = 6, 384 Ugreater = 7, 385 negative = 8, 386 positive = 9, 387 parity_even = 10, 388 parity_odd = 11, 389 less = 12, 390 greater_equal = 13, 391 less_equal = 14, 392 greater = 15, 393 394 cc_always = 16, 395 396 // aliases 397 carry = Uless, 398 not_carry = Ugreater_equal, 399 zero = equal, 400 eq = equal, 401 not_zero = not_equal, 402 ne = not_equal, 403 nz = not_equal, 404 sign = negative, 405 not_sign = positive, 406 mi = negative, 407 pl = positive, 408 hi = Ugreater, 409 ls = Uless_equal, 410 ge = greater_equal, 411 lt = less, 412 gt = greater, 413 le = less_equal, 414 hs = Ugreater_equal, 415 lo = Uless, 416 al = cc_always, 417 418 cc_default = kNoCondition 419 }; 420 421 422 // Returns the equivalent of !cc. 423 // Negation of the default kNoCondition (-1) results in a non-default 424 // no_condition value (-2). As long as tests for no_condition check 425 // for condition < 0, this will work as expected. 426 inline Condition NegateCondition(Condition cc) { 427 ASSERT(cc != cc_always); 428 return static_cast<Condition>(cc ^ 1); 429 } 430 431 432 inline Condition ReverseCondition(Condition cc) { 433 switch (cc) { 434 case Uless: 435 return Ugreater; 436 case Ugreater: 437 return Uless; 438 case Ugreater_equal: 439 return Uless_equal; 440 case Uless_equal: 441 return Ugreater_equal; 442 case less: 443 return greater; 444 case greater: 445 return less; 446 case greater_equal: 447 return less_equal; 448 case less_equal: 449 return greater_equal; 450 default: 451 return cc; 452 }; 453 } 454 455 456 // ----- Coprocessor conditions. 457 enum FPUCondition { 458 F, // False 459 UN, // Unordered 460 EQ, // Equal 461 UEQ, // Unordered or Equal 462 OLT, // Ordered or Less Than 463 ULT, // Unordered or Less Than 464 OLE, // Ordered or Less Than or Equal 465 ULE // Unordered or Less Than or Equal 466 }; 467 468 469 // ----------------------------------------------------------------------------- 470 // Hints. 471 472 // Branch hints are not used on the MIPS. They are defined so that they can 473 // appear in shared function signatures, but will be ignored in MIPS 474 // implementations. 475 enum Hint { 476 no_hint = 0 477 }; 478 479 480 inline Hint NegateHint(Hint hint) { 481 return no_hint; 482 } 483 484 485 // ----------------------------------------------------------------------------- 486 // Specific instructions, constants, and masks. 487 // These constants are declared in assembler-mips.cc, as they use named 488 // registers and other constants. 489 490 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) 491 // operations as post-increment of sp. 492 extern const Instr kPopInstruction; 493 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. 494 extern const Instr kPushInstruction; 495 // sw(r, MemOperand(sp, 0)) 496 extern const Instr kPushRegPattern; 497 // lw(r, MemOperand(sp, 0)) 498 extern const Instr kPopRegPattern; 499 extern const Instr kLwRegFpOffsetPattern; 500 extern const Instr kSwRegFpOffsetPattern; 501 extern const Instr kLwRegFpNegOffsetPattern; 502 extern const Instr kSwRegFpNegOffsetPattern; 503 // A mask for the Rt register for push, pop, lw, sw instructions. 504 extern const Instr kRtMask; 505 extern const Instr kLwSwInstrTypeMask; 506 extern const Instr kLwSwInstrArgumentMask; 507 extern const Instr kLwSwOffsetMask; 508 509 // Break 0xfffff, reserved for redirected real time call. 510 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; 511 // A nop instruction. (Encoding of sll 0 0 0). 512 const Instr nopInstr = 0; 513 514 class Instruction { 515 public: 516 enum { 517 kInstrSize = 4, 518 kInstrSizeLog2 = 2, 519 // On MIPS PC cannot actually be directly accessed. We behave as if PC was 520 // always the value of the current instruction being executed. 521 kPCReadOffset = 0 522 }; 523 524 // Get the raw instruction bits. 525 inline Instr InstructionBits() const { 526 return *reinterpret_cast<const Instr*>(this); 527 } 528 529 // Set the raw instruction bits to value. 530 inline void SetInstructionBits(Instr value) { 531 *reinterpret_cast<Instr*>(this) = value; 532 } 533 534 // Read one particular bit out of the instruction bits. 535 inline int Bit(int nr) const { 536 return (InstructionBits() >> nr) & 1; 537 } 538 539 // Read a bit field out of the instruction bits. 540 inline int Bits(int hi, int lo) const { 541 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); 542 } 543 544 // Instruction type. 545 enum Type { 546 kRegisterType, 547 kImmediateType, 548 kJumpType, 549 kUnsupported = -1 550 }; 551 552 // Get the encoding type of the instruction. 553 Type InstructionType() const; 554 555 556 // Accessors for the different named fields used in the MIPS encoding. 557 inline Opcode OpcodeValue() const { 558 return static_cast<Opcode>( 559 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); 560 } 561 562 inline int RsValue() const { 563 ASSERT(InstructionType() == kRegisterType || 564 InstructionType() == kImmediateType); 565 return Bits(kRsShift + kRsBits - 1, kRsShift); 566 } 567 568 inline int RtValue() const { 569 ASSERT(InstructionType() == kRegisterType || 570 InstructionType() == kImmediateType); 571 return Bits(kRtShift + kRtBits - 1, kRtShift); 572 } 573 574 inline int RdValue() const { 575 ASSERT(InstructionType() == kRegisterType); 576 return Bits(kRdShift + kRdBits - 1, kRdShift); 577 } 578 579 inline int SaValue() const { 580 ASSERT(InstructionType() == kRegisterType); 581 return Bits(kSaShift + kSaBits - 1, kSaShift); 582 } 583 584 inline int FunctionValue() const { 585 ASSERT(InstructionType() == kRegisterType || 586 InstructionType() == kImmediateType); 587 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); 588 } 589 590 inline int FdValue() const { 591 return Bits(kFdShift + kFdBits - 1, kFdShift); 592 } 593 594 inline int FsValue() const { 595 return Bits(kFsShift + kFsBits - 1, kFsShift); 596 } 597 598 inline int FtValue() const { 599 return Bits(kFtShift + kFtBits - 1, kFtShift); 600 } 601 602 // Float Compare condition code instruction bits. 603 inline int FCccValue() const { 604 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); 605 } 606 607 // Float Branch condition code instruction bits. 608 inline int FBccValue() const { 609 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); 610 } 611 612 // Float Branch true/false instruction bit. 613 inline int FBtrueValue() const { 614 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); 615 } 616 617 // Return the fields at their original place in the instruction encoding. 618 inline Opcode OpcodeFieldRaw() const { 619 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); 620 } 621 622 inline int RsFieldRaw() const { 623 ASSERT(InstructionType() == kRegisterType || 624 InstructionType() == kImmediateType); 625 return InstructionBits() & kRsFieldMask; 626 } 627 628 // Same as above function, but safe to call within InstructionType(). 629 inline int RsFieldRawNoAssert() const { 630 return InstructionBits() & kRsFieldMask; 631 } 632 633 inline int RtFieldRaw() const { 634 ASSERT(InstructionType() == kRegisterType || 635 InstructionType() == kImmediateType); 636 return InstructionBits() & kRtFieldMask; 637 } 638 639 inline int RdFieldRaw() const { 640 ASSERT(InstructionType() == kRegisterType); 641 return InstructionBits() & kRdFieldMask; 642 } 643 644 inline int SaFieldRaw() const { 645 ASSERT(InstructionType() == kRegisterType); 646 return InstructionBits() & kSaFieldMask; 647 } 648 649 inline int FunctionFieldRaw() const { 650 return InstructionBits() & kFunctionFieldMask; 651 } 652 653 // Get the secondary field according to the opcode. 654 inline int SecondaryValue() const { 655 Opcode op = OpcodeFieldRaw(); 656 switch (op) { 657 case SPECIAL: 658 case SPECIAL2: 659 return FunctionValue(); 660 case COP1: 661 return RsValue(); 662 case REGIMM: 663 return RtValue(); 664 default: 665 return NULLSF; 666 } 667 } 668 669 inline int32_t Imm16Value() const { 670 ASSERT(InstructionType() == kImmediateType); 671 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); 672 } 673 674 inline int32_t Imm26Value() const { 675 ASSERT(InstructionType() == kJumpType); 676 return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift); 677 } 678 679 // Say if the instruction should not be used in a branch delay slot. 680 bool IsForbiddenInBranchDelay() const; 681 // Say if the instruction 'links'. eg: jal, bal. 682 bool IsLinkingInstruction() const; 683 // Say if the instruction is a break or a trap. 684 bool IsTrap() const; 685 686 // Instructions are read of out a code stream. The only way to get a 687 // reference to an instruction is to convert a pointer. There is no way 688 // to allocate or create instances of class Instruction. 689 // Use the At(pc) function to create references to Instruction. 690 static Instruction* At(byte_* pc) { 691 return reinterpret_cast<Instruction*>(pc); 692 } 693 694 private: 695 // We need to prevent the creation of instances of class Instruction. 696 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); 697 }; 698 699 700 // ----------------------------------------------------------------------------- 701 // MIPS assembly various constants. 702 703 704 static const int kArgsSlotsSize = 4 * Instruction::kInstrSize; 705 static const int kArgsSlotsNum = 4; 706 // C/C++ argument slots size. 707 static const int kCArgsSlotsSize = 4 * Instruction::kInstrSize; 708 // JS argument slots size. 709 static const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; 710 // Assembly builtins argument slots size. 711 static const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; 712 713 static const int kBranchReturnOffset = 2 * Instruction::kInstrSize; 714 715 static const int kDoubleAlignmentBits = 3; 716 static const int kDoubleAlignment = (1 << kDoubleAlignmentBits); 717 static const int kDoubleAlignmentMask = kDoubleAlignment - 1; 718 719 720 } } // namespace v8::internal 721 722 #endif // #ifndef V8_MIPS_CONSTANTS_H_ 723 724