mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
[mips] For indirect calls we don't need $gp to point to .got. Mips linker
doesn't generate lazy binding stub for a function whose address is taken in the program. Differential Revision: http://reviews.llvm.org/D5067 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218744 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -424,7 +424,8 @@ void Mips16TargetLowering::
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
|
SDValue Chain) const {
|
||||||
SelectionDAG &DAG = CLI.DAG;
|
SelectionDAG &DAG = CLI.DAG;
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
|
MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
|
||||||
@@ -514,7 +515,8 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
|
|||||||
Ops.push_back(JumpTarget);
|
Ops.push_back(JumpTarget);
|
||||||
|
|
||||||
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
||||||
InternalLinkage, CLI, Callee, Chain);
|
InternalLinkage, IsCallReloc, CLI, Callee,
|
||||||
|
Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineBasicBlock *Mips16TargetLowering::
|
MachineBasicBlock *Mips16TargetLowering::
|
||||||
|
@@ -47,7 +47,7 @@ namespace llvm {
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee,
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
SDValue Chain) const override;
|
SDValue Chain) const override;
|
||||||
|
|
||||||
MachineBasicBlock *emitSel16(unsigned Opc, MachineInstr *MI,
|
MachineBasicBlock *emitSel16(unsigned Opc, MachineInstr *MI,
|
||||||
|
@@ -2466,13 +2466,19 @@ void MipsTargetLowering::
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
|
SDValue Chain) const {
|
||||||
// Insert node "GP copy globalreg" before call to function.
|
// Insert node "GP copy globalreg" before call to function.
|
||||||
//
|
//
|
||||||
// R_MIPS_CALL* operators (emitted when non-internal functions are called
|
// R_MIPS_CALL* operators (emitted when non-internal functions are called
|
||||||
// in PIC mode) allow symbols to be resolved via lazy binding.
|
// in PIC mode) allow symbols to be resolved via lazy binding.
|
||||||
// The lazy binding stub requires GP to point to the GOT.
|
// The lazy binding stub requires GP to point to the GOT.
|
||||||
if (IsPICCall && !InternalLinkage) {
|
// Note that we don't need GP to point to the GOT for indirect calls
|
||||||
|
// (when R_MIPS_CALL* is not used for the call) because Mips linker generates
|
||||||
|
// lazy binding stub for a function only when R_MIPS_CALL* are the only relocs
|
||||||
|
// used for the function (that is, Mips linker doesn't generate lazy binding
|
||||||
|
// stub for a function whose address is taken in the program).
|
||||||
|
if (IsPICCall && !InternalLinkage && IsCallReloc) {
|
||||||
unsigned GPReg = Subtarget.isABI_N64() ? Mips::GP_64 : Mips::GP;
|
unsigned GPReg = Subtarget.isABI_N64() ? Mips::GP_64 : Mips::GP;
|
||||||
EVT Ty = Subtarget.isABI_N64() ? MVT::i64 : MVT::i32;
|
EVT Ty = Subtarget.isABI_N64() ? MVT::i64 : MVT::i32;
|
||||||
RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));
|
RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));
|
||||||
@@ -2667,7 +2673,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||||||
bool IsPICCall =
|
bool IsPICCall =
|
||||||
(Subtarget.isABI_N64() || IsPIC); // true if calls are translated to
|
(Subtarget.isABI_N64() || IsPIC); // true if calls are translated to
|
||||||
// jalr $25
|
// jalr $25
|
||||||
bool GlobalOrExternal = false, InternalLinkage = false;
|
bool GlobalOrExternal = false, InternalLinkage = false, IsCallReloc = false;
|
||||||
SDValue CalleeLo;
|
SDValue CalleeLo;
|
||||||
EVT Ty = Callee.getValueType();
|
EVT Ty = Callee.getValueType();
|
||||||
|
|
||||||
@@ -2679,13 +2685,16 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||||||
if (InternalLinkage)
|
if (InternalLinkage)
|
||||||
Callee = getAddrLocal(G, Ty, DAG,
|
Callee = getAddrLocal(G, Ty, DAG,
|
||||||
Subtarget.isABI_N32() || Subtarget.isABI_N64());
|
Subtarget.isABI_N32() || Subtarget.isABI_N64());
|
||||||
else if (LargeGOT)
|
else if (LargeGOT) {
|
||||||
Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16,
|
Callee = getAddrGlobalLargeGOT(G, Ty, DAG, MipsII::MO_CALL_HI16,
|
||||||
MipsII::MO_CALL_LO16, Chain,
|
MipsII::MO_CALL_LO16, Chain,
|
||||||
FuncInfo->callPtrInfo(Val));
|
FuncInfo->callPtrInfo(Val));
|
||||||
else
|
IsCallReloc = true;
|
||||||
|
} else {
|
||||||
Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
Callee = getAddrGlobal(G, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
||||||
FuncInfo->callPtrInfo(Val));
|
FuncInfo->callPtrInfo(Val));
|
||||||
|
IsCallReloc = true;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
|
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
|
||||||
MipsII::MO_NO_FLAG);
|
MipsII::MO_NO_FLAG);
|
||||||
@@ -2697,13 +2706,16 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||||||
if (!Subtarget.isABI_N64() && !IsPIC) // !N64 && static
|
if (!Subtarget.isABI_N64() && !IsPIC) // !N64 && static
|
||||||
Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy(),
|
Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy(),
|
||||||
MipsII::MO_NO_FLAG);
|
MipsII::MO_NO_FLAG);
|
||||||
else if (LargeGOT)
|
else if (LargeGOT) {
|
||||||
Callee = getAddrGlobalLargeGOT(S, Ty, DAG, MipsII::MO_CALL_HI16,
|
Callee = getAddrGlobalLargeGOT(S, Ty, DAG, MipsII::MO_CALL_HI16,
|
||||||
MipsII::MO_CALL_LO16, Chain,
|
MipsII::MO_CALL_LO16, Chain,
|
||||||
FuncInfo->callPtrInfo(Sym));
|
FuncInfo->callPtrInfo(Sym));
|
||||||
else // N64 || PIC
|
IsCallReloc = true;
|
||||||
|
} else { // N64 || PIC
|
||||||
Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
Callee = getAddrGlobal(S, Ty, DAG, MipsII::MO_GOT_CALL, Chain,
|
||||||
FuncInfo->callPtrInfo(Sym));
|
FuncInfo->callPtrInfo(Sym));
|
||||||
|
IsCallReloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
GlobalOrExternal = true;
|
GlobalOrExternal = true;
|
||||||
}
|
}
|
||||||
@@ -2712,7 +2724,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||||
|
|
||||||
getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
|
getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage,
|
||||||
CLI, Callee, Chain);
|
IsCallReloc, CLI, Callee, Chain);
|
||||||
|
|
||||||
if (IsTailCall)
|
if (IsTailCall)
|
||||||
return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
|
return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
|
||||||
|
@@ -336,7 +336,8 @@ namespace llvm {
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const;
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
|
SDValue Chain) const;
|
||||||
|
|
||||||
/// ByValArgInfo - Byval argument information.
|
/// ByValArgInfo - Byval argument information.
|
||||||
struct ByValArgInfo {
|
struct ByValArgInfo {
|
||||||
|
@@ -1187,10 +1187,12 @@ void MipsSETargetLowering::
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
|
SDValue Chain) const {
|
||||||
Ops.push_back(Callee);
|
Ops.push_back(Callee);
|
||||||
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
|
||||||
InternalLinkage, CLI, Callee, Chain);
|
InternalLinkage, IsCallReloc, CLI, Callee,
|
||||||
|
Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
@@ -59,7 +59,7 @@ namespace llvm {
|
|||||||
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
getOpndList(SmallVectorImpl<SDValue> &Ops,
|
||||||
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
|
||||||
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
|
||||||
CallLoweringInfo &CLI, SDValue Callee,
|
bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
|
||||||
SDValue Chain) const override;
|
SDValue Chain) const override;
|
||||||
|
|
||||||
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
@@ -25,3 +25,11 @@ entry:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @no_lazy(void (i32)* %pf) {
|
||||||
|
|
||||||
|
; CHECK-LABEL: no_lazy
|
||||||
|
; CHECK-NOT: gp_disp
|
||||||
|
|
||||||
|
tail call void %pf(i32 1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
@@ -10,16 +10,19 @@
|
|||||||
|
|
||||||
; CHECK-LABEL: readLumaCoeff8x8_CABAC
|
; CHECK-LABEL: readLumaCoeff8x8_CABAC
|
||||||
|
|
||||||
; The check for "addiu" instruction is added so that we can match the correct "b" instruction.
|
; The check for first "addiu" instruction is added so that we can match the correct "b" instruction.
|
||||||
; CHECK: addiu ${{[0-9]+}}, $zero, -1
|
; CHECK: addiu ${{[0-9]+}}, $zero, -1
|
||||||
; CHECK: b $[[BB0:BB[0-9_]+]]
|
; CHECK: b $[[BB0:BB[0-9_]+]]
|
||||||
|
; CHECK-NEXT: addiu ${{[0-9]+}}, $zero, 0
|
||||||
|
|
||||||
; Check that sll instruction that writes to $1 starts basic block.
|
; Check that at the start of a fallthrough block there is a instruction that writes to $1.
|
||||||
; CHECK: {{BB[0-9_#]+}}:
|
; CHECK-NEXT: {{BB[0-9_#]+}}:
|
||||||
|
; CHECK-NEXT: lw $[[R1:[0-9]+]], %got(assignSE2partition)($[[R2:[0-9]+]])
|
||||||
; CHECK-NEXT: sll $1, $[[R0:[0-9]+]], 4
|
; CHECK-NEXT: sll $1, $[[R0:[0-9]+]], 4
|
||||||
|
|
||||||
; Check that identical sll instruction starts another basic block.
|
; Check that identical instructions are at the start of a target block.
|
||||||
; CHECK: [[BB0]]:
|
; CHECK: [[BB0]]:
|
||||||
|
; CHECK-NEXT: lw $[[R1]], %got(assignSE2partition)($[[R2]])
|
||||||
; CHECK-NEXT: sll $1, $[[R0]], 4
|
; CHECK-NEXT: sll $1, $[[R0]], 4
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user