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 #define _JBLEN		17	/* 12 + 4 + 1 */
338 
339 #else /* __XTENSA_CALL0_ABI__ */
340 
341 #define _JBLEN		6	/* a0, a1, a12, a13, a14, a15 */
342 
343 #endif /* __XTENSA_CALL0_ABI__ */
344 #endif /* __XTENSA__ */
345 
346 #ifdef __mep__
347 /* 16 GPRs, pc, hi, lo */
348 #define _JBLEN 19
349 #endif
350 
351 #ifdef __CRIS__
352 #define _JBLEN 18
353 #endif
354 
355 #ifdef __ia64
356 #define _JBLEN 64
357 #endif
358 
359 #ifdef __lm32__
360 #define _JBLEN 19
361 #endif
362 
363 #ifdef __m32c__
364 #if defined(__r8c_cpu__) || defined(__m16c_cpu__)
365 #define _JBLEN (22/2)
366 #else
367 #define _JBLEN (34/2)
368 #endif
369 #define _JBTYPE unsigned short
370 #endif /* __m32c__ */
371 
372 #ifdef __MSP430__
373 #define _JBLEN 9
374 
375 #ifdef __MSP430X_LARGE__
376 #define _JBTYPE unsigned long
377 #else
378 #define _JBTYPE unsigned short
379 #endif
380 #endif
381 
382 #ifdef __RL78__
383 /* Three banks of registers, SP, CS, ES, PC */
384 #define _JBLEN (8*3+8)
385 #define _JBTYPE unsigned char
386 #endif
387 
388 /*
389  * There are two versions of setjmp()/longjmp():
390  *   1) Compiler (gcc) built-in versions.
391  *   2) Function-call versions.
392  *
393  * The built-in versions are used most of the time.  When used, gcc replaces
394  * calls to setjmp()/longjmp() with inline assembly code.  The built-in
395  * versions save/restore a variable number of registers.
396 
397  * _JBLEN is set to 40 to be ultra-safe with the built-in versions.
398  * It only needs to be 12 for the function-call versions
399  * but this data structure is used by both versions.
400  */
401 #ifdef __NIOS2__
402 #define _JBLEN 40
403 #define _JBTYPE unsigned long
404 #endif
405 
406 #ifdef __PRU__
407 #define _JBLEN 48
408 #define _JBTYPE unsigned int
409 #endif
410 
411 #ifdef __RX__
412 #define _JBLEN 0x44
413 #endif
414 
415 #ifdef __VISIUM__
416 /* All call-saved GP registers: r11-r19,r21,r22,r23.  */
417 #define _JBLEN 12
418 #endif
419 
420 #ifdef __riscv
421 /* _JBTYPE using long long to make sure the alignment is align to 8 byte,
422    otherwise in rv32imafd, store/restore FPR may mis-align.  */
423 #define _JBTYPE long long
424 #ifdef __riscv_32e
425 #define _JBLEN ((4*sizeof(long))/sizeof(long))
426 #else
427 #define _JBLEN ((14*sizeof(long) + 12*sizeof(double))/sizeof(long))
428 #endif
429 #endif
430 
431 #ifdef __CSKYABIV2__
432 #define _JBTYPE unsigned long
433 #if defined(__CK801__)
434 #define _JBLEN 7
435 #elif defined(__CK802__)
436 #define _JBLEN 10
437 #else
438 #define _JBLEN 18
439 #endif
440 #endif
441 
442 #ifdef _JBLEN
443 #ifdef _JBTYPE
444 typedef	_JBTYPE jmp_buf[_JBLEN];
445 #else
446 typedef	int jmp_buf[_JBLEN];
447 #endif
448 #endif
449 
450 _END_STD_C
451 
452 #if (defined(__CYGWIN__) || defined(__rtems__)) && __POSIX_VISIBLE
453 #include <signal.h>
454 
455 #ifdef __cplusplus
456 extern "C" {
457 #endif
458 
459 /* POSIX sigsetjmp/siglongjmp macros */
460 #ifdef _JBTYPE
461 typedef _JBTYPE sigjmp_buf[_JBLEN+1+((sizeof (_JBTYPE) + sizeof (sigset_t) - 1)
462 				     /sizeof (_JBTYPE))];
463 #else
464 typedef int sigjmp_buf[_JBLEN+1+(sizeof (sigset_t)/sizeof (int))];
465 #endif
466 
467 #define _SAVEMASK	_JBLEN
468 #define _SIGMASK	(_JBLEN+1)
469 
470 #ifdef __CYGWIN__
471 # define _CYGWIN_WORKING_SIGSETJMP
472 #endif
473 
474 #ifdef _POSIX_THREADS
475 #define __SIGMASK_FUNC pthread_sigmask
476 #else
477 #define __SIGMASK_FUNC sigprocmask
478 #endif
479 
480 #ifdef __CYGWIN__
481 /* Per POSIX, siglongjmp has to be implemented as function.  Cygwin
482    provides functions for both, siglongjmp and sigsetjmp since 2.2.0. */
483 extern void siglongjmp (sigjmp_buf, int) __attribute__ ((__noreturn__));
484 extern int sigsetjmp (sigjmp_buf, int);
485 #endif
486 
487 #if defined(__GNUC__)
488 
489 #define sigsetjmp(env, savemask) \
490             __extension__ \
491             ({ \
492               sigjmp_buf *_sjbuf = &(env); \
493               ((*_sjbuf)[_SAVEMASK] = savemask,\
494               __SIGMASK_FUNC (SIG_SETMASK, 0, (sigset_t *)((*_sjbuf) + _SIGMASK)),\
495               setjmp (*_sjbuf)); \
496             })
497 
498 #define siglongjmp(env, val) \
499             __extension__ \
500             ({ \
501               sigjmp_buf *_sjbuf = &(env); \
502               ((((*_sjbuf)[_SAVEMASK]) ? \
503                __SIGMASK_FUNC (SIG_SETMASK, (sigset_t *)((*_sjbuf) + _SIGMASK), 0)\
504                : 0), \
505                longjmp (*_sjbuf, val)); \
506             })
507 
508 #else /* !__GNUC__ */
509 
510 #define sigsetjmp(env, savemask) ((env)[_SAVEMASK] = savemask,\
511                __SIGMASK_FUNC (SIG_SETMASK, 0, (sigset_t *) ((env) + _SIGMASK)),\
512                setjmp (env))
513 
514 #define siglongjmp(env, val) ((((env)[_SAVEMASK])?\
515                __SIGMASK_FUNC (SIG_SETMASK, (sigset_t *) ((env) + _SIGMASK), 0):0),\
516                longjmp (env, val))
517 
518 #endif
519 
520 /* POSIX _setjmp/_longjmp, maintained for XSI compatibility.  These
521    are equivalent to sigsetjmp/siglongjmp when not saving the signal mask.
522    New applications should use sigsetjmp/siglongjmp instead. */
523 #ifdef __CYGWIN__
524 extern void _longjmp (jmp_buf, int) __attribute__ ((__noreturn__));
525 extern int _setjmp (jmp_buf);
526 #else
527 #define _setjmp(env)		sigsetjmp ((env), 0)
528 #define _longjmp(env, val)	siglongjmp ((env), (val))
529 #endif
530 
531 #ifdef __cplusplus
532 }
533 #endif
534 #endif /* (__CYGWIN__ or __rtems__) and __POSIX_VISIBLE */
535