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