llvm.org GIT mirror llvm / bdcb222
Merging MIPS GOT changeset into 3.2 release branch. Merging r168471: Mips direct object xgot support This patch provides support for the MIPS relocations: *) R_MIPS_GOT_HI16 *) R_MIPS_GOT_LO16 *) R_MIPS_CALL_HI16 *) R_MIPS_CALL_LO16 These are used for large GOT instruction sequences. Contributer: Jack Carter Merging r168460: [mips] Generate big GOT code. Merging r168458: [mips] Simplify lowering functions in MipsISelLowering.cpp by using the helper functions added in r168456. Merging r168456: [mips] Add helper functions that create nodes for computing address. Merging r168455: [mips] Add command line option "-mxgot". Merging r168453: [mips] When a node which loads from a GOT is created, pass a MachinePointerInfo referring to a GOT entry. Merging r168450: [mips] Add target operand flag enums for big GOT relocations. Merging r168448: Add relocations used for mips big GOT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@169294 91177308-0d34-0410-b5e6-96231b3b80d8 Pawel Wodnicki 6 years ago
14 changed file(s) with 281 addition(s) and 154 deletion(s). Raw diff Collapse all Expand all
196196 VK_Mips_GOT_PAGE,
197197 VK_Mips_GOT_OFST,
198198 VK_Mips_HIGHER,
199 VK_Mips_HIGHEST
199 VK_Mips_HIGHEST,
200 VK_Mips_GOT_HI16,
201 VK_Mips_GOT_LO16,
202 VK_Mips_CALL_HI16,
203 VK_Mips_CALL_LO16
200204 };
201205
202206 private:
228228 case VK_Mips_GOT_OFST: return "GOT_OFST";
229229 case VK_Mips_HIGHER: return "HIGHER";
230230 case VK_Mips_HIGHEST: return "HIGHEST";
231 case VK_Mips_GOT_HI16: return "GOT_HI16";
232 case VK_Mips_GOT_LO16: return "GOT_LO16";
233 case VK_Mips_CALL_HI16: return "CALL_HI16";
234 case VK_Mips_CALL_LO16: return "CALL_LO16";
231235 }
232236 llvm_unreachable("Invalid variant kind");
233237 }
127127 case MCSymbolRefExpr::VK_Mips_GOT_OFST: OS << "%got_ofst("; break;
128128 case MCSymbolRefExpr::VK_Mips_HIGHER: OS << "%higher("; break;
129129 case MCSymbolRefExpr::VK_Mips_HIGHEST: OS << "%highest("; break;
130 case MCSymbolRefExpr::VK_Mips_GOT_HI16: OS << "%got_hi("; break;
131 case MCSymbolRefExpr::VK_Mips_GOT_LO16: OS << "%got_lo("; break;
132 case MCSymbolRefExpr::VK_Mips_CALL_HI16: OS << "%call_hi("; break;
133 case MCSymbolRefExpr::VK_Mips_CALL_LO16: OS << "%call_lo("; break;
130134 }
131135
132136 OS << SRE->getSymbol();
4141 case Mips::fixup_Mips_GOT_PAGE:
4242 case Mips::fixup_Mips_GOT_OFST:
4343 case Mips::fixup_Mips_GOT_DISP:
44 case Mips::fixup_Mips_GOT_LO16:
45 case Mips::fixup_Mips_CALL_LO16:
4446 break;
4547 case Mips::fixup_Mips_PC16:
4648 // So far we are only using this type for branches.
5961 break;
6062 case Mips::fixup_Mips_HI16:
6163 case Mips::fixup_Mips_GOT_Local:
64 case Mips::fixup_Mips_GOT_HI16:
65 case Mips::fixup_Mips_CALL_HI16:
6266 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
6367 Value = ((Value + 0x8000) >> 16) & 0xffff;
6468 break;
178182 { "fixup_Mips_GOT_OFST", 0, 16, 0 },
179183 { "fixup_Mips_GOT_DISP", 0, 16, 0 },
180184 { "fixup_Mips_HIGHER", 0, 16, 0 },
181 { "fixup_Mips_HIGHEST", 0, 16, 0 }
185 { "fixup_Mips_HIGHEST", 0, 16, 0 },
186 { "fixup_Mips_GOT_HI16", 0, 16, 0 },
187 { "fixup_Mips_GOT_LO16", 0, 16, 0 },
188 { "fixup_Mips_CALL_HI16", 0, 16, 0 },
189 { "fixup_Mips_CALL_LO16", 0, 16, 0 }
182190 };
183191
184192 if (Kind < FirstTargetFixupKind)
8383 /// MO_HIGHER/HIGHEST - Represents the highest or higher half word of a
8484 /// 64-bit symbol address.
8585 MO_HIGHER,
86 MO_HIGHEST
86 MO_HIGHEST,
87
88 /// MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
89 MO_GOT_HI16,
90 MO_GOT_LO16,
91 MO_CALL_HI16,
92 MO_CALL_LO16
8793 };
8894
8995 enum {
178178 case Mips::fixup_Mips_HIGHEST:
179179 Type = ELF::R_MIPS_HIGHEST;
180180 break;
181 case Mips::fixup_Mips_GOT_HI16:
182 Type = ELF::R_MIPS_GOT_HI16;
183 break;
184 case Mips::fixup_Mips_GOT_LO16:
185 Type = ELF::R_MIPS_GOT_LO16;
186 break;
187 case Mips::fixup_Mips_CALL_HI16:
188 Type = ELF::R_MIPS_CALL_HI16;
189 break;
190 case Mips::fixup_Mips_CALL_LO16:
191 Type = ELF::R_MIPS_CALL_LO16;
192 break;
181193 }
182194 return Type;
183195 }
115115 // resulting in - R_MIPS_HIGHEST
116116 fixup_Mips_HIGHEST,
117117
118 // resulting in - R_MIPS_GOT_HI16
119 fixup_Mips_GOT_HI16,
120
121 // resulting in - R_MIPS_GOT_LO16
122 fixup_Mips_GOT_LO16,
123
124 // resulting in - R_MIPS_CALL_HI16
125 fixup_Mips_CALL_HI16,
126
127 // resulting in - R_MIPS_CALL_LO16
128 fixup_Mips_CALL_LO16,
129
118130 // Marker
119131 LastTargetFixupKind,
120132 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
286286 case MCSymbolRefExpr::VK_Mips_HIGHEST:
287287 FixupKind = Mips::fixup_Mips_HIGHEST;
288288 break;
289 case MCSymbolRefExpr::VK_Mips_GOT_HI16:
290 FixupKind = Mips::fixup_Mips_GOT_HI16;
291 break;
292 case MCSymbolRefExpr::VK_Mips_GOT_LO16:
293 FixupKind = Mips::fixup_Mips_GOT_LO16;
294 break;
295 case MCSymbolRefExpr::VK_Mips_CALL_HI16:
296 FixupKind = Mips::fixup_Mips_CALL_HI16;
297 break;
298 case MCSymbolRefExpr::VK_Mips_CALL_LO16:
299 FixupKind = Mips::fixup_Mips_CALL_LO16;
300 break;
289301 } // switch
290302
291303 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), MCFixupKind(FixupKind)));
254254 def : MipsPat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>;
255255 def : MipsPat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>;
256256 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>;
257 def : MipsPat<(MipsHi texternalsym:$in), (LUi64 texternalsym:$in)>;
257258
258259 def : MipsPat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>;
259260 def : MipsPat<(MipsLo tblockaddress:$in), (DADDiu ZERO_64, tblockaddress:$in)>;
261262 def : MipsPat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>;
262263 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
263264 (DADDiu ZERO_64, tglobaltlsaddr:$in)>;
265 def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>;
264266
265267 def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaladdr:$lo)),
266268 (DADDiu CPU64Regs:$hi, tglobaladdr:$lo)>;
4545 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
4646 cl::desc("MIPS: Enable tail calls."), cl::init(false));
4747
48 static cl::opt
49 LargeGOT("mxgot", cl::Hidden,
50 cl::desc("MIPS: Enable GOT larger than 64k."), cl::init(false));
51
4852 static const uint16_t O32IntRegs[4] = {
4953 Mips::A0, Mips::A1, Mips::A2, Mips::A3
5054 };
7478 static SDValue GetGlobalReg(SelectionDAG &DAG, EVT Ty) {
7579 MipsFunctionInfo *FI = DAG.getMachineFunction().getInfo();
7680 return DAG.getRegister(FI->getGlobalBaseReg(), Ty);
81 }
82
83 static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) {
84 EVT Ty = Op.getValueType();
85
86 if (GlobalAddressSDNode *N = dyn_cast(Op))
87 return DAG.getTargetGlobalAddress(N->getGlobal(), Op.getDebugLoc(), Ty, 0,
88 Flag);
89 if (ExternalSymbolSDNode *N = dyn_cast(Op))
90 return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);
91 if (BlockAddressSDNode *N = dyn_cast(Op))
92 return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);
93 if (JumpTableSDNode *N = dyn_cast(Op))
94 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);
95 if (ConstantPoolSDNode *N = dyn_cast(Op))
96 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlignment(),
97 N->getOffset(), Flag);
98
99 llvm_unreachable("Unexpected node type.");
100 return SDValue();
101 }
102
103 static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) {
104 DebugLoc DL = Op.getDebugLoc();
105 EVT Ty = Op.getValueType();
106 SDValue Hi = getTargetNode(Op, DAG, MipsII::MO_ABS_HI);
107 SDValue Lo = getTargetNode(Op, DAG, MipsII::MO_ABS_LO);
108 return DAG.getNode(ISD::ADD, DL, Ty,
109 DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
110 DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
111 }
112
113 static SDValue getAddrLocal(SDValue Op, SelectionDAG &DAG, bool HasMips64) {
114 DebugLoc DL = Op.getDebugLoc();
115 EVT Ty = Op.getValueType();
116 unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
117 SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, GetGlobalReg(DAG, Ty),
118 getTargetNode(Op, DAG, GOTFlag));
119 SDValue Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,
120 MachinePointerInfo::getGOT(), false, false, false,
121 0);
122 unsigned LoFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
123 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty, getTargetNode(Op, DAG, LoFlag));
124 return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);
125 }
126
127 static SDValue getAddrGlobal(SDValue Op, SelectionDAG &DAG, unsigned Flag) {
128 DebugLoc DL = Op.getDebugLoc();
129 EVT Ty = Op.getValueType();
130 SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, GetGlobalReg(DAG, Ty),
131 getTargetNode(Op, DAG, Flag));
132 return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Tgt,
133 MachinePointerInfo::getGOT(), false, false, false, 0);
134 }
135
136 static SDValue getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG,
137 unsigned HiFlag, unsigned LoFlag) {
138 DebugLoc DL = Op.getDebugLoc();
139 EVT Ty = Op.getValueType();
140 SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(Op, DAG, HiFlag));
141 Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, GetGlobalReg(DAG, Ty));
142 SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
143 getTargetNode(Op, DAG, LoFlag));
144 return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Wrapper,
145 MachinePointerInfo::getGOT(), false, false, false, 0);
77146 }
78147
79148 const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
17421811 const GlobalValue *GV = cast(Op)->getGlobal();
17431812
17441813 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
1745 SDVTList VTs = DAG.getVTList(MVT::i32);
1746
17471814 const MipsTargetObjectFile &TLOF =
17481815 (const MipsTargetObjectFile&)getObjFileLowering();
17491816
17511818 if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
17521819 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
17531820 MipsII::MO_GPREL);
1754 SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
1821 SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl,
1822 DAG.getVTList(MVT::i32), &GA, 1);
17551823 SDValue GPReg = DAG.getRegister(Mips::GP, MVT::i32);
17561824 return DAG.getNode(ISD::ADD, dl, MVT::i32, GPReg, GPRelNode);
17571825 }
1826
17581827 // %hi/%lo relocation
1759 SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
1760 MipsII::MO_ABS_HI);
1761 SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
1762 MipsII::MO_ABS_LO);
1763 SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GAHi, 1);
1764 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo);
1765 return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo);
1766 }
1767
1768 EVT ValTy = Op.getValueType();
1769 bool HasGotOfst = (GV->hasInternalLinkage() ||
1770 (GV->hasLocalLinkage() && !isa(GV)));
1771 unsigned GotFlag = HasMips64 ?
1772 (HasGotOfst ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT_DISP) :
1773 (HasGotOfst ? MipsII::MO_GOT : MipsII::MO_GOT16);
1774 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, ValTy, 0, GotFlag);
1775 GA = DAG.getNode(MipsISD::Wrapper, dl, ValTy, GetGlobalReg(DAG, ValTy), GA);
1776 SDValue ResNode = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), GA,
1777 MachinePointerInfo(), false, false, false, 0);
1778 // On functions and global targets not internal linked only
1779 // a load from got/GP is necessary for PIC to work.
1780 if (!HasGotOfst)
1781 return ResNode;
1782 SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, ValTy, 0,
1783 HasMips64 ? MipsII::MO_GOT_OFST :
1784 MipsII::MO_ABS_LO);
1785 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, GALo);
1786 return DAG.getNode(ISD::ADD, dl, ValTy, ResNode, Lo);
1828 return getAddrNonPIC(Op, DAG);
1829 }
1830
1831 if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa(GV)))
1832 return getAddrLocal(Op, DAG, HasMips64);
1833
1834 if (LargeGOT)
1835 return getAddrGlobalLargeGOT(Op, DAG, MipsII::MO_GOT_HI16,
1836 MipsII::MO_GOT_LO16);
1837
1838 return getAddrGlobal(Op, DAG,
1839 HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16);
17871840 }
17881841
17891842 SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
17901843 SelectionDAG &DAG) const {
1791 const BlockAddress *BA = cast(Op)->getBlockAddress();
1792 // FIXME there isn't actually debug info here
1793 DebugLoc dl = Op.getDebugLoc();
1794
1795 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
1796 // %hi/%lo relocation
1797 SDValue BAHi =
1798 DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
1799 SDValue BALo =
1800 DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
1801 SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
1802 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
1803 return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
1804 }
1805
1806 EVT ValTy = Op.getValueType();
1807 unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
1808 unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
1809 SDValue BAGOTOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, GOTFlag);
1810 BAGOTOffset = DAG.getNode(MipsISD::Wrapper, dl, ValTy,
1811 GetGlobalReg(DAG, ValTy), BAGOTOffset);
1812 SDValue BALOOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, OFSTFlag);
1813 SDValue Load = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), BAGOTOffset,
1814 MachinePointerInfo(), false, false, false, 0);
1815 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, BALOOffset);
1816 return DAG.getNode(ISD::ADD, dl, ValTy, Load, Lo);
1844 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1845 return getAddrNonPIC(Op, DAG);
1846
1847 return getAddrLocal(Op, DAG, HasMips64);
18171848 }
18181849
18191850 SDValue MipsTargetLowering::
19001931 SDValue MipsTargetLowering::
19011932 LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
19021933 {
1903 SDValue HiPart, JTI, JTILo;
1904 // FIXME there isn't actually debug info here
1905 DebugLoc dl = Op.getDebugLoc();
1906 bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
1907 EVT PtrVT = Op.getValueType();
1908 JumpTableSDNode *JT = cast(Op);
1909
1910 if (!IsPIC && !IsN64) {
1911 JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_HI);
1912 HiPart = DAG.getNode(MipsISD::Hi, dl, PtrVT, JTI);
1913 JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO);
1914 } else {// Emit Load from Global Pointer
1915 unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
1916 unsigned OfstFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
1917 JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, GOTFlag);
1918 JTI = DAG.getNode(MipsISD::Wrapper, dl, PtrVT, GetGlobalReg(DAG, PtrVT),
1919 JTI);
1920 HiPart = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), JTI,
1921 MachinePointerInfo(), false, false, false, 0);
1922 JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OfstFlag);
1923 }
1924
1925 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, PtrVT, JTILo);
1926 return DAG.getNode(ISD::ADD, dl, PtrVT, HiPart, Lo);
1934 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1935 return getAddrNonPIC(Op, DAG);
1936
1937 return getAddrLocal(Op, DAG, HasMips64);
19271938 }
19281939
19291940 SDValue MipsTargetLowering::
19301941 LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
19311942 {
1932 SDValue ResNode;
1933 ConstantPoolSDNode *N = cast(Op);
1934 const Constant *C = N->getConstVal();
1935 // FIXME there isn't actually debug info here
1936 DebugLoc dl = Op.getDebugLoc();
1937
19381943 // gp_rel relocation
19391944 // FIXME: we should reference the constant pool using small data sections,
19401945 // but the asm printer currently doesn't support this feature without
19451950 // SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
19461951 // ResNode = DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode);
19471952
1948 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
1949 SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
1950 N->getOffset(), MipsII::MO_ABS_HI);
1951 SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
1952 N->getOffset(), MipsII::MO_ABS_LO);
1953 SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi);
1954 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo);
1955 ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo);
1956 } else {
1957 EVT ValTy = Op.getValueType();
1958 unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
1959 unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
1960 SDValue CP = DAG.getTargetConstantPool(C, ValTy, N->getAlignment(),
1961 N->getOffset(), GOTFlag);
1962 CP = DAG.getNode(MipsISD::Wrapper, dl, ValTy, GetGlobalReg(DAG, ValTy), CP);
1963 SDValue Load = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), CP,
1964 MachinePointerInfo::getConstantPool(), false,
1965 false, false, 0);
1966 SDValue CPLo = DAG.getTargetConstantPool(C, ValTy, N->getAlignment(),
1967 N->getOffset(), OFSTFlag);
1968 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, CPLo);
1969 ResNode = DAG.getNode(ISD::ADD, dl, ValTy, Load, Lo);
1970 }
1971
1972 return ResNode;
1953 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64)
1954 return getAddrNonPIC(Op, DAG);
1955
1956 return getAddrLocal(Op, DAG, HasMips64);
19731957 }
19741958
19751959 SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
28612845 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
28622846 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
28632847 // node so that legalize doesn't hack it.
2864 unsigned char OpFlag;
28652848 bool IsPICCall = (IsN64 || IsPIC); // true if calls are translated to jalr $25
28662849 bool GlobalOrExternal = false;
28672850 SDValue CalleeLo;
28682851
28692852 if (GlobalAddressSDNode *G = dyn_cast(Callee)) {
2870 if (IsPICCall && G->getGlobal()->hasInternalLinkage()) {
2871 OpFlag = IsO32 ? MipsII::MO_GOT : MipsII::MO_GOT_PAGE;
2872 unsigned char LoFlag = IsO32 ? MipsII::MO_ABS_LO : MipsII::MO_GOT_OFST;
2853 if (IsPICCall) {
2854 if (G->getGlobal()->hasInternalLinkage())
2855 Callee = getAddrLocal(Callee, DAG, HasMips64);
2856 else if (LargeGOT)
2857 Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
2858 MipsII::MO_CALL_LO16);
2859 else
2860 Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
2861 } else
28732862 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy(), 0,
2874 OpFlag);
2875 CalleeLo = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy(),
2876 0, LoFlag);
2877 } else {
2878 OpFlag = IsPICCall ? MipsII::MO_GOT_CALL : MipsII::MO_NO_FLAG;
2879 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl,
2880 getPointerTy(), 0, OpFlag);
2881 }
2882
2863 MipsII::MO_NO_FLAG);
28832864 GlobalOrExternal = true;
28842865 }
28852866 else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) {
2886 if (IsN64 || (!IsO32 && IsPIC))
2887 OpFlag = MipsII::MO_GOT_DISP;
2888 else if (!IsPIC) // !N64 && static
2889 OpFlag = MipsII::MO_NO_FLAG;
2867 if (!IsN64 && !IsPIC) // !N64 && static
2868 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
2869 MipsII::MO_NO_FLAG);
2870 else if (LargeGOT)
2871 Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
2872 MipsII::MO_CALL_LO16);
2873 else if (HasMips64)
2874 Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_DISP);
28902875 else // O32 & PIC
2891 OpFlag = MipsII::MO_GOT_CALL;
2892 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
2893 OpFlag);
2876 Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
2877
28942878 GlobalOrExternal = true;
28952879 }
28962880
28972881 SDValue InFlag;
2898
2899 // Create nodes that load address of callee and copy it to T9
2900 if (IsPICCall) {
2901 if (GlobalOrExternal) {
2902 // Load callee address
2903 Callee = DAG.getNode(MipsISD::Wrapper, dl, getPointerTy(),
2904 GetGlobalReg(DAG, getPointerTy()), Callee);
2905 SDValue LoadValue = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
2906 Callee, MachinePointerInfo::getGOT(),
2907 false, false, false, 0);
2908
2909 // Use GOT+LO if callee has internal linkage.
2910 if (CalleeLo.getNode()) {
2911 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, getPointerTy(), CalleeLo);
2912 Callee = DAG.getNode(ISD::ADD, dl, getPointerTy(), LoadValue, Lo);
2913 } else
2914 Callee = LoadValue;
2915 }
2916 }
29172882
29182883 // T9 register operand.
29192884 SDValue T9;
11531153 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
11541154 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
11551155 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1156 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
11561157
11571158 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
11581159 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
11591160 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
11601161 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
11611162 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1163 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
11621164
11631165 def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
11641166 (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
6161 case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break;
6262 case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break;
6363 case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break;
64 case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break;
65 case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break;
66 case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break;
67 case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break;
6468 }
6569
6670 switch (MOTy) {
0 ; RUN: llc -march=mipsel -mxgot < %s | FileCheck %s -check-prefix=O32
1 ; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=+n64 -mxgot < %s | \
2 ; RUN: FileCheck %s -check-prefix=N64
3
4 @v0 = external global i32
5
6 define void @foo1() nounwind {
7 entry:
8 ; O32: lui $[[R0:[0-9]+]], %got_hi(v0)
9 ; O32: addu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
10 ; O32: lw ${{[0-9]+}}, %got_lo(v0)($[[R1]])
11 ; O32: lui $[[R2:[0-9]+]], %call_hi(foo0)
12 ; O32: addu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
13 ; O32: lw ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
14
15 ; N64: lui $[[R0:[0-9]+]], %got_hi(v0)
16 ; N64: daddu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
17 ; N64: ld ${{[0-9]+}}, %got_lo(v0)($[[R1]])
18 ; N64: lui $[[R2:[0-9]+]], %call_hi(foo0)
19 ; N64: daddu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
20 ; N64: ld ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
21
22 %0 = load i32* @v0, align 4
23 tail call void @foo0(i32 %0) nounwind
24 ret void
25 }
26
27 declare void @foo0(i32)
28
29 ; call to external function.
30
31 define void @foo2(i32* nocapture %d, i32* nocapture %s, i32 %n) nounwind {
32 entry:
33 ; O32: foo2:
34 ; O32: lui $[[R2:[0-9]+]], %call_hi(memcpy)
35 ; O32: addu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
36 ; O32: lw ${{[0-9]+}}, %call_lo(memcpy)($[[R3]])
37
38 ; N64: foo2:
39 ; N64: lui $[[R2:[0-9]+]], %call_hi(memcpy)
40 ; N64: daddu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
41 ; N64: ld ${{[0-9]+}}, %call_lo(memcpy)($[[R3]])
42
43 %0 = bitcast i32* %d to i8*
44 %1 = bitcast i32* %s to i8*
45 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 %n, i32 4, i1 false)
46 ret void
47 }
48
49 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
0 ; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mxgot %s -o - | elf-dump --dump-section-data | FileCheck %s
1
2 @.str = private unnamed_addr constant [16 x i8] c"ext_1=%d, i=%d\0A\00", align 1
3 @ext_1 = external global i32
4
5 define void @fill() nounwind {
6 entry:
7
8 ; Check that the appropriate relocations were created.
9 ; For the xgot case we want to see R_MIPS_[GOT|CALL]_[HI|LO]16.
10
11 ; R_MIPS_HI16
12 ; CHECK: ('r_type', 0x05)
13
14 ; R_MIPS_LO16
15 ; CHECK: ('r_type', 0x06)
16
17 ; R_MIPS_GOT_HI16
18 ; CHECK: ('r_type', 0x16)
19
20 ; R_MIPS_GOT_LO16
21 ; CHECK: ('r_type', 0x17)
22
23 ; R_MIPS_GOT
24 ; CHECK: ('r_type', 0x09)
25
26 ; R_MIPS_LO16
27 ; CHECK: ('r_type', 0x06)
28
29 ; R_MIPS_CALL_HI16
30 ; CHECK: ('r_type', 0x1e)
31
32 ; R_MIPS_CALL_LO16
33 ; CHECK: ('r_type', 0x1f)
34
35 %0 = load i32* @ext_1, align 4
36 %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i32 0, i32 0), i32 %0) nounwind
37 ret void
38 }
39
40 declare i32 @printf(i8* nocapture, ...) nounwind
41