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 (Register::isPhysicalRegister(SrcReg
) && isARMLowRegister(SrcReg
))) &&
86 if (RC
== &ARM::tGPRRegClass
||
87 (Register::isPhysicalRegister(SrcReg
) && isARMLowRegister(SrcReg
))) {
89 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
91 MachineFunction
&MF
= *MBB
.getParent();
92 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
93 MachineMemOperand
*MMO
= MF
.getMachineMemOperand(
94 MachinePointerInfo::getFixedStack(MF
, FI
), MachineMemOperand::MOStore
,
95 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
96 BuildMI(MBB
, I
, DL
, get(ARM::tSTRspi
))
97 .addReg(SrcReg
, getKillRegState(isKill
))
101 .add(predOps(ARMCC::AL
));
105 void Thumb1InstrInfo::
106 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
107 unsigned DestReg
, int FI
,
108 const TargetRegisterClass
*RC
,
109 const TargetRegisterInfo
*TRI
) const {
111 (RC
->hasSuperClassEq(&ARM::tGPRRegClass
) ||
112 (Register::isPhysicalRegister(DestReg
) && isARMLowRegister(DestReg
))) &&
113 "Unknown regclass!");
115 if (RC
->hasSuperClassEq(&ARM::tGPRRegClass
) ||
116 (Register::isPhysicalRegister(DestReg
) && isARMLowRegister(DestReg
))) {
118 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
120 MachineFunction
&MF
= *MBB
.getParent();
121 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
122 MachineMemOperand
*MMO
= MF
.getMachineMemOperand(
123 MachinePointerInfo::getFixedStack(MF
, FI
), MachineMemOperand::MOLoad
,
124 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
125 BuildMI(MBB
, I
, DL
, get(ARM::tLDRspi
), DestReg
)
129 .add(predOps(ARMCC::AL
));
133 void Thumb1InstrInfo::expandLoadStackGuard(
134 MachineBasicBlock::iterator MI
) const {
135 MachineFunction
&MF
= *MI
->getParent()->getParent();
136 const TargetMachine
&TM
= MF
.getTarget();
137 if (TM
.isPositionIndependent())
138 expandLoadStackGuardBase(MI
, ARM::tLDRLIT_ga_pcrel
, ARM::tLDRi
);
140 expandLoadStackGuardBase(MI
, ARM::tLDRLIT_ga_abs
, ARM::tLDRi
);
143 bool Thumb1InstrInfo::canCopyGluedNodeDuringSchedule(SDNode
*N
) const {
144 // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
145 // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
146 // even if they have glue.
147 // FIXME. Actually implement the cross-copy where it is possible (post v6)
148 // because these copies entail more spilling.
149 unsigned Opcode
= N
->getMachineOpcode();
150 if (Opcode
== ARM::tADCS
|| Opcode
== ARM::tSBCS
)