Pull in r214284 from upstream llvm trunk (by Hal Finkel):

[PowerPC] Add JMP_SLOT relocation definitions

  This will be required by upcoming patches for LLDB support.

  Patch by Justin Hibbits!

Pull in r221510 from upstream llvm trunk (by Justin Hibbits):

  Add Position-independent Code model Module API.

  Summary:
  This makes PIC levels a Module flag attribute, which can be queried by the
  backend.  The flag is named `PIC Level`, and can have a value of:

    0 - Backend-default
    1 - Small-model (-fpic)
    2 - Large-model (-fPIC)

  These match the `-pic-level' command line argument for clang, and the value of the
  preprocessor macro `__PIC__'.

  Test Plan:
  New flags tests specific for the 'PIC Level' module flag.
  Tests to be added as part of a future commit for PowerPC, which will use this new API.

  Reviewers: rafael, echristo

  Reviewed By: rafael, echristo

  Subscribers: rafael, llvm-commits

  Differential Revision: http://reviews.llvm.org/D5882

Pull in r221791 from upstream llvm trunk (by Justin Hibbits):

  Add support for small-model PIC for PowerPC.

  Summary:
  Large-model was added first.  With the addition of support for multiple PIC
  models in LLVM, now add small-model PIC for 32-bit PowerPC, SysV4 ABI.  This
  generates more optimal code, for shared libraries with less than about 16380
  data objects.

  Test Plan: Test cases added or updated

  Reviewers: joerg, hfinkel

  Reviewed By: hfinkel

  Subscribers: jholewinski, mcrosier, emaste, llvm-commits

  Differential Revision: http://reviews.llvm.org/D5399

Together, these changes implement small-model PIC support for PowerPC.

Thanks to Justin Hibbits and Roman Divacky for their assistance in
getting this working.
This commit is contained in:
Dimitry Andric 2014-12-25 18:22:22 +00:00
parent 42ac84b368
commit 404df5bbd5
11 changed files with 147 additions and 62 deletions

View File

@ -23,6 +23,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/DataTypes.h"
#include <system_error>
@ -620,6 +621,15 @@ public:
unsigned getDwarfVersion() const;
/// @}
/// @name Utility functions for querying and setting PIC level
/// @{
/// \brief Returns the PIC level (small or large model)
PICLevel::Level getPICLevel() const;
/// \brief Set the PIC level (small or large model)
void setPICLevel(PICLevel::Level PL);
/// @}
};
/// An raw_ostream inserter for modules.

View File

@ -238,6 +238,7 @@ public:
VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
VK_PPC_TLSLD, // symbol@tlsld
VK_PPC_LOCAL, // symbol@local
VK_Mips_GPREL,
VK_Mips_GOT_CALL,

View File

@ -30,6 +30,10 @@ namespace llvm {
enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
}
namespace PICLevel {
enum Level { Default=0, Small=1, Large=2 };
}
// TLS models.
namespace TLSModel {
enum Model {

View File

@ -459,6 +459,8 @@ enum {
R_PPC_GOT16_HI = 16,
R_PPC_GOT16_HA = 17,
R_PPC_PLTREL24 = 18,
R_PPC_JMP_SLOT = 21,
R_PPC_LOCAL24PC = 23,
R_PPC_REL32 = 26,
R_PPC_TLS = 67,
R_PPC_DTPMOD32 = 68,
@ -547,6 +549,7 @@ enum {
R_PPC64_GOT16_LO = 15,
R_PPC64_GOT16_HI = 16,
R_PPC64_GOT16_HA = 17,
R_PPC64_JMP_SLOT = 21,
R_PPC64_REL32 = 26,
R_PPC64_ADDR64 = 38,
R_PPC64_ADDR16_HIGHER = 39,

View File

@ -461,3 +461,16 @@ Comdat *Module::getOrInsertComdat(StringRef Name) {
Entry.second.Name = &Entry;
return &Entry.second;
}
PICLevel::Level Module::getPICLevel() const {
Value *Val = getModuleFlag("PIC Level");
if (Val == NULL)
return PICLevel::Default;
return static_cast<PICLevel::Level>(cast<ConstantInt>(Val)->getZExtValue());
}
void Module::setPICLevel(PICLevel::Level PL) {
addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL);
}

View File

@ -247,6 +247,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h";
case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
case VK_PPC_TLSLD: return "tlsld";
case VK_PPC_LOCAL: return "local";
case VK_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
case VK_Mips_GOT16: return "GOT16";

View File

@ -95,6 +95,9 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
case MCSymbolRefExpr::VK_PLT:
Type = ELF::R_PPC_PLTREL24;
break;
case MCSymbolRefExpr::VK_PPC_LOCAL:
Type = ELF::R_PPC_LOCAL24PC;
break;
}
break;
case PPC::fixup_ppc_brcond14:

View File

@ -311,12 +311,35 @@ MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst;
bool isPPC64 = Subtarget.isPPC64();
bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin();
const Module *M = MF->getFunction()->getParent();
PICLevel::Level PL = M->getPICLevel();
// Lower multi-instruction pseudo operations.
switch (MI->getOpcode()) {
default: break;
case TargetOpcode::DBG_VALUE:
llvm_unreachable("Should be handled target independently");
case PPC::MoveGOTtoLR: {
// Transform %LR = MoveGOTtoLR
// Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
// _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
// _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
// blrl
// This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
MCSymbol *GOTSymbol =
OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
const MCExpr *OffsExpr =
MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol,
MCSymbolRefExpr::VK_PPC_LOCAL,
OutContext),
MCConstantExpr::Create(4, OutContext),
OutContext);
// Emit the 'bl'.
EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
return;
}
case PPC::MovePCtoLR:
case PPC::MovePCtoLR8: {
// Transform %LR = MovePCtoLR
@ -335,10 +358,14 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitLabel(PICBase);
return;
}
case PPC::GetGBRO: {
case PPC::UpdateGBR: {
// Transform %Rd = UpdateGBR(%Rt, %Ri)
// Into: lwz %Rt, .L0$poff - .L0$pb(%Ri)
// add %Rd, %Rt, %Ri
// Get the offset from the GOT Base Register to the GOT
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
MCSymbol *PICOffset = MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
MCSymbol *PICOffset =
MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
TmpInst.setOpcode(PPC::LWZ);
const MCExpr *Exp =
MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
@ -346,26 +373,26 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCSymbolRefExpr::Create(MF->getPICBaseSymbol(),
MCSymbolRefExpr::VK_None,
OutContext);
const MCOperand MO = TmpInst.getOperand(1);
TmpInst.getOperand(1) = MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp,
PB,
OutContext));
TmpInst.addOperand(MO);
const MCOperand TR = TmpInst.getOperand(1);
const MCOperand PICR = TmpInst.getOperand(0);
// Step 1: lwz %Rt, .L$poff - .L$pb(%Ri)
TmpInst.getOperand(1) =
MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext));
TmpInst.getOperand(0) = TR;
TmpInst.getOperand(2) = PICR;
EmitToStreamer(OutStreamer, TmpInst);
return;
}
case PPC::UpdateGBR: {
// Update the GOT Base Register to point to the GOT. It may be possible to
// merge this with the PPC::GetGBRO, doing it all in one step.
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
TmpInst.setOpcode(PPC::ADD4);
TmpInst.addOperand(TmpInst.getOperand(0));
TmpInst.getOperand(0) = PICR;
TmpInst.getOperand(1) = TR;
TmpInst.getOperand(2) = PICR;
EmitToStreamer(OutStreamer, TmpInst);
return;
}
case PPC::LWZtoc: {
// Transform %X3 = LWZtoc <ga:@min1>, %X2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
// Transform %R3 = LWZtoc <ga:@min1>, %R2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LWZ, and the global address operand to be a
// reference to the GOT entry we will synthesize later.
@ -382,16 +409,23 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
else if (MO.isJTI())
MOSymbol = GetJTISymbol(MO.getIndex());
MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
if (PL == PICLevel::Small) {
const MCExpr *Exp =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT,
OutContext);
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
} else {
MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
const MCExpr *Exp =
MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
OutContext);
const MCExpr *PB =
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
OutContext);
Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
const MCExpr *Exp =
MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
OutContext);
const MCExpr *PB =
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")),
OutContext);
Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
}
EmitToStreamer(OutStreamer, TmpInst);
return;
}
@ -399,7 +433,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::LDtocCPT:
case PPC::LDtoc: {
// Transform %X3 = LDtoc <ga:@min1>, %X2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD, and the global address operand to be a
// reference to the TOC entry we will synthesize later.
@ -428,7 +462,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::ADDIStocHA: {
// Transform %Xd = ADDIStocHA %X2, <ga:@sym>
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to ADDIS8. If the global address is external, has
// common linkage, is a non-local function address, or is a jump table
@ -470,7 +504,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
case PPC::LDtocL: {
// Transform %Xd = LDtocL <ga:@sym>, %Xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD. If the global address is external, has
// common linkage, or is a jump table address, then reference the
@ -507,7 +541,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
case PPC::ADDItocL: {
// Transform %Xd = ADDItocL %Xs, <ga:@sym>
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to ADDI8. If the global address is external, then
// generate a TOC entry and reference that. Otherwise reference the
@ -558,7 +592,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::LDgotTprelL:
case PPC::LDgotTprelL32: {
// Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD.
TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
@ -841,7 +875,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
}
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
EmitToStreamer(OutStreamer, TmpInst);
}
@ -857,16 +891,14 @@ void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_)
return AsmPrinter::EmitStartOfAsmFile(M);
// FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not
// optimal for some cases. We should consider supporting small model (-fpic)
// as well in the future.
assert(TM.getCodeModel() != CodeModel::Small &&
"Small code model PIC is currently unsupported.");
if (M.getPICLevel() == PICLevel::Small)
return AsmPrinter::EmitStartOfAsmFile(M);
OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getReadOnly()));
MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC"));
MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
OutStreamer.EmitLabel(CurrentPos);
@ -885,7 +917,9 @@ void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
// linux/ppc32 - Normal entry label.
if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_)
if (!Subtarget.isPPC64() &&
(TM.getRelocationModel() != Reloc::PIC_ ||
MF->getFunction()->getParent()->getPICLevel() == PICLevel::Small))
return AsmPrinter::EmitFunctionEntryLabel();
if (!Subtarget.isPPC64()) {
@ -897,7 +931,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
const MCExpr *OffsExpr =
MCBinaryExpr::CreateSub(
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")),
OutContext),
MCSymbolRefExpr::Create(PICBase, OutContext),
OutContext);

View File

@ -27,6 +27,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@ -273,23 +274,29 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
const Module *M = MF->getFunction()->getParent();
DebugLoc dl;
if (PPCLowering->getPointerTy() == MVT::i32) {
if (PPCSubTarget->isTargetELF())
if (PPCSubTarget->isTargetELF()) {
GlobalBaseReg = PPC::R30;
else
if (M->getPICLevel() == PICLevel::Small) {
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MoveGOTtoLR));
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
} else {
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
BuildMI(FirstMBB, MBBI, dl,
TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg)
.addReg(TempReg, RegState::Define).addReg(GlobalBaseReg);
MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
}
} else {
GlobalBaseReg =
RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass);
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
if (PPCSubTarget->isTargetELF()) {
unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
BuildMI(FirstMBB, MBBI, dl,
TII.get(PPC::GetGBRO), TempReg).addReg(GlobalBaseReg);
BuildMI(FirstMBB, MBBI, dl,
TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg).addReg(TempReg);
MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
}
} else {
GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass);
@ -1429,13 +1436,13 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain);
}
case PPCISD::TOC_ENTRY: {
assert ((PPCSubTarget->isPPC64() || PPCSubTarget->isSVR4ABI()) &&
"Only supported for 64-bit ABI and 32-bit SVR4");
if (PPCSubTarget->isSVR4ABI() && !PPCSubTarget->isPPC64()) {
SDValue GA = N->getOperand(0);
return CurDAG->getMachineNode(PPC::LWZtoc, dl, MVT::i32, GA,
N->getOperand(1));
}
assert (PPCSubTarget->isPPC64() &&
"Only supported for 64-bit ABI and 32-bit SVR4");
// For medium and large code model, we generate two instructions as
// described below. Otherwise we allow SelectCodeCommon to handle this,

View File

@ -1653,6 +1653,8 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
const GlobalValue *GV = GA->getGlobal();
EVT PtrVT = getPointerTy();
bool is64bit = Subtarget.isPPC64();
const Module *M = DAG.getMachineFunction().getFunction()->getParent();
PICLevel::Level picLevel = M->getPICLevel();
TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
@ -1691,7 +1693,10 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
GOTReg, TGA);
} else {
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
if (picLevel == PICLevel::Small)
GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
else
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
}
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
GOTPtr, TGA);
@ -1721,7 +1726,10 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
GOTReg, TGA);
} else {
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
if (picLevel == PICLevel::Small)
GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
else
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
}
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
GOTPtr, TGA);

View File

@ -976,6 +976,9 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
let Defs = [LR] in
def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>,
PPC970_Unit_BRU;
let Defs = [LR] in
def MoveGOTtoLR : Pseudo<(outs), (ins), "#MoveGOTtoLR", []>,
PPC970_Unit_BRU;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
let isBarrier = 1 in {
@ -2444,15 +2447,13 @@ def ADDISdtprelHA32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp)
tglobaltlsaddr:$disp))]>;
// Support for Position-independent code
def LWZtoc: Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
"#LWZtoc",
[(set i32:$rD,
(PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
def LWZtoc : Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
"#LWZtoc",
[(set i32:$rD,
(PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
// Get Global (GOT) Base Register offset, from the word immediately preceding
// the function label.
def GetGBRO: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#GetGBRO", []>;
// Update the Global(GOT) Base Register with the above offset.
def UpdateGBR: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
def UpdateGBR : Pseudo<(outs gprc:$rD, gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
// Standard shifts. These are represented separately from the real shifts above