forked from OSchip/llvm-project
First part of bug 680:
Remove TLI.LowerVA* and replace it with SDNodes that are lowered the same way as everything else. llvm-svn: 25606
This commit is contained in:
parent
c3cafb8a67
commit
e74795cd70
|
@ -278,6 +278,11 @@ public:
|
||||||
Ops.push_back(False);
|
Ops.push_back(False);
|
||||||
return getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
|
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
|
/// 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.
|
/// determined by their operands, and they produce a value AND a token chain.
|
||||||
|
|
|
@ -335,6 +335,19 @@ namespace ISD {
|
||||||
// target and not touched by the DAG optimizers.
|
// target and not touched by the DAG optimizers.
|
||||||
CALLSEQ_START, // Beginning of a call sequence
|
CALLSEQ_START, // Beginning of a call sequence
|
||||||
CALLSEQ_END, // End 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
|
// SRCVALUE - This corresponds to a Value*, and is used to associate memory
|
||||||
// locations with their value. This allows one use alias analysis
|
// locations with their value. This allows one use alias analysis
|
||||||
|
|
|
@ -366,31 +366,6 @@ public:
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||||
SelectionDAG &DAG);
|
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<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
/// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or
|
/// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or
|
||||||
/// llvm.frameaddress (depending on the value of the first argument). The
|
/// llvm.frameaddress (depending on the value of the first argument). The
|
||||||
/// return values are the result pointer and the resultant token chain. If
|
/// return values are the result pointer and the resultant token chain. If
|
||||||
|
|
|
@ -1115,13 +1115,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
|
switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
|
||||||
default: assert(0 && "This action is not supported yet!");
|
default: assert(0 && "This action is not supported yet!");
|
||||||
case TargetLowering::Custom: {
|
case TargetLowering::Custom: {
|
||||||
SDOperand Op = DAG.getLoad(Node->getValueType(0),
|
SDOperand Op = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2));
|
||||||
Tmp1, Tmp2, Node->getOperand(2));
|
|
||||||
SDOperand Tmp = TLI.LowerOperation(Op, DAG);
|
SDOperand Tmp = TLI.LowerOperation(Op, DAG);
|
||||||
if (Tmp.Val) {
|
if (Tmp.Val) {
|
||||||
Result = LegalizeOp(Tmp);
|
Result = LegalizeOp(Tmp);
|
||||||
// Since loads produce two values, make sure to remember that we legalized
|
// Since loads produce two values, make sure to remember that we
|
||||||
// both of them.
|
// legalized both of them.
|
||||||
AddLegalizedOperand(SDOperand(Node, 0), Result);
|
AddLegalizedOperand(SDOperand(Node, 0), Result);
|
||||||
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
||||||
return Result.getValue(Op.ResNo);
|
return Result.getValue(Op.ResNo);
|
||||||
|
@ -1131,8 +1130,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
case TargetLowering::Legal:
|
case TargetLowering::Legal:
|
||||||
if (Tmp1 != Node->getOperand(0) ||
|
if (Tmp1 != Node->getOperand(0) ||
|
||||||
Tmp2 != Node->getOperand(1))
|
Tmp2 != Node->getOperand(1))
|
||||||
Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2,
|
Result = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2));
|
||||||
Node->getOperand(2));
|
|
||||||
else
|
else
|
||||||
Result = SDOperand(Node, 0);
|
Result = SDOperand(Node, 0);
|
||||||
|
|
||||||
|
@ -2222,6 +2220,140 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
}
|
}
|
||||||
break;
|
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::ROTL:
|
||||||
case ISD::ROTR:
|
case ISD::ROTR:
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
||||||
|
@ -3823,6 +3955,19 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||||
break;
|
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: {
|
case ISD::LOAD: {
|
||||||
SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||||
SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||||
|
|
|
@ -1348,6 +1348,20 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
|
||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand SelectionDAG::getVAArg(MVT::ValueType VT,
|
||||||
|
SDOperand Chain, SDOperand Ptr,
|
||||||
|
SDOperand SV) {
|
||||||
|
std::vector<SDOperand> Ops;
|
||||||
|
Ops.reserve(3);
|
||||||
|
Ops.push_back(Chain);
|
||||||
|
Ops.push_back(Ptr);
|
||||||
|
Ops.push_back(SV);
|
||||||
|
std::vector<MVT::ValueType> 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,
|
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||||
std::vector<SDOperand> &Ops) {
|
std::vector<SDOperand> &Ops) {
|
||||||
switch (Ops.size()) {
|
switch (Ops.size()) {
|
||||||
|
@ -2087,14 +2101,17 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
||||||
case ISD::CALLSEQ_END: return "callseq_end";
|
case ISD::CALLSEQ_END: return "callseq_end";
|
||||||
|
|
||||||
// Other operators
|
// Other operators
|
||||||
case ISD::LOAD: return "load";
|
case ISD::LOAD: return "load";
|
||||||
case ISD::STORE: return "store";
|
case ISD::STORE: return "store";
|
||||||
case ISD::VLOAD: return "vload";
|
case ISD::VLOAD: return "vload";
|
||||||
case ISD::EXTLOAD: return "extload";
|
case ISD::EXTLOAD: return "extload";
|
||||||
case ISD::SEXTLOAD: return "sextload";
|
case ISD::SEXTLOAD: return "sextload";
|
||||||
case ISD::ZEXTLOAD: return "zextload";
|
case ISD::ZEXTLOAD: return "zextload";
|
||||||
case ISD::TRUNCSTORE: return "truncstore";
|
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::DYNAMIC_STACKALLOC: return "dynamic_stackalloc";
|
||||||
case ISD::EXTRACT_ELEMENT: return "extract_element";
|
case ISD::EXTRACT_ELEMENT: return "extract_element";
|
||||||
case ISD::BUILD_PAIR: return "build_pair";
|
case ISD::BUILD_PAIR: return "build_pair";
|
||||||
|
|
|
@ -1204,71 +1204,34 @@ SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||||
return DAG.getNode(ISD::RET, MVT::Other, Chain, 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<SDOperand,SDOperand>
|
|
||||||
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) {
|
void SelectionDAGLowering::visitVAStart(CallInst &I) {
|
||||||
DAG.setRoot(TLI.LowerVAStart(getRoot(), getValue(I.getOperand(1)),
|
DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
|
||||||
I.getOperand(1), DAG));
|
getValue(I.getOperand(1)),
|
||||||
|
DAG.getSrcValue(I.getOperand(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
|
void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
|
||||||
std::pair<SDOperand,SDOperand> Result =
|
SDOperand V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(),
|
||||||
TLI.LowerVAArg(getRoot(), getValue(I.getOperand(0)), I.getOperand(0),
|
getValue(I.getOperand(0)),
|
||||||
I.getType(), DAG);
|
DAG.getSrcValue(I.getOperand(0)));
|
||||||
setValue(&I, Result.first);
|
setValue(&I, V);
|
||||||
DAG.setRoot(Result.second);
|
DAG.setRoot(V.getValue(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitVAEnd(CallInst &I) {
|
void SelectionDAGLowering::visitVAEnd(CallInst &I) {
|
||||||
DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)),
|
DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(),
|
||||||
I.getOperand(1), DAG));
|
getValue(I.getOperand(1)),
|
||||||
|
DAG.getSrcValue(I.getOperand(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitVACopy(CallInst &I) {
|
void SelectionDAGLowering::visitVACopy(CallInst &I) {
|
||||||
SDOperand Result =
|
DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(),
|
||||||
TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), I.getOperand(2),
|
getValue(I.getOperand(1)),
|
||||||
getValue(I.getOperand(1)), I.getOperand(1), DAG);
|
getValue(I.getOperand(2)),
|
||||||
DAG.setRoot(Result);
|
DAG.getSrcValue(I.getOperand(1)),
|
||||||
|
DAG.getSrcValue(I.getOperand(2))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// It is always conservatively correct for llvm.returnaddress and
|
// It is always conservatively correct for llvm.returnaddress and
|
||||||
// llvm.frameaddress to return 0.
|
// llvm.frameaddress to return 0.
|
||||||
std::pair<SDOperand, SDOperand>
|
std::pair<SDOperand, SDOperand>
|
||||||
|
|
|
@ -368,79 +368,6 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
|
||||||
return std::make_pair(RetVal, 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<SDOperand,SDOperand> 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)
|
void AlphaTargetLowering::restoreGP(MachineBasicBlock* BB)
|
||||||
{
|
{
|
||||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
|
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));
|
ARGS.push_back(DAG.getConstant(getUID(), MVT::i64));
|
||||||
return DAG.getNode(Opc, VTS, ARGS);
|
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();
|
return SDOperand();
|
||||||
|
|
|
@ -75,15 +75,6 @@ namespace llvm {
|
||||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
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<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
void restoreGP(MachineBasicBlock* BB);
|
void restoreGP(MachineBasicBlock* BB);
|
||||||
void restoreRA(MachineBasicBlock* BB);
|
void restoreRA(MachineBasicBlock* BB);
|
||||||
unsigned getVRegGP() { return GP; }
|
unsigned getVRegGP() { return GP; }
|
||||||
|
|
|
@ -89,6 +89,13 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
|
||||||
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
|
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
|
||||||
setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
|
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::STACKSAVE, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, 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);
|
// 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<SDOperand,SDOperand> 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<SDOperand, SDOperand> IA64TargetLowering::
|
std::pair<SDOperand, SDOperand> IA64TargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
|
@ -631,5 +603,26 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
// and then just emit a 'ret' instruction
|
// and then just emit a 'ret' instruction
|
||||||
return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,13 +76,6 @@ namespace llvm {
|
||||||
/// (currently, only "ret void")
|
/// (currently, only "ret void")
|
||||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
|
|
||||||
Value *VAListV, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual std::pair<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
|
@ -110,7 +110,13 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::ConstantPool, 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.
|
// 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::STACKSAVE , MVT::Other, Expand);
|
||||||
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
|
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
|
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
|
||||||
|
@ -427,6 +433,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
// resolution stub.
|
// resolution stub.
|
||||||
return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0));
|
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();
|
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));
|
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<SDOperand,SDOperand>
|
|
||||||
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<SDOperand, SDOperand> PPCTargetLowering::
|
std::pair<SDOperand, SDOperand> PPCTargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
|
|
|
@ -94,13 +94,6 @@ namespace llvm {
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
|
|
||||||
Value *VAListV, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual std::pair<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
|
@ -66,11 +66,6 @@ namespace {
|
||||||
|
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
|
|
||||||
Value *VAListV, SelectionDAG &DAG);
|
|
||||||
virtual std::pair<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
@ -161,9 +156,15 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
|
setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
|
||||||
|
|
||||||
// Expand these to their default code.
|
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
|
||||||
|
// 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);
|
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
|
||||||
|
|
||||||
setSchedulingPreference(SchedulingForLatency);
|
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));
|
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<SDOperand,SDOperand> 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<SDOperand, SDOperand> SparcV8TargetLowering::
|
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
|
@ -714,6 +686,15 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal,
|
return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal,
|
||||||
DAG.getConstant(CC, MVT::i32), CompareFlag);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LABEL, 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::STACKSAVE, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , 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<SDOperand,SDOperand>
|
|
||||||
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
|
// Fast Calling Convention implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1898,6 +1870,14 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
DAG.getSrcValue(NULL));
|
DAG.getSrcValue(NULL));
|
||||||
return Result;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,12 +195,6 @@ namespace llvm {
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
|
|
||||||
Value *VAListV, SelectionDAG &DAG);
|
|
||||||
virtual std::pair<SDOperand,SDOperand>
|
|
||||||
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
|
|
||||||
const Type *ArgTy, SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
Loading…
Reference in New Issue