Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(720)

Unified Diff: src/mips/constants-mips.h

Issue 1349403003: MIPS: Improve performance of simulator in debug mode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix format. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/mips/constants-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/constants-mips.h
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index baaf546557c2883cf1486c4073b59bf3c5ec4ca4..d6400b65e420bdbd752078f040987ae1a7a36a0a 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -866,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,
@@ -877,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);
@@ -896,15 +898,6 @@ class Instruction {
inline int Bits(int hi, int lo) const {
return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
}
-
- // Instruction type.
- enum Type {
- kRegisterType,
- kImmediateType,
- kJumpType,
- kUnsupported = -1
- };
-
enum TypeChecks { NORMAL, EXTRA };
@@ -951,122 +944,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(TypeChecks checks = NORMAL) 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:
@@ -1081,34 +1092,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);
@@ -1116,7 +1127,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 {
@@ -1127,17 +1138,15 @@ class Instruction {
bool IsLinkingInstruction() const;
// Say if the instruction is a break or a trap.
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.
+class Instruction : public InstructionGetters<InstructionBase> {
+ public:
static Instruction* At(byte* pc) {
return reinterpret_cast<Instruction*>(pc);
}
private:
- // We need to prevent the creation of instances of class Instruction.
DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
};
@@ -1156,8 +1165,8 @@ const int kBArgsSlotsSize = 0 * Instruction::kInstrSize;
const int kBranchReturnOffset = 2 * Instruction::kInstrSize;
-
-Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
+InstructionBase::Type InstructionBase::InstructionType(
+ TypeChecks checks) const {
if (checks == EXTRA) {
if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) {
return kImmediateType;
@@ -1240,6 +1249,118 @@ Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
#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
« no previous file with comments | « no previous file | src/mips/constants-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698