LLVM  8.0.1
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  .cloneMemRefs(*MI)
136  .add(predOps(ARMCC::AL));
137 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
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.
bool useMovt(const MachineFunction &MF) const
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.
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
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.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
The memory access always returns the same value (or traps).
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
Definition: ARMBaseInfo.h:279
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
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123