Initial revision
authoreck <none@none>
Thu, 11 May 1989 10:21:37 +0000 (10:21 +0000)
committereck <none@none>
Thu, 11 May 1989 10:21:37 +0000 (10:21 +0000)
lang/cem/libcc.ansi/setjmp/setjmp.e [new file with mode: 0644]

diff --git a/lang/cem/libcc.ansi/setjmp/setjmp.e b/lang/cem/libcc.ansi/setjmp/setjmp.e
new file mode 100644 (file)
index 0000000..3a1e81f
--- /dev/null
@@ -0,0 +1,87 @@
+#
+ mes 2,EM_WSIZE,EM_PSIZE
+
+;
+; layout of a setjmp buffer:
+;
+;  -----------------
+; |   signal mask   |          (only for Berkeley 4.[2-])
+;  -----------------
+; |                 |
+; |  GTO descriptor |
+; |   (SP, LB, PC)  |
+; |                 |
+;  -----------------
+;
+; setjmp saves the signalmask, PC, SP, and LB of caller, and creates a
+; GTO descriptor from this.
+; The big problem here is how to get the return address, i.e. the PC of
+; the caller; This problem is solved by the front-end, which must pass
+; it as an extra parameter to setjmp.
+
+; a GTO descriptor must be in the global data area
+gtobuf
+ bss 3*EM_PSIZE,0,0
+
+ inp $fill_ret_area
+ exp $setjmp
+ pro $setjmp,0
+#ifdef __BSD4_2
+; save mask of currently blocked signals. 
+; longjmp must restore this mask
+ loc 0
+ cal $sigblock
+ asp EM_WSIZE
+ lfr EM_WSIZE
+ lal 0
+ loi EM_PSIZE
+ stf 3*EM_PSIZE
+#endif
+; create GTO descriptor for longjmp
+ lxl 0
+ dch           ; Local Base of caller
+ lxa 0         ; Stackpointer of caller
+ lal EM_PSIZE
+ loi EM_PSIZE  ; Return address of caller
+ lal 0
+ loi EM_PSIZE  ; address of jmpbuf
+ sti 3*EM_PSIZE        ; LB, SP, and PC stored in jmpbuf
+ loc 0
+ ret EM_WSIZE  ; setjmp must return 0
+ end 0
+
+ pro $fill_ret_area,0
+; put argument in function result area
+ lol 0
+ ret EM_WSIZE
+ end 0
+
+ exp $longjmp
+ pro $longjmp,?
+#ifdef __BSD4_2
+; restore signal mask
+ lal 0
+ loi EM_PSIZE
+ lof 3*EM_PSIZE
+ cal $sigsetmask
+ asp EM_WSIZE
+ lfr EM_WSIZE
+ asp EM_WSIZE
+#endif
+ lal 0
+ loi EM_PSIZE  ; address of jmpbuf
+ lae gtobuf
+ blm 3*EM_PSIZE        ; fill GTO descriptor from jmpbuf
+ lol EM_PSIZE  ; second parameter of longjmp: the return value
+ dup EM_WSIZE
+ zne *3
+; of course, longjmp may not return 0!
+ asp EM_WSIZE
+ loc 1
+3
+; put return value in function result area
+ cal $fill_ret_area
+ asp EM_WSIZE
+ gto gtobuf    ; there we go ...
+; ASP and GTO do not damage function result area
+ end 0