| 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 if (cont->IsSet()) { | 368 if (cont->IsSet()) { |
| 369 // TODO(turbofan): Use byte register here. | 369 // TODO(turbofan): Use byte register here. |
| 370 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 370 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 371 } | 371 } |
| 372 | 372 |
| 373 DCHECK_NE(0u, input_count); | 373 DCHECK_NE(0u, input_count); |
| 374 DCHECK_NE(0u, output_count); | 374 DCHECK_NE(0u, output_count); |
| 375 DCHECK_GE(arraysize(inputs), input_count); | 375 DCHECK_GE(arraysize(inputs), input_count); |
| 376 DCHECK_GE(arraysize(outputs), output_count); | 376 DCHECK_GE(arraysize(outputs), output_count); |
| 377 | 377 |
| 378 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 378 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
| 379 outputs, input_count, inputs); | 379 inputs); |
| 380 if (cont->IsBranch()) instr->MarkAsControl(); | |
| 381 } | 380 } |
| 382 | 381 |
| 383 | 382 |
| 384 // Shared routine for multiple binary operations. | 383 // Shared routine for multiple binary operations. |
| 385 static void VisitBinop(InstructionSelector* selector, Node* node, | 384 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 386 InstructionCode opcode) { | 385 InstructionCode opcode) { |
| 387 FlagsContinuation cont; | 386 FlagsContinuation cont; |
| 388 VisitBinop(selector, node, opcode, &cont); | 387 VisitBinop(selector, node, opcode, &cont); |
| 389 } | 388 } |
| 390 | 389 |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 | 815 |
| 817 namespace { | 816 namespace { |
| 818 | 817 |
| 819 // Shared routine for multiple compare operations. | 818 // Shared routine for multiple compare operations. |
| 820 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 819 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 821 InstructionOperand left, InstructionOperand right, | 820 InstructionOperand left, InstructionOperand right, |
| 822 FlagsContinuation* cont) { | 821 FlagsContinuation* cont) { |
| 823 IA32OperandGenerator g(selector); | 822 IA32OperandGenerator g(selector); |
| 824 if (cont->IsBranch()) { | 823 if (cont->IsBranch()) { |
| 825 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, | 824 selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, |
| 826 g.Label(cont->true_block()), | 825 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 827 g.Label(cont->false_block()))->MarkAsControl(); | |
| 828 } else { | 826 } else { |
| 829 DCHECK(cont->IsSet()); | 827 DCHECK(cont->IsSet()); |
| 830 // TODO(titzer): Needs byte register. | 828 // TODO(titzer): Needs byte register. |
| 831 selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()), | 829 selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()), |
| 832 left, right); | 830 left, right); |
| 833 } | 831 } |
| 834 } | 832 } |
| 835 | 833 |
| 836 | 834 |
| 837 // Shared routine for multiple compare operations. | 835 // Shared routine for multiple compare operations. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { | 880 if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { |
| 883 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); | 881 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); |
| 884 ExternalReference js_stack_limit = | 882 ExternalReference js_stack_limit = |
| 885 ExternalReference::address_of_stack_limit(selector->isolate()); | 883 ExternalReference::address_of_stack_limit(selector->isolate()); |
| 886 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 884 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { |
| 887 // Compare(Load(js_stack_limit), LoadStackPointer) | 885 // Compare(Load(js_stack_limit), LoadStackPointer) |
| 888 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 886 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 889 InstructionCode opcode = cont->Encode(kIA32StackCheck); | 887 InstructionCode opcode = cont->Encode(kIA32StackCheck); |
| 890 if (cont->IsBranch()) { | 888 if (cont->IsBranch()) { |
| 891 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), | 889 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
| 892 g.Label(cont->false_block()))->MarkAsControl(); | 890 g.Label(cont->false_block())); |
| 893 } else { | 891 } else { |
| 894 DCHECK(cont->IsSet()); | 892 DCHECK(cont->IsSet()); |
| 895 selector->Emit(opcode, g.DefineAsRegister(cont->result())); | 893 selector->Emit(opcode, g.DefineAsRegister(cont->result())); |
| 896 } | 894 } |
| 897 return; | 895 return; |
| 898 } | 896 } |
| 899 } | 897 } |
| 900 VisitWordCompare(selector, node, kIA32Cmp, cont); | 898 VisitWordCompare(selector, node, kIA32Cmp, cont); |
| 901 } | 899 } |
| 902 | 900 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); | 1022 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); |
| 1025 inputs[0] = index_operand; | 1023 inputs[0] = index_operand; |
| 1026 std::fill(&inputs[1], &inputs[input_count], default_operand); | 1024 std::fill(&inputs[1], &inputs[input_count], default_operand); |
| 1027 for (size_t index = 0; index < case_count; ++index) { | 1025 for (size_t index = 0; index < case_count; ++index) { |
| 1028 size_t value = case_values[index] - min_value; | 1026 size_t value = case_values[index] - min_value; |
| 1029 BasicBlock* branch = case_branches[index]; | 1027 BasicBlock* branch = case_branches[index]; |
| 1030 DCHECK_LE(0u, value); | 1028 DCHECK_LE(0u, value); |
| 1031 DCHECK_LT(value + 2, input_count); | 1029 DCHECK_LT(value + 2, input_count); |
| 1032 inputs[value + 2] = g.Label(branch); | 1030 inputs[value + 2] = g.Label(branch); |
| 1033 } | 1031 } |
| 1034 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr) | 1032 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr); |
| 1035 ->MarkAsControl(); | |
| 1036 return; | 1033 return; |
| 1037 } | 1034 } |
| 1038 | 1035 |
| 1039 // Generate a sequence of conditional jumps. | 1036 // Generate a sequence of conditional jumps. |
| 1040 size_t input_count = 2 + case_count * 2; | 1037 size_t input_count = 2 + case_count * 2; |
| 1041 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); | 1038 auto* inputs = zone()->NewArray<InstructionOperand>(input_count); |
| 1042 inputs[0] = value_operand; | 1039 inputs[0] = value_operand; |
| 1043 inputs[1] = default_operand; | 1040 inputs[1] = default_operand; |
| 1044 for (size_t index = 0; index < case_count; ++index) { | 1041 for (size_t index = 0; index < case_count; ++index) { |
| 1045 int32_t value = case_values[index]; | 1042 int32_t value = case_values[index]; |
| 1046 BasicBlock* branch = case_branches[index]; | 1043 BasicBlock* branch = case_branches[index]; |
| 1047 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); | 1044 inputs[index * 2 + 2 + 0] = g.TempImmediate(value); |
| 1048 inputs[index * 2 + 2 + 1] = g.Label(branch); | 1045 inputs[index * 2 + 2 + 1] = g.Label(branch); |
| 1049 } | 1046 } |
| 1050 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr) | 1047 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr); |
| 1051 ->MarkAsControl(); | |
| 1052 } | 1048 } |
| 1053 | 1049 |
| 1054 | 1050 |
| 1055 void InstructionSelector::VisitWord32Equal(Node* const node) { | 1051 void InstructionSelector::VisitWord32Equal(Node* const node) { |
| 1056 FlagsContinuation cont(kEqual, node); | 1052 FlagsContinuation cont(kEqual, node); |
| 1057 Int32BinopMatcher m(node); | 1053 Int32BinopMatcher m(node); |
| 1058 if (m.right().Is(0)) { | 1054 if (m.right().Is(0)) { |
| 1059 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); | 1055 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); |
| 1060 } | 1056 } |
| 1061 VisitWordCompare(this, node, &cont); | 1057 VisitWordCompare(this, node, &cont); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 if (CpuFeatures::IsSupported(SSE4_1)) { | 1167 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 1172 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1168 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| 1173 MachineOperatorBuilder::kFloat64RoundTruncate; | 1169 MachineOperatorBuilder::kFloat64RoundTruncate; |
| 1174 } | 1170 } |
| 1175 return flags; | 1171 return flags; |
| 1176 } | 1172 } |
| 1177 | 1173 |
| 1178 } // namespace compiler | 1174 } // namespace compiler |
| 1179 } // namespace internal | 1175 } // namespace internal |
| 1180 } // namespace v8 | 1176 } // namespace v8 |
| OLD | NEW |