LLVM  7.0.0svn
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 /// Return the noop instruction to use for a noop.
36 void ARMInstrInfo::getNoop(MCInst &NopInst) const {
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:
55  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 void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
94  MachineFunction &MF = *MI->getParent()->getParent();
95  const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
96  const TargetMachine &TM = MF.getTarget();
97 
98  if (!Subtarget.useMovt(MF)) {
99  if (TM.isPositionIndependent())
100  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
101  else
102  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
103  return;
104  }
105 
106  if (!TM.isPositionIndependent()) {
107  expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
108  return;
109  }
110 
111  const GlobalValue *GV =
112  cast<GlobalValue>((*MI->memoperands_begin())->getValue());
113 
114  if (!Subtarget.isGVIndirectSymbol(GV)) {
115  expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
116  return;
117  }
118 
119  MachineBasicBlock &MBB = *MI->getParent();
120  DebugLoc DL = MI->getDebugLoc();
121  unsigned Reg = MI->getOperand(0).getReg();
123 
124  MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
126  auto Flags = MachineMemOperand::MOLoad |
130  MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, 4);
131  MIB.addMemOperand(MMO);
132  BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
133  .addReg(Reg, RegState::Kill)
134  .addImm(0)
135  .setMemRefs(MI->memoperands_begin(), MI->memoperands_end())
136  .add(predOps(ARMCC::AL));
137 }
138 
139 std::pair<unsigned, unsigned>
141  const unsigned Mask = ARMII::MO_OPTION_MASK;
142  return std::make_pair(TF & Mask, TF & ~Mask);
143 }
144 
147  using namespace ARMII;
148 
149  static const std::pair<unsigned, const char *> TargetFlags[] = {
150  {MO_LO16, "arm-lo16"}, {MO_HI16, "arm-hi16"}};
151  return makeArrayRef(TargetFlags);
152 }
153 
156  using namespace ARMII;
157 
158  static const std::pair<unsigned, const char *> TargetFlags[] = {
159  {MO_GOT, "arm-got"},
160  {MO_SBREL, "arm-sbrel"},
161  {MO_DLLIMPORT, "arm-dllimport"},
162  {MO_SECREL, "arm-secrel"},
163  {MO_NONLAZY, "arm-nonlazy"}};
164  return makeArrayRef(TargetFlags);
165 }
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
unsigned Reg
A debug info location.
Definition: DebugLoc.h:34
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
void getNoop(MCInst &NopInst) const override
Return the noop instruction to use for a noop.
ARMInstrInfo(const ARMSubtarget &STI)
A description of a memory reference used in the backend.
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
Definition: ARMBaseInfo.h:254
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
The memory access is dereferenceable (i.e., doesn&#39;t trap).
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
bool useMovt(const MachineFunction &MF) const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...
Definition: ARMBaseInfo.h:265
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
unsigned getUnindexedOpcode(unsigned Opc) const override
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address...
Definition: ARMBaseInfo.h:239
void setOpcode(unsigned Op)
Definition: MCInst.h:173
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
The memory access reads data.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
The memory access always returns the same value (or traps).
MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects just that part of the flag set...
Definition: ARMBaseInfo.h:247
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
Definition: ARMBaseInfo.h:272
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:59
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address...
Definition: ARMBaseInfo.h:243