xref: /plan9/sys/src/ape/lib/ap/sparc/notetramp.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1219b2ee8SDavid du Colombier #include "../plan9/lib.h"
2219b2ee8SDavid du Colombier #include "../plan9/sys9.h"
3219b2ee8SDavid du Colombier #include <signal.h>
4*7dd7cddfSDavid du Colombier #include <setjmp.h>
5219b2ee8SDavid du Colombier 
6219b2ee8SDavid du Colombier /* A stack to hold pcs when signals nest */
7219b2ee8SDavid du Colombier #define MAXSIGSTACK 20
8219b2ee8SDavid du Colombier typedef struct Pcstack Pcstack;
9219b2ee8SDavid du Colombier static struct Pcstack {
10219b2ee8SDavid du Colombier 	int sig;
11219b2ee8SDavid du Colombier 	void (*hdlr)(int, char*, Ureg*);
12219b2ee8SDavid du Colombier 	unsigned long restorepc;
13219b2ee8SDavid du Colombier 	unsigned long restorenpc;
14*7dd7cddfSDavid du Colombier 	Ureg *u;
15219b2ee8SDavid du Colombier } pcstack[MAXSIGSTACK];
16219b2ee8SDavid du Colombier static int nstack = 0;
17219b2ee8SDavid du Colombier 
18219b2ee8SDavid du Colombier static void notecont(Ureg*, char*);
19219b2ee8SDavid du Colombier 
20219b2ee8SDavid du Colombier void
_notetramp(int sig,void (* hdlr)(int,char *,Ureg *),Ureg * u)21219b2ee8SDavid du Colombier _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
22219b2ee8SDavid du Colombier {
23219b2ee8SDavid du Colombier 	Pcstack *p;
24219b2ee8SDavid du Colombier 
25219b2ee8SDavid du Colombier 	if(nstack >= MAXSIGSTACK)
26219b2ee8SDavid du Colombier 		_NOTED(1);	/* nesting too deep; just do system default */
27219b2ee8SDavid du Colombier 	p = &pcstack[nstack];
28219b2ee8SDavid du Colombier 	p->restorepc = u->pc;
29219b2ee8SDavid du Colombier 	p->restorenpc = u->npc;
30219b2ee8SDavid du Colombier 	p->sig = sig;
31219b2ee8SDavid du Colombier 	p->hdlr = hdlr;
32*7dd7cddfSDavid du Colombier 	p->u = u;
33219b2ee8SDavid du Colombier 	nstack++;
34219b2ee8SDavid du Colombier 	u->pc = (unsigned long) notecont;
35219b2ee8SDavid du Colombier 	u->npc = u->pc+4;
36219b2ee8SDavid du Colombier 	_NOTED(2);	/* NSAVE: clear note but hold state */
37219b2ee8SDavid du Colombier }
38219b2ee8SDavid du Colombier 
39219b2ee8SDavid du Colombier static void
notecont(Ureg * u,char * s)40219b2ee8SDavid du Colombier notecont(Ureg *u, char *s)
41219b2ee8SDavid du Colombier {
42219b2ee8SDavid du Colombier 	Pcstack *p;
43219b2ee8SDavid du Colombier 	void(*f)(int, char*, Ureg*);
44219b2ee8SDavid du Colombier 
45219b2ee8SDavid du Colombier 	p = &pcstack[nstack-1];
46219b2ee8SDavid du Colombier 	f = p->hdlr;
47219b2ee8SDavid du Colombier 	u->pc = p->restorepc;
48219b2ee8SDavid du Colombier 	u->npc = p->restorenpc;
49219b2ee8SDavid du Colombier 	nstack--;
50219b2ee8SDavid du Colombier 	(*f)(p->sig, s, u);
51219b2ee8SDavid du Colombier 	_NOTED(3);	/* NRSTR */
52219b2ee8SDavid du Colombier }
53*7dd7cddfSDavid du Colombier 
54*7dd7cddfSDavid du Colombier int	__noterestore(void);
55*7dd7cddfSDavid du Colombier 
56*7dd7cddfSDavid du Colombier #define JMPBUFPC 1
57*7dd7cddfSDavid du Colombier #define JMPBUFSP 0
58*7dd7cddfSDavid du Colombier #define	JMPBUFDPC (-8)
59*7dd7cddfSDavid du Colombier 
60*7dd7cddfSDavid du Colombier extern sigset_t	_psigblocked;
61*7dd7cddfSDavid du Colombier 
62*7dd7cddfSDavid du Colombier void
siglongjmp(sigjmp_buf j,int ret)63*7dd7cddfSDavid du Colombier siglongjmp(sigjmp_buf j, int ret)
64*7dd7cddfSDavid du Colombier {
65*7dd7cddfSDavid du Colombier 	struct Ureg *u;
66*7dd7cddfSDavid du Colombier 
67*7dd7cddfSDavid du Colombier 	if(j[0])
68*7dd7cddfSDavid du Colombier 		_psigblocked = j[1];
69*7dd7cddfSDavid du Colombier 	if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
70*7dd7cddfSDavid du Colombier 		longjmp(j+2, ret);
71*7dd7cddfSDavid du Colombier 	u = pcstack[nstack-1].u;
72*7dd7cddfSDavid du Colombier 	nstack--;
73*7dd7cddfSDavid du Colombier 	u->r8 = ret;
74*7dd7cddfSDavid du Colombier 	if(ret == 0)
75*7dd7cddfSDavid du Colombier 		u->r8 = 1;
76*7dd7cddfSDavid du Colombier 	u->r9 = j[JMPBUFPC] - JMPBUFDPC;
77*7dd7cddfSDavid du Colombier 	u->pc = (unsigned long)__noterestore;
78*7dd7cddfSDavid du Colombier 	u->npc = (unsigned long)__noterestore + 4;
79*7dd7cddfSDavid du Colombier 	u->sp = j[JMPBUFSP];
80*7dd7cddfSDavid du Colombier 	_NOTED(3);	/* NRSTR */
81*7dd7cddfSDavid du Colombier }
82