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

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 a run test 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
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/llvm2ice.cpp » ('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 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8632.h ('k') | src/llvm2ice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698