Chromium Code Reviews| 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 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 split64(Var); | 751 split64(Var); |
| 752 return Var->getLo(); | 752 return Var->getLo(); |
| 753 } | 753 } |
| 754 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { | 754 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { |
| 755 uint64_t Mask = (1ull << 32) - 1; | 755 uint64_t Mask = (1ull << 32) - 1; |
| 756 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask); | 756 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask); |
| 757 } | 757 } |
| 758 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { | 758 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { |
| 759 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), | 759 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), |
| 760 Mem->getOffset(), Mem->getIndex(), | 760 Mem->getOffset(), Mem->getIndex(), |
| 761 Mem->getShift()); | 761 Mem->getShift(), Mem->getSegmentRegister()); |
| 762 } | 762 } |
| 763 llvm_unreachable("Unsupported operand type"); | 763 llvm_unreachable("Unsupported operand type"); |
| 764 return NULL; | 764 return NULL; |
| 765 } | 765 } |
| 766 | 766 |
| 767 Operand *TargetX8632::hiOperand(Operand *Operand) { | 767 Operand *TargetX8632::hiOperand(Operand *Operand) { |
| 768 assert(Operand->getType() == IceType_i64); | 768 assert(Operand->getType() == IceType_i64); |
| 769 if (Operand->getType() != IceType_i64) | 769 if (Operand->getType() != IceType_i64) |
| 770 return Operand; | 770 return Operand; |
| 771 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { | 771 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { |
| 772 split64(Var); | 772 split64(Var); |
| 773 return Var->getHi(); | 773 return Var->getHi(); |
| 774 } | 774 } |
| 775 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { | 775 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { |
| 776 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32); | 776 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32); |
| 777 } | 777 } |
| 778 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { | 778 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { |
| 779 Constant *Offset = Mem->getOffset(); | 779 Constant *Offset = Mem->getOffset(); |
| 780 if (Offset == NULL) | 780 if (Offset == NULL) |
| 781 Offset = Ctx->getConstantInt(IceType_i32, 4); | 781 Offset = Ctx->getConstantInt(IceType_i32, 4); |
| 782 else if (ConstantInteger *IntOffset = | 782 else if (ConstantInteger *IntOffset = |
| 783 llvm::dyn_cast<ConstantInteger>(Offset)) { | 783 llvm::dyn_cast<ConstantInteger>(Offset)) { |
| 784 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue()); | 784 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue()); |
| 785 } else if (ConstantRelocatable *SymOffset = | 785 } else if (ConstantRelocatable *SymOffset = |
| 786 llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 786 llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
| 787 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(), | 787 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(), |
| 788 SymOffset->getName()); | 788 SymOffset->getName()); |
| 789 } | 789 } |
| 790 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, | 790 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, |
| 791 Mem->getIndex(), Mem->getShift()); | 791 Mem->getIndex(), Mem->getShift(), |
| 792 Mem->getSegmentRegister()); | |
| 792 } | 793 } |
| 793 llvm_unreachable("Unsupported operand type"); | 794 llvm_unreachable("Unsupported operand type"); |
| 794 return NULL; | 795 return NULL; |
| 795 } | 796 } |
| 796 | 797 |
| 797 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, | 798 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, |
| 798 RegSetMask Exclude) const { | 799 RegSetMask Exclude) const { |
| 799 llvm::SmallBitVector Registers(Reg_NUM); | 800 llvm::SmallBitVector Registers(Reg_NUM); |
| 800 | 801 |
| 801 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ | 802 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1757 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true); | 1758 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true); |
| 1758 InstX8632Label *Label = InstX8632Label::create(Func, this); | 1759 InstX8632Label *Label = InstX8632Label::create(Func, this); |
| 1759 _cmp(Src0New, Src1); | 1760 _cmp(Src0New, Src1); |
| 1760 _mov(Dest, One); | 1761 _mov(Dest, One); |
| 1761 _br(getIcmp32Mapping(Inst->getCondition()), Label); | 1762 _br(getIcmp32Mapping(Inst->getCondition()), Label); |
| 1762 Context.insert(InstFakeUse::create(Func, Dest)); | 1763 Context.insert(InstFakeUse::create(Func, Dest)); |
| 1763 _mov(Dest, Zero); | 1764 _mov(Dest, Zero); |
| 1764 Context.insert(Label); | 1765 Context.insert(Label); |
| 1765 } | 1766 } |
| 1766 | 1767 |
| 1768 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { | |
| 1769 switch (Instr->getIntrinsicInfo().ID) { | |
| 1770 case AtomicCmpxchg: | |
| 1771 case AtomicFence: | |
| 1772 case AtomicFenceAll: | |
| 1773 case AtomicIsLockFree: | |
| 1774 case AtomicLoad: | |
| 1775 case AtomicRMW: | |
| 1776 case AtomicStore: | |
| 1777 case Bswap: | |
| 1778 case Ctlz: | |
| 1779 case Ctpop: | |
| 1780 case Cttz: | |
| 1781 Func->setError("Unhandled intrinsic"); | |
| 1782 return; | |
| 1783 case Longjmp: { | |
| 1784 InstCall *Call = makeHelperCall("longjmp", NULL, 2); | |
| 1785 Call->addArg(Instr->getSrc(1)); | |
| 1786 Call->addArg(Instr->getSrc(2)); | |
| 1787 lowerCall(Call); | |
| 1788 break; | |
| 1789 } | |
| 1790 case Memcpy: { | |
| 1791 // In the future, we could potentially emit an inline memcpy/memset, etc. | |
| 1792 // for intrinsic calls w/ a known length. | |
| 1793 InstCall *Call = makeHelperCall("memcpy", NULL, 3); | |
| 1794 Call->addArg(Instr->getSrc(1)); | |
| 1795 Call->addArg(Instr->getSrc(2)); | |
| 1796 Call->addArg(Instr->getSrc(3)); | |
| 1797 lowerCall(Call); | |
| 1798 break; | |
| 1799 } | |
| 1800 case Memmove: { | |
| 1801 InstCall *Call = makeHelperCall("memmove", NULL, 3); | |
| 1802 Call->addArg(Instr->getSrc(1)); | |
| 1803 Call->addArg(Instr->getSrc(2)); | |
| 1804 Call->addArg(Instr->getSrc(3)); | |
| 1805 lowerCall(Call); | |
| 1806 break; | |
| 1807 } | |
| 1808 case Memset: { | |
| 1809 InstCall *Call = makeHelperCall("memset", NULL, 3); | |
| 1810 Call->addArg(Instr->getSrc(1)); | |
| 1811 Call->addArg(Instr->getSrc(2)); | |
|
jvoung (off chromium)
2014/06/12 05:48:30
Should this code be responsible for "widening" the
Jim Stichnoth
2014/06/12 17:04:44
The Subzero lowering code assumes the simplificati
jvoung (off chromium)
2014/06/16 20:51:58
Added a movzx for this case.
Was going to add a d
Jim Stichnoth
2014/06/16 23:05:15
Hmm, looks like those two tests are not valid PNaC
jvoung (off chromium)
2014/06/17 17:36:18
Ah right, I should have looked at what the test wa
| |
| 1812 Call->addArg(Instr->getSrc(3)); | |
| 1813 lowerCall(Call); | |
| 1814 break; | |
| 1815 } | |
| 1816 case NaClReadTP: { | |
| 1817 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); | |
| 1818 Operand *Src = OperandX8632Mem::create( | |
| 1819 Func, IceType_i32, NULL, Zero, NULL, 0, | |
| 1820 OperandX8632Mem::Reg_GS); | |
| 1821 Variable *Dest = Instr->getDest(); | |
| 1822 Variable *T = NULL; | |
| 1823 _mov(T, Src); | |
| 1824 _mov(Dest, T); | |
| 1825 break; | |
| 1826 } | |
| 1827 case Setjmp: { | |
| 1828 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1); | |
| 1829 Call->addArg(Instr->getSrc(1)); | |
| 1830 lowerCall(Call); | |
| 1831 break; | |
| 1832 } | |
| 1833 case Sqrt: | |
| 1834 case Stacksave: | |
| 1835 case Stackrestore: | |
| 1836 Func->setError("Unhandled intrinsic"); | |
| 1837 return; | |
| 1838 case Trap: | |
| 1839 _ud2(); | |
| 1840 break; | |
| 1841 case UnknownIntrinsic: | |
| 1842 Func->setError("Should not be lowering UnknownIntrinsic"); | |
| 1843 return; | |
| 1844 } | |
| 1845 return; | |
| 1846 } | |
| 1847 | |
| 1767 namespace { | 1848 namespace { |
| 1768 | 1849 |
| 1769 bool isAdd(const Inst *Inst) { | 1850 bool isAdd(const Inst *Inst) { |
| 1770 if (const InstArithmetic *Arith = | 1851 if (const InstArithmetic *Arith = |
| 1771 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { | 1852 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { |
| 1772 return (Arith->getOp() == InstArithmetic::Add); | 1853 return (Arith->getOp() == InstArithmetic::Add); |
| 1773 } | 1854 } |
| 1774 return false; | 1855 return false; |
| 1775 } | 1856 } |
| 1776 | 1857 |
| 1777 void computeAddressOpt(Variable *&Base, Variable *&Index, int32_t &Shift, | 1858 void computeAddressOpt(Variable *&Base, Variable *&Index, uint16_t &Shift, |
| 1778 int32_t &Offset) { | 1859 int32_t &Offset) { |
| 1779 (void)Offset; // TODO: pattern-match for non-zero offsets. | 1860 (void)Offset; // TODO: pattern-match for non-zero offsets. |
| 1780 if (Base == NULL) | 1861 if (Base == NULL) |
| 1781 return; | 1862 return; |
| 1782 // If the Base has more than one use or is live across multiple | 1863 // If the Base has more than one use or is live across multiple |
| 1783 // blocks, then don't go further. Alternatively (?), never consider | 1864 // blocks, then don't go further. Alternatively (?), never consider |
| 1784 // a transformation that would change a variable that is currently | 1865 // a transformation that would change a variable that is currently |
| 1785 // *not* live across basic block boundaries into one that *is*. | 1866 // *not* live across basic block boundaries into one that *is*. |
| 1786 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) | 1867 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) |
| 1787 return; | 1868 return; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1948 | 2029 |
| 1949 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); | 2030 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); |
| 1950 lowerAssign(Assign); | 2031 lowerAssign(Assign); |
| 1951 } | 2032 } |
| 1952 | 2033 |
| 1953 void TargetX8632::doAddressOptLoad() { | 2034 void TargetX8632::doAddressOptLoad() { |
| 1954 Inst *Inst = *Context.getCur(); | 2035 Inst *Inst = *Context.getCur(); |
| 1955 Variable *Dest = Inst->getDest(); | 2036 Variable *Dest = Inst->getDest(); |
| 1956 Operand *Addr = Inst->getSrc(0); | 2037 Operand *Addr = Inst->getSrc(0); |
| 1957 Variable *Index = NULL; | 2038 Variable *Index = NULL; |
| 1958 int32_t Shift = 0; | 2039 uint16_t Shift = 0; |
| 1959 int32_t Offset = 0; // TODO: make Constant | 2040 int32_t Offset = 0; // TODO: make Constant |
| 2041 // At the ICE level, load instructions should not use the | |
| 2042 // segment registers, and computeAddressOpt only works at the level | |
| 2043 // of Variables and Constants, not other OperandX8632Mem, so there | |
| 2044 // should be no mention of segment registers there either. | |
| 2045 OperandX8632Mem::SegmentRegisters SegmentReg = | |
| 2046 OperandX8632Mem::DefaultSegment; | |
| 1960 Variable *Base = llvm::dyn_cast<Variable>(Addr); | 2047 Variable *Base = llvm::dyn_cast<Variable>(Addr); |
| 1961 computeAddressOpt(Base, Index, Shift, Offset); | 2048 computeAddressOpt(Base, Index, Shift, Offset); |
| 1962 if (Base && Addr != Base) { | 2049 if (Base && Addr != Base) { |
| 1963 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); | 2050 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
| 1964 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, | 2051 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, |
| 1965 Shift); | 2052 Shift, SegmentReg); |
| 1966 Inst->setDeleted(); | 2053 Inst->setDeleted(); |
| 1967 Context.insert(InstLoad::create(Func, Dest, Addr)); | 2054 Context.insert(InstLoad::create(Func, Dest, Addr)); |
| 1968 } | 2055 } |
| 1969 } | 2056 } |
| 1970 | 2057 |
| 1971 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { | 2058 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { |
| 1972 Func->setError("Phi found in regular instruction list"); | 2059 Func->setError("Phi found in regular instruction list"); |
| 1973 } | 2060 } |
| 1974 | 2061 |
| 1975 void TargetX8632::lowerRet(const InstRet *Inst) { | 2062 void TargetX8632::lowerRet(const InstRet *Inst) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2064 Value = legalize(Value, Legal_Reg | Legal_Imm, true); | 2151 Value = legalize(Value, Legal_Reg | Legal_Imm, true); |
| 2065 _store(Value, NewAddr); | 2152 _store(Value, NewAddr); |
| 2066 } | 2153 } |
| 2067 } | 2154 } |
| 2068 | 2155 |
| 2069 void TargetX8632::doAddressOptStore() { | 2156 void TargetX8632::doAddressOptStore() { |
| 2070 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); | 2157 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); |
| 2071 Operand *Data = Inst->getData(); | 2158 Operand *Data = Inst->getData(); |
| 2072 Operand *Addr = Inst->getAddr(); | 2159 Operand *Addr = Inst->getAddr(); |
| 2073 Variable *Index = NULL; | 2160 Variable *Index = NULL; |
| 2074 int32_t Shift = 0; | 2161 uint16_t Shift = 0; |
| 2075 int32_t Offset = 0; // TODO: make Constant | 2162 int32_t Offset = 0; // TODO: make Constant |
| 2076 Variable *Base = llvm::dyn_cast<Variable>(Addr); | 2163 Variable *Base = llvm::dyn_cast<Variable>(Addr); |
| 2164 // At the ICE level, load instructions should not use the | |
| 2165 // segment registers, and computeAddressOpt only works at the level | |
| 2166 // of Variables and Constants, not other OperandX8632Mem, so there | |
| 2167 // should be no mention of segment registers there either. | |
| 2168 OperandX8632Mem::SegmentRegisters SegmentReg = | |
| 2169 OperandX8632Mem::DefaultSegment; | |
| 2077 computeAddressOpt(Base, Index, Shift, Offset); | 2170 computeAddressOpt(Base, Index, Shift, Offset); |
| 2078 if (Base && Addr != Base) { | 2171 if (Base && Addr != Base) { |
| 2079 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); | 2172 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
| 2080 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, | 2173 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, |
| 2081 Shift); | 2174 Shift, SegmentReg); |
| 2082 Inst->setDeleted(); | 2175 Inst->setDeleted(); |
| 2083 Context.insert(InstStore::create(Func, Data, Addr)); | 2176 Context.insert(InstStore::create(Func, Data, Addr)); |
| 2084 } | 2177 } |
| 2085 } | 2178 } |
| 2086 | 2179 |
| 2087 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { | 2180 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { |
| 2088 // This implements the most naive possible lowering. | 2181 // This implements the most naive possible lowering. |
| 2089 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default | 2182 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default |
| 2090 Operand *Src0 = Inst->getComparison(); | 2183 Operand *Src0 = Inst->getComparison(); |
| 2091 SizeT NumCases = Inst->getNumCases(); | 2184 SizeT NumCases = Inst->getNumCases(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2132 Variable *RegIndex = NULL; | 2225 Variable *RegIndex = NULL; |
| 2133 if (Base) { | 2226 if (Base) { |
| 2134 RegBase = legalizeToVar(Base, true); | 2227 RegBase = legalizeToVar(Base, true); |
| 2135 } | 2228 } |
| 2136 if (Index) { | 2229 if (Index) { |
| 2137 RegIndex = legalizeToVar(Index, true); | 2230 RegIndex = legalizeToVar(Index, true); |
| 2138 } | 2231 } |
| 2139 if (Base != RegBase || Index != RegIndex) { | 2232 if (Base != RegBase || Index != RegIndex) { |
| 2140 From = | 2233 From = |
| 2141 OperandX8632Mem::create(Func, Mem->getType(), RegBase, | 2234 OperandX8632Mem::create(Func, Mem->getType(), RegBase, |
| 2142 Mem->getOffset(), RegIndex, Mem->getShift()); | 2235 Mem->getOffset(), RegIndex, Mem->getShift(), |
| 2236 Mem->getSegmentRegister()); | |
| 2143 } | 2237 } |
| 2144 | 2238 |
| 2145 if (!(Allowed & Legal_Mem)) { | 2239 if (!(Allowed & Legal_Mem)) { |
| 2146 Variable *Reg = makeReg(From->getType(), RegNum); | 2240 Variable *Reg = makeReg(From->getType(), RegNum); |
| 2147 _mov(Reg, From, RegNum); | 2241 _mov(Reg, From, RegNum); |
| 2148 From = Reg; | 2242 From = Reg; |
| 2149 } | 2243 } |
| 2150 return From; | 2244 return From; |
| 2151 } | 2245 } |
| 2152 if (llvm::isa<Constant>(From)) { | 2246 if (llvm::isa<Constant>(From)) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2259 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 2353 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
| 2260 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 2354 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
| 2261 } | 2355 } |
| 2262 | 2356 |
| 2263 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 2357 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
| 2264 Ostream &Str = Ctx->getStrEmit(); | 2358 Ostream &Str = Ctx->getStrEmit(); |
| 2265 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 2359 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
| 2266 } | 2360 } |
| 2267 | 2361 |
| 2268 } // end of namespace Ice | 2362 } // end of namespace Ice |
| OLD | NEW |