2 Copyright (c) 2013 Andes Technology Corporation.
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
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):
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); */
52 .type setjmp, @function
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
59 smw.bim $r6, [$r0], $r14, #0b0000
60 smw.bim $r16, [$r0], $r19, #0b1111
63 #if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
65 /* Extract $fpcfg.freg (b[3:2]), then save into jmp_buf. */
71 /* Make sure $r0 is double-word-aligned. */
75 /* Case switch according to $fpcfg.freg */
76 beqz $r2, .LCFG0_save /* Branch if $fpcfg.freg = 0b00. */
78 beqz $r15, .LCFG2_save /* Branch $fpcfg.freg = 0b10. */
80 beqz $r2, .LCFG1_save /* Branch if $fpcfg.freg = 0b01. */
81 /* Fall-through if $fpcfg.freg = 0b11. */
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
92 fsdi.bi $fd15, [$r0], #8
93 fsdi.bi $fd13, [$r0], #8
94 fsdi.bi $fd11, [$r0], #8
95 fsdi.bi $fd9, [$r0], #8
97 fsdi.bi $fd7, [$r0], #8
98 fsdi.bi $fd5, [$r0], #8
100 fsdi.bi $fd3, [$r0], #8
103 /* Set return value to zero. */
106 .size setjmp, .-setjmp
109 /* void longjmp(jmp_buf env, int val); */
113 .type longjmp, @function
115 #if __NDS32_REDUCED_REGS__
116 lmw.bim $r6, [$r0], $r10, #0b0000
118 lmw.bim $r31, [$r0], $r31, #0b1111
120 lmw.bim $r6, [$r0], $r14, #0b0000
121 lmw.bim $r16, [$r0], $r19, #0b1111
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. */
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. */
138 beqz $r2, .LCFG1_restore /* Branch if $fpcfg.freg = 0b01. */
139 /* Fall-through if $fpcfg.freg = 0b11. */
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
150 fldi.bi $fd15, [$r0], #8
151 fldi.bi $fd13, [$r0], #8
152 fldi.bi $fd11, [$r0], #8
153 fldi.bi $fd9, [$r0], #8
155 fldi.bi $fd7, [$r0], #8
156 fldi.bi $fd5, [$r0], #8
158 fldi.bi $fd3, [$r0], #8
161 /* Set val as return value. If the value val is 0, 1 will be returned
164 cmovn $r0, $r1, $r1 /* r0=(r1!=0)? r1: r0 */
166 .size longjmp, .-longjmp