xref: /aosp_15_r20/external/llvm-libc/src/setjmp/aarch64/setjmp.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Implementation of setjmp for AArch64 ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/common.h"
10 #include "src/__support/macros/config.h"
11 #include "src/setjmp/setjmp_impl.h"
12 
13 namespace LIBC_NAMESPACE_DECL {
14 
15 [[gnu::naked]] LLVM_LIBC_FUNCTION(int, setjmp, ([[maybe_unused]] jmp_buf buf)) {
16   // If BTI branch protection is in use, the compiler will automatically insert
17   // a BTI here, so we don't need to make any extra effort to do so.
18 
19   asm(
20 #if __ARM_FEATURE_PAC_DEFAULT & 1
21       // Sign the return address using the PAC A key.
22       R"(
23         paciasp
24       )"
25 #elif __ARM_FEATURE_PAC_DEFAULT & 2
26       // Sign the return address using the PAC B key.
27       R"(
28         pacibsp
29       )"
30 #endif
31 
32       // Store all the callee-saved GPRs, including fp (x29) and also lr (x30).
33       // Of course lr isn't normally callee-saved (the call instruction itself
34       // can't help clobbering it), but we certainly need to save it for this
35       // purpose.
36       R"(
37         stp x19, x20, [x0,  #0*16]
38         stp x21, x22, [x0,  #1*16]
39         stp x23, x24, [x0,  #2*16]
40         stp x25, x26, [x0,  #3*16]
41         stp x27, x28, [x0,  #4*16]
42         stp x29, x30, [x0,  #5*16]
43       )"
44 
45 #if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER
46       // Store the stack pointer, and the platform register x18.
47       R"(
48         add x1, sp, #0
49         stp x1, x18,  [x0,  #6*16]
50       )"
51 #else
52       // Store just the stack pointer.
53       R"(
54         add x1, sp, #0
55         str x1,       [x0,  #6*16]
56       )"
57 #endif
58 
59 #if __ARM_FP
60       // Store the callee-saved FP registers. AAPCS64 only requires the low 64
61       // bits of v8-v15 to be preserved, i.e. each of d8,...,d15.
62       R"(
63         stp d8,  d9,  [x0,  #7*16]
64         stp d10, d11, [x0,  #8*16]
65         stp d12, d13, [x0,  #9*16]
66         stp d14, d15, [x0, #10*16]
67       )"
68 #endif
69 
70       // Set up return value of zero.
71       R"(
72         mov x0, #0
73       )"
74 
75 #if (__ARM_FEATURE_PAC_DEFAULT & 7) == 5
76       // Authenticate the return address using the PAC A key, since the
77       // compilation options ask for PAC protection even on leaf functions.
78       R"(
79         autiasp
80       )"
81 #elif (__ARM_FEATURE_PAC_DEFAULT & 7) == 6
82       // Same, but using the PAC B key.
83       R"(
84         autibsp
85       )"
86 #endif
87 
88       R"(
89         ret
90       )");
91 }
92 
93 } // namespace LIBC_NAMESPACE_DECL
94