blob: 0106c577bd90646341070b5a61682a969ba20dc3 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
Ben Murdoch097c5b22016-05-18 11:27:45 +01005#include "test/unittests/interpreter/interpreter-assembler-unittest.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
7#include "src/code-factory.h"
8#include "src/compiler/graph.h"
9#include "src/compiler/node.h"
10#include "src/interface-descriptors.h"
11#include "src/isolate.h"
12#include "test/unittests/compiler/compiler-test-utils.h"
13#include "test/unittests/compiler/node-test-utils.h"
14
15using ::testing::_;
16
17namespace v8 {
18namespace internal {
Ben Murdoch097c5b22016-05-18 11:27:45 +010019
20using namespace compiler;
21
22namespace interpreter {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023
24const interpreter::Bytecode kBytecodes[] = {
25#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,
26 BYTECODE_LIST(DEFINE_BYTECODE)
27#undef DEFINE_BYTECODE
28};
29
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
31 return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value))
32 : IsInt32Constant(static_cast<int32_t>(value));
33}
34
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
36 const Matcher<Node*>& rhs_matcher) {
37 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher)
38 : IsInt32Add(lhs_matcher, rhs_matcher);
39}
40
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
42 const Matcher<Node*>& rhs_matcher) {
43 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher)
44 : IsInt32Sub(lhs_matcher, rhs_matcher);
45}
46
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
48 const Matcher<Node*>& rhs_matcher) {
49 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher)
50 : IsWord32Shl(lhs_matcher, rhs_matcher);
51}
52
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
54 const Matcher<Node*>& rhs_matcher) {
55 return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher)
56 : IsWord32Sar(lhs_matcher, rhs_matcher);
57}
58
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
60 const Matcher<Node*>& rhs_matcher) {
61 return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
62 : IsWord32Or(lhs_matcher, rhs_matcher);
63}
64
Ben Murdochda12d292016-06-02 14:46:10 +010065InterpreterAssemblerTest::InterpreterAssemblerForTest::
66 ~InterpreterAssemblerForTest() {
67 // Tests don't necessarily read and write accumulator but
68 // InterpreterAssembler checks accumulator uses.
69 if (Bytecodes::ReadsAccumulator(bytecode())) {
70 GetAccumulator();
71 }
72 if (Bytecodes::WritesAccumulator(bytecode())) {
73 SetAccumulator(nullptr);
74 }
75}
76
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
78 const Matcher<LoadRepresentation>& rep_matcher,
79 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) {
80 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _);
81}
82
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
84 const Matcher<StoreRepresentation>& rep_matcher,
85 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
86 const Matcher<Node*>& value_matcher) {
87 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher,
88 value_matcher, _, _);
89}
90
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091Matcher<Node*>
Ben Murdochda12d292016-06-02 14:46:10 +010092InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 int offset) {
94 return IsLoad(
95 MachineType::Uint8(),
Ben Murdoch097c5b22016-05-18 11:27:45 +010096 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
97 IsIntPtrAdd(
98 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +010099 IsIntPtrConstant(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100}
101
Ben Murdochda12d292016-06-02 14:46:10 +0100102Matcher<Node*>
103InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand(
104 int offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 Matcher<Node*> load_matcher = IsLoad(
106 MachineType::Int8(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
108 IsIntPtrAdd(
109 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100110 IsIntPtrConstant(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 if (kPointerSize == 8) {
112 load_matcher = IsChangeInt32ToInt64(load_matcher);
113 }
114 return load_matcher;
115}
116
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117Matcher<Node*>
Ben Murdochda12d292016-06-02 14:46:10 +0100118InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 int offset) {
120 if (TargetSupportsUnalignedAccess()) {
121 return IsLoad(
122 MachineType::Uint16(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100123 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
124 IsIntPtrAdd(
125 IsParameter(
126 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100127 IsIntPtrConstant(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129#if V8_TARGET_LITTLE_ENDIAN
Ben Murdochda12d292016-06-02 14:46:10 +0100130 const int kStep = -1;
131 const int kMsbOffset = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132#elif V8_TARGET_BIG_ENDIAN
Ben Murdochda12d292016-06-02 14:46:10 +0100133 const int kStep = 1;
134 const int kMsbOffset = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135#else
136#error "Unknown Architecture"
137#endif
Ben Murdochda12d292016-06-02 14:46:10 +0100138 Matcher<Node*> bytes[2];
139 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
140 bytes[i] = IsLoad(
141 MachineType::Uint8(),
142 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
143 IsIntPtrAdd(
144 IsParameter(
145 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
146 IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
147 }
148 return IsWord32Or(IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)),
149 bytes[1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150 }
151}
152
Ben Murdochda12d292016-06-02 14:46:10 +0100153Matcher<Node*>
154InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand(
155 int offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 Matcher<Node*> load_matcher;
157 if (TargetSupportsUnalignedAccess()) {
158 load_matcher = IsLoad(
159 MachineType::Int16(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
161 IsIntPtrAdd(
162 IsParameter(
163 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100164 IsIntPtrConstant(offset)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000165 } else {
166#if V8_TARGET_LITTLE_ENDIAN
Ben Murdochda12d292016-06-02 14:46:10 +0100167 const int kStep = -1;
168 const int kMsbOffset = 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169#elif V8_TARGET_BIG_ENDIAN
Ben Murdochda12d292016-06-02 14:46:10 +0100170 const int kStep = 1;
171 const int kMsbOffset = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172#else
173#error "Unknown Architecture"
174#endif
Ben Murdochda12d292016-06-02 14:46:10 +0100175 Matcher<Node*> bytes[2];
176 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
177 bytes[i] = IsLoad(
178 (i == 0) ? MachineType::Int8() : MachineType::Uint8(),
179 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
180 IsIntPtrAdd(
181 IsParameter(
182 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
183 IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
184 }
185 load_matcher = IsWord32Or(
186 IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), bytes[1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 }
188
189 if (kPointerSize == 8) {
190 load_matcher = IsChangeInt32ToInt64(load_matcher);
191 }
192 return load_matcher;
193}
194
Ben Murdochda12d292016-06-02 14:46:10 +0100195Matcher<Node*>
196InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand(
197 int offset) {
198 if (TargetSupportsUnalignedAccess()) {
199 return IsLoad(
200 MachineType::Uint32(),
201 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
202 IsIntPtrAdd(
203 IsParameter(
204 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
205 IsIntPtrConstant(offset)));
206 } else {
207#if V8_TARGET_LITTLE_ENDIAN
208 const int kStep = -1;
209 const int kMsbOffset = 3;
210#elif V8_TARGET_BIG_ENDIAN
211 const int kStep = 1;
212 const int kMsbOffset = 0;
213#else
214#error "Unknown Architecture"
215#endif
216 Matcher<Node*> bytes[4];
217 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
218 bytes[i] = IsLoad(
219 MachineType::Uint8(),
220 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
221 IsIntPtrAdd(
222 IsParameter(
223 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
224 IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
225 }
226 return IsWord32Or(
227 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)),
228 IsWord32Or(
229 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)),
230 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)),
231 bytes[3])));
232 }
233}
234
235Matcher<Node*>
236InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand(
237 int offset) {
238 Matcher<Node*> load_matcher;
239 if (TargetSupportsUnalignedAccess()) {
240 load_matcher = IsLoad(
241 MachineType::Int32(),
242 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
243 IsIntPtrAdd(
244 IsParameter(
245 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
246 IsIntPtrConstant(offset)));
247 } else {
248#if V8_TARGET_LITTLE_ENDIAN
249 const int kStep = -1;
250 int kMsbOffset = 3;
251#elif V8_TARGET_BIG_ENDIAN
252 const int kStep = 1;
253 int kMsbOffset = 0;
254#else
255#error "Unknown Architecture"
256#endif
257 Matcher<Node*> bytes[4];
258 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) {
259 bytes[i] = IsLoad(
260 (i == 0) ? MachineType::Int8() : MachineType::Uint8(),
261 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
262 IsIntPtrAdd(
263 IsParameter(
264 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
265 IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
266 }
267 load_matcher = IsWord32Or(
268 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)),
269 IsWord32Or(
270 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)),
271 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)),
272 bytes[3])));
273 }
274
275 if (kPointerSize == 8) {
276 load_matcher = IsChangeInt32ToInt64(load_matcher);
277 }
278 return load_matcher;
279}
280
281Matcher<Node*>
282InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedOperand(
283 int offset, OperandSize operand_size) {
284 switch (operand_size) {
285 case OperandSize::kByte:
286 return IsSignedByteOperand(offset);
287 case OperandSize::kShort:
288 return IsSignedShortOperand(offset);
289 case OperandSize::kQuad:
290 return IsSignedQuadOperand(offset);
291 case OperandSize::kNone:
292 UNREACHABLE();
293 }
294 return nullptr;
295}
296
297Matcher<Node*>
298InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedOperand(
299 int offset, OperandSize operand_size) {
300 switch (operand_size) {
301 case OperandSize::kByte:
302 return IsUnsignedByteOperand(offset);
303 case OperandSize::kShort:
304 return IsUnsignedShortOperand(offset);
305 case OperandSize::kQuad:
306 return IsUnsignedQuadOperand(offset);
307 case OperandSize::kNone:
308 UNREACHABLE();
309 }
310 return nullptr;
311}
312
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000313TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
314 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
315 InterpreterAssemblerForTest m(this, bytecode);
316 m.Dispatch();
317 Graph* graph = m.graph();
318
319 Node* end = graph->end();
320 EXPECT_EQ(1, end->InputCount());
321 Node* tail_call_node = end->InputAt(0);
322
Ben Murdochda12d292016-06-02 14:46:10 +0100323 OperandScale operand_scale = OperandScale::kSingle;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100324 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
325 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100326 IsIntPtrConstant(
327 interpreter::Bytecodes::Size(bytecode, operand_scale)));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100328 Matcher<Node*> target_bytecode_matcher = m.IsLoad(
329 MachineType::Uint8(),
330 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
331 next_bytecode_offset_matcher);
Ben Murdochda12d292016-06-02 14:46:10 +0100332 if (kPointerSize == 8) {
333 target_bytecode_matcher = IsChangeUint32ToUint64(target_bytecode_matcher);
334 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100335 Matcher<Node*> code_target_matcher = m.IsLoad(
336 MachineType::Pointer(),
337 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100338 IsWordShl(target_bytecode_matcher, IsIntPtrConstant(kPointerSizeLog2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000340 EXPECT_THAT(
341 tail_call_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100342 IsTailCall(
343 _, code_target_matcher,
344 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
345 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
346 next_bytecode_offset_matcher,
347 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
348 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
349 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
350 _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351 }
352}
353
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000354TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100355 // If debug code is enabled we emit extra code in Jump.
356 if (FLAG_debug_code) return;
357
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358 int jump_offsets[] = {-9710, -77, 0, +3, +97109};
359 TRACED_FOREACH(int, jump_offset, jump_offsets) {
360 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
361 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100362 m.Jump(m.IntPtrConstant(jump_offset));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000363 Graph* graph = m.graph();
364 Node* end = graph->end();
365 EXPECT_EQ(1, end->InputCount());
366 Node* tail_call_node = end->InputAt(0);
367
Ben Murdoch097c5b22016-05-18 11:27:45 +0100368 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
369 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100370 IsIntPtrConstant(jump_offset));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371 Matcher<Node*> target_bytecode_matcher =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100372 m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher);
Ben Murdochda12d292016-06-02 14:46:10 +0100373 if (kPointerSize == 8) {
374 target_bytecode_matcher =
375 IsChangeUint32ToUint64(target_bytecode_matcher);
376 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100377 Matcher<Node*> code_target_matcher = m.IsLoad(
378 MachineType::Pointer(),
379 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100380 IsWordShl(target_bytecode_matcher,
381 IsIntPtrConstant(kPointerSizeLog2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 EXPECT_THAT(
384 tail_call_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100385 IsTailCall(
386 _, code_target_matcher,
387 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
388 IsParameter(
389 InterpreterDispatchDescriptor::kRegisterFileParameter),
390 next_bytecode_offset_matcher, _,
391 IsParameter(
392 InterpreterDispatchDescriptor::kDispatchTableParameter),
393 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
394 _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395 }
396 }
397}
398
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
400 static const int kJumpIfTrueOffset = 73;
401
Ben Murdoch097c5b22016-05-18 11:27:45 +0100402 // If debug code is enabled we emit extra code in Jump.
403 if (FLAG_debug_code) return;
404
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000405 MachineOperatorBuilder machine(zone());
406
407 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
408 InterpreterAssemblerForTest m(this, bytecode);
409 Node* lhs = m.IntPtrConstant(0);
410 Node* rhs = m.IntPtrConstant(1);
Ben Murdochda12d292016-06-02 14:46:10 +0100411 m.JumpIfWordEqual(lhs, rhs, m.IntPtrConstant(kJumpIfTrueOffset));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000412 Graph* graph = m.graph();
413 Node* end = graph->end();
414 EXPECT_EQ(2, end->InputCount());
415
Ben Murdochda12d292016-06-02 14:46:10 +0100416 OperandScale operand_scale = OperandScale::kSingle;
417 int jump_offsets[] = {kJumpIfTrueOffset, interpreter::Bytecodes::Size(
418 bytecode, operand_scale)};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000419 for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100420 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
421 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100422 IsIntPtrConstant(jump_offsets[i]));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000423 Matcher<Node*> target_bytecode_matcher =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100424 m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher);
Ben Murdochda12d292016-06-02 14:46:10 +0100425 if (kPointerSize == 8) {
426 target_bytecode_matcher =
427 IsChangeUint32ToUint64(target_bytecode_matcher);
428 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100429 Matcher<Node*> code_target_matcher = m.IsLoad(
430 MachineType::Pointer(),
431 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100432 IsWordShl(target_bytecode_matcher,
433 IsIntPtrConstant(kPointerSizeLog2)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000434 EXPECT_THAT(
435 end->InputAt(i),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100436 IsTailCall(
437 _, code_target_matcher,
438 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
439 IsParameter(
440 InterpreterDispatchDescriptor::kRegisterFileParameter),
441 next_bytecode_offset_matcher, _,
442 IsParameter(
443 InterpreterDispatchDescriptor::kDispatchTableParameter),
444 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
445 _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446 }
447
448 // TODO(oth): test control flow paths.
449 }
450}
451
Ben Murdoch097c5b22016-05-18 11:27:45 +0100452TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) {
453 // If debug code is enabled we emit extra code in InterpreterReturn.
454 if (FLAG_debug_code) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000455
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
457 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100458 m.InterpreterReturn();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000459 Graph* graph = m.graph();
460
461 Node* end = graph->end();
462 EXPECT_EQ(1, end->InputCount());
463 Node* tail_call_node = end->InputAt(0);
464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000465 Handle<HeapObject> exit_trampoline =
466 isolate()->builtins()->InterpreterExitTrampoline();
467 EXPECT_THAT(
468 tail_call_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100469 IsTailCall(
470 _, IsHeapConstant(exit_trampoline),
471 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
472 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
473 IsParameter(
474 InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
475 _,
476 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
477 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
478 _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000479 }
480}
481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
Ben Murdochda12d292016-06-02 14:46:10 +0100483 static const OperandScale kOperandScales[] = {
484 OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
Ben Murdochda12d292016-06-02 14:46:10 +0100486 TRACED_FOREACH(interpreter::OperandScale, operand_scale, kOperandScales) {
487 InterpreterAssemblerForTest m(this, bytecode, operand_scale);
488 int number_of_operands =
489 interpreter::Bytecodes::NumberOfOperands(bytecode);
490 for (int i = 0; i < number_of_operands; i++) {
491 int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i,
492 operand_scale);
493 OperandType operand_type =
494 interpreter::Bytecodes::GetOperandType(bytecode, i);
495 OperandSize operand_size =
496 Bytecodes::SizeOfOperand(operand_type, operand_scale);
497 switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) {
498 case interpreter::OperandType::kRegCount:
499 EXPECT_THAT(m.BytecodeOperandCount(i),
500 m.IsUnsignedOperand(offset, operand_size));
501 break;
502 case interpreter::OperandType::kFlag8:
503 EXPECT_THAT(m.BytecodeOperandFlag(i),
504 m.IsUnsignedOperand(offset, operand_size));
505 break;
506 case interpreter::OperandType::kIdx:
507 EXPECT_THAT(m.BytecodeOperandIdx(i),
508 m.IsUnsignedOperand(offset, operand_size));
509 break;
510 case interpreter::OperandType::kImm: {
511 EXPECT_THAT(m.BytecodeOperandImm(i),
512 m.IsSignedOperand(offset, operand_size));
513 break;
514 }
515 case interpreter::OperandType::kMaybeReg:
516 case interpreter::OperandType::kReg:
517 case interpreter::OperandType::kRegOut:
518 case interpreter::OperandType::kRegOutPair:
519 case interpreter::OperandType::kRegOutTriple:
520 case interpreter::OperandType::kRegPair:
521 EXPECT_THAT(m.BytecodeOperandReg(i),
522 m.IsSignedOperand(offset, operand_size));
523 break;
524 case interpreter::OperandType::kRuntimeId:
525 EXPECT_THAT(m.BytecodeOperandRuntimeId(i),
526 m.IsUnsignedOperand(offset, operand_size));
527 break;
528 case interpreter::OperandType::kNone:
529 UNREACHABLE();
530 break;
531 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000532 }
533 }
534 }
535}
536
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000537TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
538 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
Ben Murdochda12d292016-06-02 14:46:10 +0100539 if (!interpreter::Bytecodes::ReadsAccumulator(bytecode) ||
540 !interpreter::Bytecodes::WritesAccumulator(bytecode)) {
541 continue;
542 }
543
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000544 InterpreterAssemblerForTest m(this, bytecode);
545 // Should be incoming accumulator if not set.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100546 EXPECT_THAT(
547 m.GetAccumulator(),
548 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100549 // Should be set by SetAccumulator.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef);
551 m.SetAccumulator(accumulator_value_1);
552 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1);
553 Node* accumulator_value_2 = m.Int32Constant(42);
554 m.SetAccumulator(accumulator_value_2);
555 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2);
556
557 // Should be passed to next bytecode handler on dispatch.
558 m.Dispatch();
559 Graph* graph = m.graph();
560
561 Node* end = graph->end();
562 EXPECT_EQ(1, end->InputCount());
563 Node* tail_call_node = end->InputAt(0);
564
565 EXPECT_THAT(tail_call_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100566 IsTailCall(_, _, accumulator_value_2, _, _, _, _, _, _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000567 }
568}
569
Ben Murdoch097c5b22016-05-18 11:27:45 +0100570TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
571 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
572 InterpreterAssemblerForTest m(this, bytecode);
573 Node* context_node = m.Int32Constant(100);
574 m.SetContext(context_node);
575 EXPECT_THAT(m.GetContext(), context_node);
576 }
577}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578
579TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
580 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
581 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100582 Node* reg_index_node = m.IntPtrConstant(44);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 Node* reg_location_node = m.RegisterLocation(reg_index_node);
584 EXPECT_THAT(
585 reg_location_node,
586 IsIntPtrAdd(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100587 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100588 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000589 }
590}
591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
593 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
594 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100595 Node* reg_index_node = m.IntPtrConstant(44);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 Node* load_reg_node = m.LoadRegister(reg_index_node);
597 EXPECT_THAT(
598 load_reg_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100599 m.IsLoad(
600 MachineType::AnyTagged(),
601 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100602 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000603 }
604}
605
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
607 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
608 InterpreterAssemblerForTest m(this, bytecode);
609 Node* store_value = m.Int32Constant(0xdeadbeef);
Ben Murdochda12d292016-06-02 14:46:10 +0100610 Node* reg_index_node = m.IntPtrConstant(44);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node);
612 EXPECT_THAT(
613 store_reg_node,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100614 m.IsStore(
615 StoreRepresentation(MachineRepresentation::kTagged,
616 kNoWriteBarrier),
617 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
Ben Murdochda12d292016-06-02 14:46:10 +0100618 IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100619 store_value));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000620 }
621}
622
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
624 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
625 InterpreterAssemblerForTest m(this, bytecode);
626 Node* value = m.Int32Constant(44);
Ben Murdochda12d292016-06-02 14:46:10 +0100627 EXPECT_THAT(
628 m.SmiTag(value),
629 IsWordShl(value, IsIntPtrConstant(kSmiShiftSize + kSmiTagSize)));
630 EXPECT_THAT(
631 m.SmiUntag(value),
632 IsWordSar(value, IsIntPtrConstant(kSmiShiftSize + kSmiTagSize)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633 }
634}
635
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
637 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
638 InterpreterAssemblerForTest m(this, bytecode);
639 Node* a = m.Int32Constant(0);
640 Node* b = m.Int32Constant(1);
641 Node* add = m.IntPtrAdd(a, b);
642 EXPECT_THAT(add, IsIntPtrAdd(a, b));
643 }
644}
645
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000646TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
647 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
648 InterpreterAssemblerForTest m(this, bytecode);
649 Node* a = m.Int32Constant(0);
650 Node* b = m.Int32Constant(1);
651 Node* add = m.IntPtrSub(a, b);
652 EXPECT_THAT(add, IsIntPtrSub(a, b));
653 }
654}
655
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000656TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
657 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
658 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100659 Node* a = m.IntPtrConstant(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000660 Node* add = m.WordShl(a, 10);
Ben Murdochda12d292016-06-02 14:46:10 +0100661 EXPECT_THAT(add, IsWordShl(a, IsIntPtrConstant(10)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000662 }
663}
664
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000665TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
666 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
667 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100668 Node* index = m.IntPtrConstant(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000669 Node* load_constant = m.LoadConstantPoolEntry(index);
670 Matcher<Node*> constant_pool_matcher = m.IsLoad(
671 MachineType::AnyTagged(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100672 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag));
674 EXPECT_THAT(
675 load_constant,
676 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher,
677 IsIntPtrAdd(
678 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
Ben Murdochda12d292016-06-02 14:46:10 +0100679 IsWordShl(index, IsIntPtrConstant(kPointerSizeLog2)))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 }
681}
682
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000683TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
684 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
685 InterpreterAssemblerForTest m(this, bytecode);
686 Node* object = m.IntPtrConstant(0xdeadbeef);
687 int offset = 16;
688 Node* load_field = m.LoadObjectField(object, offset);
689 EXPECT_THAT(load_field,
690 m.IsLoad(MachineType::AnyTagged(), object,
691 IsIntPtrConstant(offset - kHeapObjectTag)));
692 }
693}
694
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000695TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
696 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
697 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100698 Node* context = m.IntPtrConstant(1);
699 Node* slot_index = m.IntPtrConstant(22);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000700 Node* load_context_slot = m.LoadContextSlot(context, slot_index);
701
702 Matcher<Node*> offset =
Ben Murdochda12d292016-06-02 14:46:10 +0100703 IsIntPtrAdd(IsWordShl(slot_index, IsIntPtrConstant(kPointerSizeLog2)),
704 IsIntPtrConstant(Context::kHeaderSize - kHeapObjectTag));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000705 EXPECT_THAT(load_context_slot,
706 m.IsLoad(MachineType::AnyTagged(), context, offset));
707 }
708}
709
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000710TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
711 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
712 InterpreterAssemblerForTest m(this, bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100713 Node* context = m.IntPtrConstant(1);
714 Node* slot_index = m.IntPtrConstant(22);
715 Node* value = m.SmiConstant(Smi::FromInt(100));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000716 Node* store_context_slot = m.StoreContextSlot(context, slot_index, value);
717
718 Matcher<Node*> offset =
Ben Murdochda12d292016-06-02 14:46:10 +0100719 IsIntPtrAdd(IsWordShl(slot_index, IsIntPtrConstant(kPointerSizeLog2)),
720 IsIntPtrConstant(Context::kHeaderSize - kHeapObjectTag));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000721 EXPECT_THAT(store_context_slot,
722 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged,
723 kFullWriteBarrier),
724 context, offset, value));
725 }
726}
727
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
729 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
730 InterpreterAssemblerForTest m(this, bytecode);
731 Node* arg1 = m.Int32Constant(2);
732 Node* arg2 = m.Int32Constant(3);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100733 Node* context =
734 m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
735 Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000736 EXPECT_THAT(
737 call_runtime,
738 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100739 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
740 _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741 }
742}
743
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
745 const int kResultSizes[] = {1, 2};
746 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
747 TRACED_FOREACH(int, result_size, kResultSizes) {
748 InterpreterAssemblerForTest m(this, bytecode);
749 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size);
750
751 Node* function_id = m.Int32Constant(0);
752 Node* first_arg = m.Int32Constant(1);
753 Node* arg_count = m.Int32Constant(2);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100754 Node* context =
755 m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000756
757 Matcher<Node*> function_table = IsExternalConstant(
758 ExternalReference::runtime_function_table_address(isolate()));
759 Matcher<Node*> function = IsIntPtrAdd(
760 function_table,
761 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function))));
762 Matcher<Node*> function_entry =
763 m.IsLoad(MachineType::Pointer(), function,
Ben Murdochda12d292016-06-02 14:46:10 +0100764 IsIntPtrConstant(offsetof(Runtime::Function, entry)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000765
Ben Murdoch097c5b22016-05-18 11:27:45 +0100766 Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg,
767 arg_count, result_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 EXPECT_THAT(
769 call_runtime,
770 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
771 function_entry,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100772 IsParameter(InterpreterDispatchDescriptor::kContextParameter),
773 _, _));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774 }
775 }
776}
777
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100779 TailCallMode tail_call_modes[] = {TailCallMode::kDisallow,
780 TailCallMode::kAllow};
781 TRACED_FOREACH(TailCallMode, tail_call_mode, tail_call_modes) {
782 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
783 InterpreterAssemblerForTest m(this, bytecode);
784 Callable builtin =
785 CodeFactory::InterpreterPushArgsAndCall(isolate(), tail_call_mode);
786 Node* function = m.Int32Constant(0);
787 Node* first_arg = m.Int32Constant(1);
788 Node* arg_count = m.Int32Constant(2);
789 Node* context =
790 m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
791 Node* call_js =
792 m.CallJS(function, context, first_arg, arg_count, tail_call_mode);
793 EXPECT_THAT(
794 call_js,
795 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
796 function,
797 IsParameter(InterpreterDispatchDescriptor::kContextParameter),
798 _, _));
799 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000800 }
801}
802
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000803TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) {
804 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
805 InterpreterAssemblerForTest m(this, bytecode);
806 Node* feedback_vector = m.LoadTypeFeedbackVector();
807
Ben Murdoch097c5b22016-05-18 11:27:45 +0100808 Matcher<Node*> load_function_matcher = m.IsLoad(
809 MachineType::AnyTagged(),
810 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
811 IsIntPtrConstant(
812 InterpreterFrameConstants::kFunctionFromRegisterPointer));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000813 Matcher<Node*> load_shared_function_info_matcher =
814 m.IsLoad(MachineType::AnyTagged(), load_function_matcher,
815 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
816 kHeapObjectTag));
817
818 EXPECT_THAT(
819 feedback_vector,
820 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher,
821 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
822 kHeapObjectTag)));
823 }
824}
825
Ben Murdoch097c5b22016-05-18 11:27:45 +0100826} // namespace interpreter
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000827} // namespace internal
828} // namespace v8