LLVM  3.7.0
ARMInstrInfo.cpp
Go to the documentation of this file.
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"
20 #include "llvm/ADT/STLExtras.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"
30 using namespace llvm;
31 
33  : ARMBaseInstrInfo(STI), RI() {}
34 
35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
37  if (hasNOP()) {
38  NopInst.setOpcode(ARM::HINT);
39  NopInst.addOperand(MCOperand::createImm(0));
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));
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 void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI,
93  Reloc::Model RM) const {
94  MachineFunction &MF = *MI->getParent()->getParent();
95  const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
96 
97  if (!Subtarget.useMovt(MF)) {
98  if (RM == Reloc::PIC_)
99  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12, RM);
100  else
101  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12, RM);
102  return;
103  }
104 
105  if (RM != Reloc::PIC_) {
106  expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12, RM);
107  return;
108  }
109 
110  const GlobalValue *GV =
111  cast<GlobalValue>((*MI->memoperands_begin())->getValue());
112 
113  if (!Subtarget.GVIsIndirectSymbol(GV, RM)) {
114  expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12, RM);
115  return;
116  }
117 
118  MachineBasicBlock &MBB = *MI->getParent();
119  DebugLoc DL = MI->getDebugLoc();
120  unsigned Reg = MI->getOperand(0).getReg();
122 
123  MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
127  MachinePointerInfo::getGOT(), Flag, 4, 4);
128  MIB.addMemOperand(MMO);
129  MIB = BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg);
130  MIB.addReg(Reg, RegState::Kill).addImm(0);
131  MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
132  AddDefaultPred(MIB);
133 }
134 
135 namespace {
136  /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC
137  /// global base register for ARM ELF.
138  struct ARMCGBR : public MachineFunctionPass {
139  static char ID;
140  ARMCGBR() : MachineFunctionPass(ID) {}
141 
142  bool runOnMachineFunction(MachineFunction &MF) override {
144  if (AFI->getGlobalBaseReg() == 0)
145  return false;
146  const ARMSubtarget &STI =
147  static_cast<const ARMSubtarget &>(MF.getSubtarget());
148  // Don't do this for Thumb1.
149  if (STI.isThumb1Only())
150  return false;
151 
152  const TargetMachine &TM = MF.getTarget();
153  if (TM.getRelocationModel() != Reloc::PIC_)
154  return false;
155 
156  LLVMContext *Context = &MF.getFunction()->getContext();
157  unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
158  unsigned PCAdj = STI.isThumb() ? 4 : 8;
160  *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj);
161 
162  unsigned Align = TM.getDataLayout()->getPrefTypeAlignment(
163  Type::getInt32PtrTy(*Context));
164  unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align);
165 
166  MachineBasicBlock &FirstMBB = MF.front();
167  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
168  DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
169  unsigned TempReg =
170  MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass);
171  unsigned Opc = STI.isThumb2() ? ARM::t2LDRpci : ARM::LDRcp;
172  const TargetInstrInfo &TII = *STI.getInstrInfo();
173  MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL,
174  TII.get(Opc), TempReg)
175  .addConstantPoolIndex(Idx);
176  if (Opc == ARM::LDRcp)
177  MIB.addImm(0);
178  AddDefaultPred(MIB);
179 
180  // Fix the GOT address by adding pc.
181  unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
182  Opc = STI.isThumb2() ? ARM::tPICADD : ARM::PICADD;
183  MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg)
184  .addReg(TempReg)
185  .addImm(ARMPCLabelIndex);
186  if (Opc == ARM::PICADD)
187  AddDefaultPred(MIB);
188 
189  return true;
190  }
191 
192  const char *getPassName() const override {
193  return "ARM PIC Global Base Reg Initialization";
194  }
195 
196  void getAnalysisUsage(AnalysisUsage &AU) const override {
197  AU.setPreservesCFG();
199  }
200  };
201 }
202 
203 char ARMCGBR::ID = 0;
205 llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); }
The memory access reads data.
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:223
void getNoopForMachoTarget(MCInst &NopInst) const override
getNoopForMachoTarget - Return the noop instruction to use for a noop.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
FunctionPass * createARMGlobalBaseRegPass()
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
ARMConstantPoolValue - ARM specific constantpool value.
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
Definition: DataLayout.cpp:684
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:291
A debug info location.
Definition: DebugLoc.h:34
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool isThumb1Only() const
Definition: ARMSubtarget.h:405
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
const ARMBaseInstrInfo * getInstrInfo() const override
Definition: ARMSubtarget.h:262
ARMInstrInfo(const ARMSubtarget &STI)
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
MachineMemOperand - A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Reg
All possible values of the reg field in the ModR/M byte.
bool isThumb() const
Definition: ARMSubtarget.h:404
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
const MachineBasicBlock & front() const
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:97
TargetInstrInfo - Interface to description of machine instruction set.
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:41
unsigned getGlobalBaseReg() const
DebugLoc findDebugLoc(instr_iterator MBBI)
findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions...
Represent the analysis usage information of a pass.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
unsigned getUnindexedOpcode(unsigned Opc) const override
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
The memory access is invariant.
void setOpcode(unsigned Op)
Definition: MCInst.h:158
bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const
GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
const DataLayout * getDataLayout() const
Deprecated in 3.7, will be removed in 3.8.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:263
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static ARMConstantPoolSymbol * Create(LLVMContext &C, const char *s, unsigned ID, unsigned char PCAdj)
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
static MachinePointerInfo getGOT()
getGOT - Return a MachinePointerInfo record that refers to a GOT entry.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isThumb2() const
Definition: ARMSubtarget.h:406
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool useMovt(const MachineFunction &MF) const
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
Definition: ARMBaseInfo.h:310
Primary interface to the complete machine description for the target machine.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc, Reloc::Model RM) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...