mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Finish off bug 680, allowing targets to custom lower frame and return
address nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33636 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1f259e9d7a
commit
bcc5f36765
@ -84,6 +84,13 @@ namespace ISD {
|
|||||||
|
|
||||||
// The address of the GOT
|
// The address of the GOT
|
||||||
GLOBAL_OFFSET_TABLE,
|
GLOBAL_OFFSET_TABLE,
|
||||||
|
|
||||||
|
// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
|
||||||
|
// llvm.returnaddress on the DAG. These nodes take one operand, the index
|
||||||
|
// of the frame or return address to return. An index of zero corresponds
|
||||||
|
// to the current function's frame or return address, an index of one to the
|
||||||
|
// parent's frame or return address, and so on.
|
||||||
|
FRAMEADDR, RETURNADDR,
|
||||||
|
|
||||||
// TargetConstant* - Like Constant*, but the DAG does not do any folding or
|
// TargetConstant* - Like Constant*, but the DAG does not do any folding or
|
||||||
// simplification of the constant.
|
// simplification of the constant.
|
||||||
|
@ -739,14 +739,6 @@ public:
|
|||||||
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
||||||
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
SDOperand Callee, ArgListTy &Args, 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
|
|
||||||
/// not implemented, both of these intrinsics will return null.
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
|
||||||
SelectionDAG &DAG);
|
|
||||||
|
|
||||||
/// LowerOperation - This callback is invoked for operations that are
|
/// LowerOperation - This callback is invoked for operations that are
|
||||||
/// unsupported by the target, which are registered to use 'custom' lowering,
|
/// unsupported by the target, which are registered to use 'custom' lowering,
|
||||||
/// and whose defined values are all legal.
|
/// and whose defined values are all legal.
|
||||||
|
@ -652,6 +652,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ISD::FRAMEADDR:
|
||||||
|
case ISD::RETURNADDR:
|
||||||
|
// The only option for these nodes is to custom lower them. If the target
|
||||||
|
// does not custom lower them, then return zero.
|
||||||
|
Tmp1 = TLI.LowerOperation(Op, DAG);
|
||||||
|
if (Tmp1.Val)
|
||||||
|
Result = Tmp1;
|
||||||
|
else
|
||||||
|
Result = DAG.getConstant(0, TLI.getPointerTy());
|
||||||
|
break;
|
||||||
case ISD::AssertSext:
|
case ISD::AssertSext:
|
||||||
case ISD::AssertZext:
|
case ISD::AssertZext:
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||||
|
@ -2665,6 +2665,8 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
|||||||
case ISD::FrameIndex: return "FrameIndex";
|
case ISD::FrameIndex: return "FrameIndex";
|
||||||
case ISD::JumpTable: return "JumpTable";
|
case ISD::JumpTable: return "JumpTable";
|
||||||
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
|
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
|
||||||
|
case ISD::RETURNADDR: return "RETURNADDR";
|
||||||
|
case ISD::FRAMEADDR: return "FRAMEADDR";
|
||||||
case ISD::ConstantPool: return "ConstantPool";
|
case ISD::ConstantPool: return "ConstantPool";
|
||||||
case ISD::ExternalSymbol: return "ExternalSymbol";
|
case ISD::ExternalSymbol: return "ExternalSymbol";
|
||||||
case ISD::INTRINSIC_WO_CHAIN: {
|
case ISD::INTRINSIC_WO_CHAIN: {
|
||||||
|
@ -570,7 +570,6 @@ public:
|
|||||||
void visitVAArg(VAArgInst &I);
|
void visitVAArg(VAArgInst &I);
|
||||||
void visitVAEnd(CallInst &I);
|
void visitVAEnd(CallInst &I);
|
||||||
void visitVACopy(CallInst &I);
|
void visitVACopy(CallInst &I);
|
||||||
void visitFrameReturnAddress(CallInst &I, bool isFrameAddress);
|
|
||||||
|
|
||||||
void visitMemIntrinsic(CallInst &I, unsigned Op);
|
void visitMemIntrinsic(CallInst &I, unsigned Op);
|
||||||
|
|
||||||
@ -1932,8 +1931,14 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
|||||||
case Intrinsic::vastart: visitVAStart(I); return 0;
|
case Intrinsic::vastart: visitVAStart(I); return 0;
|
||||||
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
case Intrinsic::vaend: visitVAEnd(I); return 0;
|
||||||
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
case Intrinsic::vacopy: visitVACopy(I); return 0;
|
||||||
case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0;
|
case Intrinsic::returnaddress:
|
||||||
case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0;
|
setValue(&I, DAG.getNode(ISD::RETURNADDR, TLI.getPointerTy(),
|
||||||
|
getValue(I.getOperand(1))));
|
||||||
|
return 0;
|
||||||
|
case Intrinsic::frameaddress:
|
||||||
|
setValue(&I, DAG.getNode(ISD::FRAMEADDR, TLI.getPointerTy(),
|
||||||
|
getValue(I.getOperand(1))));
|
||||||
|
return 0;
|
||||||
case Intrinsic::setjmp:
|
case Intrinsic::setjmp:
|
||||||
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
|
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
|
||||||
break;
|
break;
|
||||||
@ -3207,19 +3212,6 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
|
return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// It is always conservatively correct for llvm.returnaddress and
|
|
||||||
// llvm.frameaddress to return 0.
|
|
||||||
//
|
|
||||||
// FIXME: Change this to insert a FRAMEADDR/RETURNADDR node, and have that be
|
|
||||||
// expanded to 0 if the target wants.
|
|
||||||
std::pair<SDOperand, SDOperand>
|
|
||||||
TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain,
|
|
||||||
unsigned Depth, SelectionDAG &DAG) {
|
|
||||||
return std::make_pair(DAG.getConstant(0, getPointerTy()), Chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
assert(0 && "LowerOperation not implemented for this target!");
|
assert(0 && "LowerOperation not implemented for this target!");
|
||||||
abort();
|
abort();
|
||||||
@ -3233,14 +3225,6 @@ SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op,
|
|||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) {
|
|
||||||
unsigned Depth = (unsigned)cast<ConstantInt>(I.getOperand(1))->getZExtValue();
|
|
||||||
std::pair<SDOperand,SDOperand> Result =
|
|
||||||
TLI.LowerFrameReturnAddress(isFrame, getRoot(), Depth, DAG);
|
|
||||||
setValue(&I, Result.first);
|
|
||||||
DAG.setRoot(Result.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getMemsetValue - Vectorized representation of the memset value
|
/// getMemsetValue - Vectorized representation of the memset value
|
||||||
/// operand.
|
/// operand.
|
||||||
static SDOperand getMemsetValue(SDOperand Value, MVT::ValueType VT,
|
static SDOperand getMemsetValue(SDOperand Value, MVT::ValueType VT,
|
||||||
|
@ -1130,7 +1130,10 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
case ISD::SRA: return LowerSRx(Op, DAG, Subtarget);
|
case ISD::SRA: return LowerSRx(Op, DAG, Subtarget);
|
||||||
case ISD::FORMAL_ARGUMENTS:
|
case ISD::FORMAL_ARGUMENTS:
|
||||||
return LowerFORMAL_ARGUMENTS(Op, DAG);
|
return LowerFORMAL_ARGUMENTS(Op, DAG);
|
||||||
|
case ISD::RETURNADDR: break;
|
||||||
|
case ISD::FRAMEADDR: break;
|
||||||
}
|
}
|
||||||
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -544,6 +544,9 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
|
return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
|
||||||
SA2, NULL, 0, MVT::i32);
|
SA2, NULL, 0, MVT::i32);
|
||||||
}
|
}
|
||||||
|
// Frame & Return address. Currently unimplemented
|
||||||
|
case ISD::RETURNADDR: break;
|
||||||
|
case ISD::FRAMEADDR: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
|
@ -532,13 +532,6 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
|||||||
return std::make_pair(RetVal, Chain);
|
return std::make_pair(RetVal, Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<SDOperand, SDOperand> IA64TargetLowering::
|
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
|
||||||
SelectionDAG &DAG) {
|
|
||||||
assert(0 && "LowerFrameReturnAddress unimplemented");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
SDOperand IA64TargetLowering::
|
SDOperand IA64TargetLowering::
|
||||||
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
switch (Op.getOpcode()) {
|
switch (Op.getOpcode()) {
|
||||||
@ -594,5 +587,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getStore(Op.getOperand(0), FR,
|
return DAG.getStore(Op.getOperand(0), FR,
|
||||||
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
||||||
}
|
}
|
||||||
|
// Frame & Return address. Currently unimplemented
|
||||||
|
case ISD::RETURNADDR: break;
|
||||||
|
case ISD::FRAMEADDR: break;
|
||||||
}
|
}
|
||||||
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,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 std::pair<SDOperand, SDOperand>
|
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
|
||||||
SelectionDAG &DAG);
|
|
||||||
|
|
||||||
// XXX virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
// XXX virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||||
// XXX MachineBasicBlock *MBB);
|
// XXX MachineBasicBlock *MBB);
|
||||||
};
|
};
|
||||||
|
@ -2634,6 +2634,10 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||||
case ISD::MUL: return LowerMUL(Op, DAG);
|
case ISD::MUL: return LowerMUL(Op, DAG);
|
||||||
|
|
||||||
|
// Frame & Return address. Currently unimplemented
|
||||||
|
case ISD::RETURNADDR: break;
|
||||||
|
case ISD::FRAMEADDR: break;
|
||||||
}
|
}
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
@ -868,7 +868,11 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
}
|
}
|
||||||
return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||||
}
|
}
|
||||||
|
// Frame & Return address. Currently unimplemented
|
||||||
|
case ISD::RETURNADDR: break;
|
||||||
|
case ISD::FRAMEADDR: break;
|
||||||
}
|
}
|
||||||
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineBasicBlock *
|
MachineBasicBlock *
|
||||||
|
@ -1940,25 +1940,6 @@ SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::pair<SDOperand, SDOperand> X86TargetLowering::
|
|
||||||
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
|
||||||
SelectionDAG &DAG) {
|
|
||||||
SDOperand Result;
|
|
||||||
if (Depth) // Depths > 0 not supported yet!
|
|
||||||
Result = DAG.getConstant(0, getPointerTy());
|
|
||||||
else {
|
|
||||||
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
|
||||||
if (!isFrameAddress)
|
|
||||||
// Just load the return address
|
|
||||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI,
|
|
||||||
NULL, 0);
|
|
||||||
else
|
|
||||||
Result = DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
|
|
||||||
DAG.getConstant(4, getPointerTy()));
|
|
||||||
}
|
|
||||||
return std::make_pair(Result, Chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86
|
/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86
|
||||||
/// specific condition code. It returns a false if it cannot do a direct
|
/// specific condition code. It returns a false if it cannot do a direct
|
||||||
/// translation. X86CC is the translated CondCode. LHS/RHS are modified as
|
/// translation. X86CC is the translated CondCode. LHS/RHS are modified as
|
||||||
@ -4621,6 +4602,26 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand X86TargetLowering::LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||||
|
// Depths > 0 not supported yet!
|
||||||
|
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||||
|
return SDOperand();
|
||||||
|
|
||||||
|
// Just load the return address
|
||||||
|
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
||||||
|
return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand X86TargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||||
|
// Depths > 0 not supported yet!
|
||||||
|
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||||
|
return SDOperand();
|
||||||
|
|
||||||
|
SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
|
||||||
|
return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
|
||||||
|
DAG.getConstant(4, getPointerTy()));
|
||||||
|
}
|
||||||
|
|
||||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||||
///
|
///
|
||||||
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
@ -4654,6 +4655,8 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG);
|
case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG);
|
||||||
case ISD::VASTART: return LowerVASTART(Op, DAG);
|
case ISD::VASTART: return LowerVASTART(Op, DAG);
|
||||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||||
|
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||||
|
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,10 +292,6 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
|
||||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
|
||||||
SelectionDAG &DAG);
|
|
||||||
|
|
||||||
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
|
virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
|
||||||
|
|
||||||
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||||
@ -406,6 +402,8 @@ namespace llvm {
|
|||||||
SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user