2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: blocks.c,v 3.12 1994/06/24 12:02:14 ceriel Exp $ */
6 /* B L O C K S T O R I N G A N D L O A D I N G */
21 extern arith NewLocal();
22 #define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
25 /* Because EM does not support the loading and storing of
26 objects having other sizes than word fragment and multiple,
27 we need to have a way of transferring these objects, whereby
28 we simulate "loi" and "sti": the address of the source resp.
29 destination is located on top of stack and a call is done
30 to load_block() resp. store_block().
31 ===============================================================
32 # Loadblock() works on the stack as follows: ([ ] indicates the
33 # position of the stackpointer)
36 # 2) | ... ATW(sz) bytes ... | sz | &stack_block | &object
37 # 3) | ... ATW(sz) bytes ...
38 ===============================================================
39 Loadblock() pushes ATW(sz) bytes directly onto the stack!
41 Store_block() works on the stack as follows:
43 1) | ... ATW(sz) bytes ... | &object
44 2) | ... ATW(sz) bytes ... | &object | &stack_block | sz
47 If sz is a legal argument for "loi" or "sti", just one EM
48 instruction is generated.
49 In the other cases, the notion of alignment is taken into account:
50 we only push an object of the size accepted by EM onto the stack,
51 while we need a loop to store the stack block into a memory object.
58 ((sz == al) && (word_align % al == 0)) ||
60 (sz % word_size == 0 || word_size % sz == 0) &&
61 (al % word_align == 0)
63 ) /* Lots of Irritating Stupid Parentheses */
69 /* allocate two pointer temporaries */
73 /* load the addresses */
74 StoreLocal(dst, pointer_size);
75 C_lor((arith)1); /* push current sp */
76 StoreLocal(src, pointer_size);
77 copy_loop(sz, src, dst);
82 /* address of destination lies on the stack */
84 /* push address of first byte of block on stack onto
85 the stack by computing it from the current stack
88 C_lor((arith)1); /* push current sp */
89 C_adp(pointer_size); /* set & to 1st byte of block */
90 C_loc(sz); /* number of bytes to transfer */
91 C_cal("__stb"); /* call transfer routine */
92 C_asp(pointer_size + pointer_size + int_size + ATW(sz));
101 arith esz = ATW(sz); /* effective size == actual # pushed bytes */
104 ((sz == al) && (word_align % al == 0)) ||
106 (sz % word_size == 0 || word_size % sz == 0) &&
107 (al % word_align == 0)
109 ) /* Lots of Irritating Stupid Parentheses */
115 /* allocate two pointer temporaries */
119 StoreLocal(src, pointer_size);
120 C_asp(-esz); /* allocate stack block */
121 C_lor((arith)1); /* push & of stack block as dst */
122 StoreLocal(dst, pointer_size);
123 copy_loop(sz, src, dst);
127 C_asp(-(esz - pointer_size)); /* allocate stack block */
128 C_lor((arith)1); /* push & of stack block as dst */
129 C_dup(pointer_size); /* fetch source address */
130 C_adp(esz - pointer_size);
132 C_loc(sz); /* # bytes to copy */
133 C_cal("__stb"); /* library copy routine */
134 C_asp(int_size + pointer_size + pointer_size);
140 copy_loop(sz, src, dst)
143 /* generate inline byte-copy loop */
144 label l_cont = text_label(), l_stop = text_label();
146 C_loc(sz); /* amount of bytes */
151 LoadLocal(src, pointer_size);
154 StoreLocal(src, pointer_size);
156 LoadLocal(dst, pointer_size);
159 StoreLocal(dst, pointer_size);