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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 321993002: Add a few Subzero intrinsics (not the atomic ones yet). (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: add variable length version too 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 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 split64(Var); 753 split64(Var);
754 return Var->getLo(); 754 return Var->getLo();
755 } 755 }
756 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { 756 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
757 uint64_t Mask = (1ull << 32) - 1; 757 uint64_t Mask = (1ull << 32) - 1;
758 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask); 758 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask);
759 } 759 }
760 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 760 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
761 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 761 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(),
762 Mem->getOffset(), Mem->getIndex(), 762 Mem->getOffset(), Mem->getIndex(),
763 Mem->getShift()); 763 Mem->getShift(), Mem->getSegmentRegister());
764 } 764 }
765 llvm_unreachable("Unsupported operand type"); 765 llvm_unreachable("Unsupported operand type");
766 return NULL; 766 return NULL;
767 } 767 }
768 768
769 Operand *TargetX8632::hiOperand(Operand *Operand) { 769 Operand *TargetX8632::hiOperand(Operand *Operand) {
770 assert(Operand->getType() == IceType_i64); 770 assert(Operand->getType() == IceType_i64);
771 if (Operand->getType() != IceType_i64) 771 if (Operand->getType() != IceType_i64)
772 return Operand; 772 return Operand;
773 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 773 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
774 split64(Var); 774 split64(Var);
775 return Var->getHi(); 775 return Var->getHi();
776 } 776 }
777 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { 777 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
778 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32); 778 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32);
779 } 779 }
780 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 780 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
781 Constant *Offset = Mem->getOffset(); 781 Constant *Offset = Mem->getOffset();
782 if (Offset == NULL) 782 if (Offset == NULL)
783 Offset = Ctx->getConstantInt(IceType_i32, 4); 783 Offset = Ctx->getConstantInt(IceType_i32, 4);
784 else if (ConstantInteger *IntOffset = 784 else if (ConstantInteger *IntOffset =
785 llvm::dyn_cast<ConstantInteger>(Offset)) { 785 llvm::dyn_cast<ConstantInteger>(Offset)) {
786 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue()); 786 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue());
787 } else if (ConstantRelocatable *SymOffset = 787 } else if (ConstantRelocatable *SymOffset =
788 llvm::dyn_cast<ConstantRelocatable>(Offset)) { 788 llvm::dyn_cast<ConstantRelocatable>(Offset)) {
789 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(), 789 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(),
790 SymOffset->getName()); 790 SymOffset->getName());
791 } 791 }
792 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, 792 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset,
793 Mem->getIndex(), Mem->getShift()); 793 Mem->getIndex(), Mem->getShift(),
794 Mem->getSegmentRegister());
794 } 795 }
795 llvm_unreachable("Unsupported operand type"); 796 llvm_unreachable("Unsupported operand type");
796 return NULL; 797 return NULL;
797 } 798 }
798 799
799 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, 800 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
800 RegSetMask Exclude) const { 801 RegSetMask Exclude) const {
801 llvm::SmallBitVector Registers(Reg_NUM); 802 llvm::SmallBitVector Registers(Reg_NUM);
802 803
803 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ 804 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true); 1760 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true);
1760 InstX8632Label *Label = InstX8632Label::create(Func, this); 1761 InstX8632Label *Label = InstX8632Label::create(Func, this);
1761 _cmp(Src0New, Src1); 1762 _cmp(Src0New, Src1);
1762 _mov(Dest, One); 1763 _mov(Dest, One);
1763 _br(getIcmp32Mapping(Inst->getCondition()), Label); 1764 _br(getIcmp32Mapping(Inst->getCondition()), Label);
1764 Context.insert(InstFakeUse::create(Func, Dest)); 1765 Context.insert(InstFakeUse::create(Func, Dest));
1765 _mov(Dest, Zero); 1766 _mov(Dest, Zero);
1766 Context.insert(Label); 1767 Context.insert(Label);
1767 } 1768 }
1768 1769
1770 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
1771 switch (Instr->getIntrinsicInfo().ID) {
1772 case AtomicCmpxchg:
1773 case AtomicFence:
1774 case AtomicFenceAll:
1775 case AtomicIsLockFree:
1776 case AtomicLoad:
1777 case AtomicRMW:
1778 case AtomicStore:
1779 case Bswap:
1780 case Ctlz:
1781 case Ctpop:
1782 case Cttz:
1783 Func->setError("Unhandled intrinsic");
1784 return;
1785 case Longjmp: {
1786 InstCall *Call = makeHelperCall("longjmp", NULL, 2);
1787 Call->addArg(Instr->getArg(0));
1788 Call->addArg(Instr->getArg(1));
1789 lowerCall(Call);
1790 break;
1791 }
1792 case Memcpy: {
1793 // In the future, we could potentially emit an inline memcpy/memset, etc.
1794 // for intrinsic calls w/ a known length.
1795 InstCall *Call = makeHelperCall("memcpy", NULL, 3);
1796 Call->addArg(Instr->getArg(0));
1797 Call->addArg(Instr->getArg(1));
1798 Call->addArg(Instr->getArg(2));
1799 lowerCall(Call);
1800 break;
1801 }
1802 case Memmove: {
1803 InstCall *Call = makeHelperCall("memmove", NULL, 3);
1804 Call->addArg(Instr->getArg(0));
1805 Call->addArg(Instr->getArg(1));
1806 Call->addArg(Instr->getArg(2));
1807 lowerCall(Call);
1808 break;
1809 }
1810 case Memset: {
1811 // The value operand needs to be extended to a stack slot size
1812 // because we "push" only works for a specific operand size.
1813 Operand *ValOp = Instr->getArg(1);
1814 assert(ValOp->getType() == IceType_i8);
1815 Variable *ValExt = makeReg(stackSlotType());
1816 _movzx(ValExt, ValOp);
1817 InstCall *Call = makeHelperCall("memset", NULL, 3);
1818 Call->addArg(Instr->getArg(0));
1819 Call->addArg(ValExt);
1820 Call->addArg(Instr->getArg(2));
1821 lowerCall(Call);
1822 break;
1823 }
1824 case NaClReadTP: {
1825 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0);
1826 Operand *Src = OperandX8632Mem::create(
1827 Func, IceType_i32, NULL, Zero, NULL, 0,
1828 OperandX8632Mem::SegReg_GS);
1829 Variable *Dest = Instr->getDest();
1830 Variable *T = NULL;
1831 _mov(T, Src);
1832 _mov(Dest, T);
1833 break;
1834 }
1835 case Setjmp: {
1836 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1);
1837 Call->addArg(Instr->getArg(0));
1838 lowerCall(Call);
1839 break;
1840 }
1841 case Sqrt:
1842 case Stacksave:
1843 case Stackrestore:
1844 Func->setError("Unhandled intrinsic");
1845 return;
1846 case Trap:
1847 _ud2();
1848 break;
1849 case UnknownIntrinsic:
1850 Func->setError("Should not be lowering UnknownIntrinsic");
1851 return;
1852 }
1853 return;
1854 }
1855
1769 namespace { 1856 namespace {
1770 1857
1771 bool isAdd(const Inst *Inst) { 1858 bool isAdd(const Inst *Inst) {
1772 if (const InstArithmetic *Arith = 1859 if (const InstArithmetic *Arith =
1773 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 1860 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
1774 return (Arith->getOp() == InstArithmetic::Add); 1861 return (Arith->getOp() == InstArithmetic::Add);
1775 } 1862 }
1776 return false; 1863 return false;
1777 } 1864 }
1778 1865
1779 void computeAddressOpt(Variable *&Base, Variable *&Index, int32_t &Shift, 1866 void computeAddressOpt(Variable *&Base, Variable *&Index, uint16_t &Shift,
1780 int32_t &Offset) { 1867 int32_t &Offset) {
1781 (void)Offset; // TODO: pattern-match for non-zero offsets. 1868 (void)Offset; // TODO: pattern-match for non-zero offsets.
1782 if (Base == NULL) 1869 if (Base == NULL)
1783 return; 1870 return;
1784 // If the Base has more than one use or is live across multiple 1871 // If the Base has more than one use or is live across multiple
1785 // blocks, then don't go further. Alternatively (?), never consider 1872 // blocks, then don't go further. Alternatively (?), never consider
1786 // a transformation that would change a variable that is currently 1873 // a transformation that would change a variable that is currently
1787 // *not* live across basic block boundaries into one that *is*. 1874 // *not* live across basic block boundaries into one that *is*.
1788 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) 1875 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/)
1789 return; 1876 return;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1950 2037
1951 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); 2038 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0);
1952 lowerAssign(Assign); 2039 lowerAssign(Assign);
1953 } 2040 }
1954 2041
1955 void TargetX8632::doAddressOptLoad() { 2042 void TargetX8632::doAddressOptLoad() {
1956 Inst *Inst = *Context.getCur(); 2043 Inst *Inst = *Context.getCur();
1957 Variable *Dest = Inst->getDest(); 2044 Variable *Dest = Inst->getDest();
1958 Operand *Addr = Inst->getSrc(0); 2045 Operand *Addr = Inst->getSrc(0);
1959 Variable *Index = NULL; 2046 Variable *Index = NULL;
1960 int32_t Shift = 0; 2047 uint16_t Shift = 0;
1961 int32_t Offset = 0; // TODO: make Constant 2048 int32_t Offset = 0; // TODO: make Constant
2049 // Vanilla ICE load instructions should not use the segment registers,
2050 // and computeAddressOpt only works at the level of Variables and Constants,
2051 // not other OperandX8632Mem, so there should be no mention of segment
2052 // registers there either.
2053 const OperandX8632Mem::SegmentRegisters SegmentReg =
2054 OperandX8632Mem::DefaultSegment;
1962 Variable *Base = llvm::dyn_cast<Variable>(Addr); 2055 Variable *Base = llvm::dyn_cast<Variable>(Addr);
1963 computeAddressOpt(Base, Index, Shift, Offset); 2056 computeAddressOpt(Base, Index, Shift, Offset);
1964 if (Base && Addr != Base) { 2057 if (Base && Addr != Base) {
1965 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); 2058 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
1966 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, 2059 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index,
1967 Shift); 2060 Shift, SegmentReg);
1968 Inst->setDeleted(); 2061 Inst->setDeleted();
1969 Context.insert(InstLoad::create(Func, Dest, Addr)); 2062 Context.insert(InstLoad::create(Func, Dest, Addr));
1970 } 2063 }
1971 } 2064 }
1972 2065
1973 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { 2066 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) {
1974 Func->setError("Phi found in regular instruction list"); 2067 Func->setError("Phi found in regular instruction list");
1975 } 2068 }
1976 2069
1977 void TargetX8632::lowerRet(const InstRet *Inst) { 2070 void TargetX8632::lowerRet(const InstRet *Inst) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 Value = legalize(Value, Legal_Reg | Legal_Imm, true); 2159 Value = legalize(Value, Legal_Reg | Legal_Imm, true);
2067 _store(Value, NewAddr); 2160 _store(Value, NewAddr);
2068 } 2161 }
2069 } 2162 }
2070 2163
2071 void TargetX8632::doAddressOptStore() { 2164 void TargetX8632::doAddressOptStore() {
2072 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); 2165 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur());
2073 Operand *Data = Inst->getData(); 2166 Operand *Data = Inst->getData();
2074 Operand *Addr = Inst->getAddr(); 2167 Operand *Addr = Inst->getAddr();
2075 Variable *Index = NULL; 2168 Variable *Index = NULL;
2076 int32_t Shift = 0; 2169 uint16_t Shift = 0;
2077 int32_t Offset = 0; // TODO: make Constant 2170 int32_t Offset = 0; // TODO: make Constant
2078 Variable *Base = llvm::dyn_cast<Variable>(Addr); 2171 Variable *Base = llvm::dyn_cast<Variable>(Addr);
2172 // Vanilla ICE load instructions should not use the segment registers,
2173 // and computeAddressOpt only works at the level of Variables and Constants,
2174 // not other OperandX8632Mem, so there should be no mention of segment
2175 // registers there either.
2176 const OperandX8632Mem::SegmentRegisters SegmentReg =
2177 OperandX8632Mem::DefaultSegment;
2079 computeAddressOpt(Base, Index, Shift, Offset); 2178 computeAddressOpt(Base, Index, Shift, Offset);
2080 if (Base && Addr != Base) { 2179 if (Base && Addr != Base) {
2081 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); 2180 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
2082 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, 2181 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index,
2083 Shift); 2182 Shift, SegmentReg);
2084 Inst->setDeleted(); 2183 Inst->setDeleted();
2085 Context.insert(InstStore::create(Func, Data, Addr)); 2184 Context.insert(InstStore::create(Func, Data, Addr));
2086 } 2185 }
2087 } 2186 }
2088 2187
2089 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { 2188 void TargetX8632::lowerSwitch(const InstSwitch *Inst) {
2090 // This implements the most naive possible lowering. 2189 // This implements the most naive possible lowering.
2091 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default 2190 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
2092 Operand *Src0 = Inst->getComparison(); 2191 Operand *Src0 = Inst->getComparison();
2093 SizeT NumCases = Inst->getNumCases(); 2192 SizeT NumCases = Inst->getNumCases();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 Variable *RegIndex = NULL; 2233 Variable *RegIndex = NULL;
2135 if (Base) { 2234 if (Base) {
2136 RegBase = legalizeToVar(Base, true); 2235 RegBase = legalizeToVar(Base, true);
2137 } 2236 }
2138 if (Index) { 2237 if (Index) {
2139 RegIndex = legalizeToVar(Index, true); 2238 RegIndex = legalizeToVar(Index, true);
2140 } 2239 }
2141 if (Base != RegBase || Index != RegIndex) { 2240 if (Base != RegBase || Index != RegIndex) {
2142 From = 2241 From =
2143 OperandX8632Mem::create(Func, Mem->getType(), RegBase, 2242 OperandX8632Mem::create(Func, Mem->getType(), RegBase,
2144 Mem->getOffset(), RegIndex, Mem->getShift()); 2243 Mem->getOffset(), RegIndex, Mem->getShift(),
2244 Mem->getSegmentRegister());
2145 } 2245 }
2146 2246
2147 if (!(Allowed & Legal_Mem)) { 2247 if (!(Allowed & Legal_Mem)) {
2148 Variable *Reg = makeReg(From->getType(), RegNum); 2248 Variable *Reg = makeReg(From->getType(), RegNum);
2149 _mov(Reg, From, RegNum); 2249 _mov(Reg, From, RegNum);
2150 From = Reg; 2250 From = Reg;
2151 } 2251 }
2152 return From; 2252 return From;
2153 } 2253 }
2154 if (llvm::isa<Constant>(From)) { 2254 if (llvm::isa<Constant>(From)) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 // llvm-mc doesn't parse "dword ptr [.L$foo]". 2361 // llvm-mc doesn't parse "dword ptr [.L$foo]".
2262 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; 2362 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
2263 } 2363 }
2264 2364
2265 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { 2365 template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
2266 Ostream &Str = Ctx->getStrEmit(); 2366 Ostream &Str = Ctx->getStrEmit();
2267 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; 2367 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
2268 } 2368 }
2269 2369
2270 } // end of namespace Ice 2370 } // end of namespace Ice
OLDNEW
« crosstest/runtests.sh ('K') | « src/IceTargetLoweringX8632.h ('k') | src/llvm2ice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698