[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
Nate Begeman
natebegeman at mac.com
Fri Mar 25 00:34:36 PST 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelPattern.cpp updated: 1.4 -> 1.5
---
Log message:
Support global addresses and fix call returns. Varargs still aren't
handled correctly for floating point arguments, or more than 8 arguemnts.
This does however, allow hello world to run.
---
Diffs of the changes: (+50 -6)
PPC32ISelPattern.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 50 insertions(+), 6 deletions(-)
Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5
--- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4 Thu Mar 24 17:35:30 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Mar 25 02:34:25 2005
@@ -229,6 +229,7 @@
Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
break;
case MVT::i32:
+ case MVT::i64:
case MVT::f32:
case MVT::f64:
break;
@@ -259,7 +260,23 @@
std::pair<SDOperand,SDOperand> PPC32TargetLowering::
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
const Type *ArgTy, SelectionDAG &DAG) {
- abort();
+ MVT::ValueType ArgVT = getValueType(ArgTy);
+ SDOperand Result;
+ if (!isVANext) {
+ Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList);
+ } else {
+ unsigned Amt;
+ if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
+ Amt = 4;
+ else {
+ assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
+ "Other types should have been promoted for varargs!");
+ Amt = 8;
+ }
+ Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList,
+ DAG.getConstant(Amt, VAList.getValueType()));
+ }
+ return std::make_pair(Result, Chain);
}
@@ -284,11 +301,22 @@
/// vreg the value is produced in, so we only emit one copy of each compiled
/// tree.
std::map<SDOperand, unsigned> ExprMap;
+
+ unsigned GlobalBaseReg;
+ bool GlobalBaseInitialized;
public:
ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM)
{}
+ /// runOnFunction - Override this function in order to reset our per-function
+ /// variables.
+ virtual bool runOnFunction(Function &Fn) {
+ // Make sure we re-emit a set of the global base reg if necessary
+ GlobalBaseInitialized = false;
+ return SelectionDAGISel::runOnFunction(Fn);
+ }
+
/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -300,6 +328,7 @@
ExprMap.clear();
}
+ unsigned ISel::getGlobalBaseReg();
unsigned SelectExpr(SDOperand N);
unsigned SelectExprFP(SDOperand N, unsigned Result);
void Select(SDOperand N);
@@ -340,6 +369,22 @@
}
}
+/// getGlobalBaseReg - Output the instructions required to put the
+/// base address to use for accessing globals into a register.
+///
+unsigned ISel::getGlobalBaseReg() {
+ if (!GlobalBaseInitialized) {
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = BB->getParent()->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ GlobalBaseReg = MakeReg(MVT::i32);
+ BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
+ BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR);
+ GlobalBaseInitialized = true;
+ }
+ return GlobalBaseReg;
+}
+
//Check to see if the load is a constant offset from a base register
void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
{
@@ -510,9 +555,8 @@
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);
+ BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg())
+ .addGlobalAddress(GV);
if (GV->hasWeakLinkage() || GV->isExternal()) {
BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
} else {
@@ -631,9 +675,9 @@
case MVT::i8:
case MVT::i16:
case MVT::i32:
- BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3);
+ BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
if (Node->getValueType(1) == MVT::i32)
- BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4);
+ BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4).addReg(PPC::R4);
break;
case MVT::f32:
case MVT::f64:
More information about the llvm-commits
mailing list