diff options
Diffstat (limited to 'deps/v8/src/mips/constants-mips.h')
-rw-r--r-- | deps/v8/src/mips/constants-mips.h | 297 |
1 files changed, 207 insertions, 90 deletions
diff --git a/deps/v8/src/mips/constants-mips.h b/deps/v8/src/mips/constants-mips.h index 8301c5e5de..200939d65a 100644 --- a/deps/v8/src/mips/constants-mips.h +++ b/deps/v8/src/mips/constants-mips.h @@ -525,6 +525,8 @@ enum SecondaryField : uint32_t { FLOOR_W_S = ((1U << 3) + 7), RECIP_S = ((2U << 3) + 5), RSQRT_S = ((2U << 3) + 6), + MADDF_S = ((3U << 3) + 0), + MSUBF_S = ((3U << 3) + 1), CLASS_S = ((3U << 3) + 3), CVT_D_S = ((4U << 3) + 1), CVT_W_S = ((4U << 3) + 4), @@ -550,6 +552,8 @@ enum SecondaryField : uint32_t { FLOOR_W_D = ((1U << 3) + 7), RECIP_D = ((2U << 3) + 5), RSQRT_D = ((2U << 3) + 6), + MADDF_D = ((3U << 3) + 0), + MSUBF_D = ((3U << 3) + 1), CLASS_D = ((3U << 3) + 3), MIN = ((3U << 3) + 4), MINA = ((3U << 3) + 5), @@ -616,8 +620,12 @@ enum SecondaryField : uint32_t { MOVF = ((2U << 3) + 1), // Function field for MOVT.fmt and MOVF.fmt SELNEZ_C = ((2U << 3) + 7), // COP1 on FPR registers. // COP1 Encoding of Function Field When rs=PS. + // COP1X Encoding of Function Field. + MADD_S = ((4U << 3) + 0), MADD_D = ((4U << 3) + 1), + MSUB_S = ((5U << 3) + 0), + MSUB_D = ((5U << 3) + 1), // PCREL Encoding of rt Field. ADDIUPC = ((0U << 2) + 0), @@ -858,8 +866,7 @@ static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); } - -class Instruction { +class InstructionBase { public: enum { kInstrSize = 4, @@ -869,6 +876,9 @@ class Instruction { kPCReadOffset = 0 }; + // Instruction type. + enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 }; + // Get the raw instruction bits. inline Instr InstructionBits() const { return *reinterpret_cast<const Instr*>(this); @@ -889,16 +899,6 @@ class Instruction { return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); } - // Instruction type. - enum Type { - kRegisterType, - kImmediateType, - kJumpType, - kUnsupported = -1 - }; - - enum TypeChecks { NORMAL, EXTRA }; - static constexpr uint64_t kOpcodeImmediateTypeMask = OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | @@ -943,122 +943,140 @@ class Instruction { FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); - // Get the encoding type of the instruction. - inline Type InstructionType(TypeChecks checks = NORMAL) const; - // Accessors for the different named fields used in the MIPS encoding. inline Opcode OpcodeValue() const { return static_cast<Opcode>( Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); } + inline int FunctionFieldRaw() const { + return InstructionBits() & kFunctionFieldMask; + } + + // Return the fields at their original place in the instruction encoding. + inline Opcode OpcodeFieldRaw() const { + return static_cast<Opcode>(InstructionBits() & kOpcodeMask); + } + + // Safe to call within InstructionType(). + inline int RsFieldRawNoAssert() const { + return InstructionBits() & kRsFieldMask; + } + + inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; } + + // Get the encoding type of the instruction. + inline Type InstructionType() const; + + protected: + InstructionBase() {} +}; + +template <class T> +class InstructionGetters : public T { + public: inline int RsValue() const { - DCHECK(InstructionType() == kRegisterType || - InstructionType() == kImmediateType); - return Bits(kRsShift + kRsBits - 1, kRsShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType || + this->InstructionType() == InstructionBase::kImmediateType); + return InstructionBase::Bits(kRsShift + kRsBits - 1, kRsShift); } inline int RtValue() const { - DCHECK(InstructionType() == kRegisterType || - InstructionType() == kImmediateType); - return Bits(kRtShift + kRtBits - 1, kRtShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType || + this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kRtShift + kRtBits - 1, kRtShift); } inline int RdValue() const { - DCHECK(InstructionType() == kRegisterType); - return Bits(kRdShift + kRdBits - 1, kRdShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType); + return this->Bits(kRdShift + kRdBits - 1, kRdShift); } inline int SaValue() const { - DCHECK(InstructionType() == kRegisterType); - return Bits(kSaShift + kSaBits - 1, kSaShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType); + return this->Bits(kSaShift + kSaBits - 1, kSaShift); } inline int LsaSaValue() const { - DCHECK(InstructionType() == kRegisterType); - return Bits(kSaShift + kLsaSaBits - 1, kSaShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType); + return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift); } inline int FunctionValue() const { - DCHECK(InstructionType() == kRegisterType || - InstructionType() == kImmediateType); - return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType || + this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); } inline int FdValue() const { - return Bits(kFdShift + kFdBits - 1, kFdShift); + return this->Bits(kFdShift + kFdBits - 1, kFdShift); } inline int FsValue() const { - return Bits(kFsShift + kFsBits - 1, kFsShift); + return this->Bits(kFsShift + kFsBits - 1, kFsShift); } inline int FtValue() const { - return Bits(kFtShift + kFtBits - 1, kFtShift); + return this->Bits(kFtShift + kFtBits - 1, kFtShift); } inline int FrValue() const { - return Bits(kFrShift + kFrBits -1, kFrShift); + return this->Bits(kFrShift + kFrBits - 1, kFrShift); } inline int Bp2Value() const { - DCHECK(InstructionType() == kRegisterType); - return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); + DCHECK(this->InstructionType() == InstructionBase::kRegisterType); + return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); } // Float Compare condition code instruction bits. inline int FCccValue() const { - return Bits(kFCccShift + kFCccBits - 1, kFCccShift); + return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift); } // Float Branch condition code instruction bits. inline int FBccValue() const { - return Bits(kFBccShift + kFBccBits - 1, kFBccShift); + return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift); } // Float Branch true/false instruction bit. inline int FBtrueValue() const { - return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); + return this->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); + return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask); } inline int RsFieldRaw() const { - DCHECK(InstructionType() == kRegisterType || - InstructionType() == kImmediateType); - return InstructionBits() & kRsFieldMask; - } - - // Same as above function, but safe to call within InstructionType(). - inline int RsFieldRawNoAssert() const { - return InstructionBits() & kRsFieldMask; + DCHECK(this->InstructionType() == InstructionBase::kRegisterType || + this->InstructionType() == InstructionBase::kImmediateType); + return this->InstructionBits() & kRsFieldMask; } inline int RtFieldRaw() const { - DCHECK(InstructionType() == kRegisterType || - InstructionType() == kImmediateType); - return InstructionBits() & kRtFieldMask; + DCHECK(this->InstructionType() == InstructionBase::kRegisterType || + this->InstructionType() == InstructionBase::kImmediateType); + return this->InstructionBits() & kRtFieldMask; } inline int RdFieldRaw() const { - DCHECK(InstructionType() == kRegisterType); - return InstructionBits() & kRdFieldMask; + DCHECK(this->InstructionType() == InstructionBase::kRegisterType); + return this->InstructionBits() & kRdFieldMask; } inline int SaFieldRaw() const { - return InstructionBits() & kSaFieldMask; + return this->InstructionBits() & kSaFieldMask; } inline int FunctionFieldRaw() const { - return InstructionBits() & kFunctionFieldMask; + return this->InstructionBits() & kFunctionFieldMask; } // Get the secondary field according to the opcode. inline int SecondaryValue() const { - Opcode op = OpcodeFieldRaw(); + Opcode op = this->OpcodeFieldRaw(); switch (op) { case SPECIAL: case SPECIAL2: @@ -1073,34 +1091,34 @@ class Instruction { } inline int32_t ImmValue(int bits) const { - DCHECK(InstructionType() == kImmediateType); - return Bits(bits - 1, 0); + DCHECK(this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(bits - 1, 0); } inline int32_t Imm16Value() const { - DCHECK(InstructionType() == kImmediateType); - return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); + DCHECK(this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); } inline int32_t Imm18Value() const { - DCHECK(InstructionType() == kImmediateType); - return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); + DCHECK(this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); } inline int32_t Imm19Value() const { - DCHECK(InstructionType() == kImmediateType); - return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); + DCHECK(this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); } inline int32_t Imm21Value() const { - DCHECK(InstructionType() == kImmediateType); - return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); + DCHECK(this->InstructionType() == InstructionBase::kImmediateType); + return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); } inline int32_t Imm26Value() const { - DCHECK((InstructionType() == kJumpType) || - (InstructionType() == kImmediateType)); - return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); + DCHECK((this->InstructionType() == InstructionBase::kJumpType) || + (this->InstructionType() == InstructionBase::kImmediateType)); + return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); } static bool IsForbiddenAfterBranchInstr(Instr instr); @@ -1108,7 +1126,7 @@ class Instruction { // Say if the instruction should not be used in a branch delay slot or // immediately after a compact branch. inline bool IsForbiddenAfterBranch() const { - return IsForbiddenAfterBranchInstr(InstructionBits()); + return IsForbiddenAfterBranchInstr(this->InstructionBits()); } inline bool IsForbiddenInBranchDelay() const { @@ -1119,7 +1137,10 @@ class Instruction { bool IsLinkingInstruction() const; // Say if the instruction is a break or a trap. bool IsTrap() const; +}; +class Instruction : public InstructionGetters<InstructionBase> { + public: // 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. @@ -1148,26 +1169,14 @@ const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; const int kBranchReturnOffset = 2 * Instruction::kInstrSize; - -Instruction::Type Instruction::InstructionType(TypeChecks checks) const { - if (checks == EXTRA) { - if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { - return kImmediateType; - } - } +InstructionBase::Type InstructionBase::InstructionType() const { switch (OpcodeFieldRaw()) { case SPECIAL: - if (checks == EXTRA) { - if (FunctionFieldToBitNumber(FunctionFieldRaw()) & - kFunctionFieldRegisterTypeMask) { - return kRegisterType; - } else { - return kUnsupported; - } - } else { + if (FunctionFieldToBitNumber(FunctionFieldRaw()) & + kFunctionFieldRegisterTypeMask) { return kRegisterType; } - break; + return kUnsupported; case SPECIAL2: switch (FunctionFieldRaw()) { case MUL: @@ -1222,16 +1231,124 @@ Instruction::Type Instruction::InstructionType(TypeChecks checks) const { return kJumpType; default: - if (checks == NORMAL) { return kImmediateType; - } else { - return kUnsupported; - } } } #undef OpcodeToBitNumber #undef FunctionFieldToBitNumber + +// ----------------------------------------------------------------------------- +// Instructions. + +template <class P> +bool InstructionGetters<P>::IsLinkingInstruction() const { + uint32_t op = this->OpcodeFieldRaw(); + switch (op) { + case JAL: + return true; + case POP76: + if (this->RsFieldRawNoAssert() == JIALC) + return true; // JIALC + else + return false; // BNEZC + case REGIMM: + switch (this->RtFieldRaw()) { + case BGEZAL: + case BLTZAL: + return true; + default: + return false; + } + case SPECIAL: + switch (this->FunctionFieldRaw()) { + case JALR: + return true; + default: + return false; + } + default: + return false; + } +} + +template <class P> +bool InstructionGetters<P>::IsTrap() const { + if (this->OpcodeFieldRaw() != SPECIAL) { + return false; + } else { + switch (this->FunctionFieldRaw()) { + case BREAK: + case TGE: + case TGEU: + case TLT: + case TLTU: + case TEQ: + case TNE: + return true; + default: + return false; + } + } +} + +// static +template <class T> +bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) { + Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask); + switch (opcode) { + case J: + case JAL: + case BEQ: + case BNE: + case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc + case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc + case BEQL: + case BNEL: + case BLEZL: // POP26 bgezc, blezc, bgec/blec + case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc + case BC: + case BALC: + case POP10: // beqzalc, bovc, beqc + case POP30: // bnezalc, bnvc, bnec + case POP66: // beqzc, jic + case POP76: // bnezc, jialc + return true; + case REGIMM: + switch (instr & kRtFieldMask) { + case BLTZ: + case BGEZ: + case BLTZAL: + case BGEZAL: + return true; + default: + return false; + } + break; + case SPECIAL: + switch (instr & kFunctionFieldMask) { + case JR: + case JALR: + return true; + default: + return false; + } + break; + case COP1: + switch (instr & kRsFieldMask) { + case BC1: + case BC1EQZ: + case BC1NEZ: + return true; + break; + default: + return false; + } + break; + default: + return false; + } +} } // namespace internal } // namespace v8 |