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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 } | 984 } |
985 | 985 |
986 | 986 |
987 bool InstructionSelector::IsTailCallAddressImmediate() { return true; } | 987 bool InstructionSelector::IsTailCallAddressImmediate() { return true; } |
988 | 988 |
989 | 989 |
990 namespace { | 990 namespace { |
991 | 991 |
992 // Shared routine for multiple compare operations. | 992 // Shared routine for multiple compare operations. |
993 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 993 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 994 size_t left_operands_count, InstructionOperand* left_operands, |
| 995 InstructionOperand right, FlagsContinuation* cont) { |
| 996 DCHECK(left_operands_count > 0 && left_operands_count <= 4); |
| 997 IA32OperandGenerator g(selector); |
| 998 opcode = cont->Encode(opcode); |
| 999 int input_count = 0; |
| 1000 InstructionOperand inputs[6]; |
| 1001 do { |
| 1002 inputs[input_count] = left_operands[input_count]; |
| 1003 } while (++input_count < left_operands_count); |
| 1004 inputs[input_count++] = right; |
| 1005 |
| 1006 if (cont->IsBranch()) { |
| 1007 inputs[input_count++] = g.Label(cont->true_block()); |
| 1008 inputs[input_count++] = g.Label(cont->false_block()); |
| 1009 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1010 } else { |
| 1011 DCHECK(cont->IsSet()); |
| 1012 InstructionOperand output = g.DefineAsRegister(cont->result()); |
| 1013 selector->Emit(opcode, 1, &output, input_count, inputs); |
| 1014 } |
| 1015 } |
| 1016 |
| 1017 // Determines if {input} of {node} can be replaced by a memory operand. |
| 1018 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, |
| 1019 Node* node, Node* input) { |
| 1020 if (input->opcode() != IrOpcode::kLoad || !selector->CanCover(node, input) || |
| 1021 selector->GetEffectLevel(input) != selector->GetEffectLevel(node)) { |
| 1022 return false; |
| 1023 } |
| 1024 if (LoadRepresentationOf(input->op()).representation() == |
| 1025 MachineRepresentation::kWord32) { |
| 1026 return (opcode == kIA32Cmp || opcode == kIA32Test); |
| 1027 } |
| 1028 return false; |
| 1029 } |
| 1030 |
| 1031 // Shared routine for multiple compare operations. |
| 1032 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
994 InstructionOperand left, InstructionOperand right, | 1033 InstructionOperand left, InstructionOperand right, |
995 FlagsContinuation* cont) { | 1034 FlagsContinuation* cont) { |
996 IA32OperandGenerator g(selector); | 1035 VisitCompare(selector, opcode, 1, &left, right, cont); |
997 if (cont->IsBranch()) { | |
998 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | |
999 g.Label(cont->true_block()), g.Label(cont->false_block())); | |
1000 } else { | |
1001 DCHECK(cont->IsSet()); | |
1002 selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()), | |
1003 left, right); | |
1004 } | |
1005 } | 1036 } |
1006 | 1037 |
1007 | 1038 |
1008 // Shared routine for multiple compare operations. | 1039 // Shared routine for multiple compare operations. |
1009 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1040 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
1010 Node* left, Node* right, FlagsContinuation* cont, | 1041 Node* left, Node* right, FlagsContinuation* cont, |
1011 bool commutative) { | 1042 bool commutative, Node* node = nullptr) { |
1012 IA32OperandGenerator g(selector); | 1043 IA32OperandGenerator g(selector); |
1013 if (commutative && g.CanBeBetterLeftOperand(right)) { | 1044 if (commutative && g.CanBeBetterLeftOperand(right)) { |
1014 std::swap(left, right); | 1045 std::swap(left, right); |
1015 } | 1046 } |
1016 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); | 1047 if (node && CanUseMemoryOperand(selector, opcode, node, left)) { |
| 1048 size_t input_count = 0; |
| 1049 InstructionOperand inputs[4]; |
| 1050 AddressingMode addressing_mode = |
| 1051 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); |
| 1052 opcode |= AddressingModeField::encode(addressing_mode); |
| 1053 VisitCompare(selector, opcode, input_count, inputs, g.Use(right), cont); |
| 1054 } else { |
| 1055 VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); |
| 1056 } |
1017 } | 1057 } |
1018 | 1058 |
1019 | 1059 |
1020 // Shared routine for multiple float32 compare operations (inputs commuted). | 1060 // Shared routine for multiple float32 compare operations (inputs commuted). |
1021 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1061 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
1022 FlagsContinuation* cont) { | 1062 FlagsContinuation* cont) { |
1023 Node* const left = node->InputAt(0); | 1063 Node* const left = node->InputAt(0); |
1024 Node* const right = node->InputAt(1); | 1064 Node* const right = node->InputAt(1); |
1025 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); | 1065 VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false); |
1026 } | 1066 } |
1027 | 1067 |
1028 | 1068 |
1029 // Shared routine for multiple float64 compare operations (inputs commuted). | 1069 // Shared routine for multiple float64 compare operations (inputs commuted). |
1030 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1070 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
1031 FlagsContinuation* cont) { | 1071 FlagsContinuation* cont) { |
1032 Node* const left = node->InputAt(0); | 1072 Node* const left = node->InputAt(0); |
1033 Node* const right = node->InputAt(1); | 1073 Node* const right = node->InputAt(1); |
1034 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); | 1074 VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false); |
1035 } | 1075 } |
1036 | 1076 |
1037 | 1077 |
1038 // Shared routine for multiple word compare operations. | 1078 // Shared routine for multiple word compare operations. |
1039 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1079 void VisitWordCompare(InstructionSelector* selector, Node* node, |
1040 InstructionCode opcode, FlagsContinuation* cont) { | 1080 InstructionCode opcode, FlagsContinuation* cont) { |
1041 IA32OperandGenerator g(selector); | 1081 IA32OperandGenerator g(selector); |
1042 Node* const left = node->InputAt(0); | 1082 Node* left = node->InputAt(0); |
1043 Node* const right = node->InputAt(1); | 1083 Node* right = node->InputAt(1); |
1044 | 1084 |
1045 // Match immediates on left or right side of comparison. | 1085 if (!g.CanBeImmediate(right) && g.CanBeImmediate(left)) { |
| 1086 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1087 std::swap(left, right); |
| 1088 } |
| 1089 |
| 1090 // Match immediates on right side of comparison. |
1046 if (g.CanBeImmediate(right)) { | 1091 if (g.CanBeImmediate(right)) { |
1047 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); | 1092 if (CanUseMemoryOperand(selector, opcode, node, left)) { |
1048 } else if (g.CanBeImmediate(left)) { | 1093 size_t left_operands_count = 0; |
1049 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1094 InstructionOperand left_operands[4]; |
1050 VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont); | 1095 AddressingMode addressing_mode = g.GetEffectiveAddressMemoryOperand( |
| 1096 left, left_operands, &left_operands_count); |
| 1097 opcode |= AddressingModeField::encode(addressing_mode); |
| 1098 VisitCompare(selector, opcode, left_operands_count, left_operands, |
| 1099 g.UseImmediate(right), cont); |
| 1100 } else { |
| 1101 VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont); |
| 1102 } |
1051 } else { | 1103 } else { |
1052 VisitCompare(selector, opcode, left, right, cont, | 1104 VisitCompare(selector, opcode, left, right, cont, |
1053 node->op()->HasProperty(Operator::kCommutative)); | 1105 node->op()->HasProperty(Operator::kCommutative), node); |
1054 } | 1106 } |
1055 } | 1107 } |
1056 | 1108 |
1057 | 1109 |
1058 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1110 void VisitWordCompare(InstructionSelector* selector, Node* node, |
1059 FlagsContinuation* cont) { | 1111 FlagsContinuation* cont) { |
1060 IA32OperandGenerator g(selector); | 1112 IA32OperandGenerator g(selector); |
1061 Int32BinopMatcher m(node); | 1113 Int32BinopMatcher m(node); |
1062 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { | 1114 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { |
1063 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); | 1115 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 MachineOperatorBuilder::kFloat64RoundTruncate | | 1409 MachineOperatorBuilder::kFloat64RoundTruncate | |
1358 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1410 MachineOperatorBuilder::kFloat32RoundTiesEven | |
1359 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1411 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1360 } | 1412 } |
1361 return flags; | 1413 return flags; |
1362 } | 1414 } |
1363 | 1415 |
1364 } // namespace compiler | 1416 } // namespace compiler |
1365 } // namespace internal | 1417 } // namespace internal |
1366 } // namespace v8 | 1418 } // namespace v8 |
OLD | NEW |