Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(683)

Side by Side Diff: test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc

Issue 642923003: [turbofan] Add support for shifted and rotated operands on ARM64. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/arm64/instruction-selector-arm64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/instruction-selector-unittest.h" 5 #include "test/unittests/compiler/instruction-selector-unittest.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace compiler { 9 namespace compiler {
10 10
(...skipping 12 matching lines...) Expand all
23 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; 23 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
24 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; 24 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
25 25
26 26
27 template <typename T> 27 template <typename T>
28 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { 28 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
29 return os << mi.constructor_name; 29 return os << mi.constructor_name;
30 } 30 }
31 31
32 32
33 struct Shift {
34 MachInst2 mi;
35 AddressingMode mode;
36 };
37
38
39 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
40 return os << shift.mi;
41 }
42
43
33 // Helper to build Int32Constant or Int64Constant depending on the given 44 // Helper to build Int32Constant or Int64Constant depending on the given
34 // machine type. 45 // machine type.
35 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type, 46 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
36 int64_t value) { 47 int64_t value) {
37 switch (type) { 48 switch (type) {
38 case kMachInt32: 49 case kMachInt32:
39 return m.Int32Constant(value); 50 return m.Int32Constant(value);
40 break; 51 break;
41 52
42 case kMachInt64: 53 case kMachInt64:
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 143
133 // ARM64 arithmetic with overflow instructions. 144 // ARM64 arithmetic with overflow instructions.
134 static const MachInst2 kOvfAddSubInstructions[] = { 145 static const MachInst2 kOvfAddSubInstructions[] = {
135 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", 146 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
136 kArm64Add32, kMachInt32}, 147 kArm64Add32, kMachInt32},
137 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", 148 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
138 kArm64Sub32, kMachInt32}}; 149 kArm64Sub32, kMachInt32}};
139 150
140 151
141 // ARM64 shift instructions. 152 // ARM64 shift instructions.
142 static const MachInst2 kShiftInstructions[] = { 153 static const Shift kShiftInstructions[] = {
143 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32}, 154 {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32},
144 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64}, 155 kMode_Operand2_R_LSL_I},
145 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32}, 156 {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64},
146 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64}, 157 kMode_Operand2_R_LSL_I},
147 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32}, 158 {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32},
148 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64}, 159 kMode_Operand2_R_LSR_I},
149 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, 160 {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64},
150 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; 161 kMode_Operand2_R_LSR_I},
162 {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32},
163 kMode_Operand2_R_ASR_I},
164 {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64},
165 kMode_Operand2_R_ASR_I},
166 {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32},
167 kMode_Operand2_R_ROR_I},
168 {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64},
169 kMode_Operand2_R_ROR_I}};
151 170
152 171
153 // ARM64 Mul/Div instructions. 172 // ARM64 Mul/Div instructions.
154 static const MachInst2 kMulDivInstructions[] = { 173 static const MachInst2 kMulDivInstructions[] = {
155 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, 174 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
156 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, 175 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
157 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, 176 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
158 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, 177 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64},
159 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, kMachInt32}, 178 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, kMachInt32},
160 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, kMachInt64}}; 179 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, kMachInt64}};
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 308 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
290 ASSERT_EQ(2U, s[0]->InputCount()); 309 ASSERT_EQ(2U, s[0]->InputCount());
291 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 310 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
292 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 311 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
293 EXPECT_EQ(1U, s[0]->OutputCount()); 312 EXPECT_EQ(1U, s[0]->OutputCount());
294 } 313 }
295 } 314 }
296 } 315 }
297 316
298 317
318 TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) {
319 const MachInst2 dpi = GetParam();
320 const MachineType type = dpi.machine_type;
321 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
322 // Only test 64-bit shifted operands with 64-bit instructions.
323 if (shift.mi.machine_type != type) continue;
324
325 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
326 StreamBuilder m(this, type, type, type);
327 m.Return((m.*dpi.constructor)(
328 m.Parameter(0),
329 (m.*shift.mi.constructor)(m.Parameter(1),
330 BuildConstant(m, type, imm))));
331 Stream s = m.Build();
332 ASSERT_EQ(1U, s.size());
333 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
334 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
335 EXPECT_EQ(3U, s[0]->InputCount());
336 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
337 EXPECT_EQ(1U, s[0]->OutputCount());
338 }
339
340 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
341 StreamBuilder m(this, type, type, type);
342 m.Return((m.*dpi.constructor)(
343 (m.*shift.mi.constructor)(m.Parameter(1),
344 BuildConstant(m, type, imm)),
345 m.Parameter(0)));
346 Stream s = m.Build();
347 ASSERT_EQ(1U, s.size());
348 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
349 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
350 EXPECT_EQ(3U, s[0]->InputCount());
351 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
352 EXPECT_EQ(1U, s[0]->OutputCount());
353 }
354 }
355 }
356
357
299 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, 358 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
300 ::testing::ValuesIn(kLogicalInstructions)); 359 ::testing::ValuesIn(kLogicalInstructions));
301 360
302 361
303 // ----------------------------------------------------------------------------- 362 // -----------------------------------------------------------------------------
304 // Add and Sub instructions. 363 // Add and Sub instructions.
305 364
306 typedef InstructionSelectorTestWithParam<AddSub> InstructionSelectorAddSubTest; 365 typedef InstructionSelectorTestWithParam<AddSub> InstructionSelectorAddSubTest;
307 366
308 367
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 ASSERT_EQ(1U, s.size()); 408 ASSERT_EQ(1U, s.size());
350 EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode()); 409 EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode());
351 ASSERT_EQ(2U, s[0]->InputCount()); 410 ASSERT_EQ(2U, s[0]->InputCount());
352 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); 411 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
353 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 412 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
354 EXPECT_EQ(1U, s[0]->OutputCount()); 413 EXPECT_EQ(1U, s[0]->OutputCount());
355 } 414 }
356 } 415 }
357 416
358 417
418 TEST_P(InstructionSelectorAddSubTest, ShiftByImmediateOnRight) {
419 const AddSub dpi = GetParam();
420 const MachineType type = dpi.mi.machine_type;
421 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
422 // Only test 64-bit shifted operands with 64-bit instructions.
423 if (shift.mi.machine_type != type) continue;
424
425 if ((shift.mi.arch_opcode == kArm64Ror32) ||
426 (shift.mi.arch_opcode == kArm64Ror)) {
427 // Not supported by add/sub instructions.
428 continue;
429 }
430
431 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
432 StreamBuilder m(this, type, type, type);
433 m.Return((m.*dpi.mi.constructor)(
434 m.Parameter(0),
435 (m.*shift.mi.constructor)(m.Parameter(1),
436 BuildConstant(m, type, imm))));
437 Stream s = m.Build();
438 ASSERT_EQ(1U, s.size());
439 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
440 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
441 EXPECT_EQ(3U, s[0]->InputCount());
442 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
443 EXPECT_EQ(1U, s[0]->OutputCount());
444 }
445 }
446 }
447
448
359 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, 449 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
360 ::testing::ValuesIn(kAddSubInstructions)); 450 ::testing::ValuesIn(kAddSubInstructions));
361 451
362 452
363 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) { 453 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) {
364 { 454 {
365 // 32-bit add. 455 // 32-bit add.
366 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 456 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
367 StreamBuilder m(this, kMachInt32, kMachInt32); 457 StreamBuilder m(this, kMachInt32, kMachInt32);
368 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); 458 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); 538 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
449 ASSERT_EQ(2U, s[0]->InputCount()); 539 ASSERT_EQ(2U, s[0]->InputCount());
450 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); 540 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
451 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); 541 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
452 EXPECT_EQ(1U, s[0]->OutputCount()); 542 EXPECT_EQ(1U, s[0]->OutputCount());
453 } 543 }
454 } 544 }
455 } 545 }
456 546
457 547
548 TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
549 // 32-bit add.
550 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
551 // Only test relevant shifted operands.
552 if (shift.mi.machine_type != kMachInt32) continue;
553 if (shift.mi.arch_opcode == kArm64Ror32) continue;
554
555 TRACED_FORRANGE(int, imm, 0, 31) {
556 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
557 m.Return((m.Int32Add)(
558 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
559 m.Parameter(0)));
560 Stream s = m.Build();
561 ASSERT_EQ(1U, s.size());
562 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
563 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
564 EXPECT_EQ(3U, s[0]->InputCount());
565 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
566 EXPECT_EQ(1U, s[0]->OutputCount());
567 }
568 }
569
570 // 64-bit add.
571 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
572 // Only test relevant shifted operands.
573 if (shift.mi.machine_type != kMachInt64) continue;
574 if (shift.mi.arch_opcode == kArm64Ror) continue;
575
576 TRACED_FORRANGE(int, imm, 0, 63) {
577 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
578 m.Return((m.Int64Add)(
579 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)),
580 m.Parameter(0)));
581 Stream s = m.Build();
582 ASSERT_EQ(1U, s.size());
583 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
584 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
585 EXPECT_EQ(3U, s[0]->InputCount());
586 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
587 EXPECT_EQ(1U, s[0]->OutputCount());
588 }
589 }
590 }
591
592
458 // ----------------------------------------------------------------------------- 593 // -----------------------------------------------------------------------------
459 // Data processing controlled branches. 594 // Data processing controlled branches.
460 595
461 596
462 typedef InstructionSelectorTestWithParam<MachInst2> 597 typedef InstructionSelectorTestWithParam<MachInst2>
463 InstructionSelectorDPFlagSetTest; 598 InstructionSelectorDPFlagSetTest;
464 599
465 600
466 TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) { 601 TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) {
467 const MachInst2 dpi = GetParam(); 602 const MachInst2 dpi = GetParam();
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 946 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
812 EXPECT_EQ(kOverflow, s[0]->flags_condition()); 947 EXPECT_EQ(kOverflow, s[0]->flags_condition());
813 } 948 }
814 } 949 }
815 950
816 951
817 // ----------------------------------------------------------------------------- 952 // -----------------------------------------------------------------------------
818 // Shift instructions. 953 // Shift instructions.
819 954
820 955
821 typedef InstructionSelectorTestWithParam<MachInst2> 956 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
822 InstructionSelectorShiftTest;
823 957
824 958
825 TEST_P(InstructionSelectorShiftTest, Parameter) { 959 TEST_P(InstructionSelectorShiftTest, Parameter) {
826 const MachInst2 dpi = GetParam(); 960 const Shift shift = GetParam();
827 const MachineType type = dpi.machine_type; 961 const MachineType type = shift.mi.machine_type;
828 StreamBuilder m(this, type, type, type); 962 StreamBuilder m(this, type, type, type);
829 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); 963 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Parameter(1)));
830 Stream s = m.Build(); 964 Stream s = m.Build();
831 ASSERT_EQ(1U, s.size()); 965 ASSERT_EQ(1U, s.size());
832 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 966 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
833 EXPECT_EQ(2U, s[0]->InputCount()); 967 EXPECT_EQ(2U, s[0]->InputCount());
834 EXPECT_EQ(1U, s[0]->OutputCount()); 968 EXPECT_EQ(1U, s[0]->OutputCount());
835 } 969 }
836 970
837 971
838 TEST_P(InstructionSelectorShiftTest, Immediate) { 972 TEST_P(InstructionSelectorShiftTest, Immediate) {
839 const MachInst2 dpi = GetParam(); 973 const Shift shift = GetParam();
840 const MachineType type = dpi.machine_type; 974 const MachineType type = shift.mi.machine_type;
841 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { 975 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
842 StreamBuilder m(this, type, type); 976 StreamBuilder m(this, type, type);
843 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); 977 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
844 Stream s = m.Build(); 978 Stream s = m.Build();
845 ASSERT_EQ(1U, s.size()); 979 ASSERT_EQ(1U, s.size());
846 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 980 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
847 EXPECT_EQ(2U, s[0]->InputCount()); 981 EXPECT_EQ(2U, s[0]->InputCount());
848 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 982 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
849 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 983 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
850 EXPECT_EQ(1U, s[0]->OutputCount()); 984 EXPECT_EQ(1U, s[0]->OutputCount());
851 } 985 }
852 } 986 }
853 987
854 988
855 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, 989 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
856 ::testing::ValuesIn(kShiftInstructions)); 990 ::testing::ValuesIn(kShiftInstructions));
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 ASSERT_EQ(3U, s[0]->InputCount()); 1755 ASSERT_EQ(3U, s[0]->InputCount());
1622 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); 1756 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
1623 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); 1757 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
1624 } 1758 }
1625 } 1759 }
1626 } 1760 }
1627 1761
1628 } // namespace compiler 1762 } // namespace compiler
1629 } // namespace internal 1763 } // namespace internal
1630 } // namespace v8 1764 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm64/instruction-selector-arm64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698