| 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 "test/unittests/compiler/interpreter-assembler-unittest.h" | 5 #include "test/unittests/compiler/interpreter-assembler-unittest.h" |
| 6 | 6 |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
| 9 #include "src/unique.h" | 9 #include "src/unique.h" |
| 10 #include "test/unittests/compiler/compiler-test-utils.h" | 10 #include "test/unittests/compiler/compiler-test-utils.h" |
| 11 #include "test/unittests/compiler/node-test-utils.h" | 11 #include "test/unittests/compiler/node-test-utils.h" |
| 12 | 12 |
| 13 using ::testing::_; | 13 using ::testing::_; |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace compiler { | 17 namespace compiler { |
| 18 | 18 |
| 19 const interpreter::Bytecode kBytecodes[] = { | 19 const interpreter::Bytecode kBytecodes[] = { |
| 20 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, | 20 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, |
| 21 BYTECODE_LIST(DEFINE_BYTECODE) | 21 BYTECODE_LIST(DEFINE_BYTECODE) |
| 22 #undef DEFINE_BYTECODE | 22 #undef DEFINE_BYTECODE |
| 23 }; | 23 }; |
| 24 | 24 |
| 25 | 25 |
| 26 Graph* | 26 Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, |
| 27 InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() { | 27 const Matcher<Node*>& rhs_matcher) { |
| 28 End(); | 28 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) |
| 29 return graph(); | 29 : IsInt32Add(lhs_matcher, rhs_matcher); |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, |
| 34 const Matcher<Node*>& rhs_matcher) { |
| 35 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) |
| 36 : IsInt32Sub(lhs_matcher, rhs_matcher); |
| 37 } |
| 38 |
| 39 |
| 40 Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, |
| 41 const Matcher<Node*>& rhs_matcher) { |
| 42 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) |
| 43 : IsWord32Shl(lhs_matcher, rhs_matcher); |
| 44 } |
| 45 |
| 46 |
| 47 Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, |
| 48 const Matcher<Node*>& rhs_matcher) { |
| 49 return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) |
| 50 : IsWord32Sar(lhs_matcher, rhs_matcher); |
| 51 } |
| 52 |
| 53 |
| 33 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( | 54 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( |
| 34 const Matcher<LoadRepresentation>& rep_matcher, | 55 const Matcher<LoadRepresentation>& rep_matcher, |
| 35 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { | 56 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { |
| 36 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, | 57 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, |
| 37 graph()->start(), graph()->start()); | 58 graph()->start(), graph()->start()); |
| 38 } | 59 } |
| 39 | 60 |
| 40 | 61 |
| 41 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( | 62 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( |
| 42 const Matcher<StoreRepresentation>& rep_matcher, | 63 const Matcher<StoreRepresentation>& rep_matcher, |
| 43 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, | 64 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, |
| 44 const Matcher<Node*>& value_matcher) { | 65 const Matcher<Node*>& value_matcher) { |
| 45 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, | 66 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, |
| 46 value_matcher, graph()->start(), | 67 value_matcher, graph()->start(), |
| 47 graph()->start()); | 68 graph()->start()); |
| 48 } | 69 } |
| 49 | 70 |
| 50 | 71 |
| 51 Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, | 72 Matcher<Node*> |
| 52 const Matcher<Node*>& rhs_matcher) { | 73 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( |
| 53 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) | 74 int operand) { |
| 54 : IsInt32Add(lhs_matcher, rhs_matcher); | 75 return IsLoad( |
| 76 kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 77 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), |
| 78 IsInt32Constant(1 + operand))); |
| 55 } | 79 } |
| 56 | 80 |
| 57 | 81 |
| 58 Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, | 82 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
| 59 const Matcher<Node*>& rhs_matcher) { | 83 IsBytecodeOperandSignExtended(int operand) { |
| 60 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) | 84 Matcher<Node*> load_matcher = IsLoad( |
| 61 : IsInt32Sub(lhs_matcher, rhs_matcher); | 85 kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), |
| 86 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), |
| 87 IsInt32Constant(1 + operand))); |
| 88 if (kPointerSize == 8) { |
| 89 load_matcher = IsChangeInt32ToInt64(load_matcher); |
| 90 } |
| 91 return load_matcher; |
| 62 } | 92 } |
| 63 | 93 |
| 64 | 94 |
| 65 Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, | 95 Graph* |
| 66 const Matcher<Node*>& rhs_matcher) { | 96 InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() { |
| 67 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) | 97 End(); |
| 68 : IsWord32Shl(lhs_matcher, rhs_matcher); | 98 return graph(); |
| 69 } | 99 } |
| 70 | 100 |
| 71 | 101 |
| 72 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { | 102 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { |
| 73 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 103 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 74 InterpreterAssemblerForTest m(this, bytecode); | 104 InterpreterAssemblerForTest m(this, bytecode); |
| 75 m.Dispatch(); | 105 m.Dispatch(); |
| 76 Graph* graph = m.GetCompletedGraph(); | 106 Graph* graph = m.GetCompletedGraph(); |
| 77 | 107 |
| 78 Node* end = graph->end(); | 108 Node* end = graph->end(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 graph->start(), graph->start())); | 161 graph->start(), graph->start())); |
| 132 } | 162 } |
| 133 } | 163 } |
| 134 | 164 |
| 135 | 165 |
| 136 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { | 166 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
| 137 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 167 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 138 InterpreterAssemblerForTest m(this, bytecode); | 168 InterpreterAssemblerForTest m(this, bytecode); |
| 139 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); | 169 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); |
| 140 for (int i = 0; i < number_of_operands; i++) { | 170 for (int i = 0; i < number_of_operands; i++) { |
| 141 Node* load_arg_node = m.BytecodeOperand(i); | 171 switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { |
| 142 EXPECT_THAT( | 172 case interpreter::OperandType::kImm8: |
| 143 load_arg_node, | 173 EXPECT_THAT(m.BytecodeOperandImm8(i), |
| 144 m.IsLoad( | 174 m.IsBytecodeOperandSignExtended(i)); |
| 145 kMachUint8, | 175 break; |
| 146 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 176 case interpreter::OperandType::kReg: |
| 147 IsIntPtrAdd( | 177 EXPECT_THAT(m.BytecodeOperandReg(i), |
| 148 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 178 m.IsBytecodeOperandSignExtended(i)); |
| 149 IsInt32Constant(1 + i)))); | 179 break; |
| 180 case interpreter::OperandType::kNone: |
| 181 UNREACHABLE(); |
| 182 break; |
| 183 } |
| 150 } | 184 } |
| 151 } | 185 } |
| 152 } | 186 } |
| 153 | |
| 154 | |
| 155 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperandSignExtended) { | |
| 156 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | |
| 157 InterpreterAssemblerForTest m(this, bytecode); | |
| 158 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); | |
| 159 for (int i = 0; i < number_of_operands; i++) { | |
| 160 Node* load_arg_node = m.BytecodeOperandSignExtended(i); | |
| 161 Matcher<Node*> load_matcher = m.IsLoad( | |
| 162 kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | |
| 163 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | |
| 164 IsInt32Constant(1 + i))); | |
| 165 if (kPointerSize == 8) { | |
| 166 load_matcher = IsChangeInt32ToInt64(load_matcher); | |
| 167 } | |
| 168 EXPECT_THAT(load_arg_node, load_matcher); | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 | 187 |
| 173 | 188 |
| 174 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { | 189 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { |
| 175 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 190 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 176 InterpreterAssemblerForTest m(this, bytecode); | 191 InterpreterAssemblerForTest m(this, bytecode); |
| 177 // Should be incoming accumulator if not set. | 192 // Should be incoming accumulator if not set. |
| 178 EXPECT_THAT(m.GetAccumulator(), | 193 EXPECT_THAT(m.GetAccumulator(), |
| 179 IsParameter(Linkage::kInterpreterAccumulatorParameter)); | 194 IsParameter(Linkage::kInterpreterAccumulatorParameter)); |
| 180 | 195 |
| 181 // Should be set by SedtAccumulator. | 196 // Should be set by SedtAccumulator. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); | 238 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); |
| 224 EXPECT_THAT( | 239 EXPECT_THAT( |
| 225 store_reg_node, | 240 store_reg_node, |
| 226 m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), | 241 m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), |
| 227 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 242 IsParameter(Linkage::kInterpreterRegisterFileParameter), |
| 228 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), | 243 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), |
| 229 store_value)); | 244 store_value)); |
| 230 } | 245 } |
| 231 } | 246 } |
| 232 | 247 |
| 248 |
| 249 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { |
| 250 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 251 InterpreterAssemblerForTest m(this, bytecode); |
| 252 Node* value = m.Int32Constant(44); |
| 253 EXPECT_THAT(m.SmiTag(value), |
| 254 IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); |
| 255 EXPECT_THAT(m.SmiUntag(value), |
| 256 IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); |
| 257 } |
| 258 } |
| 259 |
| 233 } // namespace compiler | 260 } // namespace compiler |
| 234 } // namespace internal | 261 } // namespace internal |
| 235 } // namespace v8 | 262 } // namespace v8 |
| OLD | NEW |