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