OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-decoder.h" | 5 #include "src/interpreter/bytecode-decoder.h" |
6 | 6 |
7 #include <iomanip> | 7 #include <iomanip> |
8 | 8 |
9 #include "src/utils.h" | 9 #include "src/utils.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace interpreter { | 13 namespace interpreter { |
14 | 14 |
15 // static | 15 // static |
16 Register BytecodeDecoder::DecodeRegisterOperand(const uint8_t* operand_start, | 16 Register BytecodeDecoder::DecodeRegisterOperand(const uint8_t* operand_start, |
17 OperandType operand_type, | 17 OperandType operand_type, |
18 OperandScale operand_scale) { | 18 OperandScale operand_scale) { |
19 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); | 19 DCHECK(Bytecodes::IsRegisterOperandType(operand_type)); |
20 int32_t operand = | 20 int32_t operand = |
21 DecodeSignedOperand(operand_start, operand_type, operand_scale); | 21 DecodeSignedOperand(operand_start, operand_type, operand_scale); |
22 return Register::FromOperand(operand); | 22 return Register::FromOperand(operand); |
23 } | 23 } |
24 | 24 |
25 // static | 25 // static |
| 26 RegisterList BytecodeDecoder::DecodeRegisterListOperand( |
| 27 const uint8_t* operand_start, uint32_t count, OperandType operand_type, |
| 28 OperandScale operand_scale) { |
| 29 Register first_reg = |
| 30 DecodeRegisterOperand(operand_start, operand_type, operand_scale); |
| 31 return RegisterList(first_reg.index(), static_cast<int>(count)); |
| 32 } |
| 33 |
| 34 // static |
26 int32_t BytecodeDecoder::DecodeSignedOperand(const uint8_t* operand_start, | 35 int32_t BytecodeDecoder::DecodeSignedOperand(const uint8_t* operand_start, |
27 OperandType operand_type, | 36 OperandType operand_type, |
28 OperandScale operand_scale) { | 37 OperandScale operand_scale) { |
29 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); | 38 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); |
30 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) { | 39 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) { |
31 case OperandSize::kByte: | 40 case OperandSize::kByte: |
32 return static_cast<int8_t>(*operand_start); | 41 return static_cast<int8_t>(*operand_start); |
33 case OperandSize::kShort: | 42 case OperandSize::kShort: |
34 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start)); | 43 return static_cast<int16_t>(ReadUnalignedUInt16(operand_start)); |
35 case OperandSize::kQuad: | 44 case OperandSize::kQuad: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) { | 96 for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) { |
88 os << " "; | 97 os << " "; |
89 } | 98 } |
90 | 99 |
91 os << Bytecodes::ToString(bytecode, operand_scale) << " "; | 100 os << Bytecodes::ToString(bytecode, operand_scale) << " "; |
92 | 101 |
93 // Operands for the debug break are from the original instruction. | 102 // Operands for the debug break are from the original instruction. |
94 if (Bytecodes::IsDebugBreak(bytecode)) return os; | 103 if (Bytecodes::IsDebugBreak(bytecode)) return os; |
95 | 104 |
96 int number_of_operands = Bytecodes::NumberOfOperands(bytecode); | 105 int number_of_operands = Bytecodes::NumberOfOperands(bytecode); |
97 int range = 0; | |
98 for (int i = 0; i < number_of_operands; i++) { | 106 for (int i = 0; i < number_of_operands; i++) { |
99 OperandType op_type = Bytecodes::GetOperandType(bytecode, i); | 107 OperandType op_type = Bytecodes::GetOperandType(bytecode, i); |
100 int operand_offset = | 108 int operand_offset = |
101 Bytecodes::GetOperandOffset(bytecode, i, operand_scale); | 109 Bytecodes::GetOperandOffset(bytecode, i, operand_scale); |
102 const uint8_t* operand_start = | 110 const uint8_t* operand_start = |
103 &bytecode_start[prefix_offset + operand_offset]; | 111 &bytecode_start[prefix_offset + operand_offset]; |
104 switch (op_type) { | 112 switch (op_type) { |
105 case interpreter::OperandType::kRegCount: | |
106 os << "#" | |
107 << DecodeUnsignedOperand(operand_start, op_type, operand_scale); | |
108 break; | |
109 case interpreter::OperandType::kIdx: | 113 case interpreter::OperandType::kIdx: |
110 case interpreter::OperandType::kUImm: | 114 case interpreter::OperandType::kUImm: |
111 case interpreter::OperandType::kRuntimeId: | 115 case interpreter::OperandType::kRuntimeId: |
112 case interpreter::OperandType::kIntrinsicId: | 116 case interpreter::OperandType::kIntrinsicId: |
113 os << "[" | 117 os << "[" |
114 << DecodeUnsignedOperand(operand_start, op_type, operand_scale) | 118 << DecodeUnsignedOperand(operand_start, op_type, operand_scale) |
115 << "]"; | 119 << "]"; |
116 break; | 120 break; |
117 case interpreter::OperandType::kImm: | 121 case interpreter::OperandType::kImm: |
118 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale) | 122 os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale) |
119 << "]"; | 123 << "]"; |
120 break; | 124 break; |
121 case interpreter::OperandType::kFlag8: | 125 case interpreter::OperandType::kFlag8: |
122 os << "#" | 126 os << "#" |
123 << DecodeUnsignedOperand(operand_start, op_type, operand_scale); | 127 << DecodeUnsignedOperand(operand_start, op_type, operand_scale); |
124 break; | 128 break; |
125 case interpreter::OperandType::kMaybeReg: | |
126 case interpreter::OperandType::kReg: | 129 case interpreter::OperandType::kReg: |
127 case interpreter::OperandType::kRegOut: { | 130 case interpreter::OperandType::kRegOut: { |
128 Register reg = | 131 Register reg = |
129 DecodeRegisterOperand(operand_start, op_type, operand_scale); | 132 DecodeRegisterOperand(operand_start, op_type, operand_scale); |
130 os << reg.ToString(parameter_count); | 133 os << reg.ToString(parameter_count); |
131 break; | 134 break; |
132 } | 135 } |
133 case interpreter::OperandType::kRegOutTriple: | 136 case interpreter::OperandType::kRegOutTriple: { |
134 range += 1; | 137 RegisterList reg_list = |
| 138 DecodeRegisterListOperand(operand_start, 3, op_type, operand_scale); |
| 139 os << reg_list.first_register().ToString(parameter_count) << "-" |
| 140 << reg_list.last_register().ToString(parameter_count); |
| 141 break; |
| 142 } |
135 case interpreter::OperandType::kRegOutPair: | 143 case interpreter::OperandType::kRegOutPair: |
136 case interpreter::OperandType::kRegPair: { | 144 case interpreter::OperandType::kRegPair: { |
137 range += 1; | 145 RegisterList reg_list = |
138 Register first_reg = | 146 DecodeRegisterListOperand(operand_start, 2, op_type, operand_scale); |
139 DecodeRegisterOperand(operand_start, op_type, operand_scale); | 147 os << reg_list.first_register().ToString(parameter_count) << "-" |
140 Register last_reg = Register(first_reg.index() + range); | 148 << reg_list.last_register().ToString(parameter_count); |
141 os << first_reg.ToString(parameter_count) << "-" | 149 break; |
142 << last_reg.ToString(parameter_count); | 150 } |
| 151 case interpreter::OperandType::kRegList: { |
| 152 DCHECK_LT(i, number_of_operands - 1); |
| 153 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, i + 1), |
| 154 OperandType::kRegCount); |
| 155 int reg_count_offset = |
| 156 Bytecodes::GetOperandOffset(bytecode, i + 1, operand_scale); |
| 157 const uint8_t* reg_count_operand = |
| 158 &bytecode_start[prefix_offset + reg_count_offset]; |
| 159 uint32_t count = DecodeUnsignedOperand( |
| 160 reg_count_operand, OperandType::kRegCount, operand_scale); |
| 161 RegisterList reg_list = DecodeRegisterListOperand( |
| 162 operand_start, count, op_type, operand_scale); |
| 163 os << reg_list.first_register().ToString(parameter_count) << "-" |
| 164 << reg_list.last_register().ToString(parameter_count); |
| 165 i++; // Skip kRegCount. |
143 break; | 166 break; |
144 } | 167 } |
145 case interpreter::OperandType::kNone: | 168 case interpreter::OperandType::kNone: |
| 169 case interpreter::OperandType::kRegCount: // Dealt with in kRegList. |
146 UNREACHABLE(); | 170 UNREACHABLE(); |
147 break; | 171 break; |
148 } | 172 } |
149 if (i != number_of_operands - 1) { | 173 if (i != number_of_operands - 1) { |
150 os << ", "; | 174 os << ", "; |
151 } | 175 } |
152 } | 176 } |
153 return os; | 177 return os; |
154 } | 178 } |
155 | 179 |
156 } // namespace interpreter | 180 } // namespace interpreter |
157 } // namespace internal | 181 } // namespace internal |
158 } // namespace v8 | 182 } // namespace v8 |
OLD | NEW |