1 //===- Mips16InstrInfo.cpp - Mips16 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 Mips16 implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "Mips16InstrInfo.h"
14 #include "llvm/ADT/BitVector.h"
15 #include "llvm/CodeGen/MachineBasicBlock.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineMemOperand.h"
21 #include "llvm/CodeGen/MachineOperand.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23 #include "llvm/CodeGen/TargetRegisterInfo.h"
24 #include "llvm/IR/DebugLoc.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/raw_ostream.h"
40 #define DEBUG_TYPE "mips16-instrinfo"
42 Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget
&STI
)
43 : MipsInstrInfo(STI
, Mips::Bimm16
) {}
45 const MipsRegisterInfo
&Mips16InstrInfo::getRegisterInfo() const {
49 /// isLoadFromStackSlot - If the specified machine instruction is a direct
50 /// load from a stack slot, return the virtual or physical register number of
51 /// the destination along with the FrameIndex of the loaded stack slot. If
52 /// not, return 0. This predicate must return 0 if the instruction has
53 /// any side effects other than loading from the stack slot.
54 unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr
&MI
,
55 int &FrameIndex
) const {
59 /// isStoreToStackSlot - If the specified machine instruction is a direct
60 /// store to a stack slot, return the virtual or physical register number of
61 /// the source reg along with the FrameIndex of the loaded stack slot. If
62 /// not, return 0. This predicate must return 0 if the instruction has
63 /// any side effects other than storing to the stack slot.
64 unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr
&MI
,
65 int &FrameIndex
) const {
69 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
70 MachineBasicBlock::iterator I
,
71 const DebugLoc
&DL
, unsigned DestReg
,
72 unsigned SrcReg
, bool KillSrc
) const {
75 if (Mips::CPU16RegsRegClass
.contains(DestReg
) &&
76 Mips::GPR32RegClass
.contains(SrcReg
))
77 Opc
= Mips::MoveR3216
;
78 else if (Mips::GPR32RegClass
.contains(DestReg
) &&
79 Mips::CPU16RegsRegClass
.contains(SrcReg
))
80 Opc
= Mips::Move32R16
;
81 else if ((SrcReg
== Mips::HI0
) &&
82 (Mips::CPU16RegsRegClass
.contains(DestReg
)))
83 Opc
= Mips::Mfhi16
, SrcReg
= 0;
84 else if ((SrcReg
== Mips::LO0
) &&
85 (Mips::CPU16RegsRegClass
.contains(DestReg
)))
86 Opc
= Mips::Mflo16
, SrcReg
= 0;
88 assert(Opc
&& "Cannot copy registers");
90 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
93 MIB
.addReg(DestReg
, RegState::Define
);
96 MIB
.addReg(SrcReg
, getKillRegState(KillSrc
));
99 bool Mips16InstrInfo::isCopyInstrImpl(const MachineInstr
&MI
,
100 const MachineOperand
*&Src
,
101 const MachineOperand
*&Dest
) const {
102 if (MI
.isMoveReg()) {
103 Dest
= &MI
.getOperand(0);
104 Src
= &MI
.getOperand(1);
110 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock
&MBB
,
111 MachineBasicBlock::iterator I
,
112 unsigned SrcReg
, bool isKill
, int FI
,
113 const TargetRegisterClass
*RC
,
114 const TargetRegisterInfo
*TRI
,
115 int64_t Offset
) const {
117 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
118 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOStore
);
120 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
121 Opc
= Mips::SwRxSpImmX16
;
122 assert(Opc
&& "Register class not handled!");
123 BuildMI(MBB
, I
, DL
, get(Opc
)).addReg(SrcReg
, getKillRegState(isKill
)).
124 addFrameIndex(FI
).addImm(Offset
)
128 void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock
&MBB
,
129 MachineBasicBlock::iterator I
,
130 unsigned DestReg
, int FI
,
131 const TargetRegisterClass
*RC
,
132 const TargetRegisterInfo
*TRI
,
133 int64_t Offset
) const {
135 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
136 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOLoad
);
139 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
140 Opc
= Mips::LwRxSpImmX16
;
141 assert(Opc
&& "Register class not handled!");
142 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
).addFrameIndex(FI
).addImm(Offset
)
146 bool Mips16InstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
147 MachineBasicBlock
&MBB
= *MI
.getParent();
148 switch (MI
.getDesc().getOpcode()) {
152 ExpandRetRA16(MBB
, MI
, Mips::JrcRa16
);
156 MBB
.erase(MI
.getIterator());
160 /// GetOppositeBranchOpc - Return the inverse of the specified
161 /// opcode, e.g. turning BEQ to BNE.
162 unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc
) const {
164 case Mips::BeqzRxImmX16
: return Mips::BnezRxImmX16
;
165 case Mips::BnezRxImmX16
: return Mips::BeqzRxImmX16
;
166 case Mips::BeqzRxImm16
: return Mips::BnezRxImm16
;
167 case Mips::BnezRxImm16
: return Mips::BeqzRxImm16
;
168 case Mips::BteqzT8CmpX16
: return Mips::BtnezT8CmpX16
;
169 case Mips::BteqzT8SltX16
: return Mips::BtnezT8SltX16
;
170 case Mips::BteqzT8SltiX16
: return Mips::BtnezT8SltiX16
;
171 case Mips::Btnez16
: return Mips::Bteqz16
;
172 case Mips::BtnezX16
: return Mips::BteqzX16
;
173 case Mips::BtnezT8CmpiX16
: return Mips::BteqzT8CmpiX16
;
174 case Mips::BtnezT8SltuX16
: return Mips::BteqzT8SltuX16
;
175 case Mips::BtnezT8SltiuX16
: return Mips::BteqzT8SltiuX16
;
176 case Mips::Bteqz16
: return Mips::Btnez16
;
177 case Mips::BteqzX16
: return Mips::BtnezX16
;
178 case Mips::BteqzT8CmpiX16
: return Mips::BtnezT8CmpiX16
;
179 case Mips::BteqzT8SltuX16
: return Mips::BtnezT8SltuX16
;
180 case Mips::BteqzT8SltiuX16
: return Mips::BtnezT8SltiuX16
;
181 case Mips::BtnezT8CmpX16
: return Mips::BteqzT8CmpX16
;
182 case Mips::BtnezT8SltX16
: return Mips::BteqzT8SltX16
;
183 case Mips::BtnezT8SltiX16
: return Mips::BteqzT8SltiX16
;
185 llvm_unreachable("Illegal opcode!");
188 static void addSaveRestoreRegs(MachineInstrBuilder
&MIB
,
189 const std::vector
<CalleeSavedInfo
> &CSI
,
190 unsigned Flags
= 0) {
191 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
192 // Add the callee-saved register as live-in. Do not add if the register is
193 // RA and return address is taken, because it has already been added in
194 // method MipsTargetLowering::lowerRETURNADDR.
195 // It's killed at the spill, unless the register is RA and return address
197 unsigned Reg
= CSI
[e
-i
-1].getReg();
202 MIB
.addReg(Reg
, Flags
);
207 llvm_unreachable("unexpected mips16 callee saved register");
213 // Adjust SP by FrameSize bytes. Save RA, S0, S1
214 void Mips16InstrInfo::makeFrame(unsigned SP
, int64_t FrameSize
,
215 MachineBasicBlock
&MBB
,
216 MachineBasicBlock::iterator I
) const {
218 MachineFunction
&MF
= *MBB
.getParent();
219 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
220 const BitVector Reserved
= RI
.getReservedRegs(MF
);
221 bool SaveS2
= Reserved
[Mips::S2
];
222 MachineInstrBuilder MIB
;
223 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)? Mips::Save16
:Mips::SaveX16
;
224 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
225 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
226 addSaveRestoreRegs(MIB
, CSI
);
228 MIB
.addReg(Mips::S2
);
229 if (isUInt
<11>(FrameSize
))
230 MIB
.addImm(FrameSize
);
232 int Base
= 2040; // should create template function like isUInt that
233 // returns largest possible n bit unsigned integer
234 int64_t Remainder
= FrameSize
- Base
;
236 if (isInt
<16>(-Remainder
))
237 BuildAddiuSpImm(MBB
, I
, -Remainder
);
239 adjustStackPtrBig(SP
, -Remainder
, MBB
, I
, Mips::V0
, Mips::V1
);
243 // Adjust SP by FrameSize bytes. Restore RA, S0, S1
244 void Mips16InstrInfo::restoreFrame(unsigned SP
, int64_t FrameSize
,
245 MachineBasicBlock
&MBB
,
246 MachineBasicBlock::iterator I
) const {
247 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
248 MachineFunction
*MF
= MBB
.getParent();
249 MachineFrameInfo
&MFI
= MF
->getFrameInfo();
250 const BitVector Reserved
= RI
.getReservedRegs(*MF
);
251 bool SaveS2
= Reserved
[Mips::S2
];
252 MachineInstrBuilder MIB
;
253 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)?
254 Mips::Restore16
:Mips::RestoreX16
;
256 if (!isUInt
<11>(FrameSize
)) {
257 unsigned Base
= 2040;
258 int64_t Remainder
= FrameSize
- Base
;
259 FrameSize
= Base
; // should create template function like isUInt that
260 // returns largest possible n bit unsigned integer
262 if (isInt
<16>(Remainder
))
263 BuildAddiuSpImm(MBB
, I
, Remainder
);
265 adjustStackPtrBig(SP
, Remainder
, MBB
, I
, Mips::A0
, Mips::A1
);
267 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
268 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
269 addSaveRestoreRegs(MIB
, CSI
, RegState::Define
);
271 MIB
.addReg(Mips::S2
, RegState::Define
);
272 MIB
.addImm(FrameSize
);
275 // Adjust SP by Amount bytes where bytes can be up to 32bit number.
276 // This can only be called at times that we know that there is at least one free
278 // This is clearly safe at prologue and epilogue.
279 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP
, int64_t Amount
,
280 MachineBasicBlock
&MBB
,
281 MachineBasicBlock::iterator I
,
282 unsigned Reg1
, unsigned Reg2
) const {
287 // add reg1, reg1, reg2
291 MachineInstrBuilder MIB1
= BuildMI(MBB
, I
, DL
, get(Mips::LwConstant32
), Reg1
);
292 MIB1
.addImm(Amount
).addImm(-1);
293 MachineInstrBuilder MIB2
= BuildMI(MBB
, I
, DL
, get(Mips::MoveR3216
), Reg2
);
294 MIB2
.addReg(Mips::SP
, RegState::Kill
);
295 MachineInstrBuilder MIB3
= BuildMI(MBB
, I
, DL
, get(Mips::AdduRxRyRz16
), Reg1
);
297 MIB3
.addReg(Reg2
, RegState::Kill
);
298 MachineInstrBuilder MIB4
= BuildMI(MBB
, I
, DL
, get(Mips::Move32R16
),
300 MIB4
.addReg(Reg1
, RegState::Kill
);
303 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
304 unsigned SP
, int64_t Amount
, MachineBasicBlock
&MBB
,
305 MachineBasicBlock::iterator I
) const {
306 llvm_unreachable("adjust stack pointer amount exceeded");
309 /// Adjust SP by Amount bytes.
310 void Mips16InstrInfo::adjustStackPtr(unsigned SP
, int64_t Amount
,
311 MachineBasicBlock
&MBB
,
312 MachineBasicBlock::iterator I
) const {
316 if (isInt
<16>(Amount
)) // need to change to addiu sp, ....and isInt<16>
317 BuildAddiuSpImm(MBB
, I
, Amount
);
319 adjustStackPtrBigUnrestricted(SP
, Amount
, MBB
, I
);
322 /// This function generates the sequence of instructions needed to get the
323 /// result of adding register REG and immediate IMM.
324 unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg
, int64_t Imm
,
325 MachineBasicBlock
&MBB
,
326 MachineBasicBlock::iterator II
,
328 unsigned &NewImm
) const {
330 // given original instruction is:
331 // Instr rx, T[offset] where offset is too big.
333 // lo = offset & 0xFFFF
334 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
336 // let T = temporary register
342 int32_t lo
= Imm
& 0xFFFF;
347 rs
.enterBasicBlock(MBB
);
350 // We need to know which registers can be used, in the case where there
351 // are not enough free registers. We exclude all registers that
352 // are used in the instruction that we are helping.
353 // // Consider all allocatable registers in the register class initially
354 BitVector Candidates
=
356 (*II
->getParent()->getParent(), &Mips::CPU16RegsRegClass
);
357 // Exclude all the registers being used by the instruction.
358 for (unsigned i
= 0, e
= II
->getNumOperands(); i
!= e
; ++i
) {
359 MachineOperand
&MO
= II
->getOperand(i
);
360 if (MO
.isReg() && MO
.getReg() != 0 && !MO
.isDef() &&
361 !Register::isVirtualRegister(MO
.getReg()))
362 Candidates
.reset(MO
.getReg());
365 // If the same register was used and defined in an instruction, then
366 // it will not be in the list of candidates.
368 // we need to analyze the instruction that we are helping.
369 // we need to know if it defines register x but register x is not
370 // present as an operand of the instruction. this tells
371 // whether the register is live before the instruction. if it's not
372 // then we don't need to save it in case there are no free registers.
374 for (unsigned i
= 0, e
= II
->getNumOperands(); i
!= e
; ++i
) {
375 MachineOperand
&MO
= II
->getOperand(i
);
376 if (MO
.isReg() && MO
.isDef()) {
377 DefReg
= MO
.getReg();
382 BitVector Available
= rs
.getRegsAvailable(&Mips::CPU16RegsRegClass
);
383 Available
&= Candidates
;
385 // we use T0 for the first register, if we need to save something away.
386 // we use T1 for the second register, if we need to save something away.
388 unsigned FirstRegSaved
=0, SecondRegSaved
=0;
389 unsigned FirstRegSavedTo
= 0, SecondRegSavedTo
= 0;
391 Reg
= Available
.find_first();
394 Reg
= Candidates
.find_first();
395 Candidates
.reset(Reg
);
398 FirstRegSavedTo
= Mips::T0
;
399 copyPhysReg(MBB
, II
, DL
, FirstRegSavedTo
, FirstRegSaved
, true);
403 Available
.reset(Reg
);
404 BuildMI(MBB
, II
, DL
, get(Mips::LwConstant32
), Reg
).addImm(Imm
).addImm(-1);
406 if (FrameReg
== Mips::SP
) {
407 SpReg
= Available
.find_first();
409 SpReg
= Candidates
.find_first();
410 // Candidates.reset(SpReg); // not really needed
411 if (DefReg
!= SpReg
) {
412 SecondRegSaved
= SpReg
;
413 SecondRegSavedTo
= Mips::T1
;
416 copyPhysReg(MBB
, II
, DL
, SecondRegSavedTo
, SecondRegSaved
, true);
419 Available
.reset(SpReg
);
420 copyPhysReg(MBB
, II
, DL
, SpReg
, Mips::SP
, false);
421 BuildMI(MBB
, II
, DL
, get(Mips:: AdduRxRyRz16
), Reg
).addReg(SpReg
, RegState::Kill
)
425 BuildMI(MBB
, II
, DL
, get(Mips:: AdduRxRyRz16
), Reg
).addReg(FrameReg
)
426 .addReg(Reg
, RegState::Kill
);
427 if (FirstRegSaved
|| SecondRegSaved
) {
430 copyPhysReg(MBB
, II
, DL
, FirstRegSaved
, FirstRegSavedTo
, true);
432 copyPhysReg(MBB
, II
, DL
, SecondRegSaved
, SecondRegSavedTo
, true);
437 unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc
) const {
438 return (Opc
== Mips::BeqzRxImmX16
|| Opc
== Mips::BimmX16
||
439 Opc
== Mips::Bimm16
||
440 Opc
== Mips::Bteqz16
|| Opc
== Mips::Btnez16
||
441 Opc
== Mips::BeqzRxImm16
|| Opc
== Mips::BnezRxImm16
||
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;
452 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock
&MBB
,
453 MachineBasicBlock::iterator I
,
454 unsigned Opc
) const {
455 BuildMI(MBB
, I
, I
->getDebugLoc(), get(Opc
));
458 const MCInstrDesc
&Mips16InstrInfo::AddiuSpImm(int64_t Imm
) const {
459 if (validSpImm8(Imm
))
460 return get(Mips::AddiuSpImm16
);
462 return get(Mips::AddiuSpImmX16
);
465 void Mips16InstrInfo::BuildAddiuSpImm
466 (MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
, int64_t Imm
) const {
468 BuildMI(MBB
, I
, DL
, AddiuSpImm(Imm
)).addImm(Imm
);
471 const MipsInstrInfo
*llvm::createMips16InstrInfo(const MipsSubtarget
&STI
) {
472 return new Mips16InstrInfo(STI
);
475 bool Mips16InstrInfo::validImmediate(unsigned Opcode
, unsigned Reg
,
478 case Mips::LbRxRyOffMemX16
:
479 case Mips::LbuRxRyOffMemX16
:
480 case Mips::LhRxRyOffMemX16
:
481 case Mips::LhuRxRyOffMemX16
:
482 case Mips::SbRxRyOffMemX16
:
483 case Mips::ShRxRyOffMemX16
:
484 case Mips::LwRxRyOffMemX16
:
485 case Mips::SwRxRyOffMemX16
:
486 case Mips::SwRxSpImmX16
:
487 case Mips::LwRxSpImmX16
:
488 return isInt
<16>(Amount
);
489 case Mips::AddiuRxRyOffMemX16
:
490 if ((Reg
== Mips::PC
) || (Reg
== Mips::SP
))
491 return isInt
<16>(Amount
);
492 return isInt
<15>(Amount
);
494 llvm_unreachable("unexpected Opcode in validImmediate");