LLVM API Documentation
00001 //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the ARM implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "ARMInstrInfo.h" 00015 #include "ARM.h" 00016 #include "ARMConstantPoolValue.h" 00017 #include "ARMMachineFunctionInfo.h" 00018 #include "ARMTargetMachine.h" 00019 #include "MCTargetDesc/ARMAddressingModes.h" 00020 #include "llvm/ADT/STLExtras.h" 00021 #include "llvm/CodeGen/LiveVariables.h" 00022 #include "llvm/CodeGen/MachineFrameInfo.h" 00023 #include "llvm/CodeGen/MachineInstrBuilder.h" 00024 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00025 #include "llvm/CodeGen/MachineRegisterInfo.h" 00026 #include "llvm/IR/Function.h" 00027 #include "llvm/IR/GlobalVariable.h" 00028 #include "llvm/MC/MCAsmInfo.h" 00029 #include "llvm/MC/MCInst.h" 00030 using namespace llvm; 00031 00032 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) 00033 : ARMBaseInstrInfo(STI), RI(STI) { 00034 } 00035 00036 /// getNoopForMachoTarget - Return the noop instruction to use for a noop. 00037 void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 00038 if (hasNOP()) { 00039 NopInst.setOpcode(ARM::HINT); 00040 NopInst.addOperand(MCOperand::CreateImm(0)); 00041 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 00042 NopInst.addOperand(MCOperand::CreateReg(0)); 00043 } else { 00044 NopInst.setOpcode(ARM::MOVr); 00045 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 00046 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 00047 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 00048 NopInst.addOperand(MCOperand::CreateReg(0)); 00049 NopInst.addOperand(MCOperand::CreateReg(0)); 00050 } 00051 } 00052 00053 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { 00054 switch (Opc) { 00055 default: break; 00056 case ARM::LDR_PRE_IMM: 00057 case ARM::LDR_PRE_REG: 00058 case ARM::LDR_POST_IMM: 00059 case ARM::LDR_POST_REG: 00060 return ARM::LDRi12; 00061 case ARM::LDRH_PRE: 00062 case ARM::LDRH_POST: 00063 return ARM::LDRH; 00064 case ARM::LDRB_PRE_IMM: 00065 case ARM::LDRB_PRE_REG: 00066 case ARM::LDRB_POST_IMM: 00067 case ARM::LDRB_POST_REG: 00068 return ARM::LDRBi12; 00069 case ARM::LDRSH_PRE: 00070 case ARM::LDRSH_POST: 00071 return ARM::LDRSH; 00072 case ARM::LDRSB_PRE: 00073 case ARM::LDRSB_POST: 00074 return ARM::LDRSB; 00075 case ARM::STR_PRE_IMM: 00076 case ARM::STR_PRE_REG: 00077 case ARM::STR_POST_IMM: 00078 case ARM::STR_POST_REG: 00079 return ARM::STRi12; 00080 case ARM::STRH_PRE: 00081 case ARM::STRH_POST: 00082 return ARM::STRH; 00083 case ARM::STRB_PRE_IMM: 00084 case ARM::STRB_PRE_REG: 00085 case ARM::STRB_POST_IMM: 00086 case ARM::STRB_POST_REG: 00087 return ARM::STRBi12; 00088 } 00089 00090 return 0; 00091 } 00092 00093 void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI, 00094 Reloc::Model RM) const { 00095 if (RM == Reloc::PIC_) 00096 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12, RM); 00097 else 00098 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12, RM); 00099 } 00100 00101 namespace { 00102 /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC 00103 /// global base register for ARM ELF. 00104 struct ARMCGBR : public MachineFunctionPass { 00105 static char ID; 00106 ARMCGBR() : MachineFunctionPass(ID) {} 00107 00108 bool runOnMachineFunction(MachineFunction &MF) override { 00109 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00110 if (AFI->getGlobalBaseReg() == 0) 00111 return false; 00112 00113 const ARMTargetMachine *TM = 00114 static_cast<const ARMTargetMachine *>(&MF.getTarget()); 00115 if (TM->getRelocationModel() != Reloc::PIC_) 00116 return false; 00117 00118 LLVMContext *Context = &MF.getFunction()->getContext(); 00119 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); 00120 unsigned PCAdj = TM->getSubtarget<ARMSubtarget>().isThumb() ? 4 : 8; 00121 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create( 00122 *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); 00123 00124 unsigned Align = 00125 TM->getSubtargetImpl()->getDataLayout()->getPrefTypeAlignment( 00126 Type::getInt32PtrTy(*Context)); 00127 unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align); 00128 00129 MachineBasicBlock &FirstMBB = MF.front(); 00130 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 00131 DebugLoc DL = FirstMBB.findDebugLoc(MBBI); 00132 unsigned TempReg = 00133 MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); 00134 unsigned Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ? 00135 ARM::t2LDRpci : ARM::LDRcp; 00136 const TargetInstrInfo &TII = *TM->getSubtargetImpl()->getInstrInfo(); 00137 MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, 00138 TII.get(Opc), TempReg) 00139 .addConstantPoolIndex(Idx); 00140 if (Opc == ARM::LDRcp) 00141 MIB.addImm(0); 00142 AddDefaultPred(MIB); 00143 00144 // Fix the GOT address by adding pc. 00145 unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); 00146 Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ? ARM::tPICADD 00147 : ARM::PICADD; 00148 MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg) 00149 .addReg(TempReg) 00150 .addImm(ARMPCLabelIndex); 00151 if (Opc == ARM::PICADD) 00152 AddDefaultPred(MIB); 00153 00154 00155 return true; 00156 } 00157 00158 const char *getPassName() const override { 00159 return "ARM PIC Global Base Reg Initialization"; 00160 } 00161 00162 void getAnalysisUsage(AnalysisUsage &AU) const override { 00163 AU.setPreservesCFG(); 00164 MachineFunctionPass::getAnalysisUsage(AU); 00165 } 00166 }; 00167 } 00168 00169 char ARMCGBR::ID = 0; 00170 FunctionPass* 00171 llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); }