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/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 492 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
493 VisitRR(this, kMipsFloat64RoundTruncate, node); | 493 VisitRR(this, kMipsFloat64RoundTruncate, node); |
494 } | 494 } |
495 | 495 |
496 | 496 |
497 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 497 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
498 UNREACHABLE(); | 498 UNREACHABLE(); |
499 } | 499 } |
500 | 500 |
501 | 501 |
502 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 502 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler, |
| 503 CallMode call_mode) { |
503 MipsOperandGenerator g(this); | 504 MipsOperandGenerator g(this); |
504 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 505 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
505 | 506 |
506 FrameStateDescriptor* frame_state_descriptor = NULL; | 507 FrameStateDescriptor* frame_state_descriptor = NULL; |
507 if (descriptor->NeedsFrameState()) { | 508 if (descriptor->NeedsFrameState()) { |
508 frame_state_descriptor = | 509 frame_state_descriptor = |
509 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 510 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
510 } | 511 } |
511 | 512 |
512 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 513 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
(...skipping 14 matching lines...) Expand all Loading... |
527 } | 528 } |
528 | 529 |
529 // Pass label of exception handler block. | 530 // Pass label of exception handler block. |
530 CallDescriptor::Flags flags = descriptor->flags(); | 531 CallDescriptor::Flags flags = descriptor->flags(); |
531 if (handler != nullptr) { | 532 if (handler != nullptr) { |
532 flags |= CallDescriptor::kHasExceptionHandler; | 533 flags |= CallDescriptor::kHasExceptionHandler; |
533 buffer.instruction_args.push_back(g.Label(handler)); | 534 buffer.instruction_args.push_back(g.Label(handler)); |
534 } | 535 } |
535 | 536 |
536 // Select the appropriate opcode based on the call type. | 537 // Select the appropriate opcode based on the call type. |
| 538 bool is_tail_call = call_mode == TAIL_CALL; |
537 InstructionCode opcode; | 539 InstructionCode opcode; |
538 switch (descriptor->kind()) { | 540 switch (descriptor->kind()) { |
539 case CallDescriptor::kCallCodeObject: { | 541 case CallDescriptor::kCallCodeObject: { |
540 opcode = kArchCallCodeObject; | 542 opcode = is_tail_call ? kArchTailCallCodeObject : kArchCallCodeObject; |
541 break; | 543 break; |
542 } | 544 } |
543 case CallDescriptor::kCallJSFunction: | 545 case CallDescriptor::kCallJSFunction: |
544 opcode = kArchCallJSFunction; | 546 opcode = is_tail_call ? kArchTailCallJSFunction : kArchCallJSFunction; |
545 break; | 547 break; |
546 default: | 548 default: |
547 UNREACHABLE(); | 549 UNREACHABLE(); |
548 return; | 550 return; |
549 } | 551 } |
550 opcode |= MiscField::encode(flags); | 552 opcode |= MiscField::encode(flags); |
551 | 553 |
552 // Emit the call instruction. | 554 // Emit the call instruction. |
| 555 size_t size = is_tail_call ? 0 : buffer.outputs.size(); |
553 InstructionOperand* first_output = | 556 InstructionOperand* first_output = |
554 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 557 size > 0 ? &buffer.outputs.front() : nullptr; |
555 Instruction* call_instr = | 558 Instruction* call_instr = |
556 Emit(opcode, buffer.outputs.size(), first_output, | 559 Emit(opcode, size, first_output, buffer.instruction_args.size(), |
557 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 560 &buffer.instruction_args.front()); |
558 call_instr->MarkAsCall(); | 561 call_instr->MarkAsCall(); |
559 } | 562 } |
560 | 563 |
561 | 564 |
562 void InstructionSelector::VisitCheckedLoad(Node* node) { | 565 void InstructionSelector::VisitCheckedLoad(Node* node) { |
563 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 566 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
564 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 567 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
565 MipsOperandGenerator g(this); | 568 MipsOperandGenerator g(this); |
566 Node* const buffer = node->InputAt(0); | 569 Node* const buffer = node->InputAt(0); |
567 Node* const offset = node->InputAt(1); | 570 Node* const offset = node->InputAt(1); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { | 983 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { |
981 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 984 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
982 MachineOperatorBuilder::kFloat64RoundTruncate; | 985 MachineOperatorBuilder::kFloat64RoundTruncate; |
983 } | 986 } |
984 return flags; | 987 return flags; |
985 } | 988 } |
986 | 989 |
987 } // namespace compiler | 990 } // namespace compiler |
988 } // namespace internal | 991 } // namespace internal |
989 } // namespace v8 | 992 } // namespace v8 |
OLD | NEW |