LLVM 20.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"
17#include "ARMTargetMachine.h"
19#include "llvm/ADT/STLExtras.h"
25#include "llvm/IR/Function.h"
27#include "llvm/IR/Module.h"
28#include "llvm/MC/MCAsmInfo.h"
29#include "llvm/MC/MCInst.h"
30using namespace llvm;
31
33
34/// Return the noop instruction to use for a noop.
36 MCInst NopInst;
37 if (hasNOP()) {
38 NopInst.setOpcode(ARM::HINT);
42 } else {
43 NopInst.setOpcode(ARM::MOVr);
44 NopInst.addOperand(MCOperand::createReg(ARM::R0));
45 NopInst.addOperand(MCOperand::createReg(ARM::R0));
49 }
50 return NopInst;
51}
52
53unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
54 switch (Opc) {
55 default:
56 break;
57 case ARM::LDR_PRE_IMM:
58 case ARM::LDR_PRE_REG:
59 case ARM::LDR_POST_IMM:
60 case ARM::LDR_POST_REG:
61 return ARM::LDRi12;
62 case ARM::LDRH_PRE:
63 case ARM::LDRH_POST:
64 return ARM::LDRH;
65 case ARM::LDRB_PRE_IMM:
66 case ARM::LDRB_PRE_REG:
67 case ARM::LDRB_POST_IMM:
68 case ARM::LDRB_POST_REG:
69 return ARM::LDRBi12;
70 case ARM::LDRSH_PRE:
71 case ARM::LDRSH_POST:
72 return ARM::LDRSH;
73 case ARM::LDRSB_PRE:
74 case ARM::LDRSB_POST:
75 return ARM::LDRSB;
76 case ARM::STR_PRE_IMM:
77 case ARM::STR_PRE_REG:
78 case ARM::STR_POST_IMM:
79 case ARM::STR_POST_REG:
80 return ARM::STRi12;
81 case ARM::STRH_PRE:
82 case ARM::STRH_POST:
83 return ARM::STRH;
84 case ARM::STRB_PRE_IMM:
85 case ARM::STRB_PRE_REG:
86 case ARM::STRB_POST_IMM:
87 case ARM::STRB_POST_REG:
88 return ARM::STRBi12;
89 }
90
91 return 0;
92}
93
94void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
95 MachineFunction &MF = *MI->getParent()->getParent();
96 const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
97 const TargetMachine &TM = MF.getTarget();
98 Module &M = *MF.getFunction().getParent();
99
100 if (M.getStackProtectorGuard() == "tls") {
101 expandLoadStackGuardBase(MI, ARM::MRC, ARM::LDRi12);
102 return;
103 }
104
105 const GlobalValue *GV =
106 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
107
108 bool ForceELFGOTPIC = Subtarget.isTargetELF() && !GV->isDSOLocal();
109 if (!Subtarget.useMovt() || ForceELFGOTPIC) {
110 // For ELF non-PIC, use GOT PIC code sequence as well because R_ARM_GOT_ABS
111 // does not have assembler support.
112 if (TM.isPositionIndependent() || ForceELFGOTPIC)
113 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
114 else
115 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
116 return;
117 }
118
119 if (!TM.isPositionIndependent()) {
120 expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
121 return;
122 }
123
124 if (!Subtarget.isGVIndirectSymbol(GV)) {
125 expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
126 return;
127 }
128
129 MachineBasicBlock &MBB = *MI->getParent();
130 DebugLoc DL = MI->getDebugLoc();
131 Register Reg = MI->getOperand(0).getReg();
133
134 MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
141 MIB.addMemOperand(MMO);
142 BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
144 .addImm(0)
147}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
const char LLVMTargetMachineRef TM
This file contains some templates that are useful if you are working with the STL at all.
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
unsigned getUnindexedOpcode(unsigned Opc) const override
ARMInstrInfo(const ARMSubtarget &STI)
MCInst getNop() const override
Return the noop instruction to use for a noop.
bool useMovt() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
bool isTargetELF() const
Definition: ARMSubtarget.h:311
A debug info location.
Definition: DebugLoc.h:33
bool isDSOLocal() const
Definition: GlobalValue.h:305
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:656
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
Definition: ARMBaseInfo.h:288
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.