diff --git a/lib/Target/SystemZ/SystemZCallingConv.td b/lib/Target/SystemZ/SystemZCallingConv.td index 88ff46ff29a..585c4b290e7 100644 --- a/lib/Target/SystemZ/SystemZCallingConv.td +++ b/lib/Target/SystemZ/SystemZCallingConv.td @@ -17,7 +17,11 @@ def RetCC_SystemZ : CallingConv<[ CCIfType<[i8, i16, i32], CCPromoteToType>, // i64 is returned in register R2 - CCIfType<[i64], CCAssignToReg<[R2D]>> + CCIfType<[i64], CCAssignToReg<[R2D]>>, + + // f32 / f64 are returned in F0 + CCIfType<[f32], CCAssignToReg<[F0S]>>, + CCIfType<[f64], CCAssignToReg<[F0L]>> ]>; //===----------------------------------------------------------------------===// @@ -31,6 +35,11 @@ def CC_SystemZ : CallingConv<[ // integer registers. CCIfType<[i64], CCAssignToReg<[R2D, R3D, R4D, R5D, R6D]>>, + // The first 4 ifloating point arguments of non-varargs functions are passed + // in FP registers. + CCIfType<[f32], CCAssignToReg<[F0S, F2S, F4S, F6S]>>, + CCIfType<[f64], CCAssignToReg<[F0L, F2L, F4L, F6L]>>, + // Integer values get stored in stack slots that are 8 bytes in // size and 8-byte aligned. CCIfType<[i64], CCAssignToStack<8, 8>> diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 364d6886559..f25c337c82d 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -173,33 +173,42 @@ SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, if (VA.isRegLoc()) { // Arguments passed in registers MVT RegVT = VA.getLocVT(); + TargetRegisterClass *RC; switch (RegVT.getSimpleVT()) { default: cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " << RegVT.getSimpleVT() << "\n"; abort(); - case MVT::i64: - unsigned VReg = - RegInfo.createVirtualRegister(SystemZ::GR64RegisterClass); - RegInfo.addLiveIn(VA.getLocReg(), VReg); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); - - // If this is an 8/16/32-bit value, it is really passed promoted to 64 - // bits. Insert an assert[sz]ext to capture this, then truncate to the - // right size. - if (VA.getLocInfo() == CCValAssign::SExt) - ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, - DAG.getValueType(VA.getValVT())); - else if (VA.getLocInfo() == CCValAssign::ZExt) - ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, - DAG.getValueType(VA.getValVT())); - - if (VA.getLocInfo() != CCValAssign::Full) - ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); - - ArgValues.push_back(ArgValue); + case MVT::i64: + RC = SystemZ::GR64RegisterClass; + break; + case MVT::f32: + RC = SystemZ::FP32RegisterClass; + break; + case MVT::f64: + RC = SystemZ::FP64RegisterClass; + break; } + + unsigned VReg = RegInfo.createVirtualRegister(RC); + RegInfo.addLiveIn(VA.getLocReg(), VReg); + SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); + + // If this is an 8/16/32-bit value, it is really passed promoted to 64 + // bits. Insert an assert[sz]ext to capture this, then truncate to the + // right size. + if (VA.getLocInfo() == CCValAssign::SExt) + ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, + DAG.getValueType(VA.getValVT())); + else if (VA.getLocInfo() == CCValAssign::ZExt) + ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, + DAG.getValueType(VA.getValVT())); + + if (VA.getLocInfo() != CCValAssign::Full) + ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); + + ArgValues.push_back(ArgValue); } else { // Sanity check assert(VA.isMemLoc());