Line data Source code
1 : //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file contains the ARM implementation of the TargetInstrInfo class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "ARMInstrInfo.h"
15 : #include "ARM.h"
16 : #include "ARMConstantPoolValue.h"
17 : #include "ARMMachineFunctionInfo.h"
18 : #include "ARMTargetMachine.h"
19 : #include "MCTargetDesc/ARMAddressingModes.h"
20 : #include "llvm/ADT/STLExtras.h"
21 : #include "llvm/CodeGen/LiveVariables.h"
22 : #include "llvm/CodeGen/MachineFrameInfo.h"
23 : #include "llvm/CodeGen/MachineInstrBuilder.h"
24 : #include "llvm/CodeGen/MachineJumpTableInfo.h"
25 : #include "llvm/CodeGen/MachineRegisterInfo.h"
26 : #include "llvm/IR/Function.h"
27 : #include "llvm/IR/GlobalVariable.h"
28 : #include "llvm/MC/MCAsmInfo.h"
29 : #include "llvm/MC/MCInst.h"
30 : using namespace llvm;
31 :
32 2987 : ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
33 2987 : : ARMBaseInstrInfo(STI), RI() {}
34 :
35 : /// Return the noop instruction to use for a noop.
36 16 : void ARMInstrInfo::getNoop(MCInst &NopInst) const {
37 16 : if (hasNOP()) {
38 : NopInst.setOpcode(ARM::HINT);
39 12 : NopInst.addOperand(MCOperand::createImm(0));
40 12 : NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
41 12 : NopInst.addOperand(MCOperand::createReg(0));
42 : } else {
43 : NopInst.setOpcode(ARM::MOVr);
44 4 : NopInst.addOperand(MCOperand::createReg(ARM::R0));
45 4 : NopInst.addOperand(MCOperand::createReg(ARM::R0));
46 4 : NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
47 4 : NopInst.addOperand(MCOperand::createReg(0));
48 4 : NopInst.addOperand(MCOperand::createReg(0));
49 : }
50 16 : }
51 :
52 0 : unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
53 0 : 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 0 : case ARM::LDRH_PRE:
62 : case ARM::LDRH_POST:
63 0 : return ARM::LDRH;
64 0 : case ARM::LDRB_PRE_IMM:
65 : case ARM::LDRB_PRE_REG:
66 : case ARM::LDRB_POST_IMM:
67 : case ARM::LDRB_POST_REG:
68 0 : return ARM::LDRBi12;
69 0 : case ARM::LDRSH_PRE:
70 : case ARM::LDRSH_POST:
71 0 : return ARM::LDRSH;
72 0 : case ARM::LDRSB_PRE:
73 : case ARM::LDRSB_POST:
74 0 : return ARM::LDRSB;
75 0 : case ARM::STR_PRE_IMM:
76 : case ARM::STR_PRE_REG:
77 : case ARM::STR_POST_IMM:
78 : case ARM::STR_POST_REG:
79 0 : return ARM::STRi12;
80 0 : case ARM::STRH_PRE:
81 : case ARM::STRH_POST:
82 0 : return ARM::STRH;
83 0 : case ARM::STRB_PRE_IMM:
84 : case ARM::STRB_PRE_REG:
85 : case ARM::STRB_POST_IMM:
86 : case ARM::STRB_POST_REG:
87 0 : return ARM::STRBi12;
88 : }
89 :
90 0 : return 0;
91 : }
92 :
93 20 : void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
94 20 : MachineFunction &MF = *MI->getParent()->getParent();
95 20 : const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
96 20 : const TargetMachine &TM = MF.getTarget();
97 :
98 20 : if (!Subtarget.useMovt(MF)) {
99 6 : if (TM.isPositionIndependent())
100 2 : expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
101 : else
102 4 : expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
103 10 : return;
104 : }
105 :
106 14 : if (!TM.isPositionIndependent()) {
107 4 : expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
108 4 : return;
109 : }
110 :
111 : const GlobalValue *GV =
112 10 : cast<GlobalValue>((*MI->memoperands_begin())->getValue());
113 :
114 10 : if (!Subtarget.isGVIndirectSymbol(GV)) {
115 0 : expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
116 0 : return;
117 : }
118 :
119 10 : MachineBasicBlock &MBB = *MI->getParent();
120 : DebugLoc DL = MI->getDebugLoc();
121 10 : unsigned Reg = MI->getOperand(0).getReg();
122 : MachineInstrBuilder MIB;
123 :
124 20 : MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
125 : .addGlobalAddress(GV, 0, ARMII::MO_NONLAZY);
126 : auto Flags = MachineMemOperand::MOLoad |
127 : MachineMemOperand::MODereferenceable |
128 : MachineMemOperand::MOInvariant;
129 20 : MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand(
130 : MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, 4);
131 : MIB.addMemOperand(MMO);
132 20 : BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
133 10 : .addReg(Reg, RegState::Kill)
134 : .addImm(0)
135 : .cloneMemRefs(*MI)
136 10 : .add(predOps(ARMCC::AL));
137 : }
|