xref: /aosp_15_r20/external/llvm-libc/src/setjmp/riscv/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 "src/__support/common.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/config.h"
12*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/properties/architectures.h"
13*71db0c75SAndroid Build Coastguard Worker 
14*71db0c75SAndroid Build Coastguard Worker #if !defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
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 #define LOAD_IMPL(insns, reg, val)                                             \
19*71db0c75SAndroid Build Coastguard Worker   LIBC_INLINE_ASM(#insns " " #reg ", %0\n\t" : : "m"(val) :)
20*71db0c75SAndroid Build Coastguard Worker 
21*71db0c75SAndroid Build Coastguard Worker #ifdef LIBC_TARGET_ARCH_IS_RISCV32
22*71db0c75SAndroid Build Coastguard Worker #define LOAD(reg, val) LOAD_IMPL(lw, reg, val)
23*71db0c75SAndroid Build Coastguard Worker #define LOAD_FP(reg, val) LOAD_IMPL(flw, reg, val)
24*71db0c75SAndroid Build Coastguard Worker #else
25*71db0c75SAndroid Build Coastguard Worker #define LOAD(reg, val) LOAD_IMPL(ld, reg, val)
26*71db0c75SAndroid Build Coastguard Worker #define LOAD_FP(reg, val) LOAD_IMPL(fld, reg, val)
27*71db0c75SAndroid Build Coastguard Worker #endif
28*71db0c75SAndroid Build Coastguard Worker 
29*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL {
30*71db0c75SAndroid Build Coastguard Worker 
31*71db0c75SAndroid Build Coastguard Worker LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) {
32*71db0c75SAndroid Build Coastguard Worker   LOAD(ra, buf->__pc);
33*71db0c75SAndroid Build Coastguard Worker   LOAD(s0, buf->__regs[0]);
34*71db0c75SAndroid Build Coastguard Worker   LOAD(s1, buf->__regs[1]);
35*71db0c75SAndroid Build Coastguard Worker   LOAD(s2, buf->__regs[2]);
36*71db0c75SAndroid Build Coastguard Worker   LOAD(s3, buf->__regs[3]);
37*71db0c75SAndroid Build Coastguard Worker   LOAD(s4, buf->__regs[4]);
38*71db0c75SAndroid Build Coastguard Worker   LOAD(s5, buf->__regs[5]);
39*71db0c75SAndroid Build Coastguard Worker   LOAD(s6, buf->__regs[6]);
40*71db0c75SAndroid Build Coastguard Worker   LOAD(s7, buf->__regs[7]);
41*71db0c75SAndroid Build Coastguard Worker   LOAD(s8, buf->__regs[8]);
42*71db0c75SAndroid Build Coastguard Worker   LOAD(s9, buf->__regs[9]);
43*71db0c75SAndroid Build Coastguard Worker   LOAD(s10, buf->__regs[10]);
44*71db0c75SAndroid Build Coastguard Worker   LOAD(s11, buf->__regs[11]);
45*71db0c75SAndroid Build Coastguard Worker   LOAD(sp, buf->__sp);
46*71db0c75SAndroid Build Coastguard Worker 
47*71db0c75SAndroid Build Coastguard Worker #if __riscv_float_abi_double
48*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs0, buf->__fpregs[0]);
49*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs1, buf->__fpregs[1]);
50*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs2, buf->__fpregs[2]);
51*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs3, buf->__fpregs[3]);
52*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs4, buf->__fpregs[4]);
53*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs5, buf->__fpregs[5]);
54*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs6, buf->__fpregs[6]);
55*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs7, buf->__fpregs[7]);
56*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs8, buf->__fpregs[8]);
57*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs9, buf->__fpregs[9]);
58*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs10, buf->__fpregs[10]);
59*71db0c75SAndroid Build Coastguard Worker   LOAD_FP(fs11, buf->__fpregs[11]);
60*71db0c75SAndroid Build Coastguard Worker #elif defined(__riscv_float_abi_single)
61*71db0c75SAndroid Build Coastguard Worker #error "longjmp implementation not available for the target architecture."
62*71db0c75SAndroid Build Coastguard Worker #endif
63*71db0c75SAndroid Build Coastguard Worker 
64*71db0c75SAndroid Build Coastguard Worker   val = val == 0 ? 1 : val;
65*71db0c75SAndroid Build Coastguard Worker   LIBC_INLINE_ASM("add a0, %0, zero\n\t" : : "r"(val) :);
66*71db0c75SAndroid Build Coastguard Worker }
67*71db0c75SAndroid Build Coastguard Worker 
68*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL
69