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

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

Issue 2375673002: MIPS64: Improve performance of simulator in debug mode. (Closed)
Patch Set: 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/mips64/constants-mips64.cc » ('j') | src/mips64/simulator-mips64.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips64/constants-mips64.h
diff --git a/src/mips64/constants-mips64.h b/src/mips64/constants-mips64.h
index 76794688cf3da425ef3154755634dc51b03a5a21..2d78d2947f6eb37111a4772551617b6ce8ab0a4f 100644
--- a/src/mips64/constants-mips64.h
+++ b/src/mips64/constants-mips64.h
@@ -899,8 +899,7 @@ static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) {
return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift);
}
-
-class Instruction {
+class InstructionBase {
public:
enum {
kInstrSize = 4,
@@ -910,6 +909,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);
@@ -930,14 +932,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 =
@@ -996,9 +990,6 @@ 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 {
@@ -1006,118 +997,144 @@ class Instruction {
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 this->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);
}
inline int Bp3Value() const {
- DCHECK(InstructionType() == kRegisterType);
- return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift);
+ DCHECK(this->InstructionType() == InstructionBase::kRegisterType);
+ return this->Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift);
}
// 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;
+ DCHECK(this->InstructionType() == InstructionBase::kRegisterType ||
+ this->InstructionType() == InstructionBase::kImmediateType);
+ return this->InstructionBits() & kRsFieldMask;
}
// Same as above function, but safe to call within InstructionType().
inline int RsFieldRawNoAssert() const {
- return InstructionBits() & kRsFieldMask;
+ 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:
@@ -1132,34 +1149,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);
@@ -1167,14 +1184,21 @@ 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 {
+ return IsForbiddenAfterBranch();
}
// Say if the instruction 'links'. e.g. jal, bal.
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.
@@ -1202,8 +1226,8 @@ const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2;
const int kInvalidStackOffset = -1;
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;
@@ -1306,9 +1330,119 @@ Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
}
return kUnsupported;
}
-
#undef OpcodeToBitNumber
#undef FunctionFieldToBitNumber
+
Ilija.Pavlovic1 2016/09/29 10:13:39 Why this code is transferred here from constants-m
balazs.kilvady 2016/09/29 10:57:41 Because of the template stuff. Template implementa
Ilija.Pavlovic1 2016/09/29 13:15:33 Acknowledged.
+// -----------------------------------------------------------------------------
+// Instructions.
+
+template <class P>
+bool InstructionGetters<P>::IsLinkingInstruction() const {
+ switch (OpcodeFieldRaw()) {
+ case JAL:
+ return true;
+ case POP76:
+ if (RsFieldRawNoAssert() == JIALC)
+ return true; // JIALC
+ else
+ return false; // BNEZC
+ case REGIMM:
+ switch (RtFieldRaw()) {
+ case BGEZAL:
+ case BLTZAL:
+ return true;
+ default:
+ return false;
+ }
+ case SPECIAL:
+ switch (FunctionFieldRaw()) {
+ case JALR:
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
+template <class P>
+bool InstructionGetters<P>::IsTrap() const {
+ if (OpcodeFieldRaw() != SPECIAL) {
+ return false;
+ } else {
+ switch (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/mips64/constants-mips64.cc » ('j') | src/mips64/simulator-mips64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698