OLD | NEW |
---|---|
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); | 150 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); |
151 ICEINSTICMP_TABLE; | 151 ICEINSTICMP_TABLE; |
152 #undef X | 152 #undef X |
153 } | 153 } |
154 | 154 |
155 // Validate the enum values in ICETYPEX8632_TABLE. | 155 // Validate the enum values in ICETYPEX8632_TABLE. |
156 { | 156 { |
157 // Define a temporary set of enum values based on low-level | 157 // Define a temporary set of enum values based on low-level |
158 // table entries. | 158 // table entries. |
159 enum _tmp_enum { | 159 enum _tmp_enum { |
160 #define X(tag, cvt, sdss, width) _tmp_##tag, | 160 #define X(tag, cvt, sdss, pack, width) _tmp_##tag, |
161 ICETYPEX8632_TABLE | 161 ICETYPEX8632_TABLE |
162 #undef X | 162 #undef X |
163 _num | 163 _num |
164 }; | 164 }; |
165 // Define a set of constants based on high-level table entries. | 165 // Define a set of constants based on high-level table entries. |
166 #define X(tag, size, align, elts, elty, str) \ | 166 #define X(tag, size, align, elts, elty, str) \ |
167 static const int _table1_##tag = tag; | 167 static const int _table1_##tag = tag; |
168 ICETYPE_TABLE; | 168 ICETYPE_TABLE; |
169 #undef X | 169 #undef X |
170 // Define a set of constants based on low-level table entries, | 170 // Define a set of constants based on low-level table entries, |
171 // and ensure the table entry keys are consistent. | 171 // and ensure the table entry keys are consistent. |
172 #define X(tag, cvt, sdss, width) \ | 172 #define X(tag, cvt, sdss, pack, width) \ |
173 static const int _table2_##tag = _tmp_##tag; \ | 173 static const int _table2_##tag = _tmp_##tag; \ |
174 STATIC_ASSERT(_table1_##tag == _table2_##tag); | 174 STATIC_ASSERT(_table1_##tag == _table2_##tag); |
175 ICETYPEX8632_TABLE; | 175 ICETYPEX8632_TABLE; |
176 #undef X | 176 #undef X |
177 // Repeat the static asserts with respect to the high-level | 177 // Repeat the static asserts with respect to the high-level |
178 // table entries in case the high-level table has extra entries. | 178 // table entries in case the high-level table has extra entries. |
179 #define X(tag, size, align, elts, elty, str) \ | 179 #define X(tag, size, align, elts, elty, str) \ |
180 STATIC_ASSERT(_table1_##tag == _table2_##tag); | 180 STATIC_ASSERT(_table1_##tag == _table2_##tag); |
181 ICETYPE_TABLE; | 181 ICETYPE_TABLE; |
182 #undef X | 182 #undef X |
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1447 if (ScratchRegs[i]) | 1447 if (ScratchRegs[i]) |
1448 KilledRegs.push_back(Func->getTarget()->getPhysicalRegister(i)); | 1448 KilledRegs.push_back(Func->getTarget()->getPhysicalRegister(i)); |
1449 } | 1449 } |
1450 Context.insert(InstFakeKill::create(Func, KilledRegs, NewCall)); | 1450 Context.insert(InstFakeKill::create(Func, KilledRegs, NewCall)); |
1451 | 1451 |
1452 // Generate a FakeUse to keep the call live if necessary. | 1452 // Generate a FakeUse to keep the call live if necessary. |
1453 if (Instr->hasSideEffects() && ReturnReg) { | 1453 if (Instr->hasSideEffects() && ReturnReg) { |
1454 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); | 1454 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); |
1455 Context.insert(FakeUse); | 1455 Context.insert(FakeUse); |
1456 } | 1456 } |
1457 | 1457 |
1458 if (!Dest) | 1458 if (!Dest) |
1459 return; | 1459 return; |
1460 | 1460 |
1461 // Assign the result of the call to Dest. | 1461 // Assign the result of the call to Dest. |
1462 if (ReturnReg) { | 1462 if (ReturnReg) { |
1463 if (ReturnRegHi) { | 1463 if (ReturnRegHi) { |
1464 assert(Dest->getType() == IceType_i64); | 1464 assert(Dest->getType() == IceType_i64); |
1465 split64(Dest); | 1465 split64(Dest); |
1466 Variable *DestLo = Dest->getLo(); | 1466 Variable *DestLo = Dest->getLo(); |
1467 Variable *DestHi = Dest->getHi(); | 1467 Variable *DestHi = Dest->getHi(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1513 if (Src0RM->getType() == IceType_i32) | 1513 if (Src0RM->getType() == IceType_i32) |
1514 _mov(T_Lo, Src0RM); | 1514 _mov(T_Lo, Src0RM); |
1515 else | 1515 else |
1516 _movsx(T_Lo, Src0RM); | 1516 _movsx(T_Lo, Src0RM); |
1517 _mov(DestLo, T_Lo); | 1517 _mov(DestLo, T_Lo); |
1518 Variable *T_Hi = NULL; | 1518 Variable *T_Hi = NULL; |
1519 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); | 1519 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); |
1520 _mov(T_Hi, T_Lo); | 1520 _mov(T_Hi, T_Lo); |
1521 _sar(T_Hi, Shift); | 1521 _sar(T_Hi, Shift); |
1522 _mov(DestHi, T_Hi); | 1522 _mov(DestHi, T_Hi); |
1523 } else if (isVectorType(Dest->getType())) { | |
1524 Type DestTy = Dest->getType(); | |
1525 if (DestTy == IceType_v16i8) { | |
1526 // onemask = materialize(1,1,...); dst = (src & onemask) > 0 | |
1527 Variable *OneMask = makeReg(DestTy); | |
Jim Stichnoth
2014/07/14 18:33:12
Seems to be substantial code duplication across th
wala
2014/07/15 22:52:22
Done.
| |
1528 Context.insert(InstFakeDef::create(Func, OneMask)); | |
1529 _pxor(OneMask, OneMask); | |
1530 Variable *MinusOne = makeReg(DestTy); | |
1531 Context.insert(InstFakeDef::create(Func, MinusOne)); | |
1532 _pcmpeq(MinusOne, MinusOne); | |
1533 _psub(OneMask, MinusOne); | |
1534 Variable *T = makeReg(DestTy); | |
1535 _movp(T, Src0RM); | |
1536 _pand(T, OneMask); | |
1537 Variable *Zeros = makeReg(DestTy); | |
1538 Context.insert(InstFakeDef::create(Func, Zeros)); | |
1539 _pxor(Zeros, Zeros); | |
1540 _pcmpgt(T, Zeros); | |
1541 _movp(Dest, T); | |
1542 } else { | |
1543 // width = width(elty) - 1; dest = (src << width) >> width | |
1544 SizeT ShiftAmount = 8 * typeWidthInBytes(typeElementType(DestTy)) - 1; | |
Jim Stichnoth
2014/07/14 18:33:12
Use CHAR_BIT instead of 8
wala
2014/07/15 22:52:22
Since CHAR_BIT depends on the machine the code is
Jim Stichnoth
2014/07/15 23:15:44
Good point, thanks.
| |
1545 Constant *ShiftConstant = Ctx->getConstantInt(IceType_i8, ShiftAmount); | |
1546 Variable *T = makeReg(DestTy); | |
1547 _movp(T, Src0RM); | |
1548 _psll(T, ShiftConstant); | |
1549 _psra(T, ShiftConstant); | |
1550 _movp(Dest, T); | |
1551 } | |
1523 } else { | 1552 } else { |
1524 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and | 1553 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and |
1525 // also copy to the high operand of a 64-bit variable. | 1554 // also copy to the high operand of a 64-bit variable. |
1526 // t1 = movsx src; dst = t1 | 1555 // t1 = movsx src; dst = t1 |
1527 Variable *T = makeReg(Dest->getType()); | 1556 Variable *T = makeReg(Dest->getType()); |
1528 _movsx(T, Src0RM); | 1557 _movsx(T, Src0RM); |
1529 _mov(Dest, T); | 1558 _mov(Dest, T); |
1530 } | 1559 } |
1531 break; | 1560 break; |
1532 } | 1561 } |
(...skipping 11 matching lines...) Expand all Loading... | |
1544 _movzx(Tmp, Src0RM); | 1573 _movzx(Tmp, Src0RM); |
1545 _mov(DestLo, Tmp); | 1574 _mov(DestLo, Tmp); |
1546 _mov(DestHi, Zero); | 1575 _mov(DestHi, Zero); |
1547 } else if (Src0RM->getType() == IceType_i1) { | 1576 } else if (Src0RM->getType() == IceType_i1) { |
1548 // t = Src0RM; t &= 1; Dest = t | 1577 // t = Src0RM; t &= 1; Dest = t |
1549 Operand *One = Ctx->getConstantInt(IceType_i32, 1); | 1578 Operand *One = Ctx->getConstantInt(IceType_i32, 1); |
1550 Variable *T = makeReg(IceType_i32); | 1579 Variable *T = makeReg(IceType_i32); |
1551 _movzx(T, Src0RM); | 1580 _movzx(T, Src0RM); |
1552 _and(T, One); | 1581 _and(T, One); |
1553 _mov(Dest, T); | 1582 _mov(Dest, T); |
1583 } else if (isVectorType(Dest->getType())) { | |
1584 // onemask = materialize(1,1,...); dst = src & onemask | |
1585 Type DestTy = Dest->getType(); | |
1586 Variable *OneMask = makeReg(DestTy); | |
1587 Context.insert(InstFakeDef::create(Func, OneMask)); | |
1588 _pxor(OneMask, OneMask); | |
1589 Variable *MinusOne = makeReg(DestTy); | |
1590 Context.insert(InstFakeDef::create(Func, MinusOne)); | |
1591 _pcmpeq(MinusOne, MinusOne); | |
1592 _psub(OneMask, MinusOne); | |
1593 Variable *T = makeReg(DestTy); | |
1594 _movp(T, Src0RM); | |
1595 _pand(T, OneMask); | |
1596 _movp(Dest, T); | |
1554 } else { | 1597 } else { |
1555 // t1 = movzx src; dst = t1 | 1598 // t1 = movzx src; dst = t1 |
1556 Variable *T = makeReg(Dest->getType()); | 1599 Variable *T = makeReg(Dest->getType()); |
1557 _movzx(T, Src0RM); | 1600 _movzx(T, Src0RM); |
1558 _mov(Dest, T); | 1601 _mov(Dest, T); |
1559 } | 1602 } |
1560 break; | 1603 break; |
1561 } | 1604 } |
1562 case InstCast::Trunc: { | 1605 case InstCast::Trunc: { |
1563 Operand *Src0 = Inst->getSrc(0); | 1606 if (isVectorType(Dest->getType())) { |
1564 if (Src0->getType() == IceType_i64) | 1607 // onemask = materialize(1,1,...); dst = src & onemask |
1565 Src0 = loOperand(Src0); | 1608 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1566 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 1609 Type Src0Ty = Src0RM->getType(); |
1567 // t1 = trunc Src0RM; Dest = t1 | 1610 Variable *OneMask = makeReg(Src0Ty); |
1568 Variable *T = NULL; | 1611 Context.insert(InstFakeDef::create(Func, OneMask)); |
1569 _mov(T, Src0RM); | 1612 _pxor(OneMask, OneMask); |
1570 _mov(Dest, T); | 1613 Variable *MinusOne = makeReg(Src0Ty); |
1614 Context.insert(InstFakeDef::create(Func, MinusOne)); | |
1615 _pcmpeq(MinusOne, MinusOne); | |
1616 _psub(OneMask, MinusOne); | |
1617 Variable *T = makeReg(Dest->getType()); | |
1618 _movp(T, Src0RM); | |
1619 _pand(T, OneMask); | |
1620 _movp(Dest, T); | |
1621 } else { | |
1622 Operand *Src0 = Inst->getSrc(0); | |
1623 if (Src0->getType() == IceType_i64) | |
1624 Src0 = loOperand(Src0); | |
1625 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
1626 // t1 = trunc Src0RM; Dest = t1 | |
1627 Variable *T = NULL; | |
1628 _mov(T, Src0RM); | |
1629 _mov(Dest, T); | |
1630 } | |
1571 break; | 1631 break; |
1572 } | 1632 } |
1573 case InstCast::Fptrunc: | 1633 case InstCast::Fptrunc: |
1574 case InstCast::Fpext: { | 1634 case InstCast::Fpext: { |
1575 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1635 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1576 // t1 = cvt Src0RM; Dest = t1 | 1636 // t1 = cvt Src0RM; Dest = t1 |
1577 Variable *T = makeReg(Dest->getType()); | 1637 Variable *T = makeReg(Dest->getType()); |
1578 _cvt(T, Src0RM); | 1638 _cvt(T, Src0RM); |
1579 _mov(Dest, T); | 1639 _mov(Dest, T); |
1580 break; | 1640 break; |
1581 } | 1641 } |
1582 case InstCast::Fptosi: | 1642 case InstCast::Fptosi: |
1583 if (Dest->getType() == IceType_i64) { | 1643 if (isVectorType(Dest->getType())) { |
1644 assert(Dest->getType() == IceType_v4i32 && | |
1645 Inst->getSrc(0)->getType() == IceType_v4f32); | |
1646 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1647 Variable *T = makeReg(Dest->getType()); | |
1648 _cvt(T, Src0RM); | |
Jim Stichnoth
2014/07/14 18:33:12
Looks plausible, I guess, but I'm looking forward
wala
2014/07/14 20:52:22
This is what LLVM does.
| |
1649 _movp(Dest, T); | |
1650 } else if (Dest->getType() == IceType_i64) { | |
1584 // Use a helper for converting floating-point values to 64-bit | 1651 // Use a helper for converting floating-point values to 64-bit |
1585 // integers. SSE2 appears to have no way to convert from xmm | 1652 // integers. SSE2 appears to have no way to convert from xmm |
1586 // registers to something like the edx:eax register pair, and | 1653 // registers to something like the edx:eax register pair, and |
1587 // gcc and clang both want to use x87 instructions complete with | 1654 // gcc and clang both want to use x87 instructions complete with |
1588 // temporary manipulation of the status word. This helper is | 1655 // temporary manipulation of the status word. This helper is |
1589 // not needed for x86-64. | 1656 // not needed for x86-64. |
1590 split64(Dest); | 1657 split64(Dest); |
1591 const SizeT MaxSrcs = 1; | 1658 const SizeT MaxSrcs = 1; |
1592 Type SrcType = Inst->getSrc(0)->getType(); | 1659 Type SrcType = Inst->getSrc(0)->getType(); |
1593 InstCall *Call = makeHelperCall( | 1660 InstCall *Call = makeHelperCall( |
1594 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); | 1661 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); |
1595 // TODO: Call the correct compiler-rt helper function. | 1662 // TODO: Call the correct compiler-rt helper function. |
1596 Call->addArg(Inst->getSrc(0)); | 1663 Call->addArg(Inst->getSrc(0)); |
1597 lowerCall(Call); | 1664 lowerCall(Call); |
1598 } else { | 1665 } else { |
1599 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1666 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1600 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 1667 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
1601 Variable *T_1 = makeReg(IceType_i32); | 1668 Variable *T_1 = makeReg(IceType_i32); |
1602 Variable *T_2 = makeReg(Dest->getType()); | 1669 Variable *T_2 = makeReg(Dest->getType()); |
1603 _cvt(T_1, Src0RM); | 1670 _cvt(T_1, Src0RM); |
1604 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 1671 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
1605 _mov(Dest, T_2); | 1672 _mov(Dest, T_2); |
1606 T_2->setPreferredRegister(T_1, true); | 1673 T_2->setPreferredRegister(T_1, true); |
1607 } | 1674 } |
1608 break; | 1675 break; |
1609 case InstCast::Fptoui: | 1676 case InstCast::Fptoui: |
1610 if (Dest->getType() == IceType_i64 || Dest->getType() == IceType_i32) { | 1677 if (isVectorType(Dest->getType())) { |
1678 assert(Dest->getType() == IceType_v4i32 && | |
1679 Inst->getSrc(0)->getType() == IceType_v4f32); | |
1680 const SizeT MaxSrcs = 1; | |
1681 InstCall *Call = makeHelperCall("__fptoui_v4f32", Dest, MaxSrcs); | |
Jim Stichnoth
2014/07/14 18:33:12
Here and elsewhere, the helper function will be pa
wala
2014/07/14 20:52:22
Such identifiers are reserved to the implementatio
Jim Stichnoth
2014/07/14 22:23:30
I wouldn't say Subzero will be the *complete* impl
wala
2014/07/15 22:52:21
Done.
All helpers have a Sz_ prefix.
| |
1682 Call->addArg(Inst->getSrc(0)); | |
1683 lowerCall(Call); | |
1684 } else if (Dest->getType() == IceType_i64 || | |
1685 Dest->getType() == IceType_i32) { | |
1611 // Use a helper for both x86-32 and x86-64. | 1686 // Use a helper for both x86-32 and x86-64. |
1612 split64(Dest); | 1687 split64(Dest); |
1613 const SizeT MaxSrcs = 1; | 1688 const SizeT MaxSrcs = 1; |
1614 Type DestType = Dest->getType(); | 1689 Type DestType = Dest->getType(); |
1615 Type SrcType = Inst->getSrc(0)->getType(); | 1690 Type SrcType = Inst->getSrc(0)->getType(); |
1616 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); | 1691 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); |
1617 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); | 1692 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); |
1618 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 | 1693 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 |
1619 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; | 1694 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; |
1620 // TODO: Call the correct compiler-rt helper function. | 1695 // TODO: Call the correct compiler-rt helper function. |
1621 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 1696 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
1622 Call->addArg(Inst->getSrc(0)); | 1697 Call->addArg(Inst->getSrc(0)); |
1623 lowerCall(Call); | 1698 lowerCall(Call); |
1624 return; | 1699 return; |
1625 } else { | 1700 } else { |
1626 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1701 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1627 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 1702 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
1628 Variable *T_1 = makeReg(IceType_i32); | 1703 Variable *T_1 = makeReg(IceType_i32); |
1629 Variable *T_2 = makeReg(Dest->getType()); | 1704 Variable *T_2 = makeReg(Dest->getType()); |
1630 _cvt(T_1, Src0RM); | 1705 _cvt(T_1, Src0RM); |
1631 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 1706 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
1632 _mov(Dest, T_2); | 1707 _mov(Dest, T_2); |
1633 T_2->setPreferredRegister(T_1, true); | 1708 T_2->setPreferredRegister(T_1, true); |
1634 } | 1709 } |
1635 break; | 1710 break; |
1636 case InstCast::Sitofp: | 1711 case InstCast::Sitofp: |
1637 if (Inst->getSrc(0)->getType() == IceType_i64) { | 1712 if (isVectorType(Dest->getType())) { |
1713 assert(Dest->getType() == IceType_v4f32 && | |
1714 Inst->getSrc(0)->getType() == IceType_v4i32); | |
1715 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1716 Variable *T = makeReg(Dest->getType()); | |
1717 _cvt(T, Src0RM); | |
1718 _movp(Dest, T); | |
1719 } else if (Inst->getSrc(0)->getType() == IceType_i64) { | |
1638 // Use a helper for x86-32. | 1720 // Use a helper for x86-32. |
1639 const SizeT MaxSrcs = 1; | 1721 const SizeT MaxSrcs = 1; |
1640 Type DestType = Dest->getType(); | 1722 Type DestType = Dest->getType(); |
1641 InstCall *Call = makeHelperCall( | 1723 InstCall *Call = makeHelperCall( |
1642 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); | 1724 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); |
1643 // TODO: Call the correct compiler-rt helper function. | 1725 // TODO: Call the correct compiler-rt helper function. |
1644 Call->addArg(Inst->getSrc(0)); | 1726 Call->addArg(Inst->getSrc(0)); |
1645 lowerCall(Call); | 1727 lowerCall(Call); |
1646 return; | 1728 return; |
1647 } else { | 1729 } else { |
1648 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1730 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1649 // Sign-extend the operand. | 1731 // Sign-extend the operand. |
1650 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 1732 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
1651 Variable *T_1 = makeReg(IceType_i32); | 1733 Variable *T_1 = makeReg(IceType_i32); |
1652 Variable *T_2 = makeReg(Dest->getType()); | 1734 Variable *T_2 = makeReg(Dest->getType()); |
1653 if (Src0RM->getType() == IceType_i32) | 1735 if (Src0RM->getType() == IceType_i32) |
1654 _mov(T_1, Src0RM); | 1736 _mov(T_1, Src0RM); |
1655 else | 1737 else |
1656 _movsx(T_1, Src0RM); | 1738 _movsx(T_1, Src0RM); |
1657 _cvt(T_2, T_1); | 1739 _cvt(T_2, T_1); |
1658 _mov(Dest, T_2); | 1740 _mov(Dest, T_2); |
1659 } | 1741 } |
1660 break; | 1742 break; |
1661 case InstCast::Uitofp: { | 1743 case InstCast::Uitofp: { |
1662 Operand *Src0 = Inst->getSrc(0); | 1744 Operand *Src0 = Inst->getSrc(0); |
1663 if (Src0->getType() == IceType_i64 || Src0->getType() == IceType_i32) { | 1745 if (isVectorType(Src0->getType())) { |
1746 assert(Dest->getType() == IceType_v4f32 && | |
1747 Src0->getType() == IceType_v4i32); | |
1748 const SizeT MaxSrcs = 1; | |
1749 InstCall *Call = makeHelperCall("__uitofp_v4i32", Dest, MaxSrcs); | |
1750 Call->addArg(Src0); | |
1751 lowerCall(Call); | |
1752 } else if (Src0->getType() == IceType_i64 || | |
1753 Src0->getType() == IceType_i32) { | |
1664 // Use a helper for x86-32 and x86-64. Also use a helper for | 1754 // Use a helper for x86-32 and x86-64. Also use a helper for |
1665 // i32 on x86-32. | 1755 // i32 on x86-32. |
1666 const SizeT MaxSrcs = 1; | 1756 const SizeT MaxSrcs = 1; |
1667 Type DestType = Dest->getType(); | 1757 Type DestType = Dest->getType(); |
1668 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); | 1758 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); |
1669 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); | 1759 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); |
1670 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod | 1760 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod |
1671 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; | 1761 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; |
1672 // TODO: Call the correct compiler-rt helper function. | 1762 // TODO: Call the correct compiler-rt helper function. |
1673 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 1763 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
(...skipping 18 matching lines...) Expand all Loading... | |
1692 case InstCast::Bitcast: { | 1782 case InstCast::Bitcast: { |
1693 Operand *Src0 = Inst->getSrc(0); | 1783 Operand *Src0 = Inst->getSrc(0); |
1694 if (Dest->getType() == Src0->getType()) { | 1784 if (Dest->getType() == Src0->getType()) { |
1695 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | 1785 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); |
1696 lowerAssign(Assign); | 1786 lowerAssign(Assign); |
1697 return; | 1787 return; |
1698 } | 1788 } |
1699 switch (Dest->getType()) { | 1789 switch (Dest->getType()) { |
1700 default: | 1790 default: |
1701 llvm_unreachable("Unexpected Bitcast dest type"); | 1791 llvm_unreachable("Unexpected Bitcast dest type"); |
1792 case IceType_i8: { | |
1793 assert(Src0->getType() == IceType_v8i1); | |
1794 InstCall *Call = makeHelperCall("__bitcast_v8i1_to_i8", Dest, 1); | |
1795 Call->addArg(Src0); | |
1796 lowerCall(Call); | |
1797 } break; | |
1798 case IceType_i16: { | |
1799 assert(Src0->getType() == IceType_v16i1); | |
1800 InstCall *Call = makeHelperCall("__bitcast_v16i1_to_i16", Dest, 1); | |
1801 Call->addArg(Src0); | |
1802 lowerCall(Call); | |
1803 } break; | |
1702 case IceType_i32: | 1804 case IceType_i32: |
1703 case IceType_f32: { | 1805 case IceType_f32: { |
1704 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 1806 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
1705 Type DestType = Dest->getType(); | 1807 Type DestType = Dest->getType(); |
1706 Type SrcType = Src0RM->getType(); | 1808 Type SrcType = Src0RM->getType(); |
1707 assert((DestType == IceType_i32 && SrcType == IceType_f32) || | 1809 assert((DestType == IceType_i32 && SrcType == IceType_f32) || |
1708 (DestType == IceType_f32 && SrcType == IceType_i32)); | 1810 (DestType == IceType_f32 && SrcType == IceType_i32)); |
1709 // a.i32 = bitcast b.f32 ==> | 1811 // a.i32 = bitcast b.f32 ==> |
1710 // t.f32 = b.f32 | 1812 // t.f32 = b.f32 |
1711 // s.f32 = spill t.f32 | 1813 // s.f32 = spill t.f32 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1770 _mov(T_Lo, loOperand(Src0)); | 1872 _mov(T_Lo, loOperand(Src0)); |
1771 // Technically, the Spill is defined after the _store happens, but | 1873 // Technically, the Spill is defined after the _store happens, but |
1772 // SpillLo is considered a "use" of Spill so define Spill before it | 1874 // SpillLo is considered a "use" of Spill so define Spill before it |
1773 // is used. | 1875 // is used. |
1774 Context.insert(InstFakeDef::create(Func, Spill)); | 1876 Context.insert(InstFakeDef::create(Func, Spill)); |
1775 _store(T_Lo, SpillLo); | 1877 _store(T_Lo, SpillLo); |
1776 _mov(T_Hi, hiOperand(Src0)); | 1878 _mov(T_Hi, hiOperand(Src0)); |
1777 _store(T_Hi, SpillHi); | 1879 _store(T_Hi, SpillHi); |
1778 _movq(Dest, Spill); | 1880 _movq(Dest, Spill); |
1779 } break; | 1881 } break; |
1882 case IceType_v8i1: { | |
1883 assert(Src0->getType() == IceType_i8); | |
1884 InstCall *Call = makeHelperCall("__bitcast_i8_to_v8i1", Dest, 1); | |
1885 Variable *Src0AsI32 = Func->makeVariable(IceType_i32, Context.getNode()); | |
1886 // Arguments to functions are required to be at least 32 bits wide. | |
1887 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); | |
1888 Call->addArg(Src0AsI32); | |
1889 lowerCall(Call); | |
1890 } break; | |
1891 case IceType_v16i1: { | |
1892 assert(Src0->getType() == IceType_i16); | |
1893 InstCall *Call = makeHelperCall("__bitcast_i16_to_v16i1", Dest, 1); | |
1894 Variable *Src0AsI32 = Func->makeVariable(IceType_i32, Context.getNode()); | |
1895 // Arguments to functions are required to be at least 32 bits wide. | |
1896 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); | |
1897 Call->addArg(Src0AsI32); | |
1898 lowerCall(Call); | |
1899 } break; | |
1900 case IceType_v8i16: | |
1901 case IceType_v16i8: | |
1902 case IceType_v4i32: | |
1903 case IceType_v4f32: { | |
1904 _movp(Dest, legalizeToVar(Src0)); | |
1905 } break; | |
1780 } | 1906 } |
1781 break; | 1907 break; |
1782 } | 1908 } |
1783 } | 1909 } |
1784 } | 1910 } |
1785 | 1911 |
1786 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { | 1912 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { |
1787 Operand *Src0 = Inst->getSrc(0); | 1913 Operand *Src0 = Inst->getSrc(0); |
1788 Operand *Src1 = Inst->getSrc(1); | 1914 Operand *Src1 = Inst->getSrc(1); |
1789 Variable *Dest = Inst->getDest(); | 1915 Variable *Dest = Inst->getDest(); |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2838 for (SizeT i = 0; i < Size; ++i) { | 2964 for (SizeT i = 0; i < Size; ++i) { |
2839 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 2965 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
2840 } | 2966 } |
2841 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 2967 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
2842 } | 2968 } |
2843 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 2969 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
2844 << "\n"; | 2970 << "\n"; |
2845 } | 2971 } |
2846 | 2972 |
2847 } // end of namespace Ice | 2973 } // end of namespace Ice |
OLD | NEW |