Cygwin: access: Fix X_OK behaviour for backup operators and admins
[newlib-cygwin.git] / newlib / libc / machine / nds32 / setjmp.S
blob7197c86f396193548f6b2b5c41e4787af684ad38
1 /*
2 Copyright (c) 2013 Andes Technology Corporation.
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8     Redistributions of source code must retain the above copyright
9     notice, this list of conditions and the following disclaimer.
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.
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.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED.  IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON 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
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 The setjmp/longjmp for nds32.
32 The usage of thirty-two 32-bit General Purpose Registers (GPR):
33   $r28 : $fp
34   $r29 : $gp
35   $r30 : $lp
36   $r31 : $sp
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
43 Save all callee-save registers and $fp, $gp, $lp and $sp is enough in theory.
44 For debugging issue, the layout of jum_buf in here should be in sync with GDB.
45 The $r16 ~ $r19 are used to store D0/D1, keep them for backward-compatible.
48 /* int setjmp(jmp_buf env);  */
49         .text
50         .align  2
51         .global setjmp
52         .type   setjmp, @function
53 setjmp:
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
63 #if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
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
71         /* Make sure $r0 is double-word-aligned.  */
72         addi    $r0, $r0, #7
73         bitci   $r0, $r0, #7
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
103         /* Set return value to zero.  */
104         movi    $r0, 0
105         ret
106         .size   setjmp, .-setjmp
109 /* void longjmp(jmp_buf env, int val);  */
110         .text
111         .align  2
112         .global longjmp
113         .type   longjmp, @function
114 longjmp:
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
124 #if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
126         /* Restore value of $fpcfg.freg (b[3:2]).  */
127         lwi.bi  $r2, [$r0], #4
129         /* Make sure $r0 is double-word-aligned.  */
130         addi    $r0, $r0, #7
131         bitci   $r0, $r0, #7
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
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