xref: /llvm-project/libc/src/setjmp/x86_64/setjmp.cpp (revision b1320d36339e38b073088fd45013a3c692adb301)
10f6fd1b7SMikhail R. Gadelha //===-- Implementation of setjmp ------------------------------------------===//
20f6fd1b7SMikhail R. Gadelha //
30f6fd1b7SMikhail R. Gadelha // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40f6fd1b7SMikhail R. Gadelha // See https://llvm.org/LICENSE.txt for license information.
50f6fd1b7SMikhail R. Gadelha // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60f6fd1b7SMikhail R. Gadelha //
70f6fd1b7SMikhail R. Gadelha //===----------------------------------------------------------------------===//
80f6fd1b7SMikhail R. Gadelha 
966f968cfSNick Desaulniers #include "include/llvm-libc-macros/offsetof-macro.h"
100f6fd1b7SMikhail R. Gadelha #include "src/__support/common.h"
115ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
120f6fd1b7SMikhail R. Gadelha #include "src/setjmp/setjmp_impl.h"
130f6fd1b7SMikhail R. Gadelha 
14*b1320d36SNick Desaulniers #if !defined(LIBC_TARGET_ARCH_IS_X86)
150f6fd1b7SMikhail R. Gadelha #error "Invalid file include"
160f6fd1b7SMikhail R. Gadelha #endif
170f6fd1b7SMikhail R. Gadelha 
185ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
190f6fd1b7SMikhail R. Gadelha 
20*b1320d36SNick Desaulniers #ifdef __i386__
21*b1320d36SNick Desaulniers [[gnu::naked]]
22*b1320d36SNick Desaulniers LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
23*b1320d36SNick Desaulniers   asm(R"(
24*b1320d36SNick Desaulniers       mov 4(%%esp), %%eax
25*b1320d36SNick Desaulniers 
26*b1320d36SNick Desaulniers       mov %%ebx, %c[ebx](%%eax)
27*b1320d36SNick Desaulniers       mov %%esi, %c[esi](%%eax)
28*b1320d36SNick Desaulniers       mov %%edi, %c[edi](%%eax)
29*b1320d36SNick Desaulniers       mov %%ebp, %c[ebp](%%eax)
30*b1320d36SNick Desaulniers 
31*b1320d36SNick Desaulniers       lea 4(%%esp), %%ecx
32*b1320d36SNick Desaulniers       mov %%ecx, %c[esp](%%eax)
33*b1320d36SNick Desaulniers 
34*b1320d36SNick Desaulniers       mov (%%esp), %%ecx
35*b1320d36SNick Desaulniers       mov %%ecx, %c[eip](%%eax)
36*b1320d36SNick Desaulniers 
37*b1320d36SNick Desaulniers       xorl %%eax, %%eax
38*b1320d36SNick Desaulniers       retl)" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
39*b1320d36SNick Desaulniers       [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
40*b1320d36SNick Desaulniers       [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
41*b1320d36SNick Desaulniers       [eip] "i"(offsetof(__jmp_buf, eip))
42*b1320d36SNick Desaulniers       : "eax", "ecx");
43*b1320d36SNick Desaulniers }
44*b1320d36SNick Desaulniers #else
4566f968cfSNick Desaulniers [[gnu::naked]]
4646200fcfSNick Desaulniers LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
4766f968cfSNick Desaulniers   asm(R"(
4866f968cfSNick Desaulniers       mov %%rbx, %c[rbx](%%rdi)
4966f968cfSNick Desaulniers       mov %%rbp, %c[rbp](%%rdi)
5066f968cfSNick Desaulniers       mov %%r12, %c[r12](%%rdi)
5166f968cfSNick Desaulniers       mov %%r13, %c[r13](%%rdi)
5266f968cfSNick Desaulniers       mov %%r14, %c[r14](%%rdi)
5366f968cfSNick Desaulniers       mov %%r15, %c[r15](%%rdi)
540f6fd1b7SMikhail R. Gadelha 
5566f968cfSNick Desaulniers       lea 8(%%rsp), %%rax
5666f968cfSNick Desaulniers       mov %%rax, %c[rsp](%%rdi)
570f6fd1b7SMikhail R. Gadelha 
5866f968cfSNick Desaulniers       mov (%%rsp), %%rax
5966f968cfSNick Desaulniers       mov %%rax, %c[rip](%%rdi)
600f6fd1b7SMikhail R. Gadelha 
6166f968cfSNick Desaulniers       xorl %%eax, %%eax
6266f968cfSNick Desaulniers       retq)" ::[rbx] "i"(offsetof(__jmp_buf, rbx)),
6366f968cfSNick Desaulniers       [rbp] "i"(offsetof(__jmp_buf, rbp)), [r12] "i"(offsetof(__jmp_buf, r12)),
6466f968cfSNick Desaulniers       [r13] "i"(offsetof(__jmp_buf, r13)), [r14] "i"(offsetof(__jmp_buf, r14)),
6566f968cfSNick Desaulniers       [r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)),
6666f968cfSNick Desaulniers       [rip] "i"(offsetof(__jmp_buf, rip))
6766f968cfSNick Desaulniers       : "rax");
680f6fd1b7SMikhail R. Gadelha }
69*b1320d36SNick Desaulniers #endif
700f6fd1b7SMikhail R. Gadelha 
715ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
72