123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* I N T E R M E D I A T E C O D E
- *
- * I C _ A U X . C
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <em_pseu.h>
- #include <em_spec.h>
- #include <em_mnem.h>
- #include "../share/types.h"
- #include "../share/global.h"
- #include "../share/debug.h"
- #include "../share/def.h"
- #include "../share/aux.h"
- #include "ic.h"
- #include "ic_io.h"
- #include "ic_lookup.h"
- #include "../share/alloc.h"
- #include "ic_aux.h"
- /* opr_size */
- offset opr_size(short instr)
- {
- switch(instr) {
- case op_loe:
- case op_ste:
- case op_ine:
- case op_dee:
- case op_zre:
- return (offset) ws;
- case op_lde:
- case op_sde:
- return (offset) 2*ws;
- case op_lae:
- case op_fil:
- case op_gto:
- return (offset) UNKNOWN_SIZE;
- default:
- error("illegal operand of opr_size: %d", instr);
- }
- /* NOTREACHED */
- return 0;
- }
- /* dblockdef */
- static offset argsize(arg_p arg)
- {
- /* Compute the size (in bytes) that the given initializer
- * will occupy.
- */
- offset s;
- argb_p argb;
- switch(arg->a_type) {
- case ARGOFF:
- /* See if value fits in a short */
- if ((short) arg->a_a.a_offset == arg->a_a.a_offset) {
- return ws;
- } else {
- return 2*ws;
- }
- case ARGINSTRLAB:
- case ARGOBJECT:
- case ARGPROC:
- return ps; /* pointer size */
- case ARGSTRING:
- /* strings are partitioned into pieces */
- s = 0;
- for (argb = &arg->a_a.a_string; argb != (argb_p) 0;
- argb = argb->ab_next) {
- s += argb->ab_index;
- }
- return s;
- case ARGICN:
- case ARGUCN:
- case ARGFCN:
- return arg->a_a.a_con.ac_length;
- default:
- assert(FALSE);
- }
- /* NOTREACHED */
- return 0;
- }
- static offset blocksize(byte pseudo, arg_p args)
- {
- /* Determine the number of bytes of a datablock */
- arg_p arg;
- offset sum;
- switch(pseudo) {
- case DHOL:
- case DBSS:
- if (args->a_type != ARGOFF) {
- error("offset expected");
- }
- return args->a_a.a_offset;
- case DCON:
- case DROM:
- sum = 0;
- for (arg = args; arg != (arg_p) 0; arg = arg->a_next) {
- /* Add the sizes of all initializers */
- sum += argsize(arg);
- }
- return sum;
- default:
- assert(FALSE);
- }
- /* NOTREACHED */
- return 0;
- }
- static arg_p copy_arg(arg_p arg)
- {
- /* Copy one argument */
- arg_p new;
- assert(arg->a_type == ARGOFF);
- new = newarg(ARGOFF);
- new->a_a.a_offset = arg->a_a.a_offset;
- return new;
- }
- static arg_p copy_rom(arg_p args)
- {
- /* Make a copy of the values of a rom,
- * provided that the rom contains only integer values,
- */
- arg_p arg, arg2, argh;
- for (arg = args; arg != (arg_p) 0; arg = arg->a_next) {
- if (arg->a_type != ARGOFF) {
- return (arg_p) 0;
- }
- }
- /* Now make the copy */
- arg2 = argh = copy_arg(args);
- for (arg = args->a_next; arg != (arg_p) 0; arg = arg->a_next) {
- arg2->a_next = copy_arg(arg);
- arg2 = arg2->a_next;
- }
- return argh;
- }
- void dblockdef(dblock_p db, int n, line_p lnp)
- {
- /* Process a data block defining occurrence */
- byte m = 0;
- switch(n) {
- case ps_hol:
- m = DHOL;
- break;
- case ps_bss:
- m = DBSS;
- break;
- case ps_con:
- m = DCON;
- break;
- case ps_rom:
- m = DROM;
- break;
- default:
- assert(FALSE);
- }
- db->d_pseudo = m;
- db->d_size = blocksize(m, ARG(lnp));
- if (m == DROM) {
- /* We keep the values of a rom block in the data block
- * table if the values consist of integers only.
- */
- db->d_values = copy_rom(ARG(lnp));
- }
- }
- /* combine */
- void combine(dblock_p db, line_p l1, line_p l2, byte pseu)
- {
- /* Combine two successive ROMs/CONs (without a data label
- * in between into a single ROM. E.g.:
- * xyz
- * rom 3,6,9,12
- * rom 7,0,2
- * is changed into:
- * xyz
- * rom 3,6,9,12,7,0,2
- */
- arg_p v;
- db->d_size += blocksize(pseu,ARG(l2));
- /* db is the data block that was already assigned to the
- * first rom/con. The second one is not assigned a new
- * data block of course, as the two are combined into
- * one instruction.
- */
- if (pseu == DROM && db->d_values != (arg_p) 0) {
- /* The values contained in a ROM are only copied
- * to the data block if they may be useful to us
- * (e.g. they certainly may not be strings). In our
- * case it means that both ROMs must have useful
- * arguments.
- */
- for (v = db->d_values; v->a_next != (arg_p) 0; v = v->a_next);
- /* The first rom contained useful arguments. v now points to
- * its last argument. Append the arguments of the second
- * rom to this list. If the second rom has arguments that are
- * not useful, throw away the entire list (we want to copy
- * everything or nothing).
- */
- if ((v->a_next = copy_rom(ARG(l2))) == (arg_p) 0) {
- oldargs(db->d_values);
- db->d_values = (arg_p) 0;
- }
- }
- for (v = ARG(l1); v->a_next != (arg_p) 0; v = v->a_next);
- /* combine the arguments of both instructions. */
- v->a_next = ARG(l2);
- ARG(l2) = (arg_p) 0;
- }
- /* arglist */
- static void arg_string(offset length, argb_p abp)
- {
- while (length--) {
- if (abp->ab_index == NARGBYTES)
- abp = abp->ab_next = newargb();
- abp->ab_contents[abp->ab_index++] = readchar();
- }
- }
- line_p arglist(int n)
- {
- line_p lnp;
- register arg_p ap,*app;
- bool moretocome;
- offset length;
- /*
- * creates an arglist with n elements
- * if n == 0 the arglist is variable and terminated by sp_cend
- */
- lnp = newline(OPLIST);
- app = &ARG(lnp);
- moretocome = TRUE;
- do {
- switch(table2()) {
- default:
- error("unknown byte in arglist");
- case CSTX1:
- tabval2 = (offset) tabval;
- case CSTX2:
- *app = ap = newarg(ARGOFF);
- ap->a_a.a_offset = tabval2;
- app = &ap->a_next;
- break;
- case ILBX:
- *app = ap = newarg(ARGINSTRLAB);
- ap->a_a.a_instrlab = instr_lab((short) tabval);
- app = &ap->a_next;
- break;
- case DLBX:
- *app = ap = newarg(ARGOBJECT);
- ap->a_a.a_obj = object(string,(offset) 0, (offset) 0);
- /* The size of the object is unknown */
- app = &ap->a_next;
- break;
- case sp_pnam:
- *app = ap = newarg(ARGPROC);
- ap->a_a.a_proc = proclookup(string,OCCURRING);
- app = &ap->a_next;
- break;
- case VALX1:
- tabval2 = (offset) tabval;
- case VALX2:
- *app = ap = newarg(ARGOBJECT);
- ap->a_a.a_obj = object(string, tabval2, (offset) 0);
- app = &ap->a_next;
- break;
- case sp_scon:
- *app = ap = newarg(ARGSTRING);
- length = get_off();
- arg_string(length,&ap->a_a.a_string);
- app = &ap->a_next;
- break;
- case sp_icon:
- *app = ap = newarg(ARGICN);
- goto casecon;
- case sp_ucon:
- *app = ap = newarg(ARGUCN);
- goto casecon;
- case sp_fcon:
- *app = ap = newarg(ARGFCN);
- casecon:
- length = get_int();
- ap->a_a.a_con.ac_length = (short) length;
- arg_string(get_off(),&ap->a_a.a_con.ac_con);
- app = &ap->a_next;
- break;
- case sp_cend:
- moretocome = FALSE;
- }
- if (n && (--n) == 0)
- moretocome = FALSE;
- } while (moretocome);
- return(lnp);
- }
- /* is_datalabel */
- bool is_datalabel(line_p l)
- {
- VL(l);
- return (l->l_instr == (byte) ps_sym);
- }
- /* block_of_lab */
- dblock_p block_of_lab(char *ident)
- {
- dblock_p dbl;
- /* Find the datablock with the given name.
- * Used for defining occurrences.
- */
- dbl = symlookup(ident,DEFINING);
- VD(dbl);
- if (dbl->d_pseudo != DUNKNOWN) {
- error("identifier %s redeclared", ident);
- }
- return dbl;
- }
- /* object */
- static obj_p make_object(dblock_p dbl, offset off, offset size)
- {
- /* Allocate an obj struct with the given attributes
- * (if it did not exist already).
- * Return a pointer to the found or newly created object struct.
- */
- obj_p obj, prev, new;
- /* See if the object was already present in the object list
- * of the given datablock. If it is not yet present, find
- * the right place to insert the new object. Note that
- * the objects are sorted by offset.
- */
- prev = (obj_p) 0;
- for (obj = dbl->d_objlist; obj != (obj_p) 0; obj = obj->o_next) {
- if (obj->o_off >= off) {
- break;
- }
- prev = obj;
- }
- /* Note that the data block may contain several objects
- * with the required offset; we also want the size to
- * be the right one.
- */
- while (obj != (obj_p) 0 && obj->o_off == off) {
- if (obj->o_size == UNKNOWN_SIZE) {
- obj->o_size = size;
- return obj;
- } else {
- if (size == UNKNOWN_SIZE || obj->o_size == size) {
- return obj;
- /* This is the right one */
- } else {
- prev = obj;
- obj = obj->o_next;
- }
- }
- }
- /* Allocate a new object */
- new = newobject();
- new->o_id = ++lastoid; /* create a unique object id */
- new->o_off = off;
- new->o_size = size;
- new->o_dblock = dbl;
- /* Insert the new object */
- if (prev == (obj_p) 0) {
- dbl->d_objlist = new;
- } else {
- prev->o_next = new;
- }
- new->o_next = obj;
- return new;
- }
- obj_p object(char *ident, offset off, offset size)
- {
- dblock_p dbl;
- /* Create an object struct (if it did not yet exist)
- * for the object with the given size and offset
- * within the datablock of the given name.
- */
- dbl = (ident == (char *) 0 ? hol0_db : symlookup(ident, OCCURRING));
- VD(dbl);
- return(make_object(dbl,off,size));
- }
|