source: trunk/libs/newlib/src/newlib/libc/machine/powerpc/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: 7.1 KB
Line 
1/* This is a simple version of setjmp and longjmp for the PowerPC.
2   Ian Lance Taylor, Cygnus Support, 9 Feb 1994. 
3   Modified by Jeff Johnston, Red Hat Inc. 2 Oct 2001. */
4
5#include "ppc-asm.h"
6
7FUNC_START(setjmp)
8#ifdef __ALTIVEC__
9        addi    3,3,15          # align Altivec to 16 byte boundary
10        rlwinm  3,3,0,0,27
11#else
12        addi    3,3,7           # align to 8 byte boundary
13        rlwinm  3,3,0,0,28
14#endif
15#if __SPE__
16        /* If we are E500, then save 64-bit registers.  */
17        evstdd  1,0(3)          # offset 0
18        evstdd  2,8(3)          # offset 8
19        evstdd  13,16(3)        # offset 16
20        evstdd  14,24(3)        # offset 24
21        evstdd  15,32(3)        # offset 32
22        evstdd  16,40(3)        # offset 40
23        evstdd  17,48(3)        # offset 48
24        evstdd  18,56(3)        # offset 56
25        evstdd  19,64(3)        # offset 64
26        evstdd  20,72(3)        # offset 72
27        evstdd  21,80(3)        # offset 80
28        evstdd  22,88(3)        # offset 88
29        evstdd  23,96(3)        # offset 96
30        evstdd  24,104(3)       # offset 104
31        evstdd  25,112(3)       # offset 112
32        evstdd  26,120(3)       # offset 120
33        evstdd  27,128(3)       # offset 128
34        evstdd  28,136(3)       # offset 136
35        evstdd  29,144(3)       # offset 144
36        evstdd  30,152(3)       # offset 152
37        evstdd  31,160(3)       # offset 160
38
39        /* Add 164 to r3 to account for the amount of data we just
40           stored.  Note that we are not adding 168 because the next
41           store instruction uses an offset of 4.  */
42        addi    3,3,164
43#else
44        stw     1,0(3)          # offset 0
45        stwu    2,4(3)          # offset 4
46        stwu    13,4(3)         # offset 8
47        stwu    14,4(3)         # offset 12
48        stwu    15,4(3)         # offset 16
49        stwu    16,4(3)         # offset 20
50        stwu    17,4(3)         # offset 24
51        stwu    18,4(3)         # offset 28
52        stwu    19,4(3)         # offset 32
53        stwu    20,4(3)         # offset 36
54        stwu    21,4(3)         # offset 40
55        stwu    22,4(3)         # offset 44
56        stwu    23,4(3)         # offset 48
57        stwu    24,4(3)         # offset 52
58        stwu    25,4(3)         # offset 56
59        stwu    26,4(3)         # offset 60
60        stwu    27,4(3)         # offset 64
61        stwu    28,4(3)         # offset 68
62        stwu    29,4(3)         # offset 72
63        stwu    30,4(3)         # offset 76
64        stwu    31,4(3)         # offset 80
65#endif
66
67        /* From this point on until the end of this function, add 84
68           to the offset shown if __SPE__.  This difference comes from
69           the fact that we save 21 64-bit registers instead of 21
70           32-bit registers above.  */
71        mflr    4
72        stwu    4,4(3)          # offset 84
73        mfcr    4
74        stwu    4,4(3)          # offset 88
75                                # one word pad to get floating point aligned on 8 byte boundary
76
77        /* Check whether we need to save FPRs.  Checking __NO_FPRS__
78           on its own would be enough for GCC 4.1 and above, but older
79           compilers only define _SOFT_FLOAT, so check both.  */
80#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
81        stfdu   14,8(3)         # offset 96
82        stfdu   15,8(3)         # offset 104
83        stfdu   16,8(3)         # offset 112
84        stfdu   17,8(3)         # offset 120
85        stfdu   18,8(3)         # offset 128
86        stfdu   19,8(3)         # offset 136
87        stfdu   20,8(3)         # offset 144
88        stfdu   21,8(3)         # offset 152
89        stfdu   22,8(3)         # offset 160
90        stfdu   23,8(3)         # offset 168
91        stfdu   24,8(3)         # offset 176
92        stfdu   25,8(3)         # offset 184
93        stfdu   26,8(3)         # offset 192
94        stfdu   27,8(3)         # offset 200
95        stfdu   28,8(3)         # offset 208
96        stfdu   29,8(3)         # offset 216
97        stfdu   30,8(3)         # offset 224
98        stfdu   31,8(3)         # offset 232
99#endif
100
101        /* This requires a total of 21 * 4 + 18 * 8 + 4 + 4 + 4
102           bytes == 60 * 4 bytes == 240 bytes.  */
103
104#ifdef __ALTIVEC__
105        /* save Altivec vrsave and vr20-vr31 registers */
106        mfspr   4,256           # vrsave register
107        stwu    4,16(3)         # offset 248
108        addi    3,3,8
109        stvx    20,0,3          # offset 256
110        addi    3,3,16
111        stvx    21,0,3          # offset 272
112        addi    3,3,16
113        stvx    22,0,3          # offset 288
114        addi    3,3,16
115        stvx    23,0,3          # offset 304
116        addi    3,3,16
117        stvx    24,0,3          # offset 320
118        addi    3,3,16
119        stvx    25,0,3          # offset 336
120        addi    3,3,16
121        stvx    26,0,3          # offset 352
122        addi    3,3,16
123        stvx    27,0,3          # offset 368
124        addi    3,3,16
125        stvx    28,0,3          # offset 384
126        addi    3,3,16
127        stvx    29,0,3          # offset 400
128        addi    3,3,16
129        stvx    30,0,3          # offset 416
130        addi    3,3,16
131        stvx    31,0,3          # offset 432
132
133        /* This requires a total of 240 + 8 + 8 + 12 * 16 == 448 bytes. */
134#endif
135        li      3,0
136        blr
137FUNC_END(setjmp)
138
139
140FUNC_START(longjmp)
141#ifdef __ALTIVEC__
142        addi    3,3,15          # align Altivec to 16 byte boundary
143        rlwinm  3,3,0,0,27
144#else
145        addi    3,3,7           # align to 8 byte boundary
146        rlwinm  3,3,0,0,28
147#endif
148#if __SPE__
149        /* If we are E500, then restore 64-bit registers.  */
150        evldd   1,0(3)          # offset 0
151        evldd   2,8(3)          # offset 8
152        evldd   13,16(3)        # offset 16
153        evldd   14,24(3)        # offset 24
154        evldd   15,32(3)        # offset 32
155        evldd   16,40(3)        # offset 40
156        evldd   17,48(3)        # offset 48
157        evldd   18,56(3)        # offset 56
158        evldd   19,64(3)        # offset 64
159        evldd   20,72(3)        # offset 72
160        evldd   21,80(3)        # offset 80
161        evldd   22,88(3)        # offset 88
162        evldd   23,96(3)        # offset 96
163        evldd   24,104(3)       # offset 104
164        evldd   25,112(3)       # offset 112
165        evldd   26,120(3)       # offset 120
166        evldd   27,128(3)       # offset 128
167        evldd   28,136(3)       # offset 136
168        evldd   29,144(3)       # offset 144
169        evldd   30,152(3)       # offset 152
170        evldd   31,160(3)       # offset 160
171
172        /* Add 164 to r3 to account for the amount of data we just
173           loaded.  Note that we are not adding 168 because the next
174           load instruction uses an offset of 4.  */
175        addi    3,3,164
176#else
177        lwz     1,0(3)          # offset 0
178        lwzu    2,4(3)          # offset 4
179        lwzu    13,4(3)         # offset 8
180        lwzu    14,4(3)         # offset 12
181        lwzu    15,4(3)         # offset 16
182        lwzu    16,4(3)         # offset 20
183        lwzu    17,4(3)         # offset 24
184        lwzu    18,4(3)         # offset 28
185        lwzu    19,4(3)         # offset 32
186        lwzu    20,4(3)         # offset 36
187        lwzu    21,4(3)         # offset 40
188        lwzu    22,4(3)         # offset 44
189        lwzu    23,4(3)         # offset 48
190        lwzu    24,4(3)         # offset 52
191        lwzu    25,4(3)         # offset 56
192        lwzu    26,4(3)         # offset 60
193        lwzu    27,4(3)         # offset 64
194        lwzu    28,4(3)         # offset 68
195        lwzu    29,4(3)         # offset 72
196        lwzu    30,4(3)         # offset 76
197        lwzu    31,4(3)         # offset 80
198#endif
199        /* From this point on until the end of this function, add 84
200           to the offset shown if __SPE__.  This difference comes from
201           the fact that we restore 21 64-bit registers instead of 21
202           32-bit registers above.  */
203        lwzu    5,4(3)          # offset 84
204        mtlr    5
205        lwzu    5,4(3)          # offset 88
206        mtcrf   255,5
207                                # one word pad to get floating point aligned on 8 byte boundary
208
209        /* Check whether we need to restore FPRs.  Checking
210           __NO_FPRS__ on its own would be enough for GCC 4.1 and
211           above, but older compilers only define _SOFT_FLOAT, so
212           check both.  */
213#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
214        lfdu    14,8(3)         # offset 96
215        lfdu    15,8(3)         # offset 104
216        lfdu    16,8(3)         # offset 112
217        lfdu    17,8(3)         # offset 120
218        lfdu    18,8(3)         # offset 128
219        lfdu    19,8(3)         # offset 136
220        lfdu    20,8(3)         # offset 144
221        lfdu    21,8(3)         # offset 152
222        lfdu    22,8(3)         # offset 160
223        lfdu    23,8(3)         # offset 168
224        lfdu    24,8(3)         # offset 176
225        lfdu    25,8(3)         # offset 184
226        lfdu    26,8(3)         # offset 192
227        lfdu    27,8(3)         # offset 200
228        lfdu    28,8(3)         # offset 208
229        lfdu    29,8(3)         # offset 216
230        lfdu    30,8(3)         # offset 224
231        lfdu    31,8(3)         # offset 232
232#endif
233
234#ifdef __ALTIVEC__
235        /* restore Altivec vrsave and v20-v31 registers */
236        lwzu    5,16(3)         # offset 248
237        mtspr   256,5           # vrsave
238        addi    3,3,8
239        lvx     20,0,3          # offset 256
240        addi    3,3,16
241        lvx     21,0,3          # offset 272
242        addi    3,3,16
243        lvx     22,0,3          # offset 288
244        addi    3,3,16
245        lvx     23,0,3          # offset 304
246        addi    3,3,16
247        lvx     24,0,3          # offset 320
248        addi    3,3,16
249        lvx     25,0,3          # offset 336
250        addi    3,3,16
251        lvx     26,0,3          # offset 352
252        addi    3,3,16
253        lvx     27,0,3          # offset 368
254        addi    3,3,16
255        lvx     28,0,3          # offset 384
256        addi    3,3,16
257        lvx     29,0,3          # offset 400
258        addi    3,3,16
259        lvx     30,0,3          # offset 416
260        addi    3,3,16
261        lvx     31,0,3          # offset 432
262#endif
263
264        mr.     3,4
265        bclr+   4,2
266        li      3,1
267        blr
268FUNC_END(longjmp)
Note: See TracBrowser for help on using the repository browser.