koreth@panarthea.ebay.sun.com (Steven Grimm) (10/25/89)
Submitted-by: ncar.ucar.edu!dunike!onecom!wldrdg!hans (Johann Ruegg) Posting-number: Volume 2, Issue 94 Archive-name: sozobon1.2/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 9)." # Contents: hcc/FIX.C hcc/GSUB.C hcc/NODES.C top/DATA.C # Wrapped by koreth@panarthea on Tue Oct 24 18:40:45 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'hcc/FIX.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hcc/FIX.C'\" else echo shar: Extracting \"'hcc/FIX.C'\" \(9053 characters\) sed "s/^X//" >'hcc/FIX.C' <<'END_OF_FILE' X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg X * X * Permission is granted to anyone to use this software for any purpose X * on any computer system, and to redistribute it freely, with the X * following restrictions: X * 1) No charge may be made other than reasonable charges for reproduction. X * 2) Modified versions must be clearly marked as such. X * 3) The authors are not responsible for any harmful consequences X * of using this software, even if they result from defects in it. X * X * fix.c X * X * Motorola has is not consistent in what operations allow X * which operands. This section compensates for that -- X * tries to find the best way to do something. X */ X X#include <stdio.h> X#include "param.h" X#include "nodes.h" X#include "flags.h" X#include "bstok.h" X#include "gen.h" X#include "ops.h" X X#define FAIL 0 X#define OKAY 1 X X#define CL_IMM IOPD X#define CL_AREG AOPD X#define CL_DREG DOPD X#define CL_ADR MOPD X X#define RETAREG 0x100 X#define RETDREG 0x200 X#define RETLEFT 0x400 X#define RETRIGHT 0x800 X X#define LISTMP 1 X#define RISTMP 2 X#define NDASSOC 4 X#define CANRL 8 X#define CANLR 0x10 X#define CANRD 0x20 X#define CANDL 0x40 X#define CANLD 0x80 X#define CANDD 0x100 X#define CANDR 0x200 X Xstruct mtbl { X int restr; X char *code; X int needregs; X} tbl2[] = { X {LISTMP|CANRL, X "\tN.S\t>A,<A\n", RETLEFT}, X {RISTMP|CANLR|NDASSOC, X "\tN.S\t<A,>A\n", RETRIGHT}, X {CANRD, X "\tmove.S\t<A,A\n\tN.S\t>A,A\n", RETDREG}, X {CANLD|NDASSOC, X "\tmove.S\t>A,A\n\tN.S\t<A,A\n", RETDREG}, X /* only EOR and shifts get to here */ X {CANDL|LISTMP, X "\tmove.S\t>A,R1\n\tN.S\tR1,A\n", RETLEFT|1}, X {CANDR|RISTMP|NDASSOC, X "\tmove.S\t<A,R1\n\tN.S\tR1,A\n", RETRIGHT|1}, X {CANDD, X "\tmove.S\t<A,A\n\tmove.S\t>A,R1\n\tN.S\tR1,A\n", X RETDREG|1}, X {0} X}; X Xstruct mtbl tblmul[] = { X {CANRL|LISTMP, X "\tmulU\t>A,<A\n", RETLEFT}, X {CANLR|RISTMP, X "\tmulU\t<A,>A\n", RETRIGHT}, X {CANRD, X "\tmove.w\t>A,A\n\tmulU\t<A,A\n", RETDREG}, X {0} X}; X Xstruct mtbl tbldiv[] = { X {CANRL|LISTMP, X "\text.l\t<A\n\tdivs\t>A,<A\n", RETLEFT}, X {CANRD, X "\tmove.w\t<A,A\n\text.l\tA\n\tdivs\t>A,A\n", RETDREG}, X {0} X}; X Xstruct mtbl tbludiv[] = { X {CANRD, X "\tclr.l\tA\n\tmove.w\t<A,A\n\tdivu\t>A,A\n", RETDREG}, X {0} X}; X Xstruct mtbl tblc[] = { X {CANRL, X "\tcmp.<S\t>A,<A\n", 0}, X {CANRD, X "\tmove.<S\t<A,R1\n\tcmp.<S\t>A,R1\n", 1}, X/* shouldnt get to here! */ X {CANDL, X "\tmove.<S\t>A,R1\n\tcmp.<S\tR1,<A\n", 1}, X {CANDD, X "\tmove.<S\t>A,R1\n\tmove.<S\t<A,R2\n\tcmp.<S\tR1,R2\n", 2}, X {0} X}; X Xstruct mtbl tblas[] = { X {CANRL, X "\tN.S\t>A,<A\n", RETLEFT}, X {CANDL, X "\tmove.S\t>A,R1\n\tN.S\tR1,A\n", 1|RETLEFT}, X /* only MUL, DIV and shifts should get to here */ X {CANRD, X "\tmove.S\t<A,A\n\tN.S\t>A,A\n\tmove.S\tA,<A\n", X RETDREG}, X {CANLD|NDASSOC, X "\tmove.S\t>A,A\n\tN.S\t<A,A\n\tmove.S\tA,<A\n", X RETDREG}, X {CANDD, X "\tmove.S\t<A,A\n\tmove.S\t>A,R1\n\tN.S\tR1,A\n\tmove.S\tA,<A\n", X RETDREG|1}, X {0} X}; X Xstruct mtbl tblamul[] = { X {CANRL, X "\tmulU\t>A,<A\n", RETLEFT}, X {CANLR|RISTMP, X "\tmulU\t<A,>A\n\tmove.w\t>A,<A\n", RETRIGHT}, X {CANRD, X "\tmove.w\t<A,A\n\tmulU\t>A,A\n\tmove.w\tA,<A\n", RETDREG}, X {0} X}; X Xstruct mtbl tbladiv[] = { X {CANRL, X "\text.l\t<A\n\tdivs\t>A,<A\n", RETLEFT}, X {CANRD, X "\tmove.w\t<A,A\n\text.l\tA\n\tdivs\t>A,A\n\tmove.w\tA,<A\n", X RETDREG}, X {0} X}; X Xstruct mtbl tbluadiv[] = { X {CANRD, X "\tclr.l\tA\n\tmove.w\t<A,A\n\tdivu\t>A,A\n\tmove.w\tA,<A\n", X RETDREG}, X {0} X}; X Xstruct mtbl tblamod[] = { X {CANRL, X "\text.l\t<A\n\tdivs\t>A,<A\n\tswap\t<A\n", RETLEFT}, X {CANRD, X "\tmove.w\t<A,A\n\text.l\tA\n\tdivs\t>A,A\n\tswap\tA\n\tmove.w\tA,<A\n", X RETDREG}, X {0} X}; X Xstruct mtbl tbluamod[] = { X {CANRD, X "\tclr.l\tA\n\tmove.w\t<A,A\n\tdivu\t>A,A\n\tswap\tA\n\tmove.w\tA,<A\n", X RETDREG}, X {0} X}; X Xclass(np) XNODEP np; X{ X switch (np->g_token) { X case ICON: X return CL_IMM; X case ONAME: X return (np->g_flags & IMMEDID) ? CL_IMM : CL_ADR; X case OREG: X return (np->g_flags & IMMEDID) ? CL_IMM : CL_ADR; X case PUSHER: X return CL_ADR; X case REGVAR: X if (np->g_rno < AREG) X return CL_DREG; X else X return CL_AREG; X default: X printf("Weird class "); X return CL_IMM; X } X} X Xint canswap; XNODEP matchnp; X Xfix_cmp(np, flags) XNODEP np; X{ X NODEP rp = np->n_right; X X /* special stuff for ICON 0 */ X if (rp->g_token == ICON && rp->g_offs == 0 && X (rp->g_flags & IMMEDID)) { X addcode(np, "<Q"); X return OKAY; X } X canswap = 0; X return fix_sub(np, flags, tblc); X} X Xfix2ops(np, flags) XNODEP np; X{ X canswap = flags & ASSOC; X return fix_sub(np, flags, tbl2); X} X Xfixmul(np, flags) XNODEP np; X{ X return fix_sub(np, flags, tblmul); X} X Xfixdiv(np, flags) XNODEP np; X{ X return fix_sub(np, flags, np->g_ty == ET_U ? tbludiv : tbldiv); X} X Xfixmod(np, flags) XNODEP np; X{ X int r; X X r = fixdiv(np, flags); X addcode(np, "\tswap\tA\n"); X return r; X} X Xfixamul(np, flags) XNODEP np; X{ X return fix_sub(np, flags, tblamul); X} X Xfixadiv(np, flags) XNODEP np; X{ X return fix_sub(np, flags, np->g_ty == ET_U ? tbluadiv : tbladiv); X} X Xfixamod(np, flags) XNODEP np; X{ X return fix_sub(np, flags, np->g_ty == ET_U ? tbluamod : tblamod); X} X Xfix_asn(np, flags) XNODEP np; X{ X canswap = 0; X return fix_sub(np, flags, tblas); X} X Xfix_sub(np, flags, tbl) Xregister NODEP np; Xstruct mtbl *tbl; X{ X NODEP lp = np->n_left, rp = np->n_right; X int lclass, rclass; X register struct mtbl *p; X int rv; X X lclass = class(lp); X rclass = class(rp); X matchnp = np; X X for (p = tbl; p->restr; p++) X if ((rv = cando(flags, p->restr, lclass, rclass))) { X dotbl(p, np); X return OKAY; X } X printf("no code table match! "); X return FAIL; X} X Xdotbl(p, np) Xstruct mtbl *p; XNODEP np; X{ X register int i, k; X X if (p->needregs) { X i = p->needregs; X if (i & RETLEFT) X inherit(np); X else if (i & RETRIGHT) X rinherit(np); X else if (i & RETAREG) X retreg(np, ralloc(AREG)); X else if (i & RETDREG) X retreg(np, ralloc(0)); X k = i & 7; X while (k--) X tempr(np, 0); X k = (i/AREG) & 7; X while (k--) X tempr(np, AREG); X } X addcode(np, p->code); X} X X#define canflag(l,r) (l << cansh[r]) X Xshort cansh[] = {0, 0, 4, 0, 8, 0, 0, 0, 12}; X Xcando(flags, restr, lc, rc) Xregister restr; X{ X NODEP lp = matchnp->n_left, rp = matchnp->n_right; X X if (restr & RISTMP) { X if ((rc & (CL_DREG|CL_AREG)) == 0 || X istemp(rp->g_rno) == 0) X return 0; X } else if (restr & LISTMP) { X if ((lc & (CL_DREG|CL_AREG)) == 0 || X istemp(lp->g_rno) == 0) X return 0; X } X if (restr & NDASSOC) { X if (canswap == 0) X return 0; X } X if (restr & (CANLR|CANLD)) { X flags |= quickflag(lp, flags); X } else if (restr & (CANRL|CANRD)) { X flags |= quickflag(rp, flags); X } X flags &= 0xfff; X if (restr & CANLR) { X if ((flags & canflag(lc,rc)) == 0) X return 0; X } else if (restr & CANRL) { X if ((flags & canflag(rc,lc)) == 0) X return 0; X } else if (restr & CANRD) { X if ((flags & canflag(rc,CL_DREG)) == 0) X return 0; X } else if (restr & CANDL) { X if ((flags & canflag(CL_DREG,lc)) == 0) X return 0; X } else if (restr & CANLD) { X if ((flags & canflag(lc,CL_DREG)) == 0) X return 0; X } else if (restr & CANDR) { X if ((flags & canflag(CL_DREG,rc)) == 0) X return 0; X } else if (restr & CANDD) { X if ((flags & DOPD) == 0) X return 0; X } X return 1; X} X Xquickflag(np, flags) XNODEP np; X{ X long offs; X X if (np->g_token != ICON) X return 0; X offs = np->g_offs; X if ((flags & QOPD) && np->g_offs >= 1 && np->g_offs <= 8) X return IOPD; X if ((flags & ONEOPM) && np->g_offs == 1) X return IOPM; X return 0; X} X X/* X * stuff to do field extract and field assign X * Yes, this stuff can be optimized a lot more ... feel free X */ Xfldget(np, flags) Xregister NODEP np; X{ X int how; X X how = 1; X if (np->g_fldo == 0) X how = 0; /* no shift needed */ X else if (np->g_fldo > 8) X how = 2; /* shift too big for immediate */ X X np->n_left->g_offs += np->g_offs; /* major HACK, hope it works */ X X retreg(np, ralloc(0)); X X addcode(np, "\tmove\t<A,A\n"); /* get word */ X if (how) /* shift to position */ X addcode(np, how==1 ? "\tlsr\t#Y,A\n" : X "\tlsr\t#8,A\n\tlsr\t#Z,A\n"); X addcode(np, "\tand\t#W,A\n"); /* mask off top */ X X return OKAY; X} X Xfldasn(np, flags) Xregister NODEP np; X{ X int how; X X how = 1; X if (np->g_fldo == 0) X how = 0; /* no shift needed */ X else if (np->g_fldo > 8) X how = 2; /* shift too big for immediate */ X X retreg(np, ralloc(0)); X X tempr(np, 0); X X addcode(np, "\tmove\t>A,A\n"); /* value */ X if (needmask(np)) /* mask off high bits */ X addcode(np, "\tand\t#W,A\n"); X if (how) /* shift into position */ X addcode(np, how==1 ? "\tlsl\t#Y,A\n" : X "\tlsl\t#8,A\n\tlsl\t#Z,A\n"); X X addcode(np, "\tmove\t<A,R1\n"); /* old value */ X addcode(np, "\tand\t#X,R1\n"); /* mask out old value */ X addcode(np, "\tor\tA,R1\n"); /* set new field */ X addcode(np, "\tmove\tR1,<A\n"); /* store new word */ X X if (how && (flags & NOVAL_OK) == 0) /* return value */ X addcode(np, how==1 ? "\tlsr\t#Y,A\n" : X "\tlsr\t#8,A\n\tlsr\t#Z,A\n"); X X return OKAY; X} X Xneedmask(np) Xregister NODEP np; X{ X NODEP lp = np->n_left; X X if (np->g_fldw + np->g_fldo >= 16) X return 0; X X if (lp->g_token != ICON) X return 1; X if ((int)lp->g_offs & ~ones(np->g_fldw)) { X warn("value too big for field"); X return 1; X } X return 0; X} END_OF_FILE if test 9053 -ne `wc -c <'hcc/FIX.C'`; then echo shar: \"'hcc/FIX.C'\" unpacked with wrong size! fi # end of 'hcc/FIX.C' fi if test -f 'hcc/GSUB.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hcc/GSUB.C'\" else echo shar: Extracting \"'hcc/GSUB.C'\" \(9472 characters\) sed "s/^X//" >'hcc/GSUB.C' <<'END_OF_FILE' X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg X * X * Permission is granted to anyone to use this software for any purpose X * on any computer system, and to redistribute it freely, with the X * following restrictions: X * 1) No charge may be made other than reasonable charges for reproduction. X * 2) Modified versions must be clearly marked as such. X * 3) The authors are not responsible for any harmful consequences X * of using this software, even if they result from defects in it. X * X * gsub.c X * X * Various code generation subroutines X * Includes generation of switches and X * conversion of type lists to simple type,size. X */ X X#include <stdio.h> X#include "param.h" X#include "bstok.h" X#include "tytok.h" X#include "flags.h" X#include "nodes.h" X#include "gen.h" X X#define isimmed(np) ((np)->g_flags & IMMEDID) X#define isareg(np) ((np)->g_token == REGVAR && (np)->g_rno >= AREG) X Xextern cctest; X Xextern xflags[]; X#define debug xflags['s'-'a'] X Xgen_brt(np, lbl) XNODEP np; X{ X p2_expr(&np); X mustty(np, R_SCALAR); X br_sub(np, 0, lbl); X} X Xgen_brf(np, lbl) XNODEP np; X{ X p2_expr(&np); X mustty(np, R_SCALAR); X br_sub(np, 1, lbl); X} X Xbr_sub(np, rev, lbl) XNODEP np; X{ X int i; X X switch (np->e_token) { X case DOUBLE '&': X br_split(np, lbl, rev); X return; X case DOUBLE '|': X br_split(np, lbl, 2+rev); X return; X } X genx(np, FORCC); X i = cctest; X if (i) { X if (rev) X /* reverse truth */ X i = (i&1) ? i+1 : i-1; X out_b(i, lbl); X } X} X Xbr_split(np, lbl, n) XNODEP np; X{ X int nlbl; X X if (n == 0 || n == 3) X nlbl = new_lbl(); X else X nlbl = lbl; X X br_sub(np->n_left, n<2, nlbl); X br_sub(np->n_right, n&1, lbl); X X freeunit(np); X X if (nlbl != lbl) X def_lbl(nlbl); X} X X/* generate switch X np - list of nodes with value,label pairs (sorted) X dlbl - default label or -1 X */ X#undef min X#undef max X Xgen_switch(np, odlbl) XNODEP np; X{ X int n,min,max; X int dlbl; X register NODEP p; X X if (debug) { X printf("gs %d ", odlbl); X printnode(np); X } X X /* if no default, make one! */ X if (odlbl < 0) X dlbl = new_lbl(); X else X dlbl = odlbl; X X n = 0; X for (p=np; p; p=p->n_next) { X if (n == 0) X min = max = p->c_casev; X else X max = p->c_casev; X n++; X } X if (n <= C_SIMPLE) X simple_sw(np,odlbl); X else if (n >= max/C_RATIO - min/C_RATIO) X table_sw(np,dlbl,min,max); X else { X half_sw(np,dlbl,max/2+min/2,n); X goto out; /* free already done */ X } X freenode(np); Xout: X if (odlbl < 0) X def_lbl(dlbl); X} X X/* simple if-else type switch X dlbl may be -1 -> fall through X does not free np X*/ Xsimple_sw(np, dlbl) Xregister NODEP np; X{ X while (np) { X out_d0cmp(np->c_casev); X out_b(B_EQ, np->c_casel); X np = np->n_next; X } X if (dlbl >= 0) X out_br(dlbl); X} X X/* use table switch X dlbl is not -1 X does not free np X*/ Xtable_sw(np, dlbl, min, max) XNODEP np; X{ X out_d0cmp(min); X out_b(B_LT, dlbl); X out_d0cmp(max); X out_b(B_GT, dlbl); X if (min) X out_d0sub(min); X X out_tsw(); X X while (np) { X while (min < np->c_casev) { X out_tlbl(dlbl); X min++; X } X out_tlbl(np->c_casel); X min++; X np = np->n_next; X } X} X X/* cut switch in half (by value) X dlbl is not -1 X will free np X */ Xhalf_sw(np, dlbl, cut, n) XNODEP np; X{ X register NODEP p, last; X int nlo, nhi; X int l1; X X for (p=np; p->c_casev < cut; p = p->n_next) X last = p; X /* we KNOW both pieces are non-NULL ! */ X last->n_next = NULL; X last = p; X X nlo = 0; X nhi = 0; X for (p=np; p; p=p->n_next) X nlo++; X nhi = n - nlo; X X if (nhi == 1) { /* switch hi and low */ X p = np; X np = last; X last = p; X nlo = 1; X nhi = n-1; X } X if (nlo == 1) { /* also nhi == 1 */ X out_d0cmp(np->c_casev); X out_b(B_EQ, np->c_casel); X freenode(np); X gen_switch(last, dlbl); X return; X } X l1 = new_lbl(); X out_d0cmp(cut); X out_b(B_GE, l1); X gen_switch(np, dlbl); X def_lbl(l1); X gen_switch(last, dlbl); X} X Xistempa(np) Xregister NODEP np; X{ X if (np->g_token == OREG && istemp(np->g_rno)) X return 1; X return 0; X} X Xchar chunkch[] = {0, 'b', 'w', 0, 'l'}; X Xstrasn(np) XNODEP np; X{ X int r; X long count, i; X int chunk, l; X char buf[40]; X int lisa, risa, rissp; X int useloop; X X if (np->g_ty != ET_A) X return 0; X X count = np->g_bsize; X chunk = np->g_sz; X if (count == 1) { X return 0; X } X X useloop = count > 3; X X lisa = istempa(np->n_left); X risa = istempa(np->n_right); X rissp = (np->n_right->g_token == PUSHER); X X if (lisa) X r = np->n_left->g_rno; X else X r = ralloc(AREG); /* R0 */ X indir(np, r); X np->g_offs = -(count*chunk); X X if (risa) X np->g_r1 = np->n_right->g_rno; X else if (rissp) X np->g_r1 = AREG+7; X else X tempr(np, AREG); /* R1 */ X if (useloop) X tempr(np, 0); /* R2 */ X X if (!lisa || np->n_left->g_offs) X addcode(np, "\tlea\t<A,R0\n"); X if (!(risa||rissp) || np->n_right->g_offs) X addcode(np, "\tlea\t>A,R1\n"); X X if (useloop) { X sprintf(buf, "\tmove.w\t#%d,R2\n", (int)(count-1)); X addcode(np, buf); X l = new_lbl(); X sprintf(buf, "'L%d:\tmove.%c\t(R1)+,(R0)+\n",l,chunkch[chunk]); X addcode(np, buf); X sprintf(buf, "\tdbra\tR2,'L%d\n", l); X addcode(np, buf); X } else for (i=0; i<count; i++) { X sprintf(buf, "\tmove.%c\t(R1)+,(R0)+\n", chunkch[chunk]); X addcode(np, buf); X } X X if (chunk == 1 && count & 1 && rissp) X addcode(np, "\tmove.b\t(sp)+,R2\n"); X X return 1; X} X Xstrret(np) XNODEP np; X{ X extern funstrl; X X strsub(np, funstrl); X} X Xstrpush(np) XNODEP np; X{ X return strsub(np, 0); X} X Xstrxpush(np) XNODEP np; X{ X strsub(np, -1); X} X Xstrsub(np, tolbl) Xregister NODEP np; X{ X long count, i; X int chunk, l; X char buf[40]; X char *frstr; X register NODEP tp; X int useloop; X X count = np->g_bsize; X chunk = np->g_sz; X if (chunk == 1 && count & 1 && tolbl <= 0) X count++; X X useloop = count > 3; X X if (useloop && np->g_r2 == -1) X np->g_r2 = ralloc(0); X X /* set up 'from' address */ X if (np->g_token == OREG && istemp(np->g_rno)) { X frstr = "R0"; X if (np->g_offs) X addcode(np, "\tlea\tA,R0\n"); X } else if (tolbl == -1 && (tp = np->n_left) && X tp->g_token == OREG && istemp(tp->g_rno) && X tp->g_offs == 0) { X frstr = "R1"; X np->g_r1 = tp->g_rno; X } else { X frstr = "R1"; X if (np->g_r1 == -1) X np->g_r1 = ralloc(AREG); X if (tolbl == -1) X addcode(np, "\tlea\t<A,R1\n"); X else X addcode(np, "\tlea\tA,R1\n"); X } X X /* set up 'to' address */ X if (tolbl > 0) { X sprintf(buf, "\tmove.l\t#'L%d,H\n", tolbl); X addcode(np, buf); X } else { X sprintf(buf, "\tsub\t#%d,sp\n", (int)(count*chunk)); X addcode(np, buf); X addcode(np, "\tmove.l\tsp,H\n"); X } X X /* generate copy loop */ X if (useloop) { X sprintf(buf, "\tmove.w\t#%d,R2\n", (int)(count-1)); X addcode(np, buf); X l = new_lbl(); X sprintf(buf, "'L%d:\tmove.%c\t(%s)+,(H)+\n", l, chunkch[chunk], X frstr); X addcode(np, buf); X sprintf(buf, "\tdbra\tR2,'L%d\n", l); X addcode(np, buf); X } else for (i=0; i<count; i++) { X sprintf(buf, "\tmove.%c\t(%s)+,(H)+\n", chunkch[chunk], X frstr); X addcode(np, buf); X } X X return count*chunk; X} X Xspecasn(np, flags) XNODEP np; X{ X NODEP lp = np->n_left, rp = np->n_right; X int r; X X if (rp->g_token == ICON && isimmed(rp)) { X rinherit(np); X X if (rp->g_offs == 0) X addcode(np, isareg(lp) ? "\tsub.S\t<A,<A\n" X : "\tclr.S\t<A\n"); X else X addcode(np, "\tmove.S\t>A,<A\n"); X return 1; X } X if (rp->g_token == OREG && isimmed(rp)) { X rp->g_flags &= ~IMMEDID; X if (isareg(lp)) { X inherit(np); X addcode(np, "\tlea\t>A,A\n"); X } else if (rp->g_offs == 0) { X retreg(np, rp->g_rno); X addcode(np, "\tmove.l\tA,<A\n"); X } else { X if (istemp(rp->g_rno)) X r = rp->g_rno; X else X r = ralloc(AREG); X retreg(np, r); X addcode(np, "\tlea\t>A,A\n"); X addcode(np, "\tmove.l\tA,<A\n"); X } X return 1; X } X return 0; X} X Xuntype(np) Xregister NODEP np; X{ X if (np == NULL || np->n_tptr == NULL) { X printf("? NULL untype "); X return; X } X X switch (np->e_type) { X case E_BIN: X untype(np->n_right); X /* fall through */ X case E_UNARY: X if (np->e_token == '.' && np->e_fldw) { X np->g_fldw = np->e_fldw; X np->g_fldo = np->e_fldo; X } else X np->g_fldw = 0; X X untype(np->n_left); X } X X get_tyinf(np); X X if ((np->n_flags & N_COPYT) == 0) X freenode(np->n_tptr); X np->n_tptr = NULL; /* is g_code */ X np->g_betw = NULL; X} X Xstatic char bty[] = { X ET_U, ET_U, ET_S, ET_S, ET_U, ET_S, ET_S, ET_F, ET_F, 0 X}; X Xstatic char bsz[] = { X SIZE_C, SIZE_L, SIZE_L, SIZE_S, SIZE_U, X SIZE_I, SIZE_C, SIZE_F, SIZE_D, 0 X}; X Xget_tyinf(np) Xregister NODEP np; X{ X NODEP tp = np->n_tptr; X int n; X long offs; X X offs = np->e_offs; X X /* inherit name,token,left,right,nmx from common X and token, flags, type, sc from enode */ X X switch (tp->t_token) { X case K_STRUCT: X case K_UNION: X np->g_ty = ET_A; X /* determine copy chunk size and number of chunks */ X if (tp->t_aln & 1) { X if (tp->t_size & 1) X fatal("aligned struct with odd size"); X if (tp->t_size & 2) { X np->g_bsize = tp->t_size >> 1; X np->g_sz = 2; X } else { X np->g_bsize = tp->t_size >> 2; X np->g_sz = 4; X } X } else { X np->g_bsize = tp->t_size; X np->g_sz = 1; X } X break; X case '(': X break; X case STAR: X np->g_ty = ET_U; X np->g_sz = SIZE_P; X break; X default: X n = tp->t_token-FIRST_BAS; X np->g_ty = bty[n]; X np->g_sz = bsz[n]; X } X np->g_offs = offs; /* different place */ X} X Xaddcode(np, s) Xregister NODEP np; Xchar *s; X{ X NODEP tp; X int i, c; X X while (np->g_code) X np = np->g_code; X tp = allocnode(); X np->g_code = tp; X np->n_flags &= ~N_COPYT; X i = strlen(s); X if (i < NMXSIZE) { /* fits in one */ X strcpy(tp->n_name, s); X return; X } X X /* need to split it */ X i = NMXSIZE-1; X c = s[i-1]; X if (c == '<' || c == '>' || (c>='A' && c<='Z')) /* special */ X i--; X strncpy(tp->n_name, s, i); X tp->n_name[i] = 0; X addcode(tp, &s[i]); X} END_OF_FILE if test 9472 -ne `wc -c <'hcc/GSUB.C'`; then echo shar: \"'hcc/GSUB.C'\" unpacked with wrong size! fi # end of 'hcc/GSUB.C' fi if test -f 'hcc/NODES.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hcc/NODES.C'\" else echo shar: Extracting \"'hcc/NODES.C'\" \(8680 characters\) sed "s/^X//" >'hcc/NODES.C' <<'END_OF_FILE' X/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg X * X * Permission is granted to anyone to use this software for any purpose X * on any computer system, and to redistribute it freely, with the X * following restrictions: X * 1) No charge may be made other than reasonable charges for reproduction. X * 2) Modified versions must be clearly marked as such. X * 3) The authors are not responsible for any harmful consequences X * of using this software, even if they result from defects in it. X * X * nodes.c X * X * Node allocation, deallocation, searching, printing X * and other node handling X */ X X#include <stdio.h> X#include "param.h" X#include "nodes.h" X Xextern FILE *output; XNODE *freelist; X X#define NODEINCR 100 X Xextern int oflags[]; X#define debug oflags['n'-'a'] X X#define NODELEN (sizeof(NODE)/4) X Xint nodesmade, nodesavail; X XNODE * Xallocnode() X{ X char *calloc(); X NODE *t; X int i; X Xretry: X if (freelist != 0) { X t = freelist; X freelist = t->n_next; X lclr(t, NODELEN); X nodesavail--; X if (debug) X printf("%lx+ ", t); X return t; X } X t = (NODE *)calloc(NODEINCR, sizeof(NODE)); X if (t == 0) { X printf("malloc failure\n"); X exit(1); X } X nodesmade += NODEINCR; X nodesavail += NODEINCR; X for (i=0; i<NODEINCR; i++) X t[i].n_next = &t[i+1]; X t[NODEINCR-1].n_next = 0; X freelist = t; X goto retry; X} X Xfreeunit(t) XNODE *t; X{ X if (t->n_flags & N_ISFREE) { X printf("%lx ", t); X error("Freeing free node"); X exit(1); X } else X t->n_flags |= N_ISFREE; X t->n_next = freelist; X freelist = t; X nodesavail++; X if (debug) X printf("%lx- ", t); X} X Xfreenode(t) XNODE *t; X{ X register NODE *nxt; X X if (t == NULL) return; Xagain: X if (t->n_right) X freenode(t->n_right); X if (t->n_nmx) X freenode(t->n_nmx); X if (t->n_tptr && (t->n_flags & N_COPYT) == 0) X freenode(t->n_tptr); X nxt = t->n_left; X freeunit(t); X if (nxt) { X t = nxt; X goto again; /* minimize left recursion */ X } X} X Xput_nnm(t) XNODE *t; X{ X printf("%s", t->n_name); X while (t->n_nmx) { X t = t->n_nmx; X printf("%s", t->n_name); X } X} X Xqput_nnm(t, fd) XNODE *t; XFILE *fd; X{ X fprintf(fd, "%s", t->n_name); X while (t->n_nmx) { X t = t->n_nmx; X fprintf(fd, "%s", t->n_name); X } X} X Xfput_nnm(t) XNODE *t; X{ X fprintf(output, "%s", t->n_name); X while (t->n_nmx) { X t = t->n_nmx; X fprintf(output, "%s", t->n_name); X } X} X X/* add a short string (less than NMXSIZE) to front of name */ Xnnmins(t, s) XNODEP t; Xchar *s; X{ X register i, j; X char tbuf[NMSIZE]; X NODEP n; X X i = strlen(t->n_name); X j = strlen(s); X if (j > NMSIZE-1) X return; /* compiler error */ X if (i+j <= NMSIZE-1) { /* fits in node */ X strcpy(tbuf, t->n_name); X strcpy(t->n_name, s); X strcpy(t->n_name+j, tbuf); X } else { X n = allocnode(); X n->n_nmx = t->n_nmx; X t->n_nmx = n; X strcpy(n->n_name, t->n_name); X strcpy(t->n_name, s); X } X} X X/* add a short string (less than NMXSIZE) to end of name */ Xnnmadd(t, s) XNODE *t; Xchar *s; X{ X register i,j; X int sizeb; X NODEP n; X X /* find last node */ X sizeb = NMSIZE; X while (t->n_nmx) { X t = t->n_nmx; X sizeb = NMXSIZE; X } X /* fits in current last node? */ X i = strlen(s); X j = strlen(t->n_name); X if (i < sizeb-j) { X strcat(t->n_name, s); X return; X } X /* put all of s in new node */ X n = allocnode(); X t->n_nmx = n; X t = n; X strncpy(t->n_name, s, NMXSIZE-1); X t->n_name[NMXSIZE-1] = 0; X} X Xnscpy(t, s) XNODE *t; Xchar *s; X{ X register i; X NODEP n; X X i = strlen(s); X strncpy(t->n_name, s, NMSIZE-1); X t->n_name[NMSIZE-1] = 0; X i -= NMSIZE-1; X s += NMSIZE-1; X while (i > 0) { X n = allocnode(); X t->n_nmx = n; X t = n; X strncpy(t->n_name, s, NMXSIZE-1); X t->n_name[NMXSIZE-1] = 0; X i -= NMXSIZE-1; X s += NMXSIZE-1; X } X} X Xputlist(head, np) XNODE **head, *np; X{ X np->n_next = *head; X *head = np; X} X Xputhlist(head, np) XNODE *head[], *np; X{ X putlist(&head[hash(np->n_name)], np); X} X XNODE * Xllook(head, np) XNODE *head, *np; X{ X register NODEP p; X X for (p=head; p != NULL; p = p->n_next) X if (xstrcmp(p, np) == 0) { X return p; X } X return NULL; X} X XNODE * Xhlook(head, np) XNODE *head[], *np; X{ X register NODEP p; X X p = head[hash(np->n_name)]; X return llook(p, np); X} X Xhash(s) Xregister char *s; X{ X register hval; X X hval = 0; X while (*s) X hval += *s++; X return hval & (NHASH-1); X} X Xxstrcmp(p1, p2) XNODE *p1, *p2; X{ X int rv; X X if ((rv = strcmp(p1->n_name, p2->n_name)) != 0) X return rv; X if (p1->n_nmx == NULL) { X if (p2->n_nmx == NULL) X return 0; X return -1; X } X if (p2->n_nmx == NULL) X return 1; X return xstrcmp(p1->n_nmx, p2->n_nmx); X} X Xchar * Xscopy(s) Xchar *s; X{ X int i; X char *p; X X i = strlen(s)+1; X if (i > sizeof(NODE)) { X error("preproc name too big"); X i = sizeof(NODE); X s[i-1] = 0; X } X p = (char *)allocnode(); X strcpy(p, s); X return p; X} X Xsfree(s) Xchar *s; X{ X NODEP np; X X np = (NODEP)s; X np->n_flags = 0; X freeunit(np); X} X Xprintlist(np) XNODE *np; X{ X putchar('\n'); X prln(np, 2); X} X Xprln(np, indent) XNODE *np; X{ X register NODE *svl, *nxtl; X X for (svl=np; svl != NULL; svl = nxtl) { X nxtl = svl->n_next; X svl->n_next = NULL; X prnode(svl,indent); X svl->n_next = nxtl; X /* special hack for tag list */ X if ((svl->n_flags & N_BRKPR) && svl->n_right) X prln(svl->n_right, indent+2); X } X} X Xcodeprint(np) XNODEP np; X{ X putchar('\n'); X cprnode(np,0); X} X Xcprnode(np,indent) XNODE *np; X{ X int ni; X NODEP tp; X X ni = indent+1; X while (indent--) X putchar(' '); X if (np == NULL) { X printf("<NULL>\n"); X return; X } X put_nnm(np); /* Note: BRKPR doesnt break long names */ X if (np->g_offs) X printf(" o%ld ", np->g_offs); X if (np->g_rno) X printf(" r%d ", np->g_rno); X if (np->g_needs) X printf(" n%x ", np->g_needs); X if (debug) { X printf("@%lx ", np); X if (np->n_flags & N_COPYT) X printf("C "); X if (np->n_flags & N_BRKPR) X printf("B "); X } X if (np->n_flags & N_BRKPR) { X putchar('\n'); X return; X } X if (np->g_betw) X printf(" {%s}", np->g_betw); X if (np->g_code) { X if (np->n_flags & N_COPYT) X printf(" <%s>", np->g_code); X else X for (tp=np->g_code; tp; tp = tp->g_code) X printf(" <%s>", tp->n_name); X } X putchar(' '); X out_a(np, stdout); X putchar('\n'); X if (np->n_left) { X cprnode(np->n_left,ni); X } else if (np->n_right) X cprnode(NULL, ni); X if (np->n_right) { X cprnode(np->n_right,ni); X } X} X Xprintnode(np) XNODE *np; X{ X putchar('\n'); X prnode(np,0); X} X Xprnode(np,indent) XNODE *np; X{ X int ni; X X ni = indent+1; X while (indent--) X putchar(' '); X if (np == NULL) { X printf("<NULL>\n"); X return; X } X put_nnm(np); /* Note: BRKPR doesnt break long names */ X if (np->e_offs) X printf(" o%ld ", np->e_offs); X if (np->e_rno) X printf(" r%d ", np->e_rno); X if (np->e_fldw) X printf(" (%d,%d) ", np->e_fldw, np->e_fldo); X if (debug) { X printf("@%lx ", np); X if (np->n_flags & N_COPYT) X printf("C "); X if (np->n_flags & N_BRKPR) X printf("B "); X } X if (np->n_flags & N_BRKPR) { X putchar('\n'); X return; X } X if (np->n_tptr) { X if (np->e_flags & 256) /* IMMEDID */ X printf(" $$$ "); X tprint(np->n_tptr); X } X putchar('\n'); X if (np->n_left) { X prnode(np->n_left,ni); X } else if (np->n_right) X prnode(NULL, ni); X if (np->n_right) { X prnode(np->n_right,ni); X } X} X Xtprint(np) XNODEP np; X{ X while (np != NULL) { X putchar(' '); X put_nnm(np); X#ifdef HANS X if (np->t_size) X printf(" s%ld", np->t_size); X if (np->t_aln) X printf(" a%d", np->t_aln); X#endif X if (debug) X printf("@%lx", np); X np = np->n_tptr; X } X} X XNODEP Xcopynode(op) XNODEP op; X{ X NODEP np; X X if (op == NULL) return NULL; X np = allocnode(); X lcpy(np, op, NODELEN); X if (np->n_nmx) X np->n_nmx = copynode(np->n_nmx); X if (np->n_right) X np->n_right = copynode(np->n_right); X if (np->n_left) X np->n_left = copynode(np->n_left); X if (np->n_tptr) X np->n_flags |= N_COPYT; X return np; X} X XNODEP Xcopyone(op) XNODEP op; X{ X NODEP np; X X if (op == NULL) return NULL; X np = allocnode(); X lcpy(np, op, NODELEN); X if (np->n_nmx) X np->n_nmx = copyone(np->n_nmx); X if (np->n_right) X np->n_right = NULL; X if (np->n_left) X np->n_left = NULL; X if (np->n_tptr) X np->n_flags |= N_COPYT; X return np; X} X XNODEP Xcopy_nol(op) XNODEP op; X{ X NODEP np; X X if (op == NULL) return NULL; X np = allocnode(); X lcpy(np, op, NODELEN); X if (np->n_nmx) X np->n_nmx = copynode(np->n_nmx); X if (np->n_right) /* break right links */ X np->n_right = NULL; X if (np->n_tptr) X np->n_flags |= N_COPYT; X return np; X} X XNODEP Xcopylist(np, tailp) XNODE *np, **tailp; X{ X NODEP rv, nx; X register NODEP tail; X X if (np == NULL) { X *tailp = NULL; X return NULL; X } X rv = copy_nol(np); X tail = rv; X while (tail->n_left) { X nx = copy_nol(tail->n_left); X tail->n_left = nx; X tail = nx; X } X *tailp = tail; X return rv; X} X XNODE * Xnthnode(np, n) XNODE *np; X{ X while (n--) X if (np == NULL) X return NULL; X else X np=np->n_next; X return np; X} X XNODE * Xrthnode(np, n) XNODE *np; X{ X while (n--) X if (np == NULL) X return NULL; X else X np=np->n_right; X return np; X} END_OF_FILE if test 8680 -ne `wc -c <'hcc/NODES.C'`; then echo shar: \"'hcc/NODES.C'\" unpacked with wrong size! fi # end of 'hcc/NODES.C' fi if test -f 'top/DATA.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'top/DATA.C'\" else echo shar: Extracting \"'top/DATA.C'\" \(8563 characters\) sed "s/^X//" >'top/DATA.C' <<'END_OF_FILE' X/* Copyright (c) 1988 by Sozobon, Limited. Author: Tony Andrews X * X * Permission is granted to anyone to use this software for any purpose X * on any computer system, and to redistribute it freely, with the X * following restrictions: X * 1) No charge may be made other than reasonable charges for reproduction. X * 2) Modified versions must be clearly marked as such. X * 3) The authors are not responsible for any harmful consequences X * of using this software, even if they result from defects in it. X */ X X/* X * Routines for data flow analysis of a single instruction X */ X X#include "top.h" X X/* X * idata X * X * For each instruction, we have some global information, as well X * as flags indicating what the instruction does with its operands. X * We need to know if each operand is set and/or referenced. If the X * instruction has side-effects not directly related to its operands, X * we need to know that as well, so "special case" code can deal with X * that as well. X */ Xstruct idata { X X char iflag; /* flags regarding the entire instruction */ X#define SIDE 0x01 /* inst. has side-effects */ X#define CC 0x02 /* inst. munges condition codes */ X X char op1f; /* flags for the first and second operands */ X char op2f; X#define SET 0x01 /* operand is set */ X#define REF 0x02 /* operand is referenced */ X X} idata[] = X{ X { CC, REF, REF|SET }, /* OR */ X { CC, REF, REF }, /* BTST */ X { 0, REF, SET }, /* MOVEP */ X { CC, REF, REF|SET }, /* BCHG */ X { CC, REF, REF|SET }, /* BCLR */ X { CC, REF, REF|SET }, /* BSET */ X { CC, REF, REF|SET }, /* AND */ X { CC, REF, REF|SET }, /* SUB */ X { CC, REF, REF|SET }, /* ADD */ X { CC, REF, REF|SET }, /* EOR */ X { CC, REF, REF }, /* CMP */ X { CC, REF, SET }, /* MOVE */ X { CC, REF|SET, 0 }, /* NEGX */ X { CC, REF, REF }, /* CHK */ X { 0, REF, SET }, /* LEA */ X { CC, SET, 0 }, /* CLR */ X { CC, REF|SET, 0 }, /* NEG */ X { CC, REF|SET, 0 }, /* NOT */ X { CC, REF|SET, 0 }, /* NBCD */ X { CC, REF|SET, 0 }, /* SWAP */ X { SIDE, REF, 0 }, /* PEA */ X { CC, REF|SET, 0 }, /* EXT */ X { SIDE, REF, SET }, /* MOVEM */ X { CC, REF, 0 }, /* TST */ X { CC, REF|SET, 0 }, /* TAS */ X { 0, REF, 0 }, /* TRAP */ X { SIDE, REF|SET, REF }, /* LINK */ X { SIDE, REF|SET, 0 }, /* UNLK */ X { 0, 0, 0 }, /* RESET */ X { 0, 0, 0 }, /* NOP */ X { CC, REF, 0 }, /* STOP */ X { SIDE|CC, 0, 0 }, /* RTE */ X { SIDE, 0, 0 }, /* RTS */ X { 0, 0, 0 }, /* TRAPV */ X { SIDE|CC, 0, 0 }, /* RTR */ X { SIDE, REF, 0 }, /* JSR */ X { 0, REF, 0 }, /* JMP */ X { CC, REF, REF|SET }, /* ADDQ */ X { 0, SET, 0 }, /* ST */ X { CC, REF|SET, REF }, /* DBT */ X { CC, REF, REF|SET }, /* SUBQ */ X { 0, SET, 0 }, /* SF */ X { CC, REF|SET, REF }, /* DBRA (dbf) */ X { 0, SET, 0 }, /* SHI */ X { CC, REF|SET, REF }, /* DBHI */ X { 0, SET, 0 }, /* SLS */ X { CC, REF|SET, REF }, /* DBLS */ X { 0, SET, 0 }, /* SCC */ X { CC, REF|SET, REF }, /* DBCC */ X { 0, SET, 0 }, /* SCS */ X { CC, REF|SET, REF }, /* DBCS */ X { 0, SET, 0 }, /* SNE */ X { CC, REF|SET, REF }, /* DBNE */ X { 0, SET, 0 }, /* SEQ */ X { CC, REF|SET, REF }, /* DBEQ */ X { 0, SET, 0 }, /* SVC */ X { CC, REF|SET, REF }, /* DBVC */ X { 0, SET, 0 }, /* SVS */ X { CC, REF|SET, REF }, /* DBVS */ X { 0, SET, 0 }, /* SPL */ X { 0, SET, 0 }, /* SMI */ X { CC, REF|SET, REF }, /* DBMI */ X { 0, SET, 0 }, /* SGE */ X { CC, REF|SET, REF }, /* DBGE */ X { 0, SET, 0 }, /* SLT */ X { CC, REF|SET, REF }, /* DBLT */ X { 0, SET, 0 }, /* SGT */ X { CC, REF|SET, REF }, /* DBGT */ X { 0, SET, 0 }, /* SLE */ X { CC, REF|SET, REF }, /* DBLE */ X { 0, REF, 0 }, /* BRA */ X { SIDE, REF, 0 }, /* BSR */ X { 0, REF, 0 }, /* BHI */ X { 0, REF, 0 }, /* BLS */ X { 0, REF, 0 }, /* BCC */ X { 0, REF, 0 }, /* BCS */ X { 0, REF, 0 }, /* BNE */ X { 0, REF, 0 }, /* BEQ */ X { 0, REF, 0 }, /* BVC */ X { 0, REF, 0 }, /* BVS */ X { 0, REF, 0 }, /* BPL */ X { 0, REF, 0 }, /* BMI */ X { 0, REF, 0 }, /* BGE */ X { 0, REF, 0 }, /* BLT */ X { 0, REF, 0 }, /* BGT */ X { 0, REF, 0 }, /* BLE */ X { CC, REF, SET }, /* MOVEQ */ X { CC, REF, REF|SET }, /* DIVU */ X { CC, REF, REF|SET }, /* SBCD */ X { CC, REF, REF|SET }, /* DIVS */ X { CC, REF, REF|SET }, /* SUBX */ X { CC, REF, REF }, /* CMPM */ X { CC, REF, REF|SET }, /* MULU */ X { CC, REF, REF|SET }, /* ABCD */ X { 0, REF|SET, REF|SET }, /* EXG */ X { CC, REF, REF|SET }, /* MULS */ X { CC, REF, REF|SET }, /* ADDX */ X { CC, REF, REF|SET }, /* ASR */ X { CC, REF, REF|SET }, /* LSR */ X { CC, REF, REF|SET }, /* ROXR */ X { CC, REF, REF|SET }, /* ROR */ X { CC, REF, REF|SET }, /* ASL */ X { CC, REF, REF|SET }, /* LSL */ X { CC, REF, REF|SET }, /* ROXL */ X { CC, REF, REF|SET }, /* ROL */ X { 0, 0, 0 }, /* DC */ X}; X X/* X * chkset(op) - check to see if operand 'op' sets a register X * X * This given operand is set by an instruction. Depending on the X * addressing mode used, this may set a register. If so, return X * an appropriate mask. This only happens with register direct X * addressing. X */ Xint Xchkset(op) Xregister struct opnd *op; X{ X switch (M(op->amode)) { X X case REG: X return RM(op->areg); X case REGI: X if (op->amode & (INC|DEC)) X return RM(op->areg); X else X return 0; X X default: X return 0; X } X} X X/* X * chkref(op) - check to see if operand 'op' references a register X * X * Checks for register references in source or destination X * operands, since they can occur in either. X */ Xint Xchkref(op, is_src) Xregister struct opnd *op; Xregister bool is_src; /* is the operand a source? */ X{ X switch (M(op->amode)) { X X case NONE: X case IMM: X case ABS: X case PCD: X return 0; X X case REG: X if (is_src) X return RM(op->areg); X else X return 0; X X case REGI: X case REGID: X return RM(op->areg); X X case REGIDX: X return (RM(op->areg) | RM(op->ireg)); X X case PCDX: X return RM(op->ireg); X X default: X fprintf(stderr, "illegal mode in chkref() %d\n", M(op->amode)); X exit(1); X } X} X X/* X * chkside(ip, type) - check for side-effects of 'ip' X * X * Return a mask of registers set or referenced (depending on 'type') X * by the given instruction. For example, "pea" sets and references X * the stack pointer. X */ Xint Xchkside(ip, type) XINST *ip; Xint type; X{ X switch (ip->opcode) { X case PEA: /* refs/sets the stack pointer */ X return RM(SP); X X case LINK: /* refs/sets SP */ X return RM(SP); X X case UNLK: X if (type == SET) X return RM(SP); X else X return 0; X X case RTE: X case RTS: X case RTR: X if (type == SET) X return RM(SP); X else X return RM(SP)|RM(D0); /* return value's in D0 */ X X case JSR: X case BSR: X /* X * We have to account, here, for what the called X * routine might do. Registers D0-3 and A0-3 may X * be munged. X */ X if (type == SET) X return RM(A0)|RM(A1)|RM(A2)| X RM(D0)|RM(D1)|RM(D2)|RM(SP); X else X return RM(SP); X X X case MOVEM: X /* X * We should really check for a register mask spec. X * here and parse it. The simple solution is to assume X * that all the registers used for register variables X * are referenced or modified. X */ X return RM(A3)|RM(A4)|RM(A5)|RM(A7)| X RM(D3)|RM(D4)|RM(D5)|RM(D6)|RM(D7); X X default: X fprintf(stderr, "chkside() - unknown opcode\n"); X exit(1); X } X} X X/* X * reg_set(ip) - return mask of regs set by 'ip' X */ Xint Xreg_set(ip) Xregister INST *ip; X{ X int mask = 0; /* build up a register mask */ X X if (idata[ip->opcode].op1f & SET) X mask |= chkset(&ip->src); X if (idata[ip->opcode].op1f & REF) { X if ((ip->src.amode & (INC|DEC)) != 0) X mask |= RM(ip->src.areg); X } X X if (idata[ip->opcode].op2f & SET) X mask |= chkset(&ip->dst); X if (idata[ip->opcode].op2f & REF) { X if ((ip->dst.amode & (INC|DEC)) != 0) X mask |= RM(ip->dst.areg); X } X X if (idata[ip->opcode].iflag & SIDE) X mask |= chkside(ip, SET); X X return mask; X} X X/* X * reg_ref(ip) - return mask of regs referenced by 'ip' X */ Xint Xreg_ref(ip) Xregister INST *ip; X{ X int mask = 0; /* build up a register mask */ X X mask |= chkref(&ip->src, idata[ip->opcode].op1f & REF); X mask |= chkref(&ip->dst, idata[ip->opcode].op2f & REF); X if (idata[ip->opcode].iflag & SIDE) X mask |= chkside(ip, REF); X X return mask; X} X X/* X * sets(ip, reg) - is 'reg' set by the instruction 'ip'? X */ Xbool Xsets(ip, reg) XINST *ip; Xint reg; X{ X return ((reg_set(ip) & RM(reg)) != 0); X} X X/* X * refs(ip, reg) - is 'reg' referenced by the instruction 'ip'? X */ Xbool Xrefs(ip, reg) XINST *ip; Xint reg; X{ X return ((reg_ref(ip) & RM(reg)) != 0); X} X X/* X * uses(ip, ref) - is 'reg' used by the instruction 'ip'? X */ Xbool Xuses(ip, reg) XINST *ip; Xint reg; X{ X return sets(ip, reg) || refs(ip, reg); X} END_OF_FILE if test 8563 -ne `wc -c <'top/DATA.C'`; then echo shar: \"'top/DATA.C'\" unpacked with wrong size! fi # end of 'top/DATA.C' fi echo shar: End of archive 3 \(of 9\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0