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

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.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 | « no previous file | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('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 "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 26 matching lines...) Expand all
37 } 37 }
38 38
39 bool CanBeImmediate(Node* node, ImmediateMode mode) { 39 bool CanBeImmediate(Node* node, ImmediateMode mode) {
40 int64_t value; 40 int64_t value;
41 if (node->opcode() == IrOpcode::kInt32Constant) 41 if (node->opcode() == IrOpcode::kInt32Constant)
42 value = OpParameter<int32_t>(node); 42 value = OpParameter<int32_t>(node);
43 else if (node->opcode() == IrOpcode::kInt64Constant) 43 else if (node->opcode() == IrOpcode::kInt64Constant)
44 value = OpParameter<int64_t>(node); 44 value = OpParameter<int64_t>(node);
45 else 45 else
46 return false; 46 return false;
47 return CanBeImmediate(value, mode);
48 }
49
50 bool CanBeImmediate(int64_t value, ImmediateMode mode) {
47 unsigned ignored; 51 unsigned ignored;
48 switch (mode) { 52 switch (mode) {
49 case kLogical32Imm: 53 case kLogical32Imm:
50 // TODO(dcarney): some unencodable values can be handled by 54 // TODO(dcarney): some unencodable values can be handled by
51 // switching instructions. 55 // switching instructions.
52 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 32, 56 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 32,
53 &ignored, &ignored, &ignored); 57 &ignored, &ignored, &ignored);
54 case kLogical64Imm: 58 case kLogical64Imm:
55 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64, 59 return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64,
56 &ignored, &ignored, &ignored); 60 &ignored, &ignored, &ignored);
57 case kArithmeticImm: 61 case kArithmeticImm:
58 // TODO(dcarney): -values can be handled by instruction swapping
59 return Assembler::IsImmAddSub(value); 62 return Assembler::IsImmAddSub(value);
60 case kShift32Imm: 63 case kShift32Imm:
61 return 0 <= value && value < 32; 64 return 0 <= value && value < 32;
62 case kShift64Imm: 65 case kShift64Imm:
63 return 0 <= value && value < 64; 66 return 0 <= value && value < 64;
64 case kLoadStoreImm8: 67 case kLoadStoreImm8:
65 return IsLoadStoreImmediate(value, LSByte); 68 return IsLoadStoreImmediate(value, LSByte);
66 case kLoadStoreImm16: 69 case kLoadStoreImm16:
67 return IsLoadStoreImmediate(value, LSHalfword); 70 return IsLoadStoreImmediate(value, LSHalfword);
68 case kLoadStoreImm32: 71 case kLoadStoreImm32:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 151
149 // Shared routine for multiple binary operations. 152 // Shared routine for multiple binary operations.
150 template <typename Matcher> 153 template <typename Matcher>
151 static void VisitBinop(InstructionSelector* selector, Node* node, 154 static void VisitBinop(InstructionSelector* selector, Node* node,
152 ArchOpcode opcode, ImmediateMode operand_mode) { 155 ArchOpcode opcode, ImmediateMode operand_mode) {
153 FlagsContinuation cont; 156 FlagsContinuation cont;
154 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); 157 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
155 } 158 }
156 159
157 160
161 template <typename Matcher>
162 static void VisitAddSub(InstructionSelector* selector, Node* node,
163 ArchOpcode opcode, ArchOpcode negate_opcode) {
164 Arm64OperandGenerator g(selector);
165 Matcher m(node);
166 if (m.right().HasValue() && (m.right().Value() < 0) &&
167 g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) {
168 selector->Emit(negate_opcode, g.DefineAsRegister(node),
169 g.UseRegister(m.left().node()),
170 g.TempImmediate(-m.right().Value()));
171 } else {
172 VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm);
173 }
174 }
175
176
158 void InstructionSelector::VisitLoad(Node* node) { 177 void InstructionSelector::VisitLoad(Node* node) {
159 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 178 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
160 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 179 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
161 Arm64OperandGenerator g(this); 180 Arm64OperandGenerator g(this);
162 Node* base = node->InputAt(0); 181 Node* base = node->InputAt(0);
163 Node* index = node->InputAt(1); 182 Node* index = node->InputAt(1);
164 ArchOpcode opcode; 183 ArchOpcode opcode;
165 ImmediateMode immediate_mode = kNoImmediate; 184 ImmediateMode immediate_mode = kNoImmediate;
166 switch (rep) { 185 switch (rep) {
167 case kRepFloat32: 186 case kRepFloat32:
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 return; 454 return;
436 } 455 }
437 // Select Madd(x, y, z) for Add(x, Mul(x, y)). 456 // Select Madd(x, y, z) for Add(x, Mul(x, y)).
438 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { 457 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
439 Int32BinopMatcher mright(m.right().node()); 458 Int32BinopMatcher mright(m.right().node());
440 Emit(kArm64Madd32, g.DefineAsRegister(node), 459 Emit(kArm64Madd32, g.DefineAsRegister(node),
441 g.UseRegister(mright.left().node()), 460 g.UseRegister(mright.left().node()),
442 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 461 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
443 return; 462 return;
444 } 463 }
445 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm); 464 VisitAddSub<Int32BinopMatcher>(this, node, kArm64Add32, kArm64Sub32);
446 } 465 }
447 466
448 467
449 void InstructionSelector::VisitInt64Add(Node* node) { 468 void InstructionSelector::VisitInt64Add(Node* node) {
450 Arm64OperandGenerator g(this); 469 Arm64OperandGenerator g(this);
451 Int64BinopMatcher m(node); 470 Int64BinopMatcher m(node);
452 // Select Madd(x, y, z) for Add(Mul(x, y), z). 471 // Select Madd(x, y, z) for Add(Mul(x, y), z).
453 if (m.left().IsInt64Mul() && CanCover(node, m.left().node())) { 472 if (m.left().IsInt64Mul() && CanCover(node, m.left().node())) {
454 Int64BinopMatcher mleft(m.left().node()); 473 Int64BinopMatcher mleft(m.left().node());
455 Emit(kArm64Madd, g.DefineAsRegister(node), 474 Emit(kArm64Madd, g.DefineAsRegister(node),
456 g.UseRegister(mleft.left().node()), 475 g.UseRegister(mleft.left().node()),
457 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); 476 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
458 return; 477 return;
459 } 478 }
460 // Select Madd(x, y, z) for Add(x, Mul(x, y)). 479 // Select Madd(x, y, z) for Add(x, Mul(x, y)).
461 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) { 480 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
462 Int64BinopMatcher mright(m.right().node()); 481 Int64BinopMatcher mright(m.right().node());
463 Emit(kArm64Madd, g.DefineAsRegister(node), 482 Emit(kArm64Madd, g.DefineAsRegister(node),
464 g.UseRegister(mright.left().node()), 483 g.UseRegister(mright.left().node()),
465 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 484 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
466 return; 485 return;
467 } 486 }
468 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm); 487 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Add, kArm64Sub);
469 } 488 }
470 489
471 490
472 void InstructionSelector::VisitInt32Sub(Node* node) { 491 void InstructionSelector::VisitInt32Sub(Node* node) {
473 Arm64OperandGenerator g(this); 492 Arm64OperandGenerator g(this);
474 Int32BinopMatcher m(node); 493 Int32BinopMatcher m(node);
475 494
476 // Select Msub(a, x, y) for Sub(a, Mul(x, y)). 495 // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
477 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { 496 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
478 Int32BinopMatcher mright(m.right().node()); 497 Int32BinopMatcher mright(m.right().node());
479 Emit(kArm64Msub32, g.DefineAsRegister(node), 498 Emit(kArm64Msub32, g.DefineAsRegister(node),
480 g.UseRegister(mright.left().node()), 499 g.UseRegister(mright.left().node()),
481 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 500 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
482 return; 501 return;
483 } 502 }
484 503
485 if (m.left().Is(0)) { 504 if (m.left().Is(0)) {
486 Emit(kArm64Neg32, g.DefineAsRegister(node), 505 Emit(kArm64Neg32, g.DefineAsRegister(node),
487 g.UseRegister(m.right().node())); 506 g.UseRegister(m.right().node()));
488 } else { 507 } else {
489 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm); 508 VisitAddSub<Int32BinopMatcher>(this, node, kArm64Sub32, kArm64Add32);
490 } 509 }
491 } 510 }
492 511
493 512
494 void InstructionSelector::VisitInt64Sub(Node* node) { 513 void InstructionSelector::VisitInt64Sub(Node* node) {
495 Arm64OperandGenerator g(this); 514 Arm64OperandGenerator g(this);
496 Int64BinopMatcher m(node); 515 Int64BinopMatcher m(node);
497 516
498 // Select Msub(a, x, y) for Sub(a, Mul(x, y)). 517 // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
499 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) { 518 if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
500 Int64BinopMatcher mright(m.right().node()); 519 Int64BinopMatcher mright(m.right().node());
501 Emit(kArm64Msub, g.DefineAsRegister(node), 520 Emit(kArm64Msub, g.DefineAsRegister(node),
502 g.UseRegister(mright.left().node()), 521 g.UseRegister(mright.left().node()),
503 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 522 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
504 return; 523 return;
505 } 524 }
506 525
507 if (m.left().Is(0)) { 526 if (m.left().Is(0)) {
508 Emit(kArm64Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node())); 527 Emit(kArm64Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
509 } else { 528 } else {
510 VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm); 529 VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add);
511 } 530 }
512 } 531 }
513 532
514 533
515 void InstructionSelector::VisitInt32Mul(Node* node) { 534 void InstructionSelector::VisitInt32Mul(Node* node) {
516 Arm64OperandGenerator g(this); 535 Arm64OperandGenerator g(this);
517 Int32BinopMatcher m(node); 536 Int32BinopMatcher m(node);
518 537
519 if (m.left().IsInt32Sub() && CanCover(node, m.left().node())) { 538 if (m.left().IsInt32Sub() && CanCover(node, m.left().node())) {
520 Int32BinopMatcher mleft(m.left().node()); 539 Int32BinopMatcher mleft(m.left().node());
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 call_instr->MarkAsCall(); 904 call_instr->MarkAsCall();
886 if (deoptimization != NULL) { 905 if (deoptimization != NULL) {
887 DCHECK(continuation != NULL); 906 DCHECK(continuation != NULL);
888 call_instr->MarkAsControl(); 907 call_instr->MarkAsControl();
889 } 908 }
890 } 909 }
891 910
892 } // namespace compiler 911 } // namespace compiler
893 } // namespace internal 912 } // namespace internal
894 } // namespace v8 913 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698