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 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 VisitFloat64Compare(this, node, &cont); | 1371 VisitFloat64Compare(this, node, &cont); |
1372 } | 1372 } |
1373 | 1373 |
1374 | 1374 |
1375 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { | 1375 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
1376 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); | 1376 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
1377 VisitFloat64Compare(this, node, &cont); | 1377 VisitFloat64Compare(this, node, &cont); |
1378 } | 1378 } |
1379 | 1379 |
1380 | 1380 |
1381 void InstructionSelector::VisitCall(Node* node) { | 1381 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
1382 PPCOperandGenerator g(this); | 1382 PPCOperandGenerator g(this); |
1383 const CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node); | 1383 const CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node); |
1384 | 1384 |
1385 FrameStateDescriptor* frame_state_descriptor = NULL; | 1385 FrameStateDescriptor* frame_state_descriptor = NULL; |
1386 if (descriptor->NeedsFrameState()) { | 1386 if (descriptor->NeedsFrameState()) { |
1387 frame_state_descriptor = | 1387 frame_state_descriptor = |
1388 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 1388 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
1389 } | 1389 } |
1390 | 1390 |
1391 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 1391 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
1392 | 1392 |
1393 // Compute InstructionOperands for inputs and outputs. | 1393 // Compute InstructionOperands for inputs and outputs. |
1394 // TODO(turbofan): on PPC it's probably better to use the code object in a | 1394 // TODO(turbofan): on PPC it's probably better to use the code object in a |
1395 // register if there are multiple uses of it. Improve constant pool and the | 1395 // register if there are multiple uses of it. Improve constant pool and the |
1396 // heuristics in the register allocator for where to emit constants. | 1396 // heuristics in the register allocator for where to emit constants. |
1397 InitializeCallBuffer(node, &buffer, true, false); | 1397 InitializeCallBuffer(node, &buffer, true, false); |
1398 | 1398 |
1399 // Push any stack arguments. | 1399 // Push any stack arguments. |
1400 // TODO(mbrandy): reverse order and use push only for first | 1400 // TODO(mbrandy): reverse order and use push only for first |
1401 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); | 1401 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); |
1402 i++) { | 1402 i++) { |
1403 Emit(kPPC_Push, g.NoOutput(), g.UseRegister(*i)); | 1403 Emit(kPPC_Push, g.NoOutput(), g.UseRegister(*i)); |
1404 } | 1404 } |
1405 | 1405 |
| 1406 // Pass label of exception handler block. |
| 1407 CallDescriptor::Flags flags = descriptor->flags(); |
| 1408 if (handler != nullptr) { |
| 1409 flags |= CallDescriptor::kHasExceptionHandler; |
| 1410 buffer.instruction_args.push_back(g.Label(handler)); |
| 1411 } |
| 1412 |
1406 // Select the appropriate opcode based on the call type. | 1413 // Select the appropriate opcode based on the call type. |
1407 InstructionCode opcode; | 1414 InstructionCode opcode; |
1408 switch (descriptor->kind()) { | 1415 switch (descriptor->kind()) { |
1409 case CallDescriptor::kCallCodeObject: { | 1416 case CallDescriptor::kCallCodeObject: { |
1410 opcode = kArchCallCodeObject; | 1417 opcode = kArchCallCodeObject; |
1411 break; | 1418 break; |
1412 } | 1419 } |
1413 case CallDescriptor::kCallJSFunction: | 1420 case CallDescriptor::kCallJSFunction: |
1414 opcode = kArchCallJSFunction; | 1421 opcode = kArchCallJSFunction; |
1415 break; | 1422 break; |
1416 default: | 1423 default: |
1417 UNREACHABLE(); | 1424 UNREACHABLE(); |
1418 return; | 1425 return; |
1419 } | 1426 } |
1420 opcode |= MiscField::encode(descriptor->flags()); | 1427 opcode |= MiscField::encode(flags); |
1421 | 1428 |
1422 // Emit the call instruction. | 1429 // Emit the call instruction. |
1423 InstructionOperand* first_output = | 1430 InstructionOperand* first_output = |
1424 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 1431 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
1425 Instruction* call_instr = | 1432 Instruction* call_instr = |
1426 Emit(opcode, buffer.outputs.size(), first_output, | 1433 Emit(opcode, buffer.outputs.size(), first_output, |
1427 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 1434 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
1428 call_instr->MarkAsCall(); | 1435 call_instr->MarkAsCall(); |
1429 } | 1436 } |
1430 | 1437 |
1431 | 1438 |
1432 // static | 1439 // static |
1433 MachineOperatorBuilder::Flags | 1440 MachineOperatorBuilder::Flags |
1434 InstructionSelector::SupportedMachineOperatorFlags() { | 1441 InstructionSelector::SupportedMachineOperatorFlags() { |
1435 return MachineOperatorBuilder::kFloat64Floor | | 1442 return MachineOperatorBuilder::kFloat64Floor | |
1436 MachineOperatorBuilder::kFloat64Ceil | | 1443 MachineOperatorBuilder::kFloat64Ceil | |
1437 MachineOperatorBuilder::kFloat64RoundTruncate | | 1444 MachineOperatorBuilder::kFloat64RoundTruncate | |
1438 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1445 MachineOperatorBuilder::kFloat64RoundTiesAway; |
1439 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1446 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
1440 } | 1447 } |
1441 | 1448 |
1442 } // namespace compiler | 1449 } // namespace compiler |
1443 } // namespace internal | 1450 } // namespace internal |
1444 } // namespace v8 | 1451 } // namespace v8 |
OLD | NEW |