1 2 //===-- Implementation of longjmp -----------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "src/setjmp/longjmp.h" 11 #include "src/__support/common.h" 12 #include "src/__support/macros/config.h" 13 14 namespace LIBC_NAMESPACE_DECL { 15 16 #if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1 17 18 [[gnu::naked, gnu::target("thumb")]] LLVM_LIBC_FUNCTION(void, longjmp, 19 (jmp_buf buf, 20 int val)) { 21 asm(R"( 22 # Reload r4, r5, r6, r7. 23 ldmia r0!, {r4-r7} 24 25 # Reload r8, r9. They cannot appear in register lists so load them 26 # into the lower registers, then move them into place. 27 ldmia r0!, {r2-r3} 28 mov r8, r2 29 mov r9, r3 30 31 # Reload r10, r11. They cannot appear in register lists so load them 32 # into the lower registers, then move them into place. 33 ldmia r0!, {r2-r3} 34 mov r10, r2 35 mov r11, r3 36 37 # Reload sp, lr. They cannot appear in register lists so load them 38 # into the lower registers, then move them into place. 39 ldmia r0!, {r2-r3} 40 mov sp, r2 41 mov lr, r3 42 43 # return val ?: 1; 44 movs r0, r1 45 bne .Lret_val 46 movs r0, #1 47 48 .Lret_val: 49 bx lr)"); 50 } 51 52 #else // Thumb2 or ARM 53 54 // TODO(https://github.com/llvm/llvm-project/issues/94061): fp registers 55 // (d0-d16) 56 // TODO(https://github.com/llvm/llvm-project/issues/94062): pac+bti 57 [[gnu::naked]] LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) { 58 asm(R"( 59 # While sp may appear in a register list for ARM mode, it may not for 60 # Thumb2 mode. Just load the previous value of sp into r12 then move it 61 # into sp, so that this code is portable between ARM and Thumb2. 62 63 ldm r0, {r4-r12, lr} 64 mov sp, r12 65 66 # return val ?: 1; 67 movs r0, r1 68 it eq 69 moveq r0, #1 70 bx lr)"); 71 } 72 73 #endif 74 75 } // namespace LIBC_NAMESPACE_DECL 76