123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #
- ;
- ; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
- ; See the copyright notice in the ACK home directory, in the file "Copyright".
- ;
- ;
- ; Module: coroutine primitives
- ; Author: Kees Bot, Edwin Scheffer, Ceriel Jacobs
- ; Version: $Id$
- ;
- mes 2,EM_WSIZE,EM_PSIZE
- ; topsize takes care of two things:
- ; - given a stack-break,
- ; it computes the size of the chunk of memory needed to save the stack;
- ; - also, if this stack-break = 0, it creates one, assuming that caller is
- ; the stack-break.
- ;
- ; This implementation assumes a continuous stack growing downwards
- exp $topsize
- #ifdef __sparc
- inp $topsize2
- pro $topsize, 0
- mes 11
- zer EM_PSIZE
- lal 0
- loi EM_PSIZE
- cal $topsize2
- asp 2*EM_PSIZE
- lfr EM_WSIZE
- ret EM_WSIZE
- end 0
- pro $topsize2, 3*EM_WSIZE+3*EM_PSIZE
- #else
- pro $topsize, 3*EM_WSIZE+3*EM_PSIZE
- #endif
- ; local space for line-number, ignoremask, filename, stack-break, size,
- ; and stack-pointer (see the topsave routine)
- mes 11
- lal 0
- loi EM_PSIZE
- loi EM_PSIZE ; stack-break or 0
- zer EM_PSIZE
- cmp
- zne *1
- lxl 0
- dch ; local base of caller
- #ifdef __sparc
- dch ; because of the extra layer
- #endif
- lal 0
- loi EM_PSIZE
- sti EM_PSIZE
- 1
- lal 0
- loi EM_PSIZE
- loi EM_PSIZE
- lpb ; convert this local base to an argument base.
- ; An implementation of a sort of "topsize" EM
- ; instruction should take a local base, and save
- ; the whole frame.
- lor 1 ; stack-break SP
- sbs EM_WSIZE ; stack-break-SP
- ret EM_WSIZE ; return size of block to be saved
- end 3*EM_WSIZE+3*EM_PSIZE
- exp $topsave
- #ifdef __sparc
- inp $topsave2
- pro $topsave,0
- mes 11
- lal 0
- loi 2*EM_PSIZE
- cal $topsave2
- asp 2*EM_PSIZE
- lfr EM_WSIZE
- ret EM_WSIZE
- end 0
- pro $topsave2,0
- #else
- pro $topsave, 0
- #endif
- mes 11
- loe 0
- lae 4 ; load line number and file name
- loi EM_PSIZE
- lim ; ignore mask
- lor 0 ; LB
- lal 0
- loi EM_PSIZE ; stack-break
- lpb
- lor 1
- sbs EM_WSIZE
- loc EM_WSIZE
- adu EM_WSIZE ; gives size
- dup EM_WSIZE
- stl 0 ; save size
- lor 1 ; SP (the SP BEFORE pushing)
- lor 1 ; SP (address of stack top to save)
- lal EM_PSIZE ; area
- loi EM_PSIZE
- lol 0 ; size
- bls EM_WSIZE ; move whole block
- asp 3*EM_PSIZE+3*EM_WSIZE ; remove the lot from the stack
- loc 1
- ret EM_WSIZE ; return 1
- end 0
- sv
- bss EM_PSIZE,0,0
- exp $topload
- #ifdef __sparc
- inp $topload1
- pro $topload,0
- lal 0
- loi EM_PSIZE
- cal $topload1
- asp EM_PSIZE
- lfr EM_WSIZE
- ret EM_WSIZE
- end 0
- pro $topload1, 0
- #else
- pro $topload, 0
- #endif
- mes 11
- lal 0
- loi EM_PSIZE
- lae sv
- sti EM_PSIZE ; saved parameter
- lxl 0
- 2
- dup EM_PSIZE
- adp -3*EM_PSIZE
- lal 0
- loi EM_PSIZE ; compare target SP with current LB to see if we must
- loi EM_PSIZE
- cmp ; find another LB first
- zgt *1
- dch ; just follow dynamic chain to make sure we find
- ; a legal one
- bra *2
- 1
- str 0
- lae sv
- loi EM_PSIZE
- loi EM_PSIZE ; load indirect to
- str 1 ; restore SP
- asp -EM_PSIZE ; to stop int from complaining about non-existent memory
- lae sv
- loi EM_PSIZE ; source address
- lor 1
- adp EM_PSIZE ; destination address
- lae sv
- loi EM_PSIZE
- adp EM_PSIZE
- loi EM_WSIZE ; size of block
- bls EM_WSIZE
- asp EM_PSIZE+EM_WSIZE ; drop size + SP
- str 0 ; restore local base
- sim ; ignore mask
- lae 4
- sti EM_PSIZE
- ste 0 ; line and file
- loc 0
- ret EM_WSIZE
- end 0
|