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 "MCTargetDesc/ARMAddressingModes.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/CodeGen/LiveVariables.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineJumpTableInfo.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.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"
31 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget
&STI
)
32 : ARMBaseInstrInfo(STI
), RI() {}
34 /// Return the noop instruction to use for a noop.
35 MCInst
ARMInstrInfo::getNop() const {
38 NopInst
.setOpcode(ARM::HINT
);
39 NopInst
.addOperand(MCOperand::createImm(0));
40 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
41 NopInst
.addOperand(MCOperand::createReg(0));
43 NopInst
.setOpcode(ARM::MOVr
);
44 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
45 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
46 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
47 NopInst
.addOperand(MCOperand::createReg(0));
48 NopInst
.addOperand(MCOperand::createReg(0));
53 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc
) const {
57 case ARM::LDR_PRE_IMM
:
58 case ARM::LDR_PRE_REG
:
59 case ARM::LDR_POST_IMM
:
60 case ARM::LDR_POST_REG
:
65 case ARM::LDRB_PRE_IMM
:
66 case ARM::LDRB_PRE_REG
:
67 case ARM::LDRB_POST_IMM
:
68 case ARM::LDRB_POST_REG
:
76 case ARM::STR_PRE_IMM
:
77 case ARM::STR_PRE_REG
:
78 case ARM::STR_POST_IMM
:
79 case ARM::STR_POST_REG
:
84 case ARM::STRB_PRE_IMM
:
85 case ARM::STRB_PRE_REG
:
86 case ARM::STRB_POST_IMM
:
87 case ARM::STRB_POST_REG
:
94 void 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();
99 if (!Subtarget
.useMovt()) {
100 if (TM
.isPositionIndependent())
101 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_pcrel
, ARM::LDRi12
);
103 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_abs
, ARM::LDRi12
);
107 if (!TM
.isPositionIndependent()) {
108 expandLoadStackGuardBase(MI
, ARM::MOVi32imm
, ARM::LDRi12
);
112 const GlobalValue
*GV
=
113 cast
<GlobalValue
>((*MI
->memoperands_begin())->getValue());
115 if (!Subtarget
.isGVIndirectSymbol(GV
)) {
116 expandLoadStackGuardBase(MI
, ARM::MOV_ga_pcrel
, ARM::LDRi12
);
120 MachineBasicBlock
&MBB
= *MI
->getParent();
121 DebugLoc DL
= MI
->getDebugLoc();
122 Register Reg
= MI
->getOperand(0).getReg();
123 MachineInstrBuilder MIB
;
125 MIB
= BuildMI(MBB
, MI
, DL
, get(ARM::MOV_ga_pcrel_ldr
), Reg
)
126 .addGlobalAddress(GV
, 0, ARMII::MO_NONLAZY
);
127 auto Flags
= MachineMemOperand::MOLoad
|
128 MachineMemOperand::MODereferenceable
|
129 MachineMemOperand::MOInvariant
;
130 MachineMemOperand
*MMO
= MBB
.getParent()->getMachineMemOperand(
131 MachinePointerInfo::getGOT(*MBB
.getParent()), Flags
, 4, Align(4));
132 MIB
.addMemOperand(MMO
);
133 BuildMI(MBB
, MI
, DL
, get(ARM::LDRi12
), Reg
)
134 .addReg(Reg
, RegState::Kill
)
137 .add(predOps(ARMCC::AL
));