source: trunk/libs/newlib/src/newlib/libc/machine/nds32/setjmp.S @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 4.9 KB
Line 
1/*
2Copyright (c) 2013 Andes Technology Corporation.
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
8    Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    The name of the company may not be used to endorse or promote
16    products derived from this software without specific prior written
17    permission.
18
19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22DISCLAIMED.  IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
23DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31The setjmp/longjmp for nds32.
32The usage of thirty-two 32-bit General Purpose Registers (GPR):
33  $r28 : $fp
34  $r29 : $gp
35  $r30 : $lp
36  $r31 : $sp
37
38  caller-save registers: $r0 ~ $r5, $r16 ~ $r23
39  callee-save registers: $r6 ~ $r10, $r11 ~ $r14
40  reserved for assembler : $r15
41  reserved for other use : $r24, $r25, $r26, $r27
42
43Save all callee-save registers and $fp, $gp, $lp and $sp is enough in theory.
44For debugging issue, the layout of jum_buf in here should be in sync with GDB.
45The $r16 ~ $r19 are used to store D0/D1, keep them for backward-compatible.
46*/
47
48/* int setjmp(jmp_buf env);  */
49        .text
50        .align  2
51        .global setjmp
52        .type   setjmp, @function
53setjmp:
54#if __NDS32_REDUCED_REGS__
55        smw.bim $r6, [$r0], $r10, #0b0000
56        addi    $r0, $r0, #32   /* Leave room to keep jum_buf all the same.  */
57        smw.bim $r31, [$r0], $r31, #0b1111
58#else
59        smw.bim $r6, [$r0], $r14, #0b0000
60        smw.bim $r16, [$r0], $r19, #0b1111
61#endif
62
63#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
64
65        /* Extract $fpcfg.freg (b[3:2]), then save into jmp_buf.  */
66        fmfcfg  $r2
67        slli    $r2, $r2, #28
68        srli    $r2, $r2, #30
69        swi.bi  $r2, [$r0], #4
70
71        /* Make sure $r0 is double-word-aligned.  */
72        addi    $r0, $r0, #7
73        bitci   $r0, $r0, #7
74
75        /* Case switch according to $fpcfg.freg  */
76        beqz    $r2, .LCFG0_save        /* Branch if $fpcfg.freg = 0b00.  */
77        xori    $r15, $r2, #0b10
78        beqz    $r15, .LCFG2_save       /* Branch $fpcfg.freg = 0b10.  */
79        srli    $r2, $r2, #0b01
80        beqz    $r2, .LCFG1_save        /* Branch if $fpcfg.freg = 0b01.  */
81         /* Fall-through if $fpcfg.freg = 0b11.  */
82.LCFG3_save:
83        fsdi.bi $fd31, [$r0], #8
84        fsdi.bi $fd29, [$r0], #8
85        fsdi.bi $fd27, [$r0], #8
86        fsdi.bi $fd25, [$r0], #8
87        fsdi.bi $fd23, [$r0], #8
88        fsdi.bi $fd21, [$r0], #8
89        fsdi.bi $fd19, [$r0], #8
90        fsdi.bi $fd17, [$r0], #8
91.LCFG2_save:
92        fsdi.bi $fd15, [$r0], #8
93        fsdi.bi $fd13, [$r0], #8
94        fsdi.bi $fd11, [$r0], #8
95        fsdi.bi $fd9, [$r0], #8
96.LCFG1_save:
97        fsdi.bi $fd7, [$r0], #8
98        fsdi.bi $fd5, [$r0], #8
99.LCFG0_save:
100        fsdi.bi $fd3, [$r0], #8
101#endif
102
103        /* Set return value to zero.  */
104        movi    $r0, 0
105        ret
106        .size   setjmp, .-setjmp
107
108
109/* void longjmp(jmp_buf env, int val);  */
110        .text
111        .align  2
112        .global longjmp
113        .type   longjmp, @function
114longjmp:
115#if __NDS32_REDUCED_REGS__
116        lmw.bim $r6, [$r0], $r10, #0b0000
117        addi    $r0, $r0, #32
118        lmw.bim $r31, [$r0], $r31, #0b1111
119#else
120        lmw.bim $r6, [$r0], $r14, #0b0000
121        lmw.bim $r16, [$r0], $r19, #0b1111
122#endif
123
124#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
125
126        /* Restore value of $fpcfg.freg (b[3:2]).  */
127        lwi.bi  $r2, [$r0], #4
128
129        /* Make sure $r0 is double-word-aligned.  */
130        addi    $r0, $r0, #7
131        bitci   $r0, $r0, #7
132
133        /* Case switch according to $fpcfg.freg  */
134        beqz    $r2, .LCFG0_restore     /* Branch if $fpcfg.freg = 0b00.  */
135        xori    $r15, $r2, #0b10
136        beqz    $r15, .LCFG2_restore    /* Branch $fpcfg.freg = 0b10.  */
137        srli    $r2, $r2, #0b01
138        beqz    $r2, .LCFG1_restore     /* Branch if $fpcfg.freg = 0b01.  */
139         /* Fall-through if $fpcfg.freg = 0b11.  */
140.LCFG3_restore:
141        fldi.bi $fd31, [$r0], #8
142        fldi.bi $fd29, [$r0], #8
143        fldi.bi $fd27, [$r0], #8
144        fldi.bi $fd25, [$r0], #8
145        fldi.bi $fd23, [$r0], #8
146        fldi.bi $fd21, [$r0], #8
147        fldi.bi $fd19, [$r0], #8
148        fldi.bi $fd17, [$r0], #8
149.LCFG2_restore:
150        fldi.bi $fd15, [$r0], #8
151        fldi.bi $fd13, [$r0], #8
152        fldi.bi $fd11, [$r0], #8
153        fldi.bi $fd9, [$r0], #8
154.LCFG1_restore:
155        fldi.bi $fd7, [$r0], #8
156        fldi.bi $fd5, [$r0], #8
157.LCFG0_restore:
158        fldi.bi $fd3, [$r0], #8
159#endif
160
161        /* Set val as return value.  If the value val is 0, 1 will be returned
162           instead.  */
163        movi    $r0, 1
164        cmovn   $r0, $r1, $r1   /* r0=(r1!=0)? r1: r0  */
165        ret
166        .size   longjmp, .-longjmp
Note: See TracBrowser for help on using the repository browser.