| Index: src/interpreter/bytecodes.cc
|
| diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc
|
| index 3be109f4cbefd6286151d3dbb9a60d857fb96c90..6604191c5953cccaf137a938721692f0a9da596d 100644
|
| --- a/src/interpreter/bytecodes.cc
|
| +++ b/src/interpreter/bytecodes.cc
|
| @@ -74,15 +74,13 @@ const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
|
| // static
|
| const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) {
|
| switch (operand_scale) {
|
| - case OperandScale::kSingle:
|
| - return "Single";
|
| - case OperandScale::kDouble:
|
| - return "Double";
|
| - case OperandScale::kQuadruple:
|
| - return "Quadruple";
|
| - case OperandScale::kInvalid:
|
| - UNREACHABLE();
|
| +#define CASE(Name, _) \
|
| + case OperandScale::k##Name: \
|
| + return #Name;
|
| + OPERAND_SCALE_LIST(CASE)
|
| +#undef CASE
|
| }
|
| + UNREACHABLE();
|
| return "";
|
| }
|
|
|
| @@ -241,24 +239,80 @@ bool Bytecodes::WritesAccumulator(Bytecode bytecode) {
|
| }
|
|
|
| // static
|
| +bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) {
|
| + switch (bytecode) {
|
| + case Bytecode::kLdaTrue:
|
| + case Bytecode::kLdaFalse:
|
| + case Bytecode::kLogicalNot:
|
| + case Bytecode::kTestEqual:
|
| + case Bytecode::kTestNotEqual:
|
| + case Bytecode::kTestEqualStrict:
|
| + case Bytecode::kTestLessThan:
|
| + case Bytecode::kTestLessThanOrEqual:
|
| + case Bytecode::kTestGreaterThan:
|
| + case Bytecode::kTestGreaterThanOrEqual:
|
| + case Bytecode::kTestInstanceOf:
|
| + case Bytecode::kTestIn:
|
| + case Bytecode::kForInDone:
|
| + return true;
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +// static
|
| +bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
|
| + switch (bytecode) {
|
| + case Bytecode::kLdaZero:
|
| + case Bytecode::kLdaSmi:
|
| + case Bytecode::kLdaUndefined:
|
| + case Bytecode::kLdaNull:
|
| + case Bytecode::kLdaTheHole:
|
| + case Bytecode::kLdaTrue:
|
| + case Bytecode::kLdaFalse:
|
| + case Bytecode::kLdaConstant:
|
| + case Bytecode::kLdar:
|
| + return true;
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +// static
|
| OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
|
| + DCHECK_LE(bytecode, Bytecode::kLast);
|
| + DCHECK_LT(i, NumberOfOperands(bytecode));
|
| + DCHECK_GE(i, 0);
|
| + return GetOperandTypes(bytecode)[i];
|
| +}
|
| +
|
| +// static
|
| +const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) {
|
| DCHECK(bytecode <= Bytecode::kLast);
|
| switch (bytecode) {
|
| #define CASE(Name, ...) \
|
| case Bytecode::k##Name: \
|
| - return BytecodeTraits<__VA_ARGS__>::GetOperandType(i);
|
| + return BytecodeTraits<__VA_ARGS__>::GetOperandTypes();
|
| BYTECODE_LIST(CASE)
|
| #undef CASE
|
| }
|
| UNREACHABLE();
|
| - return OperandType::kNone;
|
| + return nullptr;
|
| }
|
|
|
| // static
|
| OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i,
|
| OperandScale operand_scale) {
|
| - OperandType op_type = GetOperandType(bytecode, i);
|
| - return ScaledOperandSize(op_type, operand_scale);
|
| + DCHECK(bytecode <= Bytecode::kLast);
|
| + switch (bytecode) {
|
| +#define CASE(Name, ...) \
|
| + case Bytecode::k##Name: \
|
| + return BytecodeTraits<__VA_ARGS__>::GetOperandSize(i, operand_scale);
|
| + BYTECODE_LIST(CASE)
|
| +#undef CASE
|
| + }
|
| + UNREACHABLE();
|
| + return OperandSize::kNone;
|
| }
|
|
|
| // static
|
| @@ -279,6 +333,7 @@ int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
|
| // static
|
| int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
|
| OperandScale operand_scale) {
|
| + DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
|
| // TODO(oth): restore this to a statically determined constant.
|
| int offset = 1;
|
| for (int operand_index = 0; operand_index < i; ++operand_index) {
|
| @@ -343,6 +398,31 @@ bool Bytecodes::IsJump(Bytecode bytecode) {
|
| return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
|
| }
|
|
|
| +// static
|
| +bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) {
|
| + return bytecode == Bytecode::kJumpIfToBooleanTrue ||
|
| + bytecode == Bytecode::kJumpIfToBooleanFalse ||
|
| + bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
|
| + bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
|
| +}
|
| +
|
| +// static
|
| +Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
|
| + switch (bytecode) {
|
| + case Bytecode::kJumpIfToBooleanTrue:
|
| + return Bytecode::kJumpIfTrue;
|
| + case Bytecode::kJumpIfToBooleanFalse:
|
| + return Bytecode::kJumpIfFalse;
|
| + case Bytecode::kJumpIfToBooleanTrueConstant:
|
| + return Bytecode::kJumpIfTrueConstant;
|
| + case Bytecode::kJumpIfToBooleanFalseConstant:
|
| + return Bytecode::kJumpIfFalseConstant;
|
| + default:
|
| + break;
|
| + }
|
| + UNREACHABLE();
|
| + return Bytecode::kIllegal;
|
| +}
|
|
|
| // static
|
| bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
|
| @@ -371,6 +451,11 @@ bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
|
| }
|
|
|
| // static
|
| +bool Bytecodes::IsLdarOrStar(Bytecode bytecode) {
|
| + return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
|
| +}
|
| +
|
| +// static
|
| bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
|
| switch (bytecode) {
|
| #define CASE(Name, ...) \
|
| @@ -461,6 +546,24 @@ bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
|
| }
|
|
|
| // static
|
| +int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
|
| + switch (operand_type) {
|
| + case OperandType::kMaybeReg:
|
| + case OperandType::kReg:
|
| + case OperandType::kRegOut:
|
| + return 1;
|
| + case OperandType::kRegPair:
|
| + case OperandType::kRegOutPair:
|
| + return 2;
|
| + case OperandType::kRegOutTriple:
|
| + return 3;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +// static
|
| bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
|
| switch (operand_type) {
|
| #define CASE(Name, _) \
|
| @@ -474,10 +577,62 @@ bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
|
| }
|
|
|
| // static
|
| -OperandScale Bytecodes::NextOperandScale(OperandScale operand_scale) {
|
| - DCHECK(operand_scale >= OperandScale::kSingle &&
|
| - operand_scale <= OperandScale::kMaxValid);
|
| - return static_cast<OperandScale>(2 * static_cast<int>(operand_scale));
|
| +OperandSize Bytecodes::SizeForSignedOperand(int value) {
|
| + if (kMinInt8 <= value && value <= kMaxInt8) {
|
| + return OperandSize::kByte;
|
| + } else if (kMinInt16 <= value && value <= kMaxInt16) {
|
| + return OperandSize::kShort;
|
| + } else {
|
| + return OperandSize::kQuad;
|
| + }
|
| +}
|
| +
|
| +// static
|
| +OperandSize Bytecodes::SizeForUnsignedOperand(int value) {
|
| + DCHECK_GE(value, 0);
|
| + if (value <= kMaxUInt8) {
|
| + return OperandSize::kByte;
|
| + } else if (value <= kMaxUInt16) {
|
| + return OperandSize::kShort;
|
| + } else {
|
| + return OperandSize::kQuad;
|
| + }
|
| +}
|
| +
|
| +OperandSize Bytecodes::SizeForUnsignedOperand(size_t value) {
|
| + if (value <= static_cast<size_t>(kMaxUInt8)) {
|
| + return OperandSize::kByte;
|
| + } else if (value <= static_cast<size_t>(kMaxUInt16)) {
|
| + return OperandSize::kShort;
|
| + } else if (value <= kMaxUInt32) {
|
| + return OperandSize::kQuad;
|
| + } else {
|
| + UNREACHABLE();
|
| + return OperandSize::kQuad;
|
| + }
|
| +}
|
| +
|
| +OperandScale Bytecodes::OperandSizesToScale(OperandSize size0,
|
| + OperandSize size1,
|
| + OperandSize size2,
|
| + OperandSize size3) {
|
| + OperandSize upper = std::max(size0, size1);
|
| + OperandSize lower = std::max(size2, size3);
|
| + OperandSize result = std::max(upper, lower);
|
| + // Operand sizes have been scaled before calling this function.
|
| + // Currently all scalable operands are byte sized at
|
| + // OperandScale::kSingle.
|
| + STATIC_ASSERT(static_cast<int>(OperandSize::kByte) ==
|
| + static_cast<int>(OperandScale::kSingle) &&
|
| + static_cast<int>(OperandSize::kShort) ==
|
| + static_cast<int>(OperandScale::kDouble) &&
|
| + static_cast<int>(OperandSize::kQuad) ==
|
| + static_cast<int>(OperandScale::kQuadruple));
|
| + OperandScale operand_scale = static_cast<OperandScale>(result);
|
| + DCHECK(operand_scale == OperandScale::kSingle ||
|
| + operand_scale == OperandScale::kDouble ||
|
| + operand_scale == OperandScale::kQuadruple);
|
| + return operand_scale;
|
| }
|
|
|
| // static
|
|
|