blob: af630ac797c52bba9bcff12997db133f7bfc4725 [file] [log] [blame]
Jim Grosbach31c24bf2009-11-07 22:00:39 +00001//===- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information ----*- C++ -*-===//
Anton Korobeynikovd49ea772009-06-26 21:28:53 +00002//
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//
David Goodwinb50ea5c2009-07-02 22:18:33 +000010// This file contains the Thumb-1 implementation of the TargetInstrInfo class.
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000011//
12//===----------------------------------------------------------------------===//
13
Evan Chengb9803a82009-11-06 23:52:48 +000014#include "Thumb1InstrInfo.h"
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000015#include "ARM.h"
16#include "ARMGenInstrInfo.inc"
17#include "ARMMachineFunctionInfo.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
Evan Cheng2457f2c2010-05-22 01:47:14 +000020#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Chenge3ce8aa2009-11-01 22:04:35 +000021#include "llvm/CodeGen/MachineMemOperand.h"
22#include "llvm/CodeGen/PseudoSourceValue.h"
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000023#include "llvm/ADT/SmallVector.h"
David Goodwinb50ea5c2009-07-02 22:18:33 +000024#include "Thumb1InstrInfo.h"
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000025
26using namespace llvm;
27
Anton Korobeynikovf95215f2009-11-02 00:10:38 +000028Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
29 : ARMBaseInstrInfo(STI), RI(*this, STI) {
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000030}
31
Evan Cheng446c4282009-07-11 06:43:01 +000032unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
David Goodwin334c2642009-07-08 16:09:28 +000033 return 0;
34}
35
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +000036void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
37 MachineBasicBlock::iterator I, DebugLoc DL,
38 unsigned DestReg, unsigned SrcReg,
39 bool KillSrc) const {
40 bool tDest = ARM::tGPRRegClass.contains(DestReg);
41 bool tSrc = ARM::tGPRRegClass.contains(SrcReg);
42 unsigned Opc = ARM::tMOVgpr2gpr;
43 if (tDest && tSrc)
44 Opc = ARM::tMOVr;
45 else if (tSrc)
46 Opc = ARM::tMOVtgpr2gpr;
47 else if (tDest)
48 Opc = ARM::tMOVgpr2tgpr;
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000049
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +000050 BuildMI(MBB, I, DL, get(Opc), DestReg)
51 .addReg(SrcReg, getKillRegState(KillSrc));
52 assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
53 "Thumb1 can only copy GPR registers");
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000054}
55
David Goodwinb50ea5c2009-07-02 22:18:33 +000056void Thumb1InstrInfo::
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000057storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
58 unsigned SrcReg, bool isKill, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +000059 const TargetRegisterClass *RC,
60 const TargetRegisterInfo *TRI) const {
Evan Cheng86e5f7b2009-08-13 05:40:51 +000061 assert((RC == ARM::tGPRRegisterClass ||
62 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
63 isARMLowRegister(SrcReg))) && "Unknown regclass!");
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000064
Jim Grosbach98793b92010-01-15 22:21:03 +000065 if (RC == ARM::tGPRRegisterClass ||
66 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
67 isARMLowRegister(SrcReg))) {
Evan Cheng746ad692010-05-06 19:06:44 +000068 DebugLoc DL;
69 if (I != MBB.end()) DL = I->getDebugLoc();
70
Evan Chenge3ce8aa2009-11-01 22:04:35 +000071 MachineFunction &MF = *MBB.getParent();
72 MachineFrameInfo &MFI = *MF.getFrameInfo();
73 MachineMemOperand *MMO =
74 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
75 MachineMemOperand::MOStore, 0,
76 MFI.getObjectSize(FI),
77 MFI.getObjectAlignment(FI));
Evan Cheng446c4282009-07-11 06:43:01 +000078 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSpill))
79 .addReg(SrcReg, getKillRegState(isKill))
Evan Chenge3ce8aa2009-11-01 22:04:35 +000080 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000081 }
82}
83
David Goodwinb50ea5c2009-07-02 22:18:33 +000084void Thumb1InstrInfo::
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000085loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
86 unsigned DestReg, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +000087 const TargetRegisterClass *RC,
88 const TargetRegisterInfo *TRI) const {
Evan Cheng86e5f7b2009-08-13 05:40:51 +000089 assert((RC == ARM::tGPRRegisterClass ||
90 (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
91 isARMLowRegister(DestReg))) && "Unknown regclass!");
Anton Korobeynikovd49ea772009-06-26 21:28:53 +000092
Jim Grosbach98793b92010-01-15 22:21:03 +000093 if (RC == ARM::tGPRRegisterClass ||
94 (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
95 isARMLowRegister(DestReg))) {
Evan Cheng746ad692010-05-06 19:06:44 +000096 DebugLoc DL;
97 if (I != MBB.end()) DL = I->getDebugLoc();
98
Evan Chenge3ce8aa2009-11-01 22:04:35 +000099 MachineFunction &MF = *MBB.getParent();
100 MachineFrameInfo &MFI = *MF.getFrameInfo();
101 MachineMemOperand *MMO =
102 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI),
103 MachineMemOperand::MOLoad, 0,
104 MFI.getObjectSize(FI),
105 MFI.getObjectAlignment(FI));
Evan Cheng446c4282009-07-11 06:43:01 +0000106 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
Evan Chenge3ce8aa2009-11-01 22:04:35 +0000107 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000108 }
109}
110
David Goodwinb50ea5c2009-07-02 22:18:33 +0000111bool Thumb1InstrInfo::
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000112spillCalleeSavedRegisters(MachineBasicBlock &MBB,
113 MachineBasicBlock::iterator MI,
Evan Cheng2457f2c2010-05-22 01:47:14 +0000114 const std::vector<CalleeSavedInfo> &CSI,
115 const TargetRegisterInfo *TRI) const {
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000116 if (CSI.empty())
117 return false;
118
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000119 DebugLoc DL;
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000120 if (MI != MBB.end()) DL = MI->getDebugLoc();
121
122 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
Evan Cheng4b322e52009-08-11 21:11:32 +0000123 AddDefaultPred(MIB);
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000124 for (unsigned i = CSI.size(); i != 0; --i) {
125 unsigned Reg = CSI[i-1].getReg();
Evan Cheng2457f2c2010-05-22 01:47:14 +0000126 bool isKill = true;
127
128 // Add the callee-saved register as live-in unless it's LR and
129 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
130 // then it's already added to the function and entry block live-in sets.
131 if (Reg == ARM::LR) {
132 MachineFunction &MF = *MBB.getParent();
133 if (MF.getFrameInfo()->isReturnAddressTaken() &&
134 MF.getRegInfo().isLiveIn(Reg))
135 isKill = false;
136 }
137
Bob Wilsona3a20462010-06-22 22:04:24 +0000138 if (isKill)
Evan Cheng2457f2c2010-05-22 01:47:14 +0000139 MBB.addLiveIn(Reg);
Bob Wilsona3a20462010-06-22 22:04:24 +0000140
141 MIB.addReg(Reg, getKillRegState(isKill));
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000142 }
143 return true;
144}
145
David Goodwinb50ea5c2009-07-02 22:18:33 +0000146bool Thumb1InstrInfo::
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000147restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
148 MachineBasicBlock::iterator MI,
Evan Cheng2457f2c2010-05-22 01:47:14 +0000149 const std::vector<CalleeSavedInfo> &CSI,
150 const TargetRegisterInfo *TRI) const {
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000151 MachineFunction &MF = *MBB.getParent();
152 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
153 if (CSI.empty())
154 return false;
155
156 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
Evan Cheng4b322e52009-08-11 21:11:32 +0000157 DebugLoc DL = MI->getDebugLoc();
158 MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::tPOP));
159 AddDefaultPred(MIB);
160
John McCall6eeccd42009-12-16 20:31:50 +0000161 bool NumRegs = false;
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000162 for (unsigned i = CSI.size(); i != 0; --i) {
163 unsigned Reg = CSI[i-1].getReg();
164 if (Reg == ARM::LR) {
165 // Special epilogue for vararg functions. See emitEpilogue
166 if (isVarArg)
167 continue;
168 Reg = ARM::PC;
Evan Cheng4b322e52009-08-11 21:11:32 +0000169 (*MIB).setDesc(get(ARM::tPOP_RET));
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000170 MI = MBB.erase(MI);
171 }
Evan Cheng4b322e52009-08-11 21:11:32 +0000172 MIB.addReg(Reg, getDefRegState(true));
John McCall6eeccd42009-12-16 20:31:50 +0000173 NumRegs = true;
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000174 }
175
176 // It's illegal to emit pop instruction without operands.
Evan Cheng4b322e52009-08-11 21:11:32 +0000177 if (NumRegs)
178 MBB.insert(MI, &*MIB);
Jeffrey Yasskinfa723402010-03-22 16:13:21 +0000179 else
180 MF.DeleteMachineInstr(MIB);
Anton Korobeynikovd49ea772009-06-26 21:28:53 +0000181
182 return true;
183}