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

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

Issue 610323004: [turbofan] Negated immediates for ARM64 add/sub (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Split out addition tests 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff, 77 0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff,
78 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff, 78 0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff,
79 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000, 79 0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000,
80 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf, 80 0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf,
81 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff, 81 0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff,
82 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff, 82 0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff,
83 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff}; 83 0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff};
84 84
85 85
86 // ARM64 arithmetic instructions. 86 // ARM64 arithmetic instructions.
87 static const MachInst2 kAddSubInstructions[] = { 87 struct AddSub {
88 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, 88 MachInst2 mi;
89 {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, 89 ArchOpcode negate_arch_opcode;
90 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, 90 };
91 {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}}; 91
92
93 std::ostream& operator<<(std::ostream& os, const AddSub& op) {
94 return os << op.mi;
95 }
96
97
98 static const AddSub kAddSubInstructions[] = {
99 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
100 kArm64Sub32},
101 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
102 kArm64Sub},
103 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
104 kArm64Add32},
105 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64},
106 kArm64Add}};
92 107
93 108
94 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. 109 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
95 // Below is a combination of a random subset and some edge values. 110 // Below is a combination of a random subset and some edge values.
96 static const int32_t kAddSubImmediates[] = { 111 static const int32_t kAddSubImmediates[] = {
97 0, 1, 69, 493, 599, 701, 719, 112 0, 1, 69, 493, 599, 701, 719,
98 768, 818, 842, 945, 1246, 1286, 1429, 113 768, 818, 842, 945, 1246, 1286, 1429,
99 1669, 2171, 2179, 2182, 2254, 2334, 2338, 114 1669, 2171, 2179, 2182, 2254, 2334, 2338,
100 2343, 2396, 2449, 2610, 2732, 2855, 2876, 115 2343, 2396, 2449, 2610, 2732, 2855, 2876,
101 2944, 3377, 3458, 3475, 3476, 3540, 3574, 116 2944, 3377, 3458, 3475, 3476, 3540, 3574,
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 296 }
282 297
283 298
284 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest, 299 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
285 ::testing::ValuesIn(kLogicalInstructions)); 300 ::testing::ValuesIn(kLogicalInstructions));
286 301
287 302
288 // ----------------------------------------------------------------------------- 303 // -----------------------------------------------------------------------------
289 // Add and Sub instructions. 304 // Add and Sub instructions.
290 305
291 typedef InstructionSelectorTestWithParam<MachInst2> 306 typedef InstructionSelectorTestWithParam<AddSub> InstructionSelectorAddSubTest;
292 InstructionSelectorAddSubTest;
293 307
294 308
295 TEST_P(InstructionSelectorAddSubTest, Parameter) { 309 TEST_P(InstructionSelectorAddSubTest, Parameter) {
296 const MachInst2 dpi = GetParam(); 310 const AddSub dpi = GetParam();
297 const MachineType type = dpi.machine_type; 311 const MachineType type = dpi.mi.machine_type;
298 StreamBuilder m(this, type, type, type); 312 StreamBuilder m(this, type, type, type);
299 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); 313 m.Return((m.*dpi.mi.constructor)(m.Parameter(0), m.Parameter(1)));
300 Stream s = m.Build(); 314 Stream s = m.Build();
301 ASSERT_EQ(1U, s.size()); 315 ASSERT_EQ(1U, s.size());
302 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 316 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
303 EXPECT_EQ(2U, s[0]->InputCount()); 317 EXPECT_EQ(2U, s[0]->InputCount());
304 EXPECT_EQ(1U, s[0]->OutputCount()); 318 EXPECT_EQ(1U, s[0]->OutputCount());
305 } 319 }
306 320
307 321
308 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { 322 TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) {
309 const MachInst2 dpi = GetParam(); 323 const AddSub dpi = GetParam();
310 const MachineType type = dpi.machine_type; 324 const MachineType type = dpi.mi.machine_type;
311 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 325 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
312 StreamBuilder m(this, type, type); 326 StreamBuilder m(this, type, type);
313 m.Return((m.*dpi.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); 327 m.Return(
328 (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
314 Stream s = m.Build(); 329 Stream s = m.Build();
315 ASSERT_EQ(1U, s.size()); 330 ASSERT_EQ(1U, s.size());
316 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 331 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
317 ASSERT_EQ(2U, s[0]->InputCount()); 332 ASSERT_EQ(2U, s[0]->InputCount());
318 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 333 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
319 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); 334 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
320 EXPECT_EQ(1U, s[0]->OutputCount()); 335 EXPECT_EQ(1U, s[0]->OutputCount());
321 } 336 }
322 } 337 }
323 338
324 339
325 TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) { 340 TEST_P(InstructionSelectorAddSubTest, NegImmediateOnRight) {
326 const MachInst2 dpi = GetParam(); 341 const AddSub dpi = GetParam();
327 const MachineType type = dpi.machine_type; 342 const MachineType type = dpi.mi.machine_type;
343 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
344 if (imm == 0) continue;
345 StreamBuilder m(this, type, type);
346 m.Return(
347 (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, -imm)));
348 Stream s = m.Build();
349 ASSERT_EQ(1U, s.size());
350 EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode());
351 ASSERT_EQ(2U, s[0]->InputCount());
352 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
353 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
354 EXPECT_EQ(1U, s[0]->OutputCount());
355 }
356 }
328 357
329 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
330 StreamBuilder m(this, type, type);
331 m.Return((m.*dpi.constructor)(BuildConstant(m, type, imm), m.Parameter(0)));
332 Stream s = m.Build();
333 358
334 // Add can support an immediate on the left by commuting, but Sub can't 359 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
335 // commute. We test zero-on-left Sub later. 360 ::testing::ValuesIn(kAddSubInstructions));
336 if (strstr(dpi.constructor_name, "Add") != NULL) { 361
362
363 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) {
364 {
365 // 32-bit add.
366 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
367 StreamBuilder m(this, kMachInt32, kMachInt32);
368 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
369 Stream s = m.Build();
337 ASSERT_EQ(1U, s.size()); 370 ASSERT_EQ(1U, s.size());
338 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 371 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
372 ASSERT_EQ(2U, s[0]->InputCount());
373 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
374 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
375 EXPECT_EQ(1U, s[0]->OutputCount());
376 }
377 }
378 {
379 // 64-bit add.
380 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
381 StreamBuilder m(this, kMachInt64, kMachInt64);
382 m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0)));
383 Stream s = m.Build();
384 ASSERT_EQ(1U, s.size());
385 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
339 ASSERT_EQ(2U, s[0]->InputCount()); 386 ASSERT_EQ(2U, s[0]->InputCount());
340 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 387 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
341 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); 388 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
342 EXPECT_EQ(1U, s[0]->OutputCount()); 389 EXPECT_EQ(1U, s[0]->OutputCount());
343 } 390 }
344 } 391 }
345 } 392 }
346 393
347 394
348 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
349 ::testing::ValuesIn(kAddSubInstructions));
350
351
352 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { 395 TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
353 // Subtraction with zero on the left maps to Neg. 396 // Subtraction with zero on the left maps to Neg.
354 { 397 {
355 // 32-bit subtract. 398 // 32-bit subtract.
356 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 399 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
357 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); 400 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0)));
358 Stream s = m.Build(); 401 Stream s = m.Build();
359 402
360 ASSERT_EQ(1U, s.size()); 403 ASSERT_EQ(1U, s.size());
361 EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode()); 404 EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode());
362 EXPECT_EQ(1U, s[0]->InputCount()); 405 EXPECT_EQ(1U, s[0]->InputCount());
363 EXPECT_EQ(1U, s[0]->OutputCount()); 406 EXPECT_EQ(1U, s[0]->OutputCount());
364 } 407 }
365 { 408 {
366 // 64-bit subtract. 409 // 64-bit subtract.
367 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 410 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
368 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0))); 411 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0)));
369 Stream s = m.Build(); 412 Stream s = m.Build();
370 413
371 ASSERT_EQ(1U, s.size()); 414 ASSERT_EQ(1U, s.size());
372 EXPECT_EQ(kArm64Neg, s[0]->arch_opcode()); 415 EXPECT_EQ(kArm64Neg, s[0]->arch_opcode());
373 EXPECT_EQ(1U, s[0]->InputCount()); 416 EXPECT_EQ(1U, s[0]->InputCount());
374 EXPECT_EQ(1U, s[0]->OutputCount()); 417 EXPECT_EQ(1U, s[0]->OutputCount());
375 } 418 }
376 } 419 }
377 420
378 421
422 TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) {
423 {
424 // 32-bit add.
425 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
426 if (imm == 0) continue;
427 StreamBuilder m(this, kMachInt32, kMachInt32);
428 m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0)));
429 Stream s = m.Build();
430
431 ASSERT_EQ(1U, s.size());
432 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
433 ASSERT_EQ(2U, s[0]->InputCount());
434 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
435 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
436 EXPECT_EQ(1U, s[0]->OutputCount());
437 }
438 }
439 {
440 // 64-bit add.
441 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
442 if (imm == 0) continue;
443 StreamBuilder m(this, kMachInt64, kMachInt64);
444 m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0)));
445 Stream s = m.Build();
446
447 ASSERT_EQ(1U, s.size());
448 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
449 ASSERT_EQ(2U, s[0]->InputCount());
450 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
451 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
452 EXPECT_EQ(1U, s[0]->OutputCount());
453 }
454 }
455 }
456
457
379 // ----------------------------------------------------------------------------- 458 // -----------------------------------------------------------------------------
380 // Data processing controlled branches. 459 // Data processing controlled branches.
381 460
382 461
383 typedef InstructionSelectorTestWithParam<MachInst2> 462 typedef InstructionSelectorTestWithParam<MachInst2>
384 InstructionSelectorDPFlagSetTest; 463 InstructionSelectorDPFlagSetTest;
385 464
386 465
387 TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) { 466 TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) {
388 const MachInst2 dpi = GetParam(); 467 const MachInst2 dpi = GetParam();
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 ASSERT_EQ(1U, s.size()); 1483 ASSERT_EQ(1U, s.size());
1405 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); 1484 EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
1406 EXPECT_EQ(1U, s[0]->InputCount()); 1485 EXPECT_EQ(1U, s[0]->InputCount());
1407 EXPECT_EQ(1U, s[0]->OutputCount()); 1486 EXPECT_EQ(1U, s[0]->OutputCount());
1408 } 1487 }
1409 } 1488 }
1410 1489
1411 } // namespace compiler 1490 } // namespace compiler
1412 } // namespace internal 1491 } // namespace internal
1413 } // namespace v8 1492 } // 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