Clang support for gnu_inline attribute
[uclibc-ng.git] / libc / sysdeps / linux / nds32 / setjmp.S
blob262d74925047a32d8216aed95c2a8b82d4dbd95d
1 /*
2  * Copyright (C) 2016 Andes Technology, Inc.
3  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4  */
6 /*
7   setjmp/longjmp for nds32.
8   r0 - r5 are for paramter passing - no need to save
9   r6 - r14 are callee saved - needs to save
10   r15 is temp register for assembler - no need to save
11   r16 - r25 are caller saved - no need to save
12   r26 - r27 are temp registers for OS - no need to save
13   r28 is fp - need to save
14   r29 is gp - need to save
15   r30 is ra - need to save
16   r31 is sp - need to save
17   so we need to save r6 - r14 and r28 - r31
18   The jmpbuf looks like this:
19   r6
20   r7
21   r8
22   r9
23   r10
24   r11
25   r12
26   r13
27   r14
28   fp
29   gp
30   ra
31   sp
32 #ifdef NDS32_ABI_2FP_PLUS
33   ($fpcfg.freg)
34   (callee-saved FPU regs)
35 #endif
36   reserved(for 8-byte align if needed)
39 #include <sysdep.h>
40 #define _SETJMP_H
41 #define _ASM
42 #include <bits/setjmp.h>
43         .section .text
45 ENTRY(__sigsetjmp)
46         move    $r2, $r0
47 .off_16bit
48         ! save registers into buffer
49         smw.bim $r6, [$r2], $r14, #0xf
50 .restore_16bit
52 #ifdef NDS32_ABI_2FP_PLUS
53 /* Process for FPU registers.  */
54         fmfcfg  $r20    /* Keep $fpcfg in $r20.  */
55         slli    $r20, $r20, #28
56         srli    $r20, $r20, #30 /* Set $r20 as $fpcfg.freg.  */
57         swi.bi  $r20, [$r2], #4
59         /* Case switch for $r20 as $fpcfg.freg.  */
60         beqz    $r20, .LCFG0            /* Branch if $fpcfg.freg = 0b00.  */
61         xori    $r15, $r20, #0b10
62         beqz    $r15, .LCFG2            /* Branch if $fpcfg.freg = 0b10.  */
63         srli    $r20, $r20, #0b01
64         beqz    $r20, .LCFG1            /* Branch if $fpcfg.freg = 0b01.  */
65         /* Fall-through if $fpcfg.freg = 0b11.  */
66 .LCFG3:
67         fsdi.bi $fd31, [$r2], #8
68         fsdi.bi $fd30, [$r2], #8
69         fsdi.bi $fd29, [$r2], #8
70         fsdi.bi $fd28, [$r2], #8
71         fsdi.bi $fd27, [$r2], #8
72         fsdi.bi $fd26, [$r2], #8
73         fsdi.bi $fd25, [$r2], #8
74         fsdi.bi $fd24, [$r2], #8
75 .LCFG2:
76         fsdi.bi $fd10, [$r2], #8
77         fsdi.bi $fd9, [$r2], #8
78         fsdi.bi $fd8, [$r2], #8
79 .LCFG1:
80         fsdi.bi $fd7, [$r2], #8
81         fsdi.bi $fd6, [$r2], #8
82         fsdi.bi $fd5, [$r2], #8
83         fsdi.bi $fd4, [$r2], #8
84 .LCFG0:
85         fsdi.bi $fd3, [$r2], #8
86 #endif /* NDS32_ABI_2FP_PLUS */
89 /* Make a tail call to __sigjmp_save.  */
90 #ifdef PIC
91         /* Initialize $r2 as $gp value.  */
92         sethi   $r2, hi20(_GLOBAL_OFFSET_TABLE_-8)
93         ori     $r2, $r2, lo12(_GLOBAL_OFFSET_TABLE_-4)
94         mfusr   $r15, $pc
95         add     $r2, $r15, $r2
97         ! la    $r3, __sigjmp_save@PLT
98         sethi   $r3, hi20(__sigjmp_save@PLT)
99         ori     $r3, $r3, lo12(__sigjmp_save@PLT)
100         add     $r3, $r3, $r2
102         jr      $r3
103 #else /* NOT PIC */
104         la      $r15, C_SYMBOL_NAME(__sigjmp_save)
105         jr      $r15
106 #endif
108 END(__sigsetjmp)
109 libc_hidden_def(__sigsetjmp)