mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 06:30:39 +00:00
[mips] Generate big GOT code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168460 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
238f34a706
commit
f09a03776d
@ -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();
|
||||
|
@ -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)>;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)>;
|
||||
|
@ -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) {
|
||||
|
50
test/CodeGen/Mips/biggot.ll
Normal file
50
test/CodeGen/Mips/biggot.ll
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user