LLVM  16.0.0git
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 
33 /// Return the noop instruction to use for a noop.
35  MCInst NopInst;
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  return NopInst;
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  Module &M = *MF.getFunction().getParent();
98 
99  if (M.getStackProtectorGuard() == "tls") {
100  expandLoadStackGuardBase(MI, ARM::MRC, ARM::LDRi12);
101  return;
102  }
103 
104  const GlobalValue *GV =
105  cast<GlobalValue>((*MI->memoperands_begin())->getValue());
106 
107  if (!Subtarget.useMovt() || Subtarget.isGVInGOT(GV)) {
108  if (TM.isPositionIndependent())
109  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
110  else
111  expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
112  return;
113  }
114 
115  if (!TM.isPositionIndependent()) {
116  expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
117  return;
118  }
119 
120  if (!Subtarget.isGVIndirectSymbol(GV)) {
121  expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
122  return;
123  }
124 
125  MachineBasicBlock &MBB = *MI->getParent();
126  DebugLoc DL = MI->getDebugLoc();
127  Register Reg = MI->getOperand(0).getReg();
129 
130  MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
136  MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, Align(4));
137  MIB.addMemOperand(MMO);
138  BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
140  .addImm(0)
141  .cloneMemRefs(*MI)
142  .add(predOps(ARMCC::AL));
143 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ARMSubtarget
Definition: ARMSubtarget.h:47
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::MachineFunction::getMachineMemOperand
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align 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.
Definition: MachineFunction.cpp:454
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::MachineMemOperand::MOInvariant
@ MOInvariant
The memory access always returns the same value (or traps).
Definition: MachineMemOperand.h:144
ARMMachineFunctionInfo.h
MachineJumpTableInfo.h
llvm::MachineMemOperand
A description of a memory reference used in the backend.
Definition: MachineMemOperand.h:127
llvm::MachineMemOperand::MODereferenceable
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
Definition: MachineMemOperand.h:142
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::ARMBaseInstrInfo::expandLoadStackGuardBase
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
Definition: ARMBaseInstrInfo.cpp:4927
MachineRegisterInfo.h
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
ARMConstantPoolValue.h
llvm::ARMInstrInfo::getUnindexedOpcode
unsigned getUnindexedOpcode(unsigned Opc) const override
Definition: ARMInstrInfo.cpp:52
llvm::ARMSubtarget::useMovt
bool useMovt() const
Definition: ARMSubtarget.cpp:430
MCInst.h
LiveVariables.h
llvm::MachinePointerInfo::getGOT
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
Definition: MachineOperand.cpp:1028
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::ARMInstrInfo::getNop
MCInst getNop() const override
Return the noop instruction to use for a noop.
Definition: ARMInstrInfo.cpp:34
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
llvm::MachineInstrBuilder::cloneMemRefs
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
Definition: MachineInstrBuilder.h:213
llvm::ARMInstrInfo::ARMInstrInfo
ARMInstrInfo(const ARMSubtarget &STI)
Definition: ARMInstrInfo.cpp:31
llvm::ARMCC::AL
@ AL
Definition: ARMBaseInfo.h:45
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:650
llvm::ARMII::MO_NONLAZY
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
Definition: ARMBaseInfo.h:288
llvm::ARMBaseInstrInfo
Definition: ARMBaseInstrInfo.h:37
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:261
llvm::MachineInstrBuilder::addMemOperand
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Definition: MachineInstrBuilder.h:202
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
ARM.h
llvm::MachineFunction
Definition: MachineFunction.h:257
ARMAddressingModes.h
MCAsmInfo.h
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
ARMInstrInfo.h
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:134
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ARMSubtarget::isGVInGOT
bool isGVInGOT(const GlobalValue *GV) const
Returns the constant pool modifier needed to access the GV.
Definition: ARMSubtarget.cpp:366
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:623
llvm::MachineFunction::getTarget
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition: MachineFunction.h:653
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
MachineFrameInfo.h
GlobalVariable.h
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
Function.h
llvm::MachineInstrBuilder::addGlobalAddress
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:177
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
MachineInstrBuilder.h
llvm::ARMBaseInstrInfo::hasNOP
bool hasNOP() const
Definition: ARMBaseInstrInfo.cpp:5434
llvm::ARMSubtarget::isGVIndirectSymbol
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
Definition: ARMSubtarget.cpp:352
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::predOps
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Definition: ARMBaseInstrInfo.h:541
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
ARMTargetMachine.h
llvm::MachineInstrBundleIterator< MachineInstr >