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