Index: lib/Target/RISCV/RISCVISelLowering.h =================================================================== --- lib/Target/RISCV/RISCVISelLowering.h +++ lib/Target/RISCV/RISCVISelLowering.h @@ -16,6 +16,7 @@ #define LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H #include "RISCV.h" +#include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLowering.h" @@ -47,6 +48,9 @@ EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override; + CCAssignFn *CCAssignFnForCall(const DataLayout &DL) const; + CCAssignFn *CCAssignFnForReturn(const DataLayout &DL) const; + private: void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, const SmallVectorImpl &Ins, Index: lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- lib/Target/RISCV/RISCVISelLowering.cpp +++ lib/Target/RISCV/RISCVISelLowering.cpp @@ -395,22 +395,9 @@ return false; } -// Implements the RISC-V calling convention. Returns true upon failure. -static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, - CCState &State, bool IsFixed, bool IsRet) { - unsigned XLen = DL.getLargestLegalIntTypeSizeInBits(); - assert(XLen == 32 || XLen == 64); - MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64; - assert(ValVT == XLenVT && "Unexpected ValVT"); - assert(LocVT == XLenVT && "Unexpected LocVT"); - assert(IsFixed && "Vararg support not yet implemented"); - - // Any return value split in to more than two values can't be returned - // directly. - if (IsRet && ValNo > 1) - return true; - +static bool CC_RISCVFn(unsigned XLen, MVT XLenVT, unsigned ValNo, MVT ValVT, + MVT LocVT, CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State) { SmallVectorImpl &PendingLocs = State.getPendingLocs(); SmallVectorImpl &PendingArgFlags = State.getPendingArgFlags(); @@ -478,6 +465,87 @@ return false; } +static bool CC_RISCV32Fn(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State) { + unsigned XLen = 32; + MVT XLenVT = MVT::i32; + + return CC_RISCVFn(XLen, XLenVT, ValNo, ValVT, LocVT, LocInfo, ArgFlags, + State); +} + +static bool CC_RISCV64Fn(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State) { + unsigned XLen = 64; + MVT XLenVT = MVT::i64; + + return CC_RISCVFn(XLen, XLenVT, ValNo, ValVT, LocVT, LocInfo, ArgFlags, + State); +} + +static bool RetCC_RISCV32Fn(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State) { + unsigned XLen = 32; + MVT XLenVT = MVT::i32; + + if (ValNo > 1) + return true; + + return CC_RISCVFn(XLen, XLenVT, ValNo, ValVT, LocVT, LocInfo, ArgFlags, + State); +} + +static bool RetCC_RISCV64Fn(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + ISD::ArgFlagsTy ArgFlags, CCState &State) { + unsigned XLen = 64; + MVT XLenVT = MVT::i64; + + if (ValNo > 1) + return true; + + return CC_RISCVFn(XLen, XLenVT, ValNo, ValVT, LocVT, LocInfo, ArgFlags, + State); +} + +CCAssignFn *RISCVTargetLowering::CCAssignFnForCall(const DataLayout &DL) const { + if (DL.getLargestLegalIntTypeSizeInBits() == 32) + return CC_RISCV32Fn; + + return CC_RISCV64Fn; +} + +CCAssignFn *RISCVTargetLowering::CCAssignFnForReturn(const DataLayout &DL) + const { + if (DL.getLargestLegalIntTypeSizeInBits() == 32) + return RetCC_RISCV32Fn; + + return RetCC_RISCV64Fn; +} + +// Implements the RISC-V calling convention. Returns true upon failure. +static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State, bool IsFixed, bool IsRet) { + unsigned XLen = DL.getLargestLegalIntTypeSizeInBits(); + assert(XLen == 32 || XLen == 64); + MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64; + assert(ValVT == XLenVT && "Unexpected ValVT"); + assert(LocVT == XLenVT && "Unexpected LocVT"); + assert(IsFixed && "Vararg support not yet implemented"); + + // Any return value split in to more than two values can't be returned + // directly. + if (IsRet && ValNo > 1) + return true; + + return CC_RISCVFn(XLen, XLenVT, ValNo, ValVT, LocVT, LocInfo, ArgFlags, + State); +} + void RISCVTargetLowering::analyzeInputArgs( MachineFunction &MF, CCState &CCInfo, const SmallVectorImpl &Ins, bool IsRet) const {