mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +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,
|
unsigned CallingConv, bool isTailCall, SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG) = 0;
|
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
|
/// 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
|
||||||
|
@ -496,40 +496,30 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
|
|||||||
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot()));
|
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot()));
|
||||||
return;
|
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));
|
if (I.getOperand(i)->getType()->isSigned())
|
||||||
MVT::ValueType TmpVT;
|
RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp);
|
||||||
|
else
|
||||||
switch (Op1.getValueType()) {
|
RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp);
|
||||||
default: assert(0 && "Unknown value type!");
|
}
|
||||||
case MVT::i1:
|
NewValues.push_back(RetOp);
|
||||||
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!
|
|
||||||
}
|
}
|
||||||
// Allow targets to lower this further to meet ABI requirements
|
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues));
|
||||||
DAG.setRoot(TLI.LowerReturnTo(getRoot(), Op1, DAG));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitBr(BranchInst &I) {
|
void SelectionDAGLowering::visitBr(BranchInst &I) {
|
||||||
@ -1249,11 +1239,6 @@ MachineBasicBlock *TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
|||||||
return 0;
|
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) {
|
void SelectionDAGLowering::visitVAStart(CallInst &I) {
|
||||||
DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
|
DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
|
||||||
getValue(I.getOperand(1)),
|
getValue(I.getOperand(1)),
|
||||||
|
@ -537,44 +537,6 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
|||||||
return std::make_pair(RetVal, 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::
|
std::pair<SDOperand, SDOperand> IA64TargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
@ -586,21 +548,38 @@ SDOperand IA64TargetLowering::
|
|||||||
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
switch (Op.getOpcode()) {
|
switch (Op.getOpcode()) {
|
||||||
default: assert(0 && "Should not custom lower this!");
|
default: assert(0 && "Should not custom lower this!");
|
||||||
case ISD::RET: { // the DAGgy stuff takes care of
|
case ISD::RET: {
|
||||||
// restoring ar.pfs before adding a br.ret for functions
|
SDOperand AR_PFSVal, Copy;
|
||||||
// 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)");
|
|
||||||
|
|
||||||
SDOperand Chain = Op.getOperand(0);
|
switch(Op.getNumOperands()) {
|
||||||
SDOperand AR_PFSVal = DAG.getCopyFromReg(Chain, this->VirtGPR,
|
default:
|
||||||
MVT::i64);
|
assert(0 && "Do not know how to return this many arguments!");
|
||||||
Chain = AR_PFSVal.getValue(1);
|
abort();
|
||||||
Chain = DAG.getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal);
|
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
|
AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), VirtGPR, MVT::i64);
|
||||||
return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain);
|
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: {
|
case ISD::VAARG: {
|
||||||
MVT::ValueType VT = getPointerTy();
|
MVT::ValueType VT = getPointerTy();
|
||||||
|
@ -48,10 +48,6 @@ namespace llvm {
|
|||||||
unsigned VirtGPR; // this is public so it can be accessed in the selector
|
unsigned VirtGPR; // this is public so it can be accessed in the selector
|
||||||
// for ISD::RET. add an accessor instead? FIXME
|
// 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;
|
const char *getTargetNodeName(unsigned Opcode) const;
|
||||||
|
|
||||||
/// LowerArguments - This hook must be implemented to indicate how we should
|
/// LowerArguments - This hook must be implemented to indicate how we should
|
||||||
@ -67,11 +63,6 @@ namespace llvm {
|
|||||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
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
|
/// LowerOperation - for custom lowering specific ops
|
||||||
/// (currently, only "ret void")
|
/// (currently, only "ret void")
|
||||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
@ -110,6 +110,9 @@ 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);
|
||||||
|
|
||||||
|
// 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
|
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
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,
|
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
|
||||||
Op.getOperand(1), Op.getOperand(2));
|
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();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
@ -835,30 +862,6 @@ PPCTargetLowering::LowerCallTo(SDOperand Chain,
|
|||||||
return std::make_pair(RetVal, 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::
|
std::pair<SDOperand, SDOperand> PPCTargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
|
@ -91,9 +91,6 @@ namespace llvm {
|
|||||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|
||||||
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);
|
||||||
|
@ -63,9 +63,6 @@ namespace {
|
|||||||
unsigned CC,
|
unsigned CC,
|
||||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|
||||||
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);
|
||||||
@ -156,6 +153,9 @@ 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);
|
||||||
|
|
||||||
|
// 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
|
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||||
|
|
||||||
@ -576,32 +576,6 @@ SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
return std::make_pair(RetVal, Chain);
|
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::
|
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
@ -694,6 +668,35 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
||||||
Op.getOperand(1), Op.getOperand(2));
|
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,
|
unsigned CC,
|
||||||
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|
||||||
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);
|
||||||
@ -156,6 +153,9 @@ 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);
|
||||||
|
|
||||||
|
// 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
|
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
|
||||||
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
setOperationAction(ISD::VASTART , MVT::Other, Custom);
|
||||||
|
|
||||||
@ -576,32 +576,6 @@ SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
return std::make_pair(RetVal, Chain);
|
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::
|
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
@ -694,6 +668,35 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset,
|
||||||
Op.getOperand(1), Op.getOperand(2));
|
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);
|
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
|
// C Calling Convention implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1766,11 +1703,6 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
|
||||||
Op.getOperand(0), Op.getOperand(2), CC, Cond);
|
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: {
|
case ISD::MEMSET: {
|
||||||
SDOperand InFlag;
|
SDOperand InFlag;
|
||||||
SDOperand Chain = Op.getOperand(0);
|
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,
|
return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
|
||||||
Op.getOperand(1), Op.getOperand(2));
|
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,
|
bool isTailCall, SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG);
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
|
|
||||||
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
Block a user