summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips/constants-mips.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mips/constants-mips.h')
-rw-r--r--deps/v8/src/mips/constants-mips.h297
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