ARMInstrInfo.cpp revision 263508
1//===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the ARM implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARMInstrInfo.h" 15#include "ARM.h" 16#include "ARMConstantPoolValue.h" 17#include "ARMMachineFunctionInfo.h" 18#include "ARMTargetMachine.h" 19#include "MCTargetDesc/ARMAddressingModes.h" 20#include "llvm/ADT/STLExtras.h" 21#include "llvm/CodeGen/LiveVariables.h" 22#include "llvm/CodeGen/MachineFrameInfo.h" 23#include "llvm/CodeGen/MachineInstrBuilder.h" 24#include "llvm/CodeGen/MachineJumpTableInfo.h" 25#include "llvm/CodeGen/MachineRegisterInfo.h" 26#include "llvm/IR/Function.h" 27#include "llvm/IR/GlobalVariable.h" 28#include "llvm/MC/MCAsmInfo.h" 29#include "llvm/MC/MCInst.h" 30using namespace llvm; 31 32ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) 33 : ARMBaseInstrInfo(STI), RI(STI) { 34} 35 36/// getNoopForMachoTarget - Return the noop instruction to use for a noop. 37void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 38 if (hasNOP()) { 39 NopInst.setOpcode(ARM::HINT); 40 NopInst.addOperand(MCOperand::CreateImm(0)); 41 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 42 NopInst.addOperand(MCOperand::CreateReg(0)); 43 } else { 44 NopInst.setOpcode(ARM::MOVr); 45 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 46 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 47 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 48 NopInst.addOperand(MCOperand::CreateReg(0)); 49 NopInst.addOperand(MCOperand::CreateReg(0)); 50 } 51} 52 53unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { 54 switch (Opc) { 55 default: break; 56 case ARM::LDR_PRE_IMM: 57 case ARM::LDR_PRE_REG: 58 case ARM::LDR_POST_IMM: 59 case ARM::LDR_POST_REG: 60 return ARM::LDRi12; 61 case ARM::LDRH_PRE: 62 case ARM::LDRH_POST: 63 return ARM::LDRH; 64 case ARM::LDRB_PRE_IMM: 65 case ARM::LDRB_PRE_REG: 66 case ARM::LDRB_POST_IMM: 67 case ARM::LDRB_POST_REG: 68 return ARM::LDRBi12; 69 case ARM::LDRSH_PRE: 70 case ARM::LDRSH_POST: 71 return ARM::LDRSH; 72 case ARM::LDRSB_PRE: 73 case ARM::LDRSB_POST: 74 return ARM::LDRSB; 75 case ARM::STR_PRE_IMM: 76 case ARM::STR_PRE_REG: 77 case ARM::STR_POST_IMM: 78 case ARM::STR_POST_REG: 79 return ARM::STRi12; 80 case ARM::STRH_PRE: 81 case ARM::STRH_POST: 82 return ARM::STRH; 83 case ARM::STRB_PRE_IMM: 84 case ARM::STRB_PRE_REG: 85 case ARM::STRB_POST_IMM: 86 case ARM::STRB_POST_REG: 87 return ARM::STRBi12; 88 } 89 90 return 0; 91} 92 93namespace { 94 /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC 95 /// global base register for ARM ELF. 96 struct ARMCGBR : public MachineFunctionPass { 97 static char ID; 98 ARMCGBR() : MachineFunctionPass(ID) {} 99 100 virtual bool runOnMachineFunction(MachineFunction &MF) { 101 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 102 if (AFI->getGlobalBaseReg() == 0) 103 return false; 104 105 const ARMTargetMachine *TM = 106 static_cast<const ARMTargetMachine *>(&MF.getTarget()); 107 if (TM->getRelocationModel() != Reloc::PIC_) 108 return false; 109 110 LLVMContext *Context = &MF.getFunction()->getContext(); 111 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); 112 unsigned PCAdj = TM->getSubtarget<ARMSubtarget>().isThumb() ? 4 : 8; 113 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create( 114 *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); 115 116 unsigned Align = TM->getDataLayout() 117 ->getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); 118 unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align); 119 120 MachineBasicBlock &FirstMBB = MF.front(); 121 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 122 DebugLoc DL = FirstMBB.findDebugLoc(MBBI); 123 unsigned TempReg = 124 MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); 125 unsigned Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ? 126 ARM::t2LDRpci : ARM::LDRcp; 127 const TargetInstrInfo &TII = *TM->getInstrInfo(); 128 MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, 129 TII.get(Opc), TempReg) 130 .addConstantPoolIndex(Idx); 131 if (Opc == ARM::LDRcp) 132 MIB.addImm(0); 133 AddDefaultPred(MIB); 134 135 // Fix the GOT address by adding pc. 136 unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); 137 Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ? ARM::tPICADD 138 : ARM::PICADD; 139 MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg) 140 .addReg(TempReg) 141 .addImm(ARMPCLabelIndex); 142 if (Opc == ARM::PICADD) 143 AddDefaultPred(MIB); 144 145 146 return true; 147 } 148 149 virtual const char *getPassName() const { 150 return "ARM PIC Global Base Reg Initialization"; 151 } 152 153 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 154 AU.setPreservesCFG(); 155 MachineFunctionPass::getAnalysisUsage(AU); 156 } 157 }; 158} 159 160char ARMCGBR::ID = 0; 161FunctionPass* 162llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); } 163