1 /* $Id: ic_aux.c,v 1.7 1994/06/24 10:24:06 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 /* I N T E R M E D I A T E C O D E
16 #include "../share/types.h"
17 #include "../share/global.h"
18 #include "../share/debug.h"
19 #include "../share/def.h"
20 #include "../share/aux.h"
23 #include "ic_lookup.h"
24 #include "../share/alloc.h"
31 offset opr_size(instr)
47 return (offset) UNKNOWN_SIZE;
49 error("illegal operand of opr_size: %d", instr);
58 STATIC offset argsize(arg)
61 /* Compute the size (in bytes) that the given initializer
70 /* See if value fits in a short */
71 if ((short) arg->a_a.a_offset == arg->a_a.a_offset) {
79 return ps; /* pointer size */
81 /* strings are partitioned into pieces */
83 for (argb = &arg->a_a.a_string; argb != (argb_p) 0;
84 argb = argb->ab_next) {
91 return arg->a_a.a_con.ac_length;
99 STATIC offset blocksize(pseudo,args)
103 /* Determine the number of bytes of a datablock */
111 if (args->a_type != ARGOFF) {
112 error("offset expected");
114 return args->a_a.a_offset;
118 for (arg = args; arg != (arg_p) 0; arg = arg->a_next) {
119 /* Add the sizes of all initializers */
130 STATIC arg_p copy_arg(arg)
133 /* Copy one argument */
137 assert(arg->a_type == ARGOFF);
138 new = newarg(ARGOFF);
139 new->a_a.a_offset = arg->a_a.a_offset;
145 STATIC arg_p copy_rom(args)
148 /* Make a copy of the values of a rom,
149 * provided that the rom contains only integer values,
152 arg_p arg, arg2, argh;
154 for (arg = args; arg != (arg_p) 0; arg = arg->a_next) {
155 if (arg->a_type != ARGOFF) {
159 /* Now make the copy */
160 arg2 = argh = copy_arg(args);
161 for (arg = args->a_next; arg != (arg_p) 0; arg = arg->a_next) {
162 arg2->a_next = copy_arg(arg);
175 /* Process a data block defining occurrence */
196 db->d_size = blocksize(m, ARG(lnp));
198 /* We keep the values of a rom block in the data block
199 * table if the values consist of integers only.
201 db->d_values = copy_rom(ARG(lnp));
209 combine(db,l1,l2,pseu)
214 /* Combine two successive ROMs/CONs (without a data label
215 * in between into a single ROM. E.g.:
226 db->d_size += blocksize(pseu,ARG(l2));
227 /* db is the data block that was already assigned to the
228 * first rom/con. The second one is not assigned a new
229 * data block of course, as the two are combined into
232 if (pseu == DROM && db->d_values != (arg_p) 0) {
233 /* The values contained in a ROM are only copied
234 * to the data block if they may be useful to us
235 * (e.g. they certainly may not be strings). In our
236 * case it means that both ROMs must have useful
239 for (v = db->d_values; v->a_next != (arg_p) 0; v = v->a_next);
240 /* The first rom contained useful arguments. v now points to
241 * its last argument. Append the arguments of the second
242 * rom to this list. If the second rom has arguments that are
243 * not useful, throw away the entire list (we want to copy
244 * everything or nothing).
246 if ((v->a_next = copy_rom(ARG(l2))) == (arg_p) 0) {
247 oldargs(db->d_values);
248 db->d_values = (arg_p) 0;
251 for (v = ARG(l1); v->a_next != (arg_p) 0; v = v->a_next);
252 /* combine the arguments of both instructions. */
261 STATIC arg_string(length,abp)
267 if (abp->ab_index == NARGBYTES)
268 abp = abp->ab_next = newargb();
269 abp->ab_contents[abp->ab_index++] = readchar();
278 register arg_p ap,*app;
284 * creates an arglist with n elements
285 * if n == 0 the arglist is variable and terminated by sp_cend
288 lnp = newline(OPLIST);
294 error("unknown byte in arglist");
296 tabval2 = (offset) tabval;
298 *app = ap = newarg(ARGOFF);
299 ap->a_a.a_offset = tabval2;
303 *app = ap = newarg(ARGINSTRLAB);
304 ap->a_a.a_instrlab = instr_lab((short) tabval);
308 *app = ap = newarg(ARGOBJECT);
309 ap->a_a.a_obj = object(string,(offset) 0, (offset) 0);
310 /* The size of the object is unknown */
314 *app = ap = newarg(ARGPROC);
315 ap->a_a.a_proc = proclookup(string,OCCURRING);
319 tabval2 = (offset) tabval;
321 *app = ap = newarg(ARGOBJECT);
322 ap->a_a.a_obj = object(string, tabval2, (offset) 0);
326 *app = ap = newarg(ARGSTRING);
328 arg_string(length,&ap->a_a.a_string);
332 *app = ap = newarg(ARGICN);
335 *app = ap = newarg(ARGUCN);
338 *app = ap = newarg(ARGFCN);
341 ap->a_a.a_con.ac_length = (short) length;
342 arg_string(get_off(),&ap->a_a.a_con.ac_con);
350 } while (moretocome);
362 return (l->l_instr == (byte) ps_sym);
369 dblock_p block_of_lab(ident)
374 /* Find the datablock with the given name.
375 * Used for defining occurrences.
378 dbl = symlookup(ident,DEFINING);
380 if (dbl->d_pseudo != DUNKNOWN) {
381 error("identifier %s redeclared", ident);
390 STATIC obj_p make_object(dbl,off,size)
395 /* Allocate an obj struct with the given attributes
396 * (if it did not exist already).
397 * Return a pointer to the found or newly created object struct.
400 obj_p obj, prev, new;
402 /* See if the object was already present in the object list
403 * of the given datablock. If it is not yet present, find
404 * the right place to insert the new object. Note that
405 * the objects are sorted by offset.
408 for (obj = dbl->d_objlist; obj != (obj_p) 0; obj = obj->o_next) {
409 if (obj->o_off >= off) {
414 /* Note that the data block may contain several objects
415 * with the required offset; we also want the size to
418 while (obj != (obj_p) 0 && obj->o_off == off) {
419 if (obj->o_size == UNKNOWN_SIZE) {
423 if (size == UNKNOWN_SIZE || obj->o_size == size) {
425 /* This is the right one */
432 /* Allocate a new object */
434 new->o_id = ++lastoid; /* create a unique object id */
438 /* Insert the new object */
439 if (prev == (obj_p) 0) {
440 dbl->d_objlist = new;
450 obj_p object(ident,off,size)
457 /* Create an object struct (if it did not yet exist)
458 * for the object with the given size and offset
459 * within the datablock of the given name.
462 dbl = (ident == (char *) 0 ? hol0_db : symlookup(ident, OCCURRING));
464 return(make_object(dbl,off,size));