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

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: remove TODO 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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 if (Arg->hasReg()) { 424 if (Arg->hasReg()) {
425 assert(Ty != IceType_i64); 425 assert(Ty != IceType_i64);
426 OperandX8632Mem *Mem = OperandX8632Mem::create( 426 OperandX8632Mem *Mem = OperandX8632Mem::create(
427 Func, Ty, FramePtr, 427 Func, Ty, FramePtr,
428 Ctx->getConstantInt(IceType_i32, Arg->getStackOffset())); 428 Ctx->getConstantInt(IceType_i32, Arg->getStackOffset()));
429 _mov(Arg, Mem); 429 _mov(Arg, Mem);
430 } 430 }
431 InArgsSizeBytes += typeWidthInBytesOnStack(Ty); 431 InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
432 } 432 }
433 433
434 // static
435 Type TargetX8632::stackSlotType() { return IceType_i32; }
436
434 void TargetX8632::addProlog(CfgNode *Node) { 437 void TargetX8632::addProlog(CfgNode *Node) {
435 // If SimpleCoalescing is false, each variable without a register 438 // If SimpleCoalescing is false, each variable without a register
436 // gets its own unique stack slot, which leads to large stack 439 // gets its own unique stack slot, which leads to large stack
437 // frames. If SimpleCoalescing is true, then each "global" variable 440 // frames. If SimpleCoalescing is true, then each "global" variable
438 // without a register gets its own slot, but "local" variable slots 441 // without a register gets its own slot, but "local" variable slots
439 // are reused across basic blocks. E.g., if A and B are local to 442 // are reused across basic blocks. E.g., if A and B are local to
440 // block 1 and C is local to block 2, then C may share a slot with A 443 // block 1 and C is local to block 2, then C may share a slot with A
441 // or B. 444 // or B.
442 const bool SimpleCoalescing = true; 445 const bool SimpleCoalescing = true;
443 size_t InArgsSizeBytes = 0; 446 size_t InArgsSizeBytes = 0;
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 split64(Var); 756 split64(Var);
754 return Var->getLo(); 757 return Var->getLo();
755 } 758 }
756 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { 759 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
757 uint64_t Mask = (1ull << 32) - 1; 760 uint64_t Mask = (1ull << 32) - 1;
758 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask); 761 return Ctx->getConstantInt(IceType_i32, Const->getValue() & Mask);
759 } 762 }
760 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 763 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
761 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 764 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(),
762 Mem->getOffset(), Mem->getIndex(), 765 Mem->getOffset(), Mem->getIndex(),
763 Mem->getShift()); 766 Mem->getShift(), Mem->getSegmentRegister());
764 } 767 }
765 llvm_unreachable("Unsupported operand type"); 768 llvm_unreachable("Unsupported operand type");
766 return NULL; 769 return NULL;
767 } 770 }
768 771
769 Operand *TargetX8632::hiOperand(Operand *Operand) { 772 Operand *TargetX8632::hiOperand(Operand *Operand) {
770 assert(Operand->getType() == IceType_i64); 773 assert(Operand->getType() == IceType_i64);
771 if (Operand->getType() != IceType_i64) 774 if (Operand->getType() != IceType_i64)
772 return Operand; 775 return Operand;
773 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 776 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
774 split64(Var); 777 split64(Var);
775 return Var->getHi(); 778 return Var->getHi();
776 } 779 }
777 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) { 780 if (ConstantInteger *Const = llvm::dyn_cast<ConstantInteger>(Operand)) {
778 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32); 781 return Ctx->getConstantInt(IceType_i32, Const->getValue() >> 32);
779 } 782 }
780 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 783 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
781 Constant *Offset = Mem->getOffset(); 784 Constant *Offset = Mem->getOffset();
782 if (Offset == NULL) 785 if (Offset == NULL)
783 Offset = Ctx->getConstantInt(IceType_i32, 4); 786 Offset = Ctx->getConstantInt(IceType_i32, 4);
784 else if (ConstantInteger *IntOffset = 787 else if (ConstantInteger *IntOffset =
785 llvm::dyn_cast<ConstantInteger>(Offset)) { 788 llvm::dyn_cast<ConstantInteger>(Offset)) {
786 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue()); 789 Offset = Ctx->getConstantInt(IceType_i32, 4 + IntOffset->getValue());
787 } else if (ConstantRelocatable *SymOffset = 790 } else if (ConstantRelocatable *SymOffset =
788 llvm::dyn_cast<ConstantRelocatable>(Offset)) { 791 llvm::dyn_cast<ConstantRelocatable>(Offset)) {
789 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(), 792 Offset = Ctx->getConstantSym(IceType_i32, 4 + SymOffset->getOffset(),
790 SymOffset->getName()); 793 SymOffset->getName());
791 } 794 }
792 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, 795 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset,
793 Mem->getIndex(), Mem->getShift()); 796 Mem->getIndex(), Mem->getShift(),
797 Mem->getSegmentRegister());
794 } 798 }
795 llvm_unreachable("Unsupported operand type"); 799 llvm_unreachable("Unsupported operand type");
796 return NULL; 800 return NULL;
797 } 801 }
798 802
799 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include, 803 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
800 RegSetMask Exclude) const { 804 RegSetMask Exclude) const {
801 llvm::SmallBitVector Registers(Reg_NUM); 805 llvm::SmallBitVector Registers(Reg_NUM);
802 806
803 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ 807 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true); 1771 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true);
1768 InstX8632Label *Label = InstX8632Label::create(Func, this); 1772 InstX8632Label *Label = InstX8632Label::create(Func, this);
1769 _cmp(Src0New, Src1); 1773 _cmp(Src0New, Src1);
1770 _mov(Dest, One); 1774 _mov(Dest, One);
1771 _br(getIcmp32Mapping(Inst->getCondition()), Label); 1775 _br(getIcmp32Mapping(Inst->getCondition()), Label);
1772 Context.insert(InstFakeUse::create(Func, Dest)); 1776 Context.insert(InstFakeUse::create(Func, Dest));
1773 _mov(Dest, Zero); 1777 _mov(Dest, Zero);
1774 Context.insert(Label); 1778 Context.insert(Label);
1775 } 1779 }
1776 1780
1781 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
1782 switch (Instr->getIntrinsicInfo().ID) {
1783 case Intrinsics::AtomicCmpxchg:
1784 case Intrinsics::AtomicFence:
1785 case Intrinsics::AtomicFenceAll:
1786 case Intrinsics::AtomicIsLockFree:
1787 case Intrinsics::AtomicLoad:
1788 case Intrinsics::AtomicRMW:
1789 case Intrinsics::AtomicStore:
1790 case Intrinsics::Bswap:
1791 case Intrinsics::Ctlz:
1792 case Intrinsics::Ctpop:
1793 case Intrinsics::Cttz:
1794 Func->setError("Unhandled intrinsic");
1795 return;
1796 case Intrinsics::Longjmp: {
1797 InstCall *Call = makeHelperCall("longjmp", NULL, 2);
1798 Call->addArg(Instr->getArg(0));
1799 Call->addArg(Instr->getArg(1));
1800 lowerCall(Call);
1801 break;
1802 }
1803 case Intrinsics::Memcpy: {
1804 // In the future, we could potentially emit an inline memcpy/memset, etc.
1805 // for intrinsic calls w/ a known length.
1806 InstCall *Call = makeHelperCall("memcpy", NULL, 3);
1807 Call->addArg(Instr->getArg(0));
1808 Call->addArg(Instr->getArg(1));
1809 Call->addArg(Instr->getArg(2));
1810 lowerCall(Call);
1811 break;
1812 }
1813 case Intrinsics::Memmove: {
1814 InstCall *Call = makeHelperCall("memmove", NULL, 3);
1815 Call->addArg(Instr->getArg(0));
1816 Call->addArg(Instr->getArg(1));
1817 Call->addArg(Instr->getArg(2));
1818 lowerCall(Call);
1819 break;
1820 }
1821 case Intrinsics::Memset: {
1822 // The value operand needs to be extended to a stack slot size
1823 // because we "push" only works for a specific operand size.
1824 Operand *ValOp = Instr->getArg(1);
1825 assert(ValOp->getType() == IceType_i8);
1826 Variable *ValExt = makeReg(stackSlotType());
1827 _movzx(ValExt, ValOp);
1828 InstCall *Call = makeHelperCall("memset", NULL, 3);
1829 Call->addArg(Instr->getArg(0));
1830 Call->addArg(ValExt);
1831 Call->addArg(Instr->getArg(2));
1832 lowerCall(Call);
1833 break;
1834 }
1835 case Intrinsics::NaClReadTP: {
1836 Constant *Zero = Ctx->getConstantInt(IceType_i32, 0);
1837 Operand *Src = OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL,
1838 0, OperandX8632Mem::SegReg_GS);
1839 Variable *Dest = Instr->getDest();
1840 Variable *T = NULL;
1841 _mov(T, Src);
1842 _mov(Dest, T);
1843 break;
1844 }
1845 case Intrinsics::Setjmp: {
1846 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1);
1847 Call->addArg(Instr->getArg(0));
1848 lowerCall(Call);
1849 break;
1850 }
1851 case Intrinsics::Sqrt:
1852 case Intrinsics::Stacksave:
1853 case Intrinsics::Stackrestore:
1854 Func->setError("Unhandled intrinsic");
1855 return;
1856 case Intrinsics::Trap:
1857 _ud2();
1858 break;
1859 case Intrinsics::UnknownIntrinsic:
1860 Func->setError("Should not be lowering UnknownIntrinsic");
1861 return;
1862 }
1863 return;
1864 }
1865
1777 namespace { 1866 namespace {
1778 1867
1779 bool isAdd(const Inst *Inst) { 1868 bool isAdd(const Inst *Inst) {
1780 if (const InstArithmetic *Arith = 1869 if (const InstArithmetic *Arith =
1781 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 1870 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) {
1782 return (Arith->getOp() == InstArithmetic::Add); 1871 return (Arith->getOp() == InstArithmetic::Add);
1783 } 1872 }
1784 return false; 1873 return false;
1785 } 1874 }
1786 1875
1787 void computeAddressOpt(Variable *&Base, Variable *&Index, int32_t &Shift, 1876 void computeAddressOpt(Variable *&Base, Variable *&Index, uint16_t &Shift,
1788 int32_t &Offset) { 1877 int32_t &Offset) {
1789 (void)Offset; // TODO: pattern-match for non-zero offsets. 1878 (void)Offset; // TODO: pattern-match for non-zero offsets.
1790 if (Base == NULL) 1879 if (Base == NULL)
1791 return; 1880 return;
1792 // If the Base has more than one use or is live across multiple 1881 // If the Base has more than one use or is live across multiple
1793 // blocks, then don't go further. Alternatively (?), never consider 1882 // blocks, then don't go further. Alternatively (?), never consider
1794 // a transformation that would change a variable that is currently 1883 // a transformation that would change a variable that is currently
1795 // *not* live across basic block boundaries into one that *is*. 1884 // *not* live across basic block boundaries into one that *is*.
1796 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/) 1885 if (Base->isMultiblockLife() /* || Base->getUseCount() > 1*/)
1797 return; 1886 return;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1958 2047
1959 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); 2048 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0);
1960 lowerAssign(Assign); 2049 lowerAssign(Assign);
1961 } 2050 }
1962 2051
1963 void TargetX8632::doAddressOptLoad() { 2052 void TargetX8632::doAddressOptLoad() {
1964 Inst *Inst = *Context.getCur(); 2053 Inst *Inst = *Context.getCur();
1965 Variable *Dest = Inst->getDest(); 2054 Variable *Dest = Inst->getDest();
1966 Operand *Addr = Inst->getSrc(0); 2055 Operand *Addr = Inst->getSrc(0);
1967 Variable *Index = NULL; 2056 Variable *Index = NULL;
1968 int32_t Shift = 0; 2057 uint16_t Shift = 0;
1969 int32_t Offset = 0; // TODO: make Constant 2058 int32_t Offset = 0; // TODO: make Constant
2059 // Vanilla ICE load instructions should not use the segment registers,
2060 // and computeAddressOpt only works at the level of Variables and Constants,
2061 // not other OperandX8632Mem, so there should be no mention of segment
2062 // registers there either.
2063 const OperandX8632Mem::SegmentRegisters SegmentReg =
2064 OperandX8632Mem::DefaultSegment;
1970 Variable *Base = llvm::dyn_cast<Variable>(Addr); 2065 Variable *Base = llvm::dyn_cast<Variable>(Addr);
1971 computeAddressOpt(Base, Index, Shift, Offset); 2066 computeAddressOpt(Base, Index, Shift, Offset);
1972 if (Base && Addr != Base) { 2067 if (Base && Addr != Base) {
1973 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); 2068 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
1974 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, 2069 Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index,
1975 Shift); 2070 Shift, SegmentReg);
1976 Inst->setDeleted(); 2071 Inst->setDeleted();
1977 Context.insert(InstLoad::create(Func, Dest, Addr)); 2072 Context.insert(InstLoad::create(Func, Dest, Addr));
1978 } 2073 }
1979 } 2074 }
1980 2075
1981 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) { 2076 void TargetX8632::lowerPhi(const InstPhi * /*Inst*/) {
1982 Func->setError("Phi found in regular instruction list"); 2077 Func->setError("Phi found in regular instruction list");
1983 } 2078 }
1984 2079
1985 void TargetX8632::lowerRet(const InstRet *Inst) { 2080 void TargetX8632::lowerRet(const InstRet *Inst) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 Value = legalize(Value, Legal_Reg | Legal_Imm, true); 2169 Value = legalize(Value, Legal_Reg | Legal_Imm, true);
2075 _store(Value, NewAddr); 2170 _store(Value, NewAddr);
2076 } 2171 }
2077 } 2172 }
2078 2173
2079 void TargetX8632::doAddressOptStore() { 2174 void TargetX8632::doAddressOptStore() {
2080 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur()); 2175 InstStore *Inst = llvm::cast<InstStore>(*Context.getCur());
2081 Operand *Data = Inst->getData(); 2176 Operand *Data = Inst->getData();
2082 Operand *Addr = Inst->getAddr(); 2177 Operand *Addr = Inst->getAddr();
2083 Variable *Index = NULL; 2178 Variable *Index = NULL;
2084 int32_t Shift = 0; 2179 uint16_t Shift = 0;
2085 int32_t Offset = 0; // TODO: make Constant 2180 int32_t Offset = 0; // TODO: make Constant
2086 Variable *Base = llvm::dyn_cast<Variable>(Addr); 2181 Variable *Base = llvm::dyn_cast<Variable>(Addr);
2182 // Vanilla ICE store instructions should not use the segment registers,
2183 // and computeAddressOpt only works at the level of Variables and Constants,
2184 // not other OperandX8632Mem, so there should be no mention of segment
2185 // registers there either.
2186 const OperandX8632Mem::SegmentRegisters SegmentReg =
2187 OperandX8632Mem::DefaultSegment;
2087 computeAddressOpt(Base, Index, Shift, Offset); 2188 computeAddressOpt(Base, Index, Shift, Offset);
2088 if (Base && Addr != Base) { 2189 if (Base && Addr != Base) {
2089 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); 2190 Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset);
2090 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, 2191 Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index,
2091 Shift); 2192 Shift, SegmentReg);
2092 Inst->setDeleted(); 2193 Inst->setDeleted();
2093 Context.insert(InstStore::create(Func, Data, Addr)); 2194 Context.insert(InstStore::create(Func, Data, Addr));
2094 } 2195 }
2095 } 2196 }
2096 2197
2097 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { 2198 void TargetX8632::lowerSwitch(const InstSwitch *Inst) {
2098 // This implements the most naive possible lowering. 2199 // This implements the most naive possible lowering.
2099 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default 2200 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
2100 Operand *Src0 = Inst->getComparison(); 2201 Operand *Src0 = Inst->getComparison();
2101 SizeT NumCases = Inst->getNumCases(); 2202 SizeT NumCases = Inst->getNumCases();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 Variable *Index = Mem->getIndex(); 2241 Variable *Index = Mem->getIndex();
2141 Variable *RegBase = NULL; 2242 Variable *RegBase = NULL;
2142 Variable *RegIndex = NULL; 2243 Variable *RegIndex = NULL;
2143 if (Base) { 2244 if (Base) {
2144 RegBase = legalizeToVar(Base, true); 2245 RegBase = legalizeToVar(Base, true);
2145 } 2246 }
2146 if (Index) { 2247 if (Index) {
2147 RegIndex = legalizeToVar(Index, true); 2248 RegIndex = legalizeToVar(Index, true);
2148 } 2249 }
2149 if (Base != RegBase || Index != RegIndex) { 2250 if (Base != RegBase || Index != RegIndex) {
2150 From = 2251 From = OperandX8632Mem::create(
2151 OperandX8632Mem::create(Func, Mem->getType(), RegBase, 2252 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex,
2152 Mem->getOffset(), RegIndex, Mem->getShift()); 2253 Mem->getShift(), Mem->getSegmentRegister());
2153 } 2254 }
2154 2255
2155 if (!(Allowed & Legal_Mem)) { 2256 if (!(Allowed & Legal_Mem)) {
2156 Variable *Reg = makeReg(From->getType(), RegNum); 2257 Variable *Reg = makeReg(From->getType(), RegNum);
2157 _mov(Reg, From, RegNum); 2258 _mov(Reg, From, RegNum);
2158 From = Reg; 2259 From = Reg;
2159 } 2260 }
2160 return From; 2261 return From;
2161 } 2262 }
2162 if (llvm::isa<Constant>(From)) { 2263 if (llvm::isa<Constant>(From)) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 // llvm-mc doesn't parse "dword ptr [.L$foo]". 2388 // llvm-mc doesn't parse "dword ptr [.L$foo]".
2288 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; 2389 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
2289 } 2390 }
2290 2391
2291 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { 2392 template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
2292 Ostream &Str = Ctx->getStrEmit(); 2393 Ostream &Str = Ctx->getStrEmit();
2293 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; 2394 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
2294 } 2395 }
2295 2396
2296 } // end of namespace Ice 2397 } // 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