/* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ #ifndef NORCSID static char rcsid[] = "$Id$"; #endif #include #include "param.h" #include "instruct.h" #include "pseudo.h" #include "varinfo.h" #include "set.h" #include "expr.h" #include "iocc.h" #include "subr.h" #include #include "extern.h" extern int niops; extern iocc_t iops[]; extern int inproc; extern set_t l_sets[]; extern inst_t l_instances[]; extern expr_t subreg_expr(), regno_expr(); static struct varinfo * setcoco(int n) { struct varinfo *vi; NEW(vi, struct varinfo); vi->vi_next = VI_NULL; vi->vi_int[0] = INSSETCC; vi->vi_int[1] = n; return (vi); } static struct varinfo * generase(int n) { struct varinfo *vi; NEW(vi, struct varinfo); vi->vi_next = VI_NULL; vi->vi_int[0] = INSERASE; vi->vi_int[1] = n; return (vi); } static struct varinfo * genremove(int n) { struct varinfo *vi; NEW(vi, struct varinfo); vi->vi_next = VI_NULL; vi->vi_int[0] = INSREMOVE; vi->vi_int[1] = n; return (vi); } static int onlyreg(int argno) { register int bitno; register short *sp; if (!argno) argno++; sp = l_sets[tokpatset[argno - 1]].set_val; for (bitno = nregs; bitno < nregs + ntokens; bitno++) if (BIT(sp, bitno)) return (0); return (1); } static void makescratch(int argno) { set_t s; if (!argno) argno++; if (tokpatro[argno - 1]) error("Instruction destroys %%%d, not allowed here", argno); s = l_sets[tokpatset[argno - 1]]; BIC(s.set_val, 0); tokpatset[argno - 1] = setlookup(s); } struct varinfo *gen_inst(char *ident, int star) { register struct varinfo *vi, *retval, *eravi; register instr_p ip; register struct operand *op; register int i; register inst_p insta; if (star && !inproc) error("Variable instruction only allowed inside proc"); for (ip = l_instr; ip < l_instr + ninstr; ip++) { if (strcmp(ident, ip->i_name)) continue; if (ip->i_nops != niops) continue; for (i = 0, op = ip->i_oplist; i < niops; i++, op = op->o_next) { if (!subset(iops[i].in_set, l_sets[op->o_setno].set_val, SETSIZE)) goto cont; } goto found; /* oh well, one more won't hurt */ cont: ; } error("Such an \"%s\" does not exist", ident); return (0); found: NEW(vi, struct varinfo); vi->vi_int[0] = ip - l_instr; vi->vi_int[1] = star; vi->vi_next = 0; retval = vi; for (i = 0; i < niops; i++) { NEW(vi->vi_vi, struct varinfo); vi = vi->vi_vi; vi->vi_int[0] = iops[i].in_index; } vi->vi_vi = 0; vi = retval; for (i = 0, op = ip->i_oplist; i < niops; i++, op = op->o_next) { if (op->o_adorn & AD_CC) { vi->vi_next = setcoco(iops[i].in_index); vi = vi->vi_next; } switch (op->o_adorn & AD_RWMASK) { default: /* Nothing possible to do */ break; case AD_RO: /* It might be possible to do something * here but not now. */ break; case AD_RW: case AD_WO: /* Treated the same for now */ insta = &l_instances[iops[i].in_index]; switch (insta->in_which) { case IN_COPY: if (insta->in_info[1] == 0 && !onlyreg(insta->in_info[0])) break; makescratch(insta->in_info[0]); vi->vi_next = generase(ex_lookup( EX_SUBREG, insta->in_info[0], insta->in_info[1])); vi = vi->vi_next; break; case IN_MEMB: vi->vi_next = generase(ex_lookup( EX_TOKFIELD, insta->in_info[0], insta->in_info[1])); vi = vi->vi_next; break; case IN_RIDENT: vi->vi_next = generase(ex_lookup( EX_REG, insta->in_info[0], 0)); vi = vi->vi_next; break; case IN_ALLOC: vi->vi_next = generase(ex_lookup( EX_ALLREG, insta->in_info[0] + 1, insta->in_info[1])); vi = vi->vi_next; break; case IN_S_DESCR: case IN_D_DESCR: { int temp; if (insta->in_which == IN_S_DESCR) temp = wordsize; else temp = 2 * wordsize; temp = ex_lookup(EX_REGVAR, insta->in_info[1], temp); vi->vi_next = generase(temp); vi = vi->vi_next; vi->vi_next = genremove(temp); vi = vi->vi_next; break; } } break; } } for (eravi = ip->i_erases; eravi != VI_NULL ; eravi = eravi->vi_next) { if (eravi->vi_int[0] < 0) vi->vi_next = setcoco(0); else { vi->vi_next = generase(eravi->vi_int[0]); vi = vi->vi_next; vi->vi_next = genremove(eravi->vi_int[0]); } vi = vi->vi_next; } return (retval); }