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