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

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

Issue 652363006: [turbofan] First step towards correctified 64-bit addressing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes2 Created 6 years, 1 month 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 | « test/unittests/compiler/instruction-selector-unittest.cc ('k') | tools/gyp/v8.gyp » ('j') | 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 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.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 {
14
15 // Immediates (random subset).
16 static const int32_t kImmediates[] = {
17 kMinInt, -42, -1, 0, 1, 2, 3, 4, 5,
18 6, 7, 8, 16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt};
19
20 } // namespace
21
22
23 // ----------------------------------------------------------------------------- 13 // -----------------------------------------------------------------------------
24 // Conversions. 14 // Conversions.
25 15
26 16
27 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { 17 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
28 StreamBuilder m(this, kMachFloat32, kMachFloat64); 18 StreamBuilder m(this, kMachFloat32, kMachFloat64);
29 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); 19 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
30 Stream s = m.Build(); 20 Stream s = m.Build();
31 ASSERT_EQ(1U, s.size()); 21 ASSERT_EQ(1U, s.size());
32 EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode()); 22 EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) { 66 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
77 StreamBuilder m(this, kMachInt32, kMachInt64); 67 StreamBuilder m(this, kMachInt32, kMachInt64);
78 m.Return(m.TruncateInt64ToInt32(m.Parameter(0))); 68 m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
79 Stream s = m.Build(); 69 Stream s = m.Build();
80 ASSERT_EQ(1U, s.size()); 70 ASSERT_EQ(1U, s.size());
81 EXPECT_EQ(kX64Movl, s[0]->arch_opcode()); 71 EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
82 } 72 }
83 73
84 74
85 // ----------------------------------------------------------------------------- 75 // -----------------------------------------------------------------------------
86 // Better left operand for commutative binops
87
88 TEST_F(InstructionSelectorTest, BetterLeftOperandTestAddBinop) {
89 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
90 Node* param1 = m.Parameter(0);
91 Node* param2 = m.Parameter(1);
92 Node* add = m.Int32Add(param1, param2);
93 m.Return(m.Int32Add(add, param1));
94 Stream s = m.Build();
95 ASSERT_EQ(2U, s.size());
96 EXPECT_EQ(kX64Add32, s[0]->arch_opcode());
97 ASSERT_EQ(2U, s[0]->InputCount());
98 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated());
99 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(0)));
100 }
101
102
103 TEST_F(InstructionSelectorTest, BetterLeftOperandTestMulBinop) {
104 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
105 Node* param1 = m.Parameter(0);
106 Node* param2 = m.Parameter(1);
107 Node* mul = m.Int32Mul(param1, param2);
108 m.Return(m.Int32Mul(mul, param1));
109 Stream s = m.Build();
110 ASSERT_EQ(2U, s.size());
111 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
112 ASSERT_EQ(2U, s[0]->InputCount());
113 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated());
114 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(0)));
115 }
116
117
118 // -----------------------------------------------------------------------------
119 // Loads and stores 76 // Loads and stores
120 77
121 namespace { 78 namespace {
122 79
123 struct MemoryAccess { 80 struct MemoryAccess {
124 MachineType type; 81 MachineType type;
125 ArchOpcode load_opcode; 82 ArchOpcode load_opcode;
126 ArchOpcode store_opcode; 83 ArchOpcode store_opcode;
127 }; 84 };
128 85
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 EXPECT_EQ(3U, s[0]->InputCount()); 131 EXPECT_EQ(3U, s[0]->InputCount());
175 EXPECT_EQ(0U, s[0]->OutputCount()); 132 EXPECT_EQ(0U, s[0]->OutputCount());
176 } 133 }
177 134
178 135
179 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 136 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
180 InstructionSelectorMemoryAccessTest, 137 InstructionSelectorMemoryAccessTest,
181 ::testing::ValuesIn(kMemoryAccesses)); 138 ::testing::ValuesIn(kMemoryAccesses));
182 139
183 // ----------------------------------------------------------------------------- 140 // -----------------------------------------------------------------------------
184 // AddressingMode for loads and stores. 141 // ChangeUint32ToUint64.
185 142
186 class AddressingModeUnitTest : public InstructionSelectorTest {
187 public:
188 AddressingModeUnitTest() : m(NULL) { Reset(); }
189 ~AddressingModeUnitTest() { delete m; }
190 143
191 void Run(Node* base, Node* index, AddressingMode mode) { 144 namespace {
192 Node* load = m->Load(kMachInt32, base, index);
193 m->Store(kMachInt32, base, index, load);
194 m->Return(m->Int32Constant(0));
195 Stream s = m->Build();
196 ASSERT_EQ(2U, s.size());
197 EXPECT_EQ(mode, s[0]->addressing_mode());
198 EXPECT_EQ(mode, s[1]->addressing_mode());
199 }
200 145
201 Node* zero; 146 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
202 Node* null_ptr;
203 Node* non_zero;
204 Node* base_reg; // opaque value to generate base as register
205 Node* index_reg; // opaque value to generate index as register
206 Node* scales[arraysize(ScaleFactorMatcher::kMatchedFactors)];
207 StreamBuilder* m;
208 147
209 void Reset() { 148
210 delete m; 149 struct BinaryOperation {
211 m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32); 150 Constructor constructor;
212 zero = m->Int32Constant(0); 151 const char* constructor_name;
213 null_ptr = m->Int64Constant(0);
214 non_zero = m->Int32Constant(127);
215 base_reg = m->Parameter(0);
216 index_reg = m->Parameter(0);
217 for (size_t i = 0; i < arraysize(ScaleFactorMatcher::kMatchedFactors);
218 ++i) {
219 scales[i] = m->Int32Constant(ScaleFactorMatcher::kMatchedFactors[i]);
220 }
221 }
222 }; 152 };
223 153
224 154
225 TEST_F(AddressingModeUnitTest, AddressingMode_MR) { 155 std::ostream& operator<<(std::ostream& os, const BinaryOperation& bop) {
226 Node* base = base_reg; 156 return os << bop.constructor_name;
227 Node* index = zero;
228 Run(base, index, kMode_MR);
229 } 157 }
230 158
231 159
232 TEST_F(AddressingModeUnitTest, AddressingMode_MRI) { 160 const BinaryOperation kWord32BinaryOperations[] = {
233 Node* base = base_reg; 161 {&RawMachineAssembler::Word32And, "Word32And"},
234 Node* index = non_zero; 162 {&RawMachineAssembler::Word32Or, "Word32Or"},
235 Run(base, index, kMode_MRI); 163 {&RawMachineAssembler::Word32Xor, "Word32Xor"},
164 {&RawMachineAssembler::Word32Shl, "Word32Shl"},
165 {&RawMachineAssembler::Word32Shr, "Word32Shr"},
166 {&RawMachineAssembler::Word32Sar, "Word32Sar"},
167 {&RawMachineAssembler::Word32Ror, "Word32Ror"},
168 {&RawMachineAssembler::Word32Equal, "Word32Equal"},
169 {&RawMachineAssembler::Int32Add, "Int32Add"},
170 {&RawMachineAssembler::Int32Sub, "Int32Sub"},
171 {&RawMachineAssembler::Int32Mul, "Int32Mul"},
172 {&RawMachineAssembler::Int32MulHigh, "Int32MulHigh"},
173 {&RawMachineAssembler::Int32Div, "Int32Div"},
174 {&RawMachineAssembler::Int32LessThan, "Int32LessThan"},
175 {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual"},
176 {&RawMachineAssembler::Int32Mod, "Int32Mod"},
177 {&RawMachineAssembler::Uint32Div, "Uint32Div"},
178 {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan"},
179 {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual"},
180 {&RawMachineAssembler::Uint32Mod, "Uint32Mod"}};
181
182 } // namespace
183
184
185 typedef InstructionSelectorTestWithParam<BinaryOperation>
186 InstructionSelectorChangeUint32ToUint64Test;
187
188
189 TEST_P(InstructionSelectorChangeUint32ToUint64Test, ChangeUint32ToUint64) {
190 const BinaryOperation& bop = GetParam();
191 StreamBuilder m(this, kMachUint64, kMachInt32, kMachInt32);
192 Node* const p0 = m.Parameter(0);
193 Node* const p1 = m.Parameter(1);
194 m.Return(m.ChangeUint32ToUint64((m.*bop.constructor)(p0, p1)));
195 Stream s = m.Build();
196 ASSERT_EQ(1U, s.size());
236 } 197 }
237 198
238 199
239 TEST_F(AddressingModeUnitTest, AddressingMode_MR1) { 200 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
240 Node* base = base_reg; 201 InstructionSelectorChangeUint32ToUint64Test,
241 Node* index = index_reg; 202 ::testing::ValuesIn(kWord32BinaryOperations));
242 Run(base, index, kMode_MR1); 203
204
205 // -----------------------------------------------------------------------------
206 // TruncateInt64ToInt32.
207
208
209 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) {
210 StreamBuilder m(this, kMachInt32, kMachInt64);
211 Node* const p = m.Parameter(0);
212 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32)));
213 m.Return(t);
214 Stream s = m.Build();
215 ASSERT_EQ(1U, s.size());
216 EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
217 ASSERT_EQ(2U, s[0]->InputCount());
218 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
219 EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
220 ASSERT_EQ(1U, s[0]->OutputCount());
221 EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
222 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
243 } 223 }
244 224
245 225
246 TEST_F(AddressingModeUnitTest, AddressingMode_MRN) { 226 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) {
247 AddressingMode expected[] = {kMode_MR1, kMode_MR2, kMode_MR4, kMode_MR8}; 227 StreamBuilder m(this, kMachInt32, kMachInt64);
248 for (size_t i = 0; i < arraysize(scales); ++i) { 228 Node* const p = m.Parameter(0);
249 Reset(); 229 Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(32)));
250 Node* base = base_reg; 230 m.Return(t);
251 Node* index = m->Int32Mul(index_reg, scales[i]); 231 Stream s = m.Build();
252 Run(base, index, expected[i]); 232 ASSERT_EQ(1U, s.size());
253 } 233 EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
234 ASSERT_EQ(2U, s[0]->InputCount());
235 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
236 EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
237 ASSERT_EQ(1U, s[0]->OutputCount());
238 EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
239 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
254 } 240 }
255 241
256 242
257 TEST_F(AddressingModeUnitTest, AddressingMode_MR1I) { 243 // -----------------------------------------------------------------------------
258 Node* base = base_reg; 244 // Addition.
259 Node* index = m->Int32Add(index_reg, non_zero);
260 Run(base, index, kMode_MR1I);
261 }
262 245
263 246
264 TEST_F(AddressingModeUnitTest, AddressingMode_MRNI) { 247 TEST_F(InstructionSelectorTest, Int32AddWithInt32AddWithParameters) {
265 AddressingMode expected[] = {kMode_MR1I, kMode_MR2I, kMode_MR4I, kMode_MR8I}; 248 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
266 for (size_t i = 0; i < arraysize(scales); ++i) { 249 Node* const p0 = m.Parameter(0);
267 Reset(); 250 Node* const p1 = m.Parameter(1);
268 Node* base = base_reg; 251 Node* const a0 = m.Int32Add(p0, p1);
269 Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero); 252 m.Return(m.Int32Add(a0, p0));
270 Run(base, index, expected[i]); 253 Stream s = m.Build();
271 } 254 ASSERT_EQ(2U, s.size());
272 } 255 EXPECT_EQ(kX64Add32, s[0]->arch_opcode());
273 256 ASSERT_EQ(2U, s[0]->InputCount());
274 257 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
275 TEST_F(AddressingModeUnitTest, AddressingMode_M1) { 258 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
276 Node* base = null_ptr;
277 Node* index = index_reg;
278 Run(base, index, kMode_M1);
279 }
280
281
282 TEST_F(AddressingModeUnitTest, AddressingMode_MN) {
283 AddressingMode expected[] = {kMode_M1, kMode_M2, kMode_M4, kMode_M8};
284 for (size_t i = 0; i < arraysize(scales); ++i) {
285 Reset();
286 Node* base = null_ptr;
287 Node* index = m->Int32Mul(index_reg, scales[i]);
288 Run(base, index, expected[i]);
289 }
290 }
291
292
293 TEST_F(AddressingModeUnitTest, AddressingMode_M1I) {
294 Node* base = null_ptr;
295 Node* index = m->Int32Add(index_reg, non_zero);
296 Run(base, index, kMode_M1I);
297 }
298
299
300 TEST_F(AddressingModeUnitTest, AddressingMode_MNI) {
301 AddressingMode expected[] = {kMode_M1I, kMode_M2I, kMode_M4I, kMode_M8I};
302 for (size_t i = 0; i < arraysize(scales); ++i) {
303 Reset();
304 Node* base = null_ptr;
305 Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
306 Run(base, index, expected[i]);
307 }
308 } 259 }
309 260
310 261
311 // ----------------------------------------------------------------------------- 262 // -----------------------------------------------------------------------------
312 // Multiplication. 263 // Multiplication.
313 264
314 namespace {
315 265
316 struct MultParam { 266 TEST_F(InstructionSelectorTest, Int32MulWithInt32MulWithParameters) {
317 int value; 267 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
318 bool lea_expected; 268 Node* const p0 = m.Parameter(0);
319 AddressingMode addressing_mode; 269 Node* const p1 = m.Parameter(1);
320 }; 270 Node* const m0 = m.Int32Mul(p0, p1);
321 271 m.Return(m.Int32Mul(m0, p0));
322 272 Stream s = m.Build();
323 std::ostream& operator<<(std::ostream& os, const MultParam& m) { 273 ASSERT_EQ(2U, s.size());
324 return os << m.value << "." << m.lea_expected << "." << m.addressing_mode; 274 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
275 ASSERT_EQ(2U, s[0]->InputCount());
276 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
277 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
278 ASSERT_EQ(1U, s[0]->OutputCount());
279 EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[0]->OutputAt(0)));
280 EXPECT_EQ(kX64Imul32, s[1]->arch_opcode());
281 ASSERT_EQ(2U, s[1]->InputCount());
282 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
283 EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[1]->InputAt(1)));
325 } 284 }
326 285
327 286
328 const MultParam kMultParams[] = {{-1, false, kMode_None},
329 {0, false, kMode_None},
330 {1, true, kMode_M1},
331 {2, true, kMode_M2},
332 {3, true, kMode_MR2},
333 {4, true, kMode_M4},
334 {5, true, kMode_MR4},
335 {6, false, kMode_None},
336 {7, false, kMode_None},
337 {8, true, kMode_M8},
338 {9, true, kMode_MR8},
339 {10, false, kMode_None},
340 {11, false, kMode_None}};
341
342 } // namespace
343
344
345 typedef InstructionSelectorTestWithParam<MultParam> InstructionSelectorMultTest;
346
347
348 static unsigned InputCountForLea(AddressingMode mode) {
349 switch (mode) {
350 case kMode_MR1I:
351 case kMode_MR2I:
352 case kMode_MR4I:
353 case kMode_MR8I:
354 return 3U;
355 case kMode_M1I:
356 case kMode_M2I:
357 case kMode_M4I:
358 case kMode_M8I:
359 return 2U;
360 case kMode_MR1:
361 case kMode_MR2:
362 case kMode_MR4:
363 case kMode_MR8:
364 return 2U;
365 case kMode_M1:
366 case kMode_M2:
367 case kMode_M4:
368 case kMode_M8:
369 return 1U;
370 default:
371 UNREACHABLE();
372 return 0U;
373 }
374 }
375
376
377 static AddressingMode AddressingModeForAddMult(const MultParam& m) {
378 switch (m.addressing_mode) {
379 case kMode_MR1:
380 return kMode_MR1I;
381 case kMode_MR2:
382 return kMode_MR2I;
383 case kMode_MR4:
384 return kMode_MR4I;
385 case kMode_MR8:
386 return kMode_MR8I;
387 case kMode_M1:
388 return kMode_M1I;
389 case kMode_M2:
390 return kMode_M2I;
391 case kMode_M4:
392 return kMode_M4I;
393 case kMode_M8:
394 return kMode_M8I;
395 default:
396 UNREACHABLE();
397 return kMode_None;
398 }
399 }
400
401
402 TEST_P(InstructionSelectorMultTest, Mult32) {
403 const MultParam m_param = GetParam();
404 StreamBuilder m(this, kMachInt32, kMachInt32);
405 Node* param = m.Parameter(0);
406 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value));
407 m.Return(mult);
408 Stream s = m.Build();
409 ASSERT_EQ(1U, s.size());
410 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode());
411 if (m_param.lea_expected) {
412 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
413 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount());
414 } else {
415 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
416 ASSERT_EQ(2U, s[0]->InputCount());
417 }
418 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0)));
419 }
420
421
422 TEST_P(InstructionSelectorMultTest, Mult64) {
423 const MultParam m_param = GetParam();
424 StreamBuilder m(this, kMachInt64, kMachInt64);
425 Node* param = m.Parameter(0);
426 Node* mult = m.Int64Mul(param, m.Int64Constant(m_param.value));
427 m.Return(mult);
428 Stream s = m.Build();
429 ASSERT_EQ(1U, s.size());
430 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode());
431 if (m_param.lea_expected) {
432 EXPECT_EQ(kX64Lea, s[0]->arch_opcode());
433 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount());
434 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0)));
435 } else {
436 EXPECT_EQ(kX64Imul, s[0]->arch_opcode());
437 ASSERT_EQ(2U, s[0]->InputCount());
438 // TODO(dcarney): why is this happening?
439 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(1)));
440 }
441 }
442
443
444 TEST_P(InstructionSelectorMultTest, MultAdd32) {
445 TRACED_FOREACH(int32_t, imm, kImmediates) {
446 const MultParam m_param = GetParam();
447 StreamBuilder m(this, kMachInt32, kMachInt32);
448 Node* param = m.Parameter(0);
449 Node* mult = m.Int32Add(m.Int32Mul(param, m.Int32Constant(m_param.value)),
450 m.Int32Constant(imm));
451 m.Return(mult);
452 Stream s = m.Build();
453 if (m_param.lea_expected) {
454 ASSERT_EQ(1U, s.size());
455 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
456 EXPECT_EQ(AddressingModeForAddMult(m_param), s[0]->addressing_mode());
457 unsigned input_count = InputCountForLea(s[0]->addressing_mode());
458 ASSERT_EQ(input_count, s[0]->InputCount());
459 ASSERT_EQ(InstructionOperand::IMMEDIATE,
460 s[0]->InputAt(input_count - 1)->kind());
461 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(input_count - 1)));
462 } else {
463 ASSERT_EQ(2U, s.size());
464 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
465 EXPECT_EQ(kX64Add32, s[1]->arch_opcode());
466 }
467 }
468 }
469
470
471 TEST_P(InstructionSelectorMultTest, MultAdd64) {
472 TRACED_FOREACH(int32_t, imm, kImmediates) {
473 const MultParam m_param = GetParam();
474 StreamBuilder m(this, kMachInt64, kMachInt64);
475 Node* param = m.Parameter(0);
476 Node* mult = m.Int64Add(m.Int64Mul(param, m.Int64Constant(m_param.value)),
477 m.Int64Constant(imm));
478 m.Return(mult);
479 Stream s = m.Build();
480 if (m_param.lea_expected) {
481 ASSERT_EQ(1U, s.size());
482 EXPECT_EQ(kX64Lea, s[0]->arch_opcode());
483 EXPECT_EQ(AddressingModeForAddMult(m_param), s[0]->addressing_mode());
484 unsigned input_count = InputCountForLea(s[0]->addressing_mode());
485 ASSERT_EQ(input_count, s[0]->InputCount());
486 ASSERT_EQ(InstructionOperand::IMMEDIATE,
487 s[0]->InputAt(input_count - 1)->kind());
488 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(input_count - 1)));
489 } else {
490 ASSERT_EQ(2U, s.size());
491 EXPECT_EQ(kX64Imul, s[0]->arch_opcode());
492 EXPECT_EQ(kX64Add, s[1]->arch_opcode());
493 }
494 }
495 }
496
497
498 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest,
499 ::testing::ValuesIn(kMultParams));
500
501
502 TEST_F(InstructionSelectorTest, Int32MulHigh) { 287 TEST_F(InstructionSelectorTest, Int32MulHigh) {
503 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 288 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
504 Node* const p0 = m.Parameter(0); 289 Node* const p0 = m.Parameter(0);
505 Node* const p1 = m.Parameter(1); 290 Node* const p1 = m.Parameter(1);
506 Node* const n = m.Int32MulHigh(p0, p1); 291 Node* const n = m.Int32MulHigh(p0, p1);
507 m.Return(n); 292 m.Return(n);
508 Stream s = m.Build(); 293 Stream s = m.Build();
509 ASSERT_EQ(1U, s.size()); 294 ASSERT_EQ(1U, s.size());
510 EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode()); 295 EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode());
511 ASSERT_EQ(2U, s[0]->InputCount()); 296 ASSERT_EQ(2U, s[0]->InputCount());
512 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 297 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
513 EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax)); 298 EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
514 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 299 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
515 EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1))); 300 EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
516 ASSERT_EQ(1U, s[0]->OutputCount()); 301 ASSERT_EQ(1U, s[0]->OutputCount());
517 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 302 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
518 EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx)); 303 EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
519 } 304 }
520 305
521 } // namespace compiler 306 } // namespace compiler
522 } // namespace internal 307 } // namespace internal
523 } // namespace v8 308 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/instruction-selector-unittest.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698