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

Unified Diff: src/interpreter/bytecodes.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Operand renaming. Created 4 years, 9 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
Index: src/interpreter/bytecodes.cc
diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc
index 5f7a9085aec33bdba04bcd4764a8cfac73a6e667..ae5b349a241c7221ea5d1073ad52a005a7bce472 100644
--- a/src/interpreter/bytecodes.cc
+++ b/src/interpreter/bytecodes.cc
@@ -29,7 +29,7 @@ const char* Bytecodes::ToString(Bytecode bytecode) {
// static
const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
switch (operand_type) {
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
return #Name;
OPERAND_TYPE_LIST(CASE)
@@ -49,6 +49,8 @@ const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
return "Byte";
case OperandSize::kShort:
return "Short";
+ case OperandSize::kQuad:
+ return "Quad";
}
UNREACHABLE();
return "";
@@ -71,32 +73,28 @@ Bytecode Bytecodes::FromByte(uint8_t value) {
// static
-Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
- switch (Size(bytecode)) {
-#define CASE(Name, ...) \
- case BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize: \
- return Bytecode::k##Name;
- DEBUG_BREAK_BYTECODE_LIST(CASE)
-#undef CASE
- default:
- break;
+Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode, int operand_scale) {
+ int bytecode_size = Size(bytecode, operand_scale);
+#define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \
+ if (bytecode_size == Size(Bytecode::k##Name, operand_scale)) { \
+ return Bytecode::k##Name; \
}
+ DEBUG_BREAK_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
+#undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
UNREACHABLE();
return static_cast<Bytecode>(-1);
}
// static
-int Bytecodes::Size(Bytecode bytecode) {
- DCHECK(bytecode <= Bytecode::kLast);
- switch (bytecode) {
-#define CASE(Name, ...) \
- case Bytecode::k##Name: \
- return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize;
- BYTECODE_LIST(CASE)
-#undef CASE
+int Bytecodes::Size(Bytecode bytecode, int operand_scale) {
+ int size = 1;
+ for (int i = 0; i < NumberOfOperands(bytecode); i++) {
+ OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
+ int delta = static_cast<int>(operand_size);
+ DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
+ size += delta;
}
- UNREACHABLE();
- return 0;
+ return size;
}
@@ -131,6 +129,18 @@ int Bytecodes::NumberOfRegisterOperands(Bytecode bytecode) {
}
// static
+int Bytecodes::GetPrefixBytecodeScale(Bytecode bytecode) {
+ switch (bytecode) {
rmcilroy 2016/03/10 16:45:37 Could we make this DCHECK if it is passed a non-pr
oth 2016/03/11 16:26:12 Not really, this is one of the main ways of determ
oth 2016/03/17 13:48:38 Done.
+ case Bytecode::kExtraWide:
+ return 4;
+ case Bytecode::kWide:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+// static
OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
DCHECK(bytecode <= Bytecode::kLast);
switch (bytecode) {
@@ -144,23 +154,47 @@ OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
return OperandType::kNone;
}
+// TODO(oth): TEMPORARY
+namespace {
-// static
-OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) {
- DCHECK(bytecode <= Bytecode::kLast);
- switch (bytecode) {
-#define CASE(Name, ...) \
- case Bytecode::k##Name: \
- return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i);
- BYTECODE_LIST(CASE)
+template <OperandTypeTrait O>
+struct OperandScaler {
+ static int Multiply(int size, int scale) { return 0; }
+};
+
+template <>
+struct OperandScaler<OperandTypeTrait::kFixed> {
+ static int Multiply(int size, int scale) { return size; }
+};
+
+template <>
+struct OperandScaler<OperandTypeTrait::kScalable> {
+ static int Multiply(int size, int scale) { return size * scale; }
+};
+
+} // namespace
+
+// TODO(oth): TEMPORARY
+static int ScaledOperandSize(OperandType operand_type, int scale) {
+ switch (operand_type) {
+#define CASE(Name, Size, Trait) \
+ case OperandType::k##Name: \
+ return OperandScaler<Trait>::Multiply(static_cast<int>(Size), scale);
+ OPERAND_TYPE_LIST(CASE)
#undef CASE
}
UNREACHABLE();
- return OperandSize::kNone;
+ return 0;
}
// static
+OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, int scale) {
+ OperandType op_type = GetOperandType(bytecode, i);
+ return static_cast<OperandSize>(ScaledOperandSize(op_type, scale));
+}
+
+// static
int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
DCHECK(bytecode <= Bytecode::kLast);
switch (bytecode) {
@@ -176,31 +210,18 @@ int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
}
// static
-int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) {
- DCHECK(bytecode <= Bytecode::kLast);
- switch (bytecode) {
-#define CASE(Name, ...) \
- case Bytecode::k##Name: \
- return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i);
- BYTECODE_LIST(CASE)
-#undef CASE
+int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, int scale) {
+ int offset = 1;
+ for (int operand_index = 0; operand_index < i; ++operand_index) {
+ OperandSize operand_size = GetOperandSize(bytecode, operand_index, scale);
+ offset += static_cast<int>(operand_size);
}
- UNREACHABLE();
- return 0;
+ return offset;
}
-
// static
-OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) {
- switch (operand_type) {
-#define CASE(Name, Size) \
- case OperandType::k##Name: \
- return Size;
- OPERAND_TYPE_LIST(CASE)
-#undef CASE
- }
- UNREACHABLE();
- return OperandSize::kNone;
+OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, int scale) {
+ return static_cast<OperandSize>(ScaledOperandSize(operand_type, scale));
}
@@ -227,24 +248,10 @@ bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
bytecode == Bytecode::kJumpIfUndefinedConstant;
}
-
-// static
-bool Bytecodes::IsConditionalJumpConstantWide(Bytecode bytecode) {
- return bytecode == Bytecode::kJumpIfTrueConstantWide ||
- bytecode == Bytecode::kJumpIfFalseConstantWide ||
- bytecode == Bytecode::kJumpIfToBooleanTrueConstantWide ||
- bytecode == Bytecode::kJumpIfToBooleanFalseConstantWide ||
- bytecode == Bytecode::kJumpIfNotHoleConstantWide ||
- bytecode == Bytecode::kJumpIfNullConstantWide ||
- bytecode == Bytecode::kJumpIfUndefinedConstantWide;
-}
-
-
// static
bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
return IsConditionalJumpImmediate(bytecode) ||
- IsConditionalJumpConstant(bytecode) ||
- IsConditionalJumpConstantWide(bytecode);
+ IsConditionalJumpConstant(bytecode);
}
@@ -260,34 +267,22 @@ bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
IsConditionalJumpConstant(bytecode);
}
-
-// static
-bool Bytecodes::IsJumpConstantWide(Bytecode bytecode) {
- return bytecode == Bytecode::kJumpConstantWide ||
- IsConditionalJumpConstantWide(bytecode);
-}
-
-
// static
bool Bytecodes::IsJump(Bytecode bytecode) {
- return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode) ||
- IsJumpConstantWide(bytecode);
+ return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
}
// static
bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
- bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide ||
- bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
+ bytecode == Bytecode::kNew;
}
// static
bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
return bytecode == Bytecode::kCallRuntime ||
- bytecode == Bytecode::kCallRuntimeWide ||
- bytecode == Bytecode::kCallRuntimeForPair ||
- bytecode == Bytecode::kCallRuntimeForPairWide;
+ bytecode == Bytecode::kCallRuntimeForPair;
}
// static
@@ -304,42 +299,63 @@ bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
}
// static
+bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
+ switch (bytecode) {
+#define CASE(Name, ...) \
+ case Bytecode::k##Name: \
+ typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
+ return Name##Trait::IsScalable();
+ BYTECODE_LIST(CASE)
+#undef CASE
+ }
+ UNREACHABLE();
+ return false;
+}
+
+// static
bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
return bytecode == Bytecode::kReturn || IsJump(bytecode);
}
// static
+bool Bytecodes::IsFlagOperandType(OperandType operand_type) {
+ return operand_type == OperandType::kFlag8;
+}
+
+// static
bool Bytecodes::IsIndexOperandType(OperandType operand_type) {
- return operand_type == OperandType::kIdx8 ||
- operand_type == OperandType::kIdx16;
+ return operand_type == OperandType::kIdx;
}
// static
bool Bytecodes::IsImmediateOperandType(OperandType operand_type) {
- return operand_type == OperandType::kImm8;
+ return operand_type == OperandType::kImm;
}
// static
bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) {
- return (operand_type == OperandType::kRegCount8 ||
- operand_type == OperandType::kRegCount16);
+ return operand_type == OperandType::kRegCount;
}
// static
bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
- return (operand_type == OperandType::kMaybeReg8 ||
- operand_type == OperandType::kMaybeReg16);
+ return operand_type == OperandType::kMaybeReg;
+}
+
+// static
+bool Bytecodes::IsRuntimeIdOperandType(OperandType operand_type) {
rmcilroy 2016/03/10 16:45:37 Wondering whether these IsXXXOperandType are neces
oth 2016/03/11 16:26:12 Done. Removed all except the still useful IsRegist
+ return operand_type == OperandType::kRuntimeId;
}
// static
bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
switch (operand_type) {
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
return true;
REGISTER_OPERAND_TYPE_LIST(CASE)
#undef CASE
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
break;
NON_REGISTER_OPERAND_TYPE_LIST(CASE)
@@ -351,12 +367,12 @@ bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
// static
bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
switch (operand_type) {
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
return true;
REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
#undef CASE
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
break;
NON_REGISTER_OPERAND_TYPE_LIST(CASE)
@@ -369,12 +385,12 @@ bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
// static
bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
switch (operand_type) {
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
return true;
REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
#undef CASE
-#define CASE(Name, _) \
+#define CASE(Name, _, __) \
case OperandType::k##Name: \
break;
NON_REGISTER_OPERAND_TYPE_LIST(CASE)
@@ -386,18 +402,52 @@ bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
namespace {
static Register DecodeRegister(const uint8_t* operand_start,
- OperandType operand_type) {
- switch (Bytecodes::SizeOfOperand(operand_type)) {
+ OperandType operand_type, int operand_scale) {
+ switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
case OperandSize::kByte:
return Register::FromOperand(*operand_start);
case OperandSize::kShort:
return Register::FromWideOperand(ReadUnalignedUInt16(operand_start));
+ case OperandSize::kQuad:
+ return Register::FromWideOperand(ReadUnalignedUInt32(operand_start));
case OperandSize::kNone: {
UNREACHABLE();
}
}
return Register();
}
+
+static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
+ OperandType operand_type,
+ int operand_scale) {
+ switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
+ case OperandSize::kByte:
+ return *operand_start;
+ case OperandSize::kShort:
+ return ReadUnalignedUInt16(operand_start);
+ case OperandSize::kQuad:
+ return ReadUnalignedUInt32(operand_start);
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return 0;
+}
+
+static int32_t DecodeSignedOperand(const uint8_t* operand_start,
+ OperandType operand_type,
+ int operand_scale) {
+ switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
+ case OperandSize::kByte:
+ return static_cast<int8_t>(*operand_start);
+ case OperandSize::kShort:
+ return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
+ case OperandSize::kQuad:
+ return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return 0;
+}
} // namespace
@@ -407,18 +457,31 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
Vector<char> buf = Vector<char>::New(50);
Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
- int bytecode_size = Bytecodes::Size(bytecode);
+ int prefix_offset = 0;
+ int operand_scale = Bytecodes::GetPrefixBytecodeScale(bytecode);
+ if (operand_scale > 1) {
+ prefix_offset += 1;
+ bytecode = Bytecodes::FromByte(bytecode_start[1]);
+ }
- for (int i = 0; i < bytecode_size; i++) {
+ int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
+
+ for (int i = 0; i < prefix_offset + bytecode_size; i++) {
SNPrintF(buf, "%02x ", bytecode_start[i]);
os << buf.start();
}
const int kBytecodeColumnSize = 6;
- for (int i = bytecode_size; i < kBytecodeColumnSize; i++) {
+ for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
os << " ";
}
- os << bytecode << " ";
+ os << bytecode;
+ if (operand_scale == 2) {
+ os << "." << Bytecodes::ToString(Bytecode::kWide);
+ } else if (operand_scale == 4) {
+ os << "." << Bytecodes::ToString(Bytecode::kExtraWide);
+ }
+ os << " ";
// Operands for the debug break are from the original instruction.
if (IsDebugBreak(bytecode)) return os;
@@ -428,42 +491,41 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
for (int i = 0; i < number_of_operands; i++) {
OperandType op_type = GetOperandType(bytecode, i);
const uint8_t* operand_start =
- &bytecode_start[GetOperandOffset(bytecode, i)];
+ &bytecode_start[prefix_offset +
+ GetOperandOffset(bytecode, i, operand_scale)];
switch (op_type) {
- case interpreter::OperandType::kRegCount8:
- os << "#" << static_cast<unsigned int>(*operand_start);
- break;
- case interpreter::OperandType::kRegCount16:
- os << '#' << ReadUnalignedUInt16(operand_start);
+ case interpreter::OperandType::kRegCount:
+ os << "#"
+ << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
break;
- case interpreter::OperandType::kIdx8:
- os << "[" << static_cast<unsigned int>(*operand_start) << "]";
+ case interpreter::OperandType::kIdx:
+ case interpreter::OperandType::kRuntimeId:
+ os << "["
+ << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
+ << "]";
break;
- case interpreter::OperandType::kIdx16:
- os << "[" << ReadUnalignedUInt16(operand_start) << "]";
+ case interpreter::OperandType::kImm:
+ os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
+ << "]";
break;
- case interpreter::OperandType::kImm8:
- os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start));
+ case interpreter::OperandType::kFlag8:
+ os << "#"
+ << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
break;
- case interpreter::OperandType::kMaybeReg8:
- case interpreter::OperandType::kMaybeReg16:
- case interpreter::OperandType::kReg8:
- case interpreter::OperandType::kReg16:
- case interpreter::OperandType::kRegOut8:
- case interpreter::OperandType::kRegOut16: {
- Register reg = DecodeRegister(operand_start, op_type);
+ case interpreter::OperandType::kMaybeReg:
+ case interpreter::OperandType::kReg:
+ case interpreter::OperandType::kRegOut: {
+ Register reg = DecodeRegister(operand_start, op_type, operand_scale);
os << reg.ToString(parameter_count);
break;
}
- case interpreter::OperandType::kRegOutTriple8:
- case interpreter::OperandType::kRegOutTriple16:
+ case interpreter::OperandType::kRegOutTriple:
range += 1;
- case interpreter::OperandType::kRegOutPair8:
- case interpreter::OperandType::kRegOutPair16:
- case interpreter::OperandType::kRegPair8:
- case interpreter::OperandType::kRegPair16: {
+ case interpreter::OperandType::kRegOutPair:
+ case interpreter::OperandType::kRegPair: {
range += 1;
- Register first_reg = DecodeRegister(operand_start, op_type);
+ Register first_reg =
+ DecodeRegister(operand_start, op_type, operand_scale);
Register last_reg = Register(first_reg.index() + range);
os << first_reg.ToString(parameter_count) << "-"
<< last_reg.ToString(parameter_count);

Powered by Google App Engine
This is Rietveld 408576698