// The address of the GOT
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
// simplification of the constant.
bool isVarArg, unsigned CallingConv, bool isTailCall,
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
/// unsupported by the target, which are registered to use 'custom' lowering,
/// and whose defined values are all legal.
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::AssertZext:
Tmp1 = LegalizeOp(Node->getOperand(0));
case ISD::FrameIndex: return "FrameIndex";
case ISD::JumpTable: return "JumpTable";
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::ExternalSymbol: return "ExternalSymbol";
case ISD::INTRINSIC_WO_CHAIN: {
void visitVAArg(VAArgInst &I);
void visitVAEnd(CallInst &I);
void visitVACopy(CallInst &I);
- void visitFrameReturnAddress(CallInst &I, bool isFrameAddress);
void visitMemIntrinsic(CallInst &I, unsigned Op);
case Intrinsic::vastart: visitVAStart(I); return 0;
case Intrinsic::vaend: visitVAEnd(I); return 0;
case Intrinsic::vacopy: visitVACopy(I); return 0;
- case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0;
- case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0;
+ case Intrinsic::returnaddress:
+ 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:
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
break;
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) {
assert(0 && "LowerOperation not implemented for this target!");
abort();
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
/// operand.
static SDOperand getMemsetValue(SDOperand Value, MVT::ValueType VT,
case ISD::SRA: return LowerSRx(Op, DAG, Subtarget);
case ISD::FORMAL_ARGUMENTS:
return LowerFORMAL_ARGUMENTS(Op, DAG);
+ case ISD::RETURNADDR: break;
+ case ISD::FRAMEADDR: break;
}
+ return SDOperand();
}
//===----------------------------------------------------------------------===//
return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
SA2, NULL, 0, MVT::i32);
}
+ // Frame & Return address. Currently unimplemented
+ case ISD::RETURNADDR: break;
+ case ISD::FRAMEADDR: break;
}
return SDOperand();
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::
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
return DAG.getStore(Op.getOperand(0), FR,
Op.getOperand(1), SV->getValue(), SV->getOffset());
}
+ // Frame & Return address. Currently unimplemented
+ case ISD::RETURNADDR: break;
+ case ISD::FRAMEADDR: break;
}
+ return SDOperand();
}
/// (currently, only "ret void")
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 MachineBasicBlock *MBB);
};
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(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 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 *
-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
/// specific condition code. It returns a false if it cannot do a direct
/// translation. X86CC is the translated CondCode. LHS/RHS are modified as
}
}
+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.
///
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG);
case ISD::VASTART: return LowerVASTART(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);
}
}
///
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 MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
};
}