| 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 |