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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 613483002: Change some explicit type checks into using helper functions. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: rename Created 6 years, 2 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/IceRegistersX8632.h ('k') | src/IceTypes.h » ('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 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 _mov(Dest, T); 1574 _mov(Dest, T);
1575 break; 1575 break;
1576 case InstArithmetic::Mul: 1576 case InstArithmetic::Mul:
1577 // TODO: Optimize for llvm::isa<Constant>(Src1) 1577 // TODO: Optimize for llvm::isa<Constant>(Src1)
1578 // TODO: Strength-reduce multiplications by a constant, 1578 // TODO: Strength-reduce multiplications by a constant,
1579 // particularly -1 and powers of 2. Advanced: use lea to 1579 // particularly -1 and powers of 2. Advanced: use lea to
1580 // multiply by 3, 5, 9. 1580 // multiply by 3, 5, 9.
1581 // 1581 //
1582 // The 8-bit version of imul only allows the form "imul r/m8" 1582 // The 8-bit version of imul only allows the form "imul r/m8"
1583 // where T must be in eax. 1583 // where T must be in eax.
1584 if (Dest->getType() == IceType_i8) 1584 if (isByteSizedArithType(Dest->getType()))
1585 _mov(T, Src0, RegX8632::Reg_eax); 1585 _mov(T, Src0, RegX8632::Reg_eax);
1586 else 1586 else
1587 _mov(T, Src0); 1587 _mov(T, Src0);
1588 _imul(T, Src1); 1588 _imul(T, Src1);
1589 _mov(Dest, T); 1589 _mov(Dest, T);
1590 break; 1590 break;
1591 case InstArithmetic::Shl: 1591 case InstArithmetic::Shl:
1592 _mov(T, Src0); 1592 _mov(T, Src0);
1593 if (!llvm::isa<Constant>(Src1)) 1593 if (!llvm::isa<Constant>(Src1))
1594 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); 1594 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx);
(...skipping 11 matching lines...) Expand all
1606 _mov(T, Src0); 1606 _mov(T, Src0);
1607 if (!llvm::isa<Constant>(Src1)) 1607 if (!llvm::isa<Constant>(Src1))
1608 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); 1608 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx);
1609 _sar(T, Src1); 1609 _sar(T, Src1);
1610 _mov(Dest, T); 1610 _mov(Dest, T);
1611 break; 1611 break;
1612 case InstArithmetic::Udiv: 1612 case InstArithmetic::Udiv:
1613 // div and idiv are the few arithmetic operators that do not allow 1613 // div and idiv are the few arithmetic operators that do not allow
1614 // immediates as the operand. 1614 // immediates as the operand.
1615 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1615 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1616 if (Dest->getType() == IceType_i8) { 1616 if (isByteSizedArithType(Dest->getType())) {
1617 Variable *T_ah = NULL; 1617 Variable *T_ah = NULL;
1618 Constant *Zero = Ctx->getConstantZero(IceType_i8); 1618 Constant *Zero = Ctx->getConstantZero(IceType_i8);
1619 _mov(T, Src0, RegX8632::Reg_eax); 1619 _mov(T, Src0, RegX8632::Reg_eax);
1620 _mov(T_ah, Zero, RegX8632::Reg_ah); 1620 _mov(T_ah, Zero, RegX8632::Reg_ah);
1621 _div(T, Src1, T_ah); 1621 _div(T, Src1, T_ah);
1622 _mov(Dest, T); 1622 _mov(Dest, T);
1623 } else { 1623 } else {
1624 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1624 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1625 _mov(T, Src0, RegX8632::Reg_eax); 1625 _mov(T, Src0, RegX8632::Reg_eax);
1626 _mov(T_edx, Zero, RegX8632::Reg_edx); 1626 _mov(T_edx, Zero, RegX8632::Reg_edx);
1627 _div(T, Src1, T_edx); 1627 _div(T, Src1, T_edx);
1628 _mov(Dest, T); 1628 _mov(Dest, T);
1629 } 1629 }
1630 break; 1630 break;
1631 case InstArithmetic::Sdiv: 1631 case InstArithmetic::Sdiv:
1632 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1632 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1633 if (Dest->getType() == IceType_i8) { 1633 if (isByteSizedArithType(Dest->getType())) {
1634 _mov(T, Src0, RegX8632::Reg_eax); 1634 _mov(T, Src0, RegX8632::Reg_eax);
1635 _cbwdq(T, T); 1635 _cbwdq(T, T);
1636 _idiv(T, Src1, T); 1636 _idiv(T, Src1, T);
1637 _mov(Dest, T); 1637 _mov(Dest, T);
1638 } else { 1638 } else {
1639 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); 1639 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
1640 _mov(T, Src0, RegX8632::Reg_eax); 1640 _mov(T, Src0, RegX8632::Reg_eax);
1641 _cbwdq(T_edx, T); 1641 _cbwdq(T_edx, T);
1642 _idiv(T, Src1, T_edx); 1642 _idiv(T, Src1, T_edx);
1643 _mov(Dest, T); 1643 _mov(Dest, T);
1644 } 1644 }
1645 break; 1645 break;
1646 case InstArithmetic::Urem: 1646 case InstArithmetic::Urem:
1647 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1647 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1648 if (Dest->getType() == IceType_i8) { 1648 if (isByteSizedArithType(Dest->getType())) {
1649 Variable *T_ah = NULL; 1649 Variable *T_ah = NULL;
1650 Constant *Zero = Ctx->getConstantZero(IceType_i8); 1650 Constant *Zero = Ctx->getConstantZero(IceType_i8);
1651 _mov(T, Src0, RegX8632::Reg_eax); 1651 _mov(T, Src0, RegX8632::Reg_eax);
1652 _mov(T_ah, Zero, RegX8632::Reg_ah); 1652 _mov(T_ah, Zero, RegX8632::Reg_ah);
1653 _div(T_ah, Src1, T); 1653 _div(T_ah, Src1, T);
1654 _mov(Dest, T_ah); 1654 _mov(Dest, T_ah);
1655 } else { 1655 } else {
1656 Constant *Zero = Ctx->getConstantZero(IceType_i32); 1656 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1657 _mov(T_edx, Zero, RegX8632::Reg_edx); 1657 _mov(T_edx, Zero, RegX8632::Reg_edx);
1658 _mov(T, Src0, RegX8632::Reg_eax); 1658 _mov(T, Src0, RegX8632::Reg_eax);
1659 _div(T_edx, Src1, T); 1659 _div(T_edx, Src1, T);
1660 _mov(Dest, T_edx); 1660 _mov(Dest, T_edx);
1661 } 1661 }
1662 break; 1662 break;
1663 case InstArithmetic::Srem: 1663 case InstArithmetic::Srem:
1664 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); 1664 Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
1665 if (Dest->getType() == IceType_i8) { 1665 if (isByteSizedArithType(Dest->getType())) {
1666 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah); 1666 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah);
1667 _mov(T, Src0, RegX8632::Reg_eax); 1667 _mov(T, Src0, RegX8632::Reg_eax);
1668 _cbwdq(T, T); 1668 _cbwdq(T, T);
1669 Context.insert(InstFakeDef::create(Func, T_ah)); 1669 Context.insert(InstFakeDef::create(Func, T_ah));
1670 _idiv(T_ah, Src1, T); 1670 _idiv(T_ah, Src1, T);
1671 _mov(Dest, T_ah); 1671 _mov(Dest, T_ah);
1672 } else { 1672 } else {
1673 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); 1673 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
1674 _mov(T, Src0, RegX8632::Reg_eax); 1674 _mov(T, Src0, RegX8632::Reg_eax);
1675 _cbwdq(T_edx, T); 1675 _cbwdq(T_edx, T);
(...skipping 17 matching lines...) Expand all
1693 _mov(Dest, T); 1693 _mov(Dest, T);
1694 break; 1694 break;
1695 case InstArithmetic::Fdiv: 1695 case InstArithmetic::Fdiv:
1696 _mov(T, Src0); 1696 _mov(T, Src0);
1697 _divss(T, Src1); 1697 _divss(T, Src1);
1698 _mov(Dest, T); 1698 _mov(Dest, T);
1699 break; 1699 break;
1700 case InstArithmetic::Frem: { 1700 case InstArithmetic::Frem: {
1701 const SizeT MaxSrcs = 2; 1701 const SizeT MaxSrcs = 2;
1702 Type Ty = Dest->getType(); 1702 Type Ty = Dest->getType();
1703 InstCall *Call = 1703 InstCall *Call = makeHelperCall(
1704 makeHelperCall(Ty == IceType_f32 ? "fmodf" : "fmod", Dest, MaxSrcs); 1704 isFloat32Asserting32Or64(Ty) ? "fmodf" : "fmod", Dest, MaxSrcs);
1705 Call->addArg(Src0); 1705 Call->addArg(Src0);
1706 Call->addArg(Src1); 1706 Call->addArg(Src1);
1707 return lowerCall(Call); 1707 return lowerCall(Call);
1708 } break; 1708 } break;
1709 } 1709 }
1710 } 1710 }
1711 } 1711 }
1712 1712
1713 void TargetX8632::lowerAssign(const InstAssign *Inst) { 1713 void TargetX8632::lowerAssign(const InstAssign *Inst) {
1714 Variable *Dest = Inst->getDest(); 1714 Variable *Dest = Inst->getDest();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 OperandList XmmArgs; 1772 OperandList XmmArgs;
1773 OperandList StackArgs, StackArgLocations; 1773 OperandList StackArgs, StackArgLocations;
1774 uint32_t ParameterAreaSizeBytes = 0; 1774 uint32_t ParameterAreaSizeBytes = 0;
1775 1775
1776 // Classify each argument operand according to the location where the 1776 // Classify each argument operand according to the location where the
1777 // argument is passed. 1777 // argument is passed.
1778 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { 1778 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
1779 Operand *Arg = Instr->getArg(i); 1779 Operand *Arg = Instr->getArg(i);
1780 Type Ty = Arg->getType(); 1780 Type Ty = Arg->getType();
1781 // The PNaCl ABI requires the width of arguments to be at least 32 bits. 1781 // The PNaCl ABI requires the width of arguments to be at least 32 bits.
1782 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_i64 || 1782 assert(typeWidthInBytes(Ty) >= 4);
1783 Ty == IceType_f64 || isVectorType(Ty));
1784 if (isVectorType(Ty) && XmmArgs.size() < X86_MAX_XMM_ARGS) { 1783 if (isVectorType(Ty) && XmmArgs.size() < X86_MAX_XMM_ARGS) {
1785 XmmArgs.push_back(Arg); 1784 XmmArgs.push_back(Arg);
1786 } else { 1785 } else {
1787 StackArgs.push_back(Arg); 1786 StackArgs.push_back(Arg);
1788 if (isVectorType(Arg->getType())) { 1787 if (isVectorType(Arg->getType())) {
1789 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); 1788 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
1790 } 1789 }
1791 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); 1790 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
1792 Constant *Loc = 1791 Constant *Loc =
1793 Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes); 1792 Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 } else { 1918 } else {
1920 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || 1919 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 ||
1921 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || 1920 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 ||
1922 isVectorType(Dest->getType())); 1921 isVectorType(Dest->getType()));
1923 if (isVectorType(Dest->getType())) { 1922 if (isVectorType(Dest->getType())) {
1924 _movp(Dest, ReturnReg); 1923 _movp(Dest, ReturnReg);
1925 } else { 1924 } else {
1926 _mov(Dest, ReturnReg); 1925 _mov(Dest, ReturnReg);
1927 } 1926 }
1928 } 1927 }
1929 } else if (Dest->getType() == IceType_f32 || Dest->getType() == IceType_f64) { 1928 } else if (isScalarFloatingType(Dest->getType())) {
1930 // Special treatment for an FP function which returns its result in 1929 // Special treatment for an FP function which returns its result in
1931 // st(0). 1930 // st(0).
1932 // If Dest ends up being a physical xmm register, the fstp emit code 1931 // If Dest ends up being a physical xmm register, the fstp emit code
1933 // will route st(0) through a temporary stack slot. 1932 // will route st(0) through a temporary stack slot.
1934 _fstp(Dest); 1933 _fstp(Dest);
1935 // Create a fake use of Dest in case it actually isn't used, 1934 // Create a fake use of Dest in case it actually isn't used,
1936 // because st(0) still needs to be popped. 1935 // because st(0) still needs to be popped.
1937 Context.insert(InstFakeUse::create(Func, Dest)); 1936 Context.insert(InstFakeUse::create(Func, Dest));
1938 } 1937 }
1939 } 1938 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 // Use a helper for converting floating-point values to 64-bit 2112 // Use a helper for converting floating-point values to 64-bit
2114 // integers. SSE2 appears to have no way to convert from xmm 2113 // integers. SSE2 appears to have no way to convert from xmm
2115 // registers to something like the edx:eax register pair, and 2114 // registers to something like the edx:eax register pair, and
2116 // gcc and clang both want to use x87 instructions complete with 2115 // gcc and clang both want to use x87 instructions complete with
2117 // temporary manipulation of the status word. This helper is 2116 // temporary manipulation of the status word. This helper is
2118 // not needed for x86-64. 2117 // not needed for x86-64.
2119 split64(Dest); 2118 split64(Dest);
2120 const SizeT MaxSrcs = 1; 2119 const SizeT MaxSrcs = 1;
2121 Type SrcType = Inst->getSrc(0)->getType(); 2120 Type SrcType = Inst->getSrc(0)->getType();
2122 InstCall *Call = makeHelperCall( 2121 InstCall *Call = makeHelperCall(
2123 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); 2122 isFloat32Asserting32Or64(SrcType) ? "cvtftosi64" : "cvtdtosi64", Dest,
2123 MaxSrcs);
2124 // TODO: Call the correct compiler-rt helper function. 2124 // TODO: Call the correct compiler-rt helper function.
2125 Call->addArg(Inst->getSrc(0)); 2125 Call->addArg(Inst->getSrc(0));
2126 lowerCall(Call); 2126 lowerCall(Call);
2127 } else { 2127 } else {
2128 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2128 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2129 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2129 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
2130 Variable *T_1 = makeReg(IceType_i32); 2130 Variable *T_1 = makeReg(IceType_i32);
2131 Variable *T_2 = makeReg(Dest->getType()); 2131 Variable *T_2 = makeReg(Dest->getType());
2132 _cvtt(T_1, Src0RM); 2132 _cvtt(T_1, Src0RM);
2133 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 2133 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
(...skipping 10 matching lines...) Expand all
2144 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); 2144 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs);
2145 Call->addArg(Inst->getSrc(0)); 2145 Call->addArg(Inst->getSrc(0));
2146 lowerCall(Call); 2146 lowerCall(Call);
2147 } else if (Dest->getType() == IceType_i64 || 2147 } else if (Dest->getType() == IceType_i64 ||
2148 Dest->getType() == IceType_i32) { 2148 Dest->getType() == IceType_i32) {
2149 // Use a helper for both x86-32 and x86-64. 2149 // Use a helper for both x86-32 and x86-64.
2150 split64(Dest); 2150 split64(Dest);
2151 const SizeT MaxSrcs = 1; 2151 const SizeT MaxSrcs = 1;
2152 Type DestType = Dest->getType(); 2152 Type DestType = Dest->getType();
2153 Type SrcType = Inst->getSrc(0)->getType(); 2153 Type SrcType = Inst->getSrc(0)->getType();
2154 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); 2154 IceString DstSubstring = (isInt32Asserting32Or64(DestType) ? "32" : "64");
2155 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); 2155 IceString SrcSubstring = (isFloat32Asserting32Or64(SrcType) ? "f" : "d");
2156 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 2156 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64
2157 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; 2157 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring;
2158 // TODO: Call the correct compiler-rt helper function. 2158 // TODO: Call the correct compiler-rt helper function.
2159 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 2159 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
2160 Call->addArg(Inst->getSrc(0)); 2160 Call->addArg(Inst->getSrc(0));
2161 lowerCall(Call); 2161 lowerCall(Call);
2162 return; 2162 return;
2163 } else { 2163 } else {
2164 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2164 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2165 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2165 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
(...skipping 12 matching lines...) Expand all
2178 Inst->getSrc(0)->getType() == IceType_v4i32); 2178 Inst->getSrc(0)->getType() == IceType_v4i32);
2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2180 Variable *T = makeReg(Dest->getType()); 2180 Variable *T = makeReg(Dest->getType());
2181 _cvt(T, Src0RM); 2181 _cvt(T, Src0RM);
2182 _movp(Dest, T); 2182 _movp(Dest, T);
2183 } else if (Inst->getSrc(0)->getType() == IceType_i64) { 2183 } else if (Inst->getSrc(0)->getType() == IceType_i64) {
2184 // Use a helper for x86-32. 2184 // Use a helper for x86-32.
2185 const SizeT MaxSrcs = 1; 2185 const SizeT MaxSrcs = 1;
2186 Type DestType = Dest->getType(); 2186 Type DestType = Dest->getType();
2187 InstCall *Call = makeHelperCall( 2187 InstCall *Call = makeHelperCall(
2188 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); 2188 isFloat32Asserting32Or64(DestType) ? "cvtsi64tof" : "cvtsi64tod",
Karl 2014/09/29 16:20:51 Mnior nit. This conditional and the one one for "f
jvoung (off chromium) 2014/09/29 16:57:49 I'm inclined to leave this alone for now if that's
2189 Dest, MaxSrcs);
2189 // TODO: Call the correct compiler-rt helper function. 2190 // TODO: Call the correct compiler-rt helper function.
2190 Call->addArg(Inst->getSrc(0)); 2191 Call->addArg(Inst->getSrc(0));
2191 lowerCall(Call); 2192 lowerCall(Call);
2192 return; 2193 return;
2193 } else { 2194 } else {
2194 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2195 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2195 // Sign-extend the operand. 2196 // Sign-extend the operand.
2196 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 2197 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2
2197 Variable *T_1 = makeReg(IceType_i32); 2198 Variable *T_1 = makeReg(IceType_i32);
2198 Variable *T_2 = makeReg(Dest->getType()); 2199 Variable *T_2 = makeReg(Dest->getType());
(...skipping 13 matching lines...) Expand all
2212 const SizeT MaxSrcs = 1; 2213 const SizeT MaxSrcs = 1;
2213 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs); 2214 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs);
2214 Call->addArg(Src0); 2215 Call->addArg(Src0);
2215 lowerCall(Call); 2216 lowerCall(Call);
2216 } else if (Src0->getType() == IceType_i64 || 2217 } else if (Src0->getType() == IceType_i64 ||
2217 Src0->getType() == IceType_i32) { 2218 Src0->getType() == IceType_i32) {
2218 // Use a helper for x86-32 and x86-64. Also use a helper for 2219 // Use a helper for x86-32 and x86-64. Also use a helper for
2219 // i32 on x86-32. 2220 // i32 on x86-32.
2220 const SizeT MaxSrcs = 1; 2221 const SizeT MaxSrcs = 1;
2221 Type DestType = Dest->getType(); 2222 Type DestType = Dest->getType();
2222 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); 2223 IceString SrcSubstring =
2223 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); 2224 (isInt32Asserting32Or64(Src0->getType()) ? "32" : "64");
2225 IceString DstSubstring = (isFloat32Asserting32Or64(DestType) ? "f" : "d");
2224 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod 2226 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod
2225 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; 2227 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring;
2226 // TODO: Call the correct compiler-rt helper function. 2228 // TODO: Call the correct compiler-rt helper function.
2227 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 2229 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
2228 Call->addArg(Src0); 2230 Call->addArg(Src0);
2229 lowerCall(Call); 2231 lowerCall(Call);
2230 return; 2232 return;
2231 } else { 2233 } else {
2232 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2234 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2233 // Zero-extend the operand. 2235 // Zero-extend the operand.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2406 // is not at the lowest index. 2408 // is not at the lowest index.
2407 Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index); 2409 Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index);
2408 T = makeReg(Ty); 2410 T = makeReg(Ty);
2409 _pshufd(T, legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem), Mask); 2411 _pshufd(T, legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem), Mask);
2410 } else { 2412 } else {
2411 T = legalizeToVar(SourceVectNotLegalized); 2413 T = legalizeToVar(SourceVectNotLegalized);
2412 } 2414 }
2413 2415
2414 if (InVectorElementTy == IceType_i32) { 2416 if (InVectorElementTy == IceType_i32) {
2415 _movd(ExtractedElementR, T); 2417 _movd(ExtractedElementR, T);
2416 } else { // Ty == Icetype_f32 2418 } else { // Ty == IceType_f32
2417 // TODO(wala): _movss is only used here because _mov does not 2419 // TODO(wala): _movss is only used here because _mov does not
2418 // allow a vector source and a scalar destination. _mov should be 2420 // allow a vector source and a scalar destination. _mov should be
2419 // able to be used here. 2421 // able to be used here.
2420 // _movss is a binary instruction, so the FakeDef is needed to 2422 // _movss is a binary instruction, so the FakeDef is needed to
2421 // keep the live range analysis consistent. 2423 // keep the live range analysis consistent.
2422 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); 2424 Context.insert(InstFakeDef::create(Func, ExtractedElementR));
2423 _movss(ExtractedElementR, T); 2425 _movss(ExtractedElementR, T);
2424 } 2426 }
2425 } else { 2427 } else {
2426 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 2428 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
3033 Variable *T = NULL; 3035 Variable *T = NULL;
3034 _mov(T, Val); 3036 _mov(T, Val);
3035 _rol(T, Eight); 3037 _rol(T, Eight);
3036 _mov(Dest, T); 3038 _mov(Dest, T);
3037 } 3039 }
3038 return; 3040 return;
3039 } 3041 }
3040 case Intrinsics::Ctpop: { 3042 case Intrinsics::Ctpop: {
3041 Variable *Dest = Instr->getDest(); 3043 Variable *Dest = Instr->getDest();
3042 Operand *Val = Instr->getArg(0); 3044 Operand *Val = Instr->getArg(0);
3043 InstCall *Call = makeHelperCall(Val->getType() == IceType_i64 ? 3045 InstCall *Call =
3044 "__popcountdi2" : "__popcountsi2", Dest, 1); 3046 makeHelperCall(isInt32Asserting32Or64(Val->getType()) ? "__popcountsi2"
3047 : "__popcountdi2",
3048 Dest, 1);
3045 Call->addArg(Val); 3049 Call->addArg(Val);
3046 lowerCall(Call); 3050 lowerCall(Call);
3047 // The popcount helpers always return 32-bit values, while the intrinsic's 3051 // The popcount helpers always return 32-bit values, while the intrinsic's
3048 // signature matches the native POPCNT instruction and fills a 64-bit reg 3052 // signature matches the native POPCNT instruction and fills a 64-bit reg
3049 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case 3053 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case
3050 // the user doesn't do that in the IR. If the user does that in the IR, 3054 // the user doesn't do that in the IR. If the user does that in the IR,
3051 // then this zero'ing instruction is dead and gets optimized out. 3055 // then this zero'ing instruction is dead and gets optimized out.
3052 if (Val->getType() == IceType_i64) { 3056 if (Val->getType() == IceType_i64) {
3053 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 3057 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
3054 Constant *Zero = Ctx->getConstantZero(IceType_i32); 3058 Constant *Zero = Ctx->getConstantZero(IceType_i32);
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
3874 3878
3875 void TargetX8632::lowerRet(const InstRet *Inst) { 3879 void TargetX8632::lowerRet(const InstRet *Inst) {
3876 Variable *Reg = NULL; 3880 Variable *Reg = NULL;
3877 if (Inst->hasRetValue()) { 3881 if (Inst->hasRetValue()) {
3878 Operand *Src0 = legalize(Inst->getRetValue()); 3882 Operand *Src0 = legalize(Inst->getRetValue());
3879 if (Src0->getType() == IceType_i64) { 3883 if (Src0->getType() == IceType_i64) {
3880 Variable *eax = legalizeToVar(loOperand(Src0), RegX8632::Reg_eax); 3884 Variable *eax = legalizeToVar(loOperand(Src0), RegX8632::Reg_eax);
3881 Variable *edx = legalizeToVar(hiOperand(Src0), RegX8632::Reg_edx); 3885 Variable *edx = legalizeToVar(hiOperand(Src0), RegX8632::Reg_edx);
3882 Reg = eax; 3886 Reg = eax;
3883 Context.insert(InstFakeUse::create(Func, edx)); 3887 Context.insert(InstFakeUse::create(Func, edx));
3884 } else if (Src0->getType() == IceType_f32 || 3888 } else if (isScalarFloatingType(Src0->getType())) {
3885 Src0->getType() == IceType_f64) {
3886 _fld(Src0); 3889 _fld(Src0);
3887 } else if (isVectorType(Src0->getType())) { 3890 } else if (isVectorType(Src0->getType())) {
3888 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); 3891 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0);
3889 } else { 3892 } else {
3890 _mov(Reg, Src0, RegX8632::Reg_eax); 3893 _mov(Reg, Src0, RegX8632::Reg_eax);
3891 } 3894 }
3892 } 3895 }
3893 _ret(Reg); 3896 _ret(Reg);
3894 // Add a fake use of esp to make sure esp stays alive for the entire 3897 // Add a fake use of esp to make sure esp stays alive for the entire
3895 // function. Otherwise post-call esp adjustments get dead-code 3898 // function. Otherwise post-call esp adjustments get dead-code
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
4264 assert(!isVectorType(From->getType())); 4267 assert(!isVectorType(From->getType()));
4265 bool NeedsReg = false; 4268 bool NeedsReg = false;
4266 if (!(Allowed & Legal_Imm)) 4269 if (!(Allowed & Legal_Imm))
4267 // Immediate specifically not allowed 4270 // Immediate specifically not allowed
4268 NeedsReg = true; 4271 NeedsReg = true;
4269 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper 4272 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper
4270 // emitter is used. 4273 // emitter is used.
4271 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) 4274 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From))
4272 // Relocatable specifically not allowed 4275 // Relocatable specifically not allowed
4273 NeedsReg = true; 4276 NeedsReg = true;
4274 if (!(Allowed & Legal_Mem) && 4277 if (!(Allowed & Legal_Mem) && isScalarFloatingType(From->getType()))
4275 (From->getType() == IceType_f32 || From->getType() == IceType_f64))
4276 // On x86, FP constants are lowered to mem operands. 4278 // On x86, FP constants are lowered to mem operands.
4277 NeedsReg = true; 4279 NeedsReg = true;
4278 if (NeedsReg) { 4280 if (NeedsReg) {
4279 From = copyToReg(From, RegNum); 4281 From = copyToReg(From, RegNum);
4280 } 4282 }
4281 return From; 4283 return From;
4282 } 4284 }
4283 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { 4285 if (Variable *Var = llvm::dyn_cast<Variable>(From)) {
4284 // Check if the variable is guaranteed a physical register. This 4286 // Check if the variable is guaranteed a physical register. This
4285 // can happen either when the variable is pre-colored or when it is 4287 // can happen either when the variable is pre-colored or when it is
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
4554 Str << "\t.align\t" << Align << "\n"; 4556 Str << "\t.align\t" << Align << "\n";
4555 Str << MangledName << ":\n"; 4557 Str << MangledName << ":\n";
4556 for (SizeT i = 0; i < Size; ++i) { 4558 for (SizeT i = 0; i < Size; ++i) {
4557 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 4559 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
4558 } 4560 }
4559 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4561 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
4560 } 4562 }
4561 } 4563 }
4562 4564
4563 } // end of namespace Ice 4565 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceRegistersX8632.h ('k') | src/IceTypes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698