aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp4
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td2
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp16
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td2
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp4
-rw-r--r--test/CodeGen/Mips/biggot.ll50
6 files changed, 75 insertions, 3 deletions
diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
index b38463de4b..68d3ac5f3b 100644
--- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
+++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
@@ -128,6 +128,10 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
case MCSymbolRefExpr::VK_Mips_GOT_OFST: OS << "%got_ofst("; break;
case MCSymbolRefExpr::VK_Mips_HIGHER: OS << "%higher("; break;
case MCSymbolRefExpr::VK_Mips_HIGHEST: OS << "%highest("; break;
+ case MCSymbolRefExpr::VK_Mips_GOT_HI16: OS << "%got_hi("; break;
+ case MCSymbolRefExpr::VK_Mips_GOT_LO16: OS << "%got_lo("; break;
+ case MCSymbolRefExpr::VK_Mips_CALL_HI16: OS << "%call_hi("; break;
+ case MCSymbolRefExpr::VK_Mips_CALL_LO16: OS << "%call_lo("; break;
}
OS << SRE->getSymbol();
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index a6111689c7..83322eac8c 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -255,6 +255,7 @@ def : MipsPat<(MipsHi tblockaddress:$in), (LUi64 tblockaddress:$in)>;
def : MipsPat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>;
def : MipsPat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>;
def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>;
+def : MipsPat<(MipsHi texternalsym:$in), (LUi64 texternalsym:$in)>;
def : MipsPat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>;
def : MipsPat<(MipsLo tblockaddress:$in), (DADDiu ZERO_64, tblockaddress:$in)>;
@@ -262,6 +263,7 @@ def : MipsPat<(MipsLo tjumptable:$in), (DADDiu ZERO_64, tjumptable:$in)>;
def : MipsPat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>;
def : MipsPat<(MipsLo tglobaltlsaddr:$in),
(DADDiu ZERO_64, tglobaltlsaddr:$in)>;
+def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>;
def : MipsPat<(add CPU64Regs:$hi, (MipsLo tglobaladdr:$lo)),
(DADDiu CPU64Regs:$hi, tglobaladdr:$lo)>;
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 105c945328..2a3c5f91d4 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1832,6 +1832,10 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
if (GV->hasInternalLinkage() || (GV->hasLocalLinkage() && !isa<Function>(GV)))
return getAddrLocal(Op, DAG, HasMips64);
+ if (LargeGOT)
+ return getAddrGlobalLargeGOT(Op, DAG, MipsII::MO_GOT_HI16,
+ MipsII::MO_GOT_LO16);
+
return getAddrGlobal(Op, DAG,
HasMips64 ? MipsII::MO_GOT_DISP : MipsII::MO_GOT16);
}
@@ -2850,6 +2854,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (IsPICCall) {
if (G->getGlobal()->hasInternalLinkage())
Callee = getAddrLocal(Callee, DAG, HasMips64);
+ else if (LargeGOT)
+ Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
+ MipsII::MO_CALL_LO16);
else
Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
} else
@@ -2858,11 +2865,14 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
GlobalOrExternal = true;
}
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
- if (IsN64 || (!IsO32 && IsPIC))
- Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_DISP);
- else if (!IsPIC) // !N64 && static
+ if (!IsN64 && !IsPIC) // !N64 && static
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
MipsII::MO_NO_FLAG);
+ else if (LargeGOT)
+ Callee = getAddrGlobalLargeGOT(Callee, DAG, MipsII::MO_CALL_HI16,
+ MipsII::MO_CALL_LO16);
+ else if (HasMips64)
+ Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_DISP);
else // O32 & PIC
Callee = getAddrGlobal(Callee, DAG, MipsII::MO_GOT_CALL);
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 9197066289..9bf5d6b7d7 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -1154,12 +1154,14 @@ def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
+def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
+def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
index 5fa6339338..4162f981d1 100644
--- a/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/lib/Target/Mips/MipsMCInstLower.cpp
@@ -62,6 +62,10 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break;
case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break;
case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break;
+ case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break;
+ case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break;
+ case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break;
+ case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break;
}
switch (MOTy) {
diff --git a/test/CodeGen/Mips/biggot.ll b/test/CodeGen/Mips/biggot.ll
new file mode 100644
index 0000000000..c4ad851c82
--- /dev/null
+++ b/test/CodeGen/Mips/biggot.ll
@@ -0,0 +1,50 @@
+; RUN: llc -march=mipsel -mxgot < %s | FileCheck %s -check-prefix=O32
+; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=+n64 -mxgot < %s | \
+; RUN: FileCheck %s -check-prefix=N64
+
+@v0 = external global i32
+
+define void @foo1() nounwind {
+entry:
+; O32: lui $[[R0:[0-9]+]], %got_hi(v0)
+; O32: addu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
+; O32: lw ${{[0-9]+}}, %got_lo(v0)($[[R1]])
+; O32: lui $[[R2:[0-9]+]], %call_hi(foo0)
+; O32: addu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
+; O32: lw ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
+
+; N64: lui $[[R0:[0-9]+]], %got_hi(v0)
+; N64: daddu $[[R1:[0-9]+]], $[[R0]], ${{[a-z0-9]+}}
+; N64: ld ${{[0-9]+}}, %got_lo(v0)($[[R1]])
+; N64: lui $[[R2:[0-9]+]], %call_hi(foo0)
+; N64: daddu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
+; N64: ld ${{[0-9]+}}, %call_lo(foo0)($[[R3]])
+
+ %0 = load i32* @v0, align 4
+ tail call void @foo0(i32 %0) nounwind
+ ret void
+}
+
+declare void @foo0(i32)
+
+; call to external function.
+
+define void @foo2(i32* nocapture %d, i32* nocapture %s, i32 %n) nounwind {
+entry:
+; O32: foo2:
+; O32: lui $[[R2:[0-9]+]], %call_hi(memcpy)
+; O32: addu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
+; O32: lw ${{[0-9]+}}, %call_lo(memcpy)($[[R3]])
+
+; N64: foo2:
+; N64: lui $[[R2:[0-9]+]], %call_hi(memcpy)
+; N64: daddu $[[R3:[0-9]+]], $[[R2]], ${{[a-z0-9]+}}
+; N64: ld ${{[0-9]+}}, %call_lo(memcpy)($[[R3]])
+
+ %0 = bitcast i32* %d to i8*
+ %1 = bitcast i32* %s to i8*
+ tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 %n, i32 4, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind