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/bits.h" | 5 #include "src/base/bits.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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 outputs[output_count++] = g.DefineAsRegister(node); | 111 outputs[output_count++] = g.DefineAsRegister(node); |
112 if (cont->IsSet()) { | 112 if (cont->IsSet()) { |
113 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 113 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
114 } | 114 } |
115 | 115 |
116 DCHECK_NE(0u, input_count); | 116 DCHECK_NE(0u, input_count); |
117 DCHECK_NE(0u, output_count); | 117 DCHECK_NE(0u, output_count); |
118 DCHECK_GE(arraysize(inputs), input_count); | 118 DCHECK_GE(arraysize(inputs), input_count); |
119 DCHECK_GE(arraysize(outputs), output_count); | 119 DCHECK_GE(arraysize(outputs), output_count); |
120 | 120 |
121 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 121 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
122 outputs, input_count, inputs); | 122 inputs); |
123 if (cont->IsBranch()) instr->MarkAsControl(); | |
124 } | 123 } |
125 | 124 |
126 | 125 |
127 static void VisitBinop(InstructionSelector* selector, Node* node, | 126 static void VisitBinop(InstructionSelector* selector, Node* node, |
128 InstructionCode opcode) { | 127 InstructionCode opcode) { |
129 FlagsContinuation cont; | 128 FlagsContinuation cont; |
130 VisitBinop(selector, node, opcode, &cont); | 129 VisitBinop(selector, node, opcode, &cont); |
131 } | 130 } |
132 | 131 |
133 | 132 |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 namespace { | 770 namespace { |
772 | 771 |
773 // Shared routine for multiple compare operations. | 772 // Shared routine for multiple compare operations. |
774 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 773 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
775 InstructionOperand left, InstructionOperand right, | 774 InstructionOperand left, InstructionOperand right, |
776 FlagsContinuation* cont) { | 775 FlagsContinuation* cont) { |
777 Mips64OperandGenerator g(selector); | 776 Mips64OperandGenerator g(selector); |
778 opcode = cont->Encode(opcode); | 777 opcode = cont->Encode(opcode); |
779 if (cont->IsBranch()) { | 778 if (cont->IsBranch()) { |
780 selector->Emit(opcode, g.NoOutput(), left, right, | 779 selector->Emit(opcode, g.NoOutput(), left, right, |
781 g.Label(cont->true_block()), | 780 g.Label(cont->true_block()), g.Label(cont->false_block())); |
782 g.Label(cont->false_block()))->MarkAsControl(); | |
783 } else { | 781 } else { |
784 DCHECK(cont->IsSet()); | 782 DCHECK(cont->IsSet()); |
785 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 783 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
786 } | 784 } |
787 } | 785 } |
788 | 786 |
789 | 787 |
790 // Shared routine for multiple float compare operations. | 788 // Shared routine for multiple float compare operations. |
791 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 789 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
792 FlagsContinuation* cont) { | 790 FlagsContinuation* cont) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 } // namespace | 833 } // namespace |
836 | 834 |
837 | 835 |
838 void EmitWordCompareZero(InstructionSelector* selector, Node* value, | 836 void EmitWordCompareZero(InstructionSelector* selector, Node* value, |
839 FlagsContinuation* cont) { | 837 FlagsContinuation* cont) { |
840 Mips64OperandGenerator g(selector); | 838 Mips64OperandGenerator g(selector); |
841 InstructionCode opcode = cont->Encode(kMips64Cmp); | 839 InstructionCode opcode = cont->Encode(kMips64Cmp); |
842 InstructionOperand const value_operand = g.UseRegister(value); | 840 InstructionOperand const value_operand = g.UseRegister(value); |
843 if (cont->IsBranch()) { | 841 if (cont->IsBranch()) { |
844 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), | 842 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), |
845 g.Label(cont->true_block()), | 843 g.Label(cont->true_block()), g.Label(cont->false_block())); |
846 g.Label(cont->false_block()))->MarkAsControl(); | |
847 } else { | 844 } else { |
848 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, | 845 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, |
849 g.TempImmediate(0)); | 846 g.TempImmediate(0)); |
850 } | 847 } |
851 } | 848 } |
852 | 849 |
853 | 850 |
854 // Shared routine for word comparisons against zero. | 851 // Shared routine for word comparisons against zero. |
855 void VisitWordCompareZero(InstructionSelector* selector, Node* user, | 852 void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
856 Node* value, FlagsContinuation* cont) { | 853 Node* value, FlagsContinuation* cont) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); | 988 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); |
992 inputs[0] = index_operand; | 989 inputs[0] = index_operand; |
993 std::fill(&inputs[1], &inputs[input_count], default_operand); | 990 std::fill(&inputs[1], &inputs[input_count], default_operand); |
994 for (size_t index = 0; index < case_count; ++index) { | 991 for (size_t index = 0; index < case_count; ++index) { |
995 size_t value = case_values[index] - min_value; | 992 size_t value = case_values[index] - min_value; |
996 BasicBlock* branch = case_branches[index]; | 993 BasicBlock* branch = case_branches[index]; |
997 DCHECK_LE(0u, value); | 994 DCHECK_LE(0u, value); |
998 DCHECK_LT(value + 2, input_count); | 995 DCHECK_LT(value + 2, input_count); |
999 inputs[value + 2] = g.Label(branch); | 996 inputs[value + 2] = g.Label(branch); |
1000 } | 997 } |
1001 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr) | 998 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr); |
1002 ->MarkAsControl(); | |
1003 return; | 999 return; |
1004 } | 1000 } |
1005 | 1001 |
1006 // Generate a sequence of conditional jumps. | 1002 // Generate a sequence of conditional jumps. |
1007 size_t input_count = 2 + case_count * 2; | 1003 size_t input_count = 2 + case_count * 2; |
1008 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); | 1004 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); |
1009 inputs[0] = value_operand; | 1005 inputs[0] = value_operand; |
1010 inputs[1] = default_operand; | 1006 inputs[1] = default_operand; |
1011 for (size_t index = 0; index < case_count; ++index) { | 1007 for (size_t index = 0; index < case_count; ++index) { |
1012 int32_t value = case_values[index]; | 1008 int32_t value = case_values[index]; |
1013 BasicBlock* branch = case_branches[index]; | 1009 BasicBlock* branch = case_branches[index]; |
1014 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); | 1010 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); |
1015 inputs[index * 2 + 2 + 1] = g.Label(branch); | 1011 inputs[index * 2 + 2 + 1] = g.Label(branch); |
1016 } | 1012 } |
1017 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr) | 1013 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr); |
1018 ->MarkAsControl(); | |
1019 } | 1014 } |
1020 | 1015 |
1021 | 1016 |
1022 void InstructionSelector::VisitWord32Equal(Node* const node) { | 1017 void InstructionSelector::VisitWord32Equal(Node* const node) { |
1023 FlagsContinuation cont(kEqual, node); | 1018 FlagsContinuation cont(kEqual, node); |
1024 Int32BinopMatcher m(node); | 1019 Int32BinopMatcher m(node); |
1025 if (m.right().Is(0)) { | 1020 if (m.right().Is(0)) { |
1026 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); | 1021 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); |
1027 } | 1022 } |
1028 | 1023 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 // static | 1151 // static |
1157 MachineOperatorBuilder::Flags | 1152 MachineOperatorBuilder::Flags |
1158 InstructionSelector::SupportedMachineOperatorFlags() { | 1153 InstructionSelector::SupportedMachineOperatorFlags() { |
1159 return MachineOperatorBuilder::kFloat64RoundDown | | 1154 return MachineOperatorBuilder::kFloat64RoundDown | |
1160 MachineOperatorBuilder::kFloat64RoundTruncate; | 1155 MachineOperatorBuilder::kFloat64RoundTruncate; |
1161 } | 1156 } |
1162 | 1157 |
1163 } // namespace compiler | 1158 } // namespace compiler |
1164 } // namespace internal | 1159 } // namespace internal |
1165 } // namespace v8 | 1160 } // namespace v8 |
OLD | NEW |