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 kBytecodeArrayRegisterIndex =
24 (InterpreterFrameConstants::kRegisterFileFromFp -
25 InterpreterFrameConstants::kBytecodeArrayFromFp) /
26 kPointerSize;
27 static const int kBytecodeOffsetRegisterIndex =
28 (InterpreterFrameConstants::kRegisterFileFromFp -
29 InterpreterFrameConstants::kBytecodeOffsetFromFp) /
30 kPointerSize;
31 static const int kCallerPCOffsetRegisterIndex =
32 (InterpreterFrameConstants::kRegisterFileFromFp -
33 InterpreterFrameConstants::kCallerPCOffsetFromFp) /
34 kPointerSize;
35
FromParameterIndex(int index,int parameter_count)36 Register Register::FromParameterIndex(int index, int parameter_count) {
37 DCHECK_GE(index, 0);
38 DCHECK_LT(index, parameter_count);
39 int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
40 DCHECK_LT(register_index, 0);
41 return Register(register_index);
42 }
43
ToParameterIndex(int parameter_count) const44 int Register::ToParameterIndex(int parameter_count) const {
45 DCHECK(is_parameter());
46 return index() - kLastParamRegisterIndex + parameter_count - 1;
47 }
48
function_closure()49 Register Register::function_closure() {
50 return Register(kFunctionClosureRegisterIndex);
51 }
52
is_function_closure() const53 bool Register::is_function_closure() const {
54 return index() == kFunctionClosureRegisterIndex;
55 }
56
current_context()57 Register Register::current_context() {
58 return Register(kCurrentContextRegisterIndex);
59 }
60
is_current_context() const61 bool Register::is_current_context() const {
62 return index() == kCurrentContextRegisterIndex;
63 }
64
bytecode_array()65 Register Register::bytecode_array() {
66 return Register(kBytecodeArrayRegisterIndex);
67 }
68
is_bytecode_array() const69 bool Register::is_bytecode_array() const {
70 return index() == kBytecodeArrayRegisterIndex;
71 }
72
bytecode_offset()73 Register Register::bytecode_offset() {
74 return Register(kBytecodeOffsetRegisterIndex);
75 }
76
is_bytecode_offset() const77 bool Register::is_bytecode_offset() const {
78 return index() == kBytecodeOffsetRegisterIndex;
79 }
80
81 // static
virtual_accumulator()82 Register Register::virtual_accumulator() {
83 return Register(kCallerPCOffsetRegisterIndex);
84 }
85
SizeOfOperand() const86 OperandSize Register::SizeOfOperand() const {
87 int32_t operand = ToOperand();
88 if (operand >= kMinInt8 && operand <= kMaxInt8) {
89 return OperandSize::kByte;
90 } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
91 return OperandSize::kShort;
92 } else {
93 return OperandSize::kQuad;
94 }
95 }
96
AreContiguous(Register reg1,Register reg2,Register reg3,Register reg4,Register reg5)97 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
98 Register reg4, Register reg5) {
99 if (reg1.index() + 1 != reg2.index()) {
100 return false;
101 }
102 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
103 return false;
104 }
105 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
106 return false;
107 }
108 if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
109 return false;
110 }
111 return true;
112 }
113
ToString(int parameter_count) const114 std::string Register::ToString(int parameter_count) const {
115 if (is_current_context()) {
116 return std::string("<context>");
117 } else if (is_function_closure()) {
118 return std::string("<closure>");
119 } else if (is_parameter()) {
120 int parameter_index = ToParameterIndex(parameter_count);
121 if (parameter_index == 0) {
122 return std::string("<this>");
123 } else {
124 std::ostringstream s;
125 s << "a" << parameter_index - 1;
126 return s.str();
127 }
128 } else {
129 std::ostringstream s;
130 s << "r" << index();
131 return s.str();
132 }
133 }
134
135 } // namespace interpreter
136 } // namespace internal
137 } // namespace v8
138