OLD | NEW |
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 <list> | 5 #include <list> |
6 | 6 |
7 #include "test/compiler-unittests/instruction-selector-unittest.h" | 7 #include "test/compiler-unittests/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 namespace compiler { | 11 namespace compiler { |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*); | 15 template <typename T> |
16 | 16 struct MachInst { |
17 struct DPI { | 17 T constructor; |
18 Constructor constructor; | |
19 const char* constructor_name; | 18 const char* constructor_name; |
20 ArchOpcode arch_opcode; | 19 ArchOpcode arch_opcode; |
21 MachineType machine_type; | 20 MachineType machine_type; |
22 }; | 21 }; |
23 | 22 |
| 23 typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1; |
| 24 typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2; |
24 | 25 |
25 std::ostream& operator<<(std::ostream& os, const DPI& dpi) { | 26 |
26 return os << dpi.constructor_name; | 27 template <typename T> |
| 28 std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) { |
| 29 return os << mi.constructor_name; |
27 } | 30 } |
28 | 31 |
29 | 32 |
30 // ARM64 Logical instructions. | 33 // ARM64 logical instructions. |
31 static const DPI kLogicalInstructions[] = { | 34 static const MachInst2 kLogicalInstructions[] = { |
32 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, | 35 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, |
33 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, | 36 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, |
34 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, | 37 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, |
35 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, | 38 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, |
36 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32}, | 39 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32}, |
37 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; | 40 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}}; |
38 | 41 |
39 | 42 |
40 // ARM64 logical immediates: contiguous set bits, rotated about a power of two | 43 // ARM64 logical immediates: contiguous set bits, rotated about a power of two |
41 // sized block. The block is then duplicated across the word. Below is a random | 44 // sized block. The block is then duplicated across the word. Below is a random |
(...skipping 11 matching lines...) Expand all Loading... |
53 0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff, | 56 0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff, |
54 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, | 57 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, |
55 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, | 58 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, |
56 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, | 59 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, |
57 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, | 60 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, |
58 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, | 61 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, |
59 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, | 62 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, |
60 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; | 63 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; |
61 | 64 |
62 | 65 |
63 // ARM64 Arithmetic instructions. | 66 // ARM64 arithmetic instructions. |
64 static const DPI kAddSubInstructions[] = { | 67 static const MachInst2 kAddSubInstructions[] = { |
65 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, | 68 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, |
66 {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, | 69 {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, |
67 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, | 70 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, |
68 {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}}; | 71 {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}}; |
69 | 72 |
70 | 73 |
71 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. | 74 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. |
72 // Below is a combination of a random subset and some edge values. | 75 // Below is a combination of a random subset and some edge values. |
73 static const int32_t kAddSubImmediates[] = { | 76 static const int32_t kAddSubImmediates[] = { |
74 0, 1, 69, 493, 599, 701, 719, | 77 0, 1, 69, 493, 599, 701, 719, |
75 768, 818, 842, 945, 1246, 1286, 1429, | 78 768, 818, 842, 945, 1246, 1286, 1429, |
76 1669, 2171, 2179, 2182, 2254, 2334, 2338, | 79 1669, 2171, 2179, 2182, 2254, 2334, 2338, |
77 2343, 2396, 2449, 2610, 2732, 2855, 2876, | 80 2343, 2396, 2449, 2610, 2732, 2855, 2876, |
78 2944, 3377, 3458, 3475, 3476, 3540, 3574, | 81 2944, 3377, 3458, 3475, 3476, 3540, 3574, |
79 3601, 3813, 3871, 3917, 4095, 4096, 16384, | 82 3601, 3813, 3871, 3917, 4095, 4096, 16384, |
80 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, | 83 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, |
81 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, | 84 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, |
82 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, | 85 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, |
83 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, | 86 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, |
84 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, | 87 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, |
85 15597568, 15892480, 16773120}; | 88 15597568, 15892480, 16773120}; |
86 | 89 |
87 | 90 |
88 // ARM64 shift instructions. | 91 // ARM64 shift instructions. |
89 static const DPI kShiftInstructions[] = { | 92 static const MachInst2 kShiftInstructions[] = { |
90 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, | 93 {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32}, |
91 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, | 94 {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64}, |
92 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, | 95 {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32}, |
93 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, | 96 {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64}, |
94 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, | 97 {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32}, |
95 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, | 98 {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64}, |
96 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, | 99 {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, |
97 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; | 100 {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}}; |
98 | 101 |
99 | 102 |
100 // ARM64 Mul/Div instructions. | 103 // ARM64 Mul/Div instructions. |
101 static const DPI kMulDivInstructions[] = { | 104 static const MachInst2 kMulDivInstructions[] = { |
102 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, | 105 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, |
103 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, | 106 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, |
104 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, | 107 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, |
105 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, | 108 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, |
106 {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32}, | 109 {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32}, |
107 {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}}; | 110 {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}}; |
108 | 111 |
| 112 |
| 113 // ARM64 FP arithmetic instructions. |
| 114 static const MachInst2 kFPArithInstructions[] = { |
| 115 {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add, |
| 116 kMachFloat64}, |
| 117 {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub, |
| 118 kMachFloat64}, |
| 119 {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul, |
| 120 kMachFloat64}, |
| 121 {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div, |
| 122 kMachFloat64}}; |
| 123 |
| 124 |
| 125 struct FPCmp { |
| 126 MachInst2 mi; |
| 127 FlagsCondition cond; |
| 128 }; |
| 129 |
| 130 |
| 131 std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) { |
| 132 return os << cmp.mi; |
| 133 } |
| 134 |
| 135 |
| 136 // ARM64 FP comparison instructions. |
| 137 static const FPCmp kFPCmpInstructions[] = { |
| 138 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp, |
| 139 kMachFloat64}, |
| 140 kUnorderedEqual}, |
| 141 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", |
| 142 kArm64Float64Cmp, kMachFloat64}, |
| 143 kUnorderedLessThan}, |
| 144 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", |
| 145 kArm64Float64Cmp, kMachFloat64}, |
| 146 kUnorderedLessThanOrEqual}}; |
| 147 |
| 148 |
| 149 struct Conversion { |
| 150 // The machine_type field in MachInst1 represents the destination type. |
| 151 MachInst1 mi; |
| 152 MachineType src_machine_type; |
| 153 }; |
| 154 |
| 155 |
| 156 std::ostream& operator<<(std::ostream& os, const Conversion& conv) { |
| 157 return os << conv.mi; |
| 158 } |
| 159 |
| 160 |
| 161 // ARM64 type conversion instructions. |
| 162 static const Conversion kConversionInstructions[] = { |
| 163 {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64", |
| 164 kArm64Sxtw, kMachInt64}, |
| 165 kMachInt32}, |
| 166 {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64", |
| 167 kArm64Mov32, kMachUint64}, |
| 168 kMachUint32}, |
| 169 {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32", |
| 170 kArm64Mov32, kMachInt32}, |
| 171 kMachInt64}, |
| 172 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", |
| 173 kArm64Int32ToFloat64, kMachFloat64}, |
| 174 kMachInt32}, |
| 175 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", |
| 176 kArm64Uint32ToFloat64, kMachFloat64}, |
| 177 kMachUint32}, |
| 178 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", |
| 179 kArm64Float64ToInt32, kMachInt32}, |
| 180 kMachFloat64}, |
| 181 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", |
| 182 kArm64Float64ToUint32, kMachUint32}, |
| 183 kMachFloat64}}; |
| 184 |
109 } // namespace | 185 } // namespace |
110 | 186 |
111 | 187 |
112 // ----------------------------------------------------------------------------- | 188 // ----------------------------------------------------------------------------- |
113 // Logical instructions. | 189 // Logical instructions. |
114 | 190 |
115 | 191 |
116 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorLogicalTest; | 192 typedef InstructionSelectorTestWithParam<MachInst2> |
| 193 InstructionSelectorLogicalTest; |
| 194 |
117 | 195 |
118 TEST_P(InstructionSelectorLogicalTest, Parameter) { | 196 TEST_P(InstructionSelectorLogicalTest, Parameter) { |
119 const DPI dpi = GetParam(); | 197 const MachInst2 dpi = GetParam(); |
120 const MachineType type = dpi.machine_type; | 198 const MachineType type = dpi.machine_type; |
121 StreamBuilder m(this, type, type, type); | 199 StreamBuilder m(this, type, type, type); |
122 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 200 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
123 Stream s = m.Build(); | 201 Stream s = m.Build(); |
124 ASSERT_EQ(1U, s.size()); | 202 ASSERT_EQ(1U, s.size()); |
125 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 203 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
126 EXPECT_EQ(2U, s[0]->InputCount()); | 204 EXPECT_EQ(2U, s[0]->InputCount()); |
127 EXPECT_EQ(1U, s[0]->OutputCount()); | 205 EXPECT_EQ(1U, s[0]->OutputCount()); |
128 } | 206 } |
129 | 207 |
130 | 208 |
131 TEST_P(InstructionSelectorLogicalTest, Immediate) { | 209 TEST_P(InstructionSelectorLogicalTest, Immediate) { |
132 const DPI dpi = GetParam(); | 210 const MachInst2 dpi = GetParam(); |
133 const MachineType type = dpi.machine_type; | 211 const MachineType type = dpi.machine_type; |
134 // TODO(all): Add support for testing 64-bit immediates. | 212 // TODO(all): Add support for testing 64-bit immediates. |
135 if (type == kMachInt32) { | 213 if (type == kMachInt32) { |
136 // Immediate on the right. | 214 // Immediate on the right. |
137 TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { | 215 TRACED_FOREACH(int32_t, imm, kLogicalImmediates) { |
138 StreamBuilder m(this, type, type); | 216 StreamBuilder m(this, type, type); |
139 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 217 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
140 Stream s = m.Build(); | 218 Stream s = m.Build(); |
141 ASSERT_EQ(1U, s.size()); | 219 ASSERT_EQ(1U, s.size()); |
142 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 220 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
(...skipping 19 matching lines...) Expand all Loading... |
162 } | 240 } |
163 | 241 |
164 | 242 |
165 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, | 243 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, |
166 ::testing::ValuesIn(kLogicalInstructions)); | 244 ::testing::ValuesIn(kLogicalInstructions)); |
167 | 245 |
168 | 246 |
169 // ----------------------------------------------------------------------------- | 247 // ----------------------------------------------------------------------------- |
170 // Add and Sub instructions. | 248 // Add and Sub instructions. |
171 | 249 |
172 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorAddSubTest; | 250 typedef InstructionSelectorTestWithParam<MachInst2> |
| 251 InstructionSelectorAddSubTest; |
| 252 |
173 | 253 |
174 TEST_P(InstructionSelectorAddSubTest, Parameter) { | 254 TEST_P(InstructionSelectorAddSubTest, Parameter) { |
175 const DPI dpi = GetParam(); | 255 const MachInst2 dpi = GetParam(); |
176 const MachineType type = dpi.machine_type; | 256 const MachineType type = dpi.machine_type; |
177 StreamBuilder m(this, type, type, type); | 257 StreamBuilder m(this, type, type, type); |
178 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 258 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
179 Stream s = m.Build(); | 259 Stream s = m.Build(); |
180 ASSERT_EQ(1U, s.size()); | 260 ASSERT_EQ(1U, s.size()); |
181 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 261 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
182 EXPECT_EQ(2U, s[0]->InputCount()); | 262 EXPECT_EQ(2U, s[0]->InputCount()); |
183 EXPECT_EQ(1U, s[0]->OutputCount()); | 263 EXPECT_EQ(1U, s[0]->OutputCount()); |
184 } | 264 } |
185 | 265 |
186 | 266 |
187 TEST_P(InstructionSelectorAddSubTest, Immediate) { | 267 TEST_P(InstructionSelectorAddSubTest, Immediate) { |
188 const DPI dpi = GetParam(); | 268 const MachInst2 dpi = GetParam(); |
189 const MachineType type = dpi.machine_type; | 269 const MachineType type = dpi.machine_type; |
190 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { | 270 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { |
191 StreamBuilder m(this, type, type); | 271 StreamBuilder m(this, type, type); |
192 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 272 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
193 Stream s = m.Build(); | 273 Stream s = m.Build(); |
194 ASSERT_EQ(1U, s.size()); | 274 ASSERT_EQ(1U, s.size()); |
195 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 275 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
196 ASSERT_EQ(2U, s[0]->InputCount()); | 276 ASSERT_EQ(2U, s[0]->InputCount()); |
197 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 277 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
198 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 278 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
199 EXPECT_EQ(1U, s[0]->OutputCount()); | 279 EXPECT_EQ(1U, s[0]->OutputCount()); |
200 } | 280 } |
201 } | 281 } |
202 | 282 |
203 | 283 |
204 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, | 284 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, |
205 ::testing::ValuesIn(kAddSubInstructions)); | 285 ::testing::ValuesIn(kAddSubInstructions)); |
206 | 286 |
207 | 287 |
208 // ----------------------------------------------------------------------------- | 288 // ----------------------------------------------------------------------------- |
209 // Shift instructions. | 289 // Shift instructions. |
210 | 290 |
211 | 291 |
212 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorShiftTest; | 292 typedef InstructionSelectorTestWithParam<MachInst2> |
| 293 InstructionSelectorShiftTest; |
| 294 |
213 | 295 |
214 TEST_P(InstructionSelectorShiftTest, Parameter) { | 296 TEST_P(InstructionSelectorShiftTest, Parameter) { |
215 const DPI dpi = GetParam(); | 297 const MachInst2 dpi = GetParam(); |
216 const MachineType type = dpi.machine_type; | 298 const MachineType type = dpi.machine_type; |
217 StreamBuilder m(this, type, type, type); | 299 StreamBuilder m(this, type, type, type); |
218 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 300 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
219 Stream s = m.Build(); | 301 Stream s = m.Build(); |
220 ASSERT_EQ(1U, s.size()); | 302 ASSERT_EQ(1U, s.size()); |
221 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 303 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
222 EXPECT_EQ(2U, s[0]->InputCount()); | 304 EXPECT_EQ(2U, s[0]->InputCount()); |
223 EXPECT_EQ(1U, s[0]->OutputCount()); | 305 EXPECT_EQ(1U, s[0]->OutputCount()); |
224 } | 306 } |
225 | 307 |
226 | 308 |
227 TEST_P(InstructionSelectorShiftTest, Immediate) { | 309 TEST_P(InstructionSelectorShiftTest, Immediate) { |
228 const DPI dpi = GetParam(); | 310 const MachInst2 dpi = GetParam(); |
229 const MachineType type = dpi.machine_type; | 311 const MachineType type = dpi.machine_type; |
230 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { | 312 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { |
231 StreamBuilder m(this, type, type); | 313 StreamBuilder m(this, type, type); |
232 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); | 314 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); |
233 Stream s = m.Build(); | 315 Stream s = m.Build(); |
234 ASSERT_EQ(1U, s.size()); | 316 ASSERT_EQ(1U, s.size()); |
235 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 317 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
236 EXPECT_EQ(2U, s[0]->InputCount()); | 318 EXPECT_EQ(2U, s[0]->InputCount()); |
237 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); | 319 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); |
238 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 320 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
239 EXPECT_EQ(1U, s[0]->OutputCount()); | 321 EXPECT_EQ(1U, s[0]->OutputCount()); |
240 } | 322 } |
241 } | 323 } |
242 | 324 |
243 | 325 |
244 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, | 326 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, |
245 ::testing::ValuesIn(kShiftInstructions)); | 327 ::testing::ValuesIn(kShiftInstructions)); |
246 | 328 |
247 | 329 |
248 // ----------------------------------------------------------------------------- | 330 // ----------------------------------------------------------------------------- |
249 // Mul and Div instructions. | 331 // Mul and Div instructions. |
250 | 332 |
251 | 333 |
252 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorMulDivTest; | 334 typedef InstructionSelectorTestWithParam<MachInst2> |
| 335 InstructionSelectorMulDivTest; |
253 | 336 |
254 | 337 |
255 TEST_P(InstructionSelectorMulDivTest, Parameter) { | 338 TEST_P(InstructionSelectorMulDivTest, Parameter) { |
256 const DPI dpi = GetParam(); | 339 const MachInst2 dpi = GetParam(); |
257 const MachineType type = dpi.machine_type; | 340 const MachineType type = dpi.machine_type; |
258 StreamBuilder m(this, type, type, type); | 341 StreamBuilder m(this, type, type, type); |
259 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); | 342 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); |
260 Stream s = m.Build(); | 343 Stream s = m.Build(); |
261 ASSERT_EQ(1U, s.size()); | 344 ASSERT_EQ(1U, s.size()); |
262 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); | 345 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); |
263 EXPECT_EQ(2U, s[0]->InputCount()); | 346 EXPECT_EQ(2U, s[0]->InputCount()); |
264 EXPECT_EQ(1U, s[0]->OutputCount()); | 347 EXPECT_EQ(1U, s[0]->OutputCount()); |
265 } | 348 } |
266 | 349 |
267 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest, | 350 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest, |
268 ::testing::ValuesIn(kMulDivInstructions)); | 351 ::testing::ValuesIn(kMulDivInstructions)); |
269 | 352 |
270 | 353 |
271 // ----------------------------------------------------------------------------- | 354 // ----------------------------------------------------------------------------- |
| 355 // Floating point instructions. |
| 356 |
| 357 typedef InstructionSelectorTestWithParam<MachInst2> |
| 358 InstructionSelectorFPArithTest; |
| 359 |
| 360 |
| 361 TEST_P(InstructionSelectorFPArithTest, Parameter) { |
| 362 const MachInst2 fpa = GetParam(); |
| 363 StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type); |
| 364 m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1))); |
| 365 Stream s = m.Build(); |
| 366 ASSERT_EQ(1U, s.size()); |
| 367 EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode()); |
| 368 EXPECT_EQ(2U, s[0]->InputCount()); |
| 369 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 370 } |
| 371 |
| 372 |
| 373 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, |
| 374 ::testing::ValuesIn(kFPArithInstructions)); |
| 375 |
| 376 |
| 377 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; |
| 378 |
| 379 |
| 380 TEST_P(InstructionSelectorFPCmpTest, Parameter) { |
| 381 const FPCmp cmp = GetParam(); |
| 382 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); |
| 383 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); |
| 384 Stream s = m.Build(); |
| 385 ASSERT_EQ(1U, s.size()); |
| 386 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); |
| 387 EXPECT_EQ(2U, s[0]->InputCount()); |
| 388 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 389 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 390 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 391 } |
| 392 |
| 393 |
| 394 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest, |
| 395 ::testing::ValuesIn(kFPCmpInstructions)); |
| 396 |
| 397 |
| 398 // ----------------------------------------------------------------------------- |
272 // Conversions. | 399 // Conversions. |
273 | 400 |
| 401 typedef InstructionSelectorTestWithParam<Conversion> |
| 402 InstructionSelectorConversionTest; |
274 | 403 |
275 TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) { | 404 |
276 StreamBuilder m(this, kMachInt64, kMachInt32); | 405 TEST_P(InstructionSelectorConversionTest, Parameter) { |
277 m.Return(m.ChangeInt32ToInt64(m.Parameter(0))); | 406 const Conversion conv = GetParam(); |
| 407 StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type); |
| 408 m.Return((m.*conv.mi.constructor)(m.Parameter(0))); |
278 Stream s = m.Build(); | 409 Stream s = m.Build(); |
279 ASSERT_EQ(1U, s.size()); | 410 ASSERT_EQ(1U, s.size()); |
280 EXPECT_EQ(kArm64Sxtw, s[0]->arch_opcode()); | 411 EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode()); |
| 412 EXPECT_EQ(1U, s[0]->InputCount()); |
| 413 EXPECT_EQ(1U, s[0]->OutputCount()); |
281 } | 414 } |
282 | 415 |
283 | 416 |
284 TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) { | 417 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
285 StreamBuilder m(this, kMachUint64, kMachUint32); | 418 InstructionSelectorConversionTest, |
286 m.Return(m.ChangeUint32ToUint64(m.Parameter(0))); | 419 ::testing::ValuesIn(kConversionInstructions)); |
287 Stream s = m.Build(); | |
288 ASSERT_EQ(1U, s.size()); | |
289 EXPECT_EQ(kArm64Mov32, s[0]->arch_opcode()); | |
290 } | |
291 | 420 |
292 | 421 |
293 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) { | |
294 StreamBuilder m(this, kMachInt32, kMachInt64); | |
295 m.Return(m.TruncateInt64ToInt32(m.Parameter(0))); | |
296 Stream s = m.Build(); | |
297 ASSERT_EQ(1U, s.size()); | |
298 EXPECT_EQ(kArm64Mov32, s[0]->arch_opcode()); | |
299 } | |
300 | |
301 } // namespace compiler | 422 } // namespace compiler |
302 } // namespace internal | 423 } // namespace internal |
303 } // namespace v8 | 424 } // namespace v8 |
OLD | NEW |