1 //===- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "ARMInstrInfo.h"
16 #include "ARMGenInstrInfo.inc"
17 #include "ARMMachineFunctionInfo.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "Thumb1InstrInfo.h"
25 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget
&STI
) : RI(*this, STI
) {
28 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc
) const {
33 Thumb1InstrInfo::BlockHasNoFallThrough(const MachineBasicBlock
&MBB
) const {
34 if (MBB
.empty()) return false;
36 switch (MBB
.back().getOpcode()) {
38 case ARM::tBX_RET_vararg
:
50 bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
51 MachineBasicBlock::iterator I
,
52 unsigned DestReg
, unsigned SrcReg
,
53 const TargetRegisterClass
*DestRC
,
54 const TargetRegisterClass
*SrcRC
) const {
55 DebugLoc DL
= DebugLoc::getUnknownLoc();
56 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
58 if (DestRC
== ARM::GPRRegisterClass
) {
59 if (SrcRC
== ARM::GPRRegisterClass
) {
60 BuildMI(MBB
, I
, DL
, get(ARM::tMOVgpr2gpr
), DestReg
).addReg(SrcReg
);
62 } else if (SrcRC
== ARM::tGPRRegisterClass
) {
63 BuildMI(MBB
, I
, DL
, get(ARM::tMOVtgpr2gpr
), DestReg
).addReg(SrcReg
);
66 } else if (DestRC
== ARM::tGPRRegisterClass
) {
67 if (SrcRC
== ARM::GPRRegisterClass
) {
68 BuildMI(MBB
, I
, DL
, get(ARM::tMOVgpr2tgpr
), DestReg
).addReg(SrcReg
);
70 } else if (SrcRC
== ARM::tGPRRegisterClass
) {
71 BuildMI(MBB
, I
, DL
, get(ARM::tMOVr
), DestReg
).addReg(SrcReg
);
79 bool Thumb1InstrInfo::
80 canFoldMemoryOperand(const MachineInstr
*MI
,
81 const SmallVectorImpl
<unsigned> &Ops
) const {
82 if (Ops
.size() != 1) return false;
84 unsigned OpNum
= Ops
[0];
85 unsigned Opc
= MI
->getOpcode();
89 case ARM::tMOVtgpr2gpr
:
90 case ARM::tMOVgpr2tgpr
:
91 case ARM::tMOVgpr2gpr
: {
92 if (OpNum
== 0) { // move -> store
93 unsigned SrcReg
= MI
->getOperand(1).getReg();
94 if (TargetRegisterInfo::isPhysicalRegister(SrcReg
) &&
95 !isARMLowRegister(SrcReg
))
96 // tSpill cannot take a high register operand.
98 } else { // move -> load
99 unsigned DstReg
= MI
->getOperand(0).getReg();
100 if (TargetRegisterInfo::isPhysicalRegister(DstReg
) &&
101 !isARMLowRegister(DstReg
))
102 // tRestore cannot target a high register operand.
112 void Thumb1InstrInfo::
113 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
114 unsigned SrcReg
, bool isKill
, int FI
,
115 const TargetRegisterClass
*RC
) const {
116 DebugLoc DL
= DebugLoc::getUnknownLoc();
117 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
119 assert((RC
== ARM::tGPRRegisterClass
||
120 (TargetRegisterInfo::isPhysicalRegister(SrcReg
) &&
121 isARMLowRegister(SrcReg
))) && "Unknown regclass!");
123 if (RC
== ARM::tGPRRegisterClass
) {
124 AddDefaultPred(BuildMI(MBB
, I
, DL
, get(ARM::tSpill
))
125 .addReg(SrcReg
, getKillRegState(isKill
))
126 .addFrameIndex(FI
).addImm(0));
130 void Thumb1InstrInfo::
131 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
132 unsigned DestReg
, int FI
,
133 const TargetRegisterClass
*RC
) const {
134 DebugLoc DL
= DebugLoc::getUnknownLoc();
135 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
137 assert((RC
== ARM::tGPRRegisterClass
||
138 (TargetRegisterInfo::isPhysicalRegister(DestReg
) &&
139 isARMLowRegister(DestReg
))) && "Unknown regclass!");
141 if (RC
== ARM::tGPRRegisterClass
) {
142 AddDefaultPred(BuildMI(MBB
, I
, DL
, get(ARM::tRestore
), DestReg
)
143 .addFrameIndex(FI
).addImm(0));
147 bool Thumb1InstrInfo::
148 spillCalleeSavedRegisters(MachineBasicBlock
&MBB
,
149 MachineBasicBlock::iterator MI
,
150 const std::vector
<CalleeSavedInfo
> &CSI
) const {
154 DebugLoc DL
= DebugLoc::getUnknownLoc();
155 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
157 MachineInstrBuilder MIB
= BuildMI(MBB
, MI
, DL
, get(ARM::tPUSH
));
159 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
160 unsigned Reg
= CSI
[i
-1].getReg();
161 // Add the callee-saved register as live-in. It's killed at the spill.
163 MIB
.addReg(Reg
, RegState::Kill
);
168 bool Thumb1InstrInfo::
169 restoreCalleeSavedRegisters(MachineBasicBlock
&MBB
,
170 MachineBasicBlock::iterator MI
,
171 const std::vector
<CalleeSavedInfo
> &CSI
) const {
172 MachineFunction
&MF
= *MBB
.getParent();
173 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
177 bool isVarArg
= AFI
->getVarArgsRegSaveSize() > 0;
178 DebugLoc DL
= MI
->getDebugLoc();
179 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, get(ARM::tPOP
));
183 for (unsigned i
= CSI
.size(); i
!= 0; --i
) {
184 unsigned Reg
= CSI
[i
-1].getReg();
185 if (Reg
== ARM::LR
) {
186 // Special epilogue for vararg functions. See emitEpilogue
190 (*MIB
).setDesc(get(ARM::tPOP_RET
));
193 MIB
.addReg(Reg
, getDefRegState(true));
197 // It's illegal to emit pop instruction without operands.
199 MBB
.insert(MI
, &*MIB
);
204 MachineInstr
*Thumb1InstrInfo::
205 foldMemoryOperandImpl(MachineFunction
&MF
, MachineInstr
*MI
,
206 const SmallVectorImpl
<unsigned> &Ops
, int FI
) const {
207 if (Ops
.size() != 1) return NULL
;
209 unsigned OpNum
= Ops
[0];
210 unsigned Opc
= MI
->getOpcode();
211 MachineInstr
*NewMI
= NULL
;
215 case ARM::tMOVtgpr2gpr
:
216 case ARM::tMOVgpr2tgpr
:
217 case ARM::tMOVgpr2gpr
: {
218 if (OpNum
== 0) { // move -> store
219 unsigned SrcReg
= MI
->getOperand(1).getReg();
220 bool isKill
= MI
->getOperand(1).isKill();
221 if (TargetRegisterInfo::isPhysicalRegister(SrcReg
) &&
222 !isARMLowRegister(SrcReg
))
223 // tSpill cannot take a high register operand.
225 NewMI
= AddDefaultPred(BuildMI(MF
, MI
->getDebugLoc(), get(ARM::tSpill
))
226 .addReg(SrcReg
, getKillRegState(isKill
))
227 .addFrameIndex(FI
).addImm(0));
228 } else { // move -> load
229 unsigned DstReg
= MI
->getOperand(0).getReg();
230 if (TargetRegisterInfo::isPhysicalRegister(DstReg
) &&
231 !isARMLowRegister(DstReg
))
232 // tRestore cannot target a high register operand.
234 bool isDead
= MI
->getOperand(0).isDead();
235 NewMI
= AddDefaultPred(BuildMI(MF
, MI
->getDebugLoc(), get(ARM::tRestore
))
237 RegState::Define
| getDeadRegState(isDead
))
238 .addFrameIndex(FI
).addImm(0));