]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/Mips/Mips16InstrInfo.cpp
2 //===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // This file contains the Mips16 implementation of the TargetInstrInfo class.
13 //===----------------------------------------------------------------------===//
14 #include "Mips16InstrInfo.h"
15 #include "InstPrinter/MipsInstPrinter.h"
16 #include "MipsMachineFunction.h"
17 #include "MipsTargetMachine.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/TargetRegistry.h"
32 #define DEBUG_TYPE "mips16-instrinfo"
34 Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget
&STI
)
35 : MipsInstrInfo(STI
, Mips::Bimm16
), RI(STI
) {}
37 const MipsRegisterInfo
&Mips16InstrInfo::getRegisterInfo() const {
41 /// isLoadFromStackSlot - If the specified machine instruction is a direct
42 /// load from a stack slot, return the virtual or physical register number of
43 /// the destination along with the FrameIndex of the loaded stack slot. If
44 /// not, return 0. This predicate must return 0 if the instruction has
45 /// any side effects other than loading from the stack slot.
46 unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
47 int &FrameIndex
) const {
51 /// isStoreToStackSlot - If the specified machine instruction is a direct
52 /// store to a stack slot, return the virtual or physical register number of
53 /// the source reg along with the FrameIndex of the loaded stack slot. If
54 /// not, return 0. This predicate must return 0 if the instruction has
55 /// any side effects other than storing to the stack slot.
56 unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
57 int &FrameIndex
) const {
61 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
62 MachineBasicBlock::iterator I
, DebugLoc DL
,
63 unsigned DestReg
, unsigned SrcReg
,
67 if (Mips::CPU16RegsRegClass
.contains(DestReg
) &&
68 Mips::GPR32RegClass
.contains(SrcReg
))
69 Opc
= Mips::MoveR3216
;
70 else if (Mips::GPR32RegClass
.contains(DestReg
) &&
71 Mips::CPU16RegsRegClass
.contains(SrcReg
))
72 Opc
= Mips::Move32R16
;
73 else if ((SrcReg
== Mips::HI0
) &&
74 (Mips::CPU16RegsRegClass
.contains(DestReg
)))
75 Opc
= Mips::Mfhi16
, SrcReg
= 0;
77 else if ((SrcReg
== Mips::LO0
) &&
78 (Mips::CPU16RegsRegClass
.contains(DestReg
)))
79 Opc
= Mips::Mflo16
, SrcReg
= 0;
82 assert(Opc
&& "Cannot copy registers");
84 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
87 MIB
.addReg(DestReg
, RegState::Define
);
90 MIB
.addReg(SrcReg
, getKillRegState(KillSrc
));
93 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock
&MBB
,
94 MachineBasicBlock::iterator I
,
95 unsigned SrcReg
, bool isKill
, int FI
,
96 const TargetRegisterClass
*RC
,
97 const TargetRegisterInfo
*TRI
,
98 int64_t Offset
) const {
100 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
101 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOStore
);
103 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
104 Opc
= Mips::SwRxSpImmX16
;
105 assert(Opc
&& "Register class not handled!");
106 BuildMI(MBB
, I
, DL
, get(Opc
)).addReg(SrcReg
, getKillRegState(isKill
)).
107 addFrameIndex(FI
).addImm(Offset
)
111 void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock
&MBB
,
112 MachineBasicBlock::iterator I
,
113 unsigned DestReg
, int FI
,
114 const TargetRegisterClass
*RC
,
115 const TargetRegisterInfo
*TRI
,
116 int64_t Offset
) const {
118 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
119 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOLoad
);
122 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
123 Opc
= Mips::LwRxSpImmX16
;
124 assert(Opc
&& "Register class not handled!");
125 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
).addFrameIndex(FI
).addImm(Offset
)
129 bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI
) const {
130 MachineBasicBlock
&MBB
= *MI
->getParent();
131 switch(MI
->getDesc().getOpcode()) {
135 ExpandRetRA16(MBB
, MI
, Mips::JrcRa16
);
143 /// GetOppositeBranchOpc - Return the inverse of the specified
144 /// opcode, e.g. turning BEQ to BNE.
145 unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc
) const {
147 case Mips::BeqzRxImmX16
: return Mips::BnezRxImmX16
;
148 case Mips::BnezRxImmX16
: return Mips::BeqzRxImmX16
;
149 case Mips::BeqzRxImm16
: return Mips::BnezRxImm16
;
150 case Mips::BnezRxImm16
: return Mips::BeqzRxImm16
;
151 case Mips::BteqzT8CmpX16
: return Mips::BtnezT8CmpX16
;
152 case Mips::BteqzT8SltX16
: return Mips::BtnezT8SltX16
;
153 case Mips::BteqzT8SltiX16
: return Mips::BtnezT8SltiX16
;
154 case Mips::Btnez16
: return Mips::Bteqz16
;
155 case Mips::BtnezX16
: return Mips::BteqzX16
;
156 case Mips::BtnezT8CmpiX16
: return Mips::BteqzT8CmpiX16
;
157 case Mips::BtnezT8SltuX16
: return Mips::BteqzT8SltuX16
;
158 case Mips::BtnezT8SltiuX16
: return Mips::BteqzT8SltiuX16
;
159 case Mips::Bteqz16
: return Mips::Btnez16
;
160 case Mips::BteqzX16
: return Mips::BtnezX16
;
161 case Mips::BteqzT8CmpiX16
: return Mips::BtnezT8CmpiX16
;
162 case Mips::BteqzT8SltuX16
: return Mips::BtnezT8SltuX16
;
163 case Mips::BteqzT8SltiuX16
: return Mips::BtnezT8SltiuX16
;
164 case Mips::BtnezT8CmpX16
: return Mips::BteqzT8CmpX16
;
165 case Mips::BtnezT8SltX16
: return Mips::BteqzT8SltX16
;
166 case Mips::BtnezT8SltiX16
: return Mips::BteqzT8SltiX16
;
168 llvm_unreachable("Illegal opcode!");
171 static void addSaveRestoreRegs(MachineInstrBuilder
&MIB
,
172 const std::vector
<CalleeSavedInfo
> &CSI
,
173 unsigned Flags
= 0) {
174 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
175 // Add the callee-saved register as live-in. Do not add if the register is
176 // RA and return address is taken, because it has already been added in
177 // method MipsTargetLowering::LowerRETURNADDR.
178 // It's killed at the spill, unless the register is RA and return address
180 unsigned Reg
= CSI
[e
-i
-1].getReg();
185 MIB
.addReg(Reg
, Flags
);
190 llvm_unreachable("unexpected mips16 callee saved register");
195 // Adjust SP by FrameSize bytes. Save RA, S0, S1
196 void Mips16InstrInfo::makeFrame(unsigned SP
, int64_t FrameSize
,
197 MachineBasicBlock
&MBB
,
198 MachineBasicBlock::iterator I
) const {
199 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
200 MachineFunction
&MF
= *MBB
.getParent();
201 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
202 const BitVector Reserved
= RI
.getReservedRegs(MF
);
203 bool SaveS2
= Reserved
[Mips::S2
];
204 MachineInstrBuilder MIB
;
205 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)? Mips::Save16
:Mips::SaveX16
;
206 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
207 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
->getCalleeSavedInfo();
208 addSaveRestoreRegs(MIB
, CSI
);
210 MIB
.addReg(Mips::S2
);
211 if (isUInt
<11>(FrameSize
))
212 MIB
.addImm(FrameSize
);
214 int Base
= 2040; // should create template function like isUInt that
215 // returns largest possible n bit unsigned integer
216 int64_t Remainder
= FrameSize
- Base
;
218 if (isInt
<16>(-Remainder
))
219 BuildAddiuSpImm(MBB
, I
, -Remainder
);
221 adjustStackPtrBig(SP
, -Remainder
, MBB
, I
, Mips::V0
, Mips::V1
);
225 // Adjust SP by FrameSize bytes. Restore RA, S0, S1
226 void Mips16InstrInfo::restoreFrame(unsigned SP
, int64_t FrameSize
,
227 MachineBasicBlock
&MBB
,
228 MachineBasicBlock::iterator I
) const {
229 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
230 MachineFunction
*MF
= MBB
.getParent();
231 MachineFrameInfo
*MFI
= MF
->getFrameInfo();
232 const BitVector Reserved
= RI
.getReservedRegs(*MF
);
233 bool SaveS2
= Reserved
[Mips::S2
];
234 MachineInstrBuilder MIB
;
235 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)?
236 Mips::Restore16
:Mips::RestoreX16
;
238 if (!isUInt
<11>(FrameSize
)) {
239 unsigned Base
= 2040;
240 int64_t Remainder
= FrameSize
- Base
;
241 FrameSize
= Base
; // should create template function like isUInt that
242 // returns largest possible n bit unsigned integer
244 if (isInt
<16>(Remainder
))
245 BuildAddiuSpImm(MBB
, I
, Remainder
);
247 adjustStackPtrBig(SP
, Remainder
, MBB
, I
, Mips::A0
, Mips::A1
);
249 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
250 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
->getCalleeSavedInfo();
251 addSaveRestoreRegs(MIB
, CSI
, RegState::Define
);
253 MIB
.addReg(Mips::S2
, RegState::Define
);
254 MIB
.addImm(FrameSize
);
257 // Adjust SP by Amount bytes where bytes can be up to 32bit number.
258 // This can only be called at times that we know that there is at least one free
260 // This is clearly safe at prologue and epilogue.
262 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP
, int64_t Amount
,
263 MachineBasicBlock
&MBB
,
264 MachineBasicBlock::iterator I
,
265 unsigned Reg1
, unsigned Reg2
) const {
266 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
270 // add reg1, reg1, reg2
274 MachineInstrBuilder MIB1
= BuildMI(MBB
, I
, DL
, get(Mips::LwConstant32
), Reg1
);
275 MIB1
.addImm(Amount
).addImm(-1);
276 MachineInstrBuilder MIB2
= BuildMI(MBB
, I
, DL
, get(Mips::MoveR3216
), Reg2
);
277 MIB2
.addReg(Mips::SP
, RegState::Kill
);
278 MachineInstrBuilder MIB3
= BuildMI(MBB
, I
, DL
, get(Mips::AdduRxRyRz16
), Reg1
);
280 MIB3
.addReg(Reg2
, RegState::Kill
);
281 MachineInstrBuilder MIB4
= BuildMI(MBB
, I
, DL
, get(Mips::Move32R16
),
283 MIB4
.addReg(Reg1
, RegState::Kill
);
286 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
287 unsigned SP
, int64_t Amount
, MachineBasicBlock
&MBB
,
288 MachineBasicBlock::iterator I
) const {
289 llvm_unreachable("adjust stack pointer amount exceeded");
292 /// Adjust SP by Amount bytes.
293 void Mips16InstrInfo::adjustStackPtr(unsigned SP
, int64_t Amount
,
294 MachineBasicBlock
&MBB
,
295 MachineBasicBlock::iterator I
) const {
296 if (isInt
<16>(Amount
)) // need to change to addiu sp, ....and isInt<16>
297 BuildAddiuSpImm(MBB
, I
, Amount
);
299 adjustStackPtrBigUnrestricted(SP
, Amount
, MBB
, I
);
302 /// This function generates the sequence of instructions needed to get the
303 /// result of adding register REG and immediate IMM.
304 unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg
, int64_t Imm
,
305 MachineBasicBlock
&MBB
,
306 MachineBasicBlock::iterator II
,
307 DebugLoc DL
, unsigned &NewImm
) const {
309 // given original instruction is:
310 // Instr rx, T[offset] where offset is too big.
312 // lo = offset & 0xFFFF
313 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
315 // let T = temporary register
321 int32_t lo
= Imm
& 0xFFFF;
326 rs
.enterBasicBlock(&MBB
);
329 // We need to know which registers can be used, in the case where there
330 // are not enough free registers. We exclude all registers that
331 // are used in the instruction that we are helping.
332 // // Consider all allocatable registers in the register class initially
333 BitVector Candidates
=
335 (*II
->getParent()->getParent(), &Mips::CPU16RegsRegClass
);
336 // Exclude all the registers being used by the instruction.
337 for (unsigned i
= 0, e
= II
->getNumOperands(); i
!= e
; ++i
) {
338 MachineOperand
&MO
= II
->getOperand(i
);
339 if (MO
.isReg() && MO
.getReg() != 0 && !MO
.isDef() &&
340 !TargetRegisterInfo::isVirtualRegister(MO
.getReg()))
341 Candidates
.reset(MO
.getReg());
344 // If the same register was used and defined in an instruction, then
345 // it will not be in the list of candidates.
347 // we need to analyze the instruction that we are helping.
348 // we need to know if it defines register x but register x is not
349 // present as an operand of the instruction. this tells
350 // whether the register is live before the instruction. if it's not
351 // then we don't need to save it in case there are no free registers.
353 for (unsigned i
= 0, e
= II
->getNumOperands(); i
!= e
; ++i
) {
354 MachineOperand
&MO
= II
->getOperand(i
);
355 if (MO
.isReg() && MO
.isDef()) {
356 DefReg
= MO
.getReg();
361 BitVector Available
= rs
.getRegsAvailable(&Mips::CPU16RegsRegClass
);
362 Available
&= Candidates
;
364 // we use T0 for the first register, if we need to save something away.
365 // we use T1 for the second register, if we need to save something away.
367 unsigned FirstRegSaved
=0, SecondRegSaved
=0;
368 unsigned FirstRegSavedTo
= 0, SecondRegSavedTo
= 0;
370 Reg
= Available
.find_first();
373 Reg
= Candidates
.find_first();
374 Candidates
.reset(Reg
);
377 FirstRegSavedTo
= Mips::T0
;
378 copyPhysReg(MBB
, II
, DL
, FirstRegSavedTo
, FirstRegSaved
, true);
382 Available
.reset(Reg
);
383 BuildMI(MBB
, II
, DL
, get(Mips::LwConstant32
), Reg
).addImm(Imm
).addImm(-1);
385 if (FrameReg
== Mips::SP
) {
386 SpReg
= Available
.find_first();
388 SpReg
= Candidates
.find_first();
389 // Candidates.reset(SpReg); // not really needed
390 if (DefReg
!= SpReg
) {
391 SecondRegSaved
= SpReg
;
392 SecondRegSavedTo
= Mips::T1
;
395 copyPhysReg(MBB
, II
, DL
, SecondRegSavedTo
, SecondRegSaved
, true);
398 Available
.reset(SpReg
);
399 copyPhysReg(MBB
, II
, DL
, SpReg
, Mips::SP
, false);
400 BuildMI(MBB
, II
, DL
, get(Mips:: AdduRxRyRz16
), Reg
).addReg(SpReg
, RegState::Kill
)
404 BuildMI(MBB
, II
, DL
, get(Mips:: AdduRxRyRz16
), Reg
).addReg(FrameReg
)
405 .addReg(Reg
, RegState::Kill
);
406 if (FirstRegSaved
|| SecondRegSaved
) {
409 copyPhysReg(MBB
, II
, DL
, FirstRegSaved
, FirstRegSavedTo
, true);
411 copyPhysReg(MBB
, II
, DL
, SecondRegSaved
, SecondRegSavedTo
, true);
416 unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc
) const {
417 return (Opc
== Mips::BeqzRxImmX16
|| Opc
== Mips::BimmX16
||
418 Opc
== Mips::Bimm16
||
419 Opc
== Mips::Bteqz16
|| Opc
== Mips::Btnez16
||
420 Opc
== Mips::BeqzRxImm16
|| Opc
== Mips::BnezRxImm16
||
421 Opc
== Mips::BnezRxImmX16
|| Opc
== Mips::BteqzX16
||
422 Opc
== Mips::BteqzT8CmpX16
|| Opc
== Mips::BteqzT8CmpiX16
||
423 Opc
== Mips::BteqzT8SltX16
|| Opc
== Mips::BteqzT8SltuX16
||
424 Opc
== Mips::BteqzT8SltiX16
|| Opc
== Mips::BteqzT8SltiuX16
||
425 Opc
== Mips::BtnezX16
|| Opc
== Mips::BtnezT8CmpX16
||
426 Opc
== Mips::BtnezT8CmpiX16
|| Opc
== Mips::BtnezT8SltX16
||
427 Opc
== Mips::BtnezT8SltuX16
|| Opc
== Mips::BtnezT8SltiX16
||
428 Opc
== Mips::BtnezT8SltiuX16
) ? Opc
: 0;
431 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock
&MBB
,
432 MachineBasicBlock::iterator I
,
433 unsigned Opc
) const {
434 BuildMI(MBB
, I
, I
->getDebugLoc(), get(Opc
));
437 const MCInstrDesc
&Mips16InstrInfo::AddiuSpImm(int64_t Imm
) const {
438 if (validSpImm8(Imm
))
439 return get(Mips::AddiuSpImm16
);
441 return get(Mips::AddiuSpImmX16
);
444 void Mips16InstrInfo::BuildAddiuSpImm
445 (MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
, int64_t Imm
) const {
446 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
447 BuildMI(MBB
, I
, DL
, AddiuSpImm(Imm
)).addImm(Imm
);
450 const MipsInstrInfo
*llvm::createMips16InstrInfo(const MipsSubtarget
&STI
) {
451 return new Mips16InstrInfo(STI
);
454 bool Mips16InstrInfo::validImmediate(unsigned Opcode
, unsigned Reg
,
457 case Mips::LbRxRyOffMemX16
:
458 case Mips::LbuRxRyOffMemX16
:
459 case Mips::LhRxRyOffMemX16
:
460 case Mips::LhuRxRyOffMemX16
:
461 case Mips::SbRxRyOffMemX16
:
462 case Mips::ShRxRyOffMemX16
:
463 case Mips::LwRxRyOffMemX16
:
464 case Mips::SwRxRyOffMemX16
:
465 case Mips::SwRxSpImmX16
:
466 case Mips::LwRxSpImmX16
:
467 return isInt
<16>(Amount
);
468 case Mips::AddiuRxRyOffMemX16
:
469 if ((Reg
== Mips::PC
) || (Reg
== Mips::SP
))
470 return isInt
<16>(Amount
);
471 return isInt
<15>(Amount
);
473 llvm_unreachable("unexpected Opcode in validImmediate");
476 /// Measure the specified inline asm to determine an approximation of its
478 /// Comments (which run till the next SeparatorString or newline) do not
479 /// count as an instruction.
480 /// Any other non-whitespace text is considered an instruction, with
481 /// multiple instructions separated by SeparatorString or newlines.
482 /// Variable-length instructions are not handled here; this function
483 /// may be overloaded in the target code to do that.
484 /// We implement the special case of the .space directive taking only an
485 /// integer argument, which is the size in bytes. This is used for creating
486 /// inline code spacing for testing purposes using inline assembly.
488 unsigned Mips16InstrInfo::getInlineAsmLength(const char *Str
,
489 const MCAsmInfo
&MAI
) const {
491 // Count the number of instructions in the asm.
492 bool atInsnStart
= true;
494 for (; *Str
; ++Str
) {
495 if (*Str
== '\n' || strncmp(Str
, MAI
.getSeparatorString(),
496 strlen(MAI
.getSeparatorString())) == 0)
498 if (atInsnStart
&& !std::isspace(static_cast<unsigned char>(*Str
))) {
499 if (strncmp(Str
, ".space", 6)==0) {
501 Sz
= strtol(Str
+6, &EStr
, 10);
502 while (isspace(*EStr
)) ++EStr
;
504 DEBUG(dbgs() << "parsed .space " << Sz
<< '\n');
508 Length
+= MAI
.getMaxInstLength();
511 if (atInsnStart
&& strncmp(Str
, MAI
.getCommentString(),
512 strlen(MAI
.getCommentString())) == 0)