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" @@ -51,6 +52,11 @@ EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override; + CCAssignFn *CCAssignFnForCall(const DataLayout &DL, bool IsFixed = false, + Type *OrigTy = nullptr) const; + CCAssignFn *CCAssignFnForReturn(const DataLayout &DL, bool IsFixed = false, + Type *OrigTy = nullptr) 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 @@ -475,20 +475,11 @@ 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, Type *OrigTy) { - 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"); - - // 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, + bool IsFixed = false, Type *OrigTy = nullptr) { + const DataLayout &DL = State.getMachineFunction().getDataLayout(); // If this is a variadic argument, the RISC-V calling convention requires // that it is assigned an 'even' or 'aligned' register if it has 8-byte @@ -573,6 +564,94 @@ 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, + bool IsFixed, + Type *OrigTy) const { + assert(IsFixed && "IsFixed support not yet implemented"); + assert(OrigTy && "OrigTy support not yet implemented"); + if (DL.getLargestLegalIntTypeSizeInBits() == 32) + return CC_RISCV32Fn; + + return CC_RISCV64Fn; +} + +CCAssignFn *RISCVTargetLowering::CCAssignFnForReturn(const DataLayout &DL, + bool IsFixed, + Type *OrigTy) const { + assert(IsFixed && "IsFixed support not yet implemented"); + assert(OrigTy && "OrigTy support not yet implemented"); + if (DL.getLargestLegalIntTypeSizeInBits() == 32) + return RetCC_RISCV32Fn; + + return RetCC_RISCV64Fn; +} + +// Implements the RISC-V calling convention. Returns true upon failure. +static bool CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State, bool IsFixed, bool IsRet, Type *OrigTy) { + const DataLayout &DL = State.getMachineFunction().getDataLayout(); + 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"); + + // 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, + IsFixed, OrigTy); +} + void RISCVTargetLowering::analyzeInputArgs( MachineFunction &MF, CCState &CCInfo, const SmallVectorImpl &Ins, bool IsRet) const { @@ -589,8 +668,8 @@ else if (Ins[i].isOrigArg()) ArgTy = FType->getParamType(Ins[i].getOrigArgIndex()); - if (CC_RISCV(MF.getDataLayout(), i, ArgVT, ArgVT, CCValAssign::Full, - ArgFlags, CCInfo, /*IsRet=*/true, IsRet, ArgTy)) { + if (CC_RISCV(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo, + /*IsFixed=*/true, IsRet, ArgTy)) { DEBUG(dbgs() << "InputArg #" << i << " has unhandled type " << EVT(ArgVT).getEVTString() << '\n'); llvm_unreachable(nullptr); @@ -609,8 +688,8 @@ ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr; - if (CC_RISCV(MF.getDataLayout(), i, ArgVT, ArgVT, CCValAssign::Full, - ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) { + if (CC_RISCV(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo, + Outs[i].IsFixed, IsRet, OrigTy)) { DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type " << EVT(ArgVT).getEVTString() << "\n"); llvm_unreachable(nullptr); @@ -987,8 +1066,8 @@ for (unsigned i = 0, e = Outs.size(); i != e; ++i) { MVT VT = Outs[i].VT; ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; - if (CC_RISCV(MF.getDataLayout(), i, VT, VT, CCValAssign::Full, ArgFlags, - CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr)) + if (CC_RISCV(i, VT, VT, CCValAssign::Full, ArgFlags, CCInfo, + /*IsFixed=*/true, /*IsRet=*/true, nullptr)) return false; } return true;