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 
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 = kFirstParamRegisterIndex - index;
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 kFirstParamRegisterIndex - index();
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