| 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 |