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 |