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 7namespace v8 { 8namespace internal { 9namespace interpreter { 10 11static const int kLastParamRegisterIndex = 12 (InterpreterFrameConstants::kRegisterFileFromFp - 13 InterpreterFrameConstants::kLastParamFromFp) / 14 kPointerSize; 15static const int kFunctionClosureRegisterIndex = 16 (InterpreterFrameConstants::kRegisterFileFromFp - 17 StandardFrameConstants::kFunctionOffset) / 18 kPointerSize; 19static const int kCurrentContextRegisterIndex = 20 (InterpreterFrameConstants::kRegisterFileFromFp - 21 StandardFrameConstants::kContextOffset) / 22 kPointerSize; 23static const int kNewTargetRegisterIndex = 24 (InterpreterFrameConstants::kRegisterFileFromFp - 25 InterpreterFrameConstants::kNewTargetFromFp) / 26 kPointerSize; 27static const int kBytecodeArrayRegisterIndex = 28 (InterpreterFrameConstants::kRegisterFileFromFp - 29 InterpreterFrameConstants::kBytecodeArrayFromFp) / 30 kPointerSize; 31static const int kBytecodeOffsetRegisterIndex = 32 (InterpreterFrameConstants::kRegisterFileFromFp - 33 InterpreterFrameConstants::kBytecodeOffsetFromFp) / 34 kPointerSize; 35static const int kCallerPCOffsetRegisterIndex = 36 (InterpreterFrameConstants::kRegisterFileFromFp - 37 InterpreterFrameConstants::kCallerPCOffsetFromFp) / 38 kPointerSize; 39 40Register 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 48int Register::ToParameterIndex(int parameter_count) const { 49 DCHECK(is_parameter()); 50 return index() - kLastParamRegisterIndex + parameter_count - 1; 51} 52 53Register Register::function_closure() { 54 return Register(kFunctionClosureRegisterIndex); 55} 56 57bool Register::is_function_closure() const { 58 return index() == kFunctionClosureRegisterIndex; 59} 60 61Register Register::current_context() { 62 return Register(kCurrentContextRegisterIndex); 63} 64 65bool Register::is_current_context() const { 66 return index() == kCurrentContextRegisterIndex; 67} 68 69Register Register::new_target() { return Register(kNewTargetRegisterIndex); } 70 71bool Register::is_new_target() const { 72 return index() == kNewTargetRegisterIndex; 73} 74 75Register Register::bytecode_array() { 76 return Register(kBytecodeArrayRegisterIndex); 77} 78 79bool Register::is_bytecode_array() const { 80 return index() == kBytecodeArrayRegisterIndex; 81} 82 83Register Register::bytecode_offset() { 84 return Register(kBytecodeOffsetRegisterIndex); 85} 86 87bool Register::is_bytecode_offset() const { 88 return index() == kBytecodeOffsetRegisterIndex; 89} 90 91// static 92Register Register::virtual_accumulator() { 93 return Register(kCallerPCOffsetRegisterIndex); 94} 95 96OperandSize 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 107bool 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 124std::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