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 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1409 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
1410 VisitRR(this, kArm64Float64RoundTruncate, node); | 1410 VisitRR(this, kArm64Float64RoundTruncate, node); |
1411 } | 1411 } |
1412 | 1412 |
1413 | 1413 |
1414 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1414 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
1415 VisitRR(this, kArm64Float64RoundTiesAway, node); | 1415 VisitRR(this, kArm64Float64RoundTiesAway, node); |
1416 } | 1416 } |
1417 | 1417 |
1418 | 1418 |
1419 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 1419 void InstructionSelector::EmitPrepareArguments(NodeVector* arguments, |
| 1420 const CallDescriptor* descriptor, |
| 1421 Node* node) { |
1420 Arm64OperandGenerator g(this); | 1422 Arm64OperandGenerator g(this); |
1421 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | |
1422 | |
1423 FrameStateDescriptor* frame_state_descriptor = nullptr; | |
1424 if (descriptor->NeedsFrameState()) { | |
1425 frame_state_descriptor = GetFrameStateDescriptor( | |
1426 node->InputAt(static_cast<int>(descriptor->InputCount()))); | |
1427 } | |
1428 | |
1429 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | |
1430 | |
1431 // Compute InstructionOperands for inputs and outputs. | |
1432 // TODO(turbofan): on ARM64 it's probably better to use the code object in a | |
1433 // register if there are multiple uses of it. Improve constant pool and the | |
1434 // heuristics in the register allocator for where to emit constants. | |
1435 InitializeCallBuffer(node, &buffer, true, true); | |
1436 | 1423 |
1437 // Push the arguments to the stack. | 1424 // Push the arguments to the stack. |
1438 int aligned_push_count = static_cast<int>(buffer.pushed_nodes.size()); | 1425 int aligned_push_count = static_cast<int>(arguments->size()); |
1439 bool pushed_count_uneven = aligned_push_count & 1; | 1426 bool pushed_count_uneven = aligned_push_count & 1; |
1440 // TODO(dcarney): claim and poke probably take small immediates, | 1427 // TODO(dcarney): claim and poke probably take small immediates, |
1441 // loop here or whatever. | 1428 // loop here or whatever. |
1442 // Bump the stack pointer(s). | 1429 // Bump the stack pointer(s). |
1443 if (aligned_push_count > 0) { | 1430 if (aligned_push_count > 0) { |
1444 // TODO(dcarney): it would be better to bump the csp here only | 1431 // TODO(dcarney): it would be better to bump the csp here only |
1445 // and emit paired stores with increment for non c frames. | 1432 // and emit paired stores with increment for non c frames. |
1446 Emit(kArm64Claim, g.NoOutput(), g.TempImmediate(aligned_push_count)); | 1433 Emit(kArm64Claim, g.NoOutput(), g.TempImmediate(aligned_push_count)); |
1447 } | 1434 } |
1448 // Move arguments to the stack. | 1435 // Move arguments to the stack. |
1449 { | 1436 { |
1450 int slot = aligned_push_count - 1; | 1437 int slot = aligned_push_count - 1; |
1451 // Emit the uneven pushes. | 1438 // Emit the uneven pushes. |
1452 if (pushed_count_uneven) { | 1439 if (pushed_count_uneven) { |
1453 Node* input = buffer.pushed_nodes[slot]; | 1440 Node* input = (*arguments)[slot]; |
1454 Emit(kArm64Poke, g.NoOutput(), g.UseRegister(input), | 1441 Emit(kArm64Poke, g.NoOutput(), g.UseRegister(input), |
1455 g.TempImmediate(slot)); | 1442 g.TempImmediate(slot)); |
1456 slot--; | 1443 slot--; |
1457 } | 1444 } |
1458 // Now all pushes can be done in pairs. | 1445 // Now all pushes can be done in pairs. |
1459 for (; slot >= 0; slot -= 2) { | 1446 for (; slot >= 0; slot -= 2) { |
1460 Emit(kArm64PokePair, g.NoOutput(), | 1447 Emit(kArm64PokePair, g.NoOutput(), g.UseRegister((*arguments)[slot]), |
1461 g.UseRegister(buffer.pushed_nodes[slot]), | 1448 g.UseRegister((*arguments)[slot - 1]), g.TempImmediate(slot)); |
1462 g.UseRegister(buffer.pushed_nodes[slot - 1]), | |
1463 g.TempImmediate(slot)); | |
1464 } | 1449 } |
1465 } | 1450 } |
1466 | |
1467 // Pass label of exception handler block. | |
1468 CallDescriptor::Flags flags = descriptor->flags(); | |
1469 if (handler != nullptr) { | |
1470 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | |
1471 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | |
1472 if (hint == IfExceptionHint::kLocallyCaught) { | |
1473 flags |= CallDescriptor::kHasLocalCatchHandler; | |
1474 } | |
1475 flags |= CallDescriptor::kHasExceptionHandler; | |
1476 buffer.instruction_args.push_back(g.Label(handler)); | |
1477 } | |
1478 | |
1479 // Select the appropriate opcode based on the call type. | |
1480 InstructionCode opcode = kArchNop; | |
1481 switch (descriptor->kind()) { | |
1482 case CallDescriptor::kCallAddress: | |
1483 opcode = | |
1484 kArchCallCFunction | | |
1485 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); | |
1486 break; | |
1487 case CallDescriptor::kCallCodeObject: | |
1488 opcode = kArchCallCodeObject | MiscField::encode(flags); | |
1489 break; | |
1490 case CallDescriptor::kCallJSFunction: | |
1491 opcode = kArchCallJSFunction | MiscField::encode(flags); | |
1492 break; | |
1493 case CallDescriptor::kLazyBailout: | |
1494 opcode = kArchLazyBailout | MiscField::encode(flags); | |
1495 break; | |
1496 } | |
1497 | |
1498 // Emit the call instruction. | |
1499 size_t const output_count = buffer.outputs.size(); | |
1500 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | |
1501 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | |
1502 &buffer.instruction_args.front())->MarkAsCall(); | |
1503 } | 1451 } |
1504 | 1452 |
1505 | 1453 |
1506 void InstructionSelector::VisitTailCall(Node* node) { | 1454 void InstructionSelector::VisitTailCall(Node* node) { |
1507 Arm64OperandGenerator g(this); | 1455 Arm64OperandGenerator g(this); |
1508 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 1456 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
1509 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); | 1457 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |
1510 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); | 1458 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); |
1511 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); | 1459 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); |
1512 | 1460 |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 MachineOperatorBuilder::kFloat64RoundTruncate | | 2065 MachineOperatorBuilder::kFloat64RoundTruncate | |
2118 MachineOperatorBuilder::kFloat64RoundTiesAway | | 2066 MachineOperatorBuilder::kFloat64RoundTiesAway | |
2119 MachineOperatorBuilder::kWord32ShiftIsSafe | | 2067 MachineOperatorBuilder::kWord32ShiftIsSafe | |
2120 MachineOperatorBuilder::kInt32DivIsSafe | | 2068 MachineOperatorBuilder::kInt32DivIsSafe | |
2121 MachineOperatorBuilder::kUint32DivIsSafe; | 2069 MachineOperatorBuilder::kUint32DivIsSafe; |
2122 } | 2070 } |
2123 | 2071 |
2124 } // namespace compiler | 2072 } // namespace compiler |
2125 } // namespace internal | 2073 } // namespace internal |
2126 } // namespace v8 | 2074 } // namespace v8 |
OLD | NEW |