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 |