1 //===- SPUInstrInfo.cpp - Cell SPU 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 Cell SPU implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "SPURegisterNames.h"
15 #include "SPUInstrInfo.h"
16 #include "SPUInstrBuilder.h"
17 #include "SPUTargetMachine.h"
18 #include "SPUGenInstrInfo.inc"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/Support/Streams.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
27 //! Predicate for an unconditional branch instruction
28 inline bool isUncondBranch(const MachineInstr
*I
) {
29 unsigned opc
= I
->getOpcode();
31 return (opc
== SPU::BR
36 //! Predicate for a conditional branch instruction
37 inline bool isCondBranch(const MachineInstr
*I
) {
38 unsigned opc
= I
->getOpcode();
40 return (opc
== SPU::BRNZr32
41 || opc
== SPU::BRNZv4i32
43 || opc
== SPU::BRZv4i32
44 || opc
== SPU::BRHNZr16
45 || opc
== SPU::BRHNZv8i16
46 || opc
== SPU::BRHZr16
47 || opc
== SPU::BRHZv8i16
);
51 SPUInstrInfo::SPUInstrInfo(SPUTargetMachine
&tm
)
52 : TargetInstrInfoImpl(SPUInsts
, sizeof(SPUInsts
)/sizeof(SPUInsts
[0])),
54 RI(*TM
.getSubtargetImpl(), *this)
58 SPUInstrInfo::isMoveInstr(const MachineInstr
& MI
,
61 unsigned& SrcSR
, unsigned& DstSR
) const {
62 SrcSR
= DstSR
= 0; // No sub-registers.
64 switch (MI
.getOpcode()) {
79 assert(MI
.getNumOperands() == 3 &&
80 MI
.getOperand(0).isReg() &&
81 MI
.getOperand(1).isReg() &&
82 MI
.getOperand(2).isImm() &&
83 "invalid SPU ORI/ORHI/ORBI/AHI/AI/SFI/SFHI instruction!");
84 if (MI
.getOperand(2).getImm() == 0) {
85 sourceReg
= MI
.getOperand(1).getReg();
86 destReg
= MI
.getOperand(0).getReg();
91 assert(MI
.getNumOperands() == 3 &&
92 "wrong number of operands to AIr32");
93 if (MI
.getOperand(0).isReg() &&
94 MI
.getOperand(1).isReg() &&
95 (MI
.getOperand(2).isImm() &&
96 MI
.getOperand(2).getImm() == 0)) {
97 sourceReg
= MI
.getOperand(1).getReg();
98 destReg
= MI
.getOperand(0).getReg();
115 case SPU::ORv16i8_i8
:
116 case SPU::ORv8i16_i16
:
117 case SPU::ORv4i32_i32
:
118 case SPU::ORv2i64_i64
:
119 case SPU::ORv4f32_f32
:
120 case SPU::ORv2f64_f64
:
121 case SPU::ORi8_v16i8
:
122 case SPU::ORi16_v8i16
:
123 case SPU::ORi32_v4i32
:
124 case SPU::ORi64_v2i64
:
125 case SPU::ORf32_v4f32
:
126 case SPU::ORf64_v2f64
:
128 case SPU::ORi128_r64:
129 case SPU::ORi128_f64:
130 case SPU::ORi128_r32:
131 case SPU::ORi128_f32:
132 case SPU::ORi128_r16:
135 case SPU::ORi128_vec
:
137 case SPU::ORr64_i128:
138 case SPU::ORf64_i128:
139 case SPU::ORr32_i128:
140 case SPU::ORf32_i128:
141 case SPU::ORr16_i128:
144 case SPU::ORvec_i128
:
162 case SPU::ORr64_f64
: {
163 assert(MI
.getNumOperands() == 2 &&
164 MI
.getOperand(0).isReg() &&
165 MI
.getOperand(1).isReg() &&
166 "invalid SPU OR<type>_<vec> or LR instruction!");
167 if (MI
.getOperand(0).getReg() == MI
.getOperand(1).getReg()) {
168 sourceReg
= MI
.getOperand(1).getReg();
169 destReg
= MI
.getOperand(0).getReg();
185 assert(MI
.getNumOperands() == 3 &&
186 MI
.getOperand(0).isReg() &&
187 MI
.getOperand(1).isReg() &&
188 MI
.getOperand(2).isReg() &&
189 "invalid SPU OR(vec|r32|r64|gprc) instruction!");
190 if (MI
.getOperand(1).getReg() == MI
.getOperand(2).getReg()) {
191 sourceReg
= MI
.getOperand(1).getReg();
192 destReg
= MI
.getOperand(0).getReg();
202 SPUInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
203 int &FrameIndex
) const {
204 switch (MI
->getOpcode()) {
215 const MachineOperand MOp1
= MI
->getOperand(1);
216 const MachineOperand MOp2
= MI
->getOperand(2);
217 if (MOp1
.isImm() && MOp2
.isFI()) {
218 FrameIndex
= MOp2
.getIndex();
219 return MI
->getOperand(0).getReg();
228 SPUInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
229 int &FrameIndex
) const {
230 switch (MI
->getOpcode()) {
242 const MachineOperand MOp1
= MI
->getOperand(1);
243 const MachineOperand MOp2
= MI
->getOperand(2);
244 if (MOp1
.isImm() && MOp2
.isFI()) {
245 FrameIndex
= MOp2
.getIndex();
246 return MI
->getOperand(0).getReg();
254 bool SPUInstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
255 MachineBasicBlock::iterator MI
,
256 unsigned DestReg
, unsigned SrcReg
,
257 const TargetRegisterClass
*DestRC
,
258 const TargetRegisterClass
*SrcRC
) const
260 // We support cross register class moves for our aliases, such as R3 in any
261 // reg class to any other reg class containing R3. This is required because
262 // we instruction select bitconvert i64 -> f64 as a noop for example, so our
263 // types have no specific meaning.
265 DebugLoc DL
= DebugLoc::getUnknownLoc();
266 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
268 if (DestRC
== SPU::R8CRegisterClass
) {
269 BuildMI(MBB
, MI
, DL
, get(SPU::LRr8
), DestReg
).addReg(SrcReg
);
270 } else if (DestRC
== SPU::R16CRegisterClass
) {
271 BuildMI(MBB
, MI
, DL
, get(SPU::LRr16
), DestReg
).addReg(SrcReg
);
272 } else if (DestRC
== SPU::R32CRegisterClass
) {
273 BuildMI(MBB
, MI
, DL
, get(SPU::LRr32
), DestReg
).addReg(SrcReg
);
274 } else if (DestRC
== SPU::R32FPRegisterClass
) {
275 BuildMI(MBB
, MI
, DL
, get(SPU::LRf32
), DestReg
).addReg(SrcReg
);
276 } else if (DestRC
== SPU::R64CRegisterClass
) {
277 BuildMI(MBB
, MI
, DL
, get(SPU::LRr64
), DestReg
).addReg(SrcReg
);
278 } else if (DestRC
== SPU::R64FPRegisterClass
) {
279 BuildMI(MBB
, MI
, DL
, get(SPU::LRf64
), DestReg
).addReg(SrcReg
);
280 } else if (DestRC
== SPU::GPRCRegisterClass
) {
281 BuildMI(MBB
, MI
, DL
, get(SPU::LRr128
), DestReg
).addReg(SrcReg
);
282 } else if (DestRC
== SPU::VECREGRegisterClass
) {
283 BuildMI(MBB
, MI
, DL
, get(SPU::LRv16i8
), DestReg
).addReg(SrcReg
);
285 // Attempt to copy unknown/unsupported register class!
293 SPUInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
294 MachineBasicBlock::iterator MI
,
295 unsigned SrcReg
, bool isKill
, int FrameIdx
,
296 const TargetRegisterClass
*RC
) const
299 bool isValidFrameIdx
= (FrameIdx
< SPUFrameInfo::maxFrameOffset());
300 if (RC
== SPU::GPRCRegisterClass
) {
301 opc
= (isValidFrameIdx
? SPU::STQDr128
: SPU::STQXr128
);
302 } else if (RC
== SPU::R64CRegisterClass
) {
303 opc
= (isValidFrameIdx
? SPU::STQDr64
: SPU::STQXr64
);
304 } else if (RC
== SPU::R64FPRegisterClass
) {
305 opc
= (isValidFrameIdx
? SPU::STQDr64
: SPU::STQXr64
);
306 } else if (RC
== SPU::R32CRegisterClass
) {
307 opc
= (isValidFrameIdx
? SPU::STQDr32
: SPU::STQXr32
);
308 } else if (RC
== SPU::R32FPRegisterClass
) {
309 opc
= (isValidFrameIdx
? SPU::STQDr32
: SPU::STQXr32
);
310 } else if (RC
== SPU::R16CRegisterClass
) {
311 opc
= (isValidFrameIdx
? SPU::STQDr16
: SPU::STQXr16
);
312 } else if (RC
== SPU::R8CRegisterClass
) {
313 opc
= (isValidFrameIdx
? SPU::STQDr8
: SPU::STQXr8
);
314 } else if (RC
== SPU::VECREGRegisterClass
) {
315 opc
= (isValidFrameIdx
) ? SPU::STQDv16i8
: SPU::STQXv16i8
;
317 llvm_unreachable("Unknown regclass!");
320 DebugLoc DL
= DebugLoc::getUnknownLoc();
321 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
322 addFrameReference(BuildMI(MBB
, MI
, DL
, get(opc
))
323 .addReg(SrcReg
, getKillRegState(isKill
)), FrameIdx
);
327 SPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
328 MachineBasicBlock::iterator MI
,
329 unsigned DestReg
, int FrameIdx
,
330 const TargetRegisterClass
*RC
) const
333 bool isValidFrameIdx
= (FrameIdx
< SPUFrameInfo::maxFrameOffset());
334 if (RC
== SPU::GPRCRegisterClass
) {
335 opc
= (isValidFrameIdx
? SPU::LQDr128
: SPU::LQXr128
);
336 } else if (RC
== SPU::R64CRegisterClass
) {
337 opc
= (isValidFrameIdx
? SPU::LQDr64
: SPU::LQXr64
);
338 } else if (RC
== SPU::R64FPRegisterClass
) {
339 opc
= (isValidFrameIdx
? SPU::LQDr64
: SPU::LQXr64
);
340 } else if (RC
== SPU::R32CRegisterClass
) {
341 opc
= (isValidFrameIdx
? SPU::LQDr32
: SPU::LQXr32
);
342 } else if (RC
== SPU::R32FPRegisterClass
) {
343 opc
= (isValidFrameIdx
? SPU::LQDr32
: SPU::LQXr32
);
344 } else if (RC
== SPU::R16CRegisterClass
) {
345 opc
= (isValidFrameIdx
? SPU::LQDr16
: SPU::LQXr16
);
346 } else if (RC
== SPU::R8CRegisterClass
) {
347 opc
= (isValidFrameIdx
? SPU::LQDr8
: SPU::LQXr8
);
348 } else if (RC
== SPU::VECREGRegisterClass
) {
349 opc
= (isValidFrameIdx
) ? SPU::LQDv16i8
: SPU::LQXv16i8
;
351 llvm_unreachable("Unknown regclass in loadRegFromStackSlot!");
354 DebugLoc DL
= DebugLoc::getUnknownLoc();
355 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
356 addFrameReference(BuildMI(MBB
, MI
, DL
, get(opc
), DestReg
), FrameIdx
);
359 //! Return true if the specified load or store can be folded
361 SPUInstrInfo::canFoldMemoryOperand(const MachineInstr
*MI
,
362 const SmallVectorImpl
<unsigned> &Ops
) const {
363 if (Ops
.size() != 1) return false;
365 // Make sure this is a reg-reg copy.
366 unsigned Opc
= MI
->getOpcode();
379 if (MI
->getOperand(1).getReg() == MI
->getOperand(2).getReg())
387 /// foldMemoryOperand - SPU, like PPC, can only fold spills into
388 /// copy instructions, turning them into load/store instructions.
390 SPUInstrInfo::foldMemoryOperandImpl(MachineFunction
&MF
,
392 const SmallVectorImpl
<unsigned> &Ops
,
393 int FrameIndex
) const
395 if (Ops
.size() != 1) return 0;
397 unsigned OpNum
= Ops
[0];
398 unsigned Opc
= MI
->getOpcode();
399 MachineInstr
*NewMI
= 0;
412 if (OpNum
== 0) { // move -> store
413 unsigned InReg
= MI
->getOperand(1).getReg();
414 bool isKill
= MI
->getOperand(1).isKill();
415 bool isUndef
= MI
->getOperand(1).isUndef();
416 if (FrameIndex
< SPUFrameInfo::maxFrameOffset()) {
417 MachineInstrBuilder MIB
= BuildMI(MF
, MI
->getDebugLoc(),
420 MIB
.addReg(InReg
, getKillRegState(isKill
) | getUndefRegState(isUndef
));
421 NewMI
= addFrameReference(MIB
, FrameIndex
);
423 } else { // move -> load
424 unsigned OutReg
= MI
->getOperand(0).getReg();
425 bool isDead
= MI
->getOperand(0).isDead();
426 bool isUndef
= MI
->getOperand(0).isUndef();
427 MachineInstrBuilder MIB
= BuildMI(MF
, MI
->getDebugLoc(), get(Opc
));
429 MIB
.addReg(OutReg
, RegState::Define
| getDeadRegState(isDead
) |
430 getUndefRegState(isUndef
));
431 Opc
= (FrameIndex
< SPUFrameInfo::maxFrameOffset())
432 ? SPU::STQDr32
: SPU::STQXr32
;
433 NewMI
= addFrameReference(MIB
, FrameIndex
);
443 \note This code was kiped from PPC. There may be more branch analysis for
444 CellSPU than what's currently done here.
447 SPUInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
448 MachineBasicBlock
*&FBB
,
449 SmallVectorImpl
<MachineOperand
> &Cond
,
450 bool AllowModify
) const {
451 // If the block has no terminators, it just falls into the block after it.
452 MachineBasicBlock::iterator I
= MBB
.end();
453 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
))
456 // Get the last instruction in the block.
457 MachineInstr
*LastInst
= I
;
459 // If there is only one terminator instruction, process it.
460 if (I
== MBB
.begin() || !isUnpredicatedTerminator(--I
)) {
461 if (isUncondBranch(LastInst
)) {
462 TBB
= LastInst
->getOperand(0).getMBB();
464 } else if (isCondBranch(LastInst
)) {
465 // Block ends with fall-through condbranch.
466 TBB
= LastInst
->getOperand(1).getMBB();
467 DEBUG(cerr
<< "Pushing LastInst: ");
468 DEBUG(LastInst
->dump());
469 Cond
.push_back(MachineOperand::CreateImm(LastInst
->getOpcode()));
470 Cond
.push_back(LastInst
->getOperand(0));
473 // Otherwise, don't know what this is.
477 // Get the instruction before it if it's a terminator.
478 MachineInstr
*SecondLastInst
= I
;
480 // If there are three terminators, we don't know what sort of block this is.
481 if (SecondLastInst
&& I
!= MBB
.begin() &&
482 isUnpredicatedTerminator(--I
))
485 // If the block ends with a conditional and unconditional branch, handle it.
486 if (isCondBranch(SecondLastInst
) && isUncondBranch(LastInst
)) {
487 TBB
= SecondLastInst
->getOperand(1).getMBB();
488 DEBUG(cerr
<< "Pushing SecondLastInst: ");
489 DEBUG(SecondLastInst
->dump());
490 Cond
.push_back(MachineOperand::CreateImm(SecondLastInst
->getOpcode()));
491 Cond
.push_back(SecondLastInst
->getOperand(0));
492 FBB
= LastInst
->getOperand(0).getMBB();
496 // If the block ends with two unconditional branches, handle it. The second
497 // one is not executed, so remove it.
498 if (isUncondBranch(SecondLastInst
) && isUncondBranch(LastInst
)) {
499 TBB
= SecondLastInst
->getOperand(0).getMBB();
502 I
->eraseFromParent();
506 // Otherwise, can't handle this.
511 SPUInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
512 MachineBasicBlock::iterator I
= MBB
.end();
513 if (I
== MBB
.begin())
516 if (!isCondBranch(I
) && !isUncondBranch(I
))
519 // Remove the first branch.
520 DEBUG(cerr
<< "Removing branch: ");
522 I
->eraseFromParent();
524 if (I
== MBB
.begin())
528 if (!(isCondBranch(I
) || isUncondBranch(I
)))
531 // Remove the second branch.
532 DEBUG(cerr
<< "Removing second branch: ");
534 I
->eraseFromParent();
539 SPUInstrInfo::InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
540 MachineBasicBlock
*FBB
,
541 const SmallVectorImpl
<MachineOperand
> &Cond
) const {
542 // FIXME this should probably have a DebugLoc argument
543 DebugLoc dl
= DebugLoc::getUnknownLoc();
544 // Shouldn't be a fall through.
545 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
546 assert((Cond
.size() == 2 || Cond
.size() == 0) &&
547 "SPU branch conditions have two components!");
552 // Unconditional branch
553 MachineInstrBuilder MIB
= BuildMI(&MBB
, dl
, get(SPU::BR
));
556 DEBUG(cerr
<< "Inserted one-way uncond branch: ");
557 DEBUG((*MIB
).dump());
559 // Conditional branch
560 MachineInstrBuilder MIB
= BuildMI(&MBB
, dl
, get(Cond
[0].getImm()));
561 MIB
.addReg(Cond
[1].getReg()).addMBB(TBB
);
563 DEBUG(cerr
<< "Inserted one-way cond branch: ");
564 DEBUG((*MIB
).dump());
568 MachineInstrBuilder MIB
= BuildMI(&MBB
, dl
, get(Cond
[0].getImm()));
569 MachineInstrBuilder MIB2
= BuildMI(&MBB
, dl
, get(SPU::BR
));
571 // Two-way Conditional Branch.
572 MIB
.addReg(Cond
[1].getReg()).addMBB(TBB
);
575 DEBUG(cerr
<< "Inserted conditional branch: ");
576 DEBUG((*MIB
).dump());
577 DEBUG(cerr
<< "part 2: ");
578 DEBUG((*MIB2
).dump());
584 SPUInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock
&MBB
) const {
585 return (!MBB
.empty() && isUncondBranch(&MBB
.back()));
587 //! Reverses a branch's condition, returning false on success.
589 SPUInstrInfo::ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
)
591 // Pretty brainless way of inverting the condition, but it works, considering
592 // there are only two conditions...
594 unsigned Opc
; //! The incoming opcode
595 unsigned RevCondOpc
; //! The reversed condition opcode
597 { SPU::BRNZr32
, SPU::BRZr32
},
598 { SPU::BRNZv4i32
, SPU::BRZv4i32
},
599 { SPU::BRZr32
, SPU::BRNZr32
},
600 { SPU::BRZv4i32
, SPU::BRNZv4i32
},
601 { SPU::BRHNZr16
, SPU::BRHZr16
},
602 { SPU::BRHNZv8i16
, SPU::BRHZv8i16
},
603 { SPU::BRHZr16
, SPU::BRHNZr16
},
604 { SPU::BRHZv8i16
, SPU::BRHNZv8i16
}
607 unsigned Opc
= unsigned(Cond
[0].getImm());
608 // Pretty dull mapping between the two conditions that SPU can generate:
609 for (int i
= sizeof(revconds
)/sizeof(revconds
[0]) - 1; i
>= 0; --i
) {
610 if (revconds
[i
].Opc
== Opc
) {
611 Cond
[0].setImm(revconds
[i
].RevCondOpc
);