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 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 811 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
812 return; | 812 return; |
813 } | 813 } |
814 default: | 814 default: |
815 break; | 815 break; |
816 } | 816 } |
817 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); | 817 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); |
818 } | 818 } |
819 | 819 |
820 | 820 |
821 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { | |
822 X64OperandGenerator g(this); | |
823 Emit(kSSEFloat64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | |
824 } | |
825 | |
826 | |
827 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | |
828 X64OperandGenerator g(this); | |
829 Node* value = node->InputAt(0); | |
830 if (CanCover(node, value)) { | |
831 switch (value->opcode()) { | |
832 case IrOpcode::kWord64Sar: | |
833 case IrOpcode::kWord64Shr: { | |
834 Int64BinopMatcher m(value); | |
835 if (m.right().Is(32)) { | |
836 Emit(kX64Shr, g.DefineSameAsFirst(node), | |
837 g.UseRegister(m.left().node()), g.TempImmediate(32)); | |
838 return; | |
839 } | |
840 break; | |
841 } | |
842 default: | |
843 break; | |
844 } | |
845 } | |
846 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); | |
847 } | |
848 | |
849 | |
850 namespace { | 821 namespace { |
851 | 822 |
| 823 void VisitRO(InstructionSelector* selector, Node* node, |
| 824 InstructionCode opcode) { |
| 825 X64OperandGenerator g(selector); |
| 826 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 827 } |
| 828 |
| 829 |
| 830 void VisitRR(InstructionSelector* selector, Node* node, |
| 831 InstructionCode opcode) { |
| 832 X64OperandGenerator g(selector); |
| 833 selector->Emit(opcode, g.DefineAsRegister(node), |
| 834 g.UseRegister(node->InputAt(0))); |
| 835 } |
| 836 |
| 837 |
852 void VisitFloatBinop(InstructionSelector* selector, Node* node, | 838 void VisitFloatBinop(InstructionSelector* selector, Node* node, |
853 ArchOpcode avx_opcode, ArchOpcode sse_opcode) { | 839 ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
854 X64OperandGenerator g(selector); | 840 X64OperandGenerator g(selector); |
855 InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); | 841 InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); |
856 InstructionOperand operand1 = g.Use(node->InputAt(1)); | 842 InstructionOperand operand1 = g.Use(node->InputAt(1)); |
857 if (selector->IsSupported(AVX)) { | 843 if (selector->IsSupported(AVX)) { |
858 selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); | 844 selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); |
859 } else { | 845 } else { |
860 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); | 846 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); |
861 } | 847 } |
862 } | 848 } |
863 | 849 |
864 | 850 |
865 void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input, | 851 void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input, |
866 ArchOpcode avx_opcode, ArchOpcode sse_opcode) { | 852 ArchOpcode avx_opcode, ArchOpcode sse_opcode) { |
867 X64OperandGenerator g(selector); | 853 X64OperandGenerator g(selector); |
868 if (selector->IsSupported(AVX)) { | 854 if (selector->IsSupported(AVX)) { |
869 selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); | 855 selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); |
870 } else { | 856 } else { |
871 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); | 857 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); |
872 } | 858 } |
873 } | 859 } |
874 | 860 |
| 861 } // namespace |
875 | 862 |
876 } // namespace | 863 |
| 864 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
| 865 VisitRO(this, node, kSSEFloat64ToFloat32); |
| 866 } |
| 867 |
| 868 |
| 869 void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) { |
| 870 switch (TruncationModeOf(node->op())) { |
| 871 case TruncationMode::kJavaScript: |
| 872 return VisitRR(this, node, kArchTruncateDoubleToI); |
| 873 case TruncationMode::kRoundToZero: |
| 874 return VisitRO(this, node, kSSEFloat64ToInt32); |
| 875 } |
| 876 UNREACHABLE(); |
| 877 } |
| 878 |
| 879 |
| 880 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
| 881 X64OperandGenerator g(this); |
| 882 Node* value = node->InputAt(0); |
| 883 if (CanCover(node, value)) { |
| 884 switch (value->opcode()) { |
| 885 case IrOpcode::kWord64Sar: |
| 886 case IrOpcode::kWord64Shr: { |
| 887 Int64BinopMatcher m(value); |
| 888 if (m.right().Is(32)) { |
| 889 Emit(kX64Shr, g.DefineSameAsFirst(node), |
| 890 g.UseRegister(m.left().node()), g.TempImmediate(32)); |
| 891 return; |
| 892 } |
| 893 break; |
| 894 } |
| 895 default: |
| 896 break; |
| 897 } |
| 898 } |
| 899 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); |
| 900 } |
877 | 901 |
878 | 902 |
879 void InstructionSelector::VisitFloat32Add(Node* node) { | 903 void InstructionSelector::VisitFloat32Add(Node* node) { |
880 VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add); | 904 VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add); |
881 } | 905 } |
882 | 906 |
883 | 907 |
884 void InstructionSelector::VisitFloat32Sub(Node* node) { | 908 void InstructionSelector::VisitFloat32Sub(Node* node) { |
885 X64OperandGenerator g(this); | 909 X64OperandGenerator g(this); |
886 Float32BinopMatcher m(node); | 910 Float32BinopMatcher m(node); |
(...skipping 20 matching lines...) Expand all Loading... |
907 VisitFloatBinop(this, node, kAVXFloat32Max, kSSEFloat32Max); | 931 VisitFloatBinop(this, node, kAVXFloat32Max, kSSEFloat32Max); |
908 } | 932 } |
909 | 933 |
910 | 934 |
911 void InstructionSelector::VisitFloat32Min(Node* node) { | 935 void InstructionSelector::VisitFloat32Min(Node* node) { |
912 VisitFloatBinop(this, node, kAVXFloat32Min, kSSEFloat32Min); | 936 VisitFloatBinop(this, node, kAVXFloat32Min, kSSEFloat32Min); |
913 } | 937 } |
914 | 938 |
915 | 939 |
916 void InstructionSelector::VisitFloat32Abs(Node* node) { | 940 void InstructionSelector::VisitFloat32Abs(Node* node) { |
917 X64OperandGenerator g(this); | |
918 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); | 941 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); |
919 } | 942 } |
920 | 943 |
921 | 944 |
922 void InstructionSelector::VisitFloat32Sqrt(Node* node) { | 945 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
923 X64OperandGenerator g(this); | 946 VisitRO(this, node, kSSEFloat32Sqrt); |
924 Emit(kSSEFloat32Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | |
925 } | 947 } |
926 | 948 |
927 | 949 |
928 void InstructionSelector::VisitFloat64Add(Node* node) { | 950 void InstructionSelector::VisitFloat64Add(Node* node) { |
929 VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add); | 951 VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add); |
930 } | 952 } |
931 | 953 |
932 | 954 |
933 void InstructionSelector::VisitFloat64Sub(Node* node) { | 955 void InstructionSelector::VisitFloat64Sub(Node* node) { |
934 X64OperandGenerator g(this); | 956 X64OperandGenerator g(this); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 VisitFloatBinop(this, node, kAVXFloat64Max, kSSEFloat64Max); | 999 VisitFloatBinop(this, node, kAVXFloat64Max, kSSEFloat64Max); |
978 } | 1000 } |
979 | 1001 |
980 | 1002 |
981 void InstructionSelector::VisitFloat64Min(Node* node) { | 1003 void InstructionSelector::VisitFloat64Min(Node* node) { |
982 VisitFloatBinop(this, node, kAVXFloat64Min, kSSEFloat64Min); | 1004 VisitFloatBinop(this, node, kAVXFloat64Min, kSSEFloat64Min); |
983 } | 1005 } |
984 | 1006 |
985 | 1007 |
986 void InstructionSelector::VisitFloat64Abs(Node* node) { | 1008 void InstructionSelector::VisitFloat64Abs(Node* node) { |
987 X64OperandGenerator g(this); | |
988 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); | 1009 VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); |
989 } | 1010 } |
990 | 1011 |
991 | 1012 |
992 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 1013 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
993 X64OperandGenerator g(this); | 1014 VisitRO(this, node, kSSEFloat64Sqrt); |
994 Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | |
995 } | 1015 } |
996 | 1016 |
997 | 1017 |
998 namespace { | |
999 | |
1000 void VisitRRFloat64(InstructionSelector* selector, InstructionCode opcode, | |
1001 Node* node) { | |
1002 X64OperandGenerator g(selector); | |
1003 selector->Emit(opcode, g.DefineAsRegister(node), | |
1004 g.UseRegister(node->InputAt(0))); | |
1005 } | |
1006 | |
1007 } // namespace | |
1008 | |
1009 | |
1010 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 1018 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
1011 VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundDown), node); | 1019 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown)); |
1012 } | 1020 } |
1013 | 1021 |
1014 | 1022 |
1015 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1023 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
1016 VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundToZero), | 1024 VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
1017 node); | |
1018 } | 1025 } |
1019 | 1026 |
1020 | 1027 |
1021 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1028 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
1022 UNREACHABLE(); | 1029 UNREACHABLE(); |
1023 } | 1030 } |
1024 | 1031 |
1025 | 1032 |
1026 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 1033 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
1027 X64OperandGenerator g(this); | 1034 X64OperandGenerator g(this); |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 if (CpuFeatures::IsSupported(SSE4_1)) { | 1673 if (CpuFeatures::IsSupported(SSE4_1)) { |
1667 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1674 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1668 MachineOperatorBuilder::kFloat64RoundTruncate; | 1675 MachineOperatorBuilder::kFloat64RoundTruncate; |
1669 } | 1676 } |
1670 return flags; | 1677 return flags; |
1671 } | 1678 } |
1672 | 1679 |
1673 } // namespace compiler | 1680 } // namespace compiler |
1674 } // namespace internal | 1681 } // namespace internal |
1675 } // namespace v8 | 1682 } // namespace v8 |
OLD | NEW |