| 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 } | 467 } |
| 468 | 468 |
| 469 DCHECK_NE(0u, input_count); | 469 DCHECK_NE(0u, input_count); |
| 470 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); | 470 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); |
| 471 DCHECK_GE(arraysize(inputs), input_count); | 471 DCHECK_GE(arraysize(inputs), input_count); |
| 472 DCHECK_GE(arraysize(outputs), output_count); | 472 DCHECK_GE(arraysize(outputs), output_count); |
| 473 | 473 |
| 474 opcode = cont->Encode(opcode); | 474 opcode = cont->Encode(opcode); |
| 475 if (cont->IsDeoptimize()) { | 475 if (cont->IsDeoptimize()) { |
| 476 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 476 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
| 477 cont->kind(), cont->reason(), cont->frame_state()); | 477 cont->reason(), cont->frame_state()); |
| 478 } else if (cont->IsTrap()) { | 478 } else if (cont->IsTrap()) { |
| 479 inputs[input_count++] = g.UseImmediate(cont->trap_id()); | 479 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
| 480 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 480 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 481 } else { | 481 } else { |
| 482 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 482 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 | 485 |
| 486 | 486 |
| 487 // Shared routine for multiple binary operations. | 487 // Shared routine for multiple binary operations. |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 InstructionOperand right = g.UseRegister(m.right().node()); | 1438 InstructionOperand right = g.UseRegister(m.right().node()); |
| 1439 selector->Emit(kArm64Smull, result, left, right); | 1439 selector->Emit(kArm64Smull, result, left, right); |
| 1440 | 1440 |
| 1441 InstructionCode opcode = cont->Encode(kArm64Cmp) | | 1441 InstructionCode opcode = cont->Encode(kArm64Cmp) | |
| 1442 AddressingModeField::encode(kMode_Operand2_R_SXTW); | 1442 AddressingModeField::encode(kMode_Operand2_R_SXTW); |
| 1443 if (cont->IsBranch()) { | 1443 if (cont->IsBranch()) { |
| 1444 selector->Emit(opcode, g.NoOutput(), result, result, | 1444 selector->Emit(opcode, g.NoOutput(), result, result, |
| 1445 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1445 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1446 } else if (cont->IsDeoptimize()) { | 1446 } else if (cont->IsDeoptimize()) { |
| 1447 InstructionOperand in[] = {result, result}; | 1447 InstructionOperand in[] = {result, result}; |
| 1448 selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->kind(), | 1448 selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->reason(), |
| 1449 cont->reason(), cont->frame_state()); | 1449 cont->frame_state()); |
| 1450 } else if (cont->IsSet()) { | 1450 } else if (cont->IsSet()) { |
| 1451 selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); | 1451 selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); |
| 1452 } else { | 1452 } else { |
| 1453 DCHECK(cont->IsTrap()); | 1453 DCHECK(cont->IsTrap()); |
| 1454 selector->Emit(opcode, g.NoOutput(), result, result, | 1454 selector->Emit(opcode, g.NoOutput(), result, result, |
| 1455 g.UseImmediate(cont->trap_id())); | 1455 g.UseImmediate(cont->trap_id())); |
| 1456 } | 1456 } |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 } // namespace | 1459 } // namespace |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 // Shared routine for multiple compare operations. | 1788 // Shared routine for multiple compare operations. |
| 1789 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1789 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1790 InstructionOperand left, InstructionOperand right, | 1790 InstructionOperand left, InstructionOperand right, |
| 1791 FlagsContinuation* cont) { | 1791 FlagsContinuation* cont) { |
| 1792 Arm64OperandGenerator g(selector); | 1792 Arm64OperandGenerator g(selector); |
| 1793 opcode = cont->Encode(opcode); | 1793 opcode = cont->Encode(opcode); |
| 1794 if (cont->IsBranch()) { | 1794 if (cont->IsBranch()) { |
| 1795 selector->Emit(opcode, g.NoOutput(), left, right, | 1795 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1796 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1796 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1797 } else if (cont->IsDeoptimize()) { | 1797 } else if (cont->IsDeoptimize()) { |
| 1798 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), | 1798 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
| 1799 cont->reason(), cont->frame_state()); | 1799 cont->frame_state()); |
| 1800 } else if (cont->IsSet()) { | 1800 } else if (cont->IsSet()) { |
| 1801 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1801 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 1802 } else { | 1802 } else { |
| 1803 DCHECK(cont->IsTrap()); | 1803 DCHECK(cont->IsTrap()); |
| 1804 selector->Emit(opcode, g.NoOutput(), left, right, | 1804 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1805 g.UseImmediate(cont->trap_id())); | 1805 g.UseImmediate(cont->trap_id())); |
| 1806 } | 1806 } |
| 1807 } | 1807 } |
| 1808 | 1808 |
| 1809 | 1809 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 void EmitBranchOrDeoptimize(InstructionSelector* selector, | 1960 void EmitBranchOrDeoptimize(InstructionSelector* selector, |
| 1961 InstructionCode opcode, InstructionOperand value, | 1961 InstructionCode opcode, InstructionOperand value, |
| 1962 FlagsContinuation* cont) { | 1962 FlagsContinuation* cont) { |
| 1963 Arm64OperandGenerator g(selector); | 1963 Arm64OperandGenerator g(selector); |
| 1964 if (cont->IsBranch()) { | 1964 if (cont->IsBranch()) { |
| 1965 selector->Emit(cont->Encode(opcode), g.NoOutput(), value, | 1965 selector->Emit(cont->Encode(opcode), g.NoOutput(), value, |
| 1966 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1966 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1967 } else { | 1967 } else { |
| 1968 DCHECK(cont->IsDeoptimize()); | 1968 DCHECK(cont->IsDeoptimize()); |
| 1969 selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value, | 1969 selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value, |
| 1970 cont->kind(), cont->reason(), cont->frame_state()); | 1970 cont->reason(), cont->frame_state()); |
| 1971 } | 1971 } |
| 1972 } | 1972 } |
| 1973 | 1973 |
| 1974 // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node} | 1974 // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node} |
| 1975 // against zero, depending on the condition. | 1975 // against zero, depending on the condition. |
| 1976 bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user, | 1976 bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user, |
| 1977 FlagsCondition cond, FlagsContinuation* cont) { | 1977 FlagsCondition cond, FlagsContinuation* cont) { |
| 1978 Int32BinopMatcher m_user(user); | 1978 Int32BinopMatcher m_user(user); |
| 1979 USE(m_user); | 1979 USE(m_user); |
| 1980 DCHECK(m_user.right().Is(0) || m_user.left().Is(0)); | 1980 DCHECK(m_user.right().Is(0) || m_user.left().Is(0)); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 } | 2314 } |
| 2315 | 2315 |
| 2316 // Branch could not be combined with a compare, compare against 0 and branch. | 2316 // Branch could not be combined with a compare, compare against 0 and branch. |
| 2317 if (cont->IsBranch()) { | 2317 if (cont->IsBranch()) { |
| 2318 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(), | 2318 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(), |
| 2319 g.UseRegister(value), g.Label(cont->true_block()), | 2319 g.UseRegister(value), g.Label(cont->true_block()), |
| 2320 g.Label(cont->false_block())); | 2320 g.Label(cont->false_block())); |
| 2321 } else if (cont->IsDeoptimize()) { | 2321 } else if (cont->IsDeoptimize()) { |
| 2322 selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(), | 2322 selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(), |
| 2323 g.UseRegister(value), g.UseRegister(value), | 2323 g.UseRegister(value), g.UseRegister(value), |
| 2324 cont->kind(), cont->reason(), cont->frame_state()); | 2324 cont->reason(), cont->frame_state()); |
| 2325 } else { | 2325 } else { |
| 2326 DCHECK(cont->IsTrap()); | 2326 DCHECK(cont->IsTrap()); |
| 2327 selector->Emit(cont->Encode(kArm64Tst32), g.NoOutput(), | 2327 selector->Emit(cont->Encode(kArm64Tst32), g.NoOutput(), |
| 2328 g.UseRegister(value), g.UseRegister(value), | 2328 g.UseRegister(value), g.UseRegister(value), |
| 2329 g.UseImmediate(cont->trap_id())); | 2329 g.UseImmediate(cont->trap_id())); |
| 2330 } | 2330 } |
| 2331 } | 2331 } |
| 2332 | 2332 |
| 2333 } // namespace | 2333 } // namespace |
| 2334 | 2334 |
| 2335 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 2335 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 2336 BasicBlock* fbranch) { | 2336 BasicBlock* fbranch) { |
| 2337 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 2337 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 2338 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 2338 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
| 2339 } | 2339 } |
| 2340 | 2340 |
| 2341 void InstructionSelector::VisitDeoptimizeIf(Node* node) { | 2341 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
| 2342 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 2343 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 2342 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 2344 kNotEqual, p.kind(), p.reason(), node->InputAt(1)); | 2343 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 2345 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2344 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 2346 } | 2345 } |
| 2347 | 2346 |
| 2348 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 2347 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
| 2349 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 2350 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 2348 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 2351 kEqual, p.kind(), p.reason(), node->InputAt(1)); | 2349 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 2352 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2350 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 2353 } | 2351 } |
| 2354 | 2352 |
| 2355 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 2353 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
| 2356 FlagsContinuation cont = | 2354 FlagsContinuation cont = |
| 2357 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); | 2355 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 2358 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2356 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 2359 } | 2357 } |
| 2360 | 2358 |
| 2361 void InstructionSelector::VisitTrapUnless(Node* node, | 2359 void InstructionSelector::VisitTrapUnless(Node* node, |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2710 // static | 2708 // static |
| 2711 MachineOperatorBuilder::AlignmentRequirements | 2709 MachineOperatorBuilder::AlignmentRequirements |
| 2712 InstructionSelector::AlignmentRequirements() { | 2710 InstructionSelector::AlignmentRequirements() { |
| 2713 return MachineOperatorBuilder::AlignmentRequirements:: | 2711 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2714 FullUnalignedAccessSupport(); | 2712 FullUnalignedAccessSupport(); |
| 2715 } | 2713 } |
| 2716 | 2714 |
| 2717 } // namespace compiler | 2715 } // namespace compiler |
| 2718 } // namespace internal | 2716 } // namespace internal |
| 2719 } // namespace v8 | 2717 } // namespace v8 |
| OLD | NEW |