1 | #
|
---|
2 | mes 2,_EM_WSIZE,_EM_PSIZE
|
---|
3 | ;
|
---|
4 | ; layout of a setjmp buffer:
|
---|
5 | ;
|
---|
6 | ; -----------------
|
---|
7 | ; | flag | (!0 when blocked signals saved (POSIX))
|
---|
8 | ; -----------------
|
---|
9 | ; | signal mask/set | (for Berkeley 4.[2-] / POSIX)
|
---|
10 | ; -----------------
|
---|
11 | ; | |
|
---|
12 | ; | GTO descriptor |
|
---|
13 | ; | (SP, LB, PC) |
|
---|
14 | ; | |
|
---|
15 | ; -----------------
|
---|
16 | ;
|
---|
17 | ; setjmp saves the signalmask, PC, SP, and LB of caller, and creates a
|
---|
18 | ; GTO descriptor from this.
|
---|
19 | ; The big problem here is how to get the return address, i.e. the PC of
|
---|
20 | ; the caller; This problem is solved by the front-end, which must pass
|
---|
21 | ; it as an extra parameter to setjmp.
|
---|
22 |
|
---|
23 | ; a GTO descriptor must be in the global data area
|
---|
24 | gtobuf
|
---|
25 | bss 3*_EM_PSIZE,0,0
|
---|
26 |
|
---|
27 | inp $fill_ret_area
|
---|
28 | exp $__setjmp
|
---|
29 | pro $__setjmp,0
|
---|
30 | #if defined(_POSIX_SOURCE)
|
---|
31 | ; save mask of currently blocked signals.
|
---|
32 | ; longjmp must restore this mask
|
---|
33 | lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
|
---|
34 | lal 0
|
---|
35 | loi _EM_PSIZE
|
---|
36 | stf 3*_EM_PSIZE+_EM_LSIZE
|
---|
37 | lol _EM_PSIZE ; the flag integer at offset _EM_PSIZE
|
---|
38 | zeq *1
|
---|
39 | lal 0
|
---|
40 | loi _EM_PSIZE
|
---|
41 | adp 3*_EM_PSIZE
|
---|
42 | cal $__newsigset
|
---|
43 | asp _EM_PSIZE
|
---|
44 | 1
|
---|
45 | #elif defined(__BSD4_2)
|
---|
46 | loc 0
|
---|
47 | cal $sigblock
|
---|
48 | asp _EM_WSIZE
|
---|
49 | lfr _EM_WSIZE
|
---|
50 | lal 0
|
---|
51 | loi _EM_PSIZE
|
---|
52 | stf 3*_EM_PSIZE
|
---|
53 | #endif
|
---|
54 | ; create GTO descriptor for longjmp
|
---|
55 | lxl 0
|
---|
56 | dch ; Local Base of caller
|
---|
57 | lxa 0 ; Stackpointer of caller
|
---|
58 | lal _EM_PSIZE+_EM_WSIZE
|
---|
59 | loi _EM_PSIZE ; Return address of caller
|
---|
60 | lal 0
|
---|
61 | loi _EM_PSIZE ; address of jmpbuf
|
---|
62 | sti 3*_EM_PSIZE ; LB, SP, and PC stored in jmpbuf
|
---|
63 | loc 0
|
---|
64 | ret _EM_WSIZE ; setjmp must return 0
|
---|
65 | end 0
|
---|
66 |
|
---|
67 | pro $fill_ret_area,0
|
---|
68 | ; put argument in function result area
|
---|
69 | lol 0
|
---|
70 | ret _EM_WSIZE
|
---|
71 | end 0
|
---|
72 |
|
---|
73 | exp $longjmp
|
---|
74 | pro $longjmp,?
|
---|
75 | #if defined(_POSIX_SOURCE)
|
---|
76 | ; restore blocked mask
|
---|
77 | lal 0
|
---|
78 | loi _EM_PSIZE
|
---|
79 | lof 3*_EM_PSIZE+_EM_LSIZE
|
---|
80 | zeq *2
|
---|
81 | lal 0
|
---|
82 | loi _EM_PSIZE
|
---|
83 | adp 3*_EM_PSIZE
|
---|
84 | cal $__oldsigset
|
---|
85 | asp _EM_PSIZE
|
---|
86 | 2
|
---|
87 | #elif defined(__BSD4_2)
|
---|
88 | ; restore signal mask
|
---|
89 | lal 0
|
---|
90 | loi _EM_PSIZE
|
---|
91 | lof 3*_EM_PSIZE
|
---|
92 | cal $_sigsetmask
|
---|
93 | asp _EM_WSIZE
|
---|
94 | lfr _EM_WSIZE
|
---|
95 | asp _EM_WSIZE
|
---|
96 | #endif
|
---|
97 | lal 0
|
---|
98 | loi _EM_PSIZE ; address of jmpbuf
|
---|
99 | lae gtobuf
|
---|
100 | blm 3*_EM_PSIZE ; fill GTO descriptor from jmpbuf
|
---|
101 | lol _EM_PSIZE ; second parameter of longjmp: the return value
|
---|
102 | dup _EM_WSIZE
|
---|
103 | zne *3
|
---|
104 | ; of course, longjmp may not return 0!
|
---|
105 | inc
|
---|
106 | 3
|
---|
107 | ; put return value in function result area
|
---|
108 | cal $fill_ret_area
|
---|
109 | asp _EM_WSIZE
|
---|
110 | gto gtobuf ; there we go ...
|
---|
111 | ; ASP and GTO do not damage function result area
|
---|
112 | end 0
|
---|