[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
Nate Begeman
natebegeman at mac.com
Thu Mar 24 15:35:41 PST 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelPattern.cpp updated: 1.3 -> 1.4
---
Log message:
Implement next round of Pattern ISel fixes
1. void returns
2. multiplies
3. calls
---
Diffs of the changes: (+162 -38)
PPC32ISelPattern.cpp | 200 +++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 162 insertions(+), 38 deletions(-)
Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.3 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.3 Thu Mar 24 00:28:42 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Mar 24 17:35:30 2005
@@ -221,10 +221,16 @@
case MVT::i1:
case MVT::i8:
case MVT::i16:
+ // Promote the integer to 32 bits. If the input type is signed use a
+ // sign extend, otherwise use a zero extend.
+ if (Args[i].second->isSigned())
+ Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
+ else
+ Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
+ break;
case MVT::i32:
- case MVT::i64:
- case MVT::f64:
case MVT::f32:
+ case MVT::f64:
break;
}
args_to_use.push_back(Args[i].first);
@@ -438,14 +444,33 @@
unsigned &Reg = ExprMap[N];
if (Reg) return Reg;
- if (DestType == MVT::f64 || DestType == MVT::f32)
- return SelectExprFP(N, Result);
-
- if (N.getOpcode() != ISD::CALL)
+ if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::ADD_PARTS &&
+ N.getOpcode() != ISD::SUB_PARTS)
Reg = Result = (N.getValueType() != MVT::Other) ?
MakeReg(N.getValueType()) : 1;
- else
- abort(); // FIXME: Implement Call
+ else {
+ // If this is a call instruction, make sure to prepare ALL of the result
+ // values as well as the chain.
+ if (N.getOpcode() == ISD::CALL) {
+ if (Node->getNumValues() == 1)
+ Reg = Result = 1; // Void call, just a chain.
+ else {
+ Result = MakeReg(Node->getValueType(0));
+ ExprMap[N.getValue(0)] = Result;
+ for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
+ ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
+ ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
+ }
+ } else {
+ Result = MakeReg(Node->getValueType(0));
+ ExprMap[N.getValue(0)] = Result;
+ for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i)
+ ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
+ }
+ }
+
+ if (DestType == MVT::f64 || DestType == MVT::f32)
+ return SelectExprFP(N, Result);
switch (opcode) {
default:
@@ -482,10 +507,24 @@
case ISD::FrameIndex:
abort();
+ case ISD::GlobalAddress: {
+ GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
+ unsigned Tmp1 = MakeReg(MVT::i32);
+ // FIXME: R1 is incorrect, we need the getGlobalBaseReg() functionality
+ // from the simple isel
+ BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(PPC::R1).addGlobalAddress(GV);
+ if (GV->hasWeakLinkage() || GV->isExternal()) {
+ BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
+ } else {
+ BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV);
+ }
+ return Result;
+ }
+
case ISD::LOAD:
case ISD::EXTLOAD:
case ISD::ZEXTLOAD:
- {
+ case ISD::SEXTLOAD: {
// Make sure we generate both values.
if (Result != 1)
ExprMap[N.getValue(1)] = 1; // Generate the token
@@ -498,22 +537,13 @@
switch (Node->getValueType(0)) {
default: assert(0 && "Cannot load this type!");
- case MVT::i1:
- case MVT::i8: Opc = PPC::LBZ; break;
- case MVT::i16: Opc = PPC::LHZ; break;
- case MVT::i32: Opc = PPC::LWZ; break;
+ case MVT::i1: Opc = PPC::LBZ; Tmp3 = 0; break;
+ case MVT::i8: Opc = PPC::LBZ; Tmp3 = 1; break;
+ case MVT::i16: Opc = PPC::LHZ; Tmp3 = 0; break;
+ case MVT::i32: Opc = PPC::LWZ; Tmp3 = 0; break;
}
- if (Address.getOpcode() == ISD::GlobalAddress) { // FIXME
- BuildMI(BB, Opc, 2, Result)
- .addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal())
- .addReg(PPC::R1);
- }
- else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
- BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CP->getIndex())
- .addReg(PPC::R1);
- }
- else if(Address.getOpcode() == ISD::FrameIndex) {
+ if(Address.getOpcode() == ISD::FrameIndex) {
BuildMI(BB, Opc, 2, Result)
.addFrameIndex(cast<FrameIndexSDNode>(Address)->getIndex())
.addReg(PPC::R1);
@@ -525,10 +555,93 @@
return Result;
}
- case ISD::SEXTLOAD:
- case ISD::GlobalAddress:
- case ISD::CALL:
- abort();
+ case ISD::CALL: {
+ // Lower the chain for this call.
+ Select(N.getOperand(0));
+ ExprMap[N.getValue(Node->getNumValues()-1)] = 1;
+
+ // get the virtual reg for each argument
+ std::vector<unsigned> VRegs;
+ for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
+ VRegs.push_back(SelectExpr(N.getOperand(i)));
+
+ // The ABI specifies that the first 32 bytes of args may be passed in GPRs,
+ // and that 13 FPRs may also be used for passing any floating point args.
+ int GPR_remaining = 8, FPR_remaining = 13;
+ unsigned GPR_idx = 0, FPR_idx = 0;
+ static const unsigned GPR[] = {
+ PPC::R3, PPC::R4, PPC::R5, PPC::R6,
+ PPC::R7, PPC::R8, PPC::R9, PPC::R10,
+ };
+ static const unsigned FPR[] = {
+ PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6,
+ PPC::F7, PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12,
+ PPC::F13
+ };
+
+ // move the vregs into the appropriate architected register or stack slot
+ for(int i = 0, e = VRegs.size(); i < e; ++i) {
+ unsigned OperandType = N.getOperand(i+2).getValueType();
+ switch(OperandType) {
+ default:
+ Node->dump();
+ N.getOperand(i).Val->dump();
+ std::cerr << "Type for " << i << " is: " <<
+ N.getOperand(i+2).getValueType() << "\n";
+ assert(0 && "Unknown value type for call");
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ if (GPR_remaining > 0)
+ BuildMI(BB, PPC::OR, 2, GPR[GPR_idx]).addReg(VRegs[i])
+ .addReg(VRegs[i]);
+ break;
+ case MVT::f32:
+ case MVT::f64:
+ if (FPR_remaining > 0) {
+ BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(VRegs[i]);
+ --FPR_remaining;
+ }
+ break;
+ }
+ // All arguments consume GPRs available for argument passing
+ if (GPR_remaining > 0) --GPR_remaining;
+ if (MVT::f64 == OperandType && GPR_remaining > 0) --GPR_remaining;
+ }
+
+ // Emit the correct call instruction based on the type of symbol called.
+ if (GlobalAddressSDNode *GASD =
+ dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
+ BuildMI(BB, PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), true);
+ } else if (ExternalSymbolSDNode *ESSDN =
+ dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
+ BuildMI(BB, PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), true);
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
+ BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12);
+ BuildMI(BB, PPC::CALLindirect, 3).addImm(20).addImm(0).addReg(PPC::R12);
+ }
+
+ switch (Node->getValueType(0)) {
+ default: assert(0 && "Unknown value type for call result!");
+ case MVT::Other: return 1;
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3);
+ if (Node->getValueType(1) == MVT::i32)
+ BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4);
+ break;
+ case MVT::f32:
+ case MVT::f64:
+ BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1);
+ break;
+ }
+ return Result+N.ResNo;
+ }
case ISD::SIGN_EXTEND:
case ISD::SIGN_EXTEND_INREG:
@@ -551,9 +664,6 @@
.addImm(Tmp2).addImm(31);
return Result;
- case ISD::SETCC:
- abort();
-
case ISD::CopyFromReg:
if (Result == 1)
Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
@@ -613,14 +723,7 @@
break;
}
return Result;
-
- case ISD::SUB:
- assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
- Tmp1 = SelectExpr(N.getOperand(0));
- Tmp2 = SelectExpr(N.getOperand(1));
- BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
- return Result;
-
+
case ISD::AND:
case ISD::OR:
case ISD::XOR:
@@ -655,8 +758,23 @@
break;
}
return Result;
+
+ case ISD::SUB:
+ assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
+ return Result;
case ISD::MUL:
+ assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp2).addReg(Tmp1);
+ return Result;
+
+ case ISD::ADD_PARTS:
+ case ISD::SUB_PARTS:
case ISD::UREM:
case ISD::SREM:
case ISD::SDIV:
@@ -667,6 +785,9 @@
case ISD::FP_TO_SINT:
abort();
+ case ISD::SETCC:
+ abort();
+
case ISD::SELECT:
abort();
@@ -776,6 +897,9 @@
BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
break;
}
+ case 1:
+ Select(N.getOperand(0));
+ break;
}
BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction
return;
More information about the llvm-commits
mailing list