1 //===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===//
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 Mips implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "MipsInstrInfo.h"
15 #include "MipsTargetMachine.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "MipsGenInstrInfo.inc"
22 MipsInstrInfo::MipsInstrInfo(MipsTargetMachine
&tm
)
23 : TargetInstrInfoImpl(MipsInsts
, array_lengthof(MipsInsts
)),
24 TM(tm
), RI(*TM
.getSubtargetImpl(), *this) {}
26 static bool isZeroImm(const MachineOperand
&op
) {
27 return op
.isImm() && op
.getImm() == 0;
30 /// Return true if the instruction is a register to register move and
31 /// leave the source and dest operands in the passed parameters.
33 isMoveInstr(const MachineInstr
&MI
, unsigned &SrcReg
, unsigned &DstReg
,
34 unsigned &SrcSubIdx
, unsigned &DstSubIdx
) const
36 SrcSubIdx
= DstSubIdx
= 0; // No sub-registers.
38 // addu $dst, $src, $zero || addu $dst, $zero, $src
39 // or $dst, $src, $zero || or $dst, $zero, $src
40 if ((MI
.getOpcode() == Mips::ADDu
) || (MI
.getOpcode() == Mips::OR
)) {
41 if (MI
.getOperand(1).getReg() == Mips::ZERO
) {
42 DstReg
= MI
.getOperand(0).getReg();
43 SrcReg
= MI
.getOperand(2).getReg();
45 } else if (MI
.getOperand(2).getReg() == Mips::ZERO
) {
46 DstReg
= MI
.getOperand(0).getReg();
47 SrcReg
= MI
.getOperand(1).getReg();
55 if (MI
.getOpcode() == Mips::FMOV_S32
||
56 MI
.getOpcode() == Mips::FMOV_D32
||
57 MI
.getOpcode() == Mips::MFC1
||
58 MI
.getOpcode() == Mips::MTC1
) {
59 DstReg
= MI
.getOperand(0).getReg();
60 SrcReg
= MI
.getOperand(1).getReg();
64 // addiu $dst, $src, 0
65 if (MI
.getOpcode() == Mips::ADDiu
) {
66 if ((MI
.getOperand(1).isReg()) && (isZeroImm(MI
.getOperand(2)))) {
67 DstReg
= MI
.getOperand(0).getReg();
68 SrcReg
= MI
.getOperand(1).getReg();
75 /// isLoadFromStackSlot - If the specified machine instruction is a direct
76 /// load from a stack slot, return the virtual or physical register number of
77 /// the destination along with the FrameIndex of the loaded stack slot. If
78 /// not, return 0. This predicate must return 0 if the instruction has
79 /// any side effects other than loading from the stack slot.
80 unsigned MipsInstrInfo::
81 isLoadFromStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const
83 if ((MI
->getOpcode() == Mips::LW
) || (MI
->getOpcode() == Mips::LWC1
) ||
84 (MI
->getOpcode() == Mips::LDC1
)) {
85 if ((MI
->getOperand(2).isFI()) && // is a stack slot
86 (MI
->getOperand(1).isImm()) && // the imm is zero
87 (isZeroImm(MI
->getOperand(1)))) {
88 FrameIndex
= MI
->getOperand(2).getIndex();
89 return MI
->getOperand(0).getReg();
96 /// isStoreToStackSlot - If the specified machine instruction is a direct
97 /// store to a stack slot, return the virtual or physical register number of
98 /// the source reg along with the FrameIndex of the loaded stack slot. If
99 /// not, return 0. This predicate must return 0 if the instruction has
100 /// any side effects other than storing to the stack slot.
101 unsigned MipsInstrInfo::
102 isStoreToStackSlot(const MachineInstr
*MI
, int &FrameIndex
) const
104 if ((MI
->getOpcode() == Mips::SW
) || (MI
->getOpcode() == Mips::SWC1
) ||
105 (MI
->getOpcode() == Mips::SDC1
)) {
106 if ((MI
->getOperand(2).isFI()) && // is a stack slot
107 (MI
->getOperand(1).isImm()) && // the imm is zero
108 (isZeroImm(MI
->getOperand(1)))) {
109 FrameIndex
= MI
->getOperand(2).getIndex();
110 return MI
->getOperand(0).getReg();
116 /// insertNoop - If data hazard condition is found insert the target nop
119 insertNoop(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
) const
121 DebugLoc DL
= DebugLoc::getUnknownLoc();
122 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
123 BuildMI(MBB
, MI
, DL
, get(Mips::NOP
));
127 copyRegToReg(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
128 unsigned DestReg
, unsigned SrcReg
,
129 const TargetRegisterClass
*DestRC
,
130 const TargetRegisterClass
*SrcRC
) const {
131 DebugLoc DL
= DebugLoc::getUnknownLoc();
132 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
134 if (DestRC
!= SrcRC
) {
135 // Moves between coprocessors and cpu
136 if ((DestRC
== Mips::CPURegsRegisterClass
) &&
137 (SrcRC
== Mips::FGR32RegisterClass
))
138 BuildMI(MBB
, I
, DL
, get(Mips::MFC1
), DestReg
).addReg(SrcReg
);
139 else if ((DestRC
== Mips::FGR32RegisterClass
) &&
140 (SrcRC
== Mips::CPURegsRegisterClass
))
141 BuildMI(MBB
, I
, DL
, get(Mips::MTC1
), DestReg
).addReg(SrcReg
);
143 // Condition registers
144 else if ((SrcRC
== Mips::CCRRegisterClass
) &&
145 (SrcReg
== Mips::FCR31
))
146 return true; // This register is used implicitly, no copy needed.
147 else if ((DestRC
== Mips::CCRRegisterClass
) &&
148 (DestReg
== Mips::FCR31
))
149 return true; // This register is used implicitly, no copy needed.
151 // Move from/to Hi/Lo registers
152 else if ((DestRC
== Mips::HILORegisterClass
) &&
153 (SrcRC
== Mips::CPURegsRegisterClass
)) {
154 unsigned Opc
= (DestReg
== Mips::HI
) ? Mips::MTHI
: Mips::MTLO
;
155 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
);
156 } else if ((SrcRC
== Mips::HILORegisterClass
) &&
157 (DestRC
== Mips::CPURegsRegisterClass
)) {
158 unsigned Opc
= (SrcReg
== Mips::HI
) ? Mips::MFHI
: Mips::MFLO
;
159 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
);
161 // Can't copy this register
168 if (DestRC
== Mips::CPURegsRegisterClass
)
169 BuildMI(MBB
, I
, DL
, get(Mips::ADDu
), DestReg
).addReg(Mips::ZERO
)
171 else if (DestRC
== Mips::FGR32RegisterClass
)
172 BuildMI(MBB
, I
, DL
, get(Mips::FMOV_S32
), DestReg
).addReg(SrcReg
);
173 else if (DestRC
== Mips::AFGR64RegisterClass
)
174 BuildMI(MBB
, I
, DL
, get(Mips::FMOV_D32
), DestReg
).addReg(SrcReg
);
176 // Can't copy this register
183 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
184 unsigned SrcReg
, bool isKill
, int FI
,
185 const TargetRegisterClass
*RC
) const {
188 DebugLoc DL
= DebugLoc::getUnknownLoc();
189 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
191 if (RC
== Mips::CPURegsRegisterClass
)
193 else if (RC
== Mips::FGR32RegisterClass
)
196 assert(RC
== Mips::AFGR64RegisterClass
);
200 BuildMI(MBB
, I
, DL
, get(Opc
)).addReg(SrcReg
, false, false, isKill
)
201 .addImm(0).addFrameIndex(FI
);
204 void MipsInstrInfo::storeRegToAddr(MachineFunction
&MF
, unsigned SrcReg
,
205 bool isKill
, SmallVectorImpl
<MachineOperand
> &Addr
,
206 const TargetRegisterClass
*RC
, SmallVectorImpl
<MachineInstr
*> &NewMIs
) const
209 if (RC
== Mips::CPURegsRegisterClass
)
211 else if (RC
== Mips::FGR32RegisterClass
)
214 assert(RC
== Mips::AFGR64RegisterClass
);
218 DebugLoc DL
= DebugLoc::getUnknownLoc();
219 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, get(Opc
))
220 .addReg(SrcReg
, false, false, isKill
);
221 for (unsigned i
= 0, e
= Addr
.size(); i
!= e
; ++i
)
222 MIB
.addOperand(Addr
[i
]);
223 NewMIs
.push_back(MIB
);
228 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
229 unsigned DestReg
, int FI
,
230 const TargetRegisterClass
*RC
) const
233 if (RC
== Mips::CPURegsRegisterClass
)
235 else if (RC
== Mips::FGR32RegisterClass
)
238 assert(RC
== Mips::AFGR64RegisterClass
);
242 DebugLoc DL
= DebugLoc::getUnknownLoc();
243 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
244 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
).addImm(0).addFrameIndex(FI
);
247 void MipsInstrInfo::loadRegFromAddr(MachineFunction
&MF
, unsigned DestReg
,
248 SmallVectorImpl
<MachineOperand
> &Addr
,
249 const TargetRegisterClass
*RC
,
250 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const {
252 if (RC
== Mips::CPURegsRegisterClass
)
254 else if (RC
== Mips::FGR32RegisterClass
)
257 assert(RC
== Mips::AFGR64RegisterClass
);
261 DebugLoc DL
= DebugLoc::getUnknownLoc();
262 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, get(Opc
), DestReg
);
263 for (unsigned i
= 0, e
= Addr
.size(); i
!= e
; ++i
)
264 MIB
.addOperand(Addr
[i
]);
265 NewMIs
.push_back(MIB
);
269 MachineInstr
*MipsInstrInfo::
270 foldMemoryOperandImpl(MachineFunction
&MF
,
272 const SmallVectorImpl
<unsigned> &Ops
, int FI
) const
274 if (Ops
.size() != 1) return NULL
;
276 MachineInstr
*NewMI
= NULL
;
278 switch (MI
->getOpcode()) {
280 if ((MI
->getOperand(0).isReg()) &&
281 (MI
->getOperand(1).isReg()) &&
282 (MI
->getOperand(1).getReg() == Mips::ZERO
) &&
283 (MI
->getOperand(2).isReg())) {
284 if (Ops
[0] == 0) { // COPY -> STORE
285 unsigned SrcReg
= MI
->getOperand(2).getReg();
286 bool isKill
= MI
->getOperand(2).isKill();
287 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(Mips::SW
))
288 .addReg(SrcReg
, false, false, isKill
)
289 .addImm(0).addFrameIndex(FI
);
290 } else { // COPY -> LOAD
291 unsigned DstReg
= MI
->getOperand(0).getReg();
292 bool isDead
= MI
->getOperand(0).isDead();
293 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(Mips::LW
))
294 .addReg(DstReg
, true, false, false, isDead
)
295 .addImm(0).addFrameIndex(FI
);
301 if ((MI
->getOperand(0).isReg()) &&
302 (MI
->getOperand(1).isReg())) {
303 const TargetRegisterClass
304 *RC
= RI
.getRegClass(MI
->getOperand(0).getReg());
305 unsigned StoreOpc
, LoadOpc
;
307 if (RC
== Mips::FGR32RegisterClass
) {
308 LoadOpc
= Mips::LWC1
; StoreOpc
= Mips::SWC1
;
310 assert(RC
== Mips::AFGR64RegisterClass
);
311 LoadOpc
= Mips::LDC1
; StoreOpc
= Mips::SDC1
;
314 if (Ops
[0] == 0) { // COPY -> STORE
315 unsigned SrcReg
= MI
->getOperand(1).getReg();
316 bool isKill
= MI
->getOperand(1).isKill();
317 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(StoreOpc
))
318 .addReg(SrcReg
, false, false, isKill
)
319 .addImm(0).addFrameIndex(FI
) ;
320 } else { // COPY -> LOAD
321 unsigned DstReg
= MI
->getOperand(0).getReg();
322 bool isDead
= MI
->getOperand(0).isDead();
323 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(LoadOpc
))
324 .addReg(DstReg
, true, false, false, isDead
)
325 .addImm(0).addFrameIndex(FI
);
334 //===----------------------------------------------------------------------===//
336 //===----------------------------------------------------------------------===//
338 /// GetCondFromBranchOpc - Return the Mips CC that matches
339 /// the correspondent Branch instruction opcode.
340 static Mips::CondCode
GetCondFromBranchOpc(unsigned BrOpc
)
343 default: return Mips::COND_INVALID
;
344 case Mips::BEQ
: return Mips::COND_E
;
345 case Mips::BNE
: return Mips::COND_NE
;
346 case Mips::BGTZ
: return Mips::COND_GZ
;
347 case Mips::BGEZ
: return Mips::COND_GEZ
;
348 case Mips::BLTZ
: return Mips::COND_LZ
;
349 case Mips::BLEZ
: return Mips::COND_LEZ
;
351 // We dont do fp branch analysis yet!
353 case Mips::BC1F
: return Mips::COND_INVALID
;
357 /// GetCondBranchFromCond - Return the Branch instruction
358 /// opcode that matches the cc.
359 unsigned Mips::GetCondBranchFromCond(Mips::CondCode CC
)
362 default: assert(0 && "Illegal condition code!");
363 case Mips::COND_E
: return Mips::BEQ
;
364 case Mips::COND_NE
: return Mips::BNE
;
365 case Mips::COND_GZ
: return Mips::BGTZ
;
366 case Mips::COND_GEZ
: return Mips::BGEZ
;
367 case Mips::COND_LZ
: return Mips::BLTZ
;
368 case Mips::COND_LEZ
: return Mips::BLEZ
;
373 case Mips::FCOND_UEQ
:
374 case Mips::FCOND_OLT
:
375 case Mips::FCOND_ULT
:
376 case Mips::FCOND_OLE
:
377 case Mips::FCOND_ULE
:
379 case Mips::FCOND_NGLE
:
380 case Mips::FCOND_SEQ
:
381 case Mips::FCOND_NGL
:
383 case Mips::FCOND_NGE
:
385 case Mips::FCOND_NGT
: return Mips::BC1T
;
389 case Mips::FCOND_NEQ
:
390 case Mips::FCOND_OGL
:
391 case Mips::FCOND_UGE
:
392 case Mips::FCOND_OGE
:
393 case Mips::FCOND_UGT
:
394 case Mips::FCOND_OGT
:
396 case Mips::FCOND_GLE
:
397 case Mips::FCOND_SNE
:
399 case Mips::FCOND_NLT
:
401 case Mips::FCOND_NLE
:
402 case Mips::FCOND_GT
: return Mips::BC1F
;
406 /// GetOppositeBranchCondition - Return the inverse of the specified
407 /// condition, e.g. turning COND_E to COND_NE.
408 Mips::CondCode
Mips::GetOppositeBranchCondition(Mips::CondCode CC
)
411 default: assert(0 && "Illegal condition code!");
412 case Mips::COND_E
: return Mips::COND_NE
;
413 case Mips::COND_NE
: return Mips::COND_E
;
414 case Mips::COND_GZ
: return Mips::COND_LEZ
;
415 case Mips::COND_GEZ
: return Mips::COND_LZ
;
416 case Mips::COND_LZ
: return Mips::COND_GEZ
;
417 case Mips::COND_LEZ
: return Mips::COND_GZ
;
418 case Mips::FCOND_F
: return Mips::FCOND_T
;
419 case Mips::FCOND_UN
: return Mips::FCOND_OR
;
420 case Mips::FCOND_EQ
: return Mips::FCOND_NEQ
;
421 case Mips::FCOND_UEQ
: return Mips::FCOND_OGL
;
422 case Mips::FCOND_OLT
: return Mips::FCOND_UGE
;
423 case Mips::FCOND_ULT
: return Mips::FCOND_OGE
;
424 case Mips::FCOND_OLE
: return Mips::FCOND_UGT
;
425 case Mips::FCOND_ULE
: return Mips::FCOND_OGT
;
426 case Mips::FCOND_SF
: return Mips::FCOND_ST
;
427 case Mips::FCOND_NGLE
:return Mips::FCOND_GLE
;
428 case Mips::FCOND_SEQ
: return Mips::FCOND_SNE
;
429 case Mips::FCOND_NGL
: return Mips::FCOND_GL
;
430 case Mips::FCOND_LT
: return Mips::FCOND_NLT
;
431 case Mips::FCOND_NGE
: return Mips::FCOND_GE
;
432 case Mips::FCOND_LE
: return Mips::FCOND_NLE
;
433 case Mips::FCOND_NGT
: return Mips::FCOND_GT
;
437 bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
,
438 MachineBasicBlock
*&TBB
,
439 MachineBasicBlock
*&FBB
,
440 SmallVectorImpl
<MachineOperand
> &Cond
,
441 bool AllowModify
) const
443 // If the block has no terminators, it just falls into the block after it.
444 MachineBasicBlock::iterator I
= MBB
.end();
445 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
))
448 // Get the last instruction in the block.
449 MachineInstr
*LastInst
= I
;
451 // If there is only one terminator instruction, process it.
452 unsigned LastOpc
= LastInst
->getOpcode();
453 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
)) {
454 if (!LastInst
->getDesc().isBranch())
457 // Unconditional branch
458 if (LastOpc
== Mips::J
) {
459 TBB
= LastInst
->getOperand(0).getMBB();
463 Mips::CondCode BranchCode
= GetCondFromBranchOpc(LastInst
->getOpcode());
464 if (BranchCode
== Mips::COND_INVALID
)
465 return true; // Can't handle indirect branch.
467 // Conditional branch
468 // Block ends with fall-through condbranch.
469 if (LastOpc
!= Mips::COND_INVALID
) {
470 int LastNumOp
= LastInst
->getNumOperands();
472 TBB
= LastInst
->getOperand(LastNumOp
-1).getMBB();
473 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
475 for (int i
=0; i
<LastNumOp
-1; i
++) {
476 Cond
.push_back(LastInst
->getOperand(i
));
483 // Get the instruction before it if it is a terminator.
484 MachineInstr
*SecondLastInst
= I
;
486 // If there are three terminators, we don't know what sort of block this is.
487 if (SecondLastInst
&& I
!= MBB
.begin() && isUnpredicatedTerminator(--I
))
490 // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it.
491 unsigned SecondLastOpc
= SecondLastInst
->getOpcode();
492 Mips::CondCode BranchCode
= GetCondFromBranchOpc(SecondLastOpc
);
494 if (BranchCode
!= Mips::COND_INVALID
&& LastOpc
== Mips::J
) {
495 int SecondNumOp
= SecondLastInst
->getNumOperands();
497 TBB
= SecondLastInst
->getOperand(SecondNumOp
-1).getMBB();
498 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
500 for (int i
=0; i
<SecondNumOp
-1; i
++) {
501 Cond
.push_back(SecondLastInst
->getOperand(i
));
504 FBB
= LastInst
->getOperand(0).getMBB();
508 // If the block ends with two unconditional branches, handle it. The last
509 // one is not executed, so remove it.
510 if ((SecondLastOpc
== Mips::J
) && (LastOpc
== Mips::J
)) {
511 TBB
= SecondLastInst
->getOperand(0).getMBB();
514 I
->eraseFromParent();
518 // Otherwise, can't handle this.
522 unsigned MipsInstrInfo::
523 InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
524 MachineBasicBlock
*FBB
,
525 const SmallVectorImpl
<MachineOperand
> &Cond
) const {
526 // FIXME this should probably have a DebugLoc argument
527 DebugLoc dl
= DebugLoc::getUnknownLoc();
528 // Shouldn't be a fall through.
529 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
530 assert((Cond
.size() == 3 || Cond
.size() == 2 || Cond
.size() == 0) &&
531 "Mips branch conditions can have two|three components!");
533 if (FBB
== 0) { // One way branch.
535 // Unconditional branch?
536 BuildMI(&MBB
, dl
, get(Mips::J
)).addMBB(TBB
);
538 // Conditional branch.
539 unsigned Opc
= GetCondBranchFromCond((Mips::CondCode
)Cond
[0].getImm());
540 const TargetInstrDesc
&TID
= get(Opc
);
542 if (TID
.getNumOperands() == 3)
543 BuildMI(&MBB
, dl
, TID
).addReg(Cond
[1].getReg())
544 .addReg(Cond
[2].getReg())
547 BuildMI(&MBB
, dl
, TID
).addReg(Cond
[1].getReg())
554 // Two-way Conditional branch.
555 unsigned Opc
= GetCondBranchFromCond((Mips::CondCode
)Cond
[0].getImm());
556 const TargetInstrDesc
&TID
= get(Opc
);
558 if (TID
.getNumOperands() == 3)
559 BuildMI(&MBB
, dl
, TID
).addReg(Cond
[1].getReg()).addReg(Cond
[2].getReg())
562 BuildMI(&MBB
, dl
, TID
).addReg(Cond
[1].getReg()).addMBB(TBB
);
564 BuildMI(&MBB
, dl
, get(Mips::J
)).addMBB(FBB
);
568 unsigned MipsInstrInfo::
569 RemoveBranch(MachineBasicBlock
&MBB
) const
571 MachineBasicBlock::iterator I
= MBB
.end();
572 if (I
== MBB
.begin()) return 0;
574 if (I
->getOpcode() != Mips::J
&&
575 GetCondFromBranchOpc(I
->getOpcode()) == Mips::COND_INVALID
)
578 // Remove the branch.
579 I
->eraseFromParent();
583 if (I
== MBB
.begin()) return 1;
585 if (GetCondFromBranchOpc(I
->getOpcode()) == Mips::COND_INVALID
)
588 // Remove the branch.
589 I
->eraseFromParent();
593 /// BlockHasNoFallThrough - Analyze if MachineBasicBlock does not
594 /// fall-through into its successor block.
596 BlockHasNoFallThrough(const MachineBasicBlock
&MBB
) const
598 if (MBB
.empty()) return false;
600 switch (MBB
.back().getOpcode()) {
601 case Mips::RET
: // Return.
602 case Mips::JR
: // Indirect branch.
603 case Mips::J
: // Uncond branch.
605 default: return false;
609 /// ReverseBranchCondition - Return the inverse opcode of the
610 /// specified Branch instruction.
612 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const
614 assert( (Cond
.size() == 3 || Cond
.size() == 2) &&
615 "Invalid Mips branch condition!");
616 Cond
[0].setImm(GetOppositeBranchCondition((Mips::CondCode
)Cond
[0].getImm()));