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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 frame_state_descriptor = | 1435 frame_state_descriptor = |
1436 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 1436 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
1437 } | 1437 } |
1438 | 1438 |
1439 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 1439 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
1440 | 1440 |
1441 // Compute InstructionOperands for inputs and outputs. | 1441 // Compute InstructionOperands for inputs and outputs. |
1442 // TODO(turbofan): on PPC it's probably better to use the code object in a | 1442 // TODO(turbofan): on PPC it's probably better to use the code object in a |
1443 // register if there are multiple uses of it. Improve constant pool and the | 1443 // register if there are multiple uses of it. Improve constant pool and the |
1444 // heuristics in the register allocator for where to emit constants. | 1444 // heuristics in the register allocator for where to emit constants. |
1445 InitializeCallBuffer(node, &buffer, true, false); | 1445 InitializeCallBuffer(node, &buffer, true, true); |
1446 | 1446 |
1447 // Push any stack arguments. | 1447 // Prepare for C function call. |
1448 // TODO(mbrandy): reverse order and use push only for first | 1448 if (descriptor->IsCFunctionCall()) { |
1449 for (Node* node : base::Reversed(buffer.pushed_nodes)) { | 1449 Emit(kArchPrepareCallCFunction | |
1450 Emit(kPPC_Push, g.NoOutput(), g.UseRegister(node)); | 1450 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
| 1451 0, nullptr, 0, nullptr); |
| 1452 |
| 1453 // Poke any stack arguments. |
| 1454 int slot = kStackFrameExtraParamSlot; |
| 1455 for (Node* node : buffer.pushed_nodes) { |
| 1456 Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(node), |
| 1457 g.TempImmediate(slot)); |
| 1458 ++slot; |
| 1459 } |
| 1460 } else { |
| 1461 // Push any stack arguments. |
| 1462 int num_slots = buffer.pushed_nodes.size(); |
| 1463 int slot = 0; |
| 1464 for (Node* node : buffer.pushed_nodes) { |
| 1465 if (slot == 0) { |
| 1466 Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(node), |
| 1467 g.TempImmediate(num_slots)); |
| 1468 } else { |
| 1469 Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(node), |
| 1470 g.TempImmediate(slot)); |
| 1471 } |
| 1472 ++slot; |
| 1473 } |
1451 } | 1474 } |
1452 | 1475 |
1453 // Pass label of exception handler block. | 1476 // Pass label of exception handler block. |
1454 CallDescriptor::Flags flags = descriptor->flags(); | 1477 CallDescriptor::Flags flags = descriptor->flags(); |
1455 if (handler) { | 1478 if (handler) { |
1456 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 1479 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
1457 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 1480 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
1458 if (hint == IfExceptionHint::kLocallyCaught) { | 1481 if (hint == IfExceptionHint::kLocallyCaught) { |
1459 flags |= CallDescriptor::kHasLocalCatchHandler; | 1482 flags |= CallDescriptor::kHasLocalCatchHandler; |
1460 } | 1483 } |
1461 flags |= CallDescriptor::kHasExceptionHandler; | 1484 flags |= CallDescriptor::kHasExceptionHandler; |
1462 buffer.instruction_args.push_back(g.Label(handler)); | 1485 buffer.instruction_args.push_back(g.Label(handler)); |
1463 } | 1486 } |
1464 | 1487 |
1465 // Select the appropriate opcode based on the call type. | 1488 // Select the appropriate opcode based on the call type. |
1466 InstructionCode opcode; | 1489 InstructionCode opcode; |
1467 switch (descriptor->kind()) { | 1490 switch (descriptor->kind()) { |
1468 case CallDescriptor::kCallCodeObject: { | 1491 case CallDescriptor::kCallAddress: |
1469 opcode = kArchCallCodeObject; | 1492 opcode = |
| 1493 kArchCallCFunction | |
| 1494 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
1470 break; | 1495 break; |
1471 } | 1496 case CallDescriptor::kCallCodeObject: |
| 1497 opcode = kArchCallCodeObject | MiscField::encode(flags); |
| 1498 break; |
1472 case CallDescriptor::kCallJSFunction: | 1499 case CallDescriptor::kCallJSFunction: |
1473 opcode = kArchCallJSFunction; | 1500 opcode = kArchCallJSFunction | MiscField::encode(flags); |
1474 break; | 1501 break; |
1475 default: | 1502 default: |
1476 UNREACHABLE(); | 1503 UNREACHABLE(); |
1477 return; | 1504 return; |
1478 } | 1505 } |
1479 opcode |= MiscField::encode(flags); | |
1480 | 1506 |
1481 // Emit the call instruction. | 1507 // Emit the call instruction. |
1482 size_t const output_count = buffer.outputs.size(); | 1508 size_t const output_count = buffer.outputs.size(); |
1483 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 1509 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
1484 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1510 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
1485 &buffer.instruction_args.front())->MarkAsCall(); | 1511 &buffer.instruction_args.front())->MarkAsCall(); |
1486 } | 1512 } |
1487 | 1513 |
1488 | 1514 |
1489 void InstructionSelector::VisitTailCall(Node* node) { | 1515 void InstructionSelector::VisitTailCall(Node* node) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 InstructionSelector::SupportedMachineOperatorFlags() { | 1648 InstructionSelector::SupportedMachineOperatorFlags() { |
1623 return MachineOperatorBuilder::kFloat64RoundDown | | 1649 return MachineOperatorBuilder::kFloat64RoundDown | |
1624 MachineOperatorBuilder::kFloat64RoundTruncate | | 1650 MachineOperatorBuilder::kFloat64RoundTruncate | |
1625 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1651 MachineOperatorBuilder::kFloat64RoundTiesAway; |
1626 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1652 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
1627 } | 1653 } |
1628 | 1654 |
1629 } // namespace compiler | 1655 } // namespace compiler |
1630 } // namespace internal | 1656 } // namespace internal |
1631 } // namespace v8 | 1657 } // namespace v8 |
OLD | NEW |