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);
+
/// 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
case MVT::f64:
break; // No extension needed!
}
-
- DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot(), Op1));
+ // Allow targets to lower this further to meet ABI requirements
+ DAG.setRoot(TLI.LowerReturnTo(getRoot(), Op1, DAG));
}
void SelectionDAGLowering::visitBr(BranchInst &I) {
return 0;
}
+SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+ SelectionDAG &DAG) {
+ return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+}
+
SDOperand TargetLowering::LowerVAStart(SDOperand Chain,
SDOperand VAListP, Value *VAListV,
SelectionDAG &DAG) {
// Other cases are autogenerated.
break;
+ case ISD::ANY_EXTEND:
+ switch(N->getValueType(0)) {
+ default: assert(0 && "Unhandled type in ANY_EXTEND");
+ case MVT::i64:
+ CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Select(N->getOperand(0)),
+ Select(N->getOperand(0)));
+ break;
+ }
+ return SDOperand(N, 0);
+ case ISD::ZERO_EXTEND:
+ assert(N->getValueType(0) == MVT::i64 &&
+ N->getOperand(0).getValueType() == MVT::i32 &&
+ "ZERO_EXTEND only supported for i32 -> i64");
+ CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
+ getI32Imm(32));
+ return SDOperand(N, 0);
case ISD::SHL: {
unsigned Imm, SH, MB, ME;
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
SDOperand Val = Select(N->getOperand(1));
if (N->getOperand(1).getValueType() == MVT::i32) {
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
- } else if (N->getOperand(1).getValueType() == MVT::i64) {
- SDOperand Srl = CurDAG->getTargetNode(PPC::RLDICL, MVT::i64, Val,
- getI32Imm(32), getI32Imm(32));
- Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val);
- Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Srl);
} else {
assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
return std::make_pair(RetVal, Chain);
}
+SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+ SelectionDAG &DAG) {
+ if (Op.getValueType() == 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));
+ return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
+ } else {
+ return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+ }
+}
+
SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG) {
// vastart just stores the address of the VarArgsFrameIndex slot into the
unsigned CC,
bool isTailCall, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG);
+
+ virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
+ SelectionDAG &DAG);
virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG);