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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 383303003: Lower casting operations that involve vector types. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Rebase and make bitcast changes Created 6 years, 5 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 | « src/IceTargetLoweringX8632.h ('k') | tests_lit/llvm2ice_tests/vector-bitcast.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the TargetLoweringX8632 class, which 10 // This file implements the TargetLoweringX8632 class, which
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 const size_t TableIcmp64Size = llvm::array_lengthof(TableIcmp64); 80 const size_t TableIcmp64Size = llvm::array_lengthof(TableIcmp64);
81 81
82 InstX8632::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { 82 InstX8632::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
83 size_t Index = static_cast<size_t>(Cond); 83 size_t Index = static_cast<size_t>(Cond);
84 assert(Index < TableIcmp32Size); 84 assert(Index < TableIcmp32Size);
85 return TableIcmp32[Index].Mapping; 85 return TableIcmp32[Index].Mapping;
86 } 86 }
87 87
88 // The maximum number of arguments to pass in XMM registers 88 // The maximum number of arguments to pass in XMM registers
89 const unsigned X86_MAX_XMM_ARGS = 4; 89 const unsigned X86_MAX_XMM_ARGS = 4;
90 // The number of bits in a byte
91 const unsigned X86_CHAR_BIT = 8;
90 92
91 // In some cases, there are x-macros tables for both high-level and 93 // In some cases, there are x-macros tables for both high-level and
92 // low-level instructions/operands that use the same enum key value. 94 // low-level instructions/operands that use the same enum key value.
93 // The tables are kept separate to maintain a proper separation 95 // The tables are kept separate to maintain a proper separation
94 // between abstraction layers. There is a risk that the tables 96 // between abstraction layers. There is a risk that the tables
95 // could get out of sync if enum values are reordered or if entries 97 // could get out of sync if enum values are reordered or if entries
96 // are added or deleted. This dummy function uses static_assert to 98 // are added or deleted. This dummy function uses static_assert to
97 // ensure everything is kept in sync. 99 // ensure everything is kept in sync.
98 void xMacroIntegrityCheck() { 100 void xMacroIntegrityCheck() {
99 // Validate the enum values in FCMPX8632_TABLE. 101 // Validate the enum values in FCMPX8632_TABLE.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); 152 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag);
151 ICEINSTICMP_TABLE; 153 ICEINSTICMP_TABLE;
152 #undef X 154 #undef X
153 } 155 }
154 156
155 // Validate the enum values in ICETYPEX8632_TABLE. 157 // Validate the enum values in ICETYPEX8632_TABLE.
156 { 158 {
157 // Define a temporary set of enum values based on low-level 159 // Define a temporary set of enum values based on low-level
158 // table entries. 160 // table entries.
159 enum _tmp_enum { 161 enum _tmp_enum {
160 #define X(tag, cvt, sdss, width) _tmp_##tag, 162 #define X(tag, cvt, sdss, pack, width) _tmp_##tag,
161 ICETYPEX8632_TABLE 163 ICETYPEX8632_TABLE
162 #undef X 164 #undef X
163 _num 165 _num
164 }; 166 };
165 // Define a set of constants based on high-level table entries. 167 // Define a set of constants based on high-level table entries.
166 #define X(tag, size, align, elts, elty, str) \ 168 #define X(tag, size, align, elts, elty, str) \
167 static const int _table1_##tag = tag; 169 static const int _table1_##tag = tag;
168 ICETYPE_TABLE; 170 ICETYPE_TABLE;
169 #undef X 171 #undef X
170 // Define a set of constants based on low-level table entries, 172 // Define a set of constants based on low-level table entries,
171 // and ensure the table entry keys are consistent. 173 // and ensure the table entry keys are consistent.
172 #define X(tag, cvt, sdss, width) \ 174 #define X(tag, cvt, sdss, pack, width) \
173 static const int _table2_##tag = _tmp_##tag; \ 175 static const int _table2_##tag = _tmp_##tag; \
174 STATIC_ASSERT(_table1_##tag == _table2_##tag); 176 STATIC_ASSERT(_table1_##tag == _table2_##tag);
175 ICETYPEX8632_TABLE; 177 ICETYPEX8632_TABLE;
176 #undef X 178 #undef X
177 // Repeat the static asserts with respect to the high-level 179 // Repeat the static asserts with respect to the high-level
178 // table entries in case the high-level table has extra entries. 180 // table entries in case the high-level table has extra entries.
179 #define X(tag, size, align, elts, elty, str) \ 181 #define X(tag, size, align, elts, elty, str) \
180 STATIC_ASSERT(_table1_##tag == _table2_##tag); 182 STATIC_ASSERT(_table1_##tag == _table2_##tag);
181 ICETYPE_TABLE; 183 ICETYPE_TABLE;
182 #undef X 184 #undef X
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 if (Src0RM->getType() == IceType_i32) 1568 if (Src0RM->getType() == IceType_i32)
1567 _mov(T_Lo, Src0RM); 1569 _mov(T_Lo, Src0RM);
1568 else 1570 else
1569 _movsx(T_Lo, Src0RM); 1571 _movsx(T_Lo, Src0RM);
1570 _mov(DestLo, T_Lo); 1572 _mov(DestLo, T_Lo);
1571 Variable *T_Hi = NULL; 1573 Variable *T_Hi = NULL;
1572 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); 1574 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31);
1573 _mov(T_Hi, T_Lo); 1575 _mov(T_Hi, T_Lo);
1574 _sar(T_Hi, Shift); 1576 _sar(T_Hi, Shift);
1575 _mov(DestHi, T_Hi); 1577 _mov(DestHi, T_Hi);
1578 } else if (isVectorType(Dest->getType())) {
1579 Type DestTy = Dest->getType();
1580 if (DestTy == IceType_v16i8) {
1581 // onemask = materialize(1,1,...); dst = (src & onemask) > 0
1582 Variable *OneMask = makeVectorOfOnes(Dest->getType());
1583 Variable *T = makeReg(DestTy);
1584 _movp(T, Src0RM);
1585 _pand(T, OneMask);
1586 Variable *Zeros = makeVectorOfZeros(Dest->getType());
1587 _pcmpgt(T, Zeros);
1588 _movp(Dest, T);
1589 } else {
1590 // width = width(elty) - 1; dest = (src << width) >> width
1591 SizeT ShiftAmount =
1592 X86_CHAR_BIT * typeWidthInBytes(typeElementType(DestTy)) - 1;
1593 Constant *ShiftConstant = Ctx->getConstantInt(IceType_i8, ShiftAmount);
1594 Variable *T = makeReg(DestTy);
1595 _movp(T, Src0RM);
1596 _psll(T, ShiftConstant);
1597 _psra(T, ShiftConstant);
1598 _movp(Dest, T);
1599 }
1576 } else { 1600 } else {
1577 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and 1601 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and
1578 // also copy to the high operand of a 64-bit variable. 1602 // also copy to the high operand of a 64-bit variable.
1579 // t1 = movsx src; dst = t1 1603 // t1 = movsx src; dst = t1
1580 Variable *T = makeReg(Dest->getType()); 1604 Variable *T = makeReg(Dest->getType());
1581 _movsx(T, Src0RM); 1605 _movsx(T, Src0RM);
1582 _mov(Dest, T); 1606 _mov(Dest, T);
1583 } 1607 }
1584 break; 1608 break;
1585 } 1609 }
(...skipping 11 matching lines...) Expand all
1597 _movzx(Tmp, Src0RM); 1621 _movzx(Tmp, Src0RM);
1598 _mov(DestLo, Tmp); 1622 _mov(DestLo, Tmp);
1599 _mov(DestHi, Zero); 1623 _mov(DestHi, Zero);
1600 } else if (Src0RM->getType() == IceType_i1) { 1624 } else if (Src0RM->getType() == IceType_i1) {
1601 // t = Src0RM; t &= 1; Dest = t 1625 // t = Src0RM; t &= 1; Dest = t
1602 Operand *One = Ctx->getConstantInt(IceType_i32, 1); 1626 Operand *One = Ctx->getConstantInt(IceType_i32, 1);
1603 Variable *T = makeReg(IceType_i32); 1627 Variable *T = makeReg(IceType_i32);
1604 _movzx(T, Src0RM); 1628 _movzx(T, Src0RM);
1605 _and(T, One); 1629 _and(T, One);
1606 _mov(Dest, T); 1630 _mov(Dest, T);
1631 } else if (isVectorType(Dest->getType())) {
1632 // onemask = materialize(1,1,...); dest = onemask & src
1633 Type DestTy = Dest->getType();
1634 Variable *OneMask = makeVectorOfOnes(DestTy);
1635 Variable *T = makeReg(DestTy);
1636 _movp(T, Src0RM);
1637 _pand(T, OneMask);
1638 _movp(Dest, T);
1607 } else { 1639 } else {
1608 // t1 = movzx src; dst = t1 1640 // t1 = movzx src; dst = t1
1609 Variable *T = makeReg(Dest->getType()); 1641 Variable *T = makeReg(Dest->getType());
1610 _movzx(T, Src0RM); 1642 _movzx(T, Src0RM);
1611 _mov(Dest, T); 1643 _mov(Dest, T);
1612 } 1644 }
1613 break; 1645 break;
1614 } 1646 }
1615 case InstCast::Trunc: { 1647 case InstCast::Trunc: {
1616 Operand *Src0 = Inst->getSrc(0); 1648 if (isVectorType(Dest->getType())) {
1617 if (Src0->getType() == IceType_i64) 1649 // onemask = materialize(1,1,...); dst = src & onemask
1618 Src0 = loOperand(Src0); 1650 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1619 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 1651 Type Src0Ty = Src0RM->getType();
1620 // t1 = trunc Src0RM; Dest = t1 1652 Variable *OneMask = makeVectorOfOnes(Src0Ty);
1621 Variable *T = NULL; 1653 Variable *T = makeReg(Dest->getType());
1622 _mov(T, Src0RM); 1654 _movp(T, Src0RM);
1623 _mov(Dest, T); 1655 _pand(T, OneMask);
1656 _movp(Dest, T);
1657 } else {
1658 Operand *Src0 = Inst->getSrc(0);
1659 if (Src0->getType() == IceType_i64)
1660 Src0 = loOperand(Src0);
1661 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
1662 // t1 = trunc Src0RM; Dest = t1
1663 Variable *T = NULL;
1664 _mov(T, Src0RM);
1665 _mov(Dest, T);
1666 }
1624 break; 1667 break;
1625 } 1668 }
1626 case InstCast::Fptrunc: 1669 case InstCast::Fptrunc:
1627 case InstCast::Fpext: { 1670 case InstCast::Fpext: {
1628 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 1671 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1629 // t1 = cvt Src0RM; Dest = t1 1672 // t1 = cvt Src0RM; Dest = t1
1630 Variable *T = makeReg(Dest->getType()); 1673 Variable *T = makeReg(Dest->getType());
1631 _cvt(T, Src0RM); 1674 _cvt(T, Src0RM);
1632 _mov(Dest, T); 1675 _mov(Dest, T);
1633 break; 1676 break;
1634 } 1677 }
1635 case InstCast::Fptosi: 1678 case InstCast::Fptosi:
1636 if (Dest->getType() == IceType_i64) { 1679 if (isVectorType(Dest->getType())) {
1680 assert(Dest->getType() == IceType_v4i32 &&
1681 Inst->getSrc(0)->getType() == IceType_v4f32);
1682 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1683 Variable *T = makeReg(Dest->getType());
1684 _cvt(T, Src0RM);
1685 _movp(Dest, T);
1686 } else if (Dest->getType() == IceType_i64) {
1637 // Use a helper for converting floating-point values to 64-bit 1687 // Use a helper for converting floating-point values to 64-bit
1638 // integers. SSE2 appears to have no way to convert from xmm 1688 // integers. SSE2 appears to have no way to convert from xmm
1639 // registers to something like the edx:eax register pair, and 1689 // registers to something like the edx:eax register pair, and
1640 // gcc and clang both want to use x87 instructions complete with 1690 // gcc and clang both want to use x87 instructions complete with
1641 // temporary manipulation of the status word. This helper is 1691 // temporary manipulation of the status word. This helper is
1642 // not needed for x86-64. 1692 // not needed for x86-64.
1643 split64(Dest); 1693 split64(Dest);
1644 const SizeT MaxSrcs = 1; 1694 const SizeT MaxSrcs = 1;
1645 Type SrcType = Inst->getSrc(0)->getType(); 1695 Type SrcType = Inst->getSrc(0)->getType();
1646 InstCall *Call = makeHelperCall( 1696 InstCall *Call = makeHelperCall(
1647 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); 1697 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs);
1648 // TODO: Call the correct compiler-rt helper function. 1698 // TODO: Call the correct compiler-rt helper function.
1649 Call->addArg(Inst->getSrc(0)); 1699 Call->addArg(Inst->getSrc(0));
1650 lowerCall(Call); 1700 lowerCall(Call);
1651 } else { 1701 } else {
1652 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 1702 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1653 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 1703 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
1654 Variable *T_1 = makeReg(IceType_i32); 1704 Variable *T_1 = makeReg(IceType_i32);
1655 Variable *T_2 = makeReg(Dest->getType()); 1705 Variable *T_2 = makeReg(Dest->getType());
1656 _cvt(T_1, Src0RM); 1706 _cvt(T_1, Src0RM);
1657 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 1707 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
1658 _mov(Dest, T_2); 1708 _mov(Dest, T_2);
1659 T_2->setPreferredRegister(T_1, true); 1709 T_2->setPreferredRegister(T_1, true);
1660 } 1710 }
1661 break; 1711 break;
1662 case InstCast::Fptoui: 1712 case InstCast::Fptoui:
1663 if (Dest->getType() == IceType_i64 || Dest->getType() == IceType_i32) { 1713 if (isVectorType(Dest->getType())) {
1714 assert(Dest->getType() == IceType_v4i32 &&
1715 Inst->getSrc(0)->getType() == IceType_v4f32);
1716 const SizeT MaxSrcs = 1;
1717 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs);
1718 Call->addArg(Inst->getSrc(0));
1719 lowerCall(Call);
1720 } else if (Dest->getType() == IceType_i64 ||
1721 Dest->getType() == IceType_i32) {
1664 // Use a helper for both x86-32 and x86-64. 1722 // Use a helper for both x86-32 and x86-64.
1665 split64(Dest); 1723 split64(Dest);
1666 const SizeT MaxSrcs = 1; 1724 const SizeT MaxSrcs = 1;
1667 Type DestType = Dest->getType(); 1725 Type DestType = Dest->getType();
1668 Type SrcType = Inst->getSrc(0)->getType(); 1726 Type SrcType = Inst->getSrc(0)->getType();
1669 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); 1727 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32");
1670 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); 1728 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d");
1671 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 1729 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64
1672 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; 1730 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring;
1673 // TODO: Call the correct compiler-rt helper function. 1731 // TODO: Call the correct compiler-rt helper function.
1674 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 1732 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
1675 Call->addArg(Inst->getSrc(0)); 1733 Call->addArg(Inst->getSrc(0));
1676 lowerCall(Call); 1734 lowerCall(Call);
1677 return; 1735 return;
1678 } else { 1736 } else {
1679 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 1737 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1680 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 1738 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
1681 Variable *T_1 = makeReg(IceType_i32); 1739 Variable *T_1 = makeReg(IceType_i32);
1682 Variable *T_2 = makeReg(Dest->getType()); 1740 Variable *T_2 = makeReg(Dest->getType());
1683 _cvt(T_1, Src0RM); 1741 _cvt(T_1, Src0RM);
1684 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 1742 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
1685 _mov(Dest, T_2); 1743 _mov(Dest, T_2);
1686 T_2->setPreferredRegister(T_1, true); 1744 T_2->setPreferredRegister(T_1, true);
1687 } 1745 }
1688 break; 1746 break;
1689 case InstCast::Sitofp: 1747 case InstCast::Sitofp:
1690 if (Inst->getSrc(0)->getType() == IceType_i64) { 1748 if (isVectorType(Dest->getType())) {
1749 assert(Dest->getType() == IceType_v4f32 &&
1750 Inst->getSrc(0)->getType() == IceType_v4i32);
1751 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1752 Variable *T = makeReg(Dest->getType());
1753 _cvt(T, Src0RM);
1754 _movp(Dest, T);
1755 } else if (Inst->getSrc(0)->getType() == IceType_i64) {
1691 // Use a helper for x86-32. 1756 // Use a helper for x86-32.
1692 const SizeT MaxSrcs = 1; 1757 const SizeT MaxSrcs = 1;
1693 Type DestType = Dest->getType(); 1758 Type DestType = Dest->getType();
1694 InstCall *Call = makeHelperCall( 1759 InstCall *Call = makeHelperCall(
1695 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); 1760 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs);
1696 // TODO: Call the correct compiler-rt helper function. 1761 // TODO: Call the correct compiler-rt helper function.
1697 Call->addArg(Inst->getSrc(0)); 1762 Call->addArg(Inst->getSrc(0));
1698 lowerCall(Call); 1763 lowerCall(Call);
1699 return; 1764 return;
1700 } else { 1765 } else {
1701 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 1766 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
1702 // Sign-extend the operand. 1767 // Sign-extend the operand.
1703 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 1768 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2
1704 Variable *T_1 = makeReg(IceType_i32); 1769 Variable *T_1 = makeReg(IceType_i32);
1705 Variable *T_2 = makeReg(Dest->getType()); 1770 Variable *T_2 = makeReg(Dest->getType());
1706 if (Src0RM->getType() == IceType_i32) 1771 if (Src0RM->getType() == IceType_i32)
1707 _mov(T_1, Src0RM); 1772 _mov(T_1, Src0RM);
1708 else 1773 else
1709 _movsx(T_1, Src0RM); 1774 _movsx(T_1, Src0RM);
1710 _cvt(T_2, T_1); 1775 _cvt(T_2, T_1);
1711 _mov(Dest, T_2); 1776 _mov(Dest, T_2);
1712 } 1777 }
1713 break; 1778 break;
1714 case InstCast::Uitofp: { 1779 case InstCast::Uitofp: {
1715 Operand *Src0 = Inst->getSrc(0); 1780 Operand *Src0 = Inst->getSrc(0);
1716 if (Src0->getType() == IceType_i64 || Src0->getType() == IceType_i32) { 1781 if (isVectorType(Src0->getType())) {
1782 assert(Dest->getType() == IceType_v4f32 &&
1783 Src0->getType() == IceType_v4i32);
1784 const SizeT MaxSrcs = 1;
1785 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs);
1786 Call->addArg(Src0);
1787 lowerCall(Call);
1788 } else if (Src0->getType() == IceType_i64 ||
1789 Src0->getType() == IceType_i32) {
1717 // Use a helper for x86-32 and x86-64. Also use a helper for 1790 // Use a helper for x86-32 and x86-64. Also use a helper for
1718 // i32 on x86-32. 1791 // i32 on x86-32.
1719 const SizeT MaxSrcs = 1; 1792 const SizeT MaxSrcs = 1;
1720 Type DestType = Dest->getType(); 1793 Type DestType = Dest->getType();
1721 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); 1794 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32");
1722 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); 1795 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d");
1723 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod 1796 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod
1724 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; 1797 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring;
1725 // TODO: Call the correct compiler-rt helper function. 1798 // TODO: Call the correct compiler-rt helper function.
1726 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 1799 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
(...skipping 18 matching lines...) Expand all
1745 case InstCast::Bitcast: { 1818 case InstCast::Bitcast: {
1746 Operand *Src0 = Inst->getSrc(0); 1819 Operand *Src0 = Inst->getSrc(0);
1747 if (Dest->getType() == Src0->getType()) { 1820 if (Dest->getType() == Src0->getType()) {
1748 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); 1821 InstAssign *Assign = InstAssign::create(Func, Dest, Src0);
1749 lowerAssign(Assign); 1822 lowerAssign(Assign);
1750 return; 1823 return;
1751 } 1824 }
1752 switch (Dest->getType()) { 1825 switch (Dest->getType()) {
1753 default: 1826 default:
1754 llvm_unreachable("Unexpected Bitcast dest type"); 1827 llvm_unreachable("Unexpected Bitcast dest type");
1828 case IceType_i8: {
1829 assert(Src0->getType() == IceType_v8i1);
1830 InstCall *Call = makeHelperCall("Sz_bitcast_v8i1_to_i8", Dest, 1);
1831 Call->addArg(Src0);
1832 lowerCall(Call);
1833 } break;
1834 case IceType_i16: {
1835 assert(Src0->getType() == IceType_v16i1);
1836 InstCall *Call = makeHelperCall("Sz_bitcast_v16i1_to_i16", Dest, 1);
1837 Call->addArg(Src0);
1838 lowerCall(Call);
1839 } break;
1755 case IceType_i32: 1840 case IceType_i32:
1756 case IceType_f32: { 1841 case IceType_f32: {
1757 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 1842 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
1758 Type DestType = Dest->getType(); 1843 Type DestType = Dest->getType();
1759 Type SrcType = Src0RM->getType(); 1844 Type SrcType = Src0RM->getType();
1760 assert((DestType == IceType_i32 && SrcType == IceType_f32) || 1845 assert((DestType == IceType_i32 && SrcType == IceType_f32) ||
1761 (DestType == IceType_f32 && SrcType == IceType_i32)); 1846 (DestType == IceType_f32 && SrcType == IceType_i32));
1762 // a.i32 = bitcast b.f32 ==> 1847 // a.i32 = bitcast b.f32 ==>
1763 // t.f32 = b.f32 1848 // t.f32 = b.f32
1764 // s.f32 = spill t.f32 1849 // s.f32 = spill t.f32
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 _mov(T_Lo, loOperand(Src0)); 1908 _mov(T_Lo, loOperand(Src0));
1824 // Technically, the Spill is defined after the _store happens, but 1909 // Technically, the Spill is defined after the _store happens, but
1825 // SpillLo is considered a "use" of Spill so define Spill before it 1910 // SpillLo is considered a "use" of Spill so define Spill before it
1826 // is used. 1911 // is used.
1827 Context.insert(InstFakeDef::create(Func, Spill)); 1912 Context.insert(InstFakeDef::create(Func, Spill));
1828 _store(T_Lo, SpillLo); 1913 _store(T_Lo, SpillLo);
1829 _mov(T_Hi, hiOperand(Src0)); 1914 _mov(T_Hi, hiOperand(Src0));
1830 _store(T_Hi, SpillHi); 1915 _store(T_Hi, SpillHi);
1831 _movq(Dest, Spill); 1916 _movq(Dest, Spill);
1832 } break; 1917 } break;
1918 case IceType_v8i1: {
1919 assert(Src0->getType() == IceType_i8);
1920 InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1);
1921 Variable *Src0AsI32 = Func->makeVariable(IceType_i32, Context.getNode());
1922 // Arguments to functions are required to be at least 32 bits wide.
1923 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
1924 Call->addArg(Src0AsI32);
1925 lowerCall(Call);
1926 } break;
1927 case IceType_v16i1: {
1928 assert(Src0->getType() == IceType_i16);
1929 InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1);
1930 Variable *Src0AsI32 = Func->makeVariable(IceType_i32, Context.getNode());
1931 // Arguments to functions are required to be at least 32 bits wide.
1932 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
1933 Call->addArg(Src0AsI32);
1934 lowerCall(Call);
1935 } break;
1936 case IceType_v8i16:
1937 case IceType_v16i8:
1938 case IceType_v4i32:
1939 case IceType_v4f32: {
1940 _movp(Dest, legalizeToVar(Src0));
1941 } break;
1833 } 1942 }
1834 break; 1943 break;
1835 } 1944 }
1836 } 1945 }
1837 } 1946 }
1838 1947
1839 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { 1948 void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
1840 Operand *Src0 = Inst->getSrc(0); 1949 Operand *Src0 = Inst->getSrc(0);
1841 Operand *Src1 = Inst->getSrc(1); 1950 Operand *Src1 = Inst->getSrc(1);
1842 Variable *Dest = Inst->getDest(); 1951 Variable *Dest = Inst->getDest();
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
2868 _br(Inst->getLabelDefault()); 2977 _br(Inst->getLabelDefault());
2869 } 2978 }
2870 2979
2871 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { 2980 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) {
2872 const SizeT MaxSrcs = 0; 2981 const SizeT MaxSrcs = 0;
2873 Variable *Dest = NULL; 2982 Variable *Dest = NULL;
2874 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); 2983 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs);
2875 lowerCall(Call); 2984 lowerCall(Call);
2876 } 2985 }
2877 2986
2987 Variable *TargetX8632::makeVectorOfZeros(Type Ty, int32_t RegNum) {
2988 // There is no support for loading or emitting vector constants, so
2989 // this value is initialized using register operations.
2990 Variable *Reg = makeReg(Ty, RegNum);
2991 // Insert a FakeDef, since otherwise the live range of Reg might
2992 // be overestimated.
2993 Context.insert(InstFakeDef::create(Func, Reg));
2994 _pxor(Reg, Reg);
2995 return Reg;
2996 }
2997
2998 Variable *TargetX8632::makeVectorOfOnes(Type Ty, int32_t RegNum) {
2999 // There is no support for loading or emitting vector constants, so
3000 // this value is initialized using register operations.
3001 Variable *Dest = makeVectorOfZeros(Ty, RegNum);
3002 Variable *MinusOne = makeReg(Ty);
3003 // Insert a FakeDef so the live range of MinusOne is not overestimated.
3004 Context.insert(InstFakeDef::create(Func, MinusOne));
3005 _pcmpeq(MinusOne, MinusOne);
3006 _psub(Dest, MinusOne);
3007 return Dest;
3008 }
3009
2878 // Helper for legalize() to emit the right code to lower an operand to a 3010 // Helper for legalize() to emit the right code to lower an operand to a
2879 // register of the appropriate type. 3011 // register of the appropriate type.
2880 Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) { 3012 Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) {
2881 Type Ty = Src->getType(); 3013 Type Ty = Src->getType();
2882 Variable *Reg = makeReg(Ty, RegNum); 3014 Variable *Reg = makeReg(Ty, RegNum);
2883 if (isVectorType(Ty)) { 3015 if (isVectorType(Ty)) {
2884 _movp(Reg, Src); 3016 _movp(Reg, Src);
2885 } else { 3017 } else {
2886 _mov(Reg, Src); 3018 _mov(Reg, Src);
2887 } 3019 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2930 // uninitialized register; however, using an uninitialized register 3062 // uninitialized register; however, using an uninitialized register
2931 // results in less predictable code. 3063 // results in less predictable code.
2932 // 3064 //
2933 // If in the future the implementation is changed to lower undef 3065 // If in the future the implementation is changed to lower undef
2934 // values to uninitialized registers, a FakeDef will be needed: 3066 // values to uninitialized registers, a FakeDef will be needed:
2935 // Context.insert(InstFakeDef::create(Func, Reg)); 3067 // Context.insert(InstFakeDef::create(Func, Reg));
2936 // This is in order to ensure that the live range of Reg is not 3068 // This is in order to ensure that the live range of Reg is not
2937 // overestimated. If the constant being lowered is a 64 bit value, 3069 // overestimated. If the constant being lowered is a 64 bit value,
2938 // then the result should be split and the lo and hi components will 3070 // then the result should be split and the lo and hi components will
2939 // need to go in uninitialized registers. 3071 // need to go in uninitialized registers.
2940 3072 if (isVectorType(From->getType()))
2941 if (isVectorType(From->getType())) { 3073 return makeVectorOfZeros(From->getType());
2942 // There is no support for loading or emitting vector constants, so 3074 From = Ctx->getConstantZero(From->getType());
2943 // undef values are instead initialized in registers.
2944 Variable *Reg = makeReg(From->getType(), RegNum);
2945 // Insert a FakeDef, since otherwise the live range of Reg might
2946 // be overestimated.
2947 Context.insert(InstFakeDef::create(Func, Reg));
2948 _pxor(Reg, Reg);
2949 return Reg;
2950 } else {
2951 From = Ctx->getConstantZero(From->getType());
2952 }
2953 } 3075 }
2954 // There should be no constants of vector type (other than undef). 3076 // There should be no constants of vector type (other than undef).
2955 assert(!isVectorType(From->getType())); 3077 assert(!isVectorType(From->getType()));
2956 bool NeedsReg = false; 3078 bool NeedsReg = false;
2957 if (!(Allowed & Legal_Imm)) 3079 if (!(Allowed & Legal_Imm))
2958 // Immediate specifically not allowed 3080 // Immediate specifically not allowed
2959 NeedsReg = true; 3081 NeedsReg = true;
2960 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper 3082 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper
2961 // emitter is used. 3083 // emitter is used.
2962 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) 3084 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From))
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 for (SizeT i = 0; i < Size; ++i) { 3321 for (SizeT i = 0; i < Size; ++i) {
3200 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 3322 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
3201 } 3323 }
3202 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 3324 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
3203 } 3325 }
3204 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName 3326 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName
3205 << "\n"; 3327 << "\n";
3206 } 3328 }
3207 3329
3208 } // end of namespace Ice 3330 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | tests_lit/llvm2ice_tests/vector-bitcast.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698