[flang] Use object before converts in fir.dispatch (#68589)
[llvm-project.git] / libc / src / setjmp / x86_64 / longjmp.cpp
blob32340463e9f37baa14302f65cf0c6798af0abf04
1 //===-- Implementation of longjmp -----------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "src/setjmp/longjmp.h"
10 #include "src/__support/common.h"
12 #if !defined(LIBC_TARGET_ARCH_IS_X86_64)
13 #error "Invalid file include"
14 #endif
16 namespace LIBC_NAMESPACE {
18 LLVM_LIBC_FUNCTION(void, longjmp, (__jmp_buf * buf, int val)) {
19 register __UINT64_TYPE__ rbx __asm__("rbx");
20 register __UINT64_TYPE__ rbp __asm__("rbp");
21 register __UINT64_TYPE__ r12 __asm__("r12");
22 register __UINT64_TYPE__ r13 __asm__("r13");
23 register __UINT64_TYPE__ r14 __asm__("r14");
24 register __UINT64_TYPE__ r15 __asm__("r15");
25 register __UINT64_TYPE__ rsp __asm__("rsp");
26 register __UINT64_TYPE__ rax __asm__("rax");
28 // ABI requires that the return value should be stored in rax. So, we store
29 // |val| in rax. Note that this has to happen before we restore the registers
30 // from values in |buf|. Otherwise, once rsp and rbp are updated, we cannot
31 // read |val|.
32 val = val == 0 ? 1 : val;
33 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rax) : "m"(val) :);
34 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbx) : "m"(buf->rbx) :);
35 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbp) : "m"(buf->rbp) :);
36 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r12) : "m"(buf->r12) :);
37 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r13) : "m"(buf->r13) :);
38 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r14) : "m"(buf->r14) :);
39 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r15) : "m"(buf->r15) :);
40 LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rsp) : "m"(buf->rsp) :);
41 LIBC_INLINE_ASM("jmp *%0\n\t" : : "m"(buf->rip));
44 } // namespace LIBC_NAMESPACE