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 1.6 1994/06/27 07:58:25 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)
23 #define LocalIntVar() NewLocal(int_size, int_align, reg_any, REGISTER)
26 /* Because EM does not support the loading and storing of
27 objects having other sizes than word fragment and multiple,
28 we need to have a way of transferring these objects, whereby
29 we simulate "loi" and "sti": the address of the source resp.
30 destination is located on top of stack and a call is done
31 to load_block() resp. store_block().
32 ===============================================================
33 # Loadblock() works on the stack as follows: ([ ] indicates the
34 # position of the stackpointer)
37 # 2) | ... ATW(sz) bytes ... | sz | &stack_block | &object
38 # 3) | ... ATW(sz) bytes ...
39 ===============================================================
40 Loadblock() pushes ATW(sz) bytes directly onto the stack!
42 Store_block() works on the stack as follows:
44 1) | ... ATW(sz) bytes ... | &object
45 2) | ... ATW(sz) bytes ... | &object | &stack_block | sz
48 If sz is a legal argument for "loi" or "sti", just one EM
49 instruction is generated.
50 In the other cases, the notion of alignment is taken into account:
51 we only push an object of the size accepted by EM onto the stack,
52 while we need a loop to store the stack block into a memory object.
59 return ((int)sz % (int)word_size == 0 && al % word_align == 0) ||
61 word_size % sz == 0 &&
62 (al >= (int)sz || al >= word_align)
63 /* Lots of Irritating Stupid Parentheses */
71 if (suitable_sz(sz, al))
77 /* allocate two pointer temporaries */
81 /* load the addresses */
82 StoreLocal(dst, pointer_size);
83 C_lor((arith)1); /* push current sp */
84 StoreLocal(src, pointer_size);
85 copy_loop(sz, src, dst);
90 /* address of destination lies on the stack */
92 /* push address of first byte of block on stack onto
93 the stack by computing it from the current stack
96 C_lor((arith)1); /* push current sp */
97 C_adp(pointer_size); /* set & to 1st byte of block */
98 C_loc(sz); /* number of bytes to transfer */
99 C_cal("__stb"); /* call transfer routine */
100 C_asp(pointer_size + pointer_size + int_size + ATW(sz));
110 if (suitable_sz(sz, al))
116 /* allocate two pointer temporaries */
120 StoreLocal(src, pointer_size);
121 C_asp(-ATW(sz)); /* allocate stack block */
122 C_lor((arith)1); /* push & of stack block as dst */
123 StoreLocal(dst, pointer_size);
124 copy_loop(sz, src, dst);
128 arith esz = ATW(sz) - pointer_size;
129 C_asp(-esz); /* allocate stack block */
130 C_lor((arith)1); /* push & of stack block as dst */
131 C_dup(pointer_size); /* fetch source address */
134 C_loc(sz); /* # bytes to copy */
135 C_cal("__stb"); /* library copy routine */
136 C_asp(int_size + pointer_size + pointer_size);
146 if (suitable_sz(sz, al))
152 /* allocate two pointer temporaries */
156 StoreLocal(dst, pointer_size);
157 StoreLocal(src, pointer_size);
158 copy_loop(sz, src, dst);
162 C_loc(sz); /* # bytes to copy */
163 C_cal("__stb"); /* library copy routine */
164 C_asp(int_size + pointer_size + pointer_size);
170 copy_loop(sz, src, dst)
173 /* generate inline byte-copy loop */
174 label l_cont = text_label(), l_stop = text_label();
175 arith tmp_sz = LocalIntVar();
177 C_loc(sz); /* amount of bytes */
178 StoreLocal(tmp_sz, int_size);
180 LoadLocal(tmp_sz, int_size);
183 LoadLocal(src, pointer_size);
186 StoreLocal(src, pointer_size);
188 LoadLocal(dst, pointer_size);
191 StoreLocal(dst, pointer_size);