Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / libcc.ansi / setjmp / setjmp.e
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