From: Nate Begeman Date: Fri, 25 Mar 2005 08:34:25 +0000 (+0000) Subject: Support global addresses and fix call returns. Varargs still aren't X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c7b09f1f01b31eb8bfbb5ee4adb4d4b8d3b0968c;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20832 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp index b73663026bd..071519389d0 100644 --- a/lib/Target/PowerPC/PPCISelPattern.cpp +++ b/lib/Target/PowerPC/PPCISelPattern.cpp @@ -229,6 +229,7 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain, 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 @@ PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { std::pair 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 @@ class ISel : public SelectionDAGISel { /// vreg the value is produced in, so we only emit one copy of each compiled /// tree. std::map 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 @@ public: ExprMap.clear(); } + unsigned ISel::getGlobalBaseReg(); unsigned SelectExpr(SDOperand N); unsigned SelectExprFP(SDOperand N, unsigned Result); void Select(SDOperand N); @@ -340,6 +369,22 @@ static unsigned canUseAsImmediateForOpcode(SDOperand N, unsigned Opcode, } } +/// 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 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::GlobalAddress: { GlobalValue *GV = cast(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 @@ unsigned ISel::SelectExpr(SDOperand N) { 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: