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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 342763004: Add atomic load/store, fetch_add, fence, and is-lock-free lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: move _xadd fakedef to common _xadd code Created 6 years, 6 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 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 assert(Src0RM->getType() == IceType_f64); 1593 assert(Src0RM->getType() == IceType_f64);
1594 // a.i64 = bitcast b.f64 ==> 1594 // a.i64 = bitcast b.f64 ==>
1595 // s.f64 = spill b.f64 1595 // s.f64 = spill b.f64
1596 // t_lo.i32 = lo(s.f64) 1596 // t_lo.i32 = lo(s.f64)
1597 // a_lo.i32 = t_lo.i32 1597 // a_lo.i32 = t_lo.i32
1598 // t_hi.i32 = hi(s.f64) 1598 // t_hi.i32 = hi(s.f64)
1599 // a_hi.i32 = t_hi.i32 1599 // a_hi.i32 = t_hi.i32
1600 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); 1600 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode());
1601 Spill->setWeight(RegWeight::Zero); 1601 Spill->setWeight(RegWeight::Zero);
1602 Spill->setPreferredRegister(llvm::dyn_cast<Variable>(Src0RM), true); 1602 Spill->setPreferredRegister(llvm::dyn_cast<Variable>(Src0RM), true);
1603 _mov(Spill, Src0RM); 1603 _movq(Spill, Src0RM);
1604 1604
1605 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1605 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1606 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1606 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1607 Variable *T_Lo = makeReg(IceType_i32); 1607 Variable *T_Lo = makeReg(IceType_i32);
1608 Variable *T_Hi = makeReg(IceType_i32); 1608 Variable *T_Hi = makeReg(IceType_i32);
1609 VariableSplit *SpillLo = 1609 VariableSplit *SpillLo =
1610 VariableSplit::create(Func, Spill, VariableSplit::Low); 1610 VariableSplit::create(Func, Spill, VariableSplit::Low);
1611 VariableSplit *SpillHi = 1611 VariableSplit *SpillHi =
1612 VariableSplit::create(Func, Spill, VariableSplit::High); 1612 VariableSplit::create(Func, Spill, VariableSplit::High);
1613 1613
(...skipping 19 matching lines...) Expand all
1633 1633
1634 Variable *T_Lo = NULL, *T_Hi = NULL; 1634 Variable *T_Lo = NULL, *T_Hi = NULL;
1635 VariableSplit *SpillLo = 1635 VariableSplit *SpillLo =
1636 VariableSplit::create(Func, Spill, VariableSplit::Low); 1636 VariableSplit::create(Func, Spill, VariableSplit::Low);
1637 VariableSplit *SpillHi = 1637 VariableSplit *SpillHi =
1638 VariableSplit::create(Func, Spill, VariableSplit::High); 1638 VariableSplit::create(Func, Spill, VariableSplit::High);
1639 _mov(T_Lo, loOperand(Src0RM)); 1639 _mov(T_Lo, loOperand(Src0RM));
1640 _store(T_Lo, SpillLo); 1640 _store(T_Lo, SpillLo);
1641 _mov(T_Hi, hiOperand(Src0RM)); 1641 _mov(T_Hi, hiOperand(Src0RM));
1642 _store(T_Hi, SpillHi); 1642 _store(T_Hi, SpillHi);
1643 _mov(Dest, Spill); 1643 _movq(Dest, Spill);
1644 } break; 1644 } break;
1645 } 1645 }
1646 break; 1646 break;
1647 } 1647 }
1648 } 1648 }
1649 1649
1650 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { 1650 void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
1651 Operand *Src0 = Inst->getSrc(0); 1651 Operand *Src0 = Inst->getSrc(0);
1652 Operand *Src1 = Inst->getSrc(1); 1652 Operand *Src1 = Inst->getSrc(1);
1653 Variable *Dest = Inst->getDest(); 1653 Variable *Dest = Inst->getDest();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 _mov(Dest, One); 1774 _mov(Dest, One);
1775 _br(getIcmp32Mapping(Inst->getCondition()), Label); 1775 _br(getIcmp32Mapping(Inst->getCondition()), Label);
1776 Context.insert(InstFakeUse::create(Func, Dest)); 1776 Context.insert(InstFakeUse::create(Func, Dest));
1777 _mov(Dest, Zero); 1777 _mov(Dest, Zero);
1778 Context.insert(Label); 1778 Context.insert(Label);
1779 } 1779 }
1780 1780
1781 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { 1781 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
1782 switch (Instr->getIntrinsicInfo().ID) { 1782 switch (Instr->getIntrinsicInfo().ID) {
1783 case Intrinsics::AtomicCmpxchg: 1783 case Intrinsics::AtomicCmpxchg:
1784 if (!Intrinsics::VerifyMemoryOrder(
1785 llvm::cast<ConstantInteger>(Instr->getArg(3))->getValue())) {
1786 Func->setError("Unexpected memory order for AtomicCmpxchg");
1787 return;
1788 }
1789 // TODO(jvoung): fill it in.
1790 Func->setError("Unhandled intrinsic");
1791 return;
1784 case Intrinsics::AtomicFence: 1792 case Intrinsics::AtomicFence:
1793 if (!Intrinsics::VerifyMemoryOrder(
1794 llvm::cast<ConstantInteger>(Instr->getArg(0))->getValue())) {
1795 Func->setError("Unexpected memory order for AtomicFence");
1796 return;
1797 }
1798 _mfence();
1799 return;
1785 case Intrinsics::AtomicFenceAll: 1800 case Intrinsics::AtomicFenceAll:
1786 case Intrinsics::AtomicIsLockFree: 1801 _mfence();
JF 2014/06/24 01:23:29 FenceAll is meant as an equivalent to asm(:::"m"),
jvoung (off chromium) 2014/06/24 21:16:55 Added a comment, and a couple of speculative tests
1787 case Intrinsics::AtomicLoad: 1802 return;
1803 case Intrinsics::AtomicIsLockFree: {
1804 Constant *One = Ctx->getConstantInt(IceType_i32, 1);
JF 2014/06/24 01:23:29 It would be good to explain that x86 is always loc
jvoung (off chromium) 2014/06/24 21:16:55 iOn 2014/06/24 01:23:29, JF wrote:
1805 Variable *Dest = Instr->getDest();
1806 _mov(Dest, One);
1807 return;
1808 }
1809 case Intrinsics::AtomicLoad: {
1810 // We require the memory address to be naturally aligned.
1811 // Given that is the case, then normal loads are atomic.
1812 if (!Intrinsics::VerifyMemoryOrder(
1813 llvm::cast<ConstantInteger>(Instr->getArg(1))->getValue())) {
1814 Func->setError("Unexpected memory ordering for AtomicLoad");
1815 return;
1816 }
1817 Variable *Dest = Instr->getDest();
1818 if (Dest->getType() == IceType_i64) {
1819 // Follow what GCC does and use a movq instead of what lowerLoad()
1820 // normally does (split the load into two).
1821 // Thus, this skips load/arithmetic op folding. Load/arithmetic folding
1822 // can't happen anyway, since this is x86-32 and integer arithmetic only
1823 // happens on 32-bit quantities.
1824 Variable *T = makeReg(IceType_f64);
1825 OperandX8632Mem *Addr = FormMemoryOperand(Instr->getArg(0), IceType_f64);
1826 _movq(T, Addr);
1827 // Then cast the bits back out of the XMM register to the i64 Dest.
1828 InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
1829 lowerCast(Cast);
1830 // Make sure that the atomic load isn't elided.
1831 Context.insert(InstFakeUse::create(Func, Dest->getLo()));
1832 Context.insert(InstFakeUse::create(Func, Dest->getHi()));
1833 return;
1834 }
1835 InstLoad *Load = InstLoad::create(Func, Dest, Instr->getArg(0));
1836 lowerLoad(Load);
1837 // Make sure the atomic load isn't elided.
1838 Context.insert(InstFakeUse::create(Func, Dest));
1839 return;
1840 }
1788 case Intrinsics::AtomicRMW: 1841 case Intrinsics::AtomicRMW:
1789 case Intrinsics::AtomicStore: 1842 if (!Intrinsics::VerifyMemoryOrder(
1843 llvm::cast<ConstantInteger>(Instr->getArg(3))->getValue())) {
1844 Func->setError("Unexpected memory ordering for AtomicRMW");
1845 return;
1846 }
1847 lowerAtomicRMW(Instr->getDest(),
1848 static_cast<uint32_t>(llvm::cast<ConstantInteger>(
1849 Instr->getArg(0))->getValue()),
1850 Instr->getArg(1), Instr->getArg(2));
1851 return;
1852 case Intrinsics::AtomicStore: {
1853 if (!Intrinsics::VerifyMemoryOrder(
1854 llvm::cast<ConstantInteger>(Instr->getArg(2))->getValue())) {
1855 Func->setError("Unexpected memory ordering for AtomicStore");
1856 return;
1857 }
1858 // We require the memory address to be naturally aligned.
1859 // Given that is the case, then normal stores are atomic.
1860 // Add a fence after the store to make it visible.
1861 Operand *Value = Instr->getArg(0);
1862 Operand *Ptr = Instr->getArg(1);
1863 if (Value->getType() == IceType_i64) {
1864 // Use a movq instead of what lowerStore() normally does
1865 // (split the store into two), following what GCC does.
1866 // Cast the bits from int -> to an xmm register first.
1867 Variable *T = makeReg(IceType_f64);
1868 InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, T, Value);
1869 lowerCast(Cast);
1870 // Then store XMM w/ a movq.
1871 OperandX8632Mem *Addr = FormMemoryOperand(Ptr, IceType_f64);
1872 _storeq(T, Addr);
1873 _mfence();
1874 return;
1875 }
1876 InstStore *Store = InstStore::create(Func, Value, Ptr);
1877 lowerStore(Store);
1878 _mfence();
1879 return;
1880 }
1790 case Intrinsics::Bswap: 1881 case Intrinsics::Bswap:
1791 case Intrinsics::Ctlz: 1882 case Intrinsics::Ctlz:
1792 case Intrinsics::Ctpop: 1883 case Intrinsics::Ctpop:
1793 case Intrinsics::Cttz: 1884 case Intrinsics::Cttz:
1885 // TODO(jvoung): fill it in.
1794 Func->setError("Unhandled intrinsic"); 1886 Func->setError("Unhandled intrinsic");
1795 return; 1887 return;
1796 case Intrinsics::Longjmp: { 1888 case Intrinsics::Longjmp: {
1797 InstCall *Call = makeHelperCall("longjmp", NULL, 2); 1889 InstCall *Call = makeHelperCall("longjmp", NULL, 2);
1798 Call->addArg(Instr->getArg(0)); 1890 Call->addArg(Instr->getArg(0));
1799 Call->addArg(Instr->getArg(1)); 1891 Call->addArg(Instr->getArg(1));
1800 lowerCall(Call); 1892 lowerCall(Call);
1801 break; 1893 return;
1802 } 1894 }
1803 case Intrinsics::Memcpy: { 1895 case Intrinsics::Memcpy: {
1804 // In the future, we could potentially emit an inline memcpy/memset, etc. 1896 // In the future, we could potentially emit an inline memcpy/memset, etc.
1805 // for intrinsic calls w/ a known length. 1897 // for intrinsic calls w/ a known length.
1806 InstCall *Call = makeHelperCall("memcpy", NULL, 3); 1898 InstCall *Call = makeHelperCall("memcpy", NULL, 3);
1807 Call->addArg(Instr->getArg(0)); 1899 Call->addArg(Instr->getArg(0));
1808 Call->addArg(Instr->getArg(1)); 1900 Call->addArg(Instr->getArg(1));
1809 Call->addArg(Instr->getArg(2)); 1901 Call->addArg(Instr->getArg(2));
1810 lowerCall(Call); 1902 lowerCall(Call);
1811 break; 1903 return;
1812 } 1904 }
1813 case Intrinsics::Memmove: { 1905 case Intrinsics::Memmove: {
1814 InstCall *Call = makeHelperCall("memmove", NULL, 3); 1906 InstCall *Call = makeHelperCall("memmove", NULL, 3);
1815 Call->addArg(Instr->getArg(0)); 1907 Call->addArg(Instr->getArg(0));
1816 Call->addArg(Instr->getArg(1)); 1908 Call->addArg(Instr->getArg(1));
1817 Call->addArg(Instr->getArg(2)); 1909 Call->addArg(Instr->getArg(2));
1818 lowerCall(Call); 1910 lowerCall(Call);
1819 break; 1911 return;
1820 } 1912 }
1821 case Intrinsics::Memset: { 1913 case Intrinsics::Memset: {
1822 // The value operand needs to be extended to a stack slot size 1914 // The value operand needs to be extended to a stack slot size
1823 // because we "push" only works for a specific operand size. 1915 // because we "push" only works for a specific operand size.
1824 Operand *ValOp = Instr->getArg(1); 1916 Operand *ValOp = Instr->getArg(1);
1825 assert(ValOp->getType() == IceType_i8); 1917 assert(ValOp->getType() == IceType_i8);
1826 Variable *ValExt = makeReg(stackSlotType()); 1918 Variable *ValExt = makeReg(stackSlotType());
1827 _movzx(ValExt, ValOp); 1919 _movzx(ValExt, ValOp);
1828 InstCall *Call = makeHelperCall("memset", NULL, 3); 1920 InstCall *Call = makeHelperCall("memset", NULL, 3);
1829 Call->addArg(Instr->getArg(0)); 1921 Call->addArg(Instr->getArg(0));
1830 Call->addArg(ValExt); 1922 Call->addArg(ValExt);
1831 Call->addArg(Instr->getArg(2)); 1923 Call->addArg(Instr->getArg(2));
1832 lowerCall(Call); 1924 lowerCall(Call);
1833 break; 1925 return;
1834 } 1926 }
1835 case Intrinsics::NaClReadTP: { 1927 case Intrinsics::NaClReadTP: {
1836 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); 1928 Constant *Zero = Ctx->getConstantZero(IceType_i32);
1837 Operand *Src = OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL, 1929 Operand *Src = OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL,
1838 0, OperandX8632Mem::SegReg_GS); 1930 0, OperandX8632Mem::SegReg_GS);
1839 Variable *Dest = Instr->getDest(); 1931 Variable *Dest = Instr->getDest();
1840 Variable *T = NULL; 1932 Variable *T = NULL;
1841 _mov(T, Src); 1933 _mov(T, Src);
1842 _mov(Dest, T); 1934 _mov(Dest, T);
1843 break; 1935 return;
1844 } 1936 }
1845 case Intrinsics::Setjmp: { 1937 case Intrinsics::Setjmp: {
1846 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1); 1938 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1);
1847 Call->addArg(Instr->getArg(0)); 1939 Call->addArg(Instr->getArg(0));
1848 lowerCall(Call); 1940 lowerCall(Call);
1849 break; 1941 return;
1850 } 1942 }
1851 case Intrinsics::Sqrt: 1943 case Intrinsics::Sqrt:
1852 case Intrinsics::Stacksave: 1944 case Intrinsics::Stacksave:
1853 case Intrinsics::Stackrestore: 1945 case Intrinsics::Stackrestore:
1946 // TODO(jvoung): fill it in.
1854 Func->setError("Unhandled intrinsic"); 1947 Func->setError("Unhandled intrinsic");
1855 return; 1948 return;
1856 case Intrinsics::Trap: 1949 case Intrinsics::Trap:
1857 _ud2(); 1950 _ud2();
1858 break; 1951 return;
1859 case Intrinsics::UnknownIntrinsic: 1952 case Intrinsics::UnknownIntrinsic:
1860 Func->setError("Should not be lowering UnknownIntrinsic"); 1953 Func->setError("Should not be lowering UnknownIntrinsic");
1861 return; 1954 return;
1862 } 1955 }
1863 return; 1956 return;
1864 } 1957 }
1865 1958
1959 void TargetX8632::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
1960 Operand *Ptr, Operand *Val) {
1961 switch (Operation) {
1962 default:
1963 Func->setError("Unknown AtomicRMW operation");
1964 return;
1965 case Intrinsics::AtomicAdd: {
1966 if (Dest->getType() == IceType_i64) {
1967 // Do a nasty cmpxchg8b loop. Factor this into a function.
1968 // TODO(jvoung): fill it in.
1969 Func->setError("Unhandled AtomicRMW operation");
1970 return;
1971 }
1972 OperandX8632Mem *Addr = FormMemoryOperand(Ptr, Dest->getType());
1973 const bool Locked = true;
1974 Variable *T = NULL;
1975 _mov(T, Val);
1976 _xadd(Addr, T, Locked);
1977 _mov(Dest, T);
1978 return;
1979 }
1980 case Intrinsics::AtomicSub: {
1981 if (Dest->getType() == IceType_i64) {
1982 // Do a nasty cmpxchg8b loop.
1983 // TODO(jvoung): fill it in.
1984 Func->setError("Unhandled AtomicRMW operation");
1985 return;
1986 }
1987 // Generate a memory operand from Ptr.
1988 // neg...
1989 // Then do the same as AtomicAdd.
1990 // TODO(jvoung): fill it in.
1991 Func->setError("Unhandled AtomicRMW operation");
1992 return;
1993 }
1994 case Intrinsics::AtomicOr:
1995 case Intrinsics::AtomicAnd:
1996 case Intrinsics::AtomicXor:
1997 case Intrinsics::AtomicExchange:
1998 // TODO(jvoung): fill it in.
1999 Func->setError("Unhandled AtomicRMW operation");
2000 return;
2001 }
2002 }
2003
1866 namespace { 2004 namespace {
1867 2005
1868 bool isAdd(const Inst *Inst) { 2006 bool isAdd(const Inst *Inst) {
1869 if (const InstArithmetic *Arith = 2007 if (const InstArithmetic *Arith =
1870 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 2008 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
1871 return (Arith->getOp() == InstArithmetic::Add); 2009 return (Arith->getOp() == InstArithmetic::Add);
1872 } 2010 }
1873 return false; 2011 return false;
1874 } 2012 }
1875 2013
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 2130
1993 } // anonymous namespace 2131 } // anonymous namespace
1994 2132
1995 void TargetX8632::lowerLoad(const InstLoad *Inst) { 2133 void TargetX8632::lowerLoad(const InstLoad *Inst) {
1996 // A Load instruction can be treated the same as an Assign 2134 // A Load instruction can be treated the same as an Assign
1997 // instruction, after the source operand is transformed into an 2135 // instruction, after the source operand is transformed into an
1998 // OperandX8632Mem operand. Note that the address mode 2136 // OperandX8632Mem operand. Note that the address mode
1999 // optimization already creates an OperandX8632Mem operand, so it 2137 // optimization already creates an OperandX8632Mem operand, so it
2000 // doesn't need another level of transformation. 2138 // doesn't need another level of transformation.
2001 Type Ty = Inst->getDest()->getType(); 2139 Type Ty = Inst->getDest()->getType();
2002 Operand *Src0 = Inst->getSourceAddress(); 2140 Operand *Src0 = FormMemoryOperand(Inst->getSourceAddress(), Ty);
2003 // Address mode optimization already creates an OperandX8632Mem
2004 // operand, so it doesn't need another level of transformation.
2005 if (!llvm::isa<OperandX8632Mem>(Src0)) {
2006 Variable *Base = llvm::dyn_cast<Variable>(Src0);
2007 Constant *Offset = llvm::dyn_cast<Constant>(Src0);
2008 assert(Base || Offset);
2009 Src0 = OperandX8632Mem::create(Func, Ty, Base, Offset);
2010 }
2011 2141
2012 // Fuse this load with a subsequent Arithmetic instruction in the 2142 // Fuse this load with a subsequent Arithmetic instruction in the
2013 // following situations: 2143 // following situations:
2014 // a=[mem]; c=b+a ==> c=b+[mem] if last use of a and a not in b 2144 // a=[mem]; c=b+a ==> c=b+[mem] if last use of a and a not in b
2015 // a=[mem]; c=a+b ==> c=b+[mem] if commutative and above is true 2145 // a=[mem]; c=a+b ==> c=b+[mem] if commutative and above is true
2016 // 2146 //
2017 // TODO: Clean up and test thoroughly. 2147 // TODO: Clean up and test thoroughly.
2018 // 2148 //
2019 // TODO: Why limit to Arithmetic instructions? This could probably be 2149 // TODO: Why limit to Arithmetic instructions? This could probably be
2020 // applied to most any instruction type. Look at all source operands 2150 // applied to most any instruction type. Look at all source operands
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); 2268 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true);
2139 _mov(Dest, SrcF); 2269 _mov(Dest, SrcF);
2140 } 2270 }
2141 2271
2142 Context.insert(Label); 2272 Context.insert(Label);
2143 } 2273 }
2144 2274
2145 void TargetX8632::lowerStore(const InstStore *Inst) { 2275 void TargetX8632::lowerStore(const InstStore *Inst) {
2146 Operand *Value = Inst->getData(); 2276 Operand *Value = Inst->getData();
2147 Operand *Addr = Inst->getAddr(); 2277 Operand *Addr = Inst->getAddr();
2148 OperandX8632Mem *NewAddr = llvm::dyn_cast<OperandX8632Mem>(Addr); 2278 OperandX8632Mem *NewAddr = FormMemoryOperand(Addr, Value->getType());
2149 // Address mode optimization already creates an OperandX8632Mem
2150 // operand, so it doesn't need another level of transformation.
2151 if (!NewAddr) {
2152 // The address will be either a constant (which represents a global
2153 // variable) or a variable, so either the Base or Offset component
2154 // of the OperandX8632Mem will be set.
2155 Variable *Base = llvm::dyn_cast<Variable>(Addr);
2156 Constant *Offset = llvm::dyn_cast<Constant>(Addr);
2157 assert(Base || Offset);
2158 NewAddr = OperandX8632Mem::create(Func, Value->getType(), Base, Offset);
2159 }
2160 NewAddr = llvm::cast<OperandX8632Mem>(legalize(NewAddr));
2161 2279
2162 if (NewAddr->getType() == IceType_i64) { 2280 if (NewAddr->getType() == IceType_i64) {
2163 Value = legalize(Value); 2281 Value = legalize(Value);
2164 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm, true); 2282 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm, true);
2165 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm, true); 2283 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm, true);
2166 _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr))); 2284 _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr)));
2167 _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr))); 2285 _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr)));
2168 } else { 2286 } else {
2169 Value = legalize(Value, Legal_Reg | Legal_Imm, true); 2287 Value = legalize(Value, Legal_Reg | Legal_Imm, true);
2170 _store(Value, NewAddr); 2288 _store(Value, NewAddr);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 // 2386 //
2269 // If in the future the implementation is changed to lower undef 2387 // If in the future the implementation is changed to lower undef
2270 // values to uninitialized registers, a FakeDef will be needed: 2388 // values to uninitialized registers, a FakeDef will be needed:
2271 // Context.insert(InstFakeDef::create(Func, Reg)); 2389 // Context.insert(InstFakeDef::create(Func, Reg));
2272 // This is in order to ensure that the live range of Reg is not 2390 // This is in order to ensure that the live range of Reg is not
2273 // overestimated. If the constant being lowered is a 64 bit value, 2391 // overestimated. If the constant being lowered is a 64 bit value,
2274 // then the result should be split and the lo and hi components will 2392 // then the result should be split and the lo and hi components will
2275 // need to go in uninitialized registers. 2393 // need to go in uninitialized registers.
2276 From = Ctx->getConstantZero(From->getType()); 2394 From = Ctx->getConstantZero(From->getType());
2277 } 2395 }
2278 bool NeedsReg = !(Allowed & Legal_Imm) || 2396 bool NeedsReg =
2397 !(Allowed & Legal_Imm) ||
2279 // ConstantFloat and ConstantDouble are actually memory operands. 2398 // ConstantFloat and ConstantDouble are actually memory operands.
2280 (!(Allowed & Legal_Mem) && (From->getType() == IceType_f32 || 2399 (!(Allowed & Legal_Mem) &&
2281 From->getType() == IceType_f64)); 2400 (From->getType() == IceType_f32 || From->getType() == IceType_f64));
2282 if (NeedsReg) { 2401 if (NeedsReg) {
2283 Variable *Reg = makeReg(From->getType(), RegNum); 2402 Variable *Reg = makeReg(From->getType(), RegNum);
2284 _mov(Reg, From); 2403 _mov(Reg, From);
2285 From = Reg; 2404 From = Reg;
2286 } 2405 }
2287 return From; 2406 return From;
2288 } 2407 }
2289 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { 2408 if (Variable *Var = llvm::dyn_cast<Variable>(From)) {
2290 // We need a new physical register for the operand if: 2409 // We need a new physical register for the operand if:
2291 // Mem is not allowed and Var->getRegNum() is unknown, or 2410 // Mem is not allowed and Var->getRegNum() is unknown, or
(...skipping 12 matching lines...) Expand all
2304 llvm_unreachable("Unhandled operand kind in legalize()"); 2423 llvm_unreachable("Unhandled operand kind in legalize()");
2305 return From; 2424 return From;
2306 } 2425 }
2307 2426
2308 // Provide a trivial wrapper to legalize() for this common usage. 2427 // Provide a trivial wrapper to legalize() for this common usage.
2309 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, 2428 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap,
2310 int32_t RegNum) { 2429 int32_t RegNum) {
2311 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum)); 2430 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum));
2312 } 2431 }
2313 2432
2433 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) {
2434 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand);
2435 // It may be the case that address mode optimization already creates
2436 // an OperandX8632Mem, so in that case it wouldn't need another level
2437 // of transformation.
2438 if (!Mem) {
2439 Variable *Base = llvm::dyn_cast<Variable>(Operand);
2440 Constant *Offset = llvm::dyn_cast<Constant>(Operand);
2441 assert(Base || Offset);
2442 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
2443 }
2444 return llvm::cast<OperandX8632Mem>(legalize(Mem));
2445 }
2446
2314 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 2447 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
2315 Variable *Reg = Func->makeVariable(Type, Context.getNode()); 2448 Variable *Reg = Func->makeVariable(Type, Context.getNode());
2316 if (RegNum == Variable::NoRegister) 2449 if (RegNum == Variable::NoRegister)
2317 Reg->setWeightInfinite(); 2450 Reg->setWeightInfinite();
2318 else 2451 else
2319 Reg->setRegNum(RegNum); 2452 Reg->setRegNum(RegNum);
2320 return Reg; 2453 return Reg;
2321 } 2454 }
2322 2455
2323 void TargetX8632::postLower() { 2456 void TargetX8632::postLower() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 // llvm-mc doesn't parse "dword ptr [.L$foo]". 2521 // llvm-mc doesn't parse "dword ptr [.L$foo]".
2389 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; 2522 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
2390 } 2523 }
2391 2524
2392 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { 2525 template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
2393 Ostream &Str = Ctx->getStrEmit(); 2526 Ostream &Str = Ctx->getStrEmit();
2394 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; 2527 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
2395 } 2528 }
2396 2529
2397 } // end of namespace Ice 2530 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698