1 /*
2 Copyright (C) 1991 DJ Delorie
3 All rights reserved.
4 
5 Redistribution, modification, and use in source and binary forms is permitted
6 provided that the above copyright notice and following paragraph are
7 duplicated in all such forms.
8 
9 This file is distributed WITHOUT ANY WARRANTY; without even the implied
10 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 _BEGIN_STD_C
14 
15 #if defined(__or1k__) || defined(__or1knd__)
16 /*
17  * r1, r2, r9, r14, r16 .. r30, SR.
18  */
19 #define _JBLEN 13
20 #define _JBTYPE unsigned long
21 #endif
22 
23 #if defined(__arm__) || defined(__thumb__)
24 /*
25  * All callee preserved registers:
26  *  core registers:
27  *   r4 - r10, fp, sp, lr
28  *  VFP registers (architectural support dependent):
29  *   d8 - d15
30  */
31 #define _JBLEN 20
32 #define _JBTYPE long long
33 #endif
34 
35 #if defined(__aarch64__)
36 #define _JBLEN 22
37 #define _JBTYPE long long
38 #endif
39 
40 #if defined(__AVR__)
41 #define _JBLEN 24
42 #endif
43 
44 #ifdef __sparc__
45 /*
46  * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
47  * All else recovered by under/over(flow) handling.
48  */
49 #define	_JBLEN	13
50 #endif
51 
52 #ifdef __BFIN__
53 #define _JBLEN  40
54 #endif
55 
56 #ifdef __epiphany__
57 /* All callee preserved registers: r4-r10,fp, sp, lr,r15, r32-r39  */
58 #define _JBTYPE long long
59 #define _JBLEN 10
60 #endif
61 
62 /* necv70 was 9 as well. */
63 
64 #if defined(__m68k__) || defined(__mc68000__)
65 /*
66  * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6,
67  * fp2-fp7	for 68881.
68  * All else recovered by under/over(flow) handling.
69  */
70 #define	_JBLEN	34
71 #endif
72 
73 #if defined(__mc68hc11__) || defined(__mc68hc12__) || defined(__mc68hc1x__)
74 /*
75  * D, X, Y are not saved.
76  * Only take into account the pseudo soft registers (max 32).
77  */
78 #define _JBLEN  32
79 #endif
80 
81 #ifdef __nds32__
82 /* 17 words for GPRs,
83    1 word for $fpcfg.freg and 30 words for FPUs
84    Reserved 2 words for aligement-adjustment. When storeing double-precision
85    floating-point register into memory, the address has to be
86    double-word-aligned.
87    Check libc/machine/nds32/setjmp.S for more information.  */
88 #if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
89 #define	_JBLEN 50
90 #else
91 #define _JBLEN 18
92 #endif
93 #endif
94 
95 #if defined(__Z8001__) || defined(__Z8002__)
96 /* 16 regs + pc */
97 #define _JBLEN 20
98 #endif
99 
100 #ifdef _AM29K
101 /*
102  * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
103  * All else recovered by under/over(flow) handling.
104  */
105 #define	_JBLEN	9
106 #endif
107 
108 #ifdef __i386__
109 # if defined(__CYGWIN__) && !defined (_JBLEN)
110 #  define _JBLEN (13 * 4)
111 # elif defined(__unix__) || defined(__rtems__)
112 #  define _JBLEN	9
113 # elif defined(__iamcu__)
114 /* Intel MCU jmp_buf only covers callee-saved registers. */
115 #  define _JBLEN	6
116 # else
117 #  include "setjmp-dj.h"
118 # endif
119 #endif
120 
121 #ifdef __x86_64__
122 # ifdef __CYGWIN__
123 #  define _JBTYPE long
124 #  define _JBLEN  32
125 # else
126 #  define _JBTYPE long long
127 #  define _JBLEN  8
128 # endif
129 #endif
130 
131 #ifdef __i960__
132 #define _JBLEN 35
133 #endif
134 
135 #ifdef __M32R__
136 /* Only 8 words are currently needed.  10 gives us some slop if we need
137    to expand.  */
138 #define _JBLEN 10
139 #endif
140 
141 #ifdef __mips__
142 # if defined(__mips64)
143 #  define _JBTYPE long long
144 # endif
145 # ifdef __mips_soft_float
146 #  define _JBLEN 11
147 # else
148 #  define _JBLEN 23
149 # endif
150 #endif
151 
152 #ifdef __m88000__
153 #define _JBLEN 21
154 #endif
155 
156 #ifdef __H8300__
157 #define _JBLEN 5
158 #define _JBTYPE int
159 #endif
160 
161 #ifdef __H8300H__
162 /* same as H8/300 but registers are twice as big */
163 #define _JBLEN 5
164 #define _JBTYPE long
165 #endif
166 
167 #if defined (__H8300S__) || defined (__H8300SX__)
168 /* same as H8/300 but registers are twice as big */
169 #define _JBLEN 5
170 #define _JBTYPE long
171 #endif
172 
173 #ifdef __H8500__
174 #define _JBLEN 4
175 #endif
176 
177 #ifdef  __sh__
178 #if __SH5__
179 #define _JBLEN 50
180 #define _JBTYPE long long
181 #else
182 #define _JBLEN 20
183 #endif /* __SH5__ */
184 #endif
185 
186 #ifdef  __v800
187 #define _JBLEN 28
188 #endif
189 
190 #ifdef __PPC__
191 #ifdef __powerpc64__
192 #ifdef __ALTIVEC__
193 #define _JBLEN 70
194 #else
195 #define _JBLEN 43
196 #endif
197 #else
198 #ifdef __ALTIVEC__
199 #define _JBLEN 64
200 #else
201 #define _JBLEN 32
202 #endif
203 #endif
204 #define _JBTYPE double
205 #endif
206 
207 #ifdef __MICROBLAZE__
208 #define _JBLEN  20
209 #define _JBTYPE unsigned int
210 #endif
211 
212 #ifdef __hppa__
213 /* %r30, %r2-%r18, %r27, pad, %fr12-%fr15.
214    Note space exists for the FP registers, but they are not
215    saved.  */
216 #define _JBLEN 28
217 #endif
218 
219 #if defined(__mn10300__) || defined(__mn10200__)
220 #ifdef __AM33_2__
221 #define _JBLEN 26
222 #else
223 /* A guess */
224 #define _JBLEN 10
225 #endif
226 #endif
227 
228 #ifdef __v850
229 /* I think our setjmp is saving 15 regs at the moment.  Gives us one word
230    slop if we need to expand.  */
231 #define _JBLEN 16
232 #endif
233 
234 #if defined(_C4x)
235 #define _JBLEN 10
236 #endif
237 #if defined(_C3x)
238 #define _JBLEN 9
239 #endif
240 
241 #ifdef __TMS320C6X__
242 #define _JBLEN 13
243 #endif
244 
245 #ifdef __TIC80__
246 #define _JBLEN 13
247 #endif
248 
249 #ifdef __D10V__
250 #define _JBLEN 8
251 #endif
252 
253 #ifdef __D30V__
254 #define _JBLEN ((64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */) / 2)
255 #define _JBTYPE double
256 #endif
257 
258 #ifdef __frv__
259 #define _JBLEN (68/2)  /* room for 68 32-bit regs */
260 #define _JBTYPE double
261 #endif
262 
263 #ifdef __moxie__
264 #define _JBLEN 10
265 #endif
266 
267 #ifdef __CRX__
268 #define _JBLEN 9
269 #endif
270 
271 #if (defined(__CR16__) || defined(__CR16C__) ||defined(__CR16CP__))
272 /* r6, r7, r8, r9, r10, r11, r12 (r12L, r12H),
273  * r13 (r13L, r13H), ra(raL, raH), sp(spL, spH) */
274 #define _JBLEN 14
275 #define _JBTYPE unsigned short
276 #endif
277 
278 #ifdef __fr30__
279 #define _JBLEN 10
280 #endif
281 
282 #ifdef  __FT32__
283 #define _JBLEN 27
284 #endif
285 
286 #ifdef __iq2000__
287 #define _JBLEN 32
288 #endif
289 
290 #ifdef __mcore__
291 #define _JBLEN 16
292 #endif
293 
294 #if defined(__arc__) || defined(__ARC64__)
295 #define _JBLEN 25 /* r13-r30,blink,lp_count,lp_start,lp_end,mlo,mhi,status32 */
296 #define _JBTYPE unsigned long
297 #endif
298 
299 #ifdef __MMIX__
300 /* Using a layout compatible with GCC's built-in.  */
301 #define _JBLEN 5
302 #define _JBTYPE unsigned long
303 #endif
304 
305 #ifdef __mt__
306 #define _JBLEN 16
307 #endif
308 
309 #ifdef __SPU__
310 #define _JBLEN 50
311 #define _JBTYPE __vector signed int
312 #endif
313 
314 #ifdef __xstormy16__
315 /* 4 GPRs plus SP plus PC. */
316 #define _JBLEN 8
317 #endif
318 
319 #ifdef __XTENSA__
320 #if __XTENSA_WINDOWED_ABI__
321 
322 /* The jmp_buf structure for Xtensa windowed ABI holds the following
323    (where "proc" is the procedure that calls setjmp): 4-12 registers
324    from the window of proc, the 4 words from the save area at proc's $sp
325    (in case a subsequent alloca in proc moves $sp), and the return
326    address within proc. Everything else is saved on the stack in the
327    normal save areas. The jmp_buf structure is:
328 
329    struct jmp_buf {
330       int regs[12];
331       int save[4];
332       void *return_address;
333    }
334 
335    See the setjmp code for details.  */
336 
337 /* sizeof(struct jmp_buf) */
338 #define _JBLEN 17
339 
340 #else /* __XTENSA_CALL0_ABI__ */
341 
342 /* a0, a1, a12, a13, a14, a15 */
343 #define _JBLEN 6
344 
345 #endif /* __XTENSA_CALL0_ABI__ */
346 #endif /* __XTENSA__ */
347 
348 #ifdef __mep__
349 /* 16 GPRs, pc, hi, lo */
350 #define _JBLEN 19
351 #endif
352 
353 #ifdef __CRIS__
354 #define _JBLEN 18
355 #endif
356 
357 #ifdef __ia64
358 #define _JBLEN 64
359 #endif
360 
361 #ifdef __lm32__
362 #define _JBLEN 19
363 #endif
364 
365 #ifdef __m32c__
366 #if defined(__r8c_cpu__) || defined(__m16c_cpu__)
367 #define _JBLEN (22/2)
368 #else
369 #define _JBLEN (34/2)
370 #endif
371 #define _JBTYPE unsigned short
372 #endif /* __m32c__ */
373 
374 #ifdef __MSP430__
375 #define _JBLEN 9
376 
377 #ifdef __MSP430X_LARGE__
378 #define _JBTYPE unsigned long
379 #else
380 #define _JBTYPE unsigned short
381 #endif
382 #endif
383 
384 #ifdef __RL78__
385 /* Three banks of registers, SP, CS, ES, PC */
386 #define _JBLEN (8*3+8)
387 #define _JBTYPE unsigned char
388 #endif
389 
390 /*
391  * There are two versions of setjmp()/longjmp():
392  *   1) Compiler (gcc) built-in versions.
393  *   2) Function-call versions.
394  *
395  * The built-in versions are used most of the time.  When used, gcc replaces
396  * calls to setjmp()/longjmp() with inline assembly code.  The built-in
397  * versions save/restore a variable number of registers.
398 
399  * _JBLEN is set to 40 to be ultra-safe with the built-in versions.
400  * It only needs to be 12 for the function-call versions
401  * but this data structure is used by both versions.
402  */
403 #ifdef __NIOS2__
404 #define _JBLEN 40
405 #define _JBTYPE unsigned long
406 #endif
407 
408 #ifdef __PRU__
409 #define _JBLEN 48
410 #define _JBTYPE unsigned int
411 #endif
412 
413 #ifdef __RX__
414 #define _JBLEN 0x44
415 #endif
416 
417 #ifdef __VISIUM__
418 /* All call-saved GP registers: r11-r19,r21,r22,r23.  */
419 #define _JBLEN 12
420 #endif
421 
422 #ifdef __riscv
423 /* _JBTYPE using long long to make sure the alignment is align to 8 byte,
424    otherwise in rv32imafd, store/restore FPR may mis-align.  */
425 #define _JBTYPE long long
426 #ifdef __riscv_32e
427 #define _JBLEN ((4*sizeof(long))/sizeof(long))
428 #else
429 #define _JBLEN ((14*sizeof(long) + 12*sizeof(double))/sizeof(long))
430 #endif
431 #endif
432 
433 #ifdef __CSKYABIV2__
434 #define _JBTYPE unsigned long
435 #if defined(__CK801__)
436 #define _JBLEN 7
437 #elif defined(__CK802__)
438 #define _JBLEN 10
439 #else
440 #define _JBLEN 18
441 #endif
442 #endif
443 
444 #ifdef _JBLEN
445 #ifdef _JBTYPE
446 typedef	_JBTYPE jmp_buf[_JBLEN];
447 #else
448 typedef	int jmp_buf[_JBLEN];
449 #endif
450 #endif
451 
452 _END_STD_C
453 
454 #if (defined(__CYGWIN__) || defined(__rtems__)) && __POSIX_VISIBLE
455 #include <signal.h>
456 
457 #ifdef __cplusplus
458 extern "C" {
459 #endif
460 
461 /* POSIX sigsetjmp/siglongjmp macros */
462 #ifdef _JBTYPE
463 typedef _JBTYPE sigjmp_buf[_JBLEN+1+((sizeof (_JBTYPE) + sizeof (sigset_t) - 1)
464 				     /sizeof (_JBTYPE))];
465 #else
466 typedef int sigjmp_buf[_JBLEN+1+(sizeof (sigset_t)/sizeof (int))];
467 #endif
468 
469 #define _SAVEMASK	_JBLEN
470 #define _SIGMASK	(_JBLEN+1)
471 
472 #ifdef __CYGWIN__
473 # define _CYGWIN_WORKING_SIGSETJMP
474 #endif
475 
476 #ifdef _POSIX_THREADS
477 #define __SIGMASK_FUNC pthread_sigmask
478 #else
479 #define __SIGMASK_FUNC sigprocmask
480 #endif
481 
482 #ifdef __CYGWIN__
483 /* Per POSIX, siglongjmp has to be implemented as function.  Cygwin
484    provides functions for both, siglongjmp and sigsetjmp since 2.2.0. */
485 extern void siglongjmp (sigjmp_buf, int) __attribute__ ((__noreturn__));
486 extern int sigsetjmp (sigjmp_buf, int);
487 #endif
488 
489 #if defined(__GNUC__)
490 
491 #define sigsetjmp(env, savemask) \
492             __extension__ \
493             ({ \
494               sigjmp_buf *_sjbuf = &(env); \
495               ((*_sjbuf)[_SAVEMASK] = savemask,\
496               __SIGMASK_FUNC (SIG_SETMASK, 0, (sigset_t *)((*_sjbuf) + _SIGMASK)),\
497               setjmp (*_sjbuf)); \
498             })
499 
500 #define siglongjmp(env, val) \
501             __extension__ \
502             ({ \
503               sigjmp_buf *_sjbuf = &(env); \
504               ((((*_sjbuf)[_SAVEMASK]) ? \
505                __SIGMASK_FUNC (SIG_SETMASK, (sigset_t *)((*_sjbuf) + _SIGMASK), 0)\
506                : 0), \
507                longjmp (*_sjbuf, val)); \
508             })
509 
510 #else /* !__GNUC__ */
511 
512 #define sigsetjmp(env, savemask) ((env)[_SAVEMASK] = savemask,\
513                __SIGMASK_FUNC (SIG_SETMASK, 0, (sigset_t *) ((env) + _SIGMASK)),\
514                setjmp (env))
515 
516 #define siglongjmp(env, val) ((((env)[_SAVEMASK])?\
517                __SIGMASK_FUNC (SIG_SETMASK, (sigset_t *) ((env) + _SIGMASK), 0):0),\
518                longjmp (env, val))
519 
520 #endif
521 
522 /* POSIX _setjmp/_longjmp, maintained for XSI compatibility.  These
523    are equivalent to sigsetjmp/siglongjmp when not saving the signal mask.
524    New applications should use sigsetjmp/siglongjmp instead. */
525 #ifdef __CYGWIN__
526 extern void _longjmp (jmp_buf, int) __attribute__ ((__noreturn__));
527 extern int _setjmp (jmp_buf);
528 #else
529 #define _setjmp(env)		sigsetjmp ((env), 0)
530 #define _longjmp(env, val)	siglongjmp ((env), (val))
531 #endif
532 
533 #ifdef __cplusplus
534 }
535 #endif
536 #endif /* (__CYGWIN__ or __rtems__) and __POSIX_VISIBLE */
537