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 Register
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 Register
Mips16InstrInfo::isStoreToStackSlot(const MachineInstr
&MI
,
65 int &FrameIndex
) const {
69 void Mips16InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
70 MachineBasicBlock::iterator I
,
71 const DebugLoc
&DL
, MCRegister DestReg
,
72 MCRegister 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 std::optional
<DestSourcePair
>
100 Mips16InstrInfo::isCopyInstrImpl(const MachineInstr
&MI
) const {
102 return DestSourcePair
{MI
.getOperand(0), MI
.getOperand(1)};
106 void Mips16InstrInfo::storeRegToStack(MachineBasicBlock
&MBB
,
107 MachineBasicBlock::iterator I
,
108 Register SrcReg
, bool isKill
, int FI
,
109 const TargetRegisterClass
*RC
,
110 const TargetRegisterInfo
*TRI
,
111 int64_t Offset
) const {
113 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
114 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOStore
);
116 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
117 Opc
= Mips::SwRxSpImmX16
;
118 assert(Opc
&& "Register class not handled!");
119 BuildMI(MBB
, I
, DL
, get(Opc
)).addReg(SrcReg
, getKillRegState(isKill
)).
120 addFrameIndex(FI
).addImm(Offset
)
124 void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock
&MBB
,
125 MachineBasicBlock::iterator I
,
126 Register DestReg
, int FI
,
127 const TargetRegisterClass
*RC
,
128 const TargetRegisterInfo
*TRI
,
129 int64_t Offset
) const {
131 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
132 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOLoad
);
135 if (Mips::CPU16RegsRegClass
.hasSubClassEq(RC
))
136 Opc
= Mips::LwRxSpImmX16
;
137 assert(Opc
&& "Register class not handled!");
138 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
).addFrameIndex(FI
).addImm(Offset
)
142 bool Mips16InstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
143 MachineBasicBlock
&MBB
= *MI
.getParent();
144 switch (MI
.getDesc().getOpcode()) {
148 ExpandRetRA16(MBB
, MI
, Mips::JrcRa16
);
152 MBB
.erase(MI
.getIterator());
156 /// GetOppositeBranchOpc - Return the inverse of the specified
157 /// opcode, e.g. turning BEQ to BNE.
158 unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc
) const {
160 case Mips::BeqzRxImmX16
: return Mips::BnezRxImmX16
;
161 case Mips::BnezRxImmX16
: return Mips::BeqzRxImmX16
;
162 case Mips::BeqzRxImm16
: return Mips::BnezRxImm16
;
163 case Mips::BnezRxImm16
: return Mips::BeqzRxImm16
;
164 case Mips::BteqzT8CmpX16
: return Mips::BtnezT8CmpX16
;
165 case Mips::BteqzT8SltX16
: return Mips::BtnezT8SltX16
;
166 case Mips::BteqzT8SltiX16
: return Mips::BtnezT8SltiX16
;
167 case Mips::Btnez16
: return Mips::Bteqz16
;
168 case Mips::BtnezX16
: return Mips::BteqzX16
;
169 case Mips::BtnezT8CmpiX16
: return Mips::BteqzT8CmpiX16
;
170 case Mips::BtnezT8SltuX16
: return Mips::BteqzT8SltuX16
;
171 case Mips::BtnezT8SltiuX16
: return Mips::BteqzT8SltiuX16
;
172 case Mips::Bteqz16
: return Mips::Btnez16
;
173 case Mips::BteqzX16
: return Mips::BtnezX16
;
174 case Mips::BteqzT8CmpiX16
: return Mips::BtnezT8CmpiX16
;
175 case Mips::BteqzT8SltuX16
: return Mips::BtnezT8SltuX16
;
176 case Mips::BteqzT8SltiuX16
: return Mips::BtnezT8SltiuX16
;
177 case Mips::BtnezT8CmpX16
: return Mips::BteqzT8CmpX16
;
178 case Mips::BtnezT8SltX16
: return Mips::BteqzT8SltX16
;
179 case Mips::BtnezT8SltiX16
: return Mips::BteqzT8SltiX16
;
181 llvm_unreachable("Illegal opcode!");
184 static void addSaveRestoreRegs(MachineInstrBuilder
&MIB
,
185 ArrayRef
<CalleeSavedInfo
> CSI
,
186 unsigned Flags
= 0) {
187 for (unsigned i
= 0, e
= CSI
.size(); i
!= e
; ++i
) {
188 // Add the callee-saved register as live-in. Do not add if the register is
189 // RA and return address is taken, because it has already been added in
190 // method MipsTargetLowering::lowerRETURNADDR.
191 // It's killed at the spill, unless the register is RA and return address
193 Register Reg
= CSI
[e
-i
-1].getReg();
198 MIB
.addReg(Reg
, Flags
);
203 llvm_unreachable("unexpected mips16 callee saved register");
209 // Adjust SP by FrameSize bytes. Save RA, S0, S1
210 void Mips16InstrInfo::makeFrame(unsigned SP
, int64_t FrameSize
,
211 MachineBasicBlock
&MBB
,
212 MachineBasicBlock::iterator I
) const {
214 MachineFunction
&MF
= *MBB
.getParent();
215 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
216 const BitVector Reserved
= RI
.getReservedRegs(MF
);
217 bool SaveS2
= Reserved
[Mips::S2
];
218 MachineInstrBuilder MIB
;
219 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)? Mips::Save16
:Mips::SaveX16
;
220 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
221 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
222 addSaveRestoreRegs(MIB
, CSI
);
224 MIB
.addReg(Mips::S2
);
225 if (isUInt
<11>(FrameSize
))
226 MIB
.addImm(FrameSize
);
228 int Base
= 2040; // should create template function like isUInt that
229 // returns largest possible n bit unsigned integer
230 int64_t Remainder
= FrameSize
- Base
;
232 if (isInt
<16>(-Remainder
))
233 BuildAddiuSpImm(MBB
, I
, -Remainder
);
235 adjustStackPtrBig(SP
, -Remainder
, MBB
, I
, Mips::V0
, Mips::V1
);
239 // Adjust SP by FrameSize bytes. Restore RA, S0, S1
240 void Mips16InstrInfo::restoreFrame(unsigned SP
, int64_t FrameSize
,
241 MachineBasicBlock
&MBB
,
242 MachineBasicBlock::iterator I
) const {
243 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
244 MachineFunction
*MF
= MBB
.getParent();
245 MachineFrameInfo
&MFI
= MF
->getFrameInfo();
246 const BitVector Reserved
= RI
.getReservedRegs(*MF
);
247 bool SaveS2
= Reserved
[Mips::S2
];
248 MachineInstrBuilder MIB
;
249 unsigned Opc
= ((FrameSize
<= 128) && !SaveS2
)?
250 Mips::Restore16
:Mips::RestoreX16
;
252 if (!isUInt
<11>(FrameSize
)) {
253 unsigned Base
= 2040;
254 int64_t Remainder
= FrameSize
- Base
;
255 FrameSize
= Base
; // should create template function like isUInt that
256 // returns largest possible n bit unsigned integer
258 if (isInt
<16>(Remainder
))
259 BuildAddiuSpImm(MBB
, I
, Remainder
);
261 adjustStackPtrBig(SP
, Remainder
, MBB
, I
, Mips::A0
, Mips::A1
);
263 MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
264 const std::vector
<CalleeSavedInfo
> &CSI
= MFI
.getCalleeSavedInfo();
265 addSaveRestoreRegs(MIB
, CSI
, RegState::Define
);
267 MIB
.addReg(Mips::S2
, RegState::Define
);
268 MIB
.addImm(FrameSize
);
271 // Adjust SP by Amount bytes where bytes can be up to 32bit number.
272 // This can only be called at times that we know that there is at least one free
274 // This is clearly safe at prologue and epilogue.
275 void Mips16InstrInfo::adjustStackPtrBig(unsigned SP
, int64_t Amount
,
276 MachineBasicBlock
&MBB
,
277 MachineBasicBlock::iterator I
,
278 unsigned Reg1
, unsigned Reg2
) const {
283 // add reg1, reg1, reg2
287 MachineInstrBuilder MIB1
= BuildMI(MBB
, I
, DL
, get(Mips::LwConstant32
), Reg1
);
288 MIB1
.addImm(Amount
).addImm(-1);
289 MachineInstrBuilder MIB2
= BuildMI(MBB
, I
, DL
, get(Mips::MoveR3216
), Reg2
);
290 MIB2
.addReg(Mips::SP
, RegState::Kill
);
291 MachineInstrBuilder MIB3
= BuildMI(MBB
, I
, DL
, get(Mips::AdduRxRyRz16
), Reg1
);
293 MIB3
.addReg(Reg2
, RegState::Kill
);
294 MachineInstrBuilder MIB4
= BuildMI(MBB
, I
, DL
, get(Mips::Move32R16
),
296 MIB4
.addReg(Reg1
, RegState::Kill
);
299 void Mips16InstrInfo::adjustStackPtrBigUnrestricted(
300 unsigned SP
, int64_t Amount
, MachineBasicBlock
&MBB
,
301 MachineBasicBlock::iterator I
) const {
302 llvm_unreachable("adjust stack pointer amount exceeded");
305 /// Adjust SP by Amount bytes.
306 void Mips16InstrInfo::adjustStackPtr(unsigned SP
, int64_t Amount
,
307 MachineBasicBlock
&MBB
,
308 MachineBasicBlock::iterator I
) const {
312 if (isInt
<16>(Amount
)) // need to change to addiu sp, ....and isInt<16>
313 BuildAddiuSpImm(MBB
, I
, Amount
);
315 adjustStackPtrBigUnrestricted(SP
, Amount
, MBB
, I
);
318 /// This function generates the sequence of instructions needed to get the
319 /// result of adding register REG and immediate IMM.
320 unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg
, int64_t Imm
,
321 MachineBasicBlock
&MBB
,
322 MachineBasicBlock::iterator II
,
324 unsigned &NewImm
) const {
326 // given original instruction is:
327 // Instr rx, T[offset] where offset is too big.
329 // lo = offset & 0xFFFF
330 // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF;
332 // let T = temporary register
338 int32_t lo
= Imm
& 0xFFFF;
343 rs
.enterBasicBlockEnd(MBB
);
344 rs
.backward(std::next(II
));
346 // We need to know which registers can be used, in the case where there
347 // are not enough free registers. We exclude all registers that
348 // are used in the instruction that we are helping.
349 // // Consider all allocatable registers in the register class initially
350 BitVector Candidates
=
352 (*II
->getParent()->getParent(), &Mips::CPU16RegsRegClass
);
353 // Exclude all the registers being used by the instruction.
354 for (MachineOperand
&MO
: II
->operands()) {
355 if (MO
.isReg() && MO
.getReg() != 0 && !MO
.isDef() &&
356 !MO
.getReg().isVirtual())
357 Candidates
.reset(MO
.getReg());
360 // If the same register was used and defined in an instruction, then
361 // it will not be in the list of candidates.
363 // we need to analyze the instruction that we are helping.
364 // we need to know if it defines register x but register x is not
365 // present as an operand of the instruction. this tells
366 // whether the register is live before the instruction. if it's not
367 // then we don't need to save it in case there are no free registers.
369 for (MachineOperand
&MO
: II
->operands()) {
370 if (MO
.isReg() && MO
.isDef()) {
371 DefReg
= MO
.getReg();
376 BitVector Available
= rs
.getRegsAvailable(&Mips::CPU16RegsRegClass
);
377 Available
&= Candidates
;
379 // we use T0 for the first register, if we need to save something away.
380 // we use T1 for the second register, if we need to save something away.
382 unsigned FirstRegSaved
=0, SecondRegSaved
=0;
383 unsigned FirstRegSavedTo
= 0, SecondRegSavedTo
= 0;
385 Reg
= Available
.find_first();
388 Reg
= Candidates
.find_first();
389 Candidates
.reset(Reg
);
392 FirstRegSavedTo
= Mips::T0
;
393 copyPhysReg(MBB
, II
, DL
, FirstRegSavedTo
, FirstRegSaved
, true);
397 Available
.reset(Reg
);
398 BuildMI(MBB
, II
, DL
, get(Mips::LwConstant32
), Reg
).addImm(Imm
).addImm(-1);
400 if (FrameReg
== Mips::SP
) {
401 SpReg
= Available
.find_first();
403 SpReg
= Candidates
.find_first();
404 // Candidates.reset(SpReg); // not really needed
405 if (DefReg
!= SpReg
) {
406 SecondRegSaved
= SpReg
;
407 SecondRegSavedTo
= Mips::T1
;
410 copyPhysReg(MBB
, II
, DL
, SecondRegSavedTo
, SecondRegSaved
, true);
413 Available
.reset(SpReg
);
414 copyPhysReg(MBB
, II
, DL
, SpReg
, Mips::SP
, false);
415 BuildMI(MBB
, II
, DL
, get(Mips::AdduRxRyRz16
), Reg
)
416 .addReg(SpReg
, RegState::Kill
)
420 BuildMI(MBB
, II
, DL
, get(Mips:: AdduRxRyRz16
), Reg
).addReg(FrameReg
)
421 .addReg(Reg
, RegState::Kill
);
422 if (FirstRegSaved
|| SecondRegSaved
) {
425 copyPhysReg(MBB
, II
, DL
, FirstRegSaved
, FirstRegSavedTo
, true);
427 copyPhysReg(MBB
, II
, DL
, SecondRegSaved
, SecondRegSavedTo
, true);
432 unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc
) const {
433 return (Opc
== Mips::BeqzRxImmX16
|| Opc
== Mips::BimmX16
||
434 Opc
== Mips::Bimm16
||
435 Opc
== Mips::Bteqz16
|| Opc
== Mips::Btnez16
||
436 Opc
== Mips::BeqzRxImm16
|| Opc
== Mips::BnezRxImm16
||
437 Opc
== Mips::BnezRxImmX16
|| Opc
== Mips::BteqzX16
||
438 Opc
== Mips::BteqzT8CmpX16
|| Opc
== Mips::BteqzT8CmpiX16
||
439 Opc
== Mips::BteqzT8SltX16
|| Opc
== Mips::BteqzT8SltuX16
||
440 Opc
== Mips::BteqzT8SltiX16
|| Opc
== Mips::BteqzT8SltiuX16
||
441 Opc
== Mips::BtnezX16
|| Opc
== Mips::BtnezT8CmpX16
||
442 Opc
== Mips::BtnezT8CmpiX16
|| Opc
== Mips::BtnezT8SltX16
||
443 Opc
== Mips::BtnezT8SltuX16
|| Opc
== Mips::BtnezT8SltiX16
||
444 Opc
== Mips::BtnezT8SltiuX16
) ? Opc
: 0;
447 void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock
&MBB
,
448 MachineBasicBlock::iterator I
,
449 unsigned Opc
) const {
450 BuildMI(MBB
, I
, I
->getDebugLoc(), get(Opc
));
453 const MCInstrDesc
&Mips16InstrInfo::AddiuSpImm(int64_t Imm
) const {
454 if (validSpImm8(Imm
))
455 return get(Mips::AddiuSpImm16
);
457 return get(Mips::AddiuSpImmX16
);
460 void Mips16InstrInfo::BuildAddiuSpImm
461 (MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
, int64_t Imm
) const {
463 BuildMI(MBB
, I
, DL
, AddiuSpImm(Imm
)).addImm(Imm
);
466 const MipsInstrInfo
*llvm::createMips16InstrInfo(const MipsSubtarget
&STI
) {
467 return new Mips16InstrInfo(STI
);
470 bool Mips16InstrInfo::validImmediate(unsigned Opcode
, unsigned Reg
,
473 case Mips::LbRxRyOffMemX16
:
474 case Mips::LbuRxRyOffMemX16
:
475 case Mips::LhRxRyOffMemX16
:
476 case Mips::LhuRxRyOffMemX16
:
477 case Mips::SbRxRyOffMemX16
:
478 case Mips::ShRxRyOffMemX16
:
479 case Mips::LwRxRyOffMemX16
:
480 case Mips::SwRxRyOffMemX16
:
481 case Mips::SwRxSpImmX16
:
482 case Mips::LwRxSpImmX16
:
483 return isInt
<16>(Amount
);
484 case Mips::AddiuRxRyOffMemX16
:
485 if ((Reg
== Mips::PC
) || (Reg
== Mips::SP
))
486 return isInt
<16>(Amount
);
487 return isInt
<15>(Amount
);
489 llvm_unreachable("unexpected Opcode in validImmediate");