[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPCInstrInfo.td
Nate Begeman
natebegeman at mac.com
Sat Apr 9 13:09:23 PDT 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelPattern.cpp updated: 1.55 -> 1.56
PowerPCInstrInfo.td updated: 1.55 -> 1.56
---
Log message:
Add rlwnm instruction for variable rotate
Generate rotate left/right immediate
Generate code for brcondtwoway
Use new livein/liveout functionality
---
Diffs of the changes: (+79 -29)
PPC32ISelPattern.cpp | 104 +++++++++++++++++++++++++++++++++++++--------------
PowerPCInstrInfo.td | 4 +
2 files changed, 79 insertions(+), 29 deletions(-)
Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.56
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.55 Sat Apr 9 04:33:07 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Apr 9 15:09:12 2005
@@ -16,7 +16,7 @@
#include "PowerPC.h"
#include "PowerPCInstrBuilder.h"
#include "PowerPCInstrInfo.h"
-#include "PPC32RegisterInfo.h"
+#include "PPC32TargetMachine.h"
#include "llvm/Constants.h" // FIXME: REMOVE
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
@@ -49,7 +49,6 @@
addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
// PowerPC has no intrinsics for these particular operations
- setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
setOperationAction(ISD::MEMSET, MVT::Other, Expand);
setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
@@ -129,6 +128,7 @@
SDOperand newroot, argt;
unsigned ObjSize;
bool needsLoad = false;
+ bool ArgLive = !I->use_empty();
MVT::ValueType ObjectVT = getValueType(I->getType());
switch (ObjectVT) {
@@ -138,8 +138,9 @@
case MVT::i16:
case MVT::i32:
ObjSize = 4;
+ if (!ArgLive) break;
if (GPR_remaining > 0) {
- BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
+ MF.addLiveIn(GPR[GPR_idx]);
argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
DAG.getRoot());
if (ObjectVT != MVT::i32)
@@ -149,10 +150,11 @@
}
break;
case MVT::i64: ObjSize = 8;
+ if (!ArgLive) break;
// FIXME: can split 64b load between reg/mem if it is last arg in regs
if (GPR_remaining > 1) {
- BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
- BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]);
+ MF.addLiveIn(GPR[GPR_idx]);
+ MF.addLiveIn(GPR[GPR_idx+1]);
// Copy the extracted halves into the virtual registers
SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
DAG.getRoot());
@@ -164,10 +166,12 @@
needsLoad = true;
}
break;
- case MVT::f32: ObjSize = 4;
- case MVT::f64: ObjSize = 8;
+ case MVT::f32:
+ case MVT::f64:
+ ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
+ if (!ArgLive) break;
if (FPR_remaining > 0) {
- BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]);
+ MF.addLiveIn(FPR[FPR_idx]);
argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
DAG.getRoot());
--FPR_remaining;
@@ -214,7 +218,7 @@
// result of va_next.
std::vector<SDOperand> MemOps;
for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
- BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
+ MF.addLiveIn(GPR[GPR_idx]);
SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
Val, FIN);
@@ -226,6 +230,26 @@
DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
}
+ // Finally, inform the code generator which regs we return values in.
+ switch (getValueType(F.getReturnType())) {
+ default: assert(0 && "Unknown type!");
+ case MVT::isVoid: break;
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ MF.addLiveOut(PPC::R3);
+ break;
+ case MVT::i64:
+ MF.addLiveOut(PPC::R3);
+ MF.addLiveOut(PPC::R4);
+ break;
+ case MVT::f32:
+ case MVT::f64:
+ MF.addLiveOut(PPC::F1);
+ break;
+ }
+
return ArgValues;
}
@@ -440,7 +464,7 @@
}
namespace {
-Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops");
+Statistic<>Rotates("ppc-codegen", "Number of rotates emitted");
Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
//===--------------------------------------------------------------------===//
/// ISel - PPC32 specific code to select PPC32 machine instructions for
@@ -837,6 +861,7 @@
/// 3. or shr, and 7. or shr, shl
/// 4. or and, shr
bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
+ bool IsRotate = false;
unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
unsigned Op0Opc = OR.getOperand(0).getOpcode();
unsigned Op1Opc = OR.getOperand(1).getOpcode();
@@ -865,12 +890,14 @@
switch(Op1Opc) {
case ISD::SHL:
Amount = CN->getValue();
- InsMask <<= Amount;
+ InsMask <<= Amount;
+ if (Op0Opc == ISD::SRL) IsRotate = true;
break;
case ISD::SRL:
Amount = CN->getValue();
InsMask >>= Amount;
Amount = 32-Amount;
+ if (Op0Opc == ISD::SHL) IsRotate = true;
break;
case ISD::AND:
InsMask &= (unsigned)CN->getValue();
@@ -887,6 +914,16 @@
unsigned MB, ME;
if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) {
unsigned Tmp1, Tmp2;
+ // Check for rotlwi / rotrwi here, a special case of bitfield insert
+ // where both bitfield halves are sourced from the same value.
+ if (IsRotate &&
+ OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) {
+ ++Rotates; // Statistic
+ Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
+ BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount)
+ .addImm(0).addImm(31);
+ return true;
+ }
if (Op0Opc == ISD::AND)
Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
else
@@ -954,26 +991,38 @@
void ISel::SelectBranchCC(SDOperand N)
{
- assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
MachineBasicBlock *Dest =
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
- // Get the MBB we will fall through to so that we can hand it off to the
- // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op.
- //ilist<MachineBasicBlock>::iterator It = BB;
- //MachineBasicBlock *Fallthrough = ++It;
-
Select(N.getOperand(0)); //chain
unsigned Opc = SelectSetCR0(N.getOperand(1));
- // FIXME: Use this once we have something approximating two-way branches
- // We cannot currently use this in case the ISel hands us something like
- // BRcc MBBx
- // BR MBBy
- // since the fallthrough basic block for the conditional branch does not start
- // with the unconditional branch (it is skipped over).
- //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
- // .addMBB(Dest).addMBB(Fallthrough);
- BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest);
+
+ // Iterate to the next basic block, unless we're already at the end of the
+ ilist<MachineBasicBlock>::iterator It = BB, E = BB->getParent()->end();
+ if (It != E) ++It;
+
+ // If this is a two way branch, then grab the fallthrough basic block argument
+ // and build a PowerPC branch pseudo-op, suitable for long branch conversion
+ // if necessary by the branch selection pass. Otherwise, emit a standard
+ // conditional branch.
+ if (N.getOpcode() == ISD::BRCONDTWOWAY) {
+ MachineBasicBlock *Fallthrough =
+ cast<BasicBlockSDNode>(N.getOperand(3))->getBasicBlock();
+ if (Dest != It) {
+ BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
+ .addMBB(Dest).addMBB(Fallthrough);
+ if (Fallthrough != It)
+ BuildMI(BB, PPC::B, 1).addMBB(Fallthrough);
+ } else {
+ if (Fallthrough != It) {
+ Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc);
+ BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
+ .addMBB(Fallthrough).addMBB(Dest);
+ }
+ }
+ } else {
+ BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest);
+ }
return;
}
@@ -1670,7 +1719,6 @@
if (N.getOperand(0).getOpcode() == ISD::XOR &&
N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
- ++NotLogic;
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1));
BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
@@ -1679,7 +1727,6 @@
// Check for NOT, NOR, and NAND: xor (copy, or, and), -1
if (N.getOperand(1).getOpcode() == ISD::Constant &&
cast<ConstantSDNode>(N.getOperand(1))->isAllOnesValue()) {
- ++NotLogic;
switch(N.getOperand(0).getOpcode()) {
case ISD::OR:
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
@@ -2145,6 +2192,7 @@
return;
}
case ISD::BRCOND:
+ case ISD::BRCONDTWOWAY:
SelectBranchCC(N);
return;
case ISD::CopyToReg:
Index: llvm/lib/Target/PowerPC/PowerPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.56
--- llvm/lib/Target/PowerPC/PowerPCInstrInfo.td:1.55 Tue Apr 5 19:25:27 2005
+++ llvm/lib/Target/PowerPC/PowerPCInstrInfo.td Sat Apr 9 15:09:12 2005
@@ -458,7 +458,9 @@
def RLWINM : MForm_2<21, 0, 0, 0,
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
"rlwinm $rA, $rS, $SH, $MB, $ME">;
-
+def RLWNM : MForm_2<23, 0, 0, 0,
+ (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
+ "rlwnm $rA, $rS, $rB, $MB, $ME">;
// MD-Form instructions. 64 bit rotate instructions.
//
More information about the llvm-commits
mailing list