forked from OSchip/llvm-project
Remove ABI-duplicated call instruction patterns.
We currently have a duplicated set of call instruction patterns depending on the ABI to be followed (Darwin vs. Linux). This is a bit odd; while the different ABIs will result in different instruction sequences, the actual instructions themselves ought to be independent of the ABI. And in fact it turns out that the only nontrivial difference between the two sets of patterns is that in the PPC64 Linux ABI, the instruction used for indirect calls is marked to take X11 as extra input register (which is indeed used only with that ABI to hold an incoming environment pointer for nested functions). However, this does not need to be hard-coded at the .td pattern level; instead, the C++ code expanding calls can simply add that use, just like it adds uses for argument registers anyway. No change in generated code expected. llvm-svn: 177735
This commit is contained in:
parent
1df06d8b58
commit
f62e83f415
|
@ -81,12 +81,11 @@ public:
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
|
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
|
||||||
|
|
||||||
// BL8_NOP_ELF, BLA8_NOP_ELF, etc., all have a size of 8 because of the
|
// BL8_NOP etc. all have a size of 8 because of the following 'nop'.
|
||||||
// following 'nop'.
|
|
||||||
unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!
|
unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!
|
||||||
unsigned Opcode = MI.getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
if (Opcode == PPC::BL8_NOP_ELF || Opcode == PPC::BLA8_NOP_ELF ||
|
if (Opcode == PPC::BL8_NOP || Opcode == PPC::BLA8_NOP ||
|
||||||
Opcode == PPC::BL8_NOP_ELF_TLSGD || Opcode == PPC::BL8_NOP_ELF_TLSLD)
|
Opcode == PPC::BL8_NOP_TLSGD || Opcode == PPC::BL8_NOP_TLSLD)
|
||||||
Size = 8;
|
Size = 8;
|
||||||
|
|
||||||
// Output the constant in big endian byte order.
|
// Output the constant in big endian byte order.
|
||||||
|
@ -121,11 +120,11 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
(MCFixupKind)PPC::fixup_ppc_br24));
|
(MCFixupKind)PPC::fixup_ppc_br24));
|
||||||
|
|
||||||
// For special TLS calls, add another fixup for the symbol. Apparently
|
// For special TLS calls, add another fixup for the symbol. Apparently
|
||||||
// BL8_NOP_ELF, BL8_NOP_ELF_TLSGD, and BL8_NOP_ELF_TLSLD are sufficiently
|
// BL8_NOP, BL8_NOP_TLSGD, and BL8_NOP_TLSLD are sufficiently
|
||||||
// similar that TblGen will not generate a separate case for the latter
|
// similar that TblGen will not generate a separate case for the latter
|
||||||
// two, so this is the only way to get the extra fixup generated.
|
// two, so this is the only way to get the extra fixup generated.
|
||||||
unsigned Opcode = MI.getOpcode();
|
unsigned Opcode = MI.getOpcode();
|
||||||
if (Opcode == PPC::BL8_NOP_ELF_TLSGD || Opcode == PPC::BL8_NOP_ELF_TLSLD) {
|
if (Opcode == PPC::BL8_NOP_TLSGD || Opcode == PPC::BL8_NOP_TLSLD) {
|
||||||
const MCOperand &MO2 = MI.getOperand(OpNo+1);
|
const MCOperand &MO2 = MI.getOperand(OpNo+1);
|
||||||
Fixups.push_back(MCFixup::Create(0, MO2.getExpr(),
|
Fixups.push_back(MCFixup::Create(0, MO2.getExpr(),
|
||||||
(MCFixupKind)PPC::fixup_ppc_nofixup));
|
(MCFixupKind)PPC::fixup_ppc_nofixup));
|
||||||
|
|
|
@ -370,7 +370,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
MCSymbol *PICBase = MF->getPICBaseSymbol();
|
MCSymbol *PICBase = MF->getPICBaseSymbol();
|
||||||
|
|
||||||
// Emit the 'bl'.
|
// Emit the 'bl'.
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL)
|
||||||
// FIXME: We would like an efficient form for this, so we don't have to do
|
// FIXME: We would like an efficient form for this, so we don't have to do
|
||||||
// a lot of extra uniquing.
|
// a lot of extra uniquing.
|
||||||
.addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
|
.addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
|
||||||
|
@ -595,7 +595,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
}
|
}
|
||||||
case PPC::GETtlsADDR: {
|
case PPC::GETtlsADDR: {
|
||||||
// Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
|
// Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
|
||||||
// Into: BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd)
|
// Into: BL8_NOP_TLSGD __tls_get_addr(sym@tlsgd)
|
||||||
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
|
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
|
||||||
|
|
||||||
StringRef Name = "__tls_get_addr";
|
StringRef Name = "__tls_get_addr";
|
||||||
|
@ -608,7 +608,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
const MCExpr *SymVar =
|
const MCExpr *SymVar =
|
||||||
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
|
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
|
||||||
OutContext);
|
OutContext);
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD)
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSGD)
|
||||||
.addExpr(TlsRef)
|
.addExpr(TlsRef)
|
||||||
.addExpr(SymVar));
|
.addExpr(SymVar));
|
||||||
return;
|
return;
|
||||||
|
@ -647,7 +647,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
}
|
}
|
||||||
case PPC::GETtlsldADDR: {
|
case PPC::GETtlsldADDR: {
|
||||||
// Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
|
// Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
|
||||||
// Into: BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld)
|
// Into: BL8_NOP_TLSLD __tls_get_addr(sym@tlsld)
|
||||||
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
|
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
|
||||||
|
|
||||||
StringRef Name = "__tls_get_addr";
|
StringRef Name = "__tls_get_addr";
|
||||||
|
@ -660,7 +660,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
const MCExpr *SymVar =
|
const MCExpr *SymVar =
|
||||||
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
|
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
|
||||||
OutContext);
|
OutContext);
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD)
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSLD)
|
||||||
.addExpr(TlsRef)
|
.addExpr(TlsRef)
|
||||||
.addExpr(SymVar));
|
.addExpr(SymVar));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -179,7 +179,7 @@ getHazardType(SUnit *SU, int Stalls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow MTCTR and BCTRL to be in the same dispatch group.
|
// Do not allow MTCTR and BCTRL to be in the same dispatch group.
|
||||||
if (HasCTRSet && (Opcode == PPC::BCTRL_Darwin || Opcode == PPC::BCTRL_SVR4))
|
if (HasCTRSet && Opcode == PPC::BCTRL)
|
||||||
return NoopHazard;
|
return NoopHazard;
|
||||||
|
|
||||||
// If this is a load following a store, make sure it's not to the same or
|
// If this is a load following a store, make sure it's not to the same or
|
||||||
|
|
|
@ -568,13 +568,10 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
case PPCISD::SHL: return "PPCISD::SHL";
|
case PPCISD::SHL: return "PPCISD::SHL";
|
||||||
case PPCISD::EXTSW_32: return "PPCISD::EXTSW_32";
|
case PPCISD::EXTSW_32: return "PPCISD::EXTSW_32";
|
||||||
case PPCISD::STD_32: return "PPCISD::STD_32";
|
case PPCISD::STD_32: return "PPCISD::STD_32";
|
||||||
case PPCISD::CALL_SVR4: return "PPCISD::CALL_SVR4";
|
case PPCISD::CALL: return "PPCISD::CALL";
|
||||||
case PPCISD::CALL_NOP_SVR4: return "PPCISD::CALL_NOP_SVR4";
|
case PPCISD::CALL_NOP: return "PPCISD::CALL_NOP";
|
||||||
case PPCISD::CALL_Darwin: return "PPCISD::CALL_Darwin";
|
|
||||||
case PPCISD::NOP: return "PPCISD::NOP";
|
|
||||||
case PPCISD::MTCTR: return "PPCISD::MTCTR";
|
case PPCISD::MTCTR: return "PPCISD::MTCTR";
|
||||||
case PPCISD::BCTRL_Darwin: return "PPCISD::BCTRL_Darwin";
|
case PPCISD::BCTRL: return "PPCISD::BCTRL";
|
||||||
case PPCISD::BCTRL_SVR4: return "PPCISD::BCTRL_SVR4";
|
|
||||||
case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG";
|
case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG";
|
||||||
case PPCISD::EH_SJLJ_SETJMP: return "PPCISD::EH_SJLJ_SETJMP";
|
case PPCISD::EH_SJLJ_SETJMP: return "PPCISD::EH_SJLJ_SETJMP";
|
||||||
case PPCISD::EH_SJLJ_LONGJMP: return "PPCISD::EH_SJLJ_LONGJMP";
|
case PPCISD::EH_SJLJ_LONGJMP: return "PPCISD::EH_SJLJ_LONGJMP";
|
||||||
|
@ -3136,7 +3133,7 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
|
||||||
NodeTys.push_back(MVT::Other); // Returns a chain
|
NodeTys.push_back(MVT::Other); // Returns a chain
|
||||||
NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use.
|
NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use.
|
||||||
|
|
||||||
unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin;
|
unsigned CallOpc = PPCISD::CALL;
|
||||||
|
|
||||||
bool needIndirectCall = true;
|
bool needIndirectCall = true;
|
||||||
if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG)) {
|
if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG)) {
|
||||||
|
@ -3269,8 +3266,11 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
|
||||||
NodeTys.push_back(MVT::Other);
|
NodeTys.push_back(MVT::Other);
|
||||||
NodeTys.push_back(MVT::Glue);
|
NodeTys.push_back(MVT::Glue);
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
CallOpc = isSVR4ABI ? PPCISD::BCTRL_SVR4 : PPCISD::BCTRL_Darwin;
|
CallOpc = PPCISD::BCTRL;
|
||||||
Callee.setNode(0);
|
Callee.setNode(0);
|
||||||
|
// Add use of X11 (holding environment pointer)
|
||||||
|
if (isSVR4ABI && isPPC64)
|
||||||
|
Ops.push_back(DAG.getRegister(PPC::X11, PtrVT));
|
||||||
// Add CTR register as callee so a bctr can be emitted later.
|
// Add CTR register as callee so a bctr can be emitted later.
|
||||||
if (isTailCall)
|
if (isTailCall)
|
||||||
Ops.push_back(DAG.getRegister(isPPC64 ? PPC::CTR8 : PPC::CTR, PtrVT));
|
Ops.push_back(DAG.getRegister(isPPC64 ? PPC::CTR8 : PPC::CTR, PtrVT));
|
||||||
|
@ -3409,7 +3409,7 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,
|
||||||
|
|
||||||
bool needsTOCRestore = false;
|
bool needsTOCRestore = false;
|
||||||
if (!isTailCall && PPCSubTarget.isSVR4ABI()&& PPCSubTarget.isPPC64()) {
|
if (!isTailCall && PPCSubTarget.isSVR4ABI()&& PPCSubTarget.isPPC64()) {
|
||||||
if (CallOpc == PPCISD::BCTRL_SVR4) {
|
if (CallOpc == PPCISD::BCTRL) {
|
||||||
// This is a call through a function pointer.
|
// This is a call through a function pointer.
|
||||||
// Restore the caller TOC from the save area into R2.
|
// Restore the caller TOC from the save area into R2.
|
||||||
// See PrepareCall() for more information about calls through function
|
// See PrepareCall() for more information about calls through function
|
||||||
|
@ -3420,9 +3420,9 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,
|
||||||
// from allocating it), resulting in an additional register being
|
// from allocating it), resulting in an additional register being
|
||||||
// allocated and an unnecessary move instruction being generated.
|
// allocated and an unnecessary move instruction being generated.
|
||||||
needsTOCRestore = true;
|
needsTOCRestore = true;
|
||||||
} else if ((CallOpc == PPCISD::CALL_SVR4) && !isLocalCall(Callee)) {
|
} else if ((CallOpc == PPCISD::CALL) && !isLocalCall(Callee)) {
|
||||||
// Otherwise insert NOP for non-local calls.
|
// Otherwise insert NOP for non-local calls.
|
||||||
CallOpc = PPCISD::CALL_NOP_SVR4;
|
CallOpc = PPCISD::CALL_NOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,12 +96,9 @@ namespace llvm {
|
||||||
EXTSW_32,
|
EXTSW_32,
|
||||||
|
|
||||||
/// CALL - A direct function call.
|
/// CALL - A direct function call.
|
||||||
/// CALL_NOP_SVR4 is a call with the special NOP which follows 64-bit
|
/// CALL_NOP is a call with the special NOP which follows 64-bit
|
||||||
/// SVR4 calls.
|
/// SVR4 calls.
|
||||||
CALL_Darwin, CALL_SVR4, CALL_NOP_SVR4,
|
CALL, CALL_NOP,
|
||||||
|
|
||||||
/// NOP - Special NOP which follows 64-bit SVR4 calls.
|
|
||||||
NOP,
|
|
||||||
|
|
||||||
/// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
|
/// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
|
||||||
/// MTCTR instruction.
|
/// MTCTR instruction.
|
||||||
|
@ -109,7 +106,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a
|
/// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a
|
||||||
/// BCTRL instruction.
|
/// BCTRL instruction.
|
||||||
BCTRL_Darwin, BCTRL_SVR4,
|
BCTRL,
|
||||||
|
|
||||||
/// Return with a flag operand, matched by 'blr'
|
/// Return with a flag operand, matched by 'blr'
|
||||||
RET_FLAG,
|
RET_FLAG,
|
||||||
|
|
|
@ -75,86 +75,51 @@ let Defs = [LR8] in
|
||||||
def MovePCtoLR8 : Pseudo<(outs), (ins), "#MovePCtoLR8", []>,
|
def MovePCtoLR8 : Pseudo<(outs), (ins), "#MovePCtoLR8", []>,
|
||||||
PPC970_Unit_BRU;
|
PPC970_Unit_BRU;
|
||||||
|
|
||||||
// Darwin ABI Calls.
|
|
||||||
let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
|
let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
|
||||||
// Convenient aliases for call instructions
|
// Convenient aliases for call instructions
|
||||||
let Uses = [RM] in {
|
let Uses = [RM] in {
|
||||||
def BL8_Darwin : IForm<18, 0, 1,
|
def BL8 : IForm<18, 0, 1, (outs), (ins calltarget:$func),
|
||||||
(outs), (ins calltarget:$func),
|
"bl $func", BrB, []>; // See Pat patterns below.
|
||||||
"bl $func", BrB, []>; // See Pat patterns below.
|
|
||||||
def BLA8_Darwin : IForm<18, 1, 1,
|
|
||||||
(outs), (ins aaddr:$func),
|
|
||||||
"bla $func", BrB, [(PPCcall_Darwin (i64 imm:$func))]>;
|
|
||||||
}
|
|
||||||
let Uses = [CTR8, RM] in {
|
|
||||||
def BCTRL8_Darwin : XLForm_2_ext<19, 528, 20, 0, 1,
|
|
||||||
(outs), (ins),
|
|
||||||
"bctrl", BrB,
|
|
||||||
[(PPCbctrl_Darwin)]>, Requires<[In64BitMode]>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ELF 64 ABI Calls = Darwin ABI Calls
|
def BLA8 : IForm<18, 1, 1, (outs), (ins aaddr:$func),
|
||||||
// Used to define BL8_ELF and BLA8_ELF
|
"bla $func", BrB, [(PPCcall (i64 imm:$func))]>;
|
||||||
let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
|
}
|
||||||
// Convenient aliases for call instructions
|
let Uses = [RM], isCodeGenOnly = 1 in {
|
||||||
let Uses = [RM] in {
|
def BL8_NOP : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
||||||
def BL8_ELF : IForm<18, 0, 1,
|
|
||||||
(outs), (ins calltarget:$func),
|
|
||||||
"bl $func", BrB, []>; // See Pat patterns below.
|
|
||||||
|
|
||||||
let isCodeGenOnly = 1 in
|
|
||||||
def BL8_NOP_ELF : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
|
||||||
(outs), (ins calltarget:$func),
|
(outs), (ins calltarget:$func),
|
||||||
"bl $func\n\tnop", BrB, []>;
|
"bl $func\n\tnop", BrB, []>;
|
||||||
|
|
||||||
let isCodeGenOnly = 1 in
|
def BL8_NOP_TLSGD : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
||||||
def BL8_NOP_ELF_TLSGD : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
|
||||||
(outs), (ins calltarget:$func, tlsgd:$sym),
|
(outs), (ins calltarget:$func, tlsgd:$sym),
|
||||||
"bl $func($sym)\n\tnop", BrB, []>;
|
"bl $func($sym)\n\tnop", BrB, []>;
|
||||||
|
|
||||||
let isCodeGenOnly = 1 in
|
def BL8_NOP_TLSLD : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
||||||
def BL8_NOP_ELF_TLSLD : IForm_and_DForm_4_zero<18, 0, 1, 24,
|
|
||||||
(outs), (ins calltarget:$func, tlsgd:$sym),
|
(outs), (ins calltarget:$func, tlsgd:$sym),
|
||||||
"bl $func($sym)\n\tnop", BrB, []>;
|
"bl $func($sym)\n\tnop", BrB, []>;
|
||||||
|
|
||||||
def BLA8_ELF : IForm<18, 1, 1,
|
def BLA8_NOP : IForm_and_DForm_4_zero<18, 1, 1, 24,
|
||||||
(outs), (ins aaddr:$func),
|
|
||||||
"bla $func", BrB, [(PPCcall_SVR4 (i64 imm:$func))]>;
|
|
||||||
|
|
||||||
let isCodeGenOnly = 1 in
|
|
||||||
def BLA8_NOP_ELF : IForm_and_DForm_4_zero<18, 1, 1, 24,
|
|
||||||
(outs), (ins aaddr:$func),
|
(outs), (ins aaddr:$func),
|
||||||
"bla $func\n\tnop", BrB,
|
"bla $func\n\tnop", BrB,
|
||||||
[(PPCcall_nop_SVR4 (i64 imm:$func))]>;
|
[(PPCcall_nop (i64 imm:$func))]>;
|
||||||
}
|
}
|
||||||
let Uses = [X11, CTR8, RM] in {
|
let Uses = [CTR8, RM] in {
|
||||||
def BCTRL8_ELF : XLForm_2_ext<19, 528, 20, 0, 1,
|
def BCTRL8 : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
|
||||||
(outs), (ins),
|
"bctrl", BrB, [(PPCbctrl)]>,
|
||||||
"bctrl", BrB,
|
Requires<[In64BitMode]>;
|
||||||
[(PPCbctrl_SVR4)]>, Requires<[In64BitMode]>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
def : Pat<(PPCcall_Darwin (i64 tglobaladdr:$dst)),
|
def : Pat<(PPCcall (i64 tglobaladdr:$dst)),
|
||||||
(BL8_Darwin tglobaladdr:$dst)>;
|
(BL8 tglobaladdr:$dst)>;
|
||||||
def : Pat<(PPCcall_Darwin (i64 texternalsym:$dst)),
|
def : Pat<(PPCcall_nop (i64 tglobaladdr:$dst)),
|
||||||
(BL8_Darwin texternalsym:$dst)>;
|
(BL8_NOP tglobaladdr:$dst)>;
|
||||||
|
|
||||||
def : Pat<(PPCcall_SVR4 (i64 tglobaladdr:$dst)),
|
def : Pat<(PPCcall (i64 texternalsym:$dst)),
|
||||||
(BL8_ELF tglobaladdr:$dst)>;
|
(BL8 texternalsym:$dst)>;
|
||||||
def : Pat<(PPCcall_nop_SVR4 (i64 tglobaladdr:$dst)),
|
def : Pat<(PPCcall_nop (i64 texternalsym:$dst)),
|
||||||
(BL8_NOP_ELF tglobaladdr:$dst)>;
|
(BL8_NOP texternalsym:$dst)>;
|
||||||
|
|
||||||
def : Pat<(PPCcall_SVR4 (i64 texternalsym:$dst)),
|
|
||||||
(BL8_ELF texternalsym:$dst)>;
|
|
||||||
def : Pat<(PPCcall_nop_SVR4 (i64 texternalsym:$dst)),
|
|
||||||
(BL8_NOP_ELF texternalsym:$dst)>;
|
|
||||||
|
|
||||||
def : Pat<(PPCnop),
|
|
||||||
(NOP)>;
|
|
||||||
|
|
||||||
// Atomic operations
|
// Atomic operations
|
||||||
let usesCustomInserter = 1 in {
|
let usesCustomInserter = 1 in {
|
||||||
|
|
|
@ -726,8 +726,8 @@ unsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||||
case PPC::GC_LABEL:
|
case PPC::GC_LABEL:
|
||||||
case PPC::DBG_VALUE:
|
case PPC::DBG_VALUE:
|
||||||
return 0;
|
return 0;
|
||||||
case PPC::BL8_NOP_ELF:
|
case PPC::BL8_NOP:
|
||||||
case PPC::BLA8_NOP_ELF:
|
case PPC::BLA8_NOP:
|
||||||
return 8;
|
return 8;
|
||||||
default:
|
default:
|
||||||
return 4; // PowerPC instructions are all 4 bytes
|
return 4; // PowerPC instructions are all 4 bytes
|
||||||
|
|
|
@ -53,7 +53,6 @@ def SDT_PPCTC_ret : SDTypeProfile<0, 2, [
|
||||||
SDTCisPtrTy<0>, SDTCisVT<1, i32>
|
SDTCisPtrTy<0>, SDTCisVT<1, i32>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def SDT_PPCnop : SDTypeProfile<0, 0, []>;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PowerPC specific DAG Nodes.
|
// PowerPC specific DAG Nodes.
|
||||||
|
@ -124,16 +123,12 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeqEnd,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||||
|
|
||||||
def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
|
def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
|
||||||
def PPCcall_Darwin : SDNode<"PPCISD::CALL_Darwin", SDT_PPCCall,
|
def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||||
SDNPVariadic]>;
|
SDNPVariadic]>;
|
||||||
def PPCcall_SVR4 : SDNode<"PPCISD::CALL_SVR4", SDT_PPCCall,
|
def PPCcall_nop : SDNode<"PPCISD::CALL_NOP", SDT_PPCCall,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||||
SDNPVariadic]>;
|
SDNPVariadic]>;
|
||||||
def PPCcall_nop_SVR4 : SDNode<"PPCISD::CALL_NOP_SVR4", SDT_PPCCall,
|
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
|
||||||
SDNPVariadic]>;
|
|
||||||
def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInGlue, SDNPOutGlue]>;
|
|
||||||
def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>,
|
def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||||
def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>,
|
def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>,
|
||||||
|
@ -144,13 +139,9 @@ def PPCtoc_restore : SDNode<"PPCISD::TOC_RESTORE", SDTypeProfile<0, 0, []>,
|
||||||
SDNPInGlue, SDNPOutGlue]>;
|
SDNPInGlue, SDNPOutGlue]>;
|
||||||
def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
|
def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||||
def PPCbctrl_Darwin : SDNode<"PPCISD::BCTRL_Darwin", SDTNone,
|
def PPCbctrl : SDNode<"PPCISD::BCTRL", SDTNone,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||||
SDNPVariadic]>;
|
SDNPVariadic]>;
|
||||||
|
|
||||||
def PPCbctrl_SVR4 : SDNode<"PPCISD::BCTRL_SVR4", SDTNone,
|
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
|
||||||
SDNPVariadic]>;
|
|
||||||
|
|
||||||
def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone,
|
def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone,
|
||||||
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
|
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
|
||||||
|
@ -530,46 +521,21 @@ let isCall = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Darwin ABI Calls.
|
|
||||||
let isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
|
let isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
|
||||||
// Convenient aliases for call instructions
|
// Convenient aliases for call instructions
|
||||||
let Uses = [RM] in {
|
let Uses = [RM] in {
|
||||||
def BL_Darwin : IForm<18, 0, 1,
|
def BL : IForm<18, 0, 1, (outs), (ins calltarget:$func),
|
||||||
(outs), (ins calltarget:$func),
|
"bl $func", BrB, []>; // See Pat patterns below.
|
||||||
"bl $func", BrB, []>; // See Pat patterns below.
|
def BLA : IForm<18, 1, 1, (outs), (ins aaddr:$func),
|
||||||
def BLA_Darwin : IForm<18, 1, 1,
|
"bla $func", BrB, [(PPCcall (i32 imm:$func))]>;
|
||||||
(outs), (ins aaddr:$func),
|
|
||||||
"bla $func", BrB, [(PPCcall_Darwin (i32 imm:$func))]>;
|
|
||||||
}
|
}
|
||||||
let Uses = [CTR, RM] in {
|
let Uses = [CTR, RM] in {
|
||||||
def BCTRL_Darwin : XLForm_2_ext<19, 528, 20, 0, 1,
|
def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
|
||||||
(outs), (ins),
|
"bctrl", BrB, [(PPCbctrl)]>,
|
||||||
"bctrl", BrB,
|
Requires<[In32BitMode]>;
|
||||||
[(PPCbctrl_Darwin)]>, Requires<[In32BitMode]>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVR4 ABI Calls.
|
|
||||||
let isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
|
|
||||||
// Convenient aliases for call instructions
|
|
||||||
let Uses = [RM] in {
|
|
||||||
def BL_SVR4 : IForm<18, 0, 1,
|
|
||||||
(outs), (ins calltarget:$func),
|
|
||||||
"bl $func", BrB, []>; // See Pat patterns below.
|
|
||||||
def BLA_SVR4 : IForm<18, 1, 1,
|
|
||||||
(outs), (ins aaddr:$func),
|
|
||||||
"bla $func", BrB,
|
|
||||||
[(PPCcall_SVR4 (i32 imm:$func))]>;
|
|
||||||
}
|
|
||||||
let Uses = [CTR, RM] in {
|
|
||||||
def BCTRL_SVR4 : XLForm_2_ext<19, 528, 20, 0, 1,
|
|
||||||
(outs), (ins),
|
|
||||||
"bctrl", BrB,
|
|
||||||
[(PPCbctrl_SVR4)]>, Requires<[In32BitMode]>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
|
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
|
||||||
def TCRETURNdi :Pseudo< (outs),
|
def TCRETURNdi :Pseudo< (outs),
|
||||||
(ins calltarget:$dst, i32imm:$offset),
|
(ins calltarget:$dst, i32imm:$offset),
|
||||||
|
@ -1597,14 +1563,10 @@ def : Pat<(and (rotl GPRC:$in, GPRC:$sh), maskimm32:$imm),
|
||||||
(RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
|
(RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
def : Pat<(PPCcall_Darwin (i32 tglobaladdr:$dst)),
|
def : Pat<(PPCcall (i32 tglobaladdr:$dst)),
|
||||||
(BL_Darwin tglobaladdr:$dst)>;
|
(BL tglobaladdr:$dst)>;
|
||||||
def : Pat<(PPCcall_Darwin (i32 texternalsym:$dst)),
|
def : Pat<(PPCcall (i32 texternalsym:$dst)),
|
||||||
(BL_Darwin texternalsym:$dst)>;
|
(BL texternalsym:$dst)>;
|
||||||
def : Pat<(PPCcall_SVR4 (i32 tglobaladdr:$dst)),
|
|
||||||
(BL_SVR4 tglobaladdr:$dst)>;
|
|
||||||
def : Pat<(PPCcall_SVR4 (i32 texternalsym:$dst)),
|
|
||||||
(BL_SVR4 texternalsym:$dst)>;
|
|
||||||
|
|
||||||
|
|
||||||
def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
|
def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
|
||||||
|
|
Loading…
Reference in New Issue