xref: /aosp_15_r20/external/llvm-libc/src/setjmp/x86_64/longjmp.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Implementation of longjmp -----------------------------------------===//
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/setjmp/longjmp.h"
10*71db0c75SAndroid Build Coastguard Worker #include "include/llvm-libc-macros/offsetof-macro.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/__support/common.h"
12*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/config.h"
13*71db0c75SAndroid Build Coastguard Worker 
14*71db0c75SAndroid Build Coastguard Worker #if !defined(LIBC_TARGET_ARCH_IS_X86)
15*71db0c75SAndroid Build Coastguard Worker #error "Invalid file include"
16*71db0c75SAndroid Build Coastguard Worker #endif
17*71db0c75SAndroid Build Coastguard Worker 
18*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL {
19*71db0c75SAndroid Build Coastguard Worker 
20*71db0c75SAndroid Build Coastguard Worker #ifdef __i386__
21*71db0c75SAndroid Build Coastguard Worker [[gnu::naked]]
22*71db0c75SAndroid Build Coastguard Worker LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
23*71db0c75SAndroid Build Coastguard Worker   asm(R"(
24*71db0c75SAndroid Build Coastguard Worker       mov 0x4(%%esp), %%ecx
25*71db0c75SAndroid Build Coastguard Worker       mov 0x8(%%esp), %%eax
26*71db0c75SAndroid Build Coastguard Worker       cmpl $0x1, %%eax
27*71db0c75SAndroid Build Coastguard Worker       adcl $0x0, %%eax
28*71db0c75SAndroid Build Coastguard Worker 
29*71db0c75SAndroid Build Coastguard Worker       mov %c[ebx](%%ecx), %%ebx
30*71db0c75SAndroid Build Coastguard Worker       mov %c[esi](%%ecx), %%esi
31*71db0c75SAndroid Build Coastguard Worker       mov %c[edi](%%ecx), %%edi
32*71db0c75SAndroid Build Coastguard Worker       mov %c[ebp](%%ecx), %%ebp
33*71db0c75SAndroid Build Coastguard Worker       mov %c[esp](%%ecx), %%esp
34*71db0c75SAndroid Build Coastguard Worker 
35*71db0c75SAndroid Build Coastguard Worker       jmp *%c[eip](%%ecx)
36*71db0c75SAndroid Build Coastguard Worker       )" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
37*71db0c75SAndroid Build Coastguard Worker       [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
38*71db0c75SAndroid Build Coastguard Worker       [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
39*71db0c75SAndroid Build Coastguard Worker       [eip] "i"(offsetof(__jmp_buf, eip)));
40*71db0c75SAndroid Build Coastguard Worker }
41*71db0c75SAndroid Build Coastguard Worker #else
42*71db0c75SAndroid Build Coastguard Worker [[gnu::naked]]
43*71db0c75SAndroid Build Coastguard Worker LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
44*71db0c75SAndroid Build Coastguard Worker   asm(R"(
45*71db0c75SAndroid Build Coastguard Worker       cmpl $0x1, %%esi
46*71db0c75SAndroid Build Coastguard Worker       adcl $0x0, %%esi
47*71db0c75SAndroid Build Coastguard Worker       movq %%rsi, %%rax
48*71db0c75SAndroid Build Coastguard Worker 
49*71db0c75SAndroid Build Coastguard Worker       movq %c[rbx](%%rdi), %%rbx
50*71db0c75SAndroid Build Coastguard Worker       movq %c[rbp](%%rdi), %%rbp
51*71db0c75SAndroid Build Coastguard Worker       movq %c[r12](%%rdi), %%r12
52*71db0c75SAndroid Build Coastguard Worker       movq %c[r13](%%rdi), %%r13
53*71db0c75SAndroid Build Coastguard Worker       movq %c[r14](%%rdi), %%r14
54*71db0c75SAndroid Build Coastguard Worker       movq %c[r15](%%rdi), %%r15
55*71db0c75SAndroid Build Coastguard Worker       movq %c[rsp](%%rdi), %%rsp
56*71db0c75SAndroid Build Coastguard Worker       jmpq *%c[rip](%%rdi)
57*71db0c75SAndroid Build Coastguard Worker       )" ::[rbx] "i"(offsetof(__jmp_buf, rbx)),
58*71db0c75SAndroid Build Coastguard Worker       [rbp] "i"(offsetof(__jmp_buf, rbp)), [r12] "i"(offsetof(__jmp_buf, r12)),
59*71db0c75SAndroid Build Coastguard Worker       [r13] "i"(offsetof(__jmp_buf, r13)), [r14] "i"(offsetof(__jmp_buf, r14)),
60*71db0c75SAndroid Build Coastguard Worker       [r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)),
61*71db0c75SAndroid Build Coastguard Worker       [rip] "i"(offsetof(__jmp_buf, rip)));
62*71db0c75SAndroid Build Coastguard Worker }
63*71db0c75SAndroid Build Coastguard Worker #endif
64*71db0c75SAndroid Build Coastguard Worker 
65*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL
66