vendor/v8/src/mips/constants-mips.h in mustang-0.0.1 vs vendor/v8/src/mips/constants-mips.h in mustang-0.1.0

- old
+ new

@@ -26,28 +26,38 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef V8_MIPS_CONSTANTS_H_ #define V8_MIPS_CONSTANTS_H_ -#include "checks.h" - // UNIMPLEMENTED_ macro for MIPS. +#ifdef DEBUG #define UNIMPLEMENTED_MIPS() \ v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \ __FILE__, __LINE__, __func__) +#else +#define UNIMPLEMENTED_MIPS() +#endif + #define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n") +#ifdef _MIPS_ARCH_MIPS32R2 + #define mips32r2 1 +#else + #define mips32r2 0 +#endif + + // Defines constants and accessor classes to assemble, disassemble and // simulate MIPS32 instructions. // // See: MIPS32 Architecture For Programmers // Volume II: The MIPS32 Instruction Set // Try www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol2.pdf. -namespace assembler { -namespace mips { +namespace v8 { +namespace internal { // ----------------------------------------------------------------------------- // Registers and FPURegister. // Number of general purpose registers. @@ -59,13 +69,22 @@ // In the simulator, the PC register is simulated as the 34th register. static const int kPCRegister = 34; // Number coprocessor registers. -static const int kNumFPURegister = 32; +static const int kNumFPURegisters = 32; static const int kInvalidFPURegister = -1; +// FPU (coprocessor 1) control registers. Currently only FCSR is implemented. +static const int kFCSRRegister = 31; +static const int kInvalidFPUControlRegister = -1; +static const uint32_t kFPUInvalidResult = (uint32_t) (1 << 31) - 1; + +// FCSR constants. +static const uint32_t kFCSRFlagMask = (1 << 6) - 1; +static const uint32_t kFCSRFlagShift = 2; + // Helper functions for converting between register numbers and names. class Registers { public: // Return the name of the register. static const char* Name(int reg); @@ -86,11 +105,11 @@ static const char* names_[kNumSimuRegisters]; static const RegisterAlias aliases_[]; }; // Helper functions for converting between register numbers and names. -class FPURegister { +class FPURegisters { public: // Return the name of the register. static const char* Name(int reg); // Lookup the register number for the name provided. @@ -101,11 +120,11 @@ const char *name; }; private: - static const char* names_[kNumFPURegister]; + static const char* names_[kNumFPURegisters]; static const RegisterAlias aliases_[]; }; // ----------------------------------------------------------------------------- @@ -134,20 +153,29 @@ static const int kRdBits = 5; static const int kSaShift = 6; static const int kSaBits = 5; static const int kFunctionShift = 0; static const int kFunctionBits = 6; +static const int kLuiShift = 16; static const int kImm16Shift = 0; static const int kImm16Bits = 16; static const int kImm26Shift = 0; static const int kImm26Bits = 26; static const int kFsShift = 11; static const int kFsBits = 5; static const int kFtShift = 16; static const int kFtBits = 5; +static const int kFdShift = 6; +static const int kFdBits = 5; +static const int kFCccShift = 8; +static const int kFCccBits = 3; +static const int kFBccShift = 18; +static const int kFBccBits = 3; +static const int kFBtrueShift = 16; +static const int kFBtrueBits = 1; // ----- Miscellianous useful masks. // Instruction bit masks. static const int kOpcodeMask = ((1 << kOpcodeBits) - 1) << kOpcodeShift; static const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift; @@ -157,13 +185,13 @@ static const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift; static const int kSaFieldMask = ((1 << kSaBits) - 1) << kSaShift; static const int kFunctionFieldMask = ((1 << kFunctionBits) - 1) << kFunctionShift; // Misc masks. -static const int HIMask = 0xffff << 16; -static const int LOMask = 0xffff; -static const int signMask = 0x80000000; +static const int kHiMask = 0xffff << 16; +static const int kLoMask = 0xffff; +static const int kSignMask = 0x80000000; // ----- MIPS Opcodes and Function Fields. // We use this presentation to stay close to the table representation in // MIPS32 Architecture For Programmers, Volume II: The MIPS32 Instruction Set. @@ -192,16 +220,24 @@ BNEL = ((2 << 3) + 5) << kOpcodeShift, BLEZL = ((2 << 3) + 6) << kOpcodeShift, BGTZL = ((2 << 3) + 7) << kOpcodeShift, SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift, + SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift, LB = ((4 << 3) + 0) << kOpcodeShift, + LH = ((4 << 3) + 1) << kOpcodeShift, + LWL = ((4 << 3) + 2) << kOpcodeShift, LW = ((4 << 3) + 3) << kOpcodeShift, LBU = ((4 << 3) + 4) << kOpcodeShift, + LHU = ((4 << 3) + 5) << kOpcodeShift, + LWR = ((4 << 3) + 6) << kOpcodeShift, SB = ((5 << 3) + 0) << kOpcodeShift, + SH = ((5 << 3) + 1) << kOpcodeShift, + SWL = ((5 << 3) + 2) << kOpcodeShift, SW = ((5 << 3) + 3) << kOpcodeShift, + SWR = ((5 << 3) + 6) << kOpcodeShift, LWC1 = ((6 << 3) + 1) << kOpcodeShift, LDC1 = ((6 << 3) + 5) << kOpcodeShift, SWC1 = ((7 << 3) + 1) << kOpcodeShift, @@ -214,13 +250,16 @@ SRL = ((0 << 3) + 2), SRA = ((0 << 3) + 3), SLLV = ((0 << 3) + 4), SRLV = ((0 << 3) + 6), SRAV = ((0 << 3) + 7), + MOVCI = ((0 << 3) + 1), JR = ((1 << 3) + 0), JALR = ((1 << 3) + 1), + MOVZ = ((1 << 3) + 2), + MOVN = ((1 << 3) + 3), BREAK = ((1 << 3) + 5), MFHI = ((2 << 3) + 0), MFLO = ((2 << 3) + 2), @@ -248,37 +287,77 @@ TEQ = ((6 << 3) + 4), TNE = ((6 << 3) + 6), // SPECIAL2 Encoding of Function Field. MUL = ((0 << 3) + 2), + CLZ = ((4 << 3) + 0), + CLO = ((4 << 3) + 1), + // SPECIAL3 Encoding of Function Field. + EXT = ((0 << 3) + 0), + INS = ((0 << 3) + 4), + // REGIMM encoding of rt Field. BLTZ = ((0 << 3) + 0) << 16, BGEZ = ((0 << 3) + 1) << 16, BLTZAL = ((2 << 3) + 0) << 16, BGEZAL = ((2 << 3) + 1) << 16, // COP1 Encoding of rs Field. MFC1 = ((0 << 3) + 0) << 21, + CFC1 = ((0 << 3) + 2) << 21, MFHC1 = ((0 << 3) + 3) << 21, MTC1 = ((0 << 3) + 4) << 21, + CTC1 = ((0 << 3) + 6) << 21, MTHC1 = ((0 << 3) + 7) << 21, BC1 = ((1 << 3) + 0) << 21, S = ((2 << 3) + 0) << 21, D = ((2 << 3) + 1) << 21, W = ((2 << 3) + 4) << 21, L = ((2 << 3) + 5) << 21, PS = ((2 << 3) + 6) << 21, // COP1 Encoding of Function Field When rs=S. + ROUND_L_S = ((1 << 3) + 0), + TRUNC_L_S = ((1 << 3) + 1), + CEIL_L_S = ((1 << 3) + 2), + FLOOR_L_S = ((1 << 3) + 3), + ROUND_W_S = ((1 << 3) + 4), + TRUNC_W_S = ((1 << 3) + 5), + CEIL_W_S = ((1 << 3) + 6), + FLOOR_W_S = ((1 << 3) + 7), CVT_D_S = ((4 << 3) + 1), CVT_W_S = ((4 << 3) + 4), CVT_L_S = ((4 << 3) + 5), CVT_PS_S = ((4 << 3) + 6), // COP1 Encoding of Function Field When rs=D. + ADD_D = ((0 << 3) + 0), + SUB_D = ((0 << 3) + 1), + MUL_D = ((0 << 3) + 2), + DIV_D = ((0 << 3) + 3), + SQRT_D = ((0 << 3) + 4), + ABS_D = ((0 << 3) + 5), + MOV_D = ((0 << 3) + 6), + NEG_D = ((0 << 3) + 7), + ROUND_L_D = ((1 << 3) + 0), + TRUNC_L_D = ((1 << 3) + 1), + CEIL_L_D = ((1 << 3) + 2), + FLOOR_L_D = ((1 << 3) + 3), + ROUND_W_D = ((1 << 3) + 4), + TRUNC_W_D = ((1 << 3) + 5), + CEIL_W_D = ((1 << 3) + 6), + FLOOR_W_D = ((1 << 3) + 7), CVT_S_D = ((4 << 3) + 0), CVT_W_D = ((4 << 3) + 4), CVT_L_D = ((4 << 3) + 5), + C_F_D = ((6 << 3) + 0), + C_UN_D = ((6 << 3) + 1), + C_EQ_D = ((6 << 3) + 2), + C_UEQ_D = ((6 << 3) + 3), + C_OLT_D = ((6 << 3) + 4), + C_ULT_D = ((6 << 3) + 5), + C_OLE_D = ((6 << 3) + 6), + C_ULE_D = ((6 << 3) + 7), // COP1 Encoding of Function Field When rs=W or L. CVT_S_W = ((4 << 3) + 0), CVT_D_W = ((4 << 3) + 1), CVT_S_L = ((4 << 3) + 0), CVT_D_L = ((4 << 3) + 1), @@ -291,11 +370,11 @@ // ----- Emulated conditions. // On MIPS we use this enum to abstract from conditionnal branch instructions. // the 'U' prefix is used to specify unsigned comparisons. enum Condition { // Any value < 0 is considered no_condition. - no_condition = -1, + kNoCondition = -1, overflow = 0, no_overflow = 1, Uless = 2, Ugreater_equal= 3, @@ -319,16 +398,63 @@ not_carry = Ugreater_equal, zero = equal, eq = equal, not_zero = not_equal, ne = not_equal, + nz = not_equal, sign = negative, not_sign = positive, + mi = negative, + pl = positive, + hi = Ugreater, + ls = Uless_equal, + ge = greater_equal, + lt = less, + gt = greater, + le = less_equal, + hs = Ugreater_equal, + lo = Uless, + al = cc_always, - cc_default = no_condition + cc_default = kNoCondition }; + +// Returns the equivalent of !cc. +// Negation of the default kNoCondition (-1) results in a non-default +// no_condition value (-2). As long as tests for no_condition check +// for condition < 0, this will work as expected. +inline Condition NegateCondition(Condition cc) { + ASSERT(cc != cc_always); + return static_cast<Condition>(cc ^ 1); +} + + +inline Condition ReverseCondition(Condition cc) { + switch (cc) { + case Uless: + return Ugreater; + case Ugreater: + return Uless; + case Ugreater_equal: + return Uless_equal; + case Uless_equal: + return Ugreater_equal; + case less: + return greater; + case greater: + return less; + case greater_equal: + return less_equal; + case less_equal: + return greater_equal; + default: + return cc; + }; +} + + // ----- Coprocessor conditions. enum FPUCondition { F, // False UN, // Unordered EQ, // Equal @@ -338,22 +464,62 @@ OLE, // Ordered or Less Than or Equal ULE // Unordered or Less Than or Equal }; +// ----------------------------------------------------------------------------- +// Hints. + +// Branch hints are not used on the MIPS. They are defined so that they can +// appear in shared function signatures, but will be ignored in MIPS +// implementations. +enum Hint { + no_hint = 0 +}; + + +inline Hint NegateHint(Hint hint) { + return no_hint; +} + + +// ----------------------------------------------------------------------------- +// Specific instructions, constants, and masks. +// These constants are declared in assembler-mips.cc, as they use named +// registers and other constants. + +// addiu(sp, sp, 4) aka Pop() operation or part of Pop(r) +// operations as post-increment of sp. +extern const Instr kPopInstruction; +// addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp. +extern const Instr kPushInstruction; +// sw(r, MemOperand(sp, 0)) +extern const Instr kPushRegPattern; +// lw(r, MemOperand(sp, 0)) +extern const Instr kPopRegPattern; +extern const Instr kLwRegFpOffsetPattern; +extern const Instr kSwRegFpOffsetPattern; +extern const Instr kLwRegFpNegOffsetPattern; +extern const Instr kSwRegFpNegOffsetPattern; +// A mask for the Rt register for push, pop, lw, sw instructions. +extern const Instr kRtMask; +extern const Instr kLwSwInstrTypeMask; +extern const Instr kLwSwInstrArgumentMask; +extern const Instr kLwSwOffsetMask; + // Break 0xfffff, reserved for redirected real time call. const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; // A nop instruction. (Encoding of sll 0 0 0). const Instr nopInstr = 0; class Instruction { public: enum { - kInstructionSize = 4, - kInstructionSizeLog2 = 2, + kInstrSize = 4, + kInstrSizeLog2 = 2, // On MIPS PC cannot actually be directly accessed. We behave as if PC was - // always the value of the current instruction being exectued. + // always the value of the current instruction being executed. kPCReadOffset = 0 }; // Get the raw instruction bits. inline Instr InstructionBits() const { @@ -386,51 +552,70 @@ // Get the encoding type of the instruction. Type InstructionType() const; // Accessors for the different named fields used in the MIPS encoding. - inline Opcode OpcodeField() const { + inline Opcode OpcodeValue() const { return static_cast<Opcode>( Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); } - inline int RsField() const { + inline int RsValue() const { ASSERT(InstructionType() == kRegisterType || InstructionType() == kImmediateType); return Bits(kRsShift + kRsBits - 1, kRsShift); } - inline int RtField() const { + inline int RtValue() const { ASSERT(InstructionType() == kRegisterType || InstructionType() == kImmediateType); return Bits(kRtShift + kRtBits - 1, kRtShift); } - inline int RdField() const { + inline int RdValue() const { ASSERT(InstructionType() == kRegisterType); return Bits(kRdShift + kRdBits - 1, kRdShift); } - inline int SaField() const { + inline int SaValue() const { ASSERT(InstructionType() == kRegisterType); return Bits(kSaShift + kSaBits - 1, kSaShift); } - inline int FunctionField() const { + inline int FunctionValue() const { ASSERT(InstructionType() == kRegisterType || InstructionType() == kImmediateType); return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); } - inline int FsField() const { - return Bits(kFsShift + kRsBits - 1, kFsShift); + inline int FdValue() const { + return Bits(kFdShift + kFdBits - 1, kFdShift); } - inline int FtField() const { - return Bits(kFtShift + kRsBits - 1, kFtShift); + inline int FsValue() const { + return Bits(kFsShift + kFsBits - 1, kFsShift); } + inline int FtValue() const { + return Bits(kFtShift + kFtBits - 1, kFtShift); + } + + // Float Compare condition code instruction bits. + inline int FCccValue() const { + return Bits(kFCccShift + kFCccBits - 1, kFCccShift); + } + + // Float Branch condition code instruction bits. + inline int FBccValue() const { + return Bits(kFBccShift + kFBccBits - 1, kFBccShift); + } + + // Float Branch true/false instruction bit. + inline int FBtrueValue() const { + return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); + } + // Return the fields at their original place in the instruction encoding. inline Opcode OpcodeFieldRaw() const { return static_cast<Opcode>(InstructionBits() & kOpcodeMask); } @@ -438,10 +623,15 @@ ASSERT(InstructionType() == kRegisterType || InstructionType() == kImmediateType); return InstructionBits() & kRsFieldMask; } + // Same as above function, but safe to call within InstructionType(). + inline int RsFieldRawNoAssert() const { + return InstructionBits() & kRsFieldMask; + } + inline int RtFieldRaw() const { ASSERT(InstructionType() == kRegisterType || InstructionType() == kImmediateType); return InstructionBits() & kRtFieldMask; } @@ -459,41 +649,41 @@ inline int FunctionFieldRaw() const { return InstructionBits() & kFunctionFieldMask; } // Get the secondary field according to the opcode. - inline int SecondaryField() const { + inline int SecondaryValue() const { Opcode op = OpcodeFieldRaw(); switch (op) { case SPECIAL: case SPECIAL2: - return FunctionField(); + return FunctionValue(); case COP1: - return RsField(); + return RsValue(); case REGIMM: - return RtField(); + return RtValue(); default: return NULLSF; } } - inline int32_t Imm16Field() const { + inline int32_t Imm16Value() const { ASSERT(InstructionType() == kImmediateType); return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); } - inline int32_t Imm26Field() const { + inline int32_t Imm26Value() const { ASSERT(InstructionType() == kJumpType); return Bits(kImm16Shift + kImm26Bits - 1, kImm26Shift); } // Say if the instruction should not be used in a branch delay slot. - bool IsForbiddenInBranchDelay(); + bool IsForbiddenInBranchDelay() const; // Say if the instruction 'links'. eg: jal, bal. - bool IsLinkingInstruction(); + bool IsLinkingInstruction() const; // Say if the instruction is a break or a trap. - bool IsTrap(); + bool IsTrap() const; // Instructions are read of out a code stream. The only way to get a // reference to an instruction is to convert a pointer. There is no way // to allocate or create instances of class Instruction. // Use the At(pc) function to create references to Instruction. @@ -508,18 +698,26 @@ // ----------------------------------------------------------------------------- // MIPS assembly various constants. -static const int kArgsSlotsSize = 4 * Instruction::kInstructionSize; + +static const int kArgsSlotsSize = 4 * Instruction::kInstrSize; static const int kArgsSlotsNum = 4; +// C/C++ argument slots size. +static const int kCArgsSlotsSize = 4 * Instruction::kInstrSize; +// JS argument slots size. +static const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; +// Assembly builtins argument slots size. +static const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; -static const int kBranchReturnOffset = 2 * Instruction::kInstructionSize; +static const int kBranchReturnOffset = 2 * Instruction::kInstrSize; -static const int kDoubleAlignment = 2 * 8; -static const int kDoubleAlignmentMask = kDoubleAlignmentMask - 1; +static const int kDoubleAlignmentBits = 3; +static const int kDoubleAlignment = (1 << kDoubleAlignmentBits); +static const int kDoubleAlignmentMask = kDoubleAlignment - 1; -} } // namespace assembler::mips +} } // namespace v8::internal #endif // #ifndef V8_MIPS_CONSTANTS_H_