diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index e34dd63dbf87ef..46bbc44e1681bb 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -46,11 +46,12 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo, if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); + + const PPCInstrInfo *InstrInfo = static_cast(&MCII); + unsigned Opcode = MI.getOpcode(); // Add a fixup for the branch target. Fixups.push_back(MCFixup::create(0, MO.getExpr(), - ((MI.getOpcode() == PPC::BL8_NOTOC || - MI.getOpcode() == PPC::BL8_NOTOC_TLS || - MI.getOpcode() == PPC::BL8_NOTOC_RM) + (InstrInfo->isNoTOCCallInstr(Opcode) ? (MCFixupKind)PPC::fixup_ppc_br24_notoc : (MCFixupKind)PPC::fixup_ppc_br24))); return 0; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index c16e146da24715..597aab7fbe40c3 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -295,6 +295,99 @@ class PPCInstrInfo : public PPCGenInstrInfo { return get(Opcode).TSFlags & PPCII::Prefixed; } + /// Check if Opcode corresponds to a call instruction that should be marked + /// with the NOTOC relocation. + bool isNoTOCCallInstr(unsigned Opcode) const { + if (!get(Opcode).isCall()) + return false; + + switch (Opcode) { + default: +#ifndef NDEBUG + llvm_unreachable("Unknown call opcode"); +#endif + return false; + case PPC::BL8_NOTOC: + case PPC::BL8_NOTOC_TLS: + case PPC::BL8_NOTOC_RM: + return true; +#ifndef NDEBUG + case PPC::BL8: + case PPC::BL: + case PPC::BL8_TLS: + case PPC::BL_TLS: + case PPC::BLA8: + case PPC::BLA: + case PPC::BCCL: + case PPC::BCCLA: + case PPC::BCL: + case PPC::BCLn: + case PPC::BL8_NOP: + case PPC::BL_NOP: + case PPC::BL8_NOP_TLS: + case PPC::BLA8_NOP: + case PPC::BCTRL8: + case PPC::BCTRL: + case PPC::BCCCTRL8: + case PPC::BCCCTRL: + case PPC::BCCTRL8: + case PPC::BCCTRL: + case PPC::BCCTRL8n: + case PPC::BCCTRLn: + case PPC::BL8_RM: + case PPC::BLA8_RM: + case PPC::BL8_NOP_RM: + case PPC::BLA8_NOP_RM: + case PPC::BCTRL8_RM: + case PPC::BCTRL8_LDinto_toc: + case PPC::BCTRL8_LDinto_toc_RM: + case PPC::BL8_TLS_: + case PPC::TCRETURNdi8: + case PPC::TCRETURNai8: + case PPC::TCRETURNri8: + case PPC::TAILBCTR8: + case PPC::TAILB8: + case PPC::TAILBA8: + case PPC::BCLalways: + case PPC::BLRL: + case PPC::BCCLRL: + case PPC::BCLRL: + case PPC::BCLRLn: + case PPC::BDZL: + case PPC::BDNZL: + case PPC::BDZLA: + case PPC::BDNZLA: + case PPC::BDZLp: + case PPC::BDNZLp: + case PPC::BDZLAp: + case PPC::BDNZLAp: + case PPC::BDZLm: + case PPC::BDNZLm: + case PPC::BDZLAm: + case PPC::BDNZLAm: + case PPC::BDZLRL: + case PPC::BDNZLRL: + case PPC::BDZLRLp: + case PPC::BDNZLRLp: + case PPC::BDZLRLm: + case PPC::BDNZLRLm: + case PPC::BL_RM: + case PPC::BLA_RM: + case PPC::BL_NOP_RM: + case PPC::BCTRL_RM: + case PPC::TCRETURNdi: + case PPC::TCRETURNai: + case PPC::TCRETURNri: + case PPC::BCTRL_LWZinto_toc: + case PPC::BCTRL_LWZinto_toc_RM: + case PPC::TAILBCTR: + case PPC::TAILB: + case PPC::TAILBA: + return false; +#endif + } + } + static bool isSameClassPhysRegCopy(unsigned Opcode) { unsigned CopyOpcodes[] = {PPC::OR, PPC::OR8, PPC::FMR, PPC::VOR, PPC::XXLOR, PPC::XXLORf,