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 void ARMInstrInfo::getNoop(MCInst
&NopInst
) const {
37 NopInst
.setOpcode(ARM::HINT
);
38 NopInst
.addOperand(MCOperand::createImm(0));
39 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
40 NopInst
.addOperand(MCOperand::createReg(0));
42 NopInst
.setOpcode(ARM::MOVr
);
43 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
44 NopInst
.addOperand(MCOperand::createReg(ARM::R0
));
45 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
46 NopInst
.addOperand(MCOperand::createReg(0));
47 NopInst
.addOperand(MCOperand::createReg(0));
51 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc
) const {
55 case ARM::LDR_PRE_IMM
:
56 case ARM::LDR_PRE_REG
:
57 case ARM::LDR_POST_IMM
:
58 case ARM::LDR_POST_REG
:
63 case ARM::LDRB_PRE_IMM
:
64 case ARM::LDRB_PRE_REG
:
65 case ARM::LDRB_POST_IMM
:
66 case ARM::LDRB_POST_REG
:
74 case ARM::STR_PRE_IMM
:
75 case ARM::STR_PRE_REG
:
76 case ARM::STR_POST_IMM
:
77 case ARM::STR_POST_REG
:
82 case ARM::STRB_PRE_IMM
:
83 case ARM::STRB_PRE_REG
:
84 case ARM::STRB_POST_IMM
:
85 case ARM::STRB_POST_REG
:
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();
97 if (!Subtarget
.useMovt()) {
98 if (TM
.isPositionIndependent())
99 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_pcrel
, ARM::LDRi12
);
101 expandLoadStackGuardBase(MI
, ARM::LDRLIT_ga_abs
, ARM::LDRi12
);
105 if (!TM
.isPositionIndependent()) {
106 expandLoadStackGuardBase(MI
, ARM::MOVi32imm
, ARM::LDRi12
);
110 const GlobalValue
*GV
=
111 cast
<GlobalValue
>((*MI
->memoperands_begin())->getValue());
113 if (!Subtarget
.isGVIndirectSymbol(GV
)) {
114 expandLoadStackGuardBase(MI
, ARM::MOV_ga_pcrel
, ARM::LDRi12
);
118 MachineBasicBlock
&MBB
= *MI
->getParent();
119 DebugLoc DL
= MI
->getDebugLoc();
120 Register Reg
= MI
->getOperand(0).getReg();
121 MachineInstrBuilder MIB
;
123 MIB
= BuildMI(MBB
, MI
, DL
, get(ARM::MOV_ga_pcrel_ldr
), Reg
)
124 .addGlobalAddress(GV
, 0, ARMII::MO_NONLAZY
);
125 auto Flags
= MachineMemOperand::MOLoad
|
126 MachineMemOperand::MODereferenceable
|
127 MachineMemOperand::MOInvariant
;
128 MachineMemOperand
*MMO
= MBB
.getParent()->getMachineMemOperand(
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
)
135 .add(predOps(ARMCC::AL
));