1 //===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction Information -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips32/64 implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "MipsSEInstrInfo.h"
15 #include "MipsTargetMachine.h"
16 #include "MipsMachineFunction.h"
17 #include "InstPrinter/MipsInstPrinter.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/TargetRegistry.h"
22 #include "llvm/ADT/STLExtras.h"
26 MipsSEInstrInfo::MipsSEInstrInfo(MipsTargetMachine
&tm
)
28 tm
.getRelocationModel() == Reloc::PIC_
? Mips::B
: Mips::J
),
29 RI(*tm
.getSubtargetImpl(), *this),
30 IsN64(tm
.getSubtarget
<MipsSubtarget
>().isABI_N64()) {}
32 const MipsRegisterInfo
&MipsSEInstrInfo::getRegisterInfo() const {
36 /// isLoadFromStackSlot - If the specified machine instruction is a direct
37 /// load from a stack slot, return the virtual or physical register number of
38 /// the destination along with the FrameIndex of the loaded stack slot. If
39 /// not, return 0. This predicate must return 0 if the instruction has
40 /// any side effects other than loading from the stack slot.
41 unsigned MipsSEInstrInfo::
42 isLoadFromStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const
44 unsigned Opc
= MI
->getOpcode();
46 if ((Opc
== Mips::LW
) || (Opc
== Mips::LW_P8
) || (Opc
== Mips::LD
) ||
47 (Opc
== Mips::LD_P8
) || (Opc
== Mips::LWC1
) || (Opc
== Mips::LWC1_P8
) ||
48 (Opc
== Mips::LDC1
) || (Opc
== Mips::LDC164
) ||
49 (Opc
== Mips::LDC164_P8
)) {
50 if ((MI
->getOperand(1).isFI()) && // is a stack slot
51 (MI
->getOperand(2).isImm()) && // the imm is zero
52 (isZeroImm(MI
->getOperand(2)))) {
53 FrameIndex
= MI
->getOperand(1).getIndex();
54 return MI
->getOperand(0).getReg();
61 /// isStoreToStackSlot - If the specified machine instruction is a direct
62 /// store to a stack slot, return the virtual or physical register number of
63 /// the source reg along with the FrameIndex of the loaded stack slot. If
64 /// not, return 0. This predicate must return 0 if the instruction has
65 /// any side effects other than storing to the stack slot.
66 unsigned MipsSEInstrInfo::
67 isStoreToStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const
69 unsigned Opc
= MI
->getOpcode();
71 if ((Opc
== Mips::SW
) || (Opc
== Mips::SW_P8
) || (Opc
== Mips::SD
) ||
72 (Opc
== Mips::SD_P8
) || (Opc
== Mips::SWC1
) || (Opc
== Mips::SWC1_P8
) ||
73 (Opc
== Mips::SDC1
) || (Opc
== Mips::SDC164
) ||
74 (Opc
== Mips::SDC164_P8
)) {
75 if ((MI
->getOperand(1).isFI()) && // is a stack slot
76 (MI
->getOperand(2).isImm()) && // the imm is zero
77 (isZeroImm(MI
->getOperand(2)))) {
78 FrameIndex
= MI
->getOperand(1).getIndex();
79 return MI
->getOperand(0).getReg();
85 void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
86 MachineBasicBlock::iterator I
, DebugLoc DL
,
87 unsigned DestReg
, unsigned SrcReg
,
89 unsigned Opc
= 0, ZeroReg
= 0;
91 if (Mips::CPURegsRegClass
.contains(DestReg
)) { // Copy to CPU Reg.
92 if (Mips::CPURegsRegClass
.contains(SrcReg
))
93 Opc
= Mips::ADDu
, ZeroReg
= Mips::ZERO
;
94 else if (Mips::CCRRegClass
.contains(SrcReg
))
96 else if (Mips::FGR32RegClass
.contains(SrcReg
))
98 else if (SrcReg
== Mips::HI
)
99 Opc
= Mips::MFHI
, SrcReg
= 0;
100 else if (SrcReg
== Mips::LO
)
101 Opc
= Mips::MFLO
, SrcReg
= 0;
103 else if (Mips::CPURegsRegClass
.contains(SrcReg
)) { // Copy from CPU Reg.
104 if (Mips::CCRRegClass
.contains(DestReg
))
106 else if (Mips::FGR32RegClass
.contains(DestReg
))
108 else if (DestReg
== Mips::HI
)
109 Opc
= Mips::MTHI
, DestReg
= 0;
110 else if (DestReg
== Mips::LO
)
111 Opc
= Mips::MTLO
, DestReg
= 0;
113 else if (Mips::FGR32RegClass
.contains(DestReg
, SrcReg
))
115 else if (Mips::AFGR64RegClass
.contains(DestReg
, SrcReg
))
116 Opc
= Mips::FMOV_D32
;
117 else if (Mips::FGR64RegClass
.contains(DestReg
, SrcReg
))
118 Opc
= Mips::FMOV_D64
;
119 else if (Mips::CCRRegClass
.contains(DestReg
, SrcReg
))
120 Opc
= Mips::MOVCCRToCCR
;
121 else if (Mips::CPU64RegsRegClass
.contains(DestReg
)) { // Copy to CPU64 Reg.
122 if (Mips::CPU64RegsRegClass
.contains(SrcReg
))
123 Opc
= Mips::DADDu
, ZeroReg
= Mips::ZERO_64
;
124 else if (SrcReg
== Mips::HI64
)
125 Opc
= Mips::MFHI64
, SrcReg
= 0;
126 else if (SrcReg
== Mips::LO64
)
127 Opc
= Mips::MFLO64
, SrcReg
= 0;
128 else if (Mips::FGR64RegClass
.contains(SrcReg
))
131 else if (Mips::CPU64RegsRegClass
.contains(SrcReg
)) { // Copy from CPU64 Reg.
132 if (DestReg
== Mips::HI64
)
133 Opc
= Mips::MTHI64
, DestReg
= 0;
134 else if (DestReg
== Mips::LO64
)
135 Opc
= Mips::MTLO64
, DestReg
= 0;
136 else if (Mips::FGR64RegClass
.contains(DestReg
))
140 assert(Opc
&& "Cannot copy registers");
142 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, DL
, get(Opc
));
145 MIB
.addReg(DestReg
, RegState::Define
);
151 MIB
.addReg(SrcReg
, getKillRegState(KillSrc
));
154 void MipsSEInstrInfo::
155 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
156 unsigned SrcReg
, bool isKill
, int FI
,
157 const TargetRegisterClass
*RC
,
158 const TargetRegisterInfo
*TRI
) const {
160 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
161 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOStore
);
165 if (Mips::CPURegsRegClass
.hasSubClassEq(RC
))
166 Opc
= IsN64
? Mips::SW_P8
: Mips::SW
;
167 else if (Mips::CPU64RegsRegClass
.hasSubClassEq(RC
))
168 Opc
= IsN64
? Mips::SD_P8
: Mips::SD
;
169 else if (Mips::FGR32RegClass
.hasSubClassEq(RC
))
170 Opc
= IsN64
? Mips::SWC1_P8
: Mips::SWC1
;
171 else if (Mips::AFGR64RegClass
.hasSubClassEq(RC
))
173 else if (Mips::FGR64RegClass
.hasSubClassEq(RC
))
174 Opc
= IsN64
? Mips::SDC164_P8
: Mips::SDC164
;
176 assert(Opc
&& "Register class not handled!");
177 BuildMI(MBB
, I
, DL
, get(Opc
)).addReg(SrcReg
, getKillRegState(isKill
))
178 .addFrameIndex(FI
).addImm(0).addMemOperand(MMO
);
181 void MipsSEInstrInfo::
182 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
183 unsigned DestReg
, int FI
,
184 const TargetRegisterClass
*RC
,
185 const TargetRegisterInfo
*TRI
) const
188 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
189 MachineMemOperand
*MMO
= GetMemOperand(MBB
, FI
, MachineMemOperand::MOLoad
);
192 if (Mips::CPURegsRegClass
.hasSubClassEq(RC
))
193 Opc
= IsN64
? Mips::LW_P8
: Mips::LW
;
194 else if (Mips::CPU64RegsRegClass
.hasSubClassEq(RC
))
195 Opc
= IsN64
? Mips::LD_P8
: Mips::LD
;
196 else if (Mips::FGR32RegClass
.hasSubClassEq(RC
))
197 Opc
= IsN64
? Mips::LWC1_P8
: Mips::LWC1
;
198 else if (Mips::AFGR64RegClass
.hasSubClassEq(RC
))
200 else if (Mips::FGR64RegClass
.hasSubClassEq(RC
))
201 Opc
= IsN64
? Mips::LDC164_P8
: Mips::LDC164
;
203 assert(Opc
&& "Register class not handled!");
204 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
).addFrameIndex(FI
).addImm(0)
208 bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI
) const {
209 MachineBasicBlock
&MBB
= *MI
->getParent();
211 switch(MI
->getDesc().getOpcode()) {
215 ExpandRetRA(MBB
, MI
, Mips::RET
);
217 case Mips::BuildPairF64
:
218 ExpandBuildPairF64(MBB
, MI
);
220 case Mips::ExtractElementF64
:
221 ExpandExtractElementF64(MBB
, MI
);
229 /// GetOppositeBranchOpc - Return the inverse of the specified
230 /// opcode, e.g. turning BEQ to BNE.
231 unsigned MipsSEInstrInfo::GetOppositeBranchOpc(unsigned Opc
) const {
233 default: llvm_unreachable("Illegal opcode!");
234 case Mips::BEQ
: return Mips::BNE
;
235 case Mips::BNE
: return Mips::BEQ
;
236 case Mips::BGTZ
: return Mips::BLEZ
;
237 case Mips::BGEZ
: return Mips::BLTZ
;
238 case Mips::BLTZ
: return Mips::BGEZ
;
239 case Mips::BLEZ
: return Mips::BGTZ
;
240 case Mips::BEQ64
: return Mips::BNE64
;
241 case Mips::BNE64
: return Mips::BEQ64
;
242 case Mips::BGTZ64
: return Mips::BLEZ64
;
243 case Mips::BGEZ64
: return Mips::BLTZ64
;
244 case Mips::BLTZ64
: return Mips::BGEZ64
;
245 case Mips::BLEZ64
: return Mips::BGTZ64
;
246 case Mips::BC1T
: return Mips::BC1F
;
247 case Mips::BC1F
: return Mips::BC1T
;
251 /// Adjust SP by Amount bytes.
252 void MipsSEInstrInfo::adjustStackPtr(unsigned SP
, int64_t Amount
,
253 MachineBasicBlock
&MBB
,
254 MachineBasicBlock::iterator I
) const {
255 const MipsSubtarget
&STI
= TM
.getSubtarget
<MipsSubtarget
>();
256 DebugLoc DL
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
257 unsigned ADDu
= STI
.isABI_N64() ? Mips::DADDu
: Mips::ADDu
;
258 unsigned ADDiu
= STI
.isABI_N64() ? Mips::DADDiu
: Mips::ADDiu
;
260 if (isInt
<16>(Amount
))// addi sp, sp, amount
261 BuildMI(MBB
, I
, DL
, get(ADDiu
), SP
).addReg(SP
).addImm(Amount
);
262 else { // Expand immediate that doesn't fit in 16-bit.
263 MBB
.getParent()->getInfo
<MipsFunctionInfo
>()->setEmitNOAT();
264 unsigned Reg
= loadImmediate(Amount
, MBB
, I
, DL
, 0);
265 BuildMI(MBB
, I
, DL
, get(ADDu
), SP
).addReg(SP
).addReg(Reg
);
269 /// This function generates the sequence of instructions needed to get the
270 /// result of adding register REG and immediate IMM.
272 MipsSEInstrInfo::loadImmediate(int64_t Imm
, MachineBasicBlock
&MBB
,
273 MachineBasicBlock::iterator II
, DebugLoc DL
,
274 unsigned *NewImm
) const {
275 MipsAnalyzeImmediate AnalyzeImm
;
276 const MipsSubtarget
&STI
= TM
.getSubtarget
<MipsSubtarget
>();
277 unsigned Size
= STI
.isABI_N64() ? 64 : 32;
278 unsigned LUi
= STI
.isABI_N64() ? Mips::LUi64
: Mips::LUi
;
279 unsigned ZEROReg
= STI
.isABI_N64() ? Mips::ZERO_64
: Mips::ZERO
;
280 unsigned ATReg
= STI
.isABI_N64() ? Mips::AT_64
: Mips::AT
;
281 bool LastInstrIsADDiu
= NewImm
;
283 const MipsAnalyzeImmediate::InstSeq
&Seq
=
284 AnalyzeImm
.Analyze(Imm
, Size
, LastInstrIsADDiu
);
285 MipsAnalyzeImmediate::InstSeq::const_iterator Inst
= Seq
.begin();
287 assert(Seq
.size() && (!LastInstrIsADDiu
|| (Seq
.size() > 1)));
289 // The first instruction can be a LUi, which is different from other
290 // instructions (ADDiu, ORI and SLL) in that it does not have a register
292 if (Inst
->Opc
== LUi
)
293 BuildMI(MBB
, II
, DL
, get(LUi
), ATReg
)
294 .addImm(SignExtend64
<16>(Inst
->ImmOpnd
));
296 BuildMI(MBB
, II
, DL
, get(Inst
->Opc
), ATReg
).addReg(ZEROReg
)
297 .addImm(SignExtend64
<16>(Inst
->ImmOpnd
));
299 // Build the remaining instructions in Seq.
300 for (++Inst
; Inst
!= Seq
.end() - LastInstrIsADDiu
; ++Inst
)
301 BuildMI(MBB
, II
, DL
, get(Inst
->Opc
), ATReg
).addReg(ATReg
)
302 .addImm(SignExtend64
<16>(Inst
->ImmOpnd
));
304 if (LastInstrIsADDiu
)
305 *NewImm
= Inst
->ImmOpnd
;
310 unsigned MipsSEInstrInfo::GetAnalyzableBrOpc(unsigned Opc
) const {
311 return (Opc
== Mips::BEQ
|| Opc
== Mips::BNE
|| Opc
== Mips::BGTZ
||
312 Opc
== Mips::BGEZ
|| Opc
== Mips::BLTZ
|| Opc
== Mips::BLEZ
||
313 Opc
== Mips::BEQ64
|| Opc
== Mips::BNE64
|| Opc
== Mips::BGTZ64
||
314 Opc
== Mips::BGEZ64
|| Opc
== Mips::BLTZ64
|| Opc
== Mips::BLEZ64
||
315 Opc
== Mips::BC1T
|| Opc
== Mips::BC1F
|| Opc
== Mips::B
||
320 void MipsSEInstrInfo::ExpandRetRA(MachineBasicBlock
&MBB
,
321 MachineBasicBlock::iterator I
,
322 unsigned Opc
) const {
323 BuildMI(MBB
, I
, I
->getDebugLoc(), get(Opc
)).addReg(Mips::RA
);
326 void MipsSEInstrInfo::ExpandExtractElementF64(MachineBasicBlock
&MBB
,
327 MachineBasicBlock::iterator I
) const {
328 unsigned DstReg
= I
->getOperand(0).getReg();
329 unsigned SrcReg
= I
->getOperand(1).getReg();
330 unsigned N
= I
->getOperand(2).getImm();
331 const MCInstrDesc
& Mfc1Tdd
= get(Mips::MFC1
);
332 DebugLoc dl
= I
->getDebugLoc();
334 assert(N
< 2 && "Invalid immediate");
335 unsigned SubIdx
= N
? Mips::sub_fpodd
: Mips::sub_fpeven
;
336 unsigned SubReg
= getRegisterInfo().getSubReg(SrcReg
, SubIdx
);
338 BuildMI(MBB
, I
, dl
, Mfc1Tdd
, DstReg
).addReg(SubReg
);
341 void MipsSEInstrInfo::ExpandBuildPairF64(MachineBasicBlock
&MBB
,
342 MachineBasicBlock::iterator I
) const {
343 unsigned DstReg
= I
->getOperand(0).getReg();
344 unsigned LoReg
= I
->getOperand(1).getReg(), HiReg
= I
->getOperand(2).getReg();
345 const MCInstrDesc
& Mtc1Tdd
= get(Mips::MTC1
);
346 DebugLoc dl
= I
->getDebugLoc();
347 const TargetRegisterInfo
&TRI
= getRegisterInfo();
351 BuildMI(MBB
, I
, dl
, Mtc1Tdd
, TRI
.getSubReg(DstReg
, Mips::sub_fpeven
))
353 BuildMI(MBB
, I
, dl
, Mtc1Tdd
, TRI
.getSubReg(DstReg
, Mips::sub_fpodd
))
357 const MipsInstrInfo
*llvm::createMipsSEInstrInfo(MipsTargetMachine
&TM
) {
358 return new MipsSEInstrInfo(TM
);