xref: /aosp_15_r20/external/llvm-libc/src/setjmp/arm/setjmp.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Implementation of setjmp ------------------------------------------===//
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 #if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
16 
17 [[gnu::naked, gnu::target("thumb")]] LLVM_LIBC_FUNCTION(int, setjmp,
18                                                         (jmp_buf buf)) {
19   asm(R"(
20       # Store r4, r5, r6, and r7 into buf.
21       stmia r0!, {r4-r7}
22 
23       # Store r8, r9, r10, r11, sp, and lr into buf. Thumb(1) doesn't support
24       # the high registers > r7 in stmia, so move them into lower GPRs first.
25       # Thumb(1) also doesn't support using str with sp or lr, move them
26       # together with the rest.
27       mov r1, r8
28       mov r2, r9
29       mov r3, r10
30       stmia r0!, {r1-r3}
31 
32       mov r1, r11
33       mov r2, sp
34       mov r3, lr
35       stmia r0!, {r1-r3}
36 
37       # Return 0.
38       movs r0, #0
39       bx lr)");
40 }
41 
42 #else // Thumb2 or ARM
43 
44 // TODO(https://github.com/llvm/llvm-project/issues/94061): fp registers
45 // (d0-d16)
46 // TODO(https://github.com/llvm/llvm-project/issues/94062): pac+bti
47 [[gnu::naked]] LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
48   asm(R"(
49       # While sp may appear in a register list for ARM mode, it may not for
50       # Thumb2 mode. Just move it into r12 then stm that, so that this code
51       # is portable between ARM and Thumb2.
52       mov r12, sp
53 
54       # Store r4, r5, r6, r7, r8, r9, r10, r11, sp, and lr into buf.
55       stm r0, {r4-r12, lr}
56 
57       # Return zero.
58       mov r0, #0
59       bx lr)");
60 }
61 
62 #endif
63 
64 } // namespace LIBC_NAMESPACE_DECL
65