1 //===-- Thumb1InstrInfo.cpp - Thumb-1 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 Thumb-1 implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "Thumb1InstrInfo.h"
14 #include "ARMSubtarget.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/MachineMemOperand.h"
18 #include "llvm/MC/MCInst.h"
22 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget
&STI
)
23 : ARMBaseInstrInfo(STI
), RI() {}
25 /// Return the noop instruction to use for a noop.
26 void Thumb1InstrInfo::getNoop(MCInst
&NopInst
) const {
27 NopInst
.setOpcode(ARM::tMOVr
);
28 NopInst
.addOperand(MCOperand::createReg(ARM::R8
));
29 NopInst
.addOperand(MCOperand::createReg(ARM::R8
));
30 NopInst
.addOperand(MCOperand::createImm(ARMCC::AL
));
31 NopInst
.addOperand(MCOperand::createReg(0));
34 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc
) const {
38 void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
39 MachineBasicBlock::iterator I
,
40 const DebugLoc
&DL
, unsigned DestReg
,
41 unsigned SrcReg
, bool KillSrc
) const {
42 // Need to check the arch.
43 MachineFunction
&MF
= *MBB
.getParent();
44 const ARMSubtarget
&st
= MF
.getSubtarget
<ARMSubtarget
>();
46 assert(ARM::GPRRegClass
.contains(DestReg
, SrcReg
) &&
47 "Thumb1 can only copy GPR registers");
49 if (st
.hasV6Ops() || ARM::hGPRRegClass
.contains(SrcReg
)
50 || !ARM::tGPRRegClass
.contains(DestReg
))
51 BuildMI(MBB
, I
, DL
, get(ARM::tMOVr
), DestReg
)
52 .addReg(SrcReg
, getKillRegState(KillSrc
))
53 .add(predOps(ARMCC::AL
));
55 // FIXME: Can also use 'mov hi, $src; mov $dst, hi',
56 // with hi as either r10 or r11.
58 const TargetRegisterInfo
*RegInfo
= st
.getRegisterInfo();
59 if (MBB
.computeRegisterLiveness(RegInfo
, ARM::CPSR
, I
)
60 == MachineBasicBlock::LQR_Dead
) {
61 BuildMI(MBB
, I
, DL
, get(ARM::tMOVSr
), DestReg
)
62 .addReg(SrcReg
, getKillRegState(KillSrc
))
63 ->addRegisterDead(ARM::CPSR
, RegInfo
);
67 // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it
68 BuildMI(MBB
, I
, DL
, get(ARM::tPUSH
))
69 .add(predOps(ARMCC::AL
))
70 .addReg(SrcReg
, getKillRegState(KillSrc
));
71 BuildMI(MBB
, I
, DL
, get(ARM::tPOP
))
72 .add(predOps(ARMCC::AL
))
73 .addReg(DestReg
, getDefRegState(true));
77 void Thumb1InstrInfo::
78 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
79 unsigned SrcReg
, bool isKill
, int FI
,
80 const TargetRegisterClass
*RC
,
81 const TargetRegisterInfo
*TRI
) const {
82 assert((RC
== &ARM::tGPRRegClass
||
83 (TargetRegisterInfo::isPhysicalRegister(SrcReg
) &&
84 isARMLowRegister(SrcReg
))) && "Unknown regclass!");
86 if (RC
== &ARM::tGPRRegClass
||
87 (TargetRegisterInfo::isPhysicalRegister(SrcReg
) &&
88 isARMLowRegister(SrcReg
))) {
90 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
92 MachineFunction
&MF
= *MBB
.getParent();
93 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
94 MachineMemOperand
*MMO
= MF
.getMachineMemOperand(
95 MachinePointerInfo::getFixedStack(MF
, FI
), MachineMemOperand::MOStore
,
96 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
97 BuildMI(MBB
, I
, DL
, get(ARM::tSTRspi
))
98 .addReg(SrcReg
, getKillRegState(isKill
))
102 .add(predOps(ARMCC::AL
));
106 void Thumb1InstrInfo::
107 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
108 unsigned DestReg
, int FI
,
109 const TargetRegisterClass
*RC
,
110 const TargetRegisterInfo
*TRI
) const {
111 assert((RC
->hasSuperClassEq(&ARM::tGPRRegClass
) ||
112 (TargetRegisterInfo::isPhysicalRegister(DestReg
) &&
113 isARMLowRegister(DestReg
))) && "Unknown regclass!");
115 if (RC
->hasSuperClassEq(&ARM::tGPRRegClass
) ||
116 (TargetRegisterInfo::isPhysicalRegister(DestReg
) &&
117 isARMLowRegister(DestReg
))) {
119 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
121 MachineFunction
&MF
= *MBB
.getParent();
122 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
123 MachineMemOperand
*MMO
= MF
.getMachineMemOperand(
124 MachinePointerInfo::getFixedStack(MF
, FI
), MachineMemOperand::MOLoad
,
125 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
126 BuildMI(MBB
, I
, DL
, get(ARM::tLDRspi
), DestReg
)
130 .add(predOps(ARMCC::AL
));
134 void Thumb1InstrInfo::expandLoadStackGuard(
135 MachineBasicBlock::iterator MI
) const {
136 MachineFunction
&MF
= *MI
->getParent()->getParent();
137 const TargetMachine
&TM
= MF
.getTarget();
138 if (TM
.isPositionIndependent())
139 expandLoadStackGuardBase(MI
, ARM::tLDRLIT_ga_pcrel
, ARM::tLDRi
);
141 expandLoadStackGuardBase(MI
, ARM::tLDRLIT_ga_abs
, ARM::tLDRi
);
144 bool Thumb1InstrInfo::canCopyGluedNodeDuringSchedule(SDNode
*N
) const {
145 // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
146 // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
147 // even if they have glue.
148 // FIXME. Actually implement the cross-copy where it is possible (post v6)
149 // because these copies entail more spilling.
150 unsigned Opcode
= N
->getMachineOpcode();
151 if (Opcode
== ARM::tADCS
|| Opcode
== ARM::tSBCS
)