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 "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 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 return kMode_MR1; | 117 return kMode_MR1; |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 bool CanBeBetterLeftOperand(Node* node) const { | 121 bool CanBeBetterLeftOperand(Node* node) const { |
122 return !selector()->IsLive(node); | 122 return !selector()->IsLive(node); |
123 } | 123 } |
124 }; | 124 }; |
125 | 125 |
126 | 126 |
127 static void VisitRRFloat64(InstructionSelector* selector, | 127 namespace { |
128 InstructionCode opcode, Node* node) { | 128 |
| 129 void VisitROFloat(InstructionSelector* selector, Node* node, |
| 130 ArchOpcode opcode) { |
| 131 IA32OperandGenerator g(selector); |
| 132 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 133 } |
| 134 |
| 135 |
| 136 void VisitRRFloat(InstructionSelector* selector, Node* node, |
| 137 InstructionCode opcode) { |
129 IA32OperandGenerator g(selector); | 138 IA32OperandGenerator g(selector); |
130 selector->Emit(opcode, g.DefineAsRegister(node), | 139 selector->Emit(opcode, g.DefineAsRegister(node), |
131 g.UseRegister(node->InputAt(0))); | 140 g.UseRegister(node->InputAt(0))); |
132 } | 141 } |
133 | 142 |
134 | 143 |
| 144 void VisitRROFloat(InstructionSelector* selector, Node* node, |
| 145 ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
| 146 IA32OperandGenerator g(selector); |
| 147 InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); |
| 148 InstructionOperand operand1 = g.Use(node->InputAt(1)); |
| 149 if (selector->IsSupported(AVX)) { |
| 150 selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); |
| 151 } else { |
| 152 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); |
| 153 } |
| 154 } |
| 155 |
| 156 } // namespace |
| 157 |
| 158 |
135 void InstructionSelector::VisitLoad(Node* node) { | 159 void InstructionSelector::VisitLoad(Node* node) { |
136 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 160 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
137 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 161 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
138 | 162 |
139 ArchOpcode opcode; | 163 ArchOpcode opcode; |
140 switch (rep) { | 164 switch (rep) { |
141 case kRepFloat32: | 165 case kRepFloat32: |
142 opcode = kIA32Movss; | 166 opcode = kIA32Movss; |
143 break; | 167 break; |
144 case kRepFloat64: | 168 case kRepFloat64: |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 } | 623 } |
600 | 624 |
601 | 625 |
602 void InstructionSelector::VisitUint32Mod(Node* node) { | 626 void InstructionSelector::VisitUint32Mod(Node* node) { |
603 VisitMod(this, node, kIA32Udiv); | 627 VisitMod(this, node, kIA32Udiv); |
604 } | 628 } |
605 | 629 |
606 | 630 |
607 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 631 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
608 IA32OperandGenerator g(this); | 632 IA32OperandGenerator g(this); |
609 Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 633 Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
610 } | 634 } |
611 | 635 |
612 | 636 |
613 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 637 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
614 IA32OperandGenerator g(this); | 638 IA32OperandGenerator g(this); |
615 Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 639 Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
616 } | 640 } |
617 | 641 |
618 | 642 |
619 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 643 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
620 IA32OperandGenerator g(this); | 644 IA32OperandGenerator g(this); |
621 Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 645 Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
622 } | 646 } |
623 | 647 |
624 | 648 |
625 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 649 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
626 IA32OperandGenerator g(this); | 650 IA32OperandGenerator g(this); |
627 Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 651 Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
628 } | 652 } |
629 | 653 |
630 | 654 |
631 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 655 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
632 IA32OperandGenerator g(this); | 656 IA32OperandGenerator g(this); |
633 Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 657 Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
634 } | 658 } |
635 | 659 |
636 | 660 |
637 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { | 661 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
638 IA32OperandGenerator g(this); | 662 IA32OperandGenerator g(this); |
639 Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 663 Emit(kSSEFloat64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 664 } |
| 665 |
| 666 |
| 667 void InstructionSelector::VisitFloat32Add(Node* node) { |
| 668 VisitRROFloat(this, node, kAVXFloat32Add, kSSEFloat32Add); |
640 } | 669 } |
641 | 670 |
642 | 671 |
643 void InstructionSelector::VisitFloat64Add(Node* node) { | 672 void InstructionSelector::VisitFloat64Add(Node* node) { |
644 IA32OperandGenerator g(this); | 673 VisitRROFloat(this, node, kAVXFloat64Add, kSSEFloat64Add); |
645 if (IsSupported(AVX)) { | |
646 Emit(kAVXFloat64Add, g.DefineAsRegister(node), | |
647 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
648 } else { | |
649 Emit(kSSEFloat64Add, g.DefineSameAsFirst(node), | |
650 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
651 } | |
652 } | 674 } |
653 | 675 |
654 | 676 |
| 677 void InstructionSelector::VisitFloat32Sub(Node* node) { |
| 678 VisitRROFloat(this, node, kAVXFloat32Sub, kSSEFloat32Sub); |
| 679 } |
| 680 |
| 681 |
655 void InstructionSelector::VisitFloat64Sub(Node* node) { | 682 void InstructionSelector::VisitFloat64Sub(Node* node) { |
656 IA32OperandGenerator g(this); | 683 IA32OperandGenerator g(this); |
657 Float64BinopMatcher m(node); | 684 Float64BinopMatcher m(node); |
658 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && | 685 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && |
659 CanCover(m.node(), m.right().node())) { | 686 CanCover(m.node(), m.right().node())) { |
660 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && | 687 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
661 CanCover(m.right().node(), m.right().InputAt(0))) { | 688 CanCover(m.right().node(), m.right().InputAt(0))) { |
662 Float64BinopMatcher mright0(m.right().InputAt(0)); | 689 Float64BinopMatcher mright0(m.right().InputAt(0)); |
663 if (mright0.left().IsMinusZero()) { | 690 if (mright0.left().IsMinusZero()) { |
664 Emit(kSSEFloat64Round | MiscField::encode(kRoundUp), | 691 Emit(kSSEFloat64Round | MiscField::encode(kRoundUp), |
665 g.DefineAsRegister(node), g.UseRegister(mright0.right().node())); | 692 g.DefineAsRegister(node), g.UseRegister(mright0.right().node())); |
666 return; | 693 return; |
667 } | 694 } |
668 } | 695 } |
669 } | 696 } |
670 if (IsSupported(AVX)) { | 697 VisitRROFloat(this, node, kAVXFloat64Sub, kSSEFloat64Sub); |
671 Emit(kAVXFloat64Sub, g.DefineAsRegister(node), | 698 } |
672 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | 699 |
673 } else { | 700 |
674 Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node), | 701 void InstructionSelector::VisitFloat32Mul(Node* node) { |
675 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | 702 VisitRROFloat(this, node, kAVXFloat32Mul, kSSEFloat32Mul); |
676 } | |
677 } | 703 } |
678 | 704 |
679 | 705 |
680 void InstructionSelector::VisitFloat64Mul(Node* node) { | 706 void InstructionSelector::VisitFloat64Mul(Node* node) { |
681 IA32OperandGenerator g(this); | 707 VisitRROFloat(this, node, kAVXFloat64Mul, kSSEFloat64Mul); |
682 if (IsSupported(AVX)) { | 708 } |
683 Emit(kAVXFloat64Mul, g.DefineAsRegister(node), | 709 |
684 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | 710 |
685 } else { | 711 void InstructionSelector::VisitFloat32Div(Node* node) { |
686 Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node), | 712 VisitRROFloat(this, node, kAVXFloat32Div, kSSEFloat32Div); |
687 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
688 } | |
689 } | 713 } |
690 | 714 |
691 | 715 |
692 void InstructionSelector::VisitFloat64Div(Node* node) { | 716 void InstructionSelector::VisitFloat64Div(Node* node) { |
693 IA32OperandGenerator g(this); | 717 VisitRROFloat(this, node, kAVXFloat64Div, kSSEFloat64Div); |
694 if (IsSupported(AVX)) { | |
695 Emit(kAVXFloat64Div, g.DefineAsRegister(node), | |
696 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
697 } else { | |
698 Emit(kSSEFloat64Div, g.DefineSameAsFirst(node), | |
699 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
700 } | |
701 } | 718 } |
702 | 719 |
703 | 720 |
704 void InstructionSelector::VisitFloat64Mod(Node* node) { | 721 void InstructionSelector::VisitFloat64Mod(Node* node) { |
705 IA32OperandGenerator g(this); | 722 IA32OperandGenerator g(this); |
706 InstructionOperand temps[] = {g.TempRegister(eax)}; | 723 InstructionOperand temps[] = {g.TempRegister(eax)}; |
707 Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), | 724 Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), |
708 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, | 725 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, |
709 temps); | 726 temps); |
710 } | 727 } |
711 | 728 |
712 | 729 |
| 730 void InstructionSelector::VisitFloat32Max(Node* node) { |
| 731 VisitRROFloat(this, node, kAVXFloat32Max, kSSEFloat32Max); |
| 732 } |
| 733 |
| 734 |
713 void InstructionSelector::VisitFloat64Max(Node* node) { | 735 void InstructionSelector::VisitFloat64Max(Node* node) { |
714 IA32OperandGenerator g(this); | 736 VisitRROFloat(this, node, kAVXFloat64Max, kSSEFloat64Max); |
715 if (IsSupported(AVX)) { | 737 } |
716 Emit(kAVXFloat64Max, g.DefineAsRegister(node), | 738 |
717 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | 739 |
718 } else { | 740 void InstructionSelector::VisitFloat32Min(Node* node) { |
719 Emit(kSSEFloat64Max, g.DefineSameAsFirst(node), | 741 VisitRROFloat(this, node, kAVXFloat32Min, kSSEFloat32Min); |
720 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
721 } | |
722 } | 742 } |
723 | 743 |
724 | 744 |
725 void InstructionSelector::VisitFloat64Min(Node* node) { | 745 void InstructionSelector::VisitFloat64Min(Node* node) { |
726 IA32OperandGenerator g(this); | 746 VisitRROFloat(this, node, kAVXFloat64Min, kSSEFloat64Min); |
727 if (IsSupported(AVX)) { | 747 } |
728 Emit(kAVXFloat64Min, g.DefineAsRegister(node), | 748 |
729 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | 749 |
730 } else { | 750 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
731 Emit(kSSEFloat64Min, g.DefineSameAsFirst(node), | 751 VisitROFloat(this, node, kSSEFloat32Sqrt); |
732 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); | |
733 } | |
734 } | 752 } |
735 | 753 |
736 | 754 |
737 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 755 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
738 IA32OperandGenerator g(this); | 756 VisitROFloat(this, node, kSSEFloat64Sqrt); |
739 Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | |
740 } | 757 } |
741 | 758 |
742 | 759 |
743 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 760 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
744 VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundDown), node); | 761 VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown)); |
745 } | 762 } |
746 | 763 |
747 | 764 |
748 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 765 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
749 VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundToZero), | 766 VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
750 node); | |
751 } | 767 } |
752 | 768 |
753 | 769 |
754 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 770 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
755 UNREACHABLE(); | 771 UNREACHABLE(); |
756 } | 772 } |
757 | 773 |
758 | 774 |
759 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 775 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
760 IA32OperandGenerator g(this); | 776 IA32OperandGenerator g(this); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 Node* left, Node* right, FlagsContinuation* cont, | 855 Node* left, Node* right, FlagsContinuation* cont, |
840 bool commutative) { | 856 bool commutative) { |
841 IA32OperandGenerator g(selector); | 857 IA32OperandGenerator g(selector); |
842 if (commutative && g.CanBeBetterLeftOperand(right)) { | 858 if (commutative && g.CanBeBetterLeftOperand(right)) { |
843 std::swap(left, right); | 859 std::swap(left, right); |
844 } | 860 } |
845 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 861 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
846 } | 862 } |
847 | 863 |
848 | 864 |
| 865 // Shared routine for multiple float32 compare operations (inputs commuted). |
| 866 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 867 FlagsContinuation* cont) { |
| 868 Node* const left = node->InputAt(0); |
| 869 Node* const right = node->InputAt(1); |
| 870 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); |
| 871 } |
| 872 |
| 873 |
849 // Shared routine for multiple float64 compare operations (inputs commuted). | 874 // Shared routine for multiple float64 compare operations (inputs commuted). |
850 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 875 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
851 FlagsContinuation* cont) { | 876 FlagsContinuation* cont) { |
852 Node* const left = node->InputAt(0); | 877 Node* const left = node->InputAt(0); |
853 Node* const right = node->InputAt(1); | 878 Node* const right = node->InputAt(1); |
854 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); | 879 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); |
855 } | 880 } |
856 | 881 |
857 | 882 |
858 // Shared routine for multiple word compare operations. | 883 // Shared routine for multiple word compare operations. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 return VisitWordCompare(selector, value, cont); | 950 return VisitWordCompare(selector, value, cont); |
926 case IrOpcode::kInt32LessThanOrEqual: | 951 case IrOpcode::kInt32LessThanOrEqual: |
927 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 952 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
928 return VisitWordCompare(selector, value, cont); | 953 return VisitWordCompare(selector, value, cont); |
929 case IrOpcode::kUint32LessThan: | 954 case IrOpcode::kUint32LessThan: |
930 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 955 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
931 return VisitWordCompare(selector, value, cont); | 956 return VisitWordCompare(selector, value, cont); |
932 case IrOpcode::kUint32LessThanOrEqual: | 957 case IrOpcode::kUint32LessThanOrEqual: |
933 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 958 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
934 return VisitWordCompare(selector, value, cont); | 959 return VisitWordCompare(selector, value, cont); |
| 960 case IrOpcode::kFloat32Equal: |
| 961 cont->OverwriteAndNegateIfEqual(kUnorderedEqual); |
| 962 return VisitFloat32Compare(selector, value, cont); |
| 963 case IrOpcode::kFloat32LessThan: |
| 964 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); |
| 965 return VisitFloat32Compare(selector, value, cont); |
| 966 case IrOpcode::kFloat32LessThanOrEqual: |
| 967 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); |
| 968 return VisitFloat32Compare(selector, value, cont); |
935 case IrOpcode::kFloat64Equal: | 969 case IrOpcode::kFloat64Equal: |
936 cont->OverwriteAndNegateIfEqual(kUnorderedEqual); | 970 cont->OverwriteAndNegateIfEqual(kUnorderedEqual); |
937 return VisitFloat64Compare(selector, value, cont); | 971 return VisitFloat64Compare(selector, value, cont); |
938 case IrOpcode::kFloat64LessThan: | 972 case IrOpcode::kFloat64LessThan: |
939 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); | 973 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); |
940 return VisitFloat64Compare(selector, value, cont); | 974 return VisitFloat64Compare(selector, value, cont); |
941 case IrOpcode::kFloat64LessThanOrEqual: | 975 case IrOpcode::kFloat64LessThanOrEqual: |
942 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); | 976 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); |
943 return VisitFloat64Compare(selector, value, cont); | 977 return VisitFloat64Compare(selector, value, cont); |
944 case IrOpcode::kProjection: | 978 case IrOpcode::kProjection: |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 1100 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
1067 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1101 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1068 FlagsContinuation cont(kOverflow, ovf); | 1102 FlagsContinuation cont(kOverflow, ovf); |
1069 return VisitBinop(this, node, kIA32Sub, &cont); | 1103 return VisitBinop(this, node, kIA32Sub, &cont); |
1070 } | 1104 } |
1071 FlagsContinuation cont; | 1105 FlagsContinuation cont; |
1072 VisitBinop(this, node, kIA32Sub, &cont); | 1106 VisitBinop(this, node, kIA32Sub, &cont); |
1073 } | 1107 } |
1074 | 1108 |
1075 | 1109 |
| 1110 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1111 FlagsContinuation cont(kUnorderedEqual, node); |
| 1112 VisitFloat32Compare(this, node, &cont); |
| 1113 } |
| 1114 |
| 1115 |
| 1116 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1117 FlagsContinuation cont(kUnsignedGreaterThan, node); |
| 1118 VisitFloat32Compare(this, node, &cont); |
| 1119 } |
| 1120 |
| 1121 |
| 1122 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1123 FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); |
| 1124 VisitFloat32Compare(this, node, &cont); |
| 1125 } |
| 1126 |
| 1127 |
1076 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1128 void InstructionSelector::VisitFloat64Equal(Node* node) { |
1077 FlagsContinuation cont(kUnorderedEqual, node); | 1129 FlagsContinuation cont(kUnorderedEqual, node); |
1078 VisitFloat64Compare(this, node, &cont); | 1130 VisitFloat64Compare(this, node, &cont); |
1079 } | 1131 } |
1080 | 1132 |
1081 | 1133 |
1082 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1134 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
1083 FlagsContinuation cont(kUnsignedGreaterThan, node); | 1135 FlagsContinuation cont(kUnsignedGreaterThan, node); |
1084 VisitFloat64Compare(this, node, &cont); | 1136 VisitFloat64Compare(this, node, &cont); |
1085 } | 1137 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 Node* right = node->InputAt(1); | 1177 Node* right = node->InputAt(1); |
1126 Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), | 1178 Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), |
1127 g.UseRegister(left), g.Use(right)); | 1179 g.UseRegister(left), g.Use(right)); |
1128 } | 1180 } |
1129 | 1181 |
1130 | 1182 |
1131 // static | 1183 // static |
1132 MachineOperatorBuilder::Flags | 1184 MachineOperatorBuilder::Flags |
1133 InstructionSelector::SupportedMachineOperatorFlags() { | 1185 InstructionSelector::SupportedMachineOperatorFlags() { |
1134 MachineOperatorBuilder::Flags flags = | 1186 MachineOperatorBuilder::Flags flags = |
| 1187 MachineOperatorBuilder::kFloat32Max | |
| 1188 MachineOperatorBuilder::kFloat32Min | |
1135 MachineOperatorBuilder::kFloat64Max | | 1189 MachineOperatorBuilder::kFloat64Max | |
1136 MachineOperatorBuilder::kFloat64Min | | 1190 MachineOperatorBuilder::kFloat64Min | |
1137 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1191 MachineOperatorBuilder::kWord32ShiftIsSafe; |
1138 if (CpuFeatures::IsSupported(SSE4_1)) { | 1192 if (CpuFeatures::IsSupported(SSE4_1)) { |
1139 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1193 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1140 MachineOperatorBuilder::kFloat64RoundTruncate; | 1194 MachineOperatorBuilder::kFloat64RoundTruncate; |
1141 } | 1195 } |
1142 return flags; | 1196 return flags; |
1143 } | 1197 } |
1144 | 1198 |
1145 } // namespace compiler | 1199 } // namespace compiler |
1146 } // namespace internal | 1200 } // namespace internal |
1147 } // namespace v8 | 1201 } // namespace v8 |
OLD | NEW |