Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: src/compiler/mips/code-generator-mips.cc

Issue 2628433004: [wasm] TrapIf and TrapUnless TurboFan operators implemented on mips. (Closed)
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 #include "src/compilation-info.h" 6 #include "src/compilation-info.h"
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 1610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 return true; 1621 return true;
1622 case kUnsignedGreaterThan: 1622 case kUnsignedGreaterThan:
1623 cc = ugt; 1623 cc = ugt;
1624 return true; 1624 return true;
1625 default: 1625 default:
1626 break; 1626 break;
1627 } 1627 }
1628 return false; 1628 return false;
1629 } 1629 }
1630 1630
1631 void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
1632 Instruction* instr, FlagsCondition condition,
1633 Label* tlabel, Label* flabel, bool fallthru) {
1634 #undef __
1635 #define __ masm->
1631 1636
1632 // Assembles branches after an instruction.
1633 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1634 MipsOperandConverter i(this, instr);
1635 Label* tlabel = branch->true_label;
1636 Label* flabel = branch->false_label;
1637 Condition cc = kNoCondition; 1637 Condition cc = kNoCondition;
1638 // MIPS does not have condition code flags, so compare and branch are 1638 // MIPS does not have condition code flags, so compare and branch are
1639 // implemented differently than on the other arch's. The compare operations 1639 // implemented differently than on the other arch's. The compare operations
1640 // emit mips pseudo-instructions, which are handled here by branch 1640 // emit mips pseudo-instructions, which are handled here by branch
1641 // instructions that do the actual comparison. Essential that the input 1641 // instructions that do the actual comparison. Essential that the input
1642 // registers to compare pseudo-op are not modified before this branch op, as 1642 // registers to compare pseudo-op are not modified before this branch op, as
1643 // they are tested here. 1643 // they are tested here.
1644 1644
1645 MipsOperandConverter i(gen, instr);
1645 if (instr->arch_opcode() == kMipsTst) { 1646 if (instr->arch_opcode() == kMipsTst) {
1646 cc = FlagsConditionToConditionTst(branch->condition); 1647 cc = FlagsConditionToConditionTst(condition);
1647 __ And(at, i.InputRegister(0), i.InputOperand(1)); 1648 __ And(at, i.InputRegister(0), i.InputOperand(1));
1648 __ Branch(tlabel, cc, at, Operand(zero_reg)); 1649 __ Branch(tlabel, cc, at, Operand(zero_reg));
1649 } else if (instr->arch_opcode() == kMipsAddOvf) { 1650 } else if (instr->arch_opcode() == kMipsAddOvf) {
1650 switch (branch->condition) { 1651 switch (condition) {
1651 case kOverflow: 1652 case kOverflow:
1652 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), 1653 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1653 i.InputOperand(1), tlabel, flabel); 1654 i.InputOperand(1), tlabel, flabel);
1654 break; 1655 break;
1655 case kNotOverflow: 1656 case kNotOverflow:
1656 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), 1657 __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1657 i.InputOperand(1), flabel, tlabel); 1658 i.InputOperand(1), flabel, tlabel);
1658 break; 1659 break;
1659 default: 1660 default:
1660 UNSUPPORTED_COND(kMipsAddOvf, branch->condition); 1661 UNSUPPORTED_COND(kMipsAddOvf, condition);
1661 break; 1662 break;
1662 } 1663 }
1663 } else if (instr->arch_opcode() == kMipsSubOvf) { 1664 } else if (instr->arch_opcode() == kMipsSubOvf) {
1664 switch (branch->condition) { 1665 switch (condition) {
1665 case kOverflow: 1666 case kOverflow:
1666 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), 1667 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1667 i.InputOperand(1), tlabel, flabel); 1668 i.InputOperand(1), tlabel, flabel);
1668 break; 1669 break;
1669 case kNotOverflow: 1670 case kNotOverflow:
1670 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), 1671 __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1671 i.InputOperand(1), flabel, tlabel); 1672 i.InputOperand(1), flabel, tlabel);
1672 break; 1673 break;
1673 default: 1674 default:
1674 UNSUPPORTED_COND(kMipsAddOvf, branch->condition); 1675 UNSUPPORTED_COND(kMipsAddOvf, condition);
1675 break; 1676 break;
1676 } 1677 }
1677 } else if (instr->arch_opcode() == kMipsMulOvf) { 1678 } else if (instr->arch_opcode() == kMipsMulOvf) {
1678 switch (branch->condition) { 1679 switch (condition) {
1679 case kOverflow: 1680 case kOverflow:
1680 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), 1681 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1681 i.InputOperand(1), tlabel, flabel); 1682 i.InputOperand(1), tlabel, flabel);
1682 break; 1683 break;
1683 case kNotOverflow: 1684 case kNotOverflow:
1684 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), 1685 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1685 i.InputOperand(1), flabel, tlabel); 1686 i.InputOperand(1), flabel, tlabel);
1686 break; 1687 break;
1687 default: 1688 default:
1688 UNSUPPORTED_COND(kMipsMulOvf, branch->condition); 1689 UNSUPPORTED_COND(kMipsMulOvf, condition);
1689 break; 1690 break;
1690 } 1691 }
1691 } else if (instr->arch_opcode() == kMipsCmp) { 1692 } else if (instr->arch_opcode() == kMipsCmp) {
1692 cc = FlagsConditionToConditionCmp(branch->condition); 1693 cc = FlagsConditionToConditionCmp(condition);
1693 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 1694 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
1694 } else if (instr->arch_opcode() == kMipsCmpS) { 1695 } else if (instr->arch_opcode() == kMipsCmpS) {
1695 if (!convertCondition(branch->condition, cc)) { 1696 if (!convertCondition(condition, cc)) {
1696 UNSUPPORTED_COND(kMips64CmpS, branch->condition); 1697 UNSUPPORTED_COND(kMips64CmpS, condition);
1697 } 1698 }
1698 FPURegister left = i.InputOrZeroSingleRegister(0); 1699 FPURegister left = i.InputOrZeroSingleRegister(0);
1699 FPURegister right = i.InputOrZeroSingleRegister(1); 1700 FPURegister right = i.InputOrZeroSingleRegister(1);
1700 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && 1701 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
1701 !__ IsDoubleZeroRegSet()) { 1702 !__ IsDoubleZeroRegSet()) {
1702 __ Move(kDoubleRegZero, 0.0); 1703 __ Move(kDoubleRegZero, 0.0);
1703 } 1704 }
1704 __ BranchF32(tlabel, nullptr, cc, left, right); 1705 __ BranchF32(tlabel, nullptr, cc, left, right);
1705 } else if (instr->arch_opcode() == kMipsCmpD) { 1706 } else if (instr->arch_opcode() == kMipsCmpD) {
1706 if (!convertCondition(branch->condition, cc)) { 1707 if (!convertCondition(condition, cc)) {
1707 UNSUPPORTED_COND(kMips64CmpD, branch->condition); 1708 UNSUPPORTED_COND(kMips64CmpD, condition);
1708 } 1709 }
1709 FPURegister left = i.InputOrZeroDoubleRegister(0); 1710 FPURegister left = i.InputOrZeroDoubleRegister(0);
1710 FPURegister right = i.InputOrZeroDoubleRegister(1); 1711 FPURegister right = i.InputOrZeroDoubleRegister(1);
1711 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && 1712 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
1712 !__ IsDoubleZeroRegSet()) { 1713 !__ IsDoubleZeroRegSet()) {
1713 __ Move(kDoubleRegZero, 0.0); 1714 __ Move(kDoubleRegZero, 0.0);
1714 } 1715 }
1715 __ BranchF64(tlabel, nullptr, cc, left, right); 1716 __ BranchF64(tlabel, nullptr, cc, left, right);
1716 } else { 1717 } else {
1717 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", 1718 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
1718 instr->arch_opcode()); 1719 instr->arch_opcode());
1719 UNIMPLEMENTED(); 1720 UNIMPLEMENTED();
1720 } 1721 }
1721 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. 1722 if (!fallthru) __ Branch(flabel); // no fallthru to flabel.
1723 #undef __
1724 #define __ masm()->
1725 }
1726
1727 // Assembles branches after an instruction.
1728 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1729 Label* tlabel = branch->true_label;
1730 Label* flabel = branch->false_label;
1731 AssembleBranchToLabels(this, masm(), instr, branch->condition, tlabel, flabel,
1732 branch->fallthru);
1722 } 1733 }
1723 1734
1724 1735
1725 void CodeGenerator::AssembleArchJump(RpoNumber target) { 1736 void CodeGenerator::AssembleArchJump(RpoNumber target) {
1726 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); 1737 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
1727 } 1738 }
1728 1739
1729 void CodeGenerator::AssembleArchTrap(Instruction* instr, 1740 void CodeGenerator::AssembleArchTrap(Instruction* instr,
1730 FlagsCondition condition) { 1741 FlagsCondition condition) {
1731 UNREACHABLE(); 1742 class OutOfLineTrap final : public OutOfLineCode {
1743 public:
1744 OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
1745 : OutOfLineCode(gen),
1746 frame_elided_(frame_elided),
1747 instr_(instr),
1748 gen_(gen) {}
1749
1750 void Generate() final {
1751 MipsOperandConverter i(gen_, instr_);
1752
1753 Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>(
1754 i.InputInt32(instr_->InputCount() - 1));
1755 bool old_has_frame = __ has_frame();
1756 if (frame_elided_) {
1757 __ set_has_frame(true);
1758 __ EnterFrame(StackFrame::WASM_COMPILED);
1759 }
1760 GenerateCallToTrap(trap_id);
1761 if (frame_elided_) {
1762 __ set_has_frame(old_has_frame);
1763 }
1764 if (FLAG_debug_code) {
1765 __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap));
1766 }
1767 }
1768
1769 private:
1770 void GenerateCallToTrap(Runtime::FunctionId trap_id) {
1771 if (trap_id == Runtime::kNumFunctions) {
1772 // We cannot test calls to the runtime in cctest/test-run-wasm.
1773 // Therefore we emit a call to C here instead of a call to the runtime.
1774 // We use the context register as the scratch register, because we do
1775 // not have a context here.
1776 __ PrepareCallCFunction(0, 0, cp);
1777 __ CallCFunction(
1778 ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
1779 0);
1780 } else {
1781 __ Move(cp, isolate()->native_context());
1782 gen_->AssembleSourcePosition(instr_);
1783 __ CallRuntime(trap_id);
1784 }
1785 ReferenceMap* reference_map =
1786 new (gen_->zone()) ReferenceMap(gen_->zone());
1787 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
1788 Safepoint::kNoLazyDeopt);
1789 }
1790
1791 bool frame_elided_;
1792 Instruction* instr_;
1793 CodeGenerator* gen_;
1794 };
1795 bool frame_elided = !frame_access_state()->has_frame();
1796 auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
1797 Label* tlabel = ool->entry();
1798 AssembleBranchToLabels(this, masm(), instr, condition, tlabel, nullptr, true);
1732 } 1799 }
1733 1800
1734 // Assembles boolean materializations after an instruction. 1801 // Assembles boolean materializations after an instruction.
1735 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 1802 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
1736 FlagsCondition condition) { 1803 FlagsCondition condition) {
1737 MipsOperandConverter i(this, instr); 1804 MipsOperandConverter i(this, instr);
1738 Label done; 1805 Label done;
1739 1806
1740 // Materialize a full 32-bit 1 or 0 value. The result register is always the 1807 // Materialize a full 32-bit 1 or 0 value. The result register is always the
1741 // last output of the instruction. 1808 // last output of the instruction.
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2306 padding_size -= v8::internal::Assembler::kInstrSize; 2373 padding_size -= v8::internal::Assembler::kInstrSize;
2307 } 2374 }
2308 } 2375 }
2309 } 2376 }
2310 2377
2311 #undef __ 2378 #undef __
2312 2379
2313 } // namespace compiler 2380 } // namespace compiler
2314 } // namespace internal 2381 } // namespace internal
2315 } // namespace v8 2382 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698