From: Nate Begeman Date: Wed, 25 Jan 2006 18:21:52 +0000 (+0000) Subject: First part of bug 680: X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=acc398c195a697795bff3245943d104eb19192b9;p=oota-llvm.git First part of bug 680: Remove TLI.LowerVA* and replace it with SDNodes that are lowered the same way as everything else. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25606 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index f9d7172672e..70aafcca9ee 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -278,6 +278,11 @@ public: Ops.push_back(False); return getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops); } + + /// getVAArg - VAArg produces a result and token chain, and takes a pointer + /// and a source value as input. + SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, + SDOperand SV); /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index f0907f54995..431364e0724 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -335,6 +335,19 @@ namespace ISD { // target and not touched by the DAG optimizers. CALLSEQ_START, // Beginning of a call sequence CALLSEQ_END, // End of a call sequence + + // VAARG - VAARG has three operands: an input chain, a pointer, and a + // SRCVALUE. It returns a pair of values: the vaarg value and a new chain. + VAARG, + + // VACOPY - VACOPY has five operands: an input chain, a destination pointer, + // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the + // source. + VACOPY, + + // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a + // pointer, and a SRCVALUE. + VAEND, VASTART, // SRCVALUE - This corresponds to a Value*, and is used to associate memory // locations with their value. This allows one use alias analysis diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 2a99962a2f8..e93bc2331d8 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -366,31 +366,6 @@ public: virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG); - /// LowerVAStart - This lowers the llvm.va_start intrinsic. If not - /// implemented, this method prints a message and aborts. This method should - /// return the modified chain value. Note that VAListPtr* correspond to the - /// llvm.va_start operand. - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - - /// LowerVAEnd - This lowers llvm.va_end and returns the resultant chain. If - /// not implemented, this defaults to a noop. - virtual SDOperand LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV, - SelectionDAG &DAG); - - /// LowerVACopy - This lowers llvm.va_copy and returns the resultant chain. - /// If not implemented, this defaults to loading a pointer from the input and - /// storing it to the output. - virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, - SDOperand DestP, Value *DestV, - SelectionDAG &DAG); - - /// LowerVAArg - This lowers the vaarg instruction. If not implemented, this - /// prints a message and aborts. - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - /// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or /// llvm.frameaddress (depending on the value of the first argument). The /// return values are the result pointer and the resultant token chain. If diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index e5dd538eb45..933aa70e887 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1115,13 +1115,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { switch (TLI.getOperationAction(Node->getOpcode(), VT)) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Custom: { - SDOperand Op = DAG.getLoad(Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2)); + SDOperand Op = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2)); SDOperand Tmp = TLI.LowerOperation(Op, DAG); if (Tmp.Val) { Result = LegalizeOp(Tmp); - // Since loads produce two values, make sure to remember that we legalized - // both of them. + // Since loads produce two values, make sure to remember that we + // legalized both of them. AddLegalizedOperand(SDOperand(Node, 0), Result); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); @@ -1131,8 +1130,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2, - Node->getOperand(2)); + Result = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2)); else Result = SDOperand(Node, 0); @@ -2222,6 +2220,140 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; + case ISD::VAARG: { + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + MVT::ValueType VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); + else + Result = SDOperand(Node, 0); + break; + case TargetLowering::Expand: { + SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, + Node->getOperand(2)); + // Increment the pointer, VAList, to the next vaarg + Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, + DAG.getConstant(MVT::getSizeInBits(VT)/8, + TLI.getPointerTy())); + // Store the incremented VAList to the legalized pointer + Tmp3 = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), Tmp3, Tmp2, + Node->getOperand(2)); + // Load the actual argument out of the pointer VAList + Result = DAG.getLoad(VT, Tmp3, VAList, DAG.getSrcValue(0)); + Result = LegalizeOp(Result); + break; + } + } + // Since VAARG produces two values, make sure to remember that we + // legalized both of them. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + } + + case ISD::VACOPY: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the dest pointer. + Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the source pointer. + + switch (TLI.getOperationAction(ISD::VACOPY, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3, + Node->getOperand(3), Node->getOperand(4)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1) || + Tmp3 != Node->getOperand(2)) + Result = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3, + Node->getOperand(3), Node->getOperand(4)); + break; + case TargetLowering::Expand: + // This defaults to loading a pointer from the input and storing it to the + // output, returning the chain. + Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, Node->getOperand(3)); + Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp4.getValue(1), Tmp4, Tmp2, + Node->getOperand(4)); + Result = LegalizeOp(Result); + break; + } + break; + + case ISD::VAEND: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + switch (TLI.getOperationAction(ISD::VAEND, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + break; + case TargetLowering::Expand: + Result = Tmp1; // Default to a no-op, return the chain + break; + } + break; + + case ISD::VASTART: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + switch (TLI.getOperationAction(ISD::VASTART, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + break; + } + break; + case ISD::ROTL: case ISD::ROTR: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS @@ -3823,6 +3955,19 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ break; } + case ISD::VAARG: { + SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + Lo = DAG.getVAArg(NVT, Ch, Ptr, Node->getOperand(2)); + Hi = DAG.getVAArg(NVT, Lo.getValue(1), Ptr, Node->getOperand(2)); + + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), Hi.getValue(1)); + if (!TLI.isLittleEndian()) + std::swap(Lo, Hi); + break; + } + case ISD::LOAD: { SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain. SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ed96bd61ae2..d864042537f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1348,6 +1348,20 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { return SDOperand(N, 0); } +SDOperand SelectionDAG::getVAArg(MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, + SDOperand SV) { + std::vector Ops; + Ops.reserve(3); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(SV); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(ISD::VAARG, VTs, Ops); +} + SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, std::vector &Ops) { switch (Ops.size()) { @@ -2087,14 +2101,17 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::CALLSEQ_END: return "callseq_end"; // Other operators - case ISD::LOAD: return "load"; - case ISD::STORE: return "store"; - case ISD::VLOAD: return "vload"; - case ISD::EXTLOAD: return "extload"; - case ISD::SEXTLOAD: return "sextload"; - case ISD::ZEXTLOAD: return "zextload"; - case ISD::TRUNCSTORE: return "truncstore"; - + case ISD::LOAD: return "load"; + case ISD::STORE: return "store"; + case ISD::VLOAD: return "vload"; + case ISD::EXTLOAD: return "extload"; + case ISD::SEXTLOAD: return "sextload"; + case ISD::ZEXTLOAD: return "zextload"; + case ISD::TRUNCSTORE: return "truncstore"; + case ISD::VAARG: return "vaarg"; + case ISD::VACOPY: return "vacopy"; + case ISD::VAEND: return "vaend"; + case ISD::VASTART: return "vastart"; case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc"; case ISD::EXTRACT_ELEMENT: return "extract_element"; case ISD::BUILD_PAIR: return "build_pair"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 06a3b016de2..f75bdbeba7c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1204,71 +1204,34 @@ SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); } -SDOperand TargetLowering::LowerVAStart(SDOperand Chain, - SDOperand VAListP, Value *VAListV, - SelectionDAG &DAG) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments handling not implemented on this target!\n"; - abort(); - return SDOperand(); -} - -SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV, - SelectionDAG &DAG) { - // Default to a noop. - return Chain; -} - -SDOperand TargetLowering::LowerVACopy(SDOperand Chain, - SDOperand SrcP, Value *SrcV, - SDOperand DestP, Value *DestV, - SelectionDAG &DAG) { - // Default to copying the input list. - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, - SrcP, DAG.getSrcValue(SrcV)); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, DestP, DAG.getSrcValue(DestV)); - return Result; -} - -std::pair -TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments handling not implemented on this target!\n"; - abort(); - return std::make_pair(SDOperand(), SDOperand()); -} - - void SelectionDAGLowering::visitVAStart(CallInst &I) { - DAG.setRoot(TLI.LowerVAStart(getRoot(), getValue(I.getOperand(1)), - I.getOperand(1), DAG)); + DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(1)))); } void SelectionDAGLowering::visitVAArg(VAArgInst &I) { - std::pair Result = - TLI.LowerVAArg(getRoot(), getValue(I.getOperand(0)), I.getOperand(0), - I.getType(), DAG); - setValue(&I, Result.first); - DAG.setRoot(Result.second); + SDOperand V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(), + getValue(I.getOperand(0)), + DAG.getSrcValue(I.getOperand(0))); + setValue(&I, V); + DAG.setRoot(V.getValue(1)); } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), - I.getOperand(1), DAG)); + DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(1)))); } void SelectionDAGLowering::visitVACopy(CallInst &I) { - SDOperand Result = - TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), I.getOperand(2), - getValue(I.getOperand(1)), I.getOperand(1), DAG); - DAG.setRoot(Result); + DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)), + DAG.getSrcValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(2)))); } - // It is always conservatively correct for llvm.returnaddress and // llvm.frameaddress to return 0. std::pair diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 6f8226113c9..44b37c75fd7 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -368,79 +368,6 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, return std::make_pair(RetVal, Chain); } -SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart stores the address of the VarArgsBase and VarArgsOffset - SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); - SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); - SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, - DAG.getConstant(8, MVT::i64)); - return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, - DAG.getConstant(VarArgsOffset, MVT::i64), SA2, - DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32)); -} - -std::pair AlphaTargetLowering:: -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, - DAG.getSrcValue(VAListV)); - SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, - DAG.getConstant(8, MVT::i64)); - SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), - Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32); - SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); - if (ArgTy->isFloatingPoint()) - { - //if fp && Offset < 6*8, then subtract 6*8 from DataPtr - SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, - DAG.getConstant(8*6, MVT::i64)); - SDOperand CC = DAG.getSetCC(MVT::i64, Offset, - DAG.getConstant(8*6, MVT::i64), ISD::SETLT); - DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); - } - - SDOperand Result; - if (ArgTy == Type::IntTy) - Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1), - DataPtr, DAG.getSrcValue(NULL), MVT::i32); - else if (ArgTy == Type::UIntTy) - Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1), - DataPtr, DAG.getSrcValue(NULL), MVT::i32); - else - Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr, - DAG.getSrcValue(NULL)); - - SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, - DAG.getConstant(8, MVT::i64)); - SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, - Result.getValue(1), NewOffset, - Tmp, DAG.getSrcValue(VAListV, 8), - DAG.getValueType(MVT::i32)); - Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result); - - return std::make_pair(Result, Update); -} - -SDOperand AlphaTargetLowering:: -LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, - Value *DestV, SelectionDAG &DAG) { - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, - DAG.getSrcValue(SrcV)); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, DestP, DAG.getSrcValue(DestV)); - SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, - DAG.getConstant(8, MVT::i64)); - Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, - DAG.getSrcValue(SrcV, 8), MVT::i32); - SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, - DAG.getConstant(8, MVT::i64)); - return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), - Val, NPD, DAG.getSrcValue(DestV, 8), - DAG.getValueType(MVT::i32)); -} - void AlphaTargetLowering::restoreGP(MachineBasicBlock* BB) { BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); @@ -680,8 +607,77 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { ARGS.push_back(DAG.getConstant(getUID(), MVT::i64)); return DAG.getNode(Opc, VTS, ARGS); } + case ISD::VAARG: { + SDOperand Chain = Op.getOperand(0); + SDOperand VAListP = Op.getOperand(1); + SDOperand VAListS = Op.getOperand(2); + + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, + DAG.getConstant(8, MVT::i64)); + SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), + Tmp, DAG.getSrcValue(0), MVT::i32); + SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); + if (MVT::isFloatingPoint(Op.getValueType())) + { + //if fp && Offset < 6*8, then subtract 6*8 from DataPtr + SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, + DAG.getConstant(8*6, MVT::i64)); + SDOperand CC = DAG.getSetCC(MVT::i64, Offset, + DAG.getConstant(8*6, MVT::i64), ISD::SETLT); + DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); + } - + SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, + DAG.getConstant(8, MVT::i64)); + SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, + Offset.getValue(1), NewOffset, + Tmp, DAG.getSrcValue(0), + DAG.getValueType(MVT::i32)); + + SDOperand Result; + if (Op.getValueType() == MVT::i32) + Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Update, DataPtr, + DAG.getSrcValue(0), MVT::i32); + else + Result = DAG.getLoad(Op.getValueType(), Update, DataPtr, + DAG.getSrcValue(0)); + return Result; + } + case ISD::VACOPY: { + SDOperand Chain = Op.getOperand(0); + SDOperand DestP = Op.getOperand(1); + SDOperand SrcP = Op.getOperand(2); + SDOperand DestS = Op.getOperand(3); + SDOperand SrcS = Op.getOperand(4); + + SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SrcS); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val, + DestP, DestS); + SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, + DAG.getConstant(8, MVT::i64)); + Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, + DAG.getSrcValue(0), MVT::i32); + SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, + DAG.getConstant(8, MVT::i64)); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), + Val, NPD, DAG.getSrcValue(0),DAG.getValueType(MVT::i32)); + } + case ISD::VASTART: { + SDOperand Chain = Op.getOperand(0); + SDOperand VAListP = Op.getOperand(1); + SDOperand VAListS = Op.getOperand(2); + + // vastart stores the address of the VarArgsBase and VarArgsOffset + SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); + SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + VAListS); + SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, + DAG.getConstant(8, MVT::i64)); + return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, + DAG.getConstant(VarArgsOffset, MVT::i64), SA2, + DAG.getSrcValue(0), DAG.getValueType(MVT::i32)); + } } return SDOperand(); diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index 6b6db79a04e..aedaf395c6e 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -75,15 +75,6 @@ namespace llvm { bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, - SDOperand DestP, Value *DestV, - SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - void restoreGP(MachineBasicBlock* BB); void restoreRA(MachineBasicBlock* BB); unsigned getVRegGP() { return GP; } diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp index 91bd4e6f21f..c963bfc5a6a 100644 --- a/lib/Target/IA64/IA64ISelLowering.cpp +++ b/lib/Target/IA64/IA64ISelLowering.cpp @@ -89,6 +89,13 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM) setOperationAction(ISD::ROTR , MVT::i64 , Expand); setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VAARG , MVT::Other, Custom); + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); @@ -569,41 +576,6 @@ SDOperand IA64TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, // return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, MVT::Other, Copy, Chain, InFlag); } -SDOperand -IA64TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, - VAListP, DAG.getSrcValue(VAListV)); -} - -std::pair IA64TargetLowering:: -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i64, Chain, - VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val, - DAG.getSrcValue(NULL)); - unsigned Amt; - if (ArgVT == MVT::i32 || ArgVT == MVT::f32) - Amt = 8; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, - DAG.getConstant(Amt, Val.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - - - std::pair IA64TargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { @@ -631,5 +603,26 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { // and then just emit a 'ret' instruction return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain); } + case ISD::VAARG: { + MVT::ValueType VT = getPointerTy(); + SDOperand VAList = DAG.getLoad(VT, Op.getOperand(0), Op.getOperand(1), + Op.getOperand(2)); + // Increment the pointer, VAList, to the next vaarg + SDOperand VAIncr = DAG.getNode(ISD::ADD, VT, VAList, + DAG.getConstant(MVT::getSizeInBits(VT)/8, + VT)); + // Store the incremented VAList to the legalized pointer + VAIncr = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), VAIncr, + Op.getOperand(1), Op.getOperand(2)); + // Load the actual argument out of the pointer VAList + return DAG.getLoad(VT, VAIncr, VAList, DAG.getSrcValue(0)); + } + case ISD::VASTART: { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); + return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, + Op.getOperand(1), Op.getOperand(2)); + } } } diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h index a73bbaa7f14..bd63be15721 100644 --- a/lib/Target/IA64/IA64ISelLowering.h +++ b/lib/Target/IA64/IA64ISelLowering.h @@ -76,13 +76,6 @@ namespace llvm { /// (currently, only "ret void") virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 629b7cabf8c..df69a84acbc 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -110,7 +110,13 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); @@ -427,6 +433,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // resolution stub. return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); } + case ISD::VASTART: { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + // FIXME: Replace MVT::i32 with PointerTy + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, + Op.getOperand(1), Op.getOperand(2)); + } } return SDOperand(); } @@ -846,40 +860,6 @@ SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); } -SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot into the - // memory location argument. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); -} - -std::pair -PPCTargetLowering::LowerVAArg(SDOperand Chain, - SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - - SDOperand VAList = - DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL)); - 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; - } - VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(Amt, VAList.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - VAList, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - - std::pair PPCTargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 5e6fb43c02d..4be2b71a784 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -94,13 +94,6 @@ namespace llvm { virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 6fddeca4bac..c5b282db6ce 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -66,11 +66,6 @@ namespace { virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -161,9 +156,15 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); - // Expand these to their default code. - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); - setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); + setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); setSchedulingPreference(SchedulingForLatency); @@ -602,35 +603,6 @@ SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); } -SDOperand SparcV8TargetLowering:: -LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, - SelectionDAG &DAG) { - - SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getRegister(V8::I6, MVT::i32), - DAG.getConstant(VarArgsFrameOffset, MVT::i32)); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, Offset, - VAListP, DAG.getSrcValue(VAListV)); -} - -std::pair SparcV8TargetLowering:: -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - // Load the pointer out of the valist. - SDOperand Ptr = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(ArgVT, Ptr.getValue(1), - Ptr, DAG.getSrcValue(NULL)); - // Increment the pointer. - Ptr = DAG.getNode(ISD::ADD, MVT::i32, Ptr, - DAG.getConstant(MVT::getSizeInBits(ArgVT)/8, MVT::i32)); - // Store it back to the valist. - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Ptr, - VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Val, Chain); -} - std::pair SparcV8TargetLowering:: LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { @@ -714,6 +686,15 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, DAG.getConstant(CC, MVT::i32), CompareFlag); } + case ISD::VASTART: { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getRegister(V8::I6, MVT::i32), + DAG.getConstant(VarArgsFrameOffset, MVT::i32)); + return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, + Op.getOperand(1), Op.getOperand(2)); + } } } diff --git a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp index 6fddeca4bac..c5b282db6ce 100644 --- a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp +++ b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp @@ -66,11 +66,6 @@ namespace { virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -161,9 +156,15 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); - // Expand these to their default code. - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); - setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); + setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); setSchedulingPreference(SchedulingForLatency); @@ -602,35 +603,6 @@ SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); } -SDOperand SparcV8TargetLowering:: -LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, - SelectionDAG &DAG) { - - SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getRegister(V8::I6, MVT::i32), - DAG.getConstant(VarArgsFrameOffset, MVT::i32)); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, Offset, - VAListP, DAG.getSrcValue(VAListV)); -} - -std::pair SparcV8TargetLowering:: -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - // Load the pointer out of the valist. - SDOperand Ptr = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(ArgVT, Ptr.getValue(1), - Ptr, DAG.getSrcValue(NULL)); - // Increment the pointer. - Ptr = DAG.getNode(ISD::ADD, MVT::i32, Ptr, - DAG.getConstant(MVT::getSizeInBits(ArgVT)/8, MVT::i32)); - // Store it back to the valist. - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Ptr, - VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Val, Chain); -} - std::pair SparcV8TargetLowering:: LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { @@ -714,6 +686,15 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, DAG.getConstant(CC, MVT::i32), CompareFlag); } + case ISD::VASTART: { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getRegister(V8::I6, MVT::i32), + DAG.getConstant(VarArgsFrameOffset, MVT::i32)); + return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, + Op.getOperand(1), Op.getOperand(2)); + } } } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 04b9de348d1..cc713cf5ab8 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -169,7 +169,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); - // Expand to the default code. + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); @@ -641,40 +647,6 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, } } -SDOperand -X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); -} - - -std::pair -X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, - Value *VAListV, const Type *ArgTy, - SelectionDAG &DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, - DAG.getSrcValue(NULL)); - unsigned Amt; - if (ArgVT == MVT::i32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, - DAG.getConstant(Amt, Val.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - //===----------------------------------------------------------------------===// // Fast Calling Convention implementation //===----------------------------------------------------------------------===// @@ -1898,6 +1870,14 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { DAG.getSrcValue(NULL)); return Result; } + case ISD::VASTART: { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + // FIXME: Replace MVT::i32 with PointerTy + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, + Op.getOperand(1), Op.getOperand(2)); + } } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 1deb5f1304d..9c61bc8fb07 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -195,12 +195,6 @@ namespace llvm { virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG); - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG);