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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 2252333002: [turbofan/x64] Load word64 followed by a shift right 32 -> load (and sign-extend if necessary) high… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 4 years, 4 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
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 <algorithm> 5 #include <algorithm>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/compiler/instruction-selector-impl.h" 8 #include "src/compiler/instruction-selector-impl.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 19 matching lines...) Expand all
30 } 30 }
31 case IrOpcode::kNumberConstant: { 31 case IrOpcode::kNumberConstant: {
32 const double value = OpParameter<double>(node); 32 const double value = OpParameter<double>(node);
33 return bit_cast<int64_t>(value) == 0; 33 return bit_cast<int64_t>(value) == 0;
34 } 34 }
35 default: 35 default:
36 return false; 36 return false;
37 } 37 }
38 } 38 }
39 39
40 int32_t GetImmediateIntegerValue(Node* node) {
41 DCHECK(CanBeImmediate(node));
42 if (node->opcode() == IrOpcode::kInt32Constant) {
43 return OpParameter<int32_t>(node);
44 }
45 DCHECK_EQ(IrOpcode::kInt64Constant, node->opcode());
46 return static_cast<int32_t>(OpParameter<int64_t>(node));
47 }
48
40 bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input, 49 bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input,
41 int effect_level) { 50 int effect_level) {
42 if (input->opcode() != IrOpcode::kLoad || 51 if (input->opcode() != IrOpcode::kLoad ||
43 !selector()->CanCover(node, input)) { 52 !selector()->CanCover(node, input)) {
44 return false; 53 return false;
45 } 54 }
46 if (effect_level != selector()->GetEffectLevel(input)) { 55 if (effect_level != selector()->GetEffectLevel(input)) {
47 return false; 56 return false;
48 } 57 }
49 MachineRepresentation rep = 58 MachineRepresentation rep =
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 } 633 }
625 } 634 }
626 VisitWord64Shift(this, node, kX64Shl); 635 VisitWord64Shift(this, node, kX64Shl);
627 } 636 }
628 637
629 638
630 void InstructionSelector::VisitWord32Shr(Node* node) { 639 void InstructionSelector::VisitWord32Shr(Node* node) {
631 VisitWord32Shift(this, node, kX64Shr32); 640 VisitWord32Shift(this, node, kX64Shr32);
632 } 641 }
633 642
634 643 namespace {
635 void InstructionSelector::VisitWord64Shr(Node* node) { 644 bool TryMatchLoadWord64AndShiftRight(InstructionSelector* selector, Node* node,
636 VisitWord64Shift(this, node, kX64Shr); 645 InstructionCode opcode) {
637 } 646 DCHECK(IrOpcode::kWord64Sar == node->opcode() ||
638 647 IrOpcode::kWord64Shr == node->opcode());
639 648 X64OperandGenerator g(selector);
640 void InstructionSelector::VisitWord32Sar(Node* node) {
641 X64OperandGenerator g(this);
642 Int32BinopMatcher m(node);
643 if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
644 Int32BinopMatcher mleft(m.left().node());
645 if (mleft.right().Is(16) && m.right().Is(16)) {
646 Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
647 return;
648 } else if (mleft.right().Is(24) && m.right().Is(24)) {
649 Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
650 return;
651 }
652 }
653 VisitWord32Shift(this, node, kX64Sar32);
654 }
655
656
657 void InstructionSelector::VisitWord64Sar(Node* node) {
658 X64OperandGenerator g(this);
659 Int64BinopMatcher m(node); 649 Int64BinopMatcher m(node);
660 if (CanCover(m.node(), m.left().node()) && m.left().IsLoad() && 650 if (selector->CanCover(m.node(), m.left().node()) && m.left().IsLoad() &&
661 m.right().Is(32)) { 651 m.right().Is(32)) {
662 // Just load and sign-extend the interesting 4 bytes instead. This happens, 652 // Just load and sign-extend the interesting 4 bytes instead. This happens,
663 // for example, when we're loading and untagging SMIs. 653 // for example, when we're loading and untagging SMIs.
664 BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(), 654 BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(),
665 AddressOption::kAllowAll); 655 AddressOption::kAllowAll);
666 if (mleft.matches() && (mleft.displacement() == nullptr || 656 if (mleft.matches() && (mleft.displacement() == nullptr ||
667 g.CanBeImmediate(mleft.displacement()))) { 657 g.CanBeImmediate(mleft.displacement()))) {
668 size_t input_count = 0; 658 size_t input_count = 0;
669 InstructionOperand inputs[3]; 659 InstructionOperand inputs[3];
670 AddressingMode mode = g.GetEffectiveAddressMemoryOperand( 660 AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 case kMode_MR4I: 698 case kMode_MR4I:
709 case kMode_MR8I: 699 case kMode_MR8I:
710 case kMode_M1I: 700 case kMode_M1I:
711 case kMode_M2I: 701 case kMode_M2I:
712 case kMode_M4I: 702 case kMode_M4I:
713 case kMode_M8I: 703 case kMode_M8I:
714 UNREACHABLE(); 704 UNREACHABLE();
715 } 705 }
716 inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4); 706 inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4);
717 } else { 707 } else {
718 ImmediateOperand* op = ImmediateOperand::cast(&inputs[input_count - 1]); 708 int32_t displacement = g.GetImmediateIntegerValue(mleft.displacement());
719 int32_t displacement = sequence()->GetImmediate(op).ToInt32(); 709 inputs[input_count - 1] =
720 *op = ImmediateOperand(ImmediateOperand::INLINE, displacement + 4); 710 ImmediateOperand(ImmediateOperand::INLINE, displacement + 4);
721 } 711 }
722 InstructionOperand outputs[] = {g.DefineAsRegister(node)}; 712 InstructionOperand outputs[] = {g.DefineAsRegister(node)};
723 InstructionCode code = kX64Movsxlq | AddressingModeField::encode(mode); 713 InstructionCode code = opcode | AddressingModeField::encode(mode);
724 Emit(code, 1, outputs, input_count, inputs); 714 selector->Emit(code, 1, outputs, input_count, inputs);
715 return true;
716 }
717 }
718 return false;
719 }
720 } // namespace
721
722 void InstructionSelector::VisitWord64Shr(Node* node) {
723 if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movl)) return;
724 VisitWord64Shift(this, node, kX64Shr);
725 }
726
727 void InstructionSelector::VisitWord32Sar(Node* node) {
728 X64OperandGenerator g(this);
729 Int32BinopMatcher m(node);
730 if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
731 Int32BinopMatcher mleft(m.left().node());
732 if (mleft.right().Is(16) && m.right().Is(16)) {
733 Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
734 return;
735 } else if (mleft.right().Is(24) && m.right().Is(24)) {
736 Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
725 return; 737 return;
726 } 738 }
727 } 739 }
740 VisitWord32Shift(this, node, kX64Sar32);
741 }
742
743 void InstructionSelector::VisitWord64Sar(Node* node) {
744 if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movsxlq)) return;
728 VisitWord64Shift(this, node, kX64Sar); 745 VisitWord64Shift(this, node, kX64Sar);
729 } 746 }
730 747
731 748
732 void InstructionSelector::VisitWord32Ror(Node* node) { 749 void InstructionSelector::VisitWord32Ror(Node* node) {
733 VisitWord32Shift(this, node, kX64Ror32); 750 VisitWord32Shift(this, node, kX64Ror32);
734 } 751 }
735 752
736 753
737 void InstructionSelector::VisitWord64Ror(Node* node) { 754 void InstructionSelector::VisitWord64Ror(Node* node) {
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 1268
1252 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { 1269 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1253 X64OperandGenerator g(this); 1270 X64OperandGenerator g(this);
1254 Node* value = node->InputAt(0); 1271 Node* value = node->InputAt(0);
1255 if (CanCover(node, value)) { 1272 if (CanCover(node, value)) {
1256 switch (value->opcode()) { 1273 switch (value->opcode()) {
1257 case IrOpcode::kWord64Sar: 1274 case IrOpcode::kWord64Sar:
1258 case IrOpcode::kWord64Shr: { 1275 case IrOpcode::kWord64Shr: {
1259 Int64BinopMatcher m(value); 1276 Int64BinopMatcher m(value);
1260 if (m.right().Is(32)) { 1277 if (m.right().Is(32)) {
1278 if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) {
1279 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
1280 return;
1281 }
1261 Emit(kX64Shr, g.DefineSameAsFirst(node), 1282 Emit(kX64Shr, g.DefineSameAsFirst(node),
1262 g.UseRegister(m.left().node()), g.TempImmediate(32)); 1283 g.UseRegister(m.left().node()), g.TempImmediate(32));
1263 return; 1284 return;
1264 } 1285 }
1265 break; 1286 break;
1266 } 1287 }
1267 default: 1288 default:
1268 break; 1289 break;
1269 } 1290 }
1270 } 1291 }
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 // static 2232 // static
2212 MachineOperatorBuilder::AlignmentRequirements 2233 MachineOperatorBuilder::AlignmentRequirements
2213 InstructionSelector::AlignmentRequirements() { 2234 InstructionSelector::AlignmentRequirements() {
2214 return MachineOperatorBuilder::AlignmentRequirements:: 2235 return MachineOperatorBuilder::AlignmentRequirements::
2215 FullUnalignedAccessSupport(); 2236 FullUnalignedAccessSupport();
2216 } 2237 }
2217 2238
2218 } // namespace compiler 2239 } // namespace compiler
2219 } // namespace internal 2240 } // namespace internal
2220 } // namespace v8 2241 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.cc ('k') | test/unittests/compiler/x64/instruction-selector-x64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698