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/bytecode-register.h"
      6 
      7 namespace v8 {
      8 namespace internal {
      9 namespace interpreter {
     10 
     11 static const int kLastParamRegisterIndex =
     12     (InterpreterFrameConstants::kRegisterFileFromFp -
     13      InterpreterFrameConstants::kLastParamFromFp) /
     14     kPointerSize;
     15 static const int kFunctionClosureRegisterIndex =
     16     (InterpreterFrameConstants::kRegisterFileFromFp -
     17      StandardFrameConstants::kFunctionOffset) /
     18     kPointerSize;
     19 static const int kCurrentContextRegisterIndex =
     20     (InterpreterFrameConstants::kRegisterFileFromFp -
     21      StandardFrameConstants::kContextOffset) /
     22     kPointerSize;
     23 static const int kNewTargetRegisterIndex =
     24     (InterpreterFrameConstants::kRegisterFileFromFp -
     25      InterpreterFrameConstants::kNewTargetFromFp) /
     26     kPointerSize;
     27 static const int kBytecodeArrayRegisterIndex =
     28     (InterpreterFrameConstants::kRegisterFileFromFp -
     29      InterpreterFrameConstants::kBytecodeArrayFromFp) /
     30     kPointerSize;
     31 static const int kBytecodeOffsetRegisterIndex =
     32     (InterpreterFrameConstants::kRegisterFileFromFp -
     33      InterpreterFrameConstants::kBytecodeOffsetFromFp) /
     34     kPointerSize;
     35 static const int kCallerPCOffsetRegisterIndex =
     36     (InterpreterFrameConstants::kRegisterFileFromFp -
     37      InterpreterFrameConstants::kCallerPCOffsetFromFp) /
     38     kPointerSize;
     39 
     40 Register Register::FromParameterIndex(int index, int parameter_count) {
     41   DCHECK_GE(index, 0);
     42   DCHECK_LT(index, parameter_count);
     43   int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
     44   DCHECK_LT(register_index, 0);
     45   return Register(register_index);
     46 }
     47 
     48 int Register::ToParameterIndex(int parameter_count) const {
     49   DCHECK(is_parameter());
     50   return index() - kLastParamRegisterIndex + parameter_count - 1;
     51 }
     52 
     53 Register Register::function_closure() {
     54   return Register(kFunctionClosureRegisterIndex);
     55 }
     56 
     57 bool Register::is_function_closure() const {
     58   return index() == kFunctionClosureRegisterIndex;
     59 }
     60 
     61 Register Register::current_context() {
     62   return Register(kCurrentContextRegisterIndex);
     63 }
     64 
     65 bool Register::is_current_context() const {
     66   return index() == kCurrentContextRegisterIndex;
     67 }
     68 
     69 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
     70 
     71 bool Register::is_new_target() const {
     72   return index() == kNewTargetRegisterIndex;
     73 }
     74 
     75 Register Register::bytecode_array() {
     76   return Register(kBytecodeArrayRegisterIndex);
     77 }
     78 
     79 bool Register::is_bytecode_array() const {
     80   return index() == kBytecodeArrayRegisterIndex;
     81 }
     82 
     83 Register Register::bytecode_offset() {
     84   return Register(kBytecodeOffsetRegisterIndex);
     85 }
     86 
     87 bool Register::is_bytecode_offset() const {
     88   return index() == kBytecodeOffsetRegisterIndex;
     89 }
     90 
     91 // static
     92 Register Register::virtual_accumulator() {
     93   return Register(kCallerPCOffsetRegisterIndex);
     94 }
     95 
     96 OperandSize Register::SizeOfOperand() const {
     97   int32_t operand = ToOperand();
     98   if (operand >= kMinInt8 && operand <= kMaxInt8) {
     99     return OperandSize::kByte;
    100   } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
    101     return OperandSize::kShort;
    102   } else {
    103     return OperandSize::kQuad;
    104   }
    105 }
    106 
    107 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
    108                              Register reg4, Register reg5) {
    109   if (reg1.index() + 1 != reg2.index()) {
    110     return false;
    111   }
    112   if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
    113     return false;
    114   }
    115   if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
    116     return false;
    117   }
    118   if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
    119     return false;
    120   }
    121   return true;
    122 }
    123 
    124 std::string Register::ToString(int parameter_count) const {
    125   if (is_current_context()) {
    126     return std::string("<context>");
    127   } else if (is_function_closure()) {
    128     return std::string("<closure>");
    129   } else if (is_new_target()) {
    130     return std::string("<new.target>");
    131   } else if (is_parameter()) {
    132     int parameter_index = ToParameterIndex(parameter_count);
    133     if (parameter_index == 0) {
    134       return std::string("<this>");
    135     } else {
    136       std::ostringstream s;
    137       s << "a" << parameter_index - 1;
    138       return s.str();
    139     }
    140   } else {
    141     std::ostringstream s;
    142     s << "r" << index();
    143     return s.str();
    144   }
    145 }
    146 
    147 }  // namespace interpreter
    148 }  // namespace internal
    149 }  // namespace v8
    150