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

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: Fix formatting 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
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698