diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp index 1e1d249b37ac..0851d1993d0c 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp @@ -25,8 +25,9 @@ private: // ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target // with soft float ABI has FLen==0). unsigned FLen; - static const int NumArgGPRs = 8; - static const int NumArgFPRs = 8; + const int NumArgGPRs; + const int NumArgFPRs; + const bool EABI; bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, llvm::Type *&Field1Ty, CharUnits &Field1Off, @@ -34,8 +35,10 @@ private: CharUnits &Field2Off) const; public: - RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen) - : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen) {} + RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen, + bool EABI) + : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8), + NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {} // DefaultABIInfo's classifyReturnType and classifyArgumentType are // non-virtual, but computeInfo is virtual, so we overload it. @@ -86,7 +89,7 @@ void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const { } int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs; - int ArgFPRsLeft = FLen ? NumArgFPRs : 0; + int ArgFPRsLeft = NumArgFPRs; int NumFixedArgs = FI.getNumRequiredArgs(); int ArgNum = 0; @@ -396,9 +399,12 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, // Determine the number of GPRs needed to pass the current argument // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" // register pairs, so may consume 3 registers. + // TODO: To be compatible with GCC's behaviors, we don't align registers + // currently if we are using ILP32E calling convention. This behavior may be + // changed when RV32E/ILP32E is ratified. int NeededArgGPRs = 1; if (!IsFixed && NeededAlign == 2 * XLen) - NeededArgGPRs = 2 + (ArgGPRsLeft % 2); + NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2)); else if (Size > XLen && Size <= 2 * XLen) NeededArgGPRs = 2; @@ -480,6 +486,13 @@ Address RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, auto TInfo = getContext().getTypeInfoInChars(Ty); + // TODO: To be compatible with GCC's behaviors, we force arguments with + // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, + // `unsigned long long` and `double` to have 4-byte alignment. This + // behavior may be changed when RV32E/ILP32E is ratified. + if (EABI && XLen == 32) + TInfo.Align = std::min(TInfo.Align, CharUnits::fromQuantity(4)); + // Arguments bigger than 2*Xlen bytes are passed indirectly. bool IsIndirect = TInfo.Width > 2 * SlotSize; @@ -499,8 +512,9 @@ namespace { class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { public: RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, - unsigned FLen) - : TargetCodeGenInfo(std::make_unique<RISCVABIInfo>(CGT, XLen, FLen)) {} + unsigned FLen, bool EABI) + : TargetCodeGenInfo( + std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { @@ -526,6 +540,7 @@ public: std::unique_ptr<TargetCodeGenInfo> CodeGen::createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, - unsigned FLen) { - return std::make_unique<RISCVTargetCodeGenInfo>(CGM.getTypes(), XLen, FLen); + unsigned FLen, bool EABI) { + return std::make_unique<RISCVTargetCodeGenInfo>(CGM.getTypes(), XLen, FLen, + EABI); } |