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