| 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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 } | 529 } |
| 530 | 530 |
| 531 DCHECK_NE(0u, input_count); | 531 DCHECK_NE(0u, input_count); |
| 532 DCHECK_NE(0u, output_count); | 532 DCHECK_NE(0u, output_count); |
| 533 DCHECK_GE(arraysize(inputs), input_count); | 533 DCHECK_GE(arraysize(inputs), input_count); |
| 534 DCHECK_GE(arraysize(outputs), output_count); | 534 DCHECK_GE(arraysize(outputs), output_count); |
| 535 | 535 |
| 536 opcode = cont->Encode(opcode); | 536 opcode = cont->Encode(opcode); |
| 537 if (cont->IsDeoptimize()) { | 537 if (cont->IsDeoptimize()) { |
| 538 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 538 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
| 539 cont->kind(), cont->reason(), cont->frame_state()); | 539 cont->reason(), cont->frame_state()); |
| 540 } else { | 540 } else { |
| 541 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 541 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 542 } | 542 } |
| 543 } | 543 } |
| 544 | 544 |
| 545 | 545 |
| 546 // Shared routine for multiple binary operations. | 546 // Shared routine for multiple binary operations. |
| 547 static void VisitBinop(InstructionSelector* selector, Node* node, | 547 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 548 InstructionCode opcode) { | 548 InstructionCode opcode) { |
| 549 FlagsContinuation cont; | 549 FlagsContinuation cont; |
| (...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 opcode |= AddressingModeField::encode(addressing_mode); | 1539 opcode |= AddressingModeField::encode(addressing_mode); |
| 1540 opcode = cont->Encode(opcode); | 1540 opcode = cont->Encode(opcode); |
| 1541 inputs[input_count++] = right; | 1541 inputs[input_count++] = right; |
| 1542 | 1542 |
| 1543 if (cont->IsBranch()) { | 1543 if (cont->IsBranch()) { |
| 1544 inputs[input_count++] = g.Label(cont->true_block()); | 1544 inputs[input_count++] = g.Label(cont->true_block()); |
| 1545 inputs[input_count++] = g.Label(cont->false_block()); | 1545 inputs[input_count++] = g.Label(cont->false_block()); |
| 1546 selector->Emit(opcode, 0, nullptr, input_count, inputs); | 1546 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1547 } else if (cont->IsDeoptimize()) { | 1547 } else if (cont->IsDeoptimize()) { |
| 1548 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, | 1548 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, |
| 1549 cont->kind(), cont->reason(), cont->frame_state()); | 1549 cont->reason(), cont->frame_state()); |
| 1550 } else if (cont->IsSet()) { | 1550 } else if (cont->IsSet()) { |
| 1551 InstructionOperand output = g.DefineAsRegister(cont->result()); | 1551 InstructionOperand output = g.DefineAsRegister(cont->result()); |
| 1552 selector->Emit(opcode, 1, &output, input_count, inputs); | 1552 selector->Emit(opcode, 1, &output, input_count, inputs); |
| 1553 } else { | 1553 } else { |
| 1554 DCHECK(cont->IsTrap()); | 1554 DCHECK(cont->IsTrap()); |
| 1555 inputs[input_count++] = g.UseImmediate(cont->trap_id()); | 1555 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
| 1556 selector->Emit(opcode, 0, nullptr, input_count, inputs); | 1556 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1557 } | 1557 } |
| 1558 } | 1558 } |
| 1559 | 1559 |
| 1560 // Shared routine for multiple compare operations. | 1560 // Shared routine for multiple compare operations. |
| 1561 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1561 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1562 InstructionOperand left, InstructionOperand right, | 1562 InstructionOperand left, InstructionOperand right, |
| 1563 FlagsContinuation* cont) { | 1563 FlagsContinuation* cont) { |
| 1564 X64OperandGenerator g(selector); | 1564 X64OperandGenerator g(selector); |
| 1565 opcode = cont->Encode(opcode); | 1565 opcode = cont->Encode(opcode); |
| 1566 if (cont->IsBranch()) { | 1566 if (cont->IsBranch()) { |
| 1567 selector->Emit(opcode, g.NoOutput(), left, right, | 1567 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1568 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1568 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1569 } else if (cont->IsDeoptimize()) { | 1569 } else if (cont->IsDeoptimize()) { |
| 1570 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), | 1570 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
| 1571 cont->reason(), cont->frame_state()); | 1571 cont->frame_state()); |
| 1572 } else if (cont->IsSet()) { | 1572 } else if (cont->IsSet()) { |
| 1573 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1573 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 1574 } else { | 1574 } else { |
| 1575 DCHECK(cont->IsTrap()); | 1575 DCHECK(cont->IsTrap()); |
| 1576 selector->Emit(opcode, g.NoOutput(), left, right, | 1576 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1577 g.UseImmediate(cont->trap_id())); | 1577 g.UseImmediate(cont->trap_id())); |
| 1578 } | 1578 } |
| 1579 } | 1579 } |
| 1580 | 1580 |
| 1581 | 1581 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1748 ExternalReference js_stack_limit = | 1748 ExternalReference js_stack_limit = |
| 1749 ExternalReference::address_of_stack_limit(selector->isolate()); | 1749 ExternalReference::address_of_stack_limit(selector->isolate()); |
| 1750 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 1750 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { |
| 1751 // Compare(Load(js_stack_limit), LoadStackPointer) | 1751 // Compare(Load(js_stack_limit), LoadStackPointer) |
| 1752 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1752 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1753 InstructionCode opcode = cont->Encode(kX64StackCheck); | 1753 InstructionCode opcode = cont->Encode(kX64StackCheck); |
| 1754 if (cont->IsBranch()) { | 1754 if (cont->IsBranch()) { |
| 1755 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), | 1755 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
| 1756 g.Label(cont->false_block())); | 1756 g.Label(cont->false_block())); |
| 1757 } else if (cont->IsDeoptimize()) { | 1757 } else if (cont->IsDeoptimize()) { |
| 1758 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(), | 1758 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->reason(), |
| 1759 cont->reason(), cont->frame_state()); | 1759 cont->frame_state()); |
| 1760 } else if (cont->IsSet()) { | 1760 } else if (cont->IsSet()) { |
| 1761 selector->Emit(opcode, g.DefineAsRegister(cont->result())); | 1761 selector->Emit(opcode, g.DefineAsRegister(cont->result())); |
| 1762 } else { | 1762 } else { |
| 1763 DCHECK(cont->IsTrap()); | 1763 DCHECK(cont->IsTrap()); |
| 1764 selector->Emit(opcode, g.NoOutput(), g.UseImmediate(cont->trap_id())); | 1764 selector->Emit(opcode, g.NoOutput(), g.UseImmediate(cont->trap_id())); |
| 1765 } | 1765 } |
| 1766 return; | 1766 return; |
| 1767 } | 1767 } |
| 1768 } | 1768 } |
| 1769 VisitWordCompare(selector, node, kX64Cmp, cont); | 1769 VisitWordCompare(selector, node, kX64Cmp, cont); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1947 | 1947 |
| 1948 } // namespace | 1948 } // namespace |
| 1949 | 1949 |
| 1950 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1950 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 1951 BasicBlock* fbranch) { | 1951 BasicBlock* fbranch) { |
| 1952 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1952 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 1953 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 1953 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
| 1954 } | 1954 } |
| 1955 | 1955 |
| 1956 void InstructionSelector::VisitDeoptimizeIf(Node* node) { | 1956 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
| 1957 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 1958 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1957 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 1959 kNotEqual, p.kind(), p.reason(), node->InputAt(1)); | 1958 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 1960 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1959 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1961 } | 1960 } |
| 1962 | 1961 |
| 1963 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 1962 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
| 1964 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 1965 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1963 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 1966 kEqual, p.kind(), p.reason(), node->InputAt(1)); | 1964 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 1967 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1965 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1968 } | 1966 } |
| 1969 | 1967 |
| 1970 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 1968 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
| 1971 FlagsContinuation cont = | 1969 FlagsContinuation cont = |
| 1972 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); | 1970 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 1973 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1971 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1974 } | 1972 } |
| 1975 | 1973 |
| 1976 void InstructionSelector::VisitTrapUnless(Node* node, | 1974 void InstructionSelector::VisitTrapUnless(Node* node, |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2302 // static | 2300 // static |
| 2303 MachineOperatorBuilder::AlignmentRequirements | 2301 MachineOperatorBuilder::AlignmentRequirements |
| 2304 InstructionSelector::AlignmentRequirements() { | 2302 InstructionSelector::AlignmentRequirements() { |
| 2305 return MachineOperatorBuilder::AlignmentRequirements:: | 2303 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2306 FullUnalignedAccessSupport(); | 2304 FullUnalignedAccessSupport(); |
| 2307 } | 2305 } |
| 2308 | 2306 |
| 2309 } // namespace compiler | 2307 } // namespace compiler |
| 2310 } // namespace internal | 2308 } // namespace internal |
| 2311 } // namespace v8 | 2309 } // namespace v8 |
| OLD | NEW |