1 // Copyright 2012 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
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.
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.
28 #ifndef V8_MIPS_CONSTANTS_H_
29 #define V8_MIPS_CONSTANTS_H_
31 // UNIMPLEMENTED_ macro for MIPS.
33 #define UNIMPLEMENTED_MIPS() \
34 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
35 __FILE__, __LINE__, __func__)
37 #define UNIMPLEMENTED_MIPS()
40 #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")
48 #ifdef _MIPS_ARCH_MIPS32R2
49 static const ArchVariants kArchVariant = kMips32r2;
50 #elif _MIPS_ARCH_LOONGSON
51 // The loongson flag refers to the LOONGSON architectures based on MIPS-III,
52 // which predates (and is a subset of) the mips32r2 and r1 architectures.
53 static const ArchVariants kArchVariant = kLoongson;
55 static const ArchVariants kArchVariant = kMips32r1;
59 #if(defined(__mips_hard_float) && __mips_hard_float != 0)
60 // Use floating-point coprocessor instructions. This flag is raised when
61 // -mhard-float is passed to the compiler.
62 const bool IsMipsSoftFloatABI = false;
63 #elif(defined(__mips_soft_float) && __mips_soft_float != 0)
64 // Not using floating-point coprocessor instructions. This flag is raised when
65 // -msoft-float is passed to the compiler.
66 const bool IsMipsSoftFloatABI = true;
68 const bool IsMipsSoftFloatABI = true;
72 // Defines constants and accessor classes to assemble, disassemble and
73 // simulate MIPS32 instructions.
75 // See: MIPS32 Architecture For Programmers
76 // Volume II: The MIPS32 Instruction Set
77 // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf.
82 // -----------------------------------------------------------------------------
83 // Registers and FPURegisters.
85 // Number of general purpose registers.
86 const int kNumRegisters = 32;
87 const int kInvalidRegister = -1;
89 // Number of registers with HI, LO, and pc.
90 const int kNumSimuRegisters = 35;
92 // In the simulator, the PC register is simulated as the 34th register.
93 const int kPCRegister = 34;
95 // Number coprocessor registers.
96 const int kNumFPURegisters = 32;
97 const int kInvalidFPURegister = -1;
99 // FPU (coprocessor 1) control registers. Currently only FCSR is implemented.
100 const int kFCSRRegister = 31;
101 const int kInvalidFPUControlRegister = -1;
102 const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1;
105 const uint32_t kFCSRInexactFlagBit = 2;
106 const uint32_t kFCSRUnderflowFlagBit = 3;
107 const uint32_t kFCSROverflowFlagBit = 4;
108 const uint32_t kFCSRDivideByZeroFlagBit = 5;
109 const uint32_t kFCSRInvalidOpFlagBit = 6;
111 const uint32_t kFCSRInexactFlagMask = 1 << kFCSRInexactFlagBit;
112 const uint32_t kFCSRUnderflowFlagMask = 1 << kFCSRUnderflowFlagBit;
113 const uint32_t kFCSROverflowFlagMask = 1 << kFCSROverflowFlagBit;
114 const uint32_t kFCSRDivideByZeroFlagMask = 1 << kFCSRDivideByZeroFlagBit;
115 const uint32_t kFCSRInvalidOpFlagMask = 1 << kFCSRInvalidOpFlagBit;
117 const uint32_t kFCSRFlagMask =
118 kFCSRInexactFlagMask |
119 kFCSRUnderflowFlagMask |
120 kFCSROverflowFlagMask |
121 kFCSRDivideByZeroFlagMask |
122 kFCSRInvalidOpFlagMask;
124 const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
126 // Helper functions for converting between register numbers and names.
129 // Return the name of the register.
130 static const char* Name(int reg);
132 // Lookup the register number for the name provided.
133 static int Number(const char* name);
135 struct RegisterAlias {
140 static const int32_t kMaxValue = 0x7fffffff;
141 static const int32_t kMinValue = 0x80000000;
144 static const char* names_[kNumSimuRegisters];
145 static const RegisterAlias aliases_[];
148 // Helper functions for converting between register numbers and names.
151 // Return the name of the register.
152 static const char* Name(int reg);
154 // Lookup the register number for the name provided.
155 static int Number(const char* name);
157 struct RegisterAlias {
163 static const char* names_[kNumFPURegisters];
164 static const RegisterAlias aliases_[];
168 // -----------------------------------------------------------------------------
169 // Instructions encoding constants.
171 // On MIPS all instructions are 32 bits.
172 typedef int32_t Instr;
174 // Special Software Interrupt codes when used in the presence of the MIPS
176 enum SoftwareInterruptCodes {
177 // Transition to C code.
178 call_rt_redirected = 0xfffff
181 // On MIPS Simulator breakpoints can have different codes:
182 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
183 // the simulator will run through them and print the registers.
184 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
185 // instructions (see Assembler::stop()).
186 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
188 const uint32_t kMaxWatchpointCode = 31;
189 const uint32_t kMaxStopCode = 127;
190 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
193 // ----- Fields offset and length.
194 const int kOpcodeShift = 26;
195 const int kOpcodeBits = 6;
196 const int kRsShift = 21;
197 const int kRsBits = 5;
198 const int kRtShift = 16;
199 const int kRtBits = 5;
200 const int kRdShift = 11;
201 const int kRdBits = 5;
202 const int kSaShift = 6;
203 const int kSaBits = 5;
204 const int kFunctionShift = 0;
205 const int kFunctionBits = 6;
206 const int kLuiShift = 16;
208 const int kImm16Shift = 0;
209 const int kImm16Bits = 16;
210 const int kImm26Shift = 0;
211 const int kImm26Bits = 26;
212 const int kImm28Shift = 0;
213 const int kImm28Bits = 28;
215 // In branches and jumps immediate fields point to words, not bytes,
216 // and are therefore shifted by 2.
217 const int kImmFieldShift = 2;
219 const int kFsShift = 11;
220 const int kFsBits = 5;
221 const int kFtShift = 16;
222 const int kFtBits = 5;
223 const int kFdShift = 6;
224 const int kFdBits = 5;
225 const int kFCccShift = 8;
226 const int kFCccBits = 3;
227 const int kFBccShift = 18;
228 const int kFBccBits = 3;
229 const int kFBtrueShift = 16;
230 const int kFBtrueBits = 1;
232 // ----- Miscellaneous useful masks.
233 // Instruction bit masks.
234 const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
235 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
236 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
237 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
238 const int kRsFieldMask = ((1 << kRsBits) - 1) << kRsShift;
239 const int kRtFieldMask = ((1 << kRtBits) - 1) << kRtShift;
240 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
241 const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift;
242 const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift;
244 const int kHiMask = 0xffff << 16;
245 const int kLoMask = 0xffff;
246 const int kSignMask = 0x80000000;
247 const int kJumpAddrMask = (1 << (kImm26Bits + kImmFieldShift)) - 1;
249 // ----- MIPS Opcodes and Function Fields.
250 // We use this presentation to stay close to the table representation in
251 // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set.
253 SPECIAL = 0 << kOpcodeShift,
254 REGIMM = 1 << kOpcodeShift,
256 J = ((0 << 3) + 2) << kOpcodeShift,
257 JAL = ((0 << 3) + 3) << kOpcodeShift,
258 BEQ = ((0 << 3) + 4) << kOpcodeShift,
259 BNE = ((0 << 3) + 5) << kOpcodeShift,
260 BLEZ = ((0 << 3) + 6) << kOpcodeShift,
261 BGTZ = ((0 << 3) + 7) << kOpcodeShift,
263 ADDI = ((1 << 3) + 0) << kOpcodeShift,
264 ADDIU = ((1 << 3) + 1) << kOpcodeShift,
265 SLTI = ((1 << 3) + 2) << kOpcodeShift,
266 SLTIU = ((1 << 3) + 3) << kOpcodeShift,
267 ANDI = ((1 << 3) + 4) << kOpcodeShift,
268 ORI = ((1 << 3) + 5) << kOpcodeShift,
269 XORI = ((1 << 3) + 6) << kOpcodeShift,
270 LUI = ((1 << 3) + 7) << kOpcodeShift,
272 COP1 = ((2 << 3) + 1) << kOpcodeShift, // Coprocessor 1 class.
273 BEQL = ((2 << 3) + 4) << kOpcodeShift,
274 BNEL = ((2 << 3) + 5) << kOpcodeShift,
275 BLEZL = ((2 << 3) + 6) << kOpcodeShift,
276 BGTZL = ((2 << 3) + 7) << kOpcodeShift,
278 SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
279 SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
281 LB = ((4 << 3) + 0) << kOpcodeShift,
282 LH = ((4 << 3) + 1) << kOpcodeShift,
283 LWL = ((4 << 3) + 2) << kOpcodeShift,
284 LW = ((4 << 3) + 3) << kOpcodeShift,
285 LBU = ((4 << 3) + 4) << kOpcodeShift,
286 LHU = ((4 << 3) + 5) << kOpcodeShift,
287 LWR = ((4 << 3) + 6) << kOpcodeShift,
288 SB = ((5 << 3) + 0) << kOpcodeShift,
289 SH = ((5 << 3) + 1) << kOpcodeShift,
290 SWL = ((5 << 3) + 2) << kOpcodeShift,
291 SW = ((5 << 3) + 3) << kOpcodeShift,
292 SWR = ((5 << 3) + 6) << kOpcodeShift,
294 LWC1 = ((6 << 3) + 1) << kOpcodeShift,
295 LDC1 = ((6 << 3) + 5) << kOpcodeShift,
297 SWC1 = ((7 << 3) + 1) << kOpcodeShift,
298 SDC1 = ((7 << 3) + 5) << kOpcodeShift
301 enum SecondaryField {
302 // SPECIAL Encoding of Function Field.
303 SLL = ((0 << 3) + 0),
304 MOVCI = ((0 << 3) + 1),
305 SRL = ((0 << 3) + 2),
306 SRA = ((0 << 3) + 3),
307 SLLV = ((0 << 3) + 4),
308 SRLV = ((0 << 3) + 6),
309 SRAV = ((0 << 3) + 7),
312 JALR = ((1 << 3) + 1),
313 MOVZ = ((1 << 3) + 2),
314 MOVN = ((1 << 3) + 3),
315 BREAK = ((1 << 3) + 5),
317 MFHI = ((2 << 3) + 0),
318 MFLO = ((2 << 3) + 2),
320 MULT = ((3 << 3) + 0),
321 MULTU = ((3 << 3) + 1),
322 DIV = ((3 << 3) + 2),
323 DIVU = ((3 << 3) + 3),
325 ADD = ((4 << 3) + 0),
326 ADDU = ((4 << 3) + 1),
327 SUB = ((4 << 3) + 2),
328 SUBU = ((4 << 3) + 3),
329 AND = ((4 << 3) + 4),
331 XOR = ((4 << 3) + 6),
332 NOR = ((4 << 3) + 7),
334 SLT = ((5 << 3) + 2),
335 SLTU = ((5 << 3) + 3),
337 TGE = ((6 << 3) + 0),
338 TGEU = ((6 << 3) + 1),
339 TLT = ((6 << 3) + 2),
340 TLTU = ((6 << 3) + 3),
341 TEQ = ((6 << 3) + 4),
342 TNE = ((6 << 3) + 6),
344 // SPECIAL2 Encoding of Function Field.
345 MUL = ((0 << 3) + 2),
346 CLZ = ((4 << 3) + 0),
347 CLO = ((4 << 3) + 1),
349 // SPECIAL3 Encoding of Function Field.
350 EXT = ((0 << 3) + 0),
351 INS = ((0 << 3) + 4),
353 // REGIMM encoding of rt Field.
354 BLTZ = ((0 << 3) + 0) << 16,
355 BGEZ = ((0 << 3) + 1) << 16,
356 BLTZAL = ((2 << 3) + 0) << 16,
357 BGEZAL = ((2 << 3) + 1) << 16,
359 // COP1 Encoding of rs Field.
360 MFC1 = ((0 << 3) + 0) << 21,
361 CFC1 = ((0 << 3) + 2) << 21,
362 MFHC1 = ((0 << 3) + 3) << 21,
363 MTC1 = ((0 << 3) + 4) << 21,
364 CTC1 = ((0 << 3) + 6) << 21,
365 MTHC1 = ((0 << 3) + 7) << 21,
366 BC1 = ((1 << 3) + 0) << 21,
367 S = ((2 << 3) + 0) << 21,
368 D = ((2 << 3) + 1) << 21,
369 W = ((2 << 3) + 4) << 21,
370 L = ((2 << 3) + 5) << 21,
371 PS = ((2 << 3) + 6) << 21,
372 // COP1 Encoding of Function Field When rs=S.
373 ROUND_L_S = ((1 << 3) + 0),
374 TRUNC_L_S = ((1 << 3) + 1),
375 CEIL_L_S = ((1 << 3) + 2),
376 FLOOR_L_S = ((1 << 3) + 3),
377 ROUND_W_S = ((1 << 3) + 4),
378 TRUNC_W_S = ((1 << 3) + 5),
379 CEIL_W_S = ((1 << 3) + 6),
380 FLOOR_W_S = ((1 << 3) + 7),
381 CVT_D_S = ((4 << 3) + 1),
382 CVT_W_S = ((4 << 3) + 4),
383 CVT_L_S = ((4 << 3) + 5),
384 CVT_PS_S = ((4 << 3) + 6),
385 // COP1 Encoding of Function Field When rs=D.
386 ADD_D = ((0 << 3) + 0),
387 SUB_D = ((0 << 3) + 1),
388 MUL_D = ((0 << 3) + 2),
389 DIV_D = ((0 << 3) + 3),
390 SQRT_D = ((0 << 3) + 4),
391 ABS_D = ((0 << 3) + 5),
392 MOV_D = ((0 << 3) + 6),
393 NEG_D = ((0 << 3) + 7),
394 ROUND_L_D = ((1 << 3) + 0),
395 TRUNC_L_D = ((1 << 3) + 1),
396 CEIL_L_D = ((1 << 3) + 2),
397 FLOOR_L_D = ((1 << 3) + 3),
398 ROUND_W_D = ((1 << 3) + 4),
399 TRUNC_W_D = ((1 << 3) + 5),
400 CEIL_W_D = ((1 << 3) + 6),
401 FLOOR_W_D = ((1 << 3) + 7),
402 CVT_S_D = ((4 << 3) + 0),
403 CVT_W_D = ((4 << 3) + 4),
404 CVT_L_D = ((4 << 3) + 5),
405 C_F_D = ((6 << 3) + 0),
406 C_UN_D = ((6 << 3) + 1),
407 C_EQ_D = ((6 << 3) + 2),
408 C_UEQ_D = ((6 << 3) + 3),
409 C_OLT_D = ((6 << 3) + 4),
410 C_ULT_D = ((6 << 3) + 5),
411 C_OLE_D = ((6 << 3) + 6),
412 C_ULE_D = ((6 << 3) + 7),
413 // COP1 Encoding of Function Field When rs=W or L.
414 CVT_S_W = ((4 << 3) + 0),
415 CVT_D_W = ((4 << 3) + 1),
416 CVT_S_L = ((4 << 3) + 0),
417 CVT_D_L = ((4 << 3) + 1),
418 // COP1 Encoding of Function Field When rs=PS.
424 // ----- Emulated conditions.
425 // On MIPS we use this enum to abstract from conditionnal branch instructions.
426 // the 'U' prefix is used to specify unsigned comparisons.
428 // Any value < 0 is considered no_condition.
452 not_carry = Ugreater_equal,
455 not_zero = not_equal,
472 cc_default = kNoCondition
476 // Returns the equivalent of !cc.
477 // Negation of the default kNoCondition (-1) results in a non-default
478 // no_condition value (-2). As long as tests for no_condition check
479 // for condition < 0, this will work as expected.
480 inline Condition NegateCondition(Condition cc) {
481 ASSERT(cc != cc_always);
482 return static_cast<Condition>(cc ^ 1);
486 inline Condition ReverseCondition(Condition cc) {
495 return Ugreater_equal;
503 return greater_equal;
510 // ----- Coprocessor conditions.
512 kNoFPUCondition = -1,
515 UN = 1, // Unordered.
517 UEQ = 3, // Unordered or Equal.
518 OLT = 4, // Ordered or Less Than.
519 ULT = 5, // Unordered or Less Than.
520 OLE = 6, // Ordered or Less Than or Equal.
521 ULE = 7 // Unordered or Less Than or Equal.
525 // FPU rounding modes.
526 enum FPURoundingMode {
527 RN = 0 << 0, // Round to Nearest.
528 RZ = 1 << 0, // Round towards zero.
529 RP = 2 << 0, // Round towards Plus Infinity.
530 RM = 3 << 0, // Round towards Minus Infinity.
533 kRoundToNearest = RN,
535 kRoundToPlusInf = RP,
536 kRoundToMinusInf = RM
539 const uint32_t kFPURoundingModeMask = 3 << 0;
541 enum CheckForInexactConversion {
542 kCheckForInexactConversion,
543 kDontCheckForInexactConversion
547 // -----------------------------------------------------------------------------
550 // Branch hints are not used on the MIPS. They are defined so that they can
551 // appear in shared function signatures, but will be ignored in MIPS
558 inline Hint NegateHint(Hint hint) {
563 // -----------------------------------------------------------------------------
564 // Specific instructions, constants, and masks.
565 // These constants are declared in assembler-mips.cc, as they use named
566 // registers and other constants.
568 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
569 // operations as post-increment of sp.
570 extern const Instr kPopInstruction;
571 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
572 extern const Instr kPushInstruction;
573 // sw(r, MemOperand(sp, 0))
574 extern const Instr kPushRegPattern;
575 // lw(r, MemOperand(sp, 0))
576 extern const Instr kPopRegPattern;
577 extern const Instr kLwRegFpOffsetPattern;
578 extern const Instr kSwRegFpOffsetPattern;
579 extern const Instr kLwRegFpNegOffsetPattern;
580 extern const Instr kSwRegFpNegOffsetPattern;
581 // A mask for the Rt register for push, pop, lw, sw instructions.
582 extern const Instr kRtMask;
583 extern const Instr kLwSwInstrTypeMask;
584 extern const Instr kLwSwInstrArgumentMask;
585 extern const Instr kLwSwOffsetMask;
587 // Break 0xfffff, reserved for redirected real time call.
588 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6;
589 // A nop instruction. (Encoding of sll 0 0 0).
590 const Instr nopInstr = 0;
597 // On MIPS PC cannot actually be directly accessed. We behave as if PC was
598 // always the value of the current instruction being executed.
602 // Get the raw instruction bits.
603 inline Instr InstructionBits() const {
604 return *reinterpret_cast<const Instr*>(this);
607 // Set the raw instruction bits to value.
608 inline void SetInstructionBits(Instr value) {
609 *reinterpret_cast<Instr*>(this) = value;
612 // Read one particular bit out of the instruction bits.
613 inline int Bit(int nr) const {
614 return (InstructionBits() >> nr) & 1;
617 // Read a bit field out of the instruction bits.
618 inline int Bits(int hi, int lo) const {
619 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
630 // Get the encoding type of the instruction.
631 Type InstructionType() const;
634 // Accessors for the different named fields used in the MIPS encoding.
635 inline Opcode OpcodeValue() const {
636 return static_cast<Opcode>(
637 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift));
640 inline int RsValue() const {
641 ASSERT(InstructionType() == kRegisterType ||
642 InstructionType() == kImmediateType);
643 return Bits(kRsShift + kRsBits - 1, kRsShift);
646 inline int RtValue() const {
647 ASSERT(InstructionType() == kRegisterType ||
648 InstructionType() == kImmediateType);
649 return Bits(kRtShift + kRtBits - 1, kRtShift);
652 inline int RdValue() const {
653 ASSERT(InstructionType() == kRegisterType);
654 return Bits(kRdShift + kRdBits - 1, kRdShift);
657 inline int SaValue() const {
658 ASSERT(InstructionType() == kRegisterType);
659 return Bits(kSaShift + kSaBits - 1, kSaShift);
662 inline int FunctionValue() const {
663 ASSERT(InstructionType() == kRegisterType ||
664 InstructionType() == kImmediateType);
665 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift);
668 inline int FdValue() const {
669 return Bits(kFdShift + kFdBits - 1, kFdShift);
672 inline int FsValue() const {
673 return Bits(kFsShift + kFsBits - 1, kFsShift);
676 inline int FtValue() const {
677 return Bits(kFtShift + kFtBits - 1, kFtShift);
680 // Float Compare condition code instruction bits.
681 inline int FCccValue() const {
682 return Bits(kFCccShift + kFCccBits - 1, kFCccShift);
685 // Float Branch condition code instruction bits.
686 inline int FBccValue() const {
687 return Bits(kFBccShift + kFBccBits - 1, kFBccShift);
690 // Float Branch true/false instruction bit.
691 inline int FBtrueValue() const {
692 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift);
695 // Return the fields at their original place in the instruction encoding.
696 inline Opcode OpcodeFieldRaw() const {
697 return static_cast<Opcode>(InstructionBits() & kOpcodeMask);
700 inline int RsFieldRaw() const {
701 ASSERT(InstructionType() == kRegisterType ||
702 InstructionType() == kImmediateType);
703 return InstructionBits() & kRsFieldMask;
706 // Same as above function, but safe to call within InstructionType().
707 inline int RsFieldRawNoAssert() const {
708 return InstructionBits() & kRsFieldMask;
711 inline int RtFieldRaw() const {
712 ASSERT(InstructionType() == kRegisterType ||
713 InstructionType() == kImmediateType);
714 return InstructionBits() & kRtFieldMask;
717 inline int RdFieldRaw() const {
718 ASSERT(InstructionType() == kRegisterType);
719 return InstructionBits() & kRdFieldMask;
722 inline int SaFieldRaw() const {
723 ASSERT(InstructionType() == kRegisterType);
724 return InstructionBits() & kSaFieldMask;
727 inline int FunctionFieldRaw() const {
728 return InstructionBits() & kFunctionFieldMask;
731 // Get the secondary field according to the opcode.
732 inline int SecondaryValue() const {
733 Opcode op = OpcodeFieldRaw();
737 return FunctionValue();
747 inline int32_t Imm16Value() const {
748 ASSERT(InstructionType() == kImmediateType);
749 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift);
752 inline int32_t Imm26Value() const {
753 ASSERT(InstructionType() == kJumpType);
754 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift);
757 // Say if the instruction should not be used in a branch delay slot.
758 bool IsForbiddenInBranchDelay() const;
759 // Say if the instruction 'links'. e.g. jal, bal.
760 bool IsLinkingInstruction() const;
761 // Say if the instruction is a break or a trap.
764 // Instructions are read of out a code stream. The only way to get a
765 // reference to an instruction is to convert a pointer. There is no way
766 // to allocate or create instances of class Instruction.
767 // Use the At(pc) function to create references to Instruction.
768 static Instruction* At(byte* pc) {
769 return reinterpret_cast<Instruction*>(pc);
773 // We need to prevent the creation of instances of class Instruction.
774 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
778 // -----------------------------------------------------------------------------
779 // MIPS assembly various constants.
781 // C/C++ argument slots size.
782 const int kCArgSlotCount = 4;
783 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize;
784 // JS argument slots size.
785 const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize;
786 // Assembly builtins argument slots size.
787 const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
789 const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
791 const int kDoubleAlignmentBits = 3;
792 const int kDoubleAlignment = (1 << kDoubleAlignmentBits);
793 const int kDoubleAlignmentMask = kDoubleAlignment - 1;
796 } } // namespace v8::internal
798 #endif // #ifndef V8_MIPS_CONSTANTS_H_