LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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(STI) {
34 }
35 
36 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
38  if (hasNOP()) {
39  NopInst.setOpcode(ARM::HINT);
40  NopInst.addOperand(MCOperand::CreateImm(0));
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));
48  NopInst.addOperand(MCOperand::CreateReg(0));
49  NopInst.addOperand(MCOperand::CreateReg(0));
50  }
51 }
52 
53 unsigned 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 
93 namespace {
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) {
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;
114  *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj);
115 
116  unsigned Align = TM->getDataLayout()
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();
156  }
157  };
158 }
159 
160 char ARMCGBR::ID = 0;
162 llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); }
LLVMContext & getContext() const
Definition: Function.cpp:167
Reloc::Model getRelocationModel() const
static MCOperand CreateReg(unsigned Reg)
Definition: MCInst.h:111
FunctionPass * createARMGlobalBaseRegPass()
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
unsigned getPrefTypeAlignment(Type *Ty) const
Definition: DataLayout.cpp:600
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:292
const Function * getFunction() const
ARMInstrInfo(const ARMSubtarget &STI)
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
unsigned getUnindexedOpcode(unsigned Opc) const
const HexagonInstrInfo * TII
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
const MachineBasicBlock & front() const
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getGlobalBaseReg() const
virtual const ARMInstrInfo * getInstrInfo() const
MachineConstantPool * getConstantPool()
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
const MCInstrDesc & get(unsigned Opcode) const
Definition: MCInstrInfo.h:48
DebugLoc findDebugLoc(instr_iterator MBBI)
void setOpcode(unsigned Op)
Definition: MCInst.h:157
const STC & getSubtarget() const
void setPreservesCFG()
Definition: Pass.cpp:249
static ARMConstantPoolSymbol * Create(LLVMContext &C, const char *s, unsigned ID, unsigned char PCAdj)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
MachineRegisterInfo & getRegInfo()
virtual const DataLayout * getDataLayout() const
static MCOperand CreateImm(int64_t Val)
Definition: MCInst.h:117
virtual void getAnalysisUsage(AnalysisUsage &AU) const
const TargetMachine & getTarget() const
void addOperand(const MCOperand &Op)
Definition: MCInst.h:167
void getNoopForMachoTarget(MCInst &NopInst) const
getNoopForMachoTarget - Return the noop instruction to use for a noop.
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)