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/IR/Function.h" 26 #include "llvm/IR/GlobalVariable.h" 27 #include "llvm/MC/MCAsmInfo.h" 28 #include "llvm/MC/MCInst.h" 29 using namespace llvm; 30 31 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) 32 : ARMBaseInstrInfo(STI), RI(STI) { 33 } 34 35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop. 36 void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 37 if (hasNOP()) { 38 NopInst.setOpcode(ARM::HINT); 39 NopInst.addOperand(MCOperand::CreateImm(0)); 40 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 41 NopInst.addOperand(MCOperand::CreateReg(0)); 42 } else { 43 NopInst.setOpcode(ARM::MOVr); 44 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 45 NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); 46 NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 47 NopInst.addOperand(MCOperand::CreateReg(0)); 48 NopInst.addOperand(MCOperand::CreateReg(0)); 49 } 50 } 51 52 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { 53 switch (Opc) { 54 default: break; 55 case ARM::LDR_PRE_IMM: 56 case ARM::LDR_PRE_REG: 57 case ARM::LDR_POST_IMM: 58 case ARM::LDR_POST_REG: 59 return ARM::LDRi12; 60 case ARM::LDRH_PRE: 61 case ARM::LDRH_POST: 62 return ARM::LDRH; 63 case ARM::LDRB_PRE_IMM: 64 case ARM::LDRB_PRE_REG: 65 case ARM::LDRB_POST_IMM: 66 case ARM::LDRB_POST_REG: 67 return ARM::LDRBi12; 68 case ARM::LDRSH_PRE: 69 case ARM::LDRSH_POST: 70 return ARM::LDRSH; 71 case ARM::LDRSB_PRE: 72 case ARM::LDRSB_POST: 73 return ARM::LDRSB; 74 case ARM::STR_PRE_IMM: 75 case ARM::STR_PRE_REG: 76 case ARM::STR_POST_IMM: 77 case ARM::STR_POST_REG: 78 return ARM::STRi12; 79 case ARM::STRH_PRE: 80 case ARM::STRH_POST: 81 return ARM::STRH; 82 case ARM::STRB_PRE_IMM: 83 case ARM::STRB_PRE_REG: 84 case ARM::STRB_POST_IMM: 85 case ARM::STRB_POST_REG: 86 return ARM::STRBi12; 87 } 88 89 return 0; 90 } 91 92 namespace { 93 /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC 94 /// global base register for ARM ELF. 95 struct ARMCGBR : public MachineFunctionPass { 96 static char ID; 97 ARMCGBR() : MachineFunctionPass(ID) {} 98 99 virtual bool runOnMachineFunction(MachineFunction &MF) { 100 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 101 if (AFI->getGlobalBaseReg() == 0) 102 return false; 103 104 const ARMTargetMachine *TM = 105 static_cast<const ARMTargetMachine *>(&MF.getTarget()); 106 if (TM->getRelocationModel() != Reloc::PIC_) 107 return false; 108 109 LLVMContext *Context = &MF.getFunction()->getContext(); 110 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); 111 unsigned PCAdj = TM->getSubtarget<ARMSubtarget>().isThumb() ? 4 : 8; 112 ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create( 113 *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); 114 115 unsigned Align = TM->getDataLayout() 116 ->getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); 117 unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align); 118 119 MachineBasicBlock &FirstMBB = MF.front(); 120 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 121 DebugLoc DL = FirstMBB.findDebugLoc(MBBI); 122 unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); 123 unsigned Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ? 124 ARM::t2LDRpci : ARM::LDRcp; 125 const TargetInstrInfo &TII = *TM->getInstrInfo(); 126 MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, 127 TII.get(Opc), GlobalBaseReg) 128 .addConstantPoolIndex(Idx); 129 if (Opc == ARM::LDRcp) 130 MIB.addImm(0); 131 AddDefaultPred(MIB); 132 133 return true; 134 } 135 136 virtual const char *getPassName() const { 137 return "ARM PIC Global Base Reg Initialization"; 138 } 139 140 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 141 AU.setPreservesCFG(); 142 MachineFunctionPass::getAnalysisUsage(AU); 143 } 144 }; 145 } 146 147 char ARMCGBR::ID = 0; 148 FunctionPass* 149 llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); } 150