1 //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the ARM implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "ARMInstrInfo.h"
15 #include "ARMConstantPoolValue.h"
16 #include "ARMMachineFunctionInfo.h"
17 #include "ARMTargetMachine.h"
18 #include "llvm/CodeGen/LiveVariables.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineJumpTableInfo.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/GlobalVariable.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/MC/MCInst.h"
28 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget
&STI
) : ARMBaseInstrInfo(STI
) {}
30 /// Return the noop instruction to use for a noop.
31 MCInst
ARMInstrInfo::getNop() const {
34 NopInst
.setOpcode(ARM::HINT
);
35 NopInst
.addOperand(MCOperand::createImm(0));
36 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
37 NopInst
.addOperand(MCOperand::createReg(0));
39 NopInst
.setOpcode(ARM::MOVr
);
40 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
41 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
42 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
43 NopInst
.addOperand(MCOperand::createReg(0));
44 NopInst
.addOperand(MCOperand::createReg(0));
49 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc
) const {
53 case ARM::LDR_PRE_IMM
:
54 case ARM::LDR_PRE_REG
:
55 case ARM::LDR_POST_IMM
:
56 case ARM::LDR_POST_REG
:
61 case ARM::LDRB_PRE_IMM
:
62 case ARM::LDRB_PRE_REG
:
63 case ARM::LDRB_POST_IMM
:
64 case ARM::LDRB_POST_REG
:
72 case ARM::STR_PRE_IMM
:
73 case ARM::STR_PRE_REG
:
74 case ARM::STR_POST_IMM
:
75 case ARM::STR_POST_REG
:
80 case ARM::STRB_PRE_IMM
:
81 case ARM::STRB_PRE_REG
:
82 case ARM::STRB_POST_IMM
:
83 case ARM::STRB_POST_REG
:
90 void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI
) const {
91 MachineFunction
&MF
= *MI
->getParent()->getParent();
92 const ARMSubtarget
&Subtarget
= MF
.getSubtarget
<ARMSubtarget
>();
93 const TargetMachine
&TM
= MF
.getTarget();
94 Module
&M
= *MF
.getFunction().getParent();
96 if (M
.getStackProtectorGuard() == "tls") {
97 expandLoadStackGuardBase(MI
, ARM::MRC
, ARM::LDRi12
);
101 const GlobalValue
*GV
=
102 cast
<GlobalValue
>((*MI
->memoperands_begin())->getValue());
104 bool ForceELFGOTPIC
= Subtarget
.isTargetELF() && !GV
->isDSOLocal();
105 if (!Subtarget
.useMovt() || ForceELFGOTPIC
) {
106 // For ELF non-PIC, use GOT PIC code sequence as well because R_ARM_GOT_ABS
107 // does not have assembler support.
108 if (TM
.isPositionIndependent() || ForceELFGOTPIC
)
109 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_pcrel
, ARM::LDRi12
);
111 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_abs
, ARM::LDRi12
);
115 if (!TM
.isPositionIndependent()) {
116 expandLoadStackGuardBase(MI
, ARM::MOVi32imm
, ARM::LDRi12
);
120 if (!Subtarget
.isGVIndirectSymbol(GV
)) {
121 expandLoadStackGuardBase(MI
, ARM::MOV_ga_pcrel
, ARM::LDRi12
);
125 MachineBasicBlock
&MBB
= *MI
->getParent();
126 DebugLoc DL
= MI
->getDebugLoc();
127 Register Reg
= MI
->getOperand(0).getReg();
128 MachineInstrBuilder MIB
;
130 MIB
= BuildMI(MBB
, MI
, DL
, get(ARM::MOV_ga_pcrel_ldr
), Reg
)
131 .addGlobalAddress(GV
, 0, ARMII::MO_NONLAZY
);
132 auto Flags
= MachineMemOperand::MOLoad
|
133 MachineMemOperand::MODereferenceable
|
134 MachineMemOperand::MOInvariant
;
135 MachineMemOperand
*MMO
= MBB
.getParent()->getMachineMemOperand(
136 MachinePointerInfo::getGOT(*MBB
.getParent()), Flags
, 4, Align(4));
137 MIB
.addMemOperand(MMO
);
138 BuildMI(MBB
, MI
, DL
, get(ARM::LDRi12
), Reg
)
139 .addReg(Reg
, RegState::Kill
)
142 .add(predOps(ARMCC::AL
));