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