LLVM  10.0.0svn
ARMInstrInfo.cpp
Go to the documentation of this file.
1 //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ARMInstrInfo.h"
14 #include "ARM.h"
15 #include "ARMConstantPoolValue.h"
16 #include "ARMMachineFunctionInfo.h"
17 #include "ARMTargetMachine.h"
19 #include "llvm/ADT/STLExtras.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 
32  : ARMBaseInstrInfo(STI), RI() {}
33 
34 /// Return the noop instruction to use for a noop.
35 void ARMInstrInfo::getNoop(MCInst &NopInst) const {
36  if (hasNOP()) {
37  NopInst.setOpcode(ARM::HINT);
38  NopInst.addOperand(MCOperand::createImm(0));
40  NopInst.addOperand(MCOperand::createReg(0));
41  } else {
42  NopInst.setOpcode(ARM::MOVr);
43  NopInst.addOperand(MCOperand::createReg(ARM::R0));
44  NopInst.addOperand(MCOperand::createReg(ARM::R0));
46  NopInst.addOperand(MCOperand::createReg(0));
47  NopInst.addOperand(MCOperand::createReg(0));
48  }
49 }
50 
51 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
52  switch (Opc) {
53  default:
54  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) const {
93  MachineFunction &MF = *MI->getParent()->getParent();
94  const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
95  const TargetMachine &TM = MF.getTarget();
96 
97  if (!Subtarget.useMovt()) {
98  if (TM.isPositionIndependent())
99  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
100  else
101  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
102  return;
103  }
104 
105  if (!TM.isPositionIndependent()) {
106  expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
107  return;
108  }
109 
110  const GlobalValue *GV =
111  cast<GlobalValue>((*MI->memoperands_begin())->getValue());
112 
113  if (!Subtarget.isGVIndirectSymbol(GV)) {
114  expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
115  return;
116  }
117 
118  MachineBasicBlock &MBB = *MI->getParent();
119  DebugLoc DL = MI->getDebugLoc();
120  Register Reg = MI->getOperand(0).getReg();
122 
123  MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
125  auto Flags = MachineMemOperand::MOLoad |
129  MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, 4);
130  MIB.addMemOperand(MMO);
131  BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
132  .addReg(Reg, RegState::Kill)
133  .addImm(0)
134  .cloneMemRefs(*MI)
135  .add(predOps(ARMCC::AL));
136 }
bool useMovt() const
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned Reg
A debug info location.
Definition: DebugLoc.h:33
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:115
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.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
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:170
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 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:284
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19