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

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

Issue 2571813002: [wasm] TrapIf and TrapUnless TurboFan operators implemented on ia32. (Closed)
Patch Set: Move TrapReasonToFunctionId from wasm-opcodes to wasm-compiler Created 4 years 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/ia32/instruction-selector-ia32.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 6
7 #include "src/compilation-info.h" 7 #include "src/compilation-info.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 case kAtomicLoadWord32: 1601 case kAtomicLoadWord32:
1602 case kAtomicStoreWord8: 1602 case kAtomicStoreWord8:
1603 case kAtomicStoreWord16: 1603 case kAtomicStoreWord16:
1604 case kAtomicStoreWord32: 1604 case kAtomicStoreWord32:
1605 UNREACHABLE(); // Won't be generated by instruction selector. 1605 UNREACHABLE(); // Won't be generated by instruction selector.
1606 break; 1606 break;
1607 } 1607 }
1608 return kSuccess; 1608 return kSuccess;
1609 } // NOLINT(readability/fn_size) 1609 } // NOLINT(readability/fn_size)
1610 1610
1611 static Condition FlagsConditionToCondition(FlagsCondition condition) {
1612 switch (condition) {
1613 case kUnorderedEqual:
1614 case kEqual:
1615 return equal;
1616 break;
1617 case kUnorderedNotEqual:
1618 case kNotEqual:
1619 return not_equal;
1620 break;
1621 case kSignedLessThan:
1622 return less;
1623 break;
1624 case kSignedGreaterThanOrEqual:
1625 return greater_equal;
1626 break;
1627 case kSignedLessThanOrEqual:
1628 return less_equal;
1629 break;
1630 case kSignedGreaterThan:
1631 return greater;
1632 break;
1633 case kUnsignedLessThan:
1634 return below;
1635 break;
1636 case kUnsignedGreaterThanOrEqual:
1637 return above_equal;
1638 break;
1639 case kUnsignedLessThanOrEqual:
1640 return below_equal;
1641 break;
1642 case kUnsignedGreaterThan:
1643 return above;
1644 break;
1645 case kOverflow:
1646 return overflow;
1647 break;
1648 case kNotOverflow:
1649 return no_overflow;
1650 break;
1651 default:
1652 UNREACHABLE();
1653 return no_condition;
1654 break;
1655 }
1656 }
1611 1657
1612 // Assembles a branch after an instruction. 1658 // Assembles a branch after an instruction.
1613 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 1659 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1614 IA32OperandConverter i(this, instr);
1615 Label::Distance flabel_distance = 1660 Label::Distance flabel_distance =
1616 branch->fallthru ? Label::kNear : Label::kFar; 1661 branch->fallthru ? Label::kNear : Label::kFar;
1617 Label* tlabel = branch->true_label; 1662 Label* tlabel = branch->true_label;
1618 Label* flabel = branch->false_label; 1663 Label* flabel = branch->false_label;
1619 switch (branch->condition) { 1664 if (branch->condition == kUnorderedEqual) {
1620 case kUnorderedEqual: 1665 __ j(parity_even, flabel, flabel_distance);
1621 __ j(parity_even, flabel, flabel_distance); 1666 } else if (branch->condition == kUnorderedNotEqual) {
1622 // Fall through. 1667 __ j(parity_even, tlabel);
1623 case kEqual:
1624 __ j(equal, tlabel);
1625 break;
1626 case kUnorderedNotEqual:
1627 __ j(parity_even, tlabel);
1628 // Fall through.
1629 case kNotEqual:
1630 __ j(not_equal, tlabel);
1631 break;
1632 case kSignedLessThan:
1633 __ j(less, tlabel);
1634 break;
1635 case kSignedGreaterThanOrEqual:
1636 __ j(greater_equal, tlabel);
1637 break;
1638 case kSignedLessThanOrEqual:
1639 __ j(less_equal, tlabel);
1640 break;
1641 case kSignedGreaterThan:
1642 __ j(greater, tlabel);
1643 break;
1644 case kUnsignedLessThan:
1645 __ j(below, tlabel);
1646 break;
1647 case kUnsignedGreaterThanOrEqual:
1648 __ j(above_equal, tlabel);
1649 break;
1650 case kUnsignedLessThanOrEqual:
1651 __ j(below_equal, tlabel);
1652 break;
1653 case kUnsignedGreaterThan:
1654 __ j(above, tlabel);
1655 break;
1656 case kOverflow:
1657 __ j(overflow, tlabel);
1658 break;
1659 case kNotOverflow:
1660 __ j(no_overflow, tlabel);
1661 break;
1662 default:
1663 UNREACHABLE();
1664 break;
1665 } 1668 }
1669 __ j(FlagsConditionToCondition(branch->condition), tlabel);
1670
1666 // Add a jump if not falling through to the next block. 1671 // Add a jump if not falling through to the next block.
1667 if (!branch->fallthru) __ jmp(flabel); 1672 if (!branch->fallthru) __ jmp(flabel);
1668 } 1673 }
1669 1674
1670 1675
1671 void CodeGenerator::AssembleArchJump(RpoNumber target) { 1676 void CodeGenerator::AssembleArchJump(RpoNumber target) {
1672 if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); 1677 if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
1673 } 1678 }
1674 1679
1675 void CodeGenerator::AssembleArchTrap(Instruction* instr, 1680 void CodeGenerator::AssembleArchTrap(Instruction* instr,
1676 FlagsCondition condition) { 1681 FlagsCondition condition) {
1677 UNREACHABLE(); 1682 class OutOfLineTrap final : public OutOfLineCode {
1683 public:
1684 OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
1685 : OutOfLineCode(gen),
1686 frame_elided_(frame_elided),
1687 instr_(instr),
1688 gen_(gen) {}
1689
1690 void Generate() final {
1691 IA32OperandConverter i(gen_, instr_);
1692
1693 Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>(
1694 i.InputInt32(instr_->InputCount() - 1));
1695 bool old_has_frame = __ has_frame();
1696 if (frame_elided_) {
1697 __ set_has_frame(true);
1698 __ EnterFrame(StackFrame::WASM);
1699 }
1700 GenerateCallToTrap(trap_id);
1701 if (frame_elided_) {
1702 ReferenceMap* reference_map =
1703 new (gen_->zone()) ReferenceMap(gen_->zone());
1704 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
1705 Safepoint::kNoLazyDeopt);
1706 __ set_has_frame(old_has_frame);
1707 }
1708 if (FLAG_debug_code) {
1709 __ ud2();
1710 }
1711 }
1712
1713 private:
1714 void GenerateCallToTrap(Runtime::FunctionId trap_id) {
1715 if (trap_id == Runtime::kNumFunctions) {
1716 // We cannot test calls to the runtime in cctest/test-run-wasm.
1717 // Therefore we emit a call to C here instead of a call to the runtime.
1718 __ PrepareCallCFunction(0, esi);
1719 __ CallCFunction(
1720 ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
1721 0);
1722 } else {
1723 __ Move(esi, isolate()->native_context());
1724 gen_->AssembleSourcePosition(instr_);
1725 __ CallRuntime(trap_id);
1726 }
1727 }
1728
1729 bool frame_elided_;
1730 Instruction* instr_;
1731 CodeGenerator* gen_;
1732 };
1733 bool frame_elided = !frame_access_state()->has_frame();
1734 auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
1735 Label* tlabel = ool->entry();
1736 Label end;
1737 if (condition == kUnorderedEqual) {
1738 __ j(parity_even, &end);
1739 } else if (condition == kUnorderedNotEqual) {
1740 __ j(parity_even, tlabel);
1741 }
1742 __ j(FlagsConditionToCondition(condition), tlabel);
1743 __ bind(&end);
1678 } 1744 }
1679 1745
1680 // Assembles boolean materializations after an instruction. 1746 // Assembles boolean materializations after an instruction.
1681 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 1747 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
1682 FlagsCondition condition) { 1748 FlagsCondition condition) {
1683 IA32OperandConverter i(this, instr); 1749 IA32OperandConverter i(this, instr);
1684 Label done; 1750 Label done;
1685 1751
1686 // Materialize a full 32-bit 1 or 0 value. The result register is always the 1752 // Materialize a full 32-bit 1 or 0 value. The result register is always the
1687 // last output of the instruction. 1753 // last output of the instruction.
1688 Label check; 1754 Label check;
1689 DCHECK_NE(0u, instr->OutputCount()); 1755 DCHECK_NE(0u, instr->OutputCount());
1690 Register reg = i.OutputRegister(instr->OutputCount() - 1); 1756 Register reg = i.OutputRegister(instr->OutputCount() - 1);
1691 Condition cc = no_condition; 1757 if (condition == kUnorderedEqual) {
1692 switch (condition) { 1758 __ j(parity_odd, &check, Label::kNear);
1693 case kUnorderedEqual: 1759 __ Move(reg, Immediate(0));
1694 __ j(parity_odd, &check, Label::kNear); 1760 __ jmp(&done, Label::kNear);
1695 __ Move(reg, Immediate(0)); 1761 } else if (condition == kUnorderedNotEqual) {
1696 __ jmp(&done, Label::kNear); 1762 __ j(parity_odd, &check, Label::kNear);
1697 // Fall through. 1763 __ mov(reg, Immediate(1));
1698 case kEqual: 1764 __ jmp(&done, Label::kNear);
1699 cc = equal;
1700 break;
1701 case kUnorderedNotEqual:
1702 __ j(parity_odd, &check, Label::kNear);
1703 __ mov(reg, Immediate(1));
1704 __ jmp(&done, Label::kNear);
1705 // Fall through.
1706 case kNotEqual:
1707 cc = not_equal;
1708 break;
1709 case kSignedLessThan:
1710 cc = less;
1711 break;
1712 case kSignedGreaterThanOrEqual:
1713 cc = greater_equal;
1714 break;
1715 case kSignedLessThanOrEqual:
1716 cc = less_equal;
1717 break;
1718 case kSignedGreaterThan:
1719 cc = greater;
1720 break;
1721 case kUnsignedLessThan:
1722 cc = below;
1723 break;
1724 case kUnsignedGreaterThanOrEqual:
1725 cc = above_equal;
1726 break;
1727 case kUnsignedLessThanOrEqual:
1728 cc = below_equal;
1729 break;
1730 case kUnsignedGreaterThan:
1731 cc = above;
1732 break;
1733 case kOverflow:
1734 cc = overflow;
1735 break;
1736 case kNotOverflow:
1737 cc = no_overflow;
1738 break;
1739 default:
1740 UNREACHABLE();
1741 break;
1742 } 1765 }
1766 Condition cc = FlagsConditionToCondition(condition);
1767
1743 __ bind(&check); 1768 __ bind(&check);
1744 if (reg.is_byte_register()) { 1769 if (reg.is_byte_register()) {
1745 // setcc for byte registers (al, bl, cl, dl). 1770 // setcc for byte registers (al, bl, cl, dl).
1746 __ setcc(cc, reg); 1771 __ setcc(cc, reg);
1747 __ movzx_b(reg, reg); 1772 __ movzx_b(reg, reg);
1748 } else { 1773 } else {
1749 // Emit a branch to set a register to either 1 or 0. 1774 // Emit a branch to set a register to either 1 or 0.
1750 Label set; 1775 Label set;
1751 __ j(cc, &set, Label::kNear); 1776 __ j(cc, &set, Label::kNear);
1752 __ Move(reg, Immediate(0)); 1777 __ Move(reg, Immediate(0));
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2303 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2279 __ Nop(padding_size); 2304 __ Nop(padding_size);
2280 } 2305 }
2281 } 2306 }
2282 2307
2283 #undef __ 2308 #undef __
2284 2309
2285 } // namespace compiler 2310 } // namespace compiler
2286 } // namespace internal 2311 } // namespace internal
2287 } // namespace v8 2312 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698