1 //===- Thumb2InstrInfo.cpp - Thumb-2 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-2 implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "ARMInstrInfo.h"
16 #include "ARMAddressingModes.h"
17 #include "ARMGenInstrInfo.inc"
18 #include "ARMMachineFunctionInfo.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "Thumb2InstrInfo.h"
26 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget
&STI
) : RI(*this, STI
) {
29 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc
) const {
35 Thumb2InstrInfo::BlockHasNoFallThrough(const MachineBasicBlock
&MBB
) const {
36 if (MBB
.empty()) return false;
38 switch (MBB
.back().getOpcode()) {
40 case ARM::t2B
: // Uncond branch.
41 case ARM::t2BR_JT
: // Jumptable branch.
42 case ARM::t2TBB
: // Table branch byte.
43 case ARM::t2TBH
: // Table branch halfword.
44 case ARM::tBR_JTr
: // Jumptable branch (16-bit version).
46 case ARM::tBX_RET_vararg
:
58 Thumb2InstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
59 MachineBasicBlock::iterator I
,
60 unsigned DestReg
, unsigned SrcReg
,
61 const TargetRegisterClass
*DestRC
,
62 const TargetRegisterClass
*SrcRC
) const {
63 DebugLoc DL
= DebugLoc::getUnknownLoc();
64 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
66 if (DestRC
== ARM::GPRRegisterClass
&&
67 SrcRC
== ARM::GPRRegisterClass
) {
68 BuildMI(MBB
, I
, DL
, get(ARM::tMOVgpr2gpr
), DestReg
).addReg(SrcReg
);
70 } else if (DestRC
== ARM::GPRRegisterClass
&&
71 SrcRC
== ARM::tGPRRegisterClass
) {
72 BuildMI(MBB
, I
, DL
, get(ARM::tMOVtgpr2gpr
), DestReg
).addReg(SrcReg
);
74 } else if (DestRC
== ARM::tGPRRegisterClass
&&
75 SrcRC
== ARM::GPRRegisterClass
) {
76 BuildMI(MBB
, I
, DL
, get(ARM::tMOVgpr2tgpr
), DestReg
).addReg(SrcReg
);
80 // Handle SPR, DPR, and QPR copies.
81 return ARMBaseInstrInfo::copyRegToReg(MBB
, I
, DestReg
, SrcReg
, DestRC
, SrcRC
);
84 void Thumb2InstrInfo::
85 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
86 unsigned SrcReg
, bool isKill
, int FI
,
87 const TargetRegisterClass
*RC
) const {
88 DebugLoc DL
= DebugLoc::getUnknownLoc();
89 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
91 if (RC
== ARM::GPRRegisterClass
) {
92 AddDefaultPred(BuildMI(MBB
, I
, DL
, get(ARM::t2STRi12
))
93 .addReg(SrcReg
, getKillRegState(isKill
))
94 .addFrameIndex(FI
).addImm(0));
98 ARMBaseInstrInfo::storeRegToStackSlot(MBB
, I
, SrcReg
, isKill
, FI
, RC
);
101 void Thumb2InstrInfo::
102 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
103 unsigned DestReg
, int FI
,
104 const TargetRegisterClass
*RC
) const {
105 DebugLoc DL
= DebugLoc::getUnknownLoc();
106 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
108 if (RC
== ARM::GPRRegisterClass
) {
109 AddDefaultPred(BuildMI(MBB
, I
, DL
, get(ARM::t2LDRi12
), DestReg
)
110 .addFrameIndex(FI
).addImm(0));
114 ARMBaseInstrInfo::loadRegFromStackSlot(MBB
, I
, DestReg
, FI
, RC
);
118 void llvm::emitT2RegPlusImmediate(MachineBasicBlock
&MBB
,
119 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
120 unsigned DestReg
, unsigned BaseReg
, int NumBytes
,
121 ARMCC::CondCodes Pred
, unsigned PredReg
,
122 const ARMBaseInstrInfo
&TII
) {
123 bool isSub
= NumBytes
< 0;
124 if (isSub
) NumBytes
= -NumBytes
;
126 // If profitable, use a movw or movt to materialize the offset.
127 // FIXME: Use the scavenger to grab a scratch register.
128 if (DestReg
!= ARM::SP
&& DestReg
!= BaseReg
&&
130 ARM_AM::getT2SOImmVal(NumBytes
) == -1) {
132 if (NumBytes
< 65536) {
133 // Use a movw to materialize the 16-bit constant.
134 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::t2MOVi16
), DestReg
)
136 .addImm((unsigned)Pred
).addReg(PredReg
).addReg(0);
138 } else if ((NumBytes
& 0xffff) == 0) {
139 // Use a movt to materialize the 32-bit constant.
140 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::t2MOVTi16
), DestReg
)
142 .addImm(NumBytes
>> 16)
143 .addImm((unsigned)Pred
).addReg(PredReg
).addReg(0);
149 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::t2SUBrr
), DestReg
)
150 .addReg(BaseReg
, RegState::Kill
)
151 .addReg(DestReg
, RegState::Kill
)
152 .addImm((unsigned)Pred
).addReg(PredReg
).addReg(0);
154 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::t2ADDrr
), DestReg
)
155 .addReg(DestReg
, RegState::Kill
)
156 .addReg(BaseReg
, RegState::Kill
)
157 .addImm((unsigned)Pred
).addReg(PredReg
).addReg(0);
164 unsigned ThisVal
= NumBytes
;
166 if (DestReg
== ARM::SP
&& BaseReg
!= ARM::SP
) {
167 // mov sp, rn. Note t2MOVr cannot be used.
168 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVgpr2gpr
),DestReg
).addReg(BaseReg
);
173 if (BaseReg
== ARM::SP
) {
175 if (DestReg
== ARM::SP
&& (ThisVal
< ((1 << 7)-1) * 4)) {
176 assert((ThisVal
& 3) == 0 && "Stack update is not multiple of 4?");
177 Opc
= isSub
? ARM::tSUBspi
: ARM::tADDspi
;
178 // FIXME: Fix Thumb1 immediate encoding.
179 BuildMI(MBB
, MBBI
, dl
, TII
.get(Opc
), DestReg
)
180 .addReg(BaseReg
).addImm(ThisVal
/4);
185 // sub rd, sp, so_imm
186 Opc
= isSub
? ARM::t2SUBrSPi
: ARM::t2ADDrSPi
;
187 if (ARM_AM::getT2SOImmVal(NumBytes
) != -1) {
190 // FIXME: Move this to ARMAddressingModes.h?
191 unsigned RotAmt
= CountLeadingZeros_32(ThisVal
);
192 ThisVal
= ThisVal
& ARM_AM::rotr32(0xff000000U
, RotAmt
);
193 NumBytes
&= ~ThisVal
;
194 assert(ARM_AM::getT2SOImmVal(ThisVal
) != -1 &&
195 "Bit extraction didn't work?");
198 assert(DestReg
!= ARM::SP
&& BaseReg
!= ARM::SP
);
199 Opc
= isSub
? ARM::t2SUBri
: ARM::t2ADDri
;
200 if (ARM_AM::getT2SOImmVal(NumBytes
) != -1) {
202 } else if (ThisVal
< 4096) {
203 Opc
= isSub
? ARM::t2SUBri12
: ARM::t2ADDri12
;
206 // FIXME: Move this to ARMAddressingModes.h?
207 unsigned RotAmt
= CountLeadingZeros_32(ThisVal
);
208 ThisVal
= ThisVal
& ARM_AM::rotr32(0xff000000U
, RotAmt
);
209 NumBytes
&= ~ThisVal
;
210 assert(ARM_AM::getT2SOImmVal(ThisVal
) != -1 &&
211 "Bit extraction didn't work?");
215 // Build the new ADD / SUB.
216 AddDefaultCC(AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(Opc
), DestReg
)
217 .addReg(BaseReg
, RegState::Kill
)
225 negativeOffsetOpcode(unsigned opcode
)
228 case ARM::t2LDRi12
: return ARM::t2LDRi8
;
229 case ARM::t2LDRHi12
: return ARM::t2LDRHi8
;
230 case ARM::t2LDRBi12
: return ARM::t2LDRBi8
;
231 case ARM::t2LDRSHi12
: return ARM::t2LDRSHi8
;
232 case ARM::t2LDRSBi12
: return ARM::t2LDRSBi8
;
233 case ARM::t2STRi12
: return ARM::t2STRi8
;
234 case ARM::t2STRBi12
: return ARM::t2STRBi8
;
235 case ARM::t2STRHi12
: return ARM::t2STRHi8
;
255 positiveOffsetOpcode(unsigned opcode
)
258 case ARM::t2LDRi8
: return ARM::t2LDRi12
;
259 case ARM::t2LDRHi8
: return ARM::t2LDRHi12
;
260 case ARM::t2LDRBi8
: return ARM::t2LDRBi12
;
261 case ARM::t2LDRSHi8
: return ARM::t2LDRSHi12
;
262 case ARM::t2LDRSBi8
: return ARM::t2LDRSBi12
;
263 case ARM::t2STRi8
: return ARM::t2STRi12
;
264 case ARM::t2STRBi8
: return ARM::t2STRBi12
;
265 case ARM::t2STRHi8
: return ARM::t2STRHi12
;
270 case ARM::t2LDRSHi12
:
271 case ARM::t2LDRSBi12
:
285 immediateOffsetOpcode(unsigned opcode
)
288 case ARM::t2LDRs
: return ARM::t2LDRi12
;
289 case ARM::t2LDRHs
: return ARM::t2LDRHi12
;
290 case ARM::t2LDRBs
: return ARM::t2LDRBi12
;
291 case ARM::t2LDRSHs
: return ARM::t2LDRSHi12
;
292 case ARM::t2LDRSBs
: return ARM::t2LDRSBi12
;
293 case ARM::t2STRs
: return ARM::t2STRi12
;
294 case ARM::t2STRBs
: return ARM::t2STRBi12
;
295 case ARM::t2STRHs
: return ARM::t2STRHi12
;
300 case ARM::t2LDRSHi12
:
301 case ARM::t2LDRSBi12
:
322 bool llvm::rewriteT2FrameIndex(MachineInstr
&MI
, unsigned FrameRegIdx
,
323 unsigned FrameReg
, int &Offset
,
324 const ARMBaseInstrInfo
&TII
) {
325 unsigned Opcode
= MI
.getOpcode();
326 const TargetInstrDesc
&Desc
= MI
.getDesc();
327 unsigned AddrMode
= (Desc
.TSFlags
& ARMII::AddrModeMask
);
330 // Memory operands in inline assembly always use AddrModeT2_i12.
331 if (Opcode
== ARM::INLINEASM
)
332 AddrMode
= ARMII::AddrModeT2_i12
; // FIXME. mode for thumb2?
334 if (Opcode
== ARM::t2ADDri
|| Opcode
== ARM::t2ADDri12
) {
335 Offset
+= MI
.getOperand(FrameRegIdx
+1).getImm();
337 bool isSP
= FrameReg
== ARM::SP
;
339 // Turn it into a move.
340 MI
.setDesc(TII
.get(ARM::tMOVgpr2gpr
));
341 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
342 MI
.RemoveOperand(FrameRegIdx
+1);
350 MI
.setDesc(TII
.get(isSP
? ARM::t2SUBrSPi
: ARM::t2SUBri
));
352 MI
.setDesc(TII
.get(isSP
? ARM::t2ADDrSPi
: ARM::t2ADDri
));
355 // Common case: small offset, fits into instruction.
356 if (ARM_AM::getT2SOImmVal(Offset
) != -1) {
357 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
358 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(Offset
);
362 // Another common case: imm12.
364 unsigned NewOpc
= isSP
365 ? (isSub
? ARM::t2SUBrSPi12
: ARM::t2ADDrSPi12
)
366 : (isSub
? ARM::t2SUBri12
: ARM::t2ADDri12
);
367 MI
.setDesc(TII
.get(NewOpc
));
368 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
369 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(Offset
);
374 // Otherwise, extract 8 adjacent bits from the immediate into this
376 unsigned RotAmt
= CountLeadingZeros_32(Offset
);
377 unsigned ThisImmVal
= Offset
& ARM_AM::rotr32(0xff000000U
, RotAmt
);
379 // We will handle these bits from offset, clear them.
380 Offset
&= ~ThisImmVal
;
382 assert(ARM_AM::getT2SOImmVal(ThisImmVal
) != -1 &&
383 "Bit extraction didn't work?");
384 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(ThisImmVal
);
387 // AddrMode4 cannot handle any offset.
388 if (AddrMode
== ARMII::AddrMode4
)
391 // AddrModeT2_so cannot handle any offset. If there is no offset
392 // register then we change to an immediate version.
393 unsigned NewOpc
= Opcode
;
394 if (AddrMode
== ARMII::AddrModeT2_so
) {
395 unsigned OffsetReg
= MI
.getOperand(FrameRegIdx
+1).getReg();
396 if (OffsetReg
!= 0) {
397 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
401 MI
.RemoveOperand(FrameRegIdx
+1);
402 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(0);
403 NewOpc
= immediateOffsetOpcode(Opcode
);
404 AddrMode
= ARMII::AddrModeT2_i12
;
407 unsigned NumBits
= 0;
409 if (AddrMode
== ARMII::AddrModeT2_i8
|| AddrMode
== ARMII::AddrModeT2_i12
) {
410 // i8 supports only negative, and i12 supports only positive, so
411 // based on Offset sign convert Opcode to the appropriate
413 Offset
+= MI
.getOperand(FrameRegIdx
+1).getImm();
415 NewOpc
= negativeOffsetOpcode(Opcode
);
420 NewOpc
= positiveOffsetOpcode(Opcode
);
424 // VFP and NEON address modes.
426 if (AddrMode
== ARMII::AddrMode5
) {
427 const MachineOperand
&OffOp
= MI
.getOperand(FrameRegIdx
+1);
428 InstrOffs
= ARM_AM::getAM5Offset(OffOp
.getImm());
429 if (ARM_AM::getAM5Op(OffOp
.getImm()) == ARM_AM::sub
)
434 Offset
+= InstrOffs
* 4;
435 assert((Offset
& (Scale
-1)) == 0 && "Can't encode this offset!");
442 if (NewOpc
!= Opcode
)
443 MI
.setDesc(TII
.get(NewOpc
));
445 MachineOperand
&ImmOp
= MI
.getOperand(FrameRegIdx
+1);
447 // Attempt to fold address computation
448 // Common case: small offset, fits into instruction.
449 int ImmedOffset
= Offset
/ Scale
;
450 unsigned Mask
= (1 << NumBits
) - 1;
451 if ((unsigned)Offset
<= Mask
* Scale
) {
452 // Replace the FrameIndex with fp/sp
453 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
455 if (AddrMode
== ARMII::AddrMode5
)
456 // FIXME: Not consistent.
457 ImmedOffset
|= 1 << NumBits
;
459 ImmedOffset
= -ImmedOffset
;
461 ImmOp
.ChangeToImmediate(ImmedOffset
);
466 // Otherwise, offset doesn't fit. Pull in what we can to simplify
467 ImmedOffset
= ImmedOffset
& Mask
;
469 if (AddrMode
== ARMII::AddrMode5
)
470 // FIXME: Not consistent.
471 ImmedOffset
|= 1 << NumBits
;
473 ImmedOffset
= -ImmedOffset
;
474 if (ImmedOffset
== 0)
475 // Change the opcode back if the encoded offset is zero.
476 MI
.setDesc(TII
.get(positiveOffsetOpcode(NewOpc
)));
479 ImmOp
.ChangeToImmediate(ImmedOffset
);
480 Offset
&= ~(Mask
*Scale
);
483 Offset
= (isSub
) ? -Offset
: Offset
;