- /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC
- /// global base register for ARM ELF.
- struct ARMCGBR : public MachineFunctionPass {
- static char ID;
- ARMCGBR() : MachineFunctionPass(ID) {}
-
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
- if (AFI->getGlobalBaseReg() == 0)
- return false;
-
- const ARMTargetMachine *TM =
- static_cast<const ARMTargetMachine *>(&MF.getTarget());
- if (TM->getRelocationModel() != Reloc::PIC_)
- return false;
-
- LLVMContext* Context = &MF.getFunction()->getContext();
- GlobalValue *GV = new GlobalVariable(Type::getInt32Ty(*Context), false,
- GlobalValue::ExternalLinkage, 0,
- "_GLOBAL_OFFSET_TABLE_");
- unsigned Id = AFI->createPICLabelUId();
- ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id);
- unsigned Align = TM->getDataLayout()->getPrefTypeAlignment(GV->getType());
- unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align);
-
- MachineBasicBlock &FirstMBB = MF.front();
- MachineBasicBlock::iterator MBBI = FirstMBB.begin();
- DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
- unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
- unsigned Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ?
- ARM::t2LDRpci : ARM::LDRcp;
- const TargetInstrInfo &TII = *TM->getInstrInfo();
- MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL,
- TII.get(Opc), GlobalBaseReg)
- .addConstantPoolIndex(Idx);
- if (Opc == ARM::LDRcp)
- MIB.addImm(0);
+/// ARMCGBR - Create Global Base Reg pass. This initializes the PIC
+/// global base register for ARM ELF.
+struct ARMCGBR : public MachineFunctionPass {
+ static char ID;
+ ARMCGBR() : MachineFunctionPass(ID) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ if (AFI->getGlobalBaseReg() == 0)
+ return false;
+ const ARMSubtarget &STI =
+ static_cast<const ARMSubtarget &>(MF.getSubtarget());
+ // Don't do this for Thumb1.
+ if (STI.isThumb1Only())
+ return false;
+
+ const TargetMachine &TM = MF.getTarget();
+ if (TM.getRelocationModel() != Reloc::PIC_)
+ return false;
+
+ LLVMContext *Context = &MF.getFunction()->getContext();
+ unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
+ unsigned PCAdj = STI.isThumb() ? 4 : 8;
+ ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
+ *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj);
+
+ unsigned Align =
+ MF.getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context));
+ unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align);
+
+ MachineBasicBlock &FirstMBB = MF.front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
+ unsigned TempReg =
+ MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass);
+ unsigned Opc = STI.isThumb2() ? ARM::t2LDRpci : ARM::LDRcp;
+ const TargetInstrInfo &TII = *STI.getInstrInfo();
+ MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), TempReg)
+ .addConstantPoolIndex(Idx);
+ if (Opc == ARM::LDRcp)
+ MIB.addImm(0);
+ AddDefaultPred(MIB);
+
+ // Fix the GOT address by adding pc.
+ unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
+ Opc = STI.isThumb2() ? ARM::tPICADD : ARM::PICADD;
+ MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg)
+ .addReg(TempReg)
+ .addImm(ARMPCLabelIndex);
+ if (Opc == ARM::PICADD)