mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 09:54:09 +00:00
Remove TLI.LowerReturnTo, and just let targets custom lower ISD::RET for
the same functionality. This addresses another piece of bug 680. Next, on to fixing Alpha VAARG, which I broke last time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25696 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
da427fa5da
commit
ee625573b5
@ -360,12 +360,6 @@ public:
|
||||
unsigned CallingConv, bool isTailCall, SDOperand Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG) = 0;
|
||||
|
||||
/// LowerReturnTo - This hook lowers a return instruction into the appropriate
|
||||
/// legal ISD::RET node for the target's current ABI. This method is optional
|
||||
/// and is intended for targets that need non-standard behavior.
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
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
|
||||
|
@ -496,40 +496,30 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
|
||||
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot()));
|
||||
return;
|
||||
}
|
||||
std::vector<SDOperand> NewValues;
|
||||
NewValues.push_back(getRoot());
|
||||
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
|
||||
SDOperand RetOp = getValue(I.getOperand(i));
|
||||
|
||||
// If this is an integer return value, we need to promote it ourselves to
|
||||
// the full width of a register, since LegalizeOp will use ANY_EXTEND rather
|
||||
// than sign/zero.
|
||||
if (MVT::isInteger(RetOp.getValueType()) &&
|
||||
RetOp.getValueType() < MVT::i64) {
|
||||
MVT::ValueType TmpVT;
|
||||
if (TLI.getTypeAction(MVT::i32) == TargetLowering::Promote)
|
||||
TmpVT = TLI.getTypeToTransformTo(MVT::i32);
|
||||
else
|
||||
TmpVT = MVT::i32;
|
||||
|
||||
SDOperand Op1 = getValue(I.getOperand(0));
|
||||
MVT::ValueType TmpVT;
|
||||
|
||||
switch (Op1.getValueType()) {
|
||||
default: assert(0 && "Unknown value type!");
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
case MVT::i16:
|
||||
case MVT::i32:
|
||||
// If this is a machine where 32-bits is legal or expanded, promote to
|
||||
// 32-bits, otherwise, promote to 64-bits.
|
||||
if (TLI.getTypeAction(MVT::i32) == TargetLowering::Promote)
|
||||
TmpVT = TLI.getTypeToTransformTo(MVT::i32);
|
||||
else
|
||||
TmpVT = MVT::i32;
|
||||
|
||||
// Extend integer types to result type.
|
||||
if (I.getOperand(0)->getType()->isSigned())
|
||||
Op1 = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, Op1);
|
||||
else
|
||||
Op1 = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, Op1);
|
||||
break;
|
||||
case MVT::f32:
|
||||
// If this is a machine where f32 is promoted to f64, do so now.
|
||||
if (TLI.getTypeAction(MVT::f32) == TargetLowering::Promote)
|
||||
Op1 = DAG.getNode(ISD::FP_EXTEND, TLI.getTypeToTransformTo(MVT::f32),Op1);
|
||||
break;
|
||||
case MVT::i64:
|
||||
case MVT::f64:
|
||||
break; // No extension needed!
|
||||
if (I.getOperand(i)->getType()->isSigned())
|
||||
RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp);
|
||||
else
|
||||
RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp);
|
||||
}
|
||||
NewValues.push_back(RetOp);
|
||||
}
|
||||
// Allow targets to lower this further to meet ABI requirements
|
||||
DAG.setRoot(TLI.LowerReturnTo(getRoot(), Op1, DAG));
|
||||
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues));
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitBr(BranchInst &I) {
|
||||
@ -1249,11 +1239,6 @@ MachineBasicBlock *TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitVAStart(CallInst &I) {
|
||||
DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
|
||||
getValue(I.getOperand(1)),
|
||||
|
@ -537,44 +537,6 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
||||
return std::make_pair(RetVal, Chain);
|
||||
}
|
||||
|
||||
SDOperand IA64TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
SDOperand Copy, InFlag;
|
||||
SDOperand AR_PFSVal = DAG.getCopyFromReg(Chain, this->VirtGPR,
|
||||
MVT::i64);
|
||||
Chain = AR_PFSVal.getValue(1);
|
||||
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unknown type to return! (promote?)");
|
||||
case MVT::i64:
|
||||
Copy = DAG.getCopyToReg(Chain, IA64::r8, Op, InFlag);
|
||||
break;
|
||||
case MVT::f64:
|
||||
Copy = DAG.getCopyToReg(Chain, IA64::F8, Op, InFlag);
|
||||
break;
|
||||
}
|
||||
|
||||
Chain = Copy.getValue(0);
|
||||
InFlag = Copy.getValue(1);
|
||||
// we need to copy VirtGPR (the vreg (to become a real reg)) that holds
|
||||
// the output of this function's alloc instruction back into ar.pfs
|
||||
// before we return. this copy must not float up above the last
|
||||
// outgoing call in this function - we flag this to the ret instruction
|
||||
Chain = DAG.getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// and then just emit a 'ret' instruction
|
||||
std::vector<MVT::ValueType> NodeTys;
|
||||
std::vector<SDOperand> RetOperands;
|
||||
NodeTys.push_back(MVT::Other);
|
||||
NodeTys.push_back(MVT::Flag);
|
||||
RetOperands.push_back(Chain);
|
||||
RetOperands.push_back(InFlag);
|
||||
|
||||
return DAG.getNode(IA64ISD::RET_FLAG, NodeTys, RetOperands);
|
||||
// return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, MVT::Other, Copy, Chain, InFlag);
|
||||
}
|
||||
|
||||
std::pair<SDOperand, SDOperand> IA64TargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
@ -586,21 +548,38 @@ SDOperand IA64TargetLowering::
|
||||
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
default: assert(0 && "Should not custom lower this!");
|
||||
case ISD::RET: { // the DAGgy stuff takes care of
|
||||
// restoring ar.pfs before adding a br.ret for functions
|
||||
// that return something, but we need to take care of stuff
|
||||
// that returns void manually, so here it is:
|
||||
assert(Op.getNumOperands()==1 &&
|
||||
"trying to custom lower a return other than void! (numops!=1)");
|
||||
case ISD::RET: {
|
||||
SDOperand AR_PFSVal, Copy;
|
||||
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand AR_PFSVal = DAG.getCopyFromReg(Chain, this->VirtGPR,
|
||||
MVT::i64);
|
||||
Chain = AR_PFSVal.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal);
|
||||
switch(Op.getNumOperands()) {
|
||||
default:
|
||||
assert(0 && "Do not know how to return this many arguments!");
|
||||
abort();
|
||||
case 1:
|
||||
AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), VirtGPR, MVT::i64);
|
||||
AR_PFSVal = DAG.getCopyToReg(AR_PFSVal.getValue(1), IA64::AR_PFS,
|
||||
AR_PFSVal);
|
||||
return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, AR_PFSVal);
|
||||
case 2: {
|
||||
// Copy the result into the output register & restore ar.pfs
|
||||
MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
|
||||
unsigned ArgReg = MVT::isInteger(ArgVT) ? IA64::r8 : IA64::F8;
|
||||
|
||||
// and then just emit a 'ret' instruction
|
||||
return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain);
|
||||
AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), VirtGPR, MVT::i64);
|
||||
Copy = DAG.getCopyToReg(AR_PFSVal.getValue(1), ArgReg, Op.getOperand(1),
|
||||
SDOperand());
|
||||
AR_PFSVal = DAG.getCopyToReg(Copy.getValue(0), IA64::AR_PFS, AR_PFSVal,
|
||||
Copy.getValue(1));
|
||||
std::vector<MVT::ValueType> NodeTys;
|
||||
std::vector<SDOperand> RetOperands;
|
||||
NodeTys.push_back(MVT::Other);
|
||||
NodeTys.push_back(MVT::Flag);
|
||||
RetOperands.push_back(AR_PFSVal);
|
||||
RetOperands.push_back(AR_PFSVal.getValue(1));
|
||||
return DAG.getNode(IA64ISD::RET_FLAG, NodeTys, RetOperands);
|
||||
}
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
case ISD::VAARG: {
|
||||
MVT::ValueType VT = getPointerTy();
|
||||
|
@ -48,10 +48,6 @@ namespace llvm {
|
||||
unsigned VirtGPR; // this is public so it can be accessed in the selector
|
||||
// for ISD::RET. add an accessor instead? FIXME
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
// XXX virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||
|
||||
const char *getTargetNodeName(unsigned Opcode) const;
|
||||
|
||||
/// LowerArguments - This hook must be implemented to indicate how we should
|
||||
@ -67,11 +63,6 @@ namespace llvm {
|
||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// LowerReturnTo - This spits out restore-previous-frame-state+br.ret
|
||||
/// instructions
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// LowerOperation - for custom lowering specific ops
|
||||
/// (currently, only "ret void")
|
||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||
|
@ -110,6 +110,9 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
||||
|
||||
// RET must be custom lowered, to meet ABI requirements
|
||||
setOperationAction(ISD::RET , MVT::Other, Custom);
|
||||
|
||||
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||
|
||||
@ -440,6 +443,30 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
|
||||
Op.getOperand(1), Op.getOperand(2));
|
||||
}
|
||||
case ISD::RET: {
|
||||
SDOperand Copy;
|
||||
|
||||
switch(Op.getNumOperands()) {
|
||||
default:
|
||||
assert(0 && "Do not know how to return this many arguments!");
|
||||
abort();
|
||||
case 1:
|
||||
return SDOperand(); // ret void is legal
|
||||
case 2: {
|
||||
MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
|
||||
unsigned ArgReg = MVT::isInteger(ArgVT) ? PPC::R3 : PPC::F1;
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1),
|
||||
SDOperand());
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(2),
|
||||
SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
@ -835,30 +862,6 @@ PPCTargetLowering::LowerCallTo(SDOperand Chain,
|
||||
return std::make_pair(RetVal, Chain);
|
||||
}
|
||||
|
||||
SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
SDOperand Copy;
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32:
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::R3, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::F1, Op, SDOperand());
|
||||
break;
|
||||
case MVT::i64:
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::R3, Hi, SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, PPC::R4, Lo, Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
|
||||
std::pair<SDOperand, SDOperand> PPCTargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
|
@ -91,9 +91,6 @@ namespace llvm {
|
||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
@ -63,9 +63,6 @@ namespace {
|
||||
unsigned CC,
|
||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG);
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
@ -156,6 +153,9 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
|
||||
|
||||
// RET must be custom lowered, to meet ABI requirements
|
||||
setOperationAction(ISD::RET , MVT::Other, Custom);
|
||||
|
||||
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||
|
||||
@ -576,32 +576,6 @@ SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||
return std::make_pair(RetVal, Chain);
|
||||
}
|
||||
|
||||
SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
SDOperand Copy;
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::I0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f32:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::F0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f64:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::D0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::i64:
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
Copy = DAG.getCopyToReg(Chain, V8::I0, Hi, SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, V8::I1, Lo, Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
|
||||
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
@ -694,6 +668,35 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
||||
Op.getOperand(1), Op.getOperand(2));
|
||||
}
|
||||
case ISD::RET: {
|
||||
SDOperand Copy;
|
||||
|
||||
switch(Op.getNumOperands()) {
|
||||
default:
|
||||
assert(0 && "Do not know how to return this many arguments!");
|
||||
abort();
|
||||
case 1:
|
||||
return SDOperand(); // ret void is legal
|
||||
case 2: {
|
||||
unsigned ArgReg;
|
||||
switch(Op.getOperand(1).getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32: ArgReg = V8::I0; break;
|
||||
case MVT::f32: ArgReg = V8::F0; break;
|
||||
case MVT::f64: ArgReg = V8::D0; break;
|
||||
}
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1),
|
||||
SDOperand());
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), V8::I0, Op.getOperand(2),
|
||||
SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, V8::I1, Op.getOperand(1), Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,9 +63,6 @@ namespace {
|
||||
unsigned CC,
|
||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG);
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
@ -156,6 +153,9 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
|
||||
|
||||
// RET must be custom lowered, to meet ABI requirements
|
||||
setOperationAction(ISD::RET , MVT::Other, Custom);
|
||||
|
||||
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||
|
||||
@ -576,32 +576,6 @@ SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||
return std::make_pair(RetVal, Chain);
|
||||
}
|
||||
|
||||
SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
SDOperand Copy;
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::I0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f32:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::F0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f64:
|
||||
Copy = DAG.getCopyToReg(Chain, V8::D0, Op, SDOperand());
|
||||
break;
|
||||
case MVT::i64:
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
Copy = DAG.getCopyToReg(Chain, V8::I0, Hi, SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, V8::I1, Lo, Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
|
||||
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG) {
|
||||
@ -694,6 +668,35 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
||||
Op.getOperand(1), Op.getOperand(2));
|
||||
}
|
||||
case ISD::RET: {
|
||||
SDOperand Copy;
|
||||
|
||||
switch(Op.getNumOperands()) {
|
||||
default:
|
||||
assert(0 && "Do not know how to return this many arguments!");
|
||||
abort();
|
||||
case 1:
|
||||
return SDOperand(); // ret void is legal
|
||||
case 2: {
|
||||
unsigned ArgReg;
|
||||
switch(Op.getOperand(1).getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32: ArgReg = V8::I0; break;
|
||||
case MVT::f32: ArgReg = V8::F0; break;
|
||||
case MVT::f64: ArgReg = V8::D0; break;
|
||||
}
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1),
|
||||
SDOperand());
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), V8::I0, Op.getOperand(2),
|
||||
SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, V8::I1, Op.getOperand(1), Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,69 +269,6 @@ X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||
return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG);
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
if (!X86DAGIsel)
|
||||
return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
|
||||
|
||||
SDOperand Copy;
|
||||
MVT::ValueType OpVT = Op.getValueType();
|
||||
switch (OpVT) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32:
|
||||
Copy = DAG.getCopyToReg(Chain, X86::EAX, Op, SDOperand());
|
||||
break;
|
||||
case MVT::i64: {
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
Copy = DAG.getCopyToReg(Chain, X86::EDX, Hi, SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, X86::EAX, Lo, Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
if (!X86ScalarSSE) {
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(MVT::Other);
|
||||
Tys.push_back(MVT::Flag);
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(Op);
|
||||
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
||||
} else {
|
||||
// Spill the value to memory and reload it into top of stack.
|
||||
unsigned Size = MVT::getSizeInBits(OpVT)/8;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
|
||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||
Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Op,
|
||||
StackSlot, DAG.getSrcValue(NULL));
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(MVT::f64);
|
||||
Tys.push_back(MVT::Other);
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(StackSlot);
|
||||
Ops.push_back(DAG.getValueType(OpVT));
|
||||
Copy = DAG.getNode(X86ISD::FLD, Tys, Ops);
|
||||
Tys.clear();
|
||||
Tys.push_back(MVT::Other);
|
||||
Tys.push_back(MVT::Flag);
|
||||
Ops.clear();
|
||||
Ops.push_back(Copy.getValue(1));
|
||||
Ops.push_back(Copy);
|
||||
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DAG.getNode(X86ISD::RET_FLAG, MVT::Other,
|
||||
Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16),
|
||||
Copy.getValue(1));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// C Calling Convention implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1766,11 +1703,6 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
||||
Op.getOperand(0), Op.getOperand(2), CC, Cond);
|
||||
}
|
||||
case ISD::RET: {
|
||||
// Can only be return void.
|
||||
return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
|
||||
DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
|
||||
}
|
||||
case ISD::MEMSET: {
|
||||
SDOperand InFlag;
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
@ -1897,6 +1829,66 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
|
||||
Op.getOperand(1), Op.getOperand(2));
|
||||
}
|
||||
case ISD::RET: {
|
||||
SDOperand Copy;
|
||||
|
||||
switch(Op.getNumOperands()) {
|
||||
default:
|
||||
assert(0 && "Do not know how to return this many arguments!");
|
||||
abort();
|
||||
case 1:
|
||||
return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
|
||||
DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
|
||||
case 2: {
|
||||
MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
|
||||
if (MVT::isInteger(ArgVT))
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), X86::EAX, Op.getOperand(1),
|
||||
SDOperand());
|
||||
else if (!X86ScalarSSE) {
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(MVT::Other);
|
||||
Tys.push_back(MVT::Flag);
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Op.getOperand(0));
|
||||
Ops.push_back(Op.getOperand(1));
|
||||
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
||||
} else {
|
||||
// Spill the value to memory and reload it into top of stack.
|
||||
unsigned Size = MVT::getSizeInBits(ArgVT)/8;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
|
||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||
SDOperand Chain = DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0),
|
||||
Op.getOperand(1), StackSlot,
|
||||
DAG.getSrcValue(0));
|
||||
std::vector<MVT::ValueType> Tys;
|
||||
Tys.push_back(MVT::f64);
|
||||
Tys.push_back(MVT::Other);
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(StackSlot);
|
||||
Ops.push_back(DAG.getValueType(ArgVT));
|
||||
Copy = DAG.getNode(X86ISD::FLD, Tys, Ops);
|
||||
Tys.clear();
|
||||
Tys.push_back(MVT::Other);
|
||||
Tys.push_back(MVT::Flag);
|
||||
Ops.clear();
|
||||
Ops.push_back(Copy.getValue(1));
|
||||
Ops.push_back(Copy);
|
||||
Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
Copy = DAG.getCopyToReg(Op.getOperand(0), X86::EDX, Op.getOperand(2),
|
||||
SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, X86::EAX,Op.getOperand(1),Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(X86ISD::RET_FLAG, MVT::Other,
|
||||
Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16),
|
||||
Copy.getValue(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,9 +193,6 @@ namespace llvm {
|
||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
Loading…
Reference in New Issue
Block a user