Skip to content

Commit 0837100

Browse files
committed
[RISCV] RISCV vector calling convention (1/2)
This is the vector calling convention based on https://github.com/riscv-non-isa/riscv-elf-psabi-doc, the idea is to split between "scalar" callee-saved registers and "vector" callee-saved registers. "scalar" ones remain the original strategy, however, "vector" ones are handled together with RVV objects. The stack layout would be: |--------------------------| <-- FP | callee-allocated save | | area for register varargs| |--------------------------| | callee-saved registers | <-- scalar callee-saved | (scalar) | |--------------------------| | RVV alignment padding | |--------------------------| | callee-saved registers | <-- vector callee-saved | (vector) | |--------------------------| | RVV objects | |--------------------------| | padding before RVV | |--------------------------| | scalar local variables | |--------------------------| <-- BP | variable size objects | |--------------------------| <-- SP Note: This patch doesn't contain "tuple" type, e.g. vint32m1x2. It will be handled in https://github.com/riscv-non-isa/riscv-elf-psabi-doc (2/2). Differential Revision: https://reviews.llvm.org/D154576
1 parent 9f84594 commit 0837100

29 files changed

+409
-50
lines changed

clang/include/clang-c/Index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2991,6 +2991,7 @@ enum CXCallingConv {
29912991
CXCallingConv_AArch64SVEPCS = 18,
29922992
CXCallingConv_M68kRTD = 19,
29932993
CXCallingConv_PreserveNone = 20,
2994+
CXCallingConv_RISCVVectorCall = 21,
29942995

29952996
CXCallingConv_Invalid = 100,
29962997
CXCallingConv_Unexposed = 200

clang/include/clang/Basic/Attr.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,6 +3011,13 @@ def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86> {
30113011
let Documentation = [PreserveNoneDocs];
30123012
}
30133013

3014+
def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
3015+
let Spellings = [CXX11<"riscv", "vector_cc">,
3016+
C23<"riscv", "vector_cc">,
3017+
Clang<"riscv_vector_cc">];
3018+
let Documentation = [RISCVVectorCCDocs];
3019+
}
3020+
30143021
def Target : InheritableAttr {
30153022
let Spellings = [GCC<"target">];
30163023
let Args = [StringArgument<"featuresStr">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5494,6 +5494,17 @@ for clang builtin functions.
54945494
}];
54955495
}
54965496

5497+
def RISCVVectorCCDocs : Documentation {
5498+
let Category = DocCatCallingConvs;
5499+
let Heading = "riscv::vector_cc, riscv_vector_cc, clang::riscv_vector_cc";
5500+
let Content = [{
5501+
The ``riscv_vector_cc`` attribute can be applied to a function. It preserves 15
5502+
registers namely, v1-v7 and v24-v31 as callee-saved. Callers thus don't need
5503+
to save these registers before function calls, and callees only need to save
5504+
them if they use them.
5505+
}];
5506+
}
5507+
54975508
def PreferredNameDocs : Documentation {
54985509
let Category = DocCatDecl;
54995510
let Content = [{

clang/include/clang/Basic/Specifiers.h

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -273,29 +273,30 @@ namespace clang {
273273

274274
/// CallingConv - Specifies the calling convention that a function uses.
275275
enum CallingConv {
276-
CC_C, // __attribute__((cdecl))
277-
CC_X86StdCall, // __attribute__((stdcall))
278-
CC_X86FastCall, // __attribute__((fastcall))
279-
CC_X86ThisCall, // __attribute__((thiscall))
280-
CC_X86VectorCall, // __attribute__((vectorcall))
281-
CC_X86Pascal, // __attribute__((pascal))
282-
CC_Win64, // __attribute__((ms_abi))
283-
CC_X86_64SysV, // __attribute__((sysv_abi))
284-
CC_X86RegCall, // __attribute__((regcall))
285-
CC_AAPCS, // __attribute__((pcs("aapcs")))
286-
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
287-
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
288-
CC_SpirFunction, // default for OpenCL functions on SPIR target
289-
CC_OpenCLKernel, // inferred for OpenCL kernels
290-
CC_Swift, // __attribute__((swiftcall))
276+
CC_C, // __attribute__((cdecl))
277+
CC_X86StdCall, // __attribute__((stdcall))
278+
CC_X86FastCall, // __attribute__((fastcall))
279+
CC_X86ThisCall, // __attribute__((thiscall))
280+
CC_X86VectorCall, // __attribute__((vectorcall))
281+
CC_X86Pascal, // __attribute__((pascal))
282+
CC_Win64, // __attribute__((ms_abi))
283+
CC_X86_64SysV, // __attribute__((sysv_abi))
284+
CC_X86RegCall, // __attribute__((regcall))
285+
CC_AAPCS, // __attribute__((pcs("aapcs")))
286+
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
287+
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
288+
CC_SpirFunction, // default for OpenCL functions on SPIR target
289+
CC_OpenCLKernel, // inferred for OpenCL kernels
290+
CC_Swift, // __attribute__((swiftcall))
291291
CC_SwiftAsync, // __attribute__((swiftasynccall))
292-
CC_PreserveMost, // __attribute__((preserve_most))
293-
CC_PreserveAll, // __attribute__((preserve_all))
292+
CC_PreserveMost, // __attribute__((preserve_most))
293+
CC_PreserveAll, // __attribute__((preserve_all))
294294
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
295-
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
296-
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
297-
CC_M68kRTD, // __attribute__((m68k_rtd))
298-
CC_PreserveNone, // __attribute__((preserve_none))
295+
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
296+
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
297+
CC_M68kRTD, // __attribute__((m68k_rtd))
298+
CC_PreserveNone, // __attribute__((preserve_none))
299+
CC_RISCVVectorCall, // __attribute__((riscv_vector_cc))
299300
};
300301

301302
/// Checks whether the given calling convention supports variadic

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3445,6 +3445,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
34453445
case CC_PreserveAll:
34463446
case CC_M68kRTD:
34473447
case CC_PreserveNone:
3448+
case CC_RISCVVectorCall:
34483449
// FIXME: we should be mangling all of the above.
34493450
return "";
34503451

clang/lib/AST/Type.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,9 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
34843484
case CC_PreserveAll: return "preserve_all";
34853485
case CC_M68kRTD: return "m68k_rtd";
34863486
case CC_PreserveNone: return "preserve_none";
3487+
// clang-format off
3488+
case CC_RISCVVectorCall: return "riscv_vector_cc";
3489+
// clang-format on
34873490
}
34883491

34893492
llvm_unreachable("Invalid calling convention.");
@@ -4074,6 +4077,7 @@ bool AttributedType::isCallingConv() const {
40744077
case attr::PreserveAll:
40754078
case attr::M68kRTD:
40764079
case attr::PreserveNone:
4080+
case attr::RISCVVectorCC:
40774081
return true;
40784082
}
40794083
llvm_unreachable("invalid attr kind");

clang/lib/AST/TypePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
10711071
case CC_PreserveNone:
10721072
OS << " __attribute__((preserve_none))";
10731073
break;
1074+
case CC_RISCVVectorCall:
1075+
OS << "__attribute__((riscv_vector_cc))";
1076+
break;
10741077
}
10751078
}
10761079

@@ -1960,6 +1963,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19601963
case attr::PreserveNone:
19611964
OS << "preserve_none";
19621965
break;
1966+
case attr::RISCVVectorCC:
1967+
OS << "riscv_vector_cc";
1968+
break;
19631969
case attr::NoDeref:
19641970
OS << "noderef";
19651971
break;

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,14 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
467467
}
468468
return Ret;
469469
}
470+
471+
TargetInfo::CallingConvCheckResult
472+
RISCVTargetInfo::checkCallingConvention(CallingConv CC) const {
473+
switch (CC) {
474+
default:
475+
return CCCR_Warning;
476+
case CC_C:
477+
case CC_RISCVVectorCall:
478+
return CCCR_OK;
479+
}
480+
}

clang/lib/Basic/Targets/RISCV.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class RISCVTargetInfo : public TargetInfo {
110110

111111
bool hasBFloat16Type() const override { return true; }
112112

113+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
114+
113115
bool useFP16ConversionIntrinsics() const override {
114116
return false;
115117
}

clang/lib/CodeGen/CGCall.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
7474
case CC_SwiftAsync: return llvm::CallingConv::SwiftTail;
7575
case CC_M68kRTD: return llvm::CallingConv::M68k_RTD;
7676
case CC_PreserveNone: return llvm::CallingConv::PreserveNone;
77+
// clang-format off
78+
case CC_RISCVVectorCall: return llvm::CallingConv::RISCV_VectorCall;
79+
// clang-format on
7780
}
7881
}
7982

@@ -260,6 +263,9 @@ static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
260263
if (D->hasAttr<PreserveNoneAttr>())
261264
return CC_PreserveNone;
262265

266+
if (D->hasAttr<RISCVVectorCCAttr>())
267+
return CC_RISCVVectorCall;
268+
263269
return CC_C;
264270
}
265271

0 commit comments

Comments
 (0)