Skip to content

Commit 64c8b66

Browse files
[AArch64][SME] Add calling convention for __arm_get_current_vg (#93963)
Adds a calling convention for calls to the `__arm_get_current_vg` support routine, which preserves X1-X15, X19-X29, SP, Z0-Z31 & P0-P15. See ARM-software/abi-aa#263
1 parent 7f52e4c commit 64c8b66

File tree

8 files changed

+68
-5
lines changed

8 files changed

+68
-5
lines changed

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ enum Kind {
147147
kw_aarch64_vector_pcs,
148148
kw_aarch64_sve_vector_pcs,
149149
kw_aarch64_sme_preservemost_from_x0,
150+
kw_aarch64_sme_preservemost_from_x1,
150151
kw_aarch64_sme_preservemost_from_x2,
151152
kw_msp430_intrcc,
152153
kw_avr_intrcc,

llvm/include/llvm/IR/CallingConv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ namespace CallingConv {
267267
/// Calling convention used for RISC-V V-extension.
268268
RISCV_VectorCall = 110,
269269

270+
/// Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
271+
AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 = 111,
272+
270273
/// The highest possible ID. Must be some 2^k - 1.
271274
MaxID = 1023
272275
};

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ lltok::Kind LLLexer::LexIdentifier() {
604604
KEYWORD(aarch64_vector_pcs);
605605
KEYWORD(aarch64_sve_vector_pcs);
606606
KEYWORD(aarch64_sme_preservemost_from_x0);
607+
KEYWORD(aarch64_sme_preservemost_from_x1);
607608
KEYWORD(aarch64_sme_preservemost_from_x2);
608609
KEYWORD(msp430_intrcc);
609610
KEYWORD(avr_intrcc);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
21532153
/// ::= 'aarch64_vector_pcs'
21542154
/// ::= 'aarch64_sve_vector_pcs'
21552155
/// ::= 'aarch64_sme_preservemost_from_x0'
2156+
/// ::= 'aarch64_sme_preservemost_from_x1'
21562157
/// ::= 'aarch64_sme_preservemost_from_x2'
21572158
/// ::= 'msp430_intrcc'
21582159
/// ::= 'avr_intrcc'
@@ -2212,6 +2213,9 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
22122213
case lltok::kw_aarch64_sme_preservemost_from_x0:
22132214
CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0;
22142215
break;
2216+
case lltok::kw_aarch64_sme_preservemost_from_x1:
2217+
CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1;
2218+
break;
22152219
case lltok::kw_aarch64_sme_preservemost_from_x2:
22162220
CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2;
22172221
break;

llvm/lib/IR/AsmWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
326326
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
327327
Out << "aarch64_sme_preservemost_from_x0";
328328
break;
329+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
330+
Out << "aarch64_sme_preservemost_from_x1";
331+
break;
329332
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
330333
Out << "aarch64_sme_preservemost_from_x2";
331334
break;

llvm/lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,14 @@ def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
589589
(sequence "X%u",19, 28),
590590
LR, FP)>;
591591

592+
// SME ABI support routines such as __arm_get_current_vg preserve most registers.
593+
def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
594+
: CalleeSavedRegs<(add (sequence "Z%u", 0, 31),
595+
(sequence "P%u", 0, 15),
596+
(sequence "X%u", 1, 15),
597+
(sequence "X%u",19, 28),
598+
LR, FP)>;
599+
592600
// SME ABI support routines __arm_sme_state preserves most registers.
593601
def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
594602
: CalleeSavedRegs<(add (sequence "Z%u", 0, 31),

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,22 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
107107
if (MF->getFunction().getCallingConv() ==
108108
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
109109
report_fatal_error(
110-
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
111-
"only supported to improve calls to SME ACLE save/restore/disable-za "
110+
"Calling convention "
111+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is only "
112+
"supported to improve calls to SME ACLE save/restore/disable-za "
112113
"functions, and is not intended to be used beyond that scope.");
114+
if (MF->getFunction().getCallingConv() ==
115+
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
116+
report_fatal_error(
117+
"Calling convention "
118+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
119+
"only supported to improve calls to SME ACLE __arm_get_current_vg "
120+
"function, and is not intended to be used beyond that scope.");
113121
if (MF->getFunction().getCallingConv() ==
114122
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
115123
report_fatal_error(
116-
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
124+
"Calling convention "
125+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
117126
"only supported to improve calls to SME ACLE __arm_sme_state "
118127
"and is not intended to be used beyond that scope.");
119128
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
@@ -153,13 +162,22 @@ AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
153162
if (MF->getFunction().getCallingConv() ==
154163
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
155164
report_fatal_error(
156-
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
165+
"Calling convention "
166+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
157167
"only supported to improve calls to SME ACLE save/restore/disable-za "
158168
"functions, and is not intended to be used beyond that scope.");
169+
if (MF->getFunction().getCallingConv() ==
170+
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
171+
report_fatal_error(
172+
"Calling convention "
173+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
174+
"only supported to improve calls to SME ACLE __arm_get_current_vg "
175+
"function, and is not intended to be used beyond that scope.");
159176
if (MF->getFunction().getCallingConv() ==
160177
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
161178
report_fatal_error(
162-
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
179+
"Calling convention "
180+
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
163181
"only supported to improve calls to SME ACLE __arm_sme_state "
164182
"and is not intended to be used beyond that scope.");
165183
if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS)
@@ -236,6 +254,8 @@ AArch64RegisterInfo::getDarwinCallPreservedMask(const MachineFunction &MF,
236254
"Calling convention SVE_VectorCall is unsupported on Darwin.");
237255
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
238256
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
257+
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
258+
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1_RegMask;
239259
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
240260
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
241261
if (CC == CallingConv::CFGuard_Check)
@@ -282,6 +302,8 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
282302
: CSR_AArch64_SVE_AAPCS_RegMask;
283303
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
284304
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
305+
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
306+
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1_RegMask;
285307
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
286308
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
287309
if (CC == CallingConv::CFGuard_Check)
@@ -643,6 +665,7 @@ bool AArch64RegisterInfo::isArgumentRegister(const MachineFunction &MF,
643665
case CallingConv::AArch64_VectorCall:
644666
case CallingConv::AArch64_SVE_VectorCall:
645667
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
668+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
646669
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
647670
if (STI.isTargetWindows())
648671
return HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);

llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ define void @test_sme_calling_convention_x0() nounwind {
2525
ret void
2626
}
2727

28+
define i64 @test_sme_calling_convention_x1() nounwind {
29+
; CHECK-LABEL: test_sme_calling_convention_x1:
30+
; CHECK: // %bb.0:
31+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
32+
; CHECK-NEXT: bl __arm_get_current_vg
33+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
34+
; CHECK-NEXT: ret
35+
; DARWIN-LABEL: test_sme_calling_convention_x1:
36+
; DARWIN: stp x29, x30, [sp, #-16]!
37+
; DARWIN: bl ___arm_get_current_vg
38+
; DARWIN: ldp x29, x30, [sp], #16
39+
; DARWIN: ret
40+
;
41+
; CHECK-CSRMASK-LABEL: name: test_sme_calling_convention_x1
42+
; CHECK-CSRMASK: BL @__arm_get_current_vg, csr_aarch64_sme_abi_support_routines_preservemost_from_x1
43+
%vg = call aarch64_sme_preservemost_from_x1 i64 @__arm_get_current_vg()
44+
ret i64 %vg
45+
}
46+
2847
define i64 @test_sme_calling_convention_x2() nounwind {
2948
; CHECK-LABEL: test_sme_calling_convention_x2:
3049
; CHECK: // %bb.0:
@@ -46,4 +65,5 @@ define i64 @test_sme_calling_convention_x2() nounwind {
4665
}
4766

4867
declare void @__arm_tpidr2_save()
68+
declare i64 @__arm_get_current_vg()
4969
declare {i64, i64} @__arm_sme_state()

0 commit comments

Comments
 (0)