xref: /aosp_15_r20/external/llvm-libc/src/setjmp/x86_64/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 "include/llvm-libc-macros/offsetof-macro.h"
10 #include "src/__support/common.h"
11 #include "src/__support/macros/config.h"
12 #include "src/setjmp/setjmp_impl.h"
13 
14 #if !defined(LIBC_TARGET_ARCH_IS_X86)
15 #error "Invalid file include"
16 #endif
17 
18 namespace LIBC_NAMESPACE_DECL {
19 
20 #ifdef __i386__
21 [[gnu::naked]]
22 LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
23   asm(R"(
24       mov 4(%%esp), %%eax
25 
26       mov %%ebx, %c[ebx](%%eax)
27       mov %%esi, %c[esi](%%eax)
28       mov %%edi, %c[edi](%%eax)
29       mov %%ebp, %c[ebp](%%eax)
30 
31       lea 4(%%esp), %%ecx
32       mov %%ecx, %c[esp](%%eax)
33 
34       mov (%%esp), %%ecx
35       mov %%ecx, %c[eip](%%eax)
36 
37       xorl %%eax, %%eax
38       retl)" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
39       [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
40       [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
41       [eip] "i"(offsetof(__jmp_buf, eip))
42       : "eax", "ecx");
43 }
44 #else
45 [[gnu::naked]]
46 LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
47   asm(R"(
48       mov %%rbx, %c[rbx](%%rdi)
49       mov %%rbp, %c[rbp](%%rdi)
50       mov %%r12, %c[r12](%%rdi)
51       mov %%r13, %c[r13](%%rdi)
52       mov %%r14, %c[r14](%%rdi)
53       mov %%r15, %c[r15](%%rdi)
54 
55       lea 8(%%rsp), %%rax
56       mov %%rax, %c[rsp](%%rdi)
57 
58       mov (%%rsp), %%rax
59       mov %%rax, %c[rip](%%rdi)
60 
61       xorl %%eax, %%eax
62       retq)" ::[rbx] "i"(offsetof(__jmp_buf, rbx)),
63       [rbp] "i"(offsetof(__jmp_buf, rbp)), [r12] "i"(offsetof(__jmp_buf, r12)),
64       [r13] "i"(offsetof(__jmp_buf, r13)), [r14] "i"(offsetof(__jmp_buf, r14)),
65       [r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)),
66       [rip] "i"(offsetof(__jmp_buf, rip))
67       : "rax");
68 }
69 #endif
70 
71 } // namespace LIBC_NAMESPACE_DECL
72