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