Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/interpreter/bytecodes.h"
      6 
      7 #include <iomanip>
      8 
      9 #include "src/base/bits.h"
     10 #include "src/frames.h"
     11 #include "src/interpreter/bytecode-traits.h"
     12 #include "src/interpreter/interpreter.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 namespace interpreter {
     17 
     18 
     19 // static
     20 const char* Bytecodes::ToString(Bytecode bytecode) {
     21   switch (bytecode) {
     22 #define CASE(Name, ...)   \
     23   case Bytecode::k##Name: \
     24     return #Name;
     25     BYTECODE_LIST(CASE)
     26 #undef CASE
     27   }
     28   UNREACHABLE();
     29   return "";
     30 }
     31 
     32 // static
     33 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
     34   static const char kSeparator = '.';
     35 
     36   std::string value(ToString(bytecode));
     37   if (operand_scale > OperandScale::kSingle) {
     38     Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
     39     std::string suffix = ToString(prefix_bytecode);
     40     return value.append(1, kSeparator).append(suffix);
     41   } else {
     42     return value;
     43   }
     44 }
     45 
     46 // static
     47 const char* Bytecodes::AccumulatorUseToString(AccumulatorUse accumulator_use) {
     48   switch (accumulator_use) {
     49     case AccumulatorUse::kNone:
     50       return "None";
     51     case AccumulatorUse::kRead:
     52       return "Read";
     53     case AccumulatorUse::kWrite:
     54       return "Write";
     55     case AccumulatorUse::kReadWrite:
     56       return "ReadWrite";
     57   }
     58   UNREACHABLE();
     59   return "";
     60 }
     61 
     62 // static
     63 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
     64   switch (operand_type) {
     65 #define CASE(Name, _)        \
     66   case OperandType::k##Name: \
     67     return #Name;
     68     OPERAND_TYPE_LIST(CASE)
     69 #undef CASE
     70   }
     71   UNREACHABLE();
     72   return "";
     73 }
     74 
     75 // static
     76 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) {
     77   switch (operand_scale) {
     78 #define CASE(Name, _)         \
     79   case OperandScale::k##Name: \
     80     return #Name;
     81     OPERAND_SCALE_LIST(CASE)
     82 #undef CASE
     83   }
     84   UNREACHABLE();
     85   return "";
     86 }
     87 
     88 // static
     89 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
     90   switch (operand_size) {
     91     case OperandSize::kNone:
     92       return "None";
     93     case OperandSize::kByte:
     94       return "Byte";
     95     case OperandSize::kShort:
     96       return "Short";
     97     case OperandSize::kQuad:
     98       return "Quad";
     99   }
    100   UNREACHABLE();
    101   return "";
    102 }
    103 
    104 // static
    105 Bytecode Bytecodes::FromByte(uint8_t value) {
    106   Bytecode bytecode = static_cast<Bytecode>(value);
    107   DCHECK(bytecode <= Bytecode::kLast);
    108   return bytecode;
    109 }
    110 
    111 // static
    112 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
    113   DCHECK(!IsDebugBreak(bytecode));
    114   if (bytecode == Bytecode::kWide) {
    115     return Bytecode::kDebugBreakWide;
    116   }
    117   if (bytecode == Bytecode::kExtraWide) {
    118     return Bytecode::kDebugBreakExtraWide;
    119   }
    120   int bytecode_size = Size(bytecode, OperandScale::kSingle);
    121 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...)                    \
    122   if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
    123     return Bytecode::k##Name;                                            \
    124   }
    125   DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
    126 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
    127   UNREACHABLE();
    128   return Bytecode::kIllegal;
    129 }
    130 
    131 // static
    132 int Bytecodes::Size(Bytecode bytecode, OperandScale operand_scale) {
    133   int size = 1;
    134   for (int i = 0; i < NumberOfOperands(bytecode); i++) {
    135     OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
    136     int delta = static_cast<int>(operand_size);
    137     DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
    138     size += delta;
    139   }
    140   return size;
    141 }
    142 
    143 // static
    144 size_t Bytecodes::ReturnCount(Bytecode bytecode) {
    145   return bytecode == Bytecode::kReturn ? 1 : 0;
    146 }
    147 
    148 // static
    149 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
    150   DCHECK(bytecode <= Bytecode::kLast);
    151   switch (bytecode) {
    152 #define CASE(Name, ...)   \
    153   case Bytecode::k##Name: \
    154     return BytecodeTraits<__VA_ARGS__>::kOperandCount;
    155     BYTECODE_LIST(CASE)
    156 #undef CASE
    157   }
    158   UNREACHABLE();
    159   return 0;
    160 }
    161 
    162 // static
    163 int Bytecodes::NumberOfRegisterOperands(Bytecode bytecode) {
    164   DCHECK(bytecode <= Bytecode::kLast);
    165   switch (bytecode) {
    166 #define CASE(Name, ...)                              \
    167   case Bytecode::k##Name:                            \
    168     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
    169     return Name##Trait::kRegisterOperandCount;
    170     BYTECODE_LIST(CASE)
    171 #undef CASE
    172   }
    173   UNREACHABLE();
    174   return false;
    175 }
    176 
    177 // static
    178 Bytecode Bytecodes::OperandScaleToPrefixBytecode(OperandScale operand_scale) {
    179   switch (operand_scale) {
    180     case OperandScale::kQuadruple:
    181       return Bytecode::kExtraWide;
    182     case OperandScale::kDouble:
    183       return Bytecode::kWide;
    184     default:
    185       UNREACHABLE();
    186       return Bytecode::kIllegal;
    187   }
    188 }
    189 
    190 // static
    191 bool Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
    192   return operand_scale != OperandScale::kSingle;
    193 }
    194 
    195 // static
    196 OperandScale Bytecodes::PrefixBytecodeToOperandScale(Bytecode bytecode) {
    197   switch (bytecode) {
    198     case Bytecode::kExtraWide:
    199     case Bytecode::kDebugBreakExtraWide:
    200       return OperandScale::kQuadruple;
    201     case Bytecode::kWide:
    202     case Bytecode::kDebugBreakWide:
    203       return OperandScale::kDouble;
    204     default:
    205       UNREACHABLE();
    206       return OperandScale::kSingle;
    207   }
    208 }
    209 
    210 // static
    211 AccumulatorUse Bytecodes::GetAccumulatorUse(Bytecode bytecode) {
    212   DCHECK(bytecode <= Bytecode::kLast);
    213   switch (bytecode) {
    214 #define CASE(Name, ...)   \
    215   case Bytecode::k##Name: \
    216     return BytecodeTraits<__VA_ARGS__>::kAccumulatorUse;
    217     BYTECODE_LIST(CASE)
    218 #undef CASE
    219   }
    220   UNREACHABLE();
    221   return AccumulatorUse::kNone;
    222 }
    223 
    224 // static
    225 bool Bytecodes::ReadsAccumulator(Bytecode bytecode) {
    226   return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) ==
    227          AccumulatorUse::kRead;
    228 }
    229 
    230 // static
    231 bool Bytecodes::WritesAccumulator(Bytecode bytecode) {
    232   return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
    233          AccumulatorUse::kWrite;
    234 }
    235 
    236 // static
    237 bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) {
    238   switch (bytecode) {
    239     case Bytecode::kLdaTrue:
    240     case Bytecode::kLdaFalse:
    241     case Bytecode::kToBooleanLogicalNot:
    242     case Bytecode::kLogicalNot:
    243     case Bytecode::kTestEqual:
    244     case Bytecode::kTestNotEqual:
    245     case Bytecode::kTestEqualStrict:
    246     case Bytecode::kTestLessThan:
    247     case Bytecode::kTestLessThanOrEqual:
    248     case Bytecode::kTestGreaterThan:
    249     case Bytecode::kTestGreaterThanOrEqual:
    250     case Bytecode::kTestInstanceOf:
    251     case Bytecode::kTestIn:
    252     case Bytecode::kForInDone:
    253       return true;
    254     default:
    255       return false;
    256   }
    257 }
    258 
    259 // static
    260 bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
    261   switch (bytecode) {
    262     case Bytecode::kLdaZero:
    263     case Bytecode::kLdaSmi:
    264     case Bytecode::kLdaUndefined:
    265     case Bytecode::kLdaNull:
    266     case Bytecode::kLdaTheHole:
    267     case Bytecode::kLdaTrue:
    268     case Bytecode::kLdaFalse:
    269     case Bytecode::kLdaConstant:
    270     case Bytecode::kLdar:
    271       return true;
    272     default:
    273       return false;
    274   }
    275 }
    276 
    277 // static
    278 bool Bytecodes::IsJumpWithoutEffects(Bytecode bytecode) {
    279   return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
    280 }
    281 
    282 // static
    283 bool Bytecodes::IsRegisterLoadWithoutEffects(Bytecode bytecode) {
    284   switch (bytecode) {
    285     case Bytecode::kMov:
    286     case Bytecode::kPopContext:
    287     case Bytecode::kPushContext:
    288     case Bytecode::kStar:
    289     case Bytecode::kLdrUndefined:
    290       return true;
    291     default:
    292       return false;
    293   }
    294 }
    295 
    296 // static
    297 bool Bytecodes::IsWithoutExternalSideEffects(Bytecode bytecode) {
    298   // These bytecodes only manipulate interpreter frame state and will
    299   // never throw.
    300   return (IsAccumulatorLoadWithoutEffects(bytecode) ||
    301           IsRegisterLoadWithoutEffects(bytecode) ||
    302           bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
    303 }
    304 
    305 // static
    306 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
    307   DCHECK_LE(bytecode, Bytecode::kLast);
    308   DCHECK_LT(i, NumberOfOperands(bytecode));
    309   DCHECK_GE(i, 0);
    310   return GetOperandTypes(bytecode)[i];
    311 }
    312 
    313 // static
    314 const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) {
    315   DCHECK(bytecode <= Bytecode::kLast);
    316   switch (bytecode) {
    317 #define CASE(Name, ...)   \
    318   case Bytecode::k##Name: \
    319     return BytecodeTraits<__VA_ARGS__>::GetOperandTypes();
    320     BYTECODE_LIST(CASE)
    321 #undef CASE
    322   }
    323   UNREACHABLE();
    324   return nullptr;
    325 }
    326 
    327 // static
    328 const OperandTypeInfo* Bytecodes::GetOperandTypeInfos(Bytecode bytecode) {
    329   DCHECK(bytecode <= Bytecode::kLast);
    330   switch (bytecode) {
    331 #define CASE(Name, ...)   \
    332   case Bytecode::k##Name: \
    333     return BytecodeTraits<__VA_ARGS__>::GetOperandTypeInfos();
    334     BYTECODE_LIST(CASE)
    335 #undef CASE
    336   }
    337   UNREACHABLE();
    338   return nullptr;
    339 }
    340 
    341 // static
    342 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i,
    343                                       OperandScale operand_scale) {
    344   DCHECK_LT(i, NumberOfOperands(bytecode));
    345   return GetOperandSizes(bytecode, operand_scale)[i];
    346 }
    347 
    348 // static
    349 const OperandSize* Bytecodes::GetOperandSizes(Bytecode bytecode,
    350                                               OperandScale operand_scale) {
    351   DCHECK(bytecode <= Bytecode::kLast);
    352   switch (bytecode) {
    353 #define CASE(Name, ...)   \
    354   case Bytecode::k##Name: \
    355     return BytecodeTraits<__VA_ARGS__>::GetOperandSizes(operand_scale);
    356     BYTECODE_LIST(CASE)
    357 #undef CASE
    358   }
    359   UNREACHABLE();
    360   return nullptr;
    361 }
    362 
    363 // static
    364 int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
    365   DCHECK(bytecode <= Bytecode::kLast);
    366   switch (bytecode) {
    367 #define CASE(Name, ...)                              \
    368   case Bytecode::k##Name:                            \
    369     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
    370     return Name##Trait::kRegisterOperandBitmap;
    371     BYTECODE_LIST(CASE)
    372 #undef CASE
    373   }
    374   UNREACHABLE();
    375   return false;
    376 }
    377 
    378 // static
    379 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
    380                                 OperandScale operand_scale) {
    381   DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
    382   // TODO(oth): restore this to a statically determined constant.
    383   int offset = 1;
    384   for (int operand_index = 0; operand_index < i; ++operand_index) {
    385     OperandSize operand_size =
    386         GetOperandSize(bytecode, operand_index, operand_scale);
    387     offset += static_cast<int>(operand_size);
    388   }
    389   return offset;
    390 }
    391 
    392 // static
    393 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type,
    394                                      OperandScale operand_scale) {
    395   return static_cast<OperandSize>(
    396       ScaledOperandSize(operand_type, operand_scale));
    397 }
    398 
    399 // static
    400 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
    401   return bytecode == Bytecode::kJumpIfTrue ||
    402          bytecode == Bytecode::kJumpIfFalse ||
    403          bytecode == Bytecode::kJumpIfToBooleanTrue ||
    404          bytecode == Bytecode::kJumpIfToBooleanFalse ||
    405          bytecode == Bytecode::kJumpIfNotHole ||
    406          bytecode == Bytecode::kJumpIfNull ||
    407          bytecode == Bytecode::kJumpIfUndefined;
    408 }
    409 
    410 
    411 // static
    412 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
    413   return bytecode == Bytecode::kJumpIfTrueConstant ||
    414          bytecode == Bytecode::kJumpIfFalseConstant ||
    415          bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
    416          bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
    417          bytecode == Bytecode::kJumpIfNotHoleConstant ||
    418          bytecode == Bytecode::kJumpIfNullConstant ||
    419          bytecode == Bytecode::kJumpIfUndefinedConstant;
    420 }
    421 
    422 // static
    423 bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
    424   return IsConditionalJumpImmediate(bytecode) ||
    425          IsConditionalJumpConstant(bytecode);
    426 }
    427 
    428 
    429 // static
    430 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
    431   return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
    432 }
    433 
    434 
    435 // static
    436 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
    437   return bytecode == Bytecode::kJumpConstant ||
    438          IsConditionalJumpConstant(bytecode);
    439 }
    440 
    441 // static
    442 bool Bytecodes::IsJump(Bytecode bytecode) {
    443   return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
    444 }
    445 
    446 // static
    447 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) {
    448   return bytecode == Bytecode::kJumpIfToBooleanTrue ||
    449          bytecode == Bytecode::kJumpIfToBooleanFalse ||
    450          bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
    451          bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
    452 }
    453 
    454 // static
    455 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
    456   switch (bytecode) {
    457     case Bytecode::kJumpIfToBooleanTrue:
    458       return Bytecode::kJumpIfTrue;
    459     case Bytecode::kJumpIfToBooleanFalse:
    460       return Bytecode::kJumpIfFalse;
    461     case Bytecode::kJumpIfToBooleanTrueConstant:
    462       return Bytecode::kJumpIfTrueConstant;
    463     case Bytecode::kJumpIfToBooleanFalseConstant:
    464       return Bytecode::kJumpIfFalseConstant;
    465     default:
    466       break;
    467   }
    468   UNREACHABLE();
    469   return Bytecode::kIllegal;
    470 }
    471 
    472 // static
    473 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
    474   return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
    475          bytecode == Bytecode::kNew;
    476 }
    477 
    478 // static
    479 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
    480   return bytecode == Bytecode::kCallRuntime ||
    481          bytecode == Bytecode::kCallRuntimeForPair ||
    482          bytecode == Bytecode::kInvokeIntrinsic;
    483 }
    484 
    485 // static
    486 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
    487   switch (bytecode) {
    488 #define CASE(Name, ...) case Bytecode::k##Name:
    489     DEBUG_BREAK_BYTECODE_LIST(CASE);
    490 #undef CASE
    491     return true;
    492     default:
    493       break;
    494   }
    495   return false;
    496 }
    497 
    498 // static
    499 bool Bytecodes::IsLdarOrStar(Bytecode bytecode) {
    500   return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
    501 }
    502 
    503 // static
    504 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
    505   switch (bytecode) {
    506 #define CASE(Name, ...)                              \
    507   case Bytecode::k##Name:                            \
    508     typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
    509     return Name##Trait::IsScalable();
    510     BYTECODE_LIST(CASE)
    511 #undef CASE
    512   }
    513   UNREACHABLE();
    514   return false;
    515 }
    516 
    517 // static
    518 bool Bytecodes::IsPrefixScalingBytecode(Bytecode bytecode) {
    519   switch (bytecode) {
    520     case Bytecode::kExtraWide:
    521     case Bytecode::kDebugBreakExtraWide:
    522     case Bytecode::kWide:
    523     case Bytecode::kDebugBreakWide:
    524       return true;
    525     default:
    526       return false;
    527   }
    528 }
    529 
    530 // static
    531 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
    532   return bytecode == Bytecode::kReturn || IsJump(bytecode);
    533 }
    534 
    535 // static
    536 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
    537   return operand_type == OperandType::kMaybeReg;
    538 }
    539 
    540 // static
    541 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
    542   switch (operand_type) {
    543 #define CASE(Name, _)        \
    544   case OperandType::k##Name: \
    545     return true;
    546     REGISTER_OPERAND_TYPE_LIST(CASE)
    547 #undef CASE
    548 #define CASE(Name, _)        \
    549   case OperandType::k##Name: \
    550     break;
    551     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
    552 #undef CASE
    553   }
    554   return false;
    555 }
    556 
    557 // static
    558 bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
    559   switch (operand_type) {
    560 #define CASE(Name, _)        \
    561   case OperandType::k##Name: \
    562     return true;
    563     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
    564 #undef CASE
    565 #define CASE(Name, _)        \
    566   case OperandType::k##Name: \
    567     break;
    568     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
    569     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
    570 #undef CASE
    571   }
    572   return false;
    573 }
    574 
    575 // static
    576 bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
    577   switch (operand_type) {
    578 #define CASE(Name, _)        \
    579   case OperandType::k##Name: \
    580     return true;
    581     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
    582 #undef CASE
    583 #define CASE(Name, _)        \
    584   case OperandType::k##Name: \
    585     break;
    586     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
    587     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
    588 #undef CASE
    589   }
    590   return false;
    591 }
    592 
    593 // static
    594 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
    595   switch (operand_type) {
    596     case OperandType::kMaybeReg:
    597     case OperandType::kReg:
    598     case OperandType::kRegOut:
    599       return 1;
    600     case OperandType::kRegPair:
    601     case OperandType::kRegOutPair:
    602       return 2;
    603     case OperandType::kRegOutTriple:
    604       return 3;
    605     default:
    606       UNREACHABLE();
    607   }
    608   return 0;
    609 }
    610 
    611 // static
    612 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
    613   switch (operand_type) {
    614 #define CASE(Name, _)        \
    615   case OperandType::k##Name: \
    616     return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
    617     OPERAND_TYPE_LIST(CASE)
    618 #undef CASE
    619   }
    620   UNREACHABLE();
    621   return false;
    622 }
    623 
    624 // static
    625 OperandSize Bytecodes::SizeForSignedOperand(int value) {
    626   if (value >= kMinInt8 && value <= kMaxInt8) {
    627     return OperandSize::kByte;
    628   } else if (value >= kMinInt16 && value <= kMaxInt16) {
    629     return OperandSize::kShort;
    630   } else {
    631     return OperandSize::kQuad;
    632   }
    633 }
    634 
    635 // static
    636 OperandSize Bytecodes::SizeForUnsignedOperand(uint32_t value) {
    637   if (value <= kMaxUInt8) {
    638     return OperandSize::kByte;
    639   } else if (value <= kMaxUInt16) {
    640     return OperandSize::kShort;
    641   } else {
    642     return OperandSize::kQuad;
    643   }
    644 }
    645 
    646 // static
    647 Register Bytecodes::DecodeRegisterOperand(const uint8_t* operand_start,
    648                                           OperandType operand_type,
    649                                           OperandScale operand_scale) {
    650   DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
    651   int32_t operand =
    652       DecodeSignedOperand(operand_start, operand_type, operand_scale);
    653   return Register::FromOperand(operand);
    654 }
    655 
    656 // static
    657 int32_t Bytecodes::DecodeSignedOperand(const uint8_t* operand_start,
    658                                        OperandType operand_type,
    659                                        OperandScale operand_scale) {
    660   DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
    661   switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
    662     case OperandSize::kByte:
    663       return static_cast<int8_t>(*operand_start);
    664     case OperandSize::kShort:
    665       return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
    666     case OperandSize::kQuad:
    667       return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
    668     case OperandSize::kNone:
    669       UNREACHABLE();
    670   }
    671   return 0;
    672 }
    673 
    674 // static
    675 uint32_t Bytecodes::DecodeUnsignedOperand(const uint8_t* operand_start,
    676                                           OperandType operand_type,
    677                                           OperandScale operand_scale) {
    678   DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
    679   switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
    680     case OperandSize::kByte:
    681       return *operand_start;
    682     case OperandSize::kShort:
    683       return ReadUnalignedUInt16(operand_start);
    684     case OperandSize::kQuad:
    685       return ReadUnalignedUInt32(operand_start);
    686     case OperandSize::kNone:
    687       UNREACHABLE();
    688   }
    689   return 0;
    690 }
    691 
    692 // static
    693 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
    694                                 int parameter_count) {
    695   Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
    696   int prefix_offset = 0;
    697   OperandScale operand_scale = OperandScale::kSingle;
    698   if (IsPrefixScalingBytecode(bytecode)) {
    699     prefix_offset = 1;
    700     operand_scale = Bytecodes::PrefixBytecodeToOperandScale(bytecode);
    701     bytecode = Bytecodes::FromByte(bytecode_start[1]);
    702   }
    703 
    704   // Prepare to print bytecode and operands as hex digits.
    705   std::ios saved_format(nullptr);
    706   saved_format.copyfmt(saved_format);
    707   os.fill('0');
    708   os.flags(std::ios::hex);
    709 
    710   int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
    711   for (int i = 0; i < prefix_offset + bytecode_size; i++) {
    712     os << std::setw(2) << static_cast<uint32_t>(bytecode_start[i]) << ' ';
    713   }
    714   os.copyfmt(saved_format);
    715 
    716   const int kBytecodeColumnSize = 6;
    717   for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
    718     os << "   ";
    719   }
    720 
    721   os << Bytecodes::ToString(bytecode, operand_scale) << " ";
    722 
    723   // Operands for the debug break are from the original instruction.
    724   if (IsDebugBreak(bytecode)) return os;
    725 
    726   int number_of_operands = NumberOfOperands(bytecode);
    727   int range = 0;
    728   for (int i = 0; i < number_of_operands; i++) {
    729     OperandType op_type = GetOperandType(bytecode, i);
    730     const uint8_t* operand_start =
    731         &bytecode_start[prefix_offset +
    732                         GetOperandOffset(bytecode, i, operand_scale)];
    733     switch (op_type) {
    734       case interpreter::OperandType::kRegCount:
    735         os << "#"
    736            << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
    737         break;
    738       case interpreter::OperandType::kIdx:
    739       case interpreter::OperandType::kRuntimeId:
    740       case interpreter::OperandType::kIntrinsicId:
    741         os << "["
    742            << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
    743            << "]";
    744         break;
    745       case interpreter::OperandType::kImm:
    746         os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
    747            << "]";
    748         break;
    749       case interpreter::OperandType::kFlag8:
    750         os << "#"
    751            << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
    752         break;
    753       case interpreter::OperandType::kMaybeReg:
    754       case interpreter::OperandType::kReg:
    755       case interpreter::OperandType::kRegOut: {
    756         Register reg =
    757             DecodeRegisterOperand(operand_start, op_type, operand_scale);
    758         os << reg.ToString(parameter_count);
    759         break;
    760       }
    761       case interpreter::OperandType::kRegOutTriple:
    762         range += 1;
    763       case interpreter::OperandType::kRegOutPair:
    764       case interpreter::OperandType::kRegPair: {
    765         range += 1;
    766         Register first_reg =
    767             DecodeRegisterOperand(operand_start, op_type, operand_scale);
    768         Register last_reg = Register(first_reg.index() + range);
    769         os << first_reg.ToString(parameter_count) << "-"
    770            << last_reg.ToString(parameter_count);
    771         break;
    772       }
    773       case interpreter::OperandType::kNone:
    774         UNREACHABLE();
    775         break;
    776     }
    777     if (i != number_of_operands - 1) {
    778       os << ", ";
    779     }
    780   }
    781   return os;
    782 }
    783 
    784 // static
    785 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
    786                                    OperandScale operand_scale) {
    787   return operand_scale == OperandScale::kSingle ||
    788          Bytecodes::IsBytecodeWithScalableOperands(bytecode);
    789 }
    790 
    791 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
    792   return os << Bytecodes::ToString(bytecode);
    793 }
    794 
    795 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use) {
    796   return os << Bytecodes::AccumulatorUseToString(use);
    797 }
    798 
    799 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
    800   return os << Bytecodes::OperandSizeToString(operand_size);
    801 }
    802 
    803 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) {
    804   return os << Bytecodes::OperandScaleToString(operand_scale);
    805 }
    806 
    807 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
    808   return os << Bytecodes::OperandTypeToString(operand_type);
    809 }
    810 
    811 static const int kLastParamRegisterIndex =
    812     (InterpreterFrameConstants::kRegisterFileFromFp -
    813      InterpreterFrameConstants::kLastParamFromFp) /
    814     kPointerSize;
    815 static const int kFunctionClosureRegisterIndex =
    816     (InterpreterFrameConstants::kRegisterFileFromFp -
    817      StandardFrameConstants::kFunctionOffset) /
    818     kPointerSize;
    819 static const int kCurrentContextRegisterIndex =
    820     (InterpreterFrameConstants::kRegisterFileFromFp -
    821      StandardFrameConstants::kContextOffset) /
    822     kPointerSize;
    823 static const int kNewTargetRegisterIndex =
    824     (InterpreterFrameConstants::kRegisterFileFromFp -
    825      InterpreterFrameConstants::kNewTargetFromFp) /
    826     kPointerSize;
    827 static const int kBytecodeArrayRegisterIndex =
    828     (InterpreterFrameConstants::kRegisterFileFromFp -
    829      InterpreterFrameConstants::kBytecodeArrayFromFp) /
    830     kPointerSize;
    831 static const int kBytecodeOffsetRegisterIndex =
    832     (InterpreterFrameConstants::kRegisterFileFromFp -
    833      InterpreterFrameConstants::kBytecodeOffsetFromFp) /
    834     kPointerSize;
    835 static const int kCallerPCOffsetRegisterIndex =
    836     (InterpreterFrameConstants::kRegisterFileFromFp -
    837      InterpreterFrameConstants::kCallerPCOffsetFromFp) /
    838     kPointerSize;
    839 
    840 Register Register::FromParameterIndex(int index, int parameter_count) {
    841   DCHECK_GE(index, 0);
    842   DCHECK_LT(index, parameter_count);
    843   int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
    844   DCHECK_LT(register_index, 0);
    845   return Register(register_index);
    846 }
    847 
    848 int Register::ToParameterIndex(int parameter_count) const {
    849   DCHECK(is_parameter());
    850   return index() - kLastParamRegisterIndex + parameter_count - 1;
    851 }
    852 
    853 Register Register::function_closure() {
    854   return Register(kFunctionClosureRegisterIndex);
    855 }
    856 
    857 bool Register::is_function_closure() const {
    858   return index() == kFunctionClosureRegisterIndex;
    859 }
    860 
    861 Register Register::current_context() {
    862   return Register(kCurrentContextRegisterIndex);
    863 }
    864 
    865 bool Register::is_current_context() const {
    866   return index() == kCurrentContextRegisterIndex;
    867 }
    868 
    869 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
    870 
    871 bool Register::is_new_target() const {
    872   return index() == kNewTargetRegisterIndex;
    873 }
    874 
    875 Register Register::bytecode_array() {
    876   return Register(kBytecodeArrayRegisterIndex);
    877 }
    878 
    879 bool Register::is_bytecode_array() const {
    880   return index() == kBytecodeArrayRegisterIndex;
    881 }
    882 
    883 Register Register::bytecode_offset() {
    884   return Register(kBytecodeOffsetRegisterIndex);
    885 }
    886 
    887 bool Register::is_bytecode_offset() const {
    888   return index() == kBytecodeOffsetRegisterIndex;
    889 }
    890 
    891 // static
    892 Register Register::virtual_accumulator() {
    893   return Register(kCallerPCOffsetRegisterIndex);
    894 }
    895 
    896 OperandSize Register::SizeOfOperand() const {
    897   int32_t operand = ToOperand();
    898   if (operand >= kMinInt8 && operand <= kMaxInt8) {
    899     return OperandSize::kByte;
    900   } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
    901     return OperandSize::kShort;
    902   } else {
    903     return OperandSize::kQuad;
    904   }
    905 }
    906 
    907 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
    908                              Register reg4, Register reg5) {
    909   if (reg1.index() + 1 != reg2.index()) {
    910     return false;
    911   }
    912   if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
    913     return false;
    914   }
    915   if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
    916     return false;
    917   }
    918   if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
    919     return false;
    920   }
    921   return true;
    922 }
    923 
    924 std::string Register::ToString(int parameter_count) {
    925   if (is_current_context()) {
    926     return std::string("<context>");
    927   } else if (is_function_closure()) {
    928     return std::string("<closure>");
    929   } else if (is_new_target()) {
    930     return std::string("<new.target>");
    931   } else if (is_parameter()) {
    932     int parameter_index = ToParameterIndex(parameter_count);
    933     if (parameter_index == 0) {
    934       return std::string("<this>");
    935     } else {
    936       std::ostringstream s;
    937       s << "a" << parameter_index - 1;
    938       return s.str();
    939     }
    940   } else {
    941     std::ostringstream s;
    942     s << "r" << index();
    943     return s.str();
    944   }
    945 }
    946 
    947 }  // namespace interpreter
    948 }  // namespace internal
    949 }  // namespace v8
    950