blob: 9a04c85e080f76e8949ccdb772e579016b29e5af [file] [log] [blame]
Akira Hatanakab7fa3c92012-07-31 21:49:49 +00001//===-- Mips16InstrInfo.cpp - Mips16 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 Mips16 implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
Dmitri Gribenko8b2a3d12013-08-18 08:29:51 +000013
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000014#include "Mips16InstrInfo.h"
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000015#include "InstPrinter/MipsInstPrinter.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "MipsMachineFunction.h"
17#include "MipsTargetMachine.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringRef.h"
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000020#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
Reed Kotler66165c82013-02-08 03:57:41 +000022#include "llvm/CodeGen/RegisterScavenging.h"
Reed Kotlerd019dbf2012-12-20 04:07:42 +000023#include "llvm/Support/CommandLine.h"
Reed Kotlercb374092013-02-18 00:59:04 +000024#include "llvm/Support/Debug.h"
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000025#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/TargetRegistry.h"
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000027
28using namespace llvm;
29
Reed Kotlerd019dbf2012-12-20 04:07:42 +000030static cl::opt<bool> NeverUseSaveRestore(
31 "mips16-never-use-save-restore",
32 cl::init(false),
Jack Carter7ab15fa2013-01-19 02:00:40 +000033 cl::desc("For testing ability to adjust stack pointer "
34 "without save/restore instruction"),
Reed Kotlerd019dbf2012-12-20 04:07:42 +000035 cl::Hidden);
36
37
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000038Mips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm)
Reed Kotler67439242012-10-17 22:29:54 +000039 : MipsInstrInfo(tm, Mips::BimmX16),
Bill Wendlingead89ef2013-06-07 07:04:14 +000040 RI(*tm.getSubtargetImpl()) {}
Akira Hatanakacb37e132012-07-31 23:41:32 +000041
42const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const {
43 return RI;
44}
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000045
46/// isLoadFromStackSlot - If the specified machine instruction is a direct
47/// load from a stack slot, return the virtual or physical register number of
48/// the destination along with the FrameIndex of the loaded stack slot. If
49/// not, return 0. This predicate must return 0 if the instruction has
50/// any side effects other than loading from the stack slot.
51unsigned Mips16InstrInfo::
52isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
53{
54 return 0;
55}
56
57/// isStoreToStackSlot - If the specified machine instruction is a direct
58/// store to a stack slot, return the virtual or physical register number of
59/// the source reg along with the FrameIndex of the loaded stack slot. If
60/// not, return 0. This predicate must return 0 if the instruction has
61/// any side effects other than storing to the stack slot.
62unsigned Mips16InstrInfo::
63isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
64{
65 return 0;
66}
67
68void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
69 MachineBasicBlock::iterator I, DebugLoc DL,
70 unsigned DestReg, unsigned SrcReg,
71 bool KillSrc) const {
Reed Kotlercf11c592012-10-12 02:01:09 +000072 unsigned Opc = 0;
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000073
Reed Kotlercf11c592012-10-12 02:01:09 +000074 if (Mips::CPU16RegsRegClass.contains(DestReg) &&
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000075 Mips::GPR32RegClass.contains(SrcReg))
Reed Kotlercf11c592012-10-12 02:01:09 +000076 Opc = Mips::MoveR3216;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000077 else if (Mips::GPR32RegClass.contains(DestReg) &&
Reed Kotlercf11c592012-10-12 02:01:09 +000078 Mips::CPU16RegsRegClass.contains(SrcReg))
79 Opc = Mips::Move32R16;
Akira Hatanaka8002a3f2013-08-14 00:47:08 +000080 else if ((SrcReg == Mips::HI0) &&
Reed Kotlercf11c592012-10-12 02:01:09 +000081 (Mips::CPU16RegsRegClass.contains(DestReg)))
82 Opc = Mips::Mfhi16, SrcReg = 0;
83
Akira Hatanaka8002a3f2013-08-14 00:47:08 +000084 else if ((SrcReg == Mips::LO0) &&
Reed Kotlercf11c592012-10-12 02:01:09 +000085 (Mips::CPU16RegsRegClass.contains(DestReg)))
86 Opc = Mips::Mflo16, SrcReg = 0;
87
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000088
89 assert(Opc && "Cannot copy registers");
90
91 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
92
93 if (DestReg)
94 MIB.addReg(DestReg, RegState::Define);
95
Akira Hatanakab7fa3c92012-07-31 21:49:49 +000096 if (SrcReg)
97 MIB.addReg(SrcReg, getKillRegState(KillSrc));
98}
99
100void Mips16InstrInfo::
Akira Hatanaka465facca2013-03-29 02:14:12 +0000101storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
102 unsigned SrcReg, bool isKill, int FI,
103 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
104 int64_t Offset) const {
Reed Kotler210ebe92012-09-28 02:26:24 +0000105 DebugLoc DL;
106 if (I != MBB.end()) DL = I->getDebugLoc();
107 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
108 unsigned Opc = 0;
109 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
110 Opc = Mips::SwRxSpImmX16;
111 assert(Opc && "Register class not handled!");
Reed Kotler30cedf62013-08-04 01:13:25 +0000112 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)).
113 addFrameIndex(FI).addImm(Offset)
114 .addMemOperand(MMO);
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000115}
116
117void Mips16InstrInfo::
Akira Hatanaka465facca2013-03-29 02:14:12 +0000118loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
119 unsigned DestReg, int FI, const TargetRegisterClass *RC,
120 const TargetRegisterInfo *TRI, int64_t Offset) const {
Reed Kotler210ebe92012-09-28 02:26:24 +0000121 DebugLoc DL;
122 if (I != MBB.end()) DL = I->getDebugLoc();
123 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
124 unsigned Opc = 0;
125
126 if (Mips::CPU16RegsRegClass.hasSubClassEq(RC))
127 Opc = Mips::LwRxSpImmX16;
128 assert(Opc && "Register class not handled!");
Akira Hatanaka465facca2013-03-29 02:14:12 +0000129 BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset)
Reed Kotler210ebe92012-09-28 02:26:24 +0000130 .addMemOperand(MMO);
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000131}
132
133bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
134 MachineBasicBlock &MBB = *MI->getParent();
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000135 switch(MI->getDesc().getOpcode()) {
136 default:
137 return false;
138 case Mips::RetRA16:
Reed Kotlera8117532012-10-30 00:54:49 +0000139 ExpandRetRA16(MBB, MI, Mips::JrcRa16);
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000140 break;
141 }
142
143 MBB.erase(MI);
144 return true;
145}
146
147/// GetOppositeBranchOpc - Return the inverse of the specified
148/// opcode, e.g. turning BEQ to BNE.
Akira Hatanaka067d8152013-05-13 17:43:19 +0000149unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const {
Reed Kotler67439242012-10-17 22:29:54 +0000150 switch (Opc) {
151 default: llvm_unreachable("Illegal opcode!");
152 case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16;
153 case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16;
154 case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16;
155 case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16;
156 case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16;
157 case Mips::BtnezX16: return Mips::BteqzX16;
158 case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16;
159 case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16;
160 case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16;
161 case Mips::BteqzX16: return Mips::BtnezX16;
162 case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16;
163 case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16;
164 case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16;
165 case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16;
166 case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16;
167 case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16;
168 }
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000169 assert(false && "Implement this function.");
170 return 0;
171}
172
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000173// Adjust SP by FrameSize bytes. Save RA, S0, S1
Jack Carter7ab15fa2013-01-19 02:00:40 +0000174void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
175 MachineBasicBlock &MBB,
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000176 MachineBasicBlock::iterator I) const {
177 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
178 if (!NeverUseSaveRestore) {
179 if (isUInt<11>(FrameSize))
180 BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize);
181 else {
Jack Carter7ab15fa2013-01-19 02:00:40 +0000182 int Base = 2040; // should create template function like isUInt that
183 // returns largest possible n bit unsigned integer
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000184 int64_t Remainder = FrameSize - Base;
185 BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base);
186 if (isInt<16>(-Remainder))
Reed Kotler188dad02013-02-16 19:04:29 +0000187 BuildAddiuSpImm(MBB, I, -Remainder);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000188 else
189 adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
190 }
191
192 }
193 else {
194 //
195 // sw ra, -4[sp]
196 // sw s1, -8[sp]
197 // sw s0, -12[sp]
198
Jack Carter7ab15fa2013-01-19 02:00:40 +0000199 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
200 Mips::RA);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000201 MIB1.addReg(Mips::SP);
202 MIB1.addImm(-4);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000203 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
204 Mips::S1);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000205 MIB2.addReg(Mips::SP);
206 MIB2.addImm(-8);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000207 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::SwRxSpImmX16),
208 Mips::S0);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000209 MIB3.addReg(Mips::SP);
210 MIB3.addImm(-12);
211 adjustStackPtrBig(SP, -FrameSize, MBB, I, Mips::V0, Mips::V1);
212 }
213}
214
215// Adjust SP by FrameSize bytes. Restore RA, S0, S1
Jack Carter7ab15fa2013-01-19 02:00:40 +0000216void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
217 MachineBasicBlock &MBB,
218 MachineBasicBlock::iterator I) const {
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000219 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
220 if (!NeverUseSaveRestore) {
221 if (isUInt<11>(FrameSize))
222 BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize);
223 else {
Jack Carter7ab15fa2013-01-19 02:00:40 +0000224 int Base = 2040; // should create template function like isUInt that
225 // returns largest possible n bit unsigned integer
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000226 int64_t Remainder = FrameSize - Base;
227 if (isInt<16>(Remainder))
Reed Kotler188dad02013-02-16 19:04:29 +0000228 BuildAddiuSpImm(MBB, I, Remainder);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000229 else
230 adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
231 BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base);
232 }
233 }
234 else {
235 adjustStackPtrBig(SP, FrameSize, MBB, I, Mips::A0, Mips::A1);
236 // lw ra, -4[sp]
237 // lw s1, -8[sp]
238 // lw s0, -12[sp]
Jack Carter7ab15fa2013-01-19 02:00:40 +0000239 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
240 Mips::A0);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000241 MIB1.addReg(Mips::SP);
242 MIB1.addImm(-4);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000243 MachineInstrBuilder MIB0 = BuildMI(MBB, I, DL, get(Mips::Move32R16),
244 Mips::RA);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000245 MIB0.addReg(Mips::A0);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000246 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
247 Mips::S1);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000248 MIB2.addReg(Mips::SP);
249 MIB2.addImm(-8);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000250 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::LwRxSpImmX16),
251 Mips::S0);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000252 MIB3.addReg(Mips::SP);
253 MIB3.addImm(-12);
254 }
255
256}
257
258// Adjust SP by Amount bytes where bytes can be up to 32bit number.
Jack Carter7ab15fa2013-01-19 02:00:40 +0000259// This can only be called at times that we know that there is at least one free
260// register.
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000261// This is clearly safe at prologue and epilogue.
262//
Jack Carter7ab15fa2013-01-19 02:00:40 +0000263void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount,
264 MachineBasicBlock &MBB,
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000265 MachineBasicBlock::iterator I,
266 unsigned Reg1, unsigned Reg2) const {
267 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
268// MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
269// unsigned Reg1 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass);
270// unsigned Reg2 = RegInfo.createVirtualRegister(&Mips::CPU16RegsRegClass);
271 //
272 // li reg1, constant
273 // move reg2, sp
274 // add reg1, reg1, reg2
275 // move sp, reg1
276 //
277 //
278 MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1);
279 MIB1.addImm(Amount);
280 MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2);
281 MIB2.addReg(Mips::SP, RegState::Kill);
282 MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1);
283 MIB3.addReg(Reg1);
284 MIB3.addReg(Reg2, RegState::Kill);
Jack Carter7ab15fa2013-01-19 02:00:40 +0000285 MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16),
286 Mips::SP);
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000287 MIB4.addReg(Reg1, RegState::Kill);
288}
289
Jack Carter7ab15fa2013-01-19 02:00:40 +0000290void Mips16InstrInfo::adjustStackPtrBigUnrestricted(unsigned SP, int64_t Amount,
291 MachineBasicBlock &MBB,
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000292 MachineBasicBlock::iterator I) const {
293 assert(false && "adjust stack pointer amount exceeded");
294}
295
Reed Kotler27a72292012-10-31 05:21:10 +0000296/// Adjust SP by Amount bytes.
297void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
298 MachineBasicBlock &MBB,
299 MachineBasicBlock::iterator I) const {
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000300 if (isInt<16>(Amount)) // need to change to addiu sp, ....and isInt<16>
Reed Kotler188dad02013-02-16 19:04:29 +0000301 BuildAddiuSpImm(MBB, I, Amount);
Reed Kotler27a72292012-10-31 05:21:10 +0000302 else
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000303 adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
304}
305
306/// This function generates the sequence of instructions needed to get the
307/// result of adding register REG and immediate IMM.
308unsigned
Reed Kotler66165c82013-02-08 03:57:41 +0000309Mips16InstrInfo::loadImmediate(unsigned FrameReg,
310 int64_t Imm, MachineBasicBlock &MBB,
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000311 MachineBasicBlock::iterator II, DebugLoc DL,
Reed Kotler66165c82013-02-08 03:57:41 +0000312 unsigned &NewImm) const {
313 //
314 // given original instruction is:
315 // Instr rx, T[offset] where offset is too big.
316 //
317 // lo = offset & 0xFFFF
318 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
319 //
320 // let T = temporary register
321 // li T, hi
322 // shl T, 16
323 // add T, Rx, T
324 //
325 RegScavenger rs;
326 int32_t lo = Imm & 0xFFFF;
Reed Kotler66165c82013-02-08 03:57:41 +0000327 NewImm = lo;
Reed Kotler30cedf62013-08-04 01:13:25 +0000328 int Reg =0;
329 int SpReg = 0;
330
Reed Kotler66165c82013-02-08 03:57:41 +0000331 rs.enterBasicBlock(&MBB);
332 rs.forward(II);
333 //
Reed Kotler30cedf62013-08-04 01:13:25 +0000334 // We need to know which registers can be used, in the case where there
335 // are not enough free registers. We exclude all registers that
336 // are used in the instruction that we are helping.
337 // // Consider all allocatable registers in the register class initially
338 BitVector Candidates =
339 RI.getAllocatableSet
340 (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass);
341 // Exclude all the registers being used by the instruction.
342 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
343 MachineOperand &MO = II->getOperand(i);
344 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
345 !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
346 Candidates.reset(MO.getReg());
347 }
348 //
349 // If the same register was used and defined in an instruction, then
350 // it will not be in the list of candidates.
351 //
352 // we need to analyze the instruction that we are helping.
353 // we need to know if it defines register x but register x is not
354 // present as an operand of the instruction. this tells
355 // whether the register is live before the instruction. if it's not
356 // then we don't need to save it in case there are no free registers.
357 //
358 int DefReg = 0;
359 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
360 MachineOperand &MO = II->getOperand(i);
361 if (MO.isReg() && MO.isDef()) {
362 DefReg = MO.getReg();
363 break;
364 }
365 }
366 //
367 BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass);
368
369 Available &= Candidates;
370 //
Reed Kotler66165c82013-02-08 03:57:41 +0000371 // we use T0 for the first register, if we need to save something away.
372 // we use T1 for the second register, if we need to save something away.
373 //
374 unsigned FirstRegSaved =0, SecondRegSaved=0;
375 unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0;
Reed Kotlerd019dbf2012-12-20 04:07:42 +0000376
Reed Kotler30cedf62013-08-04 01:13:25 +0000377
378 Reg = Available.find_first();
379
380 if (Reg == -1) {
381 Reg = Candidates.find_first();
382 Candidates.reset(Reg);
383 if (DefReg != Reg) {
384 FirstRegSaved = Reg;
385 FirstRegSavedTo = Mips::T0;
386 copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true);
387 }
Reed Kotler66165c82013-02-08 03:57:41 +0000388 }
389 else
Reed Kotler30cedf62013-08-04 01:13:25 +0000390 Available.reset(Reg);
391 BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm);
392 NewImm = 0;
Reed Kotler66165c82013-02-08 03:57:41 +0000393 if (FrameReg == Mips::SP) {
Reed Kotler30cedf62013-08-04 01:13:25 +0000394 SpReg = Available.find_first();
395 if (SpReg == -1) {
396 SpReg = Candidates.find_first();
397 // Candidates.reset(SpReg); // not really needed
398 if (DefReg!= SpReg) {
399 SecondRegSaved = SpReg;
Reed Kotler66165c82013-02-08 03:57:41 +0000400 SecondRegSavedTo = Mips::T1;
401 }
Reed Kotler30cedf62013-08-04 01:13:25 +0000402 if (SecondRegSaved)
403 copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true);
Reed Kotler66165c82013-02-08 03:57:41 +0000404 }
Reed Kotler30cedf62013-08-04 01:13:25 +0000405 else
406 Available.reset(SpReg);
Reed Kotler66165c82013-02-08 03:57:41 +0000407 copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false);
Reed Kotler30cedf62013-08-04 01:13:25 +0000408 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill)
Reed Kotler66165c82013-02-08 03:57:41 +0000409 .addReg(Reg);
410 }
411 else
412 BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg)
413 .addReg(Reg, RegState::Kill);
414 if (FirstRegSaved || SecondRegSaved) {
415 II = llvm::next(II);
416 if (FirstRegSaved)
417 copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true);
418 if (SecondRegSaved)
419 copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true);
420 }
421 return Reg;
Reed Kotler27a72292012-10-31 05:21:10 +0000422}
423
Reed Kotler30cedf62013-08-04 01:13:25 +0000424/// This function generates the sequence of instructions needed to get the
425/// result of adding register REG and immediate IMM.
426unsigned
427Mips16InstrInfo::basicLoadImmediate(
428 unsigned FrameReg,
429 int64_t Imm, MachineBasicBlock &MBB,
430 MachineBasicBlock::iterator II, DebugLoc DL,
431 unsigned &NewImm) const {
432 const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass;
433 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
434 unsigned Reg = RegInfo.createVirtualRegister(RC);
435 BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm);
436 NewImm = 0;
437 return Reg;
438}
439
Akira Hatanaka067d8152013-05-13 17:43:19 +0000440unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
Reed Kotler67439242012-10-17 22:29:54 +0000441 return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 ||
442 Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 ||
443 Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 ||
444 Opc == Mips::BteqzT8SltX16 || Opc == Mips::BteqzT8SltuX16 ||
445 Opc == Mips::BteqzT8SltiX16 || Opc == Mips::BteqzT8SltiuX16 ||
446 Opc == Mips::BtnezX16 || Opc == Mips::BtnezT8CmpX16 ||
447 Opc == Mips::BtnezT8CmpiX16 || Opc == Mips::BtnezT8SltX16 ||
448 Opc == Mips::BtnezT8SltuX16 || Opc == Mips::BtnezT8SltiX16 ||
449 Opc == Mips::BtnezT8SltiuX16 ) ? Opc : 0;
Akira Hatanakab7fa3c92012-07-31 21:49:49 +0000450}
451
452void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB,
453 MachineBasicBlock::iterator I,
454 unsigned Opc) const {
455 BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
456}
Akira Hatanakafab89292012-08-02 18:21:47 +0000457
Reed Kotler7b503c22013-02-20 05:45:15 +0000458
Reed Kotler8cf51032013-02-16 09:47:57 +0000459const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const {
Reed Kotlerf662cff2013-02-13 20:28:27 +0000460 if (validSpImm8(Imm))
Reed Kotler8cf51032013-02-16 09:47:57 +0000461 return get(Mips::AddiuSpImm16);
Reed Kotlerf662cff2013-02-13 20:28:27 +0000462 else
Reed Kotler8cf51032013-02-16 09:47:57 +0000463 return get(Mips::AddiuSpImmX16);
Reed Kotlerf662cff2013-02-13 20:28:27 +0000464}
465
Reed Kotler188dad02013-02-16 19:04:29 +0000466void Mips16InstrInfo::BuildAddiuSpImm
467 (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const {
468 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
469 BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm);
470}
471
Akira Hatanakafab89292012-08-02 18:21:47 +0000472const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) {
473 return new Mips16InstrInfo(TM);
474}
Reed Kotler30cedf62013-08-04 01:13:25 +0000475
Reed Kotler30cedf62013-08-04 01:13:25 +0000476bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg,
477 int64_t Amount) {
478 switch (Opcode) {
479 case Mips::LbRxRyOffMemX16:
480 case Mips::LbuRxRyOffMemX16:
481 case Mips::LhRxRyOffMemX16:
482 case Mips::LhuRxRyOffMemX16:
483 case Mips::SbRxRyOffMemX16:
484 case Mips::ShRxRyOffMemX16:
485 case Mips::LwRxRyOffMemX16:
486 case Mips::SwRxRyOffMemX16:
487 case Mips::SwRxSpImmX16:
488 case Mips::LwRxSpImmX16:
489 return isInt<16>(Amount);
490 case Mips::AddiuRxRyOffMemX16:
491 if ((Reg == Mips::PC) || (Reg == Mips::SP))
492 return isInt<16>(Amount);
493 return isInt<15>(Amount);
494 }
Reed Kotler30cedf62013-08-04 01:13:25 +0000495 llvm_unreachable("unexpected Opcode in validImmediate");
496}