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 <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 Loading... | |
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 Loading... | |
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 static bool TryMatchLoadWord64AndShiftRight(InstructionSelector* selector, |
Jarin
2016/08/18 10:38:16
anonymous namespace?
epertoso
2016/08/18 10:51:11
Done.
| |
635 void InstructionSelector::VisitWord64Shr(Node* node) { | 644 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 Loading... | |
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 | |
721 void InstructionSelector::VisitWord64Shr(Node* node) { | |
722 if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movl)) return; | |
723 VisitWord64Shift(this, node, kX64Shr); | |
724 } | |
725 | |
726 void InstructionSelector::VisitWord32Sar(Node* node) { | |
727 X64OperandGenerator g(this); | |
728 Int32BinopMatcher m(node); | |
729 if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) { | |
730 Int32BinopMatcher mleft(m.left().node()); | |
731 if (mleft.right().Is(16) && m.right().Is(16)) { | |
732 Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node())); | |
733 return; | |
734 } else if (mleft.right().Is(24) && m.right().Is(24)) { | |
735 Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node())); | |
725 return; | 736 return; |
726 } | 737 } |
727 } | 738 } |
739 VisitWord32Shift(this, node, kX64Sar32); | |
740 } | |
741 | |
742 void InstructionSelector::VisitWord64Sar(Node* node) { | |
743 if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movsxlq)) return; | |
728 VisitWord64Shift(this, node, kX64Sar); | 744 VisitWord64Shift(this, node, kX64Sar); |
729 } | 745 } |
730 | 746 |
731 | 747 |
732 void InstructionSelector::VisitWord32Ror(Node* node) { | 748 void InstructionSelector::VisitWord32Ror(Node* node) { |
733 VisitWord32Shift(this, node, kX64Ror32); | 749 VisitWord32Shift(this, node, kX64Ror32); |
734 } | 750 } |
735 | 751 |
736 | 752 |
737 void InstructionSelector::VisitWord64Ror(Node* node) { | 753 void InstructionSelector::VisitWord64Ror(Node* node) { |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1251 | 1267 |
1252 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 1268 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
1253 X64OperandGenerator g(this); | 1269 X64OperandGenerator g(this); |
1254 Node* value = node->InputAt(0); | 1270 Node* value = node->InputAt(0); |
1255 if (CanCover(node, value)) { | 1271 if (CanCover(node, value)) { |
1256 switch (value->opcode()) { | 1272 switch (value->opcode()) { |
1257 case IrOpcode::kWord64Sar: | 1273 case IrOpcode::kWord64Sar: |
1258 case IrOpcode::kWord64Shr: { | 1274 case IrOpcode::kWord64Shr: { |
1259 Int64BinopMatcher m(value); | 1275 Int64BinopMatcher m(value); |
1260 if (m.right().Is(32)) { | 1276 if (m.right().Is(32)) { |
1277 if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) { | |
1278 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | |
1279 return; | |
1280 } | |
1261 Emit(kX64Shr, g.DefineSameAsFirst(node), | 1281 Emit(kX64Shr, g.DefineSameAsFirst(node), |
1262 g.UseRegister(m.left().node()), g.TempImmediate(32)); | 1282 g.UseRegister(m.left().node()), g.TempImmediate(32)); |
1263 return; | 1283 return; |
1264 } | 1284 } |
1265 break; | 1285 break; |
1266 } | 1286 } |
1267 default: | 1287 default: |
1268 break; | 1288 break; |
1269 } | 1289 } |
1270 } | 1290 } |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2211 // static | 2231 // static |
2212 MachineOperatorBuilder::AlignmentRequirements | 2232 MachineOperatorBuilder::AlignmentRequirements |
2213 InstructionSelector::AlignmentRequirements() { | 2233 InstructionSelector::AlignmentRequirements() { |
2214 return MachineOperatorBuilder::AlignmentRequirements:: | 2234 return MachineOperatorBuilder::AlignmentRequirements:: |
2215 FullUnalignedAccessSupport(); | 2235 FullUnalignedAccessSupport(); |
2216 } | 2236 } |
2217 | 2237 |
2218 } // namespace compiler | 2238 } // namespace compiler |
2219 } // namespace internal | 2239 } // namespace internal |
2220 } // namespace v8 | 2240 } // namespace v8 |
OLD | NEW |