From f9676e1d02d3ec27b8841e34ffdc624e12a95895 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Sun, 12 Feb 2017 00:34:37 +1100 Subject: [PATCH] Add type safety by changing union tree to struct tree which does not have access to extended fields, and requires a dynamic cast before they are accessed --- c0.h | 49 +-- c00.c | 70 ++-- c01.c | 379 +++++++++--------- c02.c | 48 +-- c03.c | 8 +- c04.c | 94 ++--- c1.h | 127 +++--- c10.c | 846 +++++++++++++++++++++------------------ c11.c | 463 +++++++++++---------- c12.c | 1128 +++++++++++++++++++++++++++++----------------------- c13.c | 5 + ccom.h | 126 +++--- fields.sed | 73 ++++ 13 files changed, 1881 insertions(+), 1535 deletions(-) create mode 100644 fields.sed diff --git a/c0.h b/c0.h index 2fe1536..f44e63c 100644 --- a/c0.h +++ b/c0.h @@ -65,7 +65,7 @@ extern char ctab[]; extern char symbuf[MAXCPS+2]; extern struct nmlist *hshtab[HSHSIZ]; extern int kwhash[(HSHSIZ+LNBPW-1)/LNBPW]; -extern union tree **cp; +extern struct tree **cp; extern int isn0; extern struct swtab swtab[SWSIZ]; extern int unscflg; @@ -106,7 +106,7 @@ extern FILE *sbufp; #endif extern int regvar; extern int bitoffs; -extern struct tnode funcblk; +extern struct nnode funcblk; extern char cvntab[]; extern char numbuf[64]; extern struct nmlist **memlist; @@ -201,33 +201,34 @@ void putstr __P((int lab, register int max)); void cntstr __P((void)); int getcc __P((void)); int mapch __P((int ac)); -union tree *tree __P((/*int eflag*/)); -union tree *xprtype __P((void)); +struct tree *tree __P((/*int eflag*/)); +struct tnode *xprtype __P((void)); char *copnum __P((int len)); /* c01.c */ void build __P((int op)); -void structident __P((register union tree *p1, register union tree *p2)); -union tree *convert __P((union tree *p, int t, int cvn, int len)); -void setype __P((register union tree *p, register int t, register union tree *newp)); -union tree *chkfun __P((register union tree *p)); -union tree *disarray __P((register union tree *p)); -void chkw __P((union tree *p, int okt)); +void structident __P((register struct tree *p1, register struct nnode *p2)); +struct tree *convert __P((struct tree *p, int t, int cvn, int len)); +void setype __P((register struct tree *p, register int t, register struct tree *newp)); +struct tree *chkfun __P((register struct tree *p)); +struct tree *disarray __P((register struct tree *p)); +void chkw __P((struct tree *p, int okt)); int lintyp __P((int t)); void werror0 __P((char *s, ...)); void error0 __P((char *s, ...)); -union tree *block __P((int op, int t, int *subs, union str *str, union tree *p1, union tree *p2)); -union tree *nblock __P((register struct nmlist *ds)); -union tree *cblock __P((int v)); -union tree *fblock __P((int t, char *string)); +struct tnode *block __P((int op, int t, int *subs, union str *str, struct tree *p1, struct tree *p2)); +struct nnode *nblock __P((register struct nmlist *ds)); +struct cnode *cblock __P((_INT value)); +struct lnode *lblock __P((_LONG lvalue)); +struct fnode *fblock __P((int value, _DOUBLE fvalue)); char *Tblock __P((int n)); char *starttree __P((void)); void endtree __P((char *tp)); char *Dblock __P((int n)); -void chklval __P((register union tree *p)); -int fold __P((int op, register union tree *p1, union tree *p2)); +void chklval __P((register struct tree *p)); +int fold __P((int op, register struct tree *p1, struct tree *p2)); int conexp __P((void)); -void assignop __P((int op, register union tree *p1, register union tree *p2)); +void assignop __P((int op, register struct tree *p1, register struct tree *p2)); struct nmlist *gentemp __P((int type)); /* c02.c */ @@ -238,7 +239,7 @@ void strinit __P((struct nmlist *np, int sclass)); void setinit __P((register struct nmlist *np)); void statement __P((void)); int forstmt __P((void)); -union tree *pexpr __P((/*int eflag*/)); +struct tree *pexpr __P((/*int eflag*/)); void pswitch0 __P((void)); void funchead __P((void)); void blockhead __P((void)); @@ -264,14 +265,14 @@ int goodreg __P((struct nmlist *hp)); /* c04.c */ int decref0 __P((register int t)); int incref0 __P((register int t)); -void cbranch0 __P((union tree *t, int lbl, int cond)); -void rcexpr0 __P((register union tree *tp)); -void treeout __P((register union tree *tp, int isstruct)); +void cbranch0 __P((struct tree *t, int lbl, int cond)); +void rcexpr0 __P((register struct tree *tp)); +void treeout __P((register struct tree *tp, int isstruct)); void branch0 __P((int lab)); void label0 __P((int l)); -int plength __P((register union tree *p)); -int length __P((union tree *cs)); -int rlength __P((union tree *cs)); +int plength __P((register struct tree *p)); +int length __P((struct tree *cs)); +int rlength __P((struct tree *cs)); int simplegoto __P((void)); int nextchar __P((void)); int spnextchar __P((void)); diff --git a/c00.c b/c00.c index 6e8a66e..17f0ada 100644 --- a/c00.c +++ b/c00.c @@ -18,7 +18,7 @@ int isn0 = 1; int peeksym = -1; int line = 1; -struct tnode funcblk = { NAME }; +struct nnode funcblk = { { NAME, 0, (int *)NULL, (union str *)NULL }, (struct nmlist *)NULL, 0/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/, 0/*nn_nloc*/ }; struct kwtab kwtab[] = { {"int", INT}, @@ -54,8 +54,8 @@ struct kwtab kwtab[] = { {0, 0} }; -union tree *cmst[CMSIZ]; -union tree **cp = cmst; +struct tree *cmst[CMSIZ]; +struct tree **cp = cmst; int Wflag; /* print warning messages */ #if 0 @@ -628,13 +628,13 @@ loop: * "," or ":" because those delimiters are special * in initializer (and some other) expressions. */ -union tree *tree(/*eflag*/) /*int eflag;*/ { +struct tree *tree(/*eflag*/) /*int eflag;*/ { int *op, opst[SSIZE], *pp, prst[SSIZE]; register int andflg, o; register struct nmlist *cs; int p, ps, os, xo = 0, *xop; /*char *svtree;*/ - static struct cnode garbage = { CON, INT, (int *)NULL, (union str *)NULL, 0 }; + static struct cnode garbage = { { CON, INT, (int *)NULL, (union str *)NULL}, 0 }; /*svtree = starttree();*/ op = opst; @@ -651,7 +651,7 @@ advanc: if (cs->hclass==TYPEDEF) goto atype; if (cs->hclass==ENUMCON) { - *cp++ = cblock(cs->hoffset); + *cp++ = (struct tree *)cblock(cs->hoffset); goto tand; } if (cs->hclass==0 && cs->htype==0) @@ -664,29 +664,20 @@ advanc: error0("%s undefined; func. %s", cs->name, funcsym ? funcsym->name : "(none)"); } - *cp++ = nblock(cs); + *cp++ = (struct tree *)nblock(cs); goto tand; case FCON: /* *cp++ = fblock(DOUBLE, copnum(cval));*/ - *cp = (union tree *)Tblock(sizeof(struct fnode)); - (*cp)->f.op = FCON; - (*cp)->f.type = DOUBLE; - (*cp)->f.value = isn1++; - (*cp)->f.fvalue = fcval; - cp++; + *cp++ = (struct tree *)fblock(isn1++, fcval); goto tand; case LCON: - *cp = (union tree *)Tblock(sizeof(struct lnode)); - (*cp)->l.op = LCON; - (*cp)->l.type = LONG; - (*cp)->l.lvalue = lcval; - cp++; + *cp++ = (struct tree *)lblock(lcval); goto tand; case CON: - *cp++ = cblock(cval); + *cp++ = (struct tree *)cblock(cval); goto tand; /* fake a static char array */ @@ -720,25 +711,18 @@ advanc: putstr(cval, 0); cs = (struct nmlist *)Tblock(sizeof(struct nmlist)); cs->hclass = STATIC; - cs->hoffset = cval; -#if 1 /* one-pass version */ - /* really should change this to use nblock and fill in nmlist above better */ - *cp = (union tree *)Tblock(sizeof(struct nnode)); - (*cp)->n.op = NAME; - (*cp)->n.type = unscflg? ARRAY+UNCHAR:ARRAY+CHAR; - (*cp)->n.subsp = &nchstr; - (*cp)->n.strp = (union str *)NULL; - (*cp)->n.tr1 = (union tree *)cs; - (*cp)->n.class = STATIC; - (*cp)->n.regno = 0; - (*cp)->n.offset = 0; - (*cp)->n.nloc = cval; - cp++; -#else + /* cs->hoffset = cval; *cp++ = block(NAME, unscflg? ARRAY+UNCHAR:ARRAY+CHAR, &nchstr, - (union str *)NULL, (union tree *)cs, TNULL); -#endif - /*printf("string %p\n", cp[-1]);*/ + (union str *)NULL, (struct tree *)cs, TNULL);*/ + cs->hflag = 0; + cs->htype = unscflg? ARRAY+UNCHAR:ARRAY+CHAR; + cs->hstrp = (union str *)&nchstr; + cs->hoffset = cval; + cs->nextnm = 0; + cs->sparent = 0; + cs->hblklev = 0; + cs->name = 0; + *cp++ = (struct tree *)nblock(cs); tand: if(cp>=cmst+CMSIZ) { @@ -755,7 +739,7 @@ advanc: if (*op != LPARN || andflg) goto syntax; peeksym = o; - *cp++ = xprtype(); + *cp++ = (struct tree *)xprtype(); if ((o=symbol()) != RPARN) goto syntax; o = CAST; @@ -896,7 +880,7 @@ opon1: goto advanc; case MCALL: - *cp++ = block(NULLOP0, INT, (int *)NULL, + *cp++ = (struct tree *)block(NULLOP0, INT, (int *)NULL, (union str *)NULL, TNULL, TNULL); os = CALL; break; @@ -905,7 +889,7 @@ opon1: case INCAFT: case DECBEF: case DECAFT: - *cp++ = cblock(1); + *cp++ = (struct tree *)cblock(1); break; case LPARN: @@ -927,13 +911,13 @@ syntax: errflush(o); /*if (eflag) endtree(svtree);*/ - return((union tree *) &garbage); + return((struct tree *) &garbage); } -union tree *xprtype() { +struct tnode *xprtype() { struct nmlist typer, absname; int sc; - register union tree **scp; + register struct tree **scp; scp = cp; sc = DEFXTRN; /* will cause error if class mentioned */ diff --git a/c01.c b/c01.c index 85b4946..7b6c043 100644 --- a/c01.c +++ b/c01.c @@ -24,7 +24,7 @@ void build(op) int op; { register int t1; int t2, t; - register union tree *p1, *p2, *p3; + register struct tree *p1, *p2, *p3; int dope, leftc, cvn, pcvn; /* @@ -39,16 +39,16 @@ void build(op) int op; { if ((dope&BINARY)!=0) { p2 = chkfun(disarray(*--cp)); if (p2) - t2 = p2->t.type; + t2 = p2->t_type; } p1 = *--cp; /* * sizeof gets turned into a number here. */ if (op==SIZEOF) { - p1 = cblock(length(p1)); - p1->c.type = UNSIGN; - *cp++ = p1; + struct cnode *p = cblock(length(p1)); + p->cn_type = UNSIGN; + *cp++ = (struct tree *)p; return; } if (op!=AMPER) { @@ -56,7 +56,7 @@ void build(op) int op; { if (op!=CALL) p1 = chkfun(p1); } - t1 = p1->t.type; + t1 = p1->t_type; if (t1==CHAR) t1 = INT; else if (t1==UNCHAR) @@ -72,18 +72,18 @@ void build(op) int op; { case CAST: if ((t1&XTYPE)==FUNC || (t1&XTYPE)==ARRAY) error0("Disallowed conversion"); - if (p1->t.type==UNCHAR) { - *cp++ = block(ETYPE, UNSIGN, (int *)NULL, (union str *)NULL, + if (p1->t_type==UNCHAR) { + *cp++ = (struct tree *)block(ETYPE, UNSIGN, (int *)NULL, (union str *)NULL, TNULL, TNULL); *cp++ = p2; build(CAST); - *cp++ = cblock(0377); + *cp++ = (struct tree *)cblock(0377); build(AND); return; } - if (p2->t.type==CHAR || p2->t.type==UNCHAR) - p2 = block(PLUS, t2, (int *)NULL, (union str *)NULL, - p2, cblock(0)); + if (p2->t_type==CHAR || p2->t_type==UNCHAR) + p2 = (struct tree *)block(PLUS, t2, (int *)NULL, (union str *)NULL, + p2, (struct tree *)cblock(0)); break; /* end of expression */ @@ -93,7 +93,7 @@ void build(op) int op; { /* no-conversion operators */ case QUEST: - if (p2->t.op!=COLON) + if (p2->t_op!=COLON) error0("Illegal conditional"); else if (fold(QUEST, p1, p2)) @@ -108,13 +108,13 @@ void build(op) int op; { * case COMMA: */ case SEQNC: - *cp++ = block(op, t2, p2->t.subsp, p2->t.strp, p1, p2); + *cp++ = (struct tree *)block(op, t2, p2->t_subsp, p2->t_strp, p1, p2); return; case COMMA: case LOGAND: case LOGOR: - *cp++ = block(op, t, p2->t.subsp, p2->t.strp, p1, p2); + *cp++ = (struct tree *)block(op, t, p2->t_subsp, p2->t_strp, p1, p2); return; case EXCLA: @@ -144,18 +144,18 @@ void build(op) int op; { } if ((t1&XTYPE) != FUNC) error0("Call of non-function"); - *cp++ = block(CALL,decref0(t1),p1->t.subsp,p1->t.strp,p1,p2); + *cp++ = (struct tree *)block(CALL,decref0(t1),p1->t_subsp,p1->t_strp,p1,p2); return; case STAR: if ((t1&XTYPE) == FUNC) error0("Illegal indirection"); - *cp++ = block(STAR, decref0(t1), p1->t.subsp, p1->t.strp, p1, TNULL); + *cp++ = (struct tree *)block(STAR, decref0(t1), p1->t_subsp, p1->t_strp, p1, TNULL); return; case AMPER: - if (p1->t.op==NAME || p1->t.op==STAR) { - *cp++ = block(op,incref0(p1->t.type),p1->t.subsp,p1->t.strp,p1,TNULL); + if (p1->t_op==NAME || p1->t_op==STAR) { + *cp++ = (struct tree *)block(op,incref0(p1->t_type),p1->t_subsp,p1->t_strp,p1,TNULL); return; } error0("Illegal lvalue"); @@ -165,7 +165,7 @@ void build(op) int op; { * a.b goes to (&a)->b */ case DOT: - if (p1->t.op==CALL && t1==STRUCT) { + if (p1->t_op==CALL && t1==STRUCT) { t1 = incref0(t1); setype(p1, t1, p1); } else { @@ -180,30 +180,32 @@ void build(op) int op; { * then * is tacked on to access the member. */ case ARROW: - if (p2->t.op!=NAME || ((struct nmlist *)p2->t.tr1)->hclass!=MOS) { + if (p2->t_op!=NAME || ((struct nnode *)p2)->nn_tr1->hclass!=MOS) { error0("Illegal structure ref"); *cp++ = p1; return; } - structident(p1, p2); - t2 = p2->t.type; - if (t2==INT && ((struct nmlist *)p2->t.tr1)->hflag&FFIELD) +#define np2 ((struct nnode *)p2) + structident(p1, np2); + t2 = np2->nn_type; + if (t2==INT && np2->nn_tr1->hflag&FFIELD) t2 = UNSIGN; t = incref0(t2); chkw(p1, -1); - setype(p1, t, p2); - *cp++ = block(PLUS, t, p2->t.subsp, p2->t.strp, - p1, cblock(((struct nmlist *)p2->t.tr1)->hoffset)); + setype(p1, t, (struct tree *)np2); + *cp++ = (struct tree *)block(PLUS, t, np2->nn_subsp, np2->nn_strp, + p1, (struct tree *)cblock(np2->nn_tr1->hoffset)); build(STAR); - if (((struct nmlist *)p2->t.tr1)->hflag&FFIELD) + if (np2->nn_tr1->hflag&FFIELD) #if 1 - cp[-1] = block(FSEL, UNSIGN, (int *)NULL, (union str *)NULL, - cp[-1], (union tree *)((struct nmlist *)p2->t.tr1)->hstrp); + cp[-1] = (struct tree *)block(FSEL, UNSIGN, (int *)NULL, (union str *)NULL, + cp[-1], (struct tree *)np2->nn_tr1->hstrp); #else - *cp++ = block(FSEL, UNSIGN, (int *)NULL, (union str *)NULL, - *--cp, (union tree *)((struct nmlist *)p2->t.tr1)->hstrp); + *cp++ = (struct tree *)block(FSEL, UNSIGN, (int *)NULL, (union str *)NULL, + *--cp, (struct tree *)np2->nn_tr1->hstrp); #endif return; +#undef np2 } if ((dope&LVALUE)!=0) chklval(p1); @@ -220,13 +222,13 @@ void build(op) int op; { t1 = DOUBLE; else if (op==FTOI) t1 = INT; - if (!fold(op, p1, (union tree *)NULL)) - *cp++ = block(op, t1, p1->t.subsp, p1->t.strp, p1,TNULL); + if (!fold(op, p1, (struct tree *)NULL)) + *cp++ = (struct tree *)block(op, t1, p1->t_subsp, p1->t_strp, p1,TNULL); return; } cvn = 0; if (t1==STRUCT || t2==STRUCT) { - if (t1!=t2 || p1->t.strp != p2->t.strp) + if (t1!=t2 || p1->t_strp != p2->t_strp) error0("Incompatible structures"); cvn = 0; } else @@ -252,12 +254,12 @@ void build(op) int op; { t = t1; if (op==ASSIGN) { if (cvn==PTI) { - if (t1!=t2 || ((t1&TYPE)==STRUCT && p1->t.strp!=p2->t.strp)) + if (t1!=t2 || ((t1&TYPE)==STRUCT && p1->t_strp!=p2->t_strp)) werror0("mixed pointer assignment"); cvn = leftc = 0; } if ((cvn==ITP || cvn==LTP) - && (p2->t.op!=CON || p2->c.value!=0) - && (p2->t.op!=LCON || p2->l.lvalue!=0)) { + && (p2->t_op!=CON || ((struct cnode *)p2)->cn_value!=0) + && (p2->t_op!=LCON || ((struct lnode *)p2)->ln_lvalue!=0)) { /* * Allow "i = p" and "p = i" with a warning, where * i is some form of integer (not 0) and p is a @@ -305,8 +307,8 @@ void build(op) int op; { */ if (op==COLON && (cvn==ITP || cvn==LTP)) { p3 = leftc? p1: p2; - if ((p3->t.op!=CON || p3->c.value!=0) - && (p3->t.op!=LCON || p3->l.lvalue!=0)) { + if ((p3->t_op!=CON || ((struct cnode *)p3)->cn_value!=0) + && (p3->t_op!=LCON || ((struct lnode *)p3)->ln_lvalue!=0)) { werror0("illegal combination of pointer and integer, op :"); if (cvn==ITP) cvn = leftc = 0; @@ -330,8 +332,8 @@ void build(op) int op; { cvn = 0; if (op==MINUS) { pcvn++; - p1 = block(ITOL, LONG, (int *)NULL, (union str *)NULL, p1, TNULL); - p2 = block(ITOL, LONG, (int *)NULL, (union str *)NULL, p2, TNULL); + p1 = (struct tree *)block(ITOL, LONG, (int *)NULL, (union str *)NULL, p1, TNULL); + p2 = (struct tree *)block(ITOL, LONG, (int *)NULL, (union str *)NULL, p2, TNULL); t = LONG; } else { if (t1!=t2 || (t1!=(PTR+CHAR) && t1!=(PTR+UNCHAR))) @@ -341,8 +343,8 @@ void build(op) int op; { if (cvn) { if ((cvn==ITP || cvn==LTP) && (opdope0[op]&PCVOK)==0) { p3 = leftc? p1: p2; - if ((p3->t.op!=CON || p3->c.value!=0) - && (p3->t.op!=LCON || p3->l.lvalue!=0)) + if ((p3->t_op!=CON || ((struct cnode *)p3)->cn_value!=0) + && (p3->t_op!=LCON || ((struct lnode *)p3)->ln_lvalue!=0)) cvn = XX; else cvn = 0; @@ -364,21 +366,21 @@ void build(op) int op; { t = INT; if (op==CAST) { /* could the below be an oversight? gcc notes rhs always true */ - if (t!=DOUBLE /*&& (t!=INT || p2->t.type!=CHAR || p2->t.type!=UNCHAR)*/) { - p2->t.type = t; - p2->t.subsp = p1->t.subsp; - p2->t.strp = p1->t.strp; + if (t!=DOUBLE /*&& (t!=INT || p2->t_type!=CHAR || p2->t_type!=UNCHAR)*/) { + p2->t_type = t; + p2->t_subsp = p1->t_subsp; + p2->t_strp = p1->t_strp; } - if (t==INT && p1->t.type==CHAR) - p2 = block(ITOC, INT, (int *)NULL, (union str *)NULL, p2, TNULL); + if (t==INT && p1->t_type==CHAR) + p2 = (struct tree *)block(ITOC, INT, (int *)NULL, (union str *)NULL, p2, TNULL); *cp++ = p2; return; } - if (pcvn) - t2 = plength(p1->t.tr1); + if (pcvn) /* says op == MINUS */ + t2 = plength(((struct tnode *)p1)->tn_tr1); if (fold(op, p1, p2)==0) { p3 = leftc?p2:p1; - *cp++ = block(op, t, p3->t.subsp, p3->t.strp, p1, p2); + *cp++ = (struct tree *)block(op, t, p3->t_subsp, p3->t_strp, p1, p2); } if (pcvn) { p1 = *--cp; @@ -386,17 +388,17 @@ void build(op) int op; { } } -void structident(p1, p2) register union tree *p1; register union tree *p2; { +void structident(p1, p2) register struct tree *p1; register struct nnode *p2; { register struct nmlist *np, *nporig; int vartypes = 0, namesame = 1; - np = nporig = (struct nmlist *)p2->t.tr1; + np = nporig = p2->nn_tr1; for (;;) { - if (namesame && p1->t.type==STRUCT+PTR && p1->t.strp == np->sparent) { - p2->t.type = np->htype; - p2->t.strp = np->hstrp; - p2->t.subsp = np->hsubsp; - p2->t.tr1 = (union tree *)np; + if (namesame && p1->t_type==STRUCT+PTR && p1->t_strp == np->sparent) { + p2->nn_type = np->htype; + p2->nn_strp = np->hstrp; + p2->nn_subsp = np->hsubsp; + p2->nn_tr1 = np; return; } np = np->nextnm; @@ -421,7 +423,7 @@ void structident(p1, p2) register union tree *p1; register union tree *p2; { /* * Generate the appropriate conversion operator. */ -union tree *convert(p, t, cvn, len) union tree *p; int t; int cvn; int len; { +struct tree *convert(p, t, cvn, len) struct tree *p; int t; int cvn; int len; { register int op; if (cvn==0) @@ -430,9 +432,9 @@ union tree *convert(p, t, cvn, len) union tree *p; int t; int cvn; int len; { if (opdope0[op]&BINARY) { if (len==0) error0("Illegal conversion"); - return(block(op, t, (int *)NULL, (union str *)NULL, p, cblock(len))); + return((struct tree *)block(op, t, (int *)NULL, (union str *)NULL, p, (struct tree *)cblock(len))); } - return(block(op, t, (int *)NULL, (union str *)NULL, p, TNULL)); + return((struct tree *)block(op, t, (int *)NULL, (union str *)NULL, p, TNULL)); } /* @@ -442,16 +444,16 @@ union tree *convert(p, t, cvn, len) union tree *p; int t; int cvn; int len; { * type at. * Used with structure references. */ -void setype(p, t, newp) register union tree *p; register int t; register union tree *newp; { - for (;; p = p->t.tr1) { - p->t.subsp = newp->t.subsp; - p->t.strp = newp->t.strp; - p->t.type = t; - if (p->t.op==AMPER) +void setype(p, t, newp) register struct tree *p; register int t; register struct tree *newp; { + for (;; p = ((struct tnode *)p)->tn_tr1) { + p->t_subsp = newp->t_subsp; + p->t_strp = newp->t_strp; + p->t_type = t; + if (p->t_op==AMPER) t = decref0(t); - else if (p->t.op==STAR) + else if (p->t_op==STAR) t = incref0(t); - else if (p->t.op!=PLUS) + else if (p->t_op!=PLUS) break; } } @@ -460,11 +462,11 @@ void setype(p, t, newp) register union tree *p; register int t; register union t * A mention of a function name is turned into * a pointer to that function. */ -union tree *chkfun(p) register union tree *p; { +struct tree *chkfun(p) register struct tree *p; { register int t; - if (((t = p->t.type)&XTYPE)==FUNC && p->t.op!=ETYPE) - return(block(AMPER,incref0(t),p->t.subsp,p->t.strp,p,TNULL)); + if (((t = p->t_type)&XTYPE)==FUNC && p->t_op!=ETYPE) + return((struct tree *)block(AMPER,incref0(t),p->t_subsp,p->t_strp,p,TNULL)); return(p); } @@ -472,17 +474,17 @@ union tree *chkfun(p) register union tree *p; { * A mention of an array is turned into * a pointer to the base of the array. */ -union tree *disarray(p) register union tree *p; { +struct tree *disarray(p) register struct tree *p; { register int t; if (p==NULL) return(p); /* check array & not MOS and not typer */ - if (((t = p->t.type)&XTYPE)!=ARRAY - || p->t.op==NAME && ((struct nmlist *)p->t.tr1)->hclass==MOS - || p->t.op==ETYPE) + if (((t = p->t_type)&XTYPE)!=ARRAY + || p->t_op==NAME && ((struct nnode *)p)->nn_tr1->hclass==MOS + || p->t_op==ETYPE) return(p); - p->t.subsp++; + p->t_subsp++; *cp++ = p; setype(p, decref0(t), p); build(AMPER); @@ -495,8 +497,8 @@ union tree *disarray(p) register union tree *p; { * okt might be nonexistent or 'long' * (e.g. for <<). */ -void chkw(p, okt) union tree *p; int okt; { - register int t = p->t.type; +void chkw(p, okt) struct tree *p; int okt; { + register int t = p->t_type; if (t == UNLONG) t = LONG; @@ -579,107 +581,94 @@ void error0(s, va_alist) char *s; va_dcl * setting the operator, type, dimen/struct table ptrs, * and the operands. */ -union tree *block(op, t, subs, str, p1,p2) int op; int t; int *subs; union str *str; union tree *p1; union tree *p2; { - register union tree *p; - - /*fprintf(stderr, "block(%d, %d, {%d, %d}, {%d, %d})\n", op, t, - (op == NAME) ? -2 : (p1 ? (int)(_INT)p1->t.op : -1), - (op == NAME) ? -2 : (p1 ? (int)(_INT)p1->t.type : -1), - (op == FSEL) ? -3 : (p2 ? (int)(_INT)p2->t.op : -1), - (op == FSEL) ? -3 : (p2 ? (int)(_INT)p2->t.type : -1));*/ - p = (union tree *)Tblock(sizeof(struct tnode)); - p->t.op = op; - p->t.type = t; - p->t.subsp = subs; - p->t.strp = str; - p->t.tr1 = p1; +struct tnode *block(op, t, subs, str, p1, p2) int op; int t; int *subs; union str *str; struct tree *p1; struct tree *p2; { + register struct tnode *p; + + p = (struct tnode *)Tblock(sizeof(struct tnode)); + p->tn_op = op; + p->tn_type = t; + p->tn_subsp = subs; + p->tn_strp = str; + p->tn_tr1 = p1; if (opdope0[op]&BINARY) - p->t.tr2 = p2; + p->tn_tr2 = p2; else - p->t.tr2 = NULL; + p->tn_tr2 = NULL; return(p); } -union tree *nblock(ds) register struct nmlist *ds; { - /* return(block(NAME, ds->htype, ds->hsubsp, ds->hstrp, (union tree *)ds, TNULL));*/ - /* XXX compatibility: */ - /* formerly c0 would output a NAME node as follows: */ - /* hp = (struct nmlist *)tp->t.tr1; */ - /* if (hp->hclass==EXTERN) */ - /* outcode("BNNS", NAME, EXTERN, tp->t.type, hp->name); */ - /* else */ - /* outcode("BNNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->t.type, hp->hoffset); */ - /* this would then be decoded by c1 as follows: */ - /* t = geti(); */ - /* if (t==EXTERN) { */ - /* tp = getblk(sizeof(struct xnode)); */ - /* tp->t.type = geti(); */ - /* outname(s); */ - /* tp->x.name = (char *)getblk(strlen(s) + 1); */ - /* strcpy(tp->x.name, s); */ - /* } else { */ - /* tp = getblk(sizeof(struct nnode)); */ - /* tp->t.type = geti(); */ - /* tp->n.nloc = geti(); */ - /* } */ - /* tp->t.op = NAME; */ - /* tp->n.class = t; */ - /* tp->n.regno = 0; */ - /* tp->n.offset = 0; */ - union tree *tp; +struct nnode *nblock(ds) register struct nmlist *ds; { + /* return(block(NAME, ds->htype, ds->hsubsp, ds->hstrp, (struct tree *)ds, TNULL));*/ + struct nnode *p; + if (ds->hclass == EXTERN) { - tp = (union tree *)Tblock(sizeof(struct xnode)); - /*fprintf(stderr, "nblock xtname %p\n", tp);*/ - tp->x.name = Tblock((strlen(ds->name)+2+LNCPW-1) & ~(LNCPW-1)); - tp->x.name[0] = '_'; - strcpy(tp->x.name + 1, ds->name); +#define xp (*(struct xnode **)&p) + xp = (struct xnode *)Tblock(sizeof(struct xnode)); + xp->xn_name = Tblock((strlen(ds->name)+2+LNCPW-1) & ~(LNCPW-1)); + xp->xn_name[0] = '_'; + strcpy(xp->xn_name + 1, ds->name); +#undef xp } else { - tp = (union tree *)Tblock(sizeof(struct nnode)); - /*fprintf(stderr, "nblock tname %p\n", tp);*/ - tp->n.nloc = ds->hoffset; + p = (struct nnode *)Tblock(sizeof(struct nnode)); + p->nn_nloc = ds->hoffset; } - tp->n.op = NAME; - tp->n.type = ds->htype; - tp->n.subsp = ds->hsubsp; - tp->n.strp = ds->hstrp; - tp->n.tr1 = (union tree *)ds; - tp->n.class = ds->hclass==0?STATIC:ds->hclass; - tp->n.regno = 0; - tp->n.offset = 0; - return tp; + p->nn_op = NAME; + p->nn_type = ds->htype; + p->nn_subsp = ds->hsubsp; + p->nn_strp = ds->hstrp; + p->nn_tr1 = ds; + p->nn_class = ds->hclass==0?STATIC:ds->hclass; + p->nn_regno = 0; + p->nn_offset = 0; + return p; } /* * Generate a block for a constant */ -union tree *cblock(v) int v; { - register union tree *p; - - /*fprintf(stderr, "cblock(0%06o)\n", v & 0177777);*/ - p = (union tree *)Tblock(sizeof(struct cnode)); - p->c.op = CON; - p->c.type = INT; - p->c.subsp = NULL; - p->c.strp = NULL; - p->c.value = v; +struct cnode *cblock(value) _INT value; { + register struct cnode *p; + + p = (struct cnode *)Tblock(sizeof(struct cnode)); + p->cn_op = CON; + p->cn_type = INT; + p->cn_subsp = NULL; + p->cn_strp = NULL; + p->cn_value = value; return(p); } /* * A block for a float constant */ -/*union tree *fblock(t, string) int t; char *string; { - register union tree *p; - - p = (union tree *)Tblock(sizeof(struct fnode)); - p->f.op = FCON; - p->f.type = t; - p->f.subsp = NULL; - p->f.strp = NULL; - p->f.cstr = string; +struct lnode *lblock(lvalue) _LONG lvalue; { + register struct lnode *p; + + p = (struct lnode *)Tblock(sizeof(struct lnode)); + p->ln_op = LCON; + p->ln_type = LONG; + p->ln_subsp = NULL; + p->ln_strp = NULL; + p->ln_lvalue = lvalue; return(p); -}*/ +} + +/* + * A block for a float constant + */ +struct fnode *fblock(value, fvalue) int value; _DOUBLE fvalue; { + register struct fnode *p; + + p = (struct fnode *)Tblock(sizeof(struct fnode)); + p->fn_op = FCON; + p->fn_type = DOUBLE; + p->fn_subsp = NULL; + p->fn_strp = NULL; + p->fn_value = value; + p->fn_fvalue = fvalue; + return(p); +} /* * Assign a block for use in the @@ -758,10 +747,10 @@ char *Dblock(n) int n; { /* * Check that a tree can be used as an lvalue. */ -void chklval(p) register union tree *p; { - if (p->t.op==FSEL) - p = p->t.tr1; - if (p->t.op!=NAME && p->t.op!=STAR) +void chklval(p) register struct tree *p; { + if (p->t_op==FSEL) + p = ((struct tnode *)p)->tn_tr1; + if (p->t_op!=NAME && p->t_op!=STAR) error0("Lvalue required"); } @@ -771,31 +760,36 @@ void chklval(p) register union tree *p; { * but this is used to allow constant expressions * to be used in switches and array bounds. */ -int fold(op, p1, p2) int op; register union tree *p1; union tree *p2; { +int fold(op, p1, p2) int op; register struct tree *p1; struct tree *p2; { register int v1, v2; int unsignf; - if (p1->t.op!=CON) + if (p1->t_op!=CON) return(0); - unsignf = p1->c.type==UNSIGN; - unsignf |= p1->c.type==UNLONG; +#define cp1 ((struct cnode *)p1) + unsignf = cp1->cn_type==UNSIGN; + unsignf |= cp1->cn_type==UNLONG; if (op==QUEST) { - if (p2->t.tr1->t.op==CON && p2->t.tr2->t.op==CON) { - p1->c.value = p1->c.value? p2->t.tr1->c.value: p2->t.tr2->c.value; - *cp++ = p1; - p1->t.type = p2->t.type; +#define tp2 ((struct tnode *)p2) + if (tp2->tn_tr1->t_op==CON && tp2->tn_tr2->t_op==CON) { + cp1->cn_value = cp1->cn_value? ((struct cnode *)tp2->tn_tr1)->cn_value: ((struct cnode *)tp2->tn_tr2)->cn_value; + *cp++ = (struct tree *)cp1; + cp1->cn_type = tp2->tn_type; return(1); } return(0); +#undef tp2 } if (p2) { - if (p2->t.op!=CON) + if (p2->t_op!=CON) return(0); - v2 = p2->c.value; - unsignf |= p2->c.type==UNSIGN; - unsignf |= p2->c.type==UNLONG; +#define cp2 ((struct cnode *)p2) + v2 = cp2->cn_value; + unsignf |= cp2->cn_type==UNSIGN; + unsignf |= cp2->cn_type==UNLONG; +#undef cp2 } - v1 = p1->c.value; + v1 = cp1->cn_value; switch (op) { case PLUS: @@ -923,11 +917,12 @@ int fold(op, p1, p2) int op; register union tree *p1; union tree *p2; { default: return(0); } - p1->c.value = v1; - *cp++ = p1; + cp1->cn_value = v1; + *cp++ = (struct tree *)cp1; if (unsignf) - p1->t.type = UNSIGN; + cp1->cn_type = UNSIGN; return(1); +#undef cp1 } /* @@ -935,26 +930,26 @@ int fold(op, p1, p2) int op; register union tree *p1; union tree *p2; { * for example an array bound or a case value. */ int conexp() { - register union tree *t; + register struct tree *t; char *st = starttree(); initflg++; if (t = tree(/*1*/)) - if (t->t.op != CON) + if (t->t_op != CON) error0("Constant required"); + if (!t) abort(); /* don't think this can ever happen */ initflg--; - /*fprintf(stderr, "conexp() %d\n", t->c.value);*/ endtree(st); - return(t->c.value); + return(((struct cnode *)t)->cn_value); } /* * Handle peculiar assignment ops that need a temporary. */ -void assignop(op, p1, p2) int op; register union tree *p1; register union tree *p2; { +void assignop(op, p1, p2) int op; register struct tree *p1; register struct tree *p2; { register struct nmlist *np; op += PLUS - ASPLUS; - if (p1->t.op==NAME) { + if (p1->t_op==NAME) { *cp++ = p1; *cp++ = p1; *cp++ = p2; @@ -962,14 +957,14 @@ void assignop(op, p1, p2) int op; register union tree *p1; register union tree * build(ASSIGN); return; } - np = gentemp(incref0(p1->t.type)); - *cp++ = nblock(np); + np = gentemp(incref0(p1->t_type)); + *cp++ = (struct tree *)nblock(np); *cp++ = p1; build(AMPER); build(ASSIGN); - *cp++ = nblock(np); + *cp++ = (struct tree *)nblock(np); build(STAR); - *cp++ = nblock(np); + *cp++ = (struct tree *)nblock(np); build(STAR); *cp++ = p2; build(op); @@ -991,7 +986,7 @@ struct nmlist *gentemp(type) int type; { tp->hsubsp = NULL; tp->hstrp = NULL; tp->hblklev = blklev; - autolen -= rlength((union tree *)tp); + autolen -= rlength((struct tree *)tp); tp->hoffset = autolen; if (autolen < maxauto) maxauto = autolen; diff --git a/c02.c b/c02.c index 0d91a3d..f191e01 100644 --- a/c02.c +++ b/c02.c @@ -46,8 +46,8 @@ void extdef() { if ((ds->htype&XTYPE)==FUNC) { if ((peeksym=symbol())==LBRACE || peeksym==KEYW || (peeksym==NAME && csym->hclass==TYPEDEF)) { - funcblk.type = decref0(ds->htype); - funcblk.strp = ds->hstrp; + funcblk.nn_type = decref0(ds->htype); + funcblk.nn_strp = ds->hstrp; setinit(ds); outcode("BS", SYMDEF, sclass==EXTERN?ds->name:""); cfunc(); @@ -57,7 +57,7 @@ void extdef() { error0("Inappropriate parameters"); } else if ((o=symbol())==COMMA || o==SEMI) { peeksym = o; - o = (length((union tree *)ds)+ALIGN) & ~ALIGN; + o = (length((struct tree *)ds)+ALIGN) & ~ALIGN; if (sclass==STATIC) { setinit(ds); outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->name, SSPACE, o); @@ -132,7 +132,7 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; { struct nmlist np; register int nel, ninit; int width, isarray, o, brace, realtype; - union tree *s; + struct tree *s; np = *anp; realtype = np.htype; @@ -141,7 +141,7 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; { isarray++; else flex = 0; - width = length((union tree *)&np); + width = length((struct tree *)&np); nel = 1; /* * If it's an array, find the number of elements. @@ -156,7 +156,7 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; { np.hsubsp++; if (width==0 && flex==0) error0("0-length row: %s", anp->name); - o = length((union tree *)&np); + o = length((struct tree *)&np); nel = (unsigned)width/o; width = o; } @@ -190,18 +190,18 @@ int cinit(anp, flex, sclass) struct nmlist *anp; int flex; int sclass; { initflg = 0; if (np.hflag&FFIELD) error0("No field initialization"); - *cp++ = nblock(&np); + *cp++ = (struct tree *)nblock(&np); *cp++ = s; build(ASSIGN); if (sclass==AUTO||sclass==REG) rcexpr0(*--cp); else if (sclass==ENUMCON) { - if (s->t.op!=CON) + if (s->t_op!=CON) error0("Illegal enum constant for %s", anp->name); - anp->hoffset = s->c.value; + anp->hoffset = ((struct cnode *)s)->cn_value; } else - rcexpr0(block(INIT,np.htype,(int *)NULL, - (union str *)NULL, (*--cp)->t.tr2, TNULL)); + rcexpr0((struct tree *)block(INIT,np.htype,(int *)NULL, + (union str *)NULL, ((struct tnode *)(*--cp))->tn_tr2, TNULL)); endtree(st); } ninit++; @@ -351,7 +351,7 @@ stmt: case IF: { register int o2; - register union tree *np; + register struct tree *np; char *st = starttree(); np = pexpr(/*1*/); @@ -477,7 +477,7 @@ stmt: goto stmt; case SWITCH: { - register union tree *np; + register struct tree *np; register char *st; o1 = brklab; @@ -485,7 +485,7 @@ stmt: st = starttree(); np = pexpr(/*0*/); chkw(np, -1); - rcexpr0(block(RFORCE,0,(int *)NULL,(union str *)NULL,np,TNULL)); + rcexpr0((struct tree *)block(RFORCE,0,(int *)NULL,(union str *)NULL,np,TNULL)); endtree(st); pswitch0(); brklab = o1; @@ -568,7 +568,7 @@ syntax: */ int forstmt() { register int o; - register union tree *st; + register struct tree *st; register int l; char *ss; @@ -628,16 +628,16 @@ int forstmt() { * A parenthesized expression, * as after "if". */ -union tree *pexpr(/*eflag*/) /*int eflag;*/ { +struct tree *pexpr(/*eflag*/) /*int eflag;*/ { register int o; - register union tree *t; + register struct tree *t; if ((o=symbol())!=LPARN) goto syntax; t = tree(/*eflag*/); if ((o=symbol())!=RPARN) goto syntax; - if (t->t.type==VOID) + if (t->t_type==VOID) error0("Illegal use of void"); return(t); syntax: @@ -685,7 +685,7 @@ void pswitch0() { * Structure resembling a block for a register variable. */ struct nmlist hreg = { REG, 0, 0, NULL, NULL, 0 }; -struct tnode areg = { NAME, 0, NULL, NULL, 0/*degree*/, (union tree *)&hreg}; +struct nnode areg = { { NAME, 0, (int *)NULL, (union str *)NULL }, &hreg, 0/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/, 0/*nn_nlock*/ }; void funchead() { register int pl; register struct nmlist *cs; @@ -703,13 +703,13 @@ void funchead() { cs->htype -= (ARRAY-PTR); /* set ptr */ cs->hsubsp++; /* pop dims */ } - pl += rlength((union tree *)cs); + pl += rlength((struct tree *)cs); if (cs->hclass==AREG && (hreg.hoffset=goodreg(cs))>=0) { st = starttree(); - *cp++ = (union tree *)&areg; - *cp++ = nblock(cs); - areg.type = cs->htype; - areg.strp = cs->hstrp; + *cp++ = (struct tree *)&areg; + *cp++ = (struct tree *)nblock(cs); + areg.nn_type = cs->htype; + areg.nn_strp = cs->hstrp; cs->hclass = AUTO; build(ASSIGN); rcexpr0(*--cp); diff --git a/c03.c b/c03.c index 68582a5..57ac212 100644 --- a/c03.c +++ b/c03.c @@ -255,7 +255,7 @@ int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; { isunion++; mosflg = FMOS; if ((peeksym=symbol()) == SEMI) { - o = length((union tree *)tptr); + o = length((struct tree *)tptr); if (o>offset) offset = o; } @@ -441,7 +441,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs } elsize = 0; if (skw==MOS) { - elsize = length((union tree *)dsym); + elsize = length((struct tree *)dsym); if ((peeksym = symbol())==COLON) { elsize = 0; peeksym = -1; @@ -485,7 +485,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs if (skw==AUTO) { /* if (STAUTO < 0) { */ /*fprintf(stderr, "%s autolen %d -> ", dsym->name, autolen);*/ - autolen -= rlength((union tree *)dsym); + autolen -= rlength((struct tree *)dsym); dsym->hoffset = autolen; if (autolen < maxauto) maxauto = autolen; @@ -507,7 +507,7 @@ int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offs outcode("B", EVEN); } else outcode("BBNBN", BSS, LABEL, isn0++, SSPACE, - rlength((union tree *)dsym)); + rlength((struct tree *)dsym)); outcode("B", PROG); isinit = 0; } else if (skw==REG && isinit) { diff --git a/c04.c b/c04.c index a3f778f..9b25479 100644 --- a/c04.c +++ b/c04.c @@ -37,7 +37,7 @@ int incref0(t) register int t; { * Make a tree that causes a branch to lbl * if the tree's value is non-zero together with the cond. */ -void cbranch0(t, lbl, cond) union tree *t; int lbl; int cond; { +void cbranch0(t, lbl, cond) struct tree *t; int lbl; int cond; { #if 1 /* one-pass version */ long outloc; @@ -61,21 +61,23 @@ void cbranch0(t, lbl, cond) union tree *t; int lbl; int cond; { /* * Write out a tree. */ -void rcexpr0(tp) register union tree *tp; { +void rcexpr0(tp) register struct tree *tp; { #if 1 /* one-pass version */ long outloc; #endif /* * Special optimization */ - if (tp->t.op==INIT && tp->t.tr1->t.op==CON) { - if (tp->t.type==CHAR || tp->t.type==UNCHAR) { - outcode("B1N0", BDATA, tp->t.tr1->c.value); + if (tp->t_op==INIT && ((struct tnode *)tp)->tn_tr1->t_op==CON) { +#define ttp ((struct tnode *)tp) + if (ttp->tn_type==CHAR || ttp->tn_type==UNCHAR) { + outcode("B1N0", BDATA, ((struct cnode *)ttp->tn_tr1)->cn_value); return; - } else if (tp->t.type==INT || tp->t.type==UNSIGN) { - outcode("BN", SINIT, tp->t.tr1->c.value); + } else if (ttp->tn_type==INT || ttp->tn_type==UNSIGN) { + outcode("BN", SINIT, ((struct cnode *)ttp->tn_tr1)->cn_value); return; } +#undef ttp } #if 1 /* one-pass version */ regpanic = 0; @@ -96,28 +98,28 @@ void rcexpr0(tp) register union tree *tp; { } #if 0 -void treeout(tp, isstruct) register union tree *tp; int isstruct; { +void treeout(tp, isstruct) register struct tree *tp; int isstruct; { register struct nmlist *hp; register int nextisstruct; - if (tp == NULL || tp->t.op==NULLOP0) { + if (tp == NULL || tp->tn_op==NULLOP0) { outcode("B", NULLOP); return; } - nextisstruct = tp->t.type==STRUCT; - switch(tp->t.op) { + nextisstruct = tp->tn_type==STRUCT; + switch(tp->tn_op) { case NAME: - hp = (struct nmlist *)tp->t.tr1; + hp = (struct nmlist *)tp->tn_tr1; if (hp->hclass==TYPEDEF) error0("Illegal use of type name"); #if 1 if (hp->hclass==EXTERN) - outcode("BNNS", NAME, EXTERN, tp->t.type, hp->name); + outcode("BNNS", NAME, EXTERN, tp->tn_type, hp->name); else - outcode("BNNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->t.type, hp->hoffset); + outcode("BNNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->tn_type, hp->hoffset); #else - outcode("BNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->t.type); + outcode("BNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->tn_type); if (hp->hclass==EXTERN) outcode("S", hp->name); else @@ -126,26 +128,26 @@ void treeout(tp, isstruct) register union tree *tp; int isstruct; { break; case LCON: - outcode("BNNN", tp->l.op, tp->l.type, (_UNSIGNED_INT)(tp->l.lvalue>>16), - (_UNSIGNED_INT)tp->l.lvalue); + outcode("BNNN", tp->ln_op, tp->ln_type, (_UNSIGNED_INT)(tp->ln_lvalue>>16), + (_UNSIGNED_INT)tp->ln_lvalue); break; case CON: - outcode("BNN", tp->c.op, tp->c.type, tp->c.value); + outcode("BNN", tp->cn_op, tp->cn_type, tp->cn_value); break; case FCON: - outcode("BNF", tp->f.op, tp->f.type, tp->f.cstr); + outcode("BNF", tp->fn_op, tp->fn_type, tp->f.cstr); break; case STRING: - outcode("BNNN", NAME, STATIC, tp->t.type, tp->t.tr1); + outcode("BNNN", NAME, STATIC, tp->tn_type, tp->tn_tr1); break; case FSEL: - treeout(tp->t.tr1, nextisstruct); - outcode("BNNN", tp->t.op, tp->t.type, - ((struct FS *)tp->t.tr2)->bitoffs, ((struct FS *)tp->t.tr2)->flen); + treeout(tp->tn_tr1, nextisstruct); + outcode("BNNN", tp->tn_op, tp->tn_type, + ((struct FS *)tp->tn_tr2)->bitoffs, ((struct FS *)tp->tn_tr2)->flen); break; case ETYPE: @@ -153,26 +155,26 @@ void treeout(tp, isstruct) register union tree *tp; int isstruct; { break; case AMPER: - treeout(tp->t.tr1, 1); - outcode("BN", tp->t.op, tp->t.type); + treeout(tp->tn_tr1, 1); + outcode("BN", tp->tn_op, tp->tn_type); break; case CALL: - treeout(tp->t.tr1, 1); - treeout(tp->t.tr2, 0); - outcode("BN", CALL, tp->t.type); + treeout(tp->tn_tr1, 1); + treeout(tp->tn_tr2, 0); + outcode("BN", CALL, tp->tn_type); break; default: - treeout(tp->t.tr1, nextisstruct); - if (opdope0[tp->t.op]&BINARY) - treeout(tp->t.tr2, nextisstruct); - outcode("BN", tp->t.op, tp->t.type); + treeout(tp->tn_tr1, nextisstruct); + if (opdope0[tp->tn_op]&BINARY) + treeout(tp->tn_tr2, nextisstruct); + outcode("BN", tp->tn_op, tp->tn_type); break; } if (nextisstruct && isstruct==0) - outcode("BNN", STRASG, STRUCT, tp->t.strp->S.ssize); + outcode("BNN", STRASG, STRUCT, tp->tn_strp->S.ssize); } #endif @@ -195,14 +197,14 @@ void label0(l) int l; { * is some kind of pointer; return the size of the object * to which the pointer points. */ -int plength(p) register union tree *p; { +int plength(p) register struct tree *p; { register int t, l; - if (p==0 || ((t=p->t.type)&~TYPE) == 0) /* not a reference */ + if (p==0 || ((t=p->t_type)&~TYPE) == 0) /* not a reference */ return(1); - p->t.type = decref0(t); + p->t_type = decref0(t); l = length(p); - p->t.type = t; + p->t_type = t; return(l); } @@ -210,17 +212,17 @@ int plength(p) register union tree *p; { * return the number of bytes in the object * whose tree node is acs. */ -int length(cs) union tree *cs; { +int length(cs) struct tree *cs; { register int t, elsz; long n; int nd; - t = cs->t.type; + t = cs->t_type; n = 1; nd = 0; while ((t&XTYPE) == ARRAY) { t = decref0(t); - n *= cs->t.subsp[nd++]; + n *= cs->t_subsp[nd++]; } if ((t&~TYPE)==FUNC) return(0); @@ -256,7 +258,7 @@ int length(cs) union tree *cs; { break; case STRUCT: - if ((elsz = cs->t.strp->S.ssize) == 0) + if ((elsz = cs->t_strp->S.ssize) == 0) error0("Undefined structure"); break; default: @@ -272,7 +274,7 @@ int length(cs) union tree *cs; { /* * The number of bytes in an object, rounded up to a word. */ -int rlength(cs) union tree *cs; { +int rlength(cs) struct tree *cs; { return((length(cs)+ALIGN) & ~ALIGN); } @@ -342,14 +344,14 @@ void chconbrk(l) int l; { * The goto statement. */ void dogoto() { - register union tree *np; + register struct tree *np; register char *st; st = starttree(); *cp++ = tree(/*0*/); build(STAR); chkw(np = *--cp, -1); - rcexpr0(block(JUMP, 0, (int *)NULL, (union str *)NULL, np, TNULL)); + rcexpr0((struct tree *)block(JUMP, 0, (int *)NULL, (union str *)NULL, np, TNULL)); endtree(st); } @@ -362,10 +364,10 @@ void doret() { register char *st; st = starttree(); - *cp++ = (union tree *)&funcblk; + *cp++ = (struct tree *)&funcblk; *cp++ = tree(/*0*/); build(ASSIGN); - cp[-1] = cp[-1]->t.tr2; + cp[-1] = ((struct tnode *)cp[-1])->tn_tr2; build(RFORCE); rcexpr0(*--cp); endtree(st); diff --git a/c1.h b/c1.h index c9ad894..4980780 100644 --- a/c1.h +++ b/c1.h @@ -110,25 +110,25 @@ extern long totspace; extern int regpanic; /* set when SU register alg. fails */ extern int panicposs; /* set when there might be need for regpanic */ extern jmp_buf jmpbuf; -extern long ftell(); -/*extern char *sbrk();*/ -extern struct optab *match(); -extern union tree *optim(); -extern union tree *unoptim(); -extern union tree *pow2(); -extern union tree *tnode1(); -extern union tree *sdelay(); -extern union tree *ncopy(); -extern union tree *getblk(); -extern union tree *strfunc(); -extern union tree *isconstant(); -extern union tree *tconst(); -extern union tree *hardlongs(); -extern union tree *lconst(); -extern union tree *acommute(); -extern union tree *lvfield(); -extern union tree *paint(); -extern long ftell(); +/*long ftell();*/ +/*char *sbrk();*/ +/*struct optab *match();*/ +/*struct tree *optim();*/ +/*struct tree *unoptim();*/ +/*struct tree *pow2();*/ +/*struct tree *tnode();*/ +/*struct tree *sdelay();*/ +/*struct tree *ncopy();*/ +/*struct tree *getblk();*/ +/*struct tree *strfunc();*/ +/*struct tree *isconstant();*/ +/*struct tree *tconst();*/ +/*struct tree *hardlongs();*/ +/*struct tree *lconst();*/ +/*struct tree *acommute();*/ +/*struct tree *lvfield();*/ +/*struct tree *paint();*/ +/*long ftell();*/ /* * Some special stuff for long comparisons @@ -140,8 +140,8 @@ extern int xlab1, xlab2, xop, xzero; struct acl { int nextl; int nextn; - union tree *nlist[LSTSIZ]; - union tree *llist[LSTSIZ+1]; + struct tnode *nlist[LSTSIZ]; + struct tree *llist[LSTSIZ+1]; }; #endif @@ -155,41 +155,41 @@ struct acl { /* c10.c */ int main __P((int argc, char *argv[])); -struct optab *match __P((union tree *tree, struct table *table, int nrleft, int nocvt)); -int rcexpr1 __P((union tree *atree, struct table *atable, int reg)); -int cexpr __P((register union tree *tree, struct table *table, int areg)); -int reorder __P((union tree **treep, struct table *table, int reg)); -int sreorder __P((union tree **treep, struct table *table, int reg, int recurf)); -int delay __P((union tree **treep, struct table *table, int reg)); -union tree *sdelay __P((union tree **ap)); -union tree *paint __P((register union tree *tp, register int type)); -union tree *ncopy __P((register union tree *p)); -int chkleaf __P((register union tree *tree, struct table *table, int reg)); -int comarg __P((register union tree *tree, int *flagp)); -union tree *strfunc __P((register union tree *tp)); -void doinit __P((register int type, register union tree *tree)); -void movreg __P((int r0, int r1, union tree *tree)); +struct optab *match __P((struct tree *tree, struct table *table, int nrleft, int nocvt)); +int rcexpr1 __P((struct tree *atree, struct table *atable, int reg)); +int cexpr __P((register struct tree *tree, struct table *table, int areg)); +int reorder __P((struct tree **treep, struct table *table, int reg)); +int sreorder __P((struct tree **treep, struct table *table, int reg, int recurf)); +int delay __P((struct tree **treep, struct table *table, int reg)); +struct tree *sdelay __P((struct tree **ap)); +struct tree *paint __P((register struct tree *tp, register int type)); +struct nnode *ncopy __P((register struct nnode *p)); +int chkleaf __P((register struct tree *tree, struct table *table, int reg)); +int comarg __P((register struct tree *tree, int *flagp)); +struct tree *strfunc __P((register struct tree *tp)); +void doinit __P((register int type, register struct tree *tree)); +void movreg __P((int r0, int r1, struct tree *tree)); /* c11.c */ -int degree __P((register union tree *t)); -void pname __P((register union tree *p, int flag)); -void pbase __P((register union tree *p)); -int xdcalc __P((register union tree *p, int nrleft)); -int dcalc __P((register union tree *p, int nrleft)); -int notcompat __P((register union tree *p, int ast, int deg, int op)); +int degree __P((register struct tree *t)); +void pname __P((register struct tree *p, int flag)); +void pbase __P((register struct nnode *p)); +int xdcalc __P((register struct tree *p, int nrleft)); +int dcalc __P((register struct tree *p, int nrleft)); +int notcompat __P((register struct tree *p, int ast, int deg, int op)); int prins __P((int op, int c, struct instab *itable, int lbl)); -int collcon __P((register union tree *p)); -int isfloat __P((register union tree *t)); -int oddreg __P((register union tree *t, register int reg)); +int collcon __P((register struct tree *p)); +int isfloat __P((register struct tree *t)); +int oddreg __P((register struct tree *t, register int reg)); int arlength __P((int t)); void pswitch1 __P((struct swtab *afp, struct swtab *alp, int deflab)); void breq __P((int v, int l)); int sort __P((struct swtab *afp, struct swtab *alp)); -int ispow2 __P((register union tree *tree)); -union tree *pow2 __P((register union tree *tree)); -void cbranch1 __P((union tree *atree, register int lbl, int cond, register int reg)); +int ispow2 __P((register struct tnode *tree)); +struct tnode *pow2 __P((register struct tnode *tree)); +void cbranch1 __P((struct tree *atree, register int lbl, int cond, register int reg)); void branch1 __P((int lbl, int aop, int c)); -void longrel __P((union tree *atree, int lbl, int cond, int reg)); +void longrel __P((struct tnode *atree, int lbl, int cond, int reg)); int xlongrel __P((int f)); void label1 __P((int l)); void popstk __P((int a)); @@ -198,27 +198,28 @@ void error1 __P((char *s, ...)); void psoct __P((int an)); void getree __P((void)); int geti __P((void)); -void strasg __P((union tree *atp)); +void strasg __P((struct tnode *atp)); int decref1 __P((register int t)); int incref1 __P((register int t)); /* c12.c */ -union tree *optim __P((register union tree *tree)); -union tree *unoptim __P((register union tree *tree)); -union tree *lvfield __P((register union tree *t)); -union tree *acommute __P((register union tree *tree)); -int sideeffects __P((register union tree *tp)); +struct tree *optim __P((register struct tree *tree)); +struct tree *binoptim __P((register struct tree *tree)); +struct tree *unoptim __P((register struct tree *tree)); +struct tree *lvfield __P((register struct tnode *t)); +struct tree *acommute __P((register struct tree *tree)); +int sideeffects __P((register struct tree *tp)); void distrib __P((struct acl *list)); -void squash __P((union tree **p, union tree **maxp)); +void squash __P((struct tree **p, struct tree **maxp)); void _const __P((int op, register _INT *vp, _INT v, int type)); -union tree *lconst __P((int op, register union tree *lp, register union tree *rp)); -void insert __P((int op, register union tree *tree, register struct acl *list)); -union tree *tnode1 __P((int op, int type, union tree *tr1, union tree *tr2)); -union tree *tconst __P((int val, int type)); -union tree *getblk __P((int size)); +struct lnode *lconst __P((int op, register struct tree *lp, register struct tree *rp)); +void insert __P((int op, register struct tree *tree, register struct acl *list)); +struct tnode *tnode __P((int op, int type, struct tree *tr1, struct tree *tr2)); +struct cnode *tconst __P((int val, int type)); +struct tree *getblk __P((int size)); int islong __P((int t)); -union tree *isconstant __P((register union tree *t)); -union tree *hardlongs __P((register union tree *t)); -int uns __P((union tree *tp)); +struct tree *isconstant __P((register struct tree *t)); +struct tree *hardlongs __P((register struct tree *t)); +int uns __P((struct tree *tp)); #endif diff --git a/c10.c b/c10.c index d86173f..212007a 100644 --- a/c10.c +++ b/c10.c @@ -27,10 +27,10 @@ char notrel[] = { NEQUAL, EQUAL, GREAT, GREATEQ, LESS, LESSEQ, GREATP, GREATQP, LESSP, LESSEQP }; -struct cnode czero = { CON, INT, 0/*subsp*/, 0/*strp*/, 0}; -struct cnode cone = { CON, INT, 0/*subsp*/, 0/*strp*/, 1}; +struct cnode czero = { { CON, INT, (int *)NULL, (union str *)NULL }, 0}; +struct cnode cone = { { CON, INT, (int *)NULL, (union str *)NULL }, 1}; -struct nnode sfuncr = { NAME, STRUCT, 0/*subsp*/, 0/*strp*/, 0/*tr1*/, STATIC, 0, 0, 0 }; +struct nnode sfuncr = { { NAME, STRUCT, (int *)NULL, (union str *)NULL }, (struct nmlist *)NULL, STATIC, 0, 0, 0 }; struct table *cregtab; int nreg = 3; @@ -90,62 +90,64 @@ int main(argc, argv) int argc; char *argv[]; { * required is not too large. * Return a ptr to the table entry or 0 if none found. */ -struct optab *match(tree, table, nrleft, nocvt) union tree *tree; struct table *table; int nrleft; int nocvt; { +struct optab *match(tree, table, nrleft, nocvt) struct tree *tree; struct table *table; int nrleft; int nocvt; { #define NOCVL 1 #define NOCVR 2 int op, d1, d2, dope; - union tree *p2; - register union tree *p1; + struct tree *p2; + register struct tree *p1; register struct optab *opt; if (tree==NULL) return(NULL); if (table==lsptab) table = sptab; - if ((op = tree->t.op)==0) + if ((op = tree->t_op)==0) return(0); dope = opdope1[op]; if ((dope&LEAF) == 0) - p1 = tree->t.tr1; + p1 = ((struct tnode *)tree)->tn_tr1; else p1 = tree; d1 = dcalc(p1, nrleft); if ((dope&BINARY)!=0) { - p2 = tree->t.tr2; +#define ttree ((struct tnode *)tree) + p2 = ttree->tn_tr2; /* - * If a subtree starts off with a conversion operator, + * If a subttree starts off with a conversion operator, * try for a match with the conversion eliminated. * E.g. int = double can be done without generating * the converted int in a register by * movf double,fr0; movfi fr0,int . */ - if (opdope1[p2->t.op]&CNVRT && (nocvt&NOCVR)==0 - && (opdope1[p2->t.tr1->t.op]&CNVRT)==0) { - tree->t.tr2 = p2->t.tr1; - if (opt = match(tree, table, nrleft, NOCVL)) + if (opdope1[p2->t_op]&CNVRT && (nocvt&NOCVR)==0 + && (opdope1[((struct tnode *)p2)->tn_tr1->t_op]&CNVRT)==0) { + ttree->tn_tr2 = ((struct tnode *)p2)->tn_tr1; + if (opt = match((struct tree *)ttree, table, nrleft, NOCVL)) return(opt); - tree->t.tr2 = p2; - } else if (opdope1[p1->t.op]&CNVRT && (nocvt&NOCVL)==0 - && (opdope1[p1->t.tr1->t.op]&CNVRT)==0) { - tree->t.tr1 = p1->t.tr1; - if (opt = match(tree, table, nrleft, NOCVR)) + ttree->tn_tr2 = p2; + } else if (opdope1[p1->t_op]&CNVRT && (nocvt&NOCVL)==0 + && (opdope1[((struct tnode *)p1)->tn_tr1->t_op]&CNVRT)==0) { + ttree->tn_tr1 = ((struct tnode *)p1)->tn_tr1; + if (opt = match((struct tree *)ttree, table, nrleft, NOCVR)) return(opt); - tree->t.tr1 = p1; + ttree->tn_tr1 = p1; } d2 = dcalc(p2, nrleft); +#undef ttree } for (; table->tabop!=op; table++) if (table->tabop==0) return(0); for (opt = table->tabp; opt->tabdeg1!=0; opt++) { if (d1 > (opt->tabdeg1&077) - || (opt->tabdeg1 >= 0100 && (p1->t.op != STAR))) + || (opt->tabdeg1 >= 0100 && (p1->t_op != STAR))) continue; if (notcompat(p1, opt->tabtyp1, opt->tabdeg1, op)) continue; if ((opdope1[op]&BINARY)!=0 && p2!=0) { if (d2 > (opt->tabdeg2&077) - || (opt->tabdeg2 >= 0100) && (p2->t.op != STAR) ) + || (opt->tabdeg2 >= 0100) && (p2->t_op != STAR) ) continue; if (notcompat(p2,opt->tabtyp2, opt->tabdeg2, 0)) continue; @@ -178,10 +180,10 @@ struct optab *match(tree, table, nrleft, nocvt) union tree *tree; struct table * * A number of special cases are recognized, and * there is an interaction with the optimizer routines. */ -int rcexpr1(atree, atable, reg) union tree *atree; struct table *atable; int reg; { +int rcexpr1(atree, atable, reg) struct tree *atree; struct table *atable; int reg; { register int r; int modf, nargs, recurf; - register union tree *tree; + register struct tree *tree; register struct table *table; /*fprintf(stderr, "rcexpr1(0x%08x, 0x%08x, 0x%08x)\n", atree, atable, reg);*/ @@ -198,58 +200,64 @@ int rcexpr1(atree, atable, reg) union tree *atree; struct table *atable; int reg again: if((tree=atree)==0) return(0); - if (tree->t.type==VOID) { + if (tree->t_type==VOID) { if (table!=efftab) error1("Illegal use of void"); - tree->t.type = INT; + tree->t_type = INT; } - if (opdope1[tree->t.op]&RELAT && tree->t.tr2->t.op==CON - && tree->t.tr2->c.value==0 + if (opdope1[tree->t_op]&RELAT && ((struct tnode *)tree)->tn_tr2->t_op==CON + && ((struct cnode *)((struct tnode *)tree)->tn_tr2)->cn_value==0 && table==cctab) - tree = atree = tree->t.tr1; + tree = atree = ((struct tnode *)tree)->tn_tr1; /* * fieldselect(...) : in efftab mode, * ignore the select, otherwise * do the shift and mask. */ - if (tree->t.op == FSELT) { + if (tree->t_op == FSELT) { if (table==efftab) - atree = tree = tree->t.tr1; + atree = tree = ((struct tnode *)tree)->tn_tr1; else { - tree->t.op = FSEL; + tree->t_op = FSEL; atree = tree = optim(tree); } } - switch (tree->t.op) { + switch (tree->t_op) { /* * Structure assignments */ /* case STRASG:*/ case ASSIGN: - if (tree->t.type != STRUCT) +#define ttree ((struct tnode *)tree) + if (ttree->tn_type != STRUCT) break; - strasg(tree); + strasg(ttree); return(0); +#undef ttree /* * An initializing expression */ case INIT: tree = optim(tree); - doinit(tree->t.type, tree->t.tr1); +#define ttree ((struct tnode *)tree) + doinit(ttree->tn_type, ttree->tn_tr1); return(0); +#undef ttree /* * Put the value of an expression in r0, * for a switch or a return */ case RFORCE: - if (tree->t.type == STRUCT) { - strasg(tree); +#define ttree ((struct tnode *)tree) + if (ttree->tn_type == STRUCT) { + strasg(ttree); return(0); } - tree = tree->t.tr1; +#undef ttree + tree = ((struct tnode *)tree)->tn_tr1; if((r=rcexpr1(tree, regtab, reg)) != 0) movreg(r, 0, tree); return(0); @@ -258,10 +266,12 @@ again: * sequential execution */ case SEQNC: - r = nstack; - rcexpr1(tree->t.tr1, efftab, reg); +#define ttree ((struct tnode *)tree) + r = nstack; + rcexpr1(ttree->tn_tr1, efftab, reg); nstack = r; - atree = tree = tree->t.tr2; +#undef ttree + atree = tree = ((struct tnode *)tree)->tn_tr2; goto again; /* @@ -270,11 +280,13 @@ again: * instruction will be produced when cctab is used. */ case ANDN: +#define ttree ((struct tnode *)tree) if (table==cctab) { - tree->t.op = TAND; - tree->t.tr2 = optim(tnode1(COMPL, tree->t.type, tree->t.tr2, TNULL)); + ttree->tn_op = TAND; + ttree->tn_tr2 = optim((struct tree *)tnode(COMPL, ttree->tn_type, ttree->tn_tr2, TNULL)); } break; +#undef ttree /* * Handle a subroutine call. It has to be done @@ -304,27 +316,28 @@ again: * If a strange error crops up, uncommenting the catch might * be tried ... */ - if (tree->t.tr1->t.op!=NAME || tree->t.tr1->n.class!=EXTERN) { + if (tree->tn_tr1->tn_op!=NAME || tree->tn_tr1->nn_class!=EXTERN) { nargs++; nstack++; } #endif - tree = tree->t.tr2; - if(tree->t.op) { - while (tree->t.op==COMMA) { - r += comarg(tree->t.tr2, &modf); - tree = tree->t.tr1; + tree = ((struct tnode *)tree)->tn_tr2; + if(tree->t_op) { + while (tree->t_op==COMMA) { + r += comarg(((struct tnode *)tree)->tn_tr2, &modf); + tree = ((struct tnode *)tree)->tn_tr1; nargs++; } r += comarg(tree, &modf); nargs++; } tree = atree; - tree->t.op = CALL2; - if (modf && tree->t.tr1->t.op==NAME - && tree->t.tr1->n.class==EXTERN) - tree->t.op = CALL1; - if (cexpr(tree, regtab, reg)<0) +#define ttree ((struct tnode *)tree) + ttree->tn_op = CALL2; + if (modf && ttree->tn_tr1->t_op==NAME + && ((struct nnode *)ttree->tn_tr1)->nn_class==EXTERN) + ttree->tn_op = CALL1; + if (cexpr((struct tree *)ttree, regtab, reg)<0) error1("compiler botch: call"); popstk(r); nstack -= nargs; @@ -332,54 +345,61 @@ again: return(0); r = 0; goto fixup; +#undef ttree /* * Longs need special treatment. */ case ASULSH: /* 18 */ case ULSH: /* 17 */ - if (tree->t.type != LONG && tree->t.type != UNLONG) +#define ttree ((struct tnode *)tree) + if (ttree->tn_type != LONG && ttree->tn_type != UNLONG) break; - if (tree->t.tr2->t.op==ITOL) - tree->t.tr2 = tree->t.tr2->t.tr1; + if (ttree->tn_tr2->t_op==ITOL) + ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1; else - tree->t.tr2 = optim(tnode1(LTOI,INT,tree->t.tr2,TNULL)); - if (tree->t.op==ASULSH) + ttree->tn_tr2 = optim((struct tree *)tnode(LTOI,INT,ttree->tn_tr2,TNULL)); + if (ttree->tn_op==ASULSH) { - tree->t.op = UASLSHL; - tree->t.tr1 = tnode1(AMPER, LONG+PTR, tree->t.tr1, TNULL); + ttree->tn_op = UASLSHL; + ttree->tn_tr1 = (struct tree *)tnode(AMPER, LONG+PTR, ttree->tn_tr1, TNULL); } else - tree->t.op = ULLSHIFT; + ttree->tn_op = ULLSHIFT; break; +#undef ttree case ASLSH: case LSHIFT: - if (tree->t.type==LONG || tree->t.type==UNLONG) { - if (tree->t.tr2->t.op==ITOL) - tree->t.tr2 = tree->t.tr2->t.tr1; +#define ttree ((struct tnode *)tree) + if (ttree->tn_type==LONG || ttree->tn_type==UNLONG) { + if (ttree->tn_tr2->t_op==ITOL) + ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1; else - tree->t.tr2 = optim(tnode1(LTOI,INT,tree->t.tr2,TNULL)); - if (tree->t.op==ASLSH) - tree->t.op = ASLSHL; + ttree->tn_tr2 = optim((struct tree *)tnode(LTOI,INT,ttree->tn_tr2,TNULL)); + if (ttree->tn_op==ASLSH) + ttree->tn_op = ASLSHL; else - tree->t.op = LLSHIFT; + ttree->tn_op = LLSHIFT; } break; +#undef ttree /* * Try to change * to shift. */ case TIMES: case ASTIMES: - tree = pow2(tree); + tree = (struct tree *)pow2((struct tnode *)tree); } /* * Try to find postfix ++ and -- operators that can be * pulled out and done after the rest of the expression */ + /* delay() has to be able to assume input pointer is a tnode */ + if (tree != atree) abort(); if (table!=cctab && table!=cregtab && recurf<2 - && (opdope1[tree->t.op]&LEAF)==0) { + && (opdope1[tree->t_op]&LEAF)==0) { if (r=delay(&atree, table, reg)) { tree = atree; table = efftab; @@ -391,25 +411,25 @@ again: * so reg = x+y is done as reg = x; reg += y */ if (recurf==0 && reorder(&atree, table, reg)) { - if (table==cctab && atree->t.op==NAME) + if (table==cctab && atree->t_op==NAME) return(reg); } tree = atree; - if (table==efftab && tree->t.op==NAME) + if (table==efftab && tree->t_op==NAME) return(reg); if ((r=cexpr(tree, table, reg))>=0) { - if (table==cregtab && (tree->t.op==INCAFT - || tree->t.op==DECAFT || tree->t.op==TIMES)) + if (table==cregtab && (tree->t_op==INCAFT + || tree->t_op==DECAFT || tree->t_op==TIMES)) goto fixup; return(r); } - if (table!=regtab && (table!=cctab||(opdope1[tree->t.op]&RELAT)==0)) { + if (table!=regtab && (table!=cctab||(opdope1[tree->t_op]&RELAT)==0)) { if((r=cexpr(tree, regtab, reg))>=0) { fixup: modf = isfloat(tree); - dbprint(tree->t.op); + dbprint(tree->t_op); if (table==sptab || table==lsptab) { - if (tree->t.type==LONG || tree->t.type==UNLONG){ + if (tree->t_type==LONG || tree->t_type==UNLONG){ fprintf(temp_fp[temp_fi], /*printf(*/"mov\tr%d,-(sp)\n",r+1); nstack++; } @@ -425,27 +445,31 @@ again: /* * Special grace for unsigned chars as right operands */ - if (opdope1[tree->t.op]&BINARY && tree->t.tr2->t.type==UNCHAR) { - tree->t.tr2 = tnode1(LOAD, UNSIGN, tree->t.tr2, TNULL); - return(rcexpr1(tree, table, reg)); + if (opdope1[tree->t_op]&BINARY && ((struct tnode *)tree)->tn_tr2->t_type==UNCHAR) { +#define ttree ((struct tnode *)tree) + ttree->tn_tr2 = (struct tree *)tnode(LOAD, UNSIGN, ttree->tn_tr2, TNULL); + return(rcexpr1((struct tree *)ttree, table, reg)); +#undef ttree } /* * There's a last chance for this operator */ - if (tree->t.op==LTOI) { - r = rcexpr1(tree->t.tr1, regtab, reg); + if (tree->t_op==LTOI) { +#define ttree ((struct tnode *)tree) + r = rcexpr1(ttree->tn_tr1, regtab, reg); if (r >= 0) { r++; goto fixup; } +#undef ttree } - r = tree->t.op; - if (tree->t.type == STRUCT) + r = tree->t_op; + if (tree->t_type == STRUCT) error1("Illegal operation on structure"); else if (r > 0 && r < UASLSHL && opntab[r]) error1("No code table for op: %s(%d) type: %d", opntab[r], r, - tree->t.type); + tree->t_type); else error1("No code table for op %d", r); return(reg); @@ -460,18 +484,17 @@ again: * Most of the work is the macro-expansion of the * code table. */ -int cexpr(tree, table, areg) register union tree *tree; struct table *table; int areg; { +int cexpr(tree, table, areg) register struct tree *tree; struct table *table; int areg; { int c, r; - register union tree *p, *p1; + register struct tree *p, *p1; struct table *ctable; - union tree *p2; + struct tree *p2; char *string; int reg, reg1, rreg, flag, opd; struct optab *opt; reg = areg; - p1 = tree->t.tr2; - c = tree->t.op; + c = tree->t_op; opd = opdope1[c]; /* * When the value of a relational or a logical expression is @@ -479,58 +502,64 @@ int cexpr(tree, table, areg) register union tree *tree; struct table *table; int */ if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) { cbranch1(tree, c=isn1++, 1, reg); - rcexpr1((union tree *)&czero, table, reg); + rcexpr1((struct tree *)&czero, table, reg); branch1(isn1, 0, 0); label1(c); - rcexpr1((union tree *)&cone, table, reg); + rcexpr1((struct tree *)&cone, table, reg); label1(isn1++); return(reg); } if(c==QUEST) { +#define ttree ((struct tnode *)tree) if (table==cctab) return(-1); - cbranch1(tree->t.tr1, c=isn1++, 0, reg); + cbranch1(ttree->tn_tr1, c=isn1++, 0, reg); flag = nstack; - rreg = rcexpr1(p1->t.tr1, table, reg); + rreg = rcexpr1(((struct tnode *)ttree->tn_tr2)->tn_tr1, table, reg); nstack = flag; branch1(r=isn1++, 0, 0); label1(c); - reg = rcexpr1(p1->t.tr2, table, rreg); + reg = rcexpr1(((struct tnode *)ttree->tn_tr2)->tn_tr2, table, rreg); if (rreg!=reg) - movreg(reg, rreg, tree->t.tr2); + movreg(reg, rreg, ttree->tn_tr2); label1(r); return(rreg); +#undef ttree } reg = oddreg(tree, reg); reg1 = reg+1; /* * long values take 2 registers. */ - if ((tree->t.type==LONG||tree->t.type==UNLONG||opd&RELAT&&(tree->t.tr1->t.type==LONG||tree->t.tr1->t.type==UNLONG)) - && tree->t.op!=ITOL) + if ((tree->t_type==LONG||tree->t_type==UNLONG||opd&RELAT&&(((struct tnode *)tree)->tn_tr1->t_type==LONG||((struct tnode *)tree)->tn_tr1->t_type==UNLONG)) + && tree->t_op!=ITOL) reg1++; /* * Leaves of the expression tree */ if ((r = chkleaf(tree, table, reg)) >= 0) return(r); + /* if chkleaf returns -1 then tree is a struct tnode */ +#define ttree ((struct tnode *)tree) /* * x + (-1) is better done as x-1. */ - if (tree->t.op==PLUS||tree->t.op==ASPLUS) { - if ((p1=tree->t.tr2)->t.op==CON && p1->c.value==-1) { - p1->c.value = -p1->c.value; - tree->t.op += (MINUS-PLUS); + if (ttree->tn_op==PLUS||ttree->tn_op==ASPLUS) { + if ((p1=ttree->tn_tr2)->t_op==CON && ((struct cnode *)p1)->cn_value==-1) { +#define cp1 ((struct cnode *)p1) + cp1->cn_value = -cp1->cn_value; + ttree->tn_op += (MINUS-PLUS); +#undef cp1 } } /* * Because of a peculiarity of the PDP11 table * char = *intreg++ and *--intreg cannot go through. */ - if (tree->t.tr2 && (tree->t.tr2->t.op==AUTOI||tree->t.tr2->t.op==AUTOD) - && (tree->t.tr1->t.type==CHAR || tree->t.tr1->t.type==UNCHAR) - && tree->t.tr2->t.type!=CHAR && tree->t.tr2->t.type!=UNCHAR) - tree->t.tr2 = tnode1(LOAD, tree->t.tr2->t.type, tree->t.tr2, TNULL); + if (ttree->tn_tr2 && (ttree->tn_tr2->t_op==AUTOI||ttree->tn_tr2->t_op==AUTOD) + && (ttree->tn_tr1->t_type==CHAR || ttree->tn_tr1->t_type==UNCHAR) + && ttree->tn_tr2->t_type!=CHAR && ttree->tn_tr2->t_type!=UNCHAR) + ttree->tn_tr2 = (struct tree *)tnode(LOAD, ttree->tn_tr2->t_type, ttree->tn_tr2, TNULL); /* * Another peculiarity of the PDP11 table manifested itself when * amplifying the move3: table. The same case which optimizes @@ -545,10 +574,10 @@ int cexpr(tree, table, areg) register union tree *tree; struct table *table; int * u_char handling in the compiler is a bit awkward, it would be nice * if %aub in the tables had a more unique meaning. */ - if (tree->t.tr2 && tree->t.tr1->t.op == NAME - && tree->t.tr1->n.class == REG && tree->t.op == ASSIGN - && tree->t.tr2->t.type == UNCHAR) - tree->t.tr2 = tnode1(LOAD, UNSIGN, tree->t.tr2, TNULL); + if (ttree->tn_tr2 && ttree->tn_tr1->t_op == NAME + && ((struct nnode *)ttree->tn_tr1)->nn_class == REG && ttree->tn_op == ASSIGN + && ttree->tn_tr2->t_type == UNCHAR) + ttree->tn_tr2 = (struct tree *)tnode(LOAD, UNSIGN, ttree->tn_tr2, TNULL); if (table==cregtab) table = regtab; /* @@ -558,7 +587,7 @@ int cexpr(tree, table, areg) register union tree *tree; struct table *table; int * a shift or * postfix ++ or --. Unravelled, if the table is * cctab and the operator is not special, try first - * for efftab; if the table isn1't, if the operator is, + * for efftab; if the table isn't, if the operator is, * or the first match fails, try to match * with the table actually asked for. */ @@ -567,50 +596,54 @@ int cexpr(tree, table, areg) register union tree *tree; struct table *table; int * r = nreg - reg - (reg-areg) - (reg1-reg-1); */ r = nreg - reg + areg - reg1 + 1; - if (table!=cctab || c==INCAFT || c==DECAFT || tree->t.type==LONG || tree->t.type==UNLONG -/* || c==ASRSH || c==ASLSH || c==ASULSH || tree->t.tr1->t.type==UNCHAR */ + if (table!=cctab || c==INCAFT || c==DECAFT || ttree->tn_type==LONG || ttree->tn_type==UNLONG +/* || c==ASRSH || c==ASLSH || c==ASULSH || ttree->tn_tr1->tn_type==UNCHAR */ || c==ASRSH || c==ASLSH || c==ASULSH - || (opt = match(tree, efftab, r, 0)) == 0) - if ((opt=match(tree, table, r, 0))==0) + || (opt = match((struct tree *)ttree, efftab, r, 0)) == 0) + if ((opt=match((struct tree *)ttree, table, r, 0))==0) return(-1); string = opt->tabstring; - p1 = tree->t.tr1; - if (p1->t.op==FCON && p1->f.value>0) { -#ifdef pdp11 + p1 = ttree->tn_tr1; + if (p1->t_op==FCON && ((struct fnode *)p1)->fn_value>0) { +#define fp1 ((struct fnode *)p1) +#ifdef pdfp11 /* nonportable */ - fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value, - ((_UNSIGNED_INT *)&(p1->f.fvalue))[0], - ((_UNSIGNED_INT *)&(p1->f.fvalue))[1], - ((_UNSIGNED_INT *)&(p1->f.fvalue))[2], - ((_UNSIGNED_INT *)&(p1->f.fvalue))[3] ); + fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", fp1->fn_value, + ((_UNSIGNED_INT *)&(fp1->fn_fvalue))[0], + ((_UNSIGNED_INT *)&(fp1->fn_fvalue))[1], + ((_UNSIGNED_INT *)&(fp1->fn_fvalue))[2], + ((_UNSIGNED_INT *)&(fp1->fn_fvalue))[3] ); #else - fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value, - (int)(p1->f.fvalue.h >> 16) & 0xffff, - (int)p1->f.fvalue.h & 0xffff, - (int)(p1->f.fvalue.l >> 16) & 0xffff, - (int)p1->f.fvalue.l & 0xffff ); + fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", fp1->fn_value, + (int)(fp1->fn_fvalue.h >> 16) & 0xffff, + (int)fp1->fn_fvalue.h & 0xffff, + (int)(fp1->fn_fvalue.l >> 16) & 0xffff, + (int)fp1->fn_fvalue.l & 0xffff ); #endif - p1->f/*c*/.value = -p1->f/*c*/.value; + fp1->fn_value = -fp1->fn_value; /* says flushed out */ +#undef fp1 } p2 = 0; - if (opdope1[tree->t.op]&BINARY) { - p2 = tree->t.tr2; - if (p2->t.op==FCON && p2->f.value>0) { + if (opdope1[ttree->tn_op]&BINARY) { + p2 = ttree->tn_tr2; + if (p2->t_op==FCON && ((struct fnode *)p2)->fn_value>0) { +#define fp2 ((struct fnode *)p2) #ifdef pdp11 /* nonportable */ - fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value, - ((_UNSIGNED_INT *)&(p2->f.fvalue))[0], - ((_UNSIGNED_INT *)&(p2->f.fvalue))[1], - ((_UNSIGNED_INT *)&(p2->f.fvalue))[2], - ((_UNSIGNED_INT *)&(p2->f.fvalue))[3] ); + fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", fp2->fn_value, + ((_UNSIGNED_INT *)&(fp2->fn_fvalue))[0], + ((_UNSIGNED_INT *)&(fp2->fn_fvalue))[1], + ((_UNSIGNED_INT *)&(fp2->fn_fvalue))[2], + ((_UNSIGNED_INT *)&(fp2->fn_fvalue))[3] ); #else - fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value, - (int)(p2->f.fvalue.h >> 16) & 0xffff, - (int)p2->f.fvalue.h & 0xffff, - (int)(p2->f.fvalue.l >> 16) & 0xffff, - (int)p2->f.fvalue.l & 0xffff ); + fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", fp2->fn_value, + (int)(fp2->fn_fvalue.h >> 16) & 0xffff, + (int)fp2->fn_fvalue.h & 0xffff, + (int)(fp2->fn_fvalue.l >> 16) & 0xffff, + (int)fp2->fn_fvalue.l & 0xffff ); #endif - p2->f.value = -p2->f.value; + fp2->fn_value = -fp2->fn_value; /* says flushed out */ +#undef fp2 } } loop: @@ -624,15 +657,15 @@ loop: switch (c) { case '\n': - dbprint(tree->t.op); + dbprint(ttree->tn_op); break; case '\0': - if (!isfloat(tree)) - if (tree->t.op==DIVIDE||tree->t.op==ASDIV) + if (!isfloat((struct tree *)ttree)) + if (ttree->tn_op==DIVIDE||ttree->tn_op==ASDIV) reg--; - if (table==regtab && (opdope1[tree->t.op]&ASSGOP)) { - if (tree->t.tr1->t.type==CHAR) + if (table==regtab && (opdope1[ttree->tn_op]&ASSGOP)) { + if (ttree->tn_tr1->t_type==CHAR) fprintf(temp_fp[temp_fi], /*printf(*/"movb r%d,r%d\n", reg, reg); } return(reg); @@ -666,27 +699,27 @@ loop: string++; else c = 0; - prins(tree->t.op, c, instab, 0); + prins(ttree->tn_op, c, instab, 0); goto loop; /* B1 */ case 'C': if ((opd&LEAF) != 0) - p = tree; + p = (struct tree *)ttree; else p = p1; goto pbyte; /* BF */ case 'P': - p = tree; + p = (struct tree *)ttree; goto pb1; /* B2 */ case 'D': p = p2; pbyte: - if (p->t.type==CHAR || p->t.type==UNCHAR) + if (p->t_type==CHAR || p->t_type==UNCHAR) fputc('b', temp_fp[temp_fi]) /*putchar('b')*/; pb1: if (isfloat(p)) @@ -695,10 +728,10 @@ loop: /* BE */ case 'L': - if (p1->t.type==CHAR || p2->t.type==CHAR - || p1->t.type==UNCHAR || p2->t.type==UNCHAR) + if (p1->t_type==CHAR || p2->t_type==CHAR + || p1->t_type==UNCHAR || p2->t_type==UNCHAR) fputc('b', temp_fp[temp_fi]) /*putchar('b')*/; - p = tree; + p = (struct tree *)ttree; goto pb1; /* F */ @@ -715,7 +748,7 @@ loop: /* H */ case 'H': - p = tree; + p = (struct tree *)ttree; flag = 04; subtre: @@ -736,15 +769,17 @@ loop: if ((c&04)!=0) ctable = cctab; if ((flag&01) && ctable==regtab && (c&01)==0 - && ((c&040)||tree->t.op==DIVIDE||tree->t.op==MOD - || tree->t.op==ASDIV||tree->t.op==ASMOD||tree->t.op==ITOL)) + && ((c&040)||ttree->tn_op==DIVIDE||ttree->tn_op==MOD + || ttree->tn_op==ASDIV||ttree->tn_op==ASMOD||ttree->tn_op==ITOL)) ctable = cregtab; if ((c&01)!=0) { - p = p->t.tr1; + /* previous code was accessing tn_tr1 without a type check */ + if (opdope1[p->t_op] & LEAF) abort(); + p = ((struct tnode *)p)->tn_tr1; if(collcon(p) && ctable!=sptab) { - if (p->t.op==STAR) - p = p->t.tr1; - p = p->t.tr1; + if (p->t_op==STAR) + p = ((struct tnode *)p)->tn_tr1; + p = ((struct tnode *)p)->tn_tr1; } } if (table==lsptab && ctable==sptab) @@ -752,7 +787,7 @@ loop: if (c&010) r = reg1; else - if (opdope1[p->t.op]&LEAF || p->t.degree < 2) + if (opdope1[p->t_op]&LEAF || ((struct tnode *)p)->tn_degree < 2) r = reg; else r = areg; @@ -765,8 +800,8 @@ loop: else reg1 = rreg; } else if (rreg!=reg) - if ((c&020)==0 && oddreg(tree, 0)==0 && tree->t.type!=LONG - && tree->t.type!=UNLONG + if ((c&020)==0 && oddreg((struct tree *)ttree, 0)==0 && ttree->tn_type!=LONG + && ttree->tn_type!=UNLONG && (flag&04 || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077) || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) { @@ -793,7 +828,7 @@ loop: string++; r++; } - if (r>nreg || r>=4 && tree->t.type==DOUBLE) { + if (r>nreg || r>=4 && ttree->tn_type==DOUBLE) { if (regpanic) error1("Register overflow: simplify expression"); else @@ -819,24 +854,30 @@ loop: /* #1 */ case '#': - p = p1->t.tr1; + /* previous code was accessing tn_tr1 without a type check */ + if (opdope1[p1->t_op] & LEAF) abort(); + p = ((struct tnode *)p1)->tn_tr1; goto nmbr; /* #2 */ case '"': - p = p2->t.tr1; + /* previous code was accessing tn_tr1 without a type check */ + if (opdope1[p2->t_op] & LEAF) abort(); + p = ((struct tnode *)p2)->tn_tr1; nmbr: if(collcon(p)) { - if (p->t.op==STAR) { + if (p->t_op==STAR) { fprintf(temp_fp[temp_fi], /*printf(*/"*"); - p = p->t.tr1; + p = ((struct tnode *)p)->tn_tr1; } - if ((p = p->t.tr2)->t.op == CON) { - if (p->c.value) - psoct(p->c.value); - } else if (p->t.op==AMPER) - pname(p->t.tr1, 0); + if ((p = ((struct tnode *)p)->tn_tr2)->t_op == CON) { +#define cp ((struct cnode *)p) + if (cp->cn_value) + psoct(cp->cn_value); +#undef cp + } else if (p->t_op==AMPER) + pname(((struct tnode *)p)->tn_tr1, 0); } goto loop; @@ -855,7 +896,7 @@ loop: goto loop; case 'V': /* adc sbc, clr, or sxt as required for longs */ - switch(tree->t.op) { + switch(ttree->tn_op) { case PLUS: case ASPLUS: case INCBEF: @@ -872,22 +913,23 @@ loop: break; case ASSIGN: - p = tree->t.tr2; + p = ttree->tn_tr2; goto lcasev; case ASDIV: case ASMOD: case ASULSH: - p = tree->t.tr1; + p = ttree->tn_tr1; lcasev: - if (p->t.type!=LONG && p->t.type!=UNLONG) { - if (uns(p) || uns(tree->t.tr2)) + if (p->t_type!=LONG && p->t_type!=UNLONG) { + if (uns(p) || uns(ttree->tn_tr2)) fprintf(temp_fp[temp_fi], /*printf(*/"clr"); else fprintf(temp_fp[temp_fi], /*printf(*/"sxt"); goto loop; } default: + /* no conversion needed, skip to end of line */ while ((c = *string++)!='\n' && c!='\0'); break; } @@ -897,7 +939,9 @@ loop: * Mask used in field assignments */ case 'Z': - fprintf(temp_fp[temp_fi], /*printf(*/"$%o", UNS(tree->F.mask)); + /* previous code was accessing fa_mask without a type check */ + if (ttree->tn_op != FSELA) abort(); + fprintf(temp_fp[temp_fi], /*printf(*/"$%o", UNS(((struct fasgn *)ttree)->fa_mask)); goto loop; /* @@ -912,6 +956,7 @@ loop: } fputc(c, temp_fp[temp_fi]) /*putchar(c)*/; goto loop; +#undef ttree } /* @@ -919,18 +964,19 @@ loop: * on the subtrees and then on the tree itself. * It returns non-zero if anything changed. */ -int reorder(treep, table, reg) union tree **treep; struct table *table; int reg; { +int reorder(treep, table, reg) struct tree **treep; struct table *table; int reg; { register int r, o; - register union tree *p; + register struct tree *p; p = *treep; - o = p->t.op; + o = p->t_op; if (opdope1[o]&LEAF||o==LOGOR||o==LOGAND||o==SEQNC||o==QUEST||o==COLON) return(0); - while(sreorder(&p->t.tr1, regtab, reg, 1)) +#define tp ((struct tnode *)p) + while(sreorder(&tp->tn_tr1, regtab, reg, 1)) ; if (opdope1[o]&BINARY) - while(sreorder(&p->t.tr2, regtab, reg, 1)) + while(sreorder(&tp->tn_tr2, regtab, reg, 1)) ; r = 0; if (table!=cctab) @@ -938,6 +984,7 @@ int reorder(treep, table, reg) union tree **treep; struct table *table; int reg; r++; *treep = optim(*treep); return(r); +#undef tp } /* @@ -950,87 +997,97 @@ int reorder(treep, table, reg) union tree **treep; struct table *table; int reg; * Moreover, expressions like "reg = x+y" are best done as * "reg = x; reg += y" (so long as "reg" and "y" are not the same!). */ -int sreorder(treep, table, reg, recurf) union tree **treep; struct table *table; int reg; int recurf; { - register union tree *p, *p1; +int sreorder(treep, table, reg, recurf) struct tree **treep; struct table *table; int reg; int recurf; { + register struct tree *p, *p1; p = *treep; - if (opdope1[p->t.op]&LEAF) + if (opdope1[p->t_op]&LEAF) return(0); - if (p->t.op==PLUS && recurf) - if (reorder(&p->t.tr2, table, reg)) - *treep = p = optim(p); - if ((p1 = p->t.tr1)==TNULL) +#define tp ((struct tnode *)p) + if (tp->tn_op==PLUS && recurf) + if (reorder(&tp->tn_tr2, table, reg)) + /* in this case optim() is guaranteed to return a struct tnode */ + { + *treep = p = optim((struct tree *)tp); + if (opdope1[p->t_op] & LEAF) abort(); + } + if ((p1 = tp->tn_tr1)==TNULL) return(0); - if (p->t.op==STAR || p->t.op==PLUS) { - if (recurf && reorder(&p->t.tr1, table, reg)) { - *treep = p = optim(p); - if (opdope1[p->t.op]&LEAF) + if (tp->tn_op==STAR || tp->tn_op==PLUS) { + if (recurf && reorder(&tp->tn_tr1, table, reg)) { + /* in this case optim() might not return a struct tnode */ + *treep = p = optim((struct tree *)tp); + if (opdope1[p->t_op]&LEAF) return(0); + /* but it's a struct tnode, so continue accessing via tp */ } - p1 = p->t.tr1; + p1 = tp->tn_tr1; } - if (p1->t.op==NAME) switch(p->t.op) { - case ASLSH: - case ASRSH: - case ASSIGN: - if (p1->n.class != REG || p1->n.type==CHAR - || isfloat(p->t.tr2)) + if (p1->t_op==NAME) switch(tp->tn_op) { + case ASLSH: + case ASRSH: + case ASSIGN: + if (((struct nnode *)p1)->nn_class != REG || ((struct nnode *)p1)->nn_type==CHAR + || isfloat(tp->tn_tr2)) + return(0); + if (tp->tn_op==ASSIGN) switch (tp->tn_tr2->t_op) { + case RSHIFT: + if (tp->tn_type==UNSIGN) return(0); - if (p->t.op==ASSIGN) switch (p->t.tr2->t.op) { - case RSHIFT: - if (p->t.type==UNSIGN) - return(0); - goto caseGEN; - case TIMES: - if (!ispow2(p->t.tr2)) - break; - p->t.tr2 = pow2(p->t.tr2); - case PLUS: - case MINUS: - case AND: - case ANDN: - case OR: - case EXOR: - case LSHIFT: - caseGEN: - p1 = p->t.tr2->t.tr2; - if (xdcalc(p1, 16) > 12 - || p1->t.op==NAME - &&(p1->n.nloc==p->t.tr1->n.nloc - || p1->n.regno==p->t.tr1->n.nloc)) - return(0); - p1 = p->t.tr2; - p->t.tr2 = p1->t.tr1; - if (p1->t.tr1->t.op!=NAME - || p1->t.tr1->n.class!=REG - || p1->t.tr1->n.nloc!=p->t.tr1->n.nloc) - rcexpr1(p, efftab, reg); - p->t.tr2 = p1->t.tr2; - p->t.op = p1->t.op + ASPLUS - PLUS; - *treep = p; - return(1); - } - goto OK; - - case ASTIMES: - if (!ispow2(p)) + goto caseGEN; + case TIMES: + if (!ispow2((struct tnode *)tp->tn_tr2)) + break; + tp->tn_tr2 = (struct tree *)pow2((struct tnode *)tp->tn_tr2); + case PLUS: + case MINUS: + case AND: + case ANDN: + case OR: + case EXOR: + case LSHIFT: + caseGEN: + p1 = ((struct tnode *)tp->tn_tr2)->tn_tr2; + if (xdcalc(p1, 16) > 12 + || p1->t_op==NAME + &&(((struct nnode *)p1)->nn_nloc==((struct nnode *)tp->tn_tr1)->nn_nloc + || ((struct nnode *)p1)->nn_regno==((struct nnode *)tp->tn_tr1)->nn_nloc)) return(0); - case ASPLUS: - case ASMINUS: - case ASAND: - case ASANDN: - case ASOR: - case ASXOR: - case INCBEF: - case DECBEF: - OK: - if (table==cctab||table==cregtab) - reg += 020; - rcexpr1(optim(p), efftab, ~reg); - *treep = p1; + p1 = tp->tn_tr2; +#define tp1 ((struct tnode *)p1) + tp->tn_tr2 = tp1->tn_tr1; + if (tp1->tn_tr1->t_op!=NAME + || ((struct nnode *)tp1->tn_tr1)->nn_class!=REG + || ((struct nnode *)tp1->tn_tr1)->nn_nloc!=((struct nnode *)tp->tn_tr1)->nn_nloc) + rcexpr1((struct tree *)tp, efftab, reg); + tp->tn_tr2 = tp1->tn_tr2; + tp->tn_op = tp1->tn_op + ASPLUS - PLUS; + *treep = (struct tree *)tp; return(1); +#undef tp1 + } + goto OK; + + case ASTIMES: + if (!ispow2(tp)) + return(0); + case ASPLUS: + case ASMINUS: + case ASAND: + case ASANDN: + case ASOR: + case ASXOR: + case INCBEF: + case DECBEF: + OK: + if (table==cctab||table==cregtab) + reg += 020; + rcexpr1(optim((struct tree *)tp), efftab, ~reg); + *treep = p1; + return(1); } return(0); +#undef tp } /* @@ -1044,84 +1101,98 @@ int sreorder(treep, table, reg, recurf) union tree **treep; struct table *table; * Otherwise it uses sdelay to search for inc/dec * among the operands. */ -int delay(treep, table, reg) union tree **treep; struct table *table; int reg; { - register union tree *p, *p1; +int delay(treep, table, reg) struct tree **treep; struct table *table; int reg; { + register struct tnode *p; + register struct tree *p1; register int r; - p = *treep; - if ((p->t.op==INCAFT||p->t.op==DECAFT) - && p->t.tr1->t.op==NAME) { - r = p->t.tr1->n.class; + p = (struct tnode *)*treep; + if ((p->tn_op==INCAFT||p->tn_op==DECAFT) + && p->tn_tr1->t_op==NAME) { + r = ((struct nnode *)p->tn_tr1)->nn_class; if (r == EXTERN || r == OFFS || r == STATIC && - p->t.tr1->t.type == UNCHAR) - return(1+rcexpr1(p->t.tr1, table, reg)); + p->tn_tr1->t_type == UNCHAR) + return(1+rcexpr1(p->tn_tr1, table, reg)); else - return(1+rcexpr1(paint(p->t.tr1, p->t.type), table,reg)); + return(1+rcexpr1(paint(p->tn_tr1, p->tn_type), table,reg)); } p1 = 0; /* * typo fix, original code. - * if (opdope1[p->t.op]&BINARY) { - * if (p->t.op==LOGAND || p->t.op==LOGOR - * || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC) + * if (opdope1[p->tn_op]&BINARY) { + * if (p->tn_op==LOGAND || p->tn_op==LOGOR + * || p->tn_op==QUEST || p->tn_op==COLON || p->tn_op==SEQNC) * return(0); * } - * p1 = sdelay(&p->t.tr2); + * p1 = sdelay(&p->tn_tr2); * if (p1==0) - * p1 = sdelay(&p->t.tr1); + * p1 = sdelay(&p->tn_tr1); */ - if (opdope1[p->t.op]&BINARY) { - if (p->t.op==LOGAND || p->t.op==LOGOR - || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC) + if (opdope1[p->tn_op]&BINARY) { + if (p->tn_op==LOGAND || p->tn_op==LOGOR + || p->tn_op==QUEST || p->tn_op==COLON || p->tn_op==SEQNC) return(0); - p1 = sdelay(&p->t.tr2); + p1 = sdelay(&p->tn_tr2); } if (p1==0) - p1 = sdelay(&p->t.tr1); + p1 = sdelay(&p->tn_tr1); if (p1) { - r = rcexpr1(optim(p), table, reg); + r = rcexpr1(optim((struct tree *)p), table, reg); *treep = p1; return(r+1); } return(0); } -union tree *sdelay(ap) union tree **ap; { - register union tree *p, *p1; +struct tree *sdelay(ap) struct tree **ap; { + register struct tree *p, *p1; if ((p = *ap)==TNULL) return(TNULL); - if ((p->t.op==INCAFT||p->t.op==DECAFT) && p->t.tr1->t.op==NAME) { - *ap = paint(ncopy(p->t.tr1), p->t.type); - return(p); + if ((p->t_op==INCAFT||p->t_op==DECAFT) && ((struct tnode *)p)->tn_tr1->t_op==NAME) { +#define tp ((struct tnode *)p) + *ap = paint((struct tree *)ncopy((struct nnode *)tp->tn_tr1), tp->tn_type); + return((struct tree *)tp); +#undef tp } - if (p->t.op==STAR || p->t.op==PLUS) - if (p1=sdelay(&p->t.tr1)) + if (p->t_op==STAR || p->t_op==PLUS) + if (p1=sdelay(&((struct tnode *)p)->tn_tr1)) return(p1); - if (p->t.op==PLUS) - return(sdelay(&p->t.tr2)); + if (p->t_op==PLUS) + return(sdelay(&((struct tnode *)p)->tn_tr2)); return(0); } /* * Propagate possible implicit type-changing operation */ -union tree *paint(tp, type) register union tree *tp; register int type; { +struct tree *paint(tp, type) register struct tree *tp; register int type; { - if (tp->t.type==type) + if (tp->t_type==type) return(tp); - if (tp->t.type==CHAR && type==INT) + if (tp->t_type==CHAR && type==INT) return(tp); - if (tp->t.type==CHAR || tp->t.type==UNCHAR) - return(optim(tnode1(LOAD, type, tp, TNULL))); - tp->t.type = type; - if (tp->t.op==AMPER && type&XTYPE) - tp->t.tr1 = paint(tp->t.tr1, decref1(type)); - else if (tp->t.op==STAR) - tp->t.tr1 = paint(tp->t.tr1, incref1(type)); - else if (tp->t.op==ASSIGN) { - paint(tp->t.tr1, type); - paint(tp->t.tr2, type); + if (tp->t_type==CHAR || tp->t_type==UNCHAR) + return(optim((struct tree *)tnode(LOAD, type, tp, TNULL))); + tp->t_type = type; + if (tp->t_op==AMPER && type&XTYPE) +#define ttp ((struct tnode *)tp) + ttp->tn_tr1 = paint(ttp->tn_tr1, decref1(type)); +#undef ttp + else if (tp->t_op==STAR) +#define ttp ((struct tnode *)tp) + ttp->tn_tr1 = paint(ttp->tn_tr1, incref1(type)); +#undef ttp + else if (tp->t_op==ASSIGN) { +#define ttp ((struct tnode *)tp) + /* previous code was not saving back return value from paint() ??? */ + struct tree *temp = + paint(ttp->tn_tr1, type); + if (temp != ttp->tn_tr1) abort(); + temp = + paint(ttp->tn_tr2, type); + if (temp != ttp->tn_tr2) abort(); +#undef ttp } return(tp); } @@ -1133,19 +1204,26 @@ union tree *paint(tp, type) register union tree *tp; register int type; { * be changed to some offset class, accidentally * modifying the reg--. */ -union tree *ncopy(p) register union tree *p; { - register union tree *q; - - q = getblk(sizeof(struct xnode)); - q->n.op = p->n.op; - q->n.type = p->n.type; - q->n.class = p->n.class; - q->n.regno = p->n.regno; - q->n.offset = p->n.offset; - if (q->n.class==EXTERN || q->n.class==XOFFS) - q->x.name = p->x.name; - else - q->n.nloc = p->n.nloc; +struct nnode *ncopy(p) register struct nnode *p; { + struct nnode *q; + + if (p->nn_class==EXTERN || p->nn_class==XOFFS) { +#define xp ((struct xnode *)p) +#define xq (*(struct xnode **)&q) + xq = (struct xnode *)getblk(sizeof(struct xnode)); + xq->xn_name = xp->xn_name; +#undef xp +#undef xq + } + else { + q = (struct nnode *)getblk(sizeof(struct nnode)); + q->nn_nloc = p->nn_nloc; + } + q->nn_op = p->nn_op; + q->nn_type = p->nn_type; + q->nn_class = p->nn_class; + q->nn_regno = p->nn_regno; + q->nn_offset = p->nn_offset; return(q); } @@ -1153,20 +1231,20 @@ union tree *ncopy(p) register union tree *p; { * If the tree can be immediately loaded into a register, * produce code to do so and return success. */ -int chkleaf(tree, table, reg) register union tree *tree; struct table *table; int reg; { +int chkleaf(tree, table, reg) register struct tree *tree; struct table *table; int reg; { struct tnode lbuf; - /*fprintf(stderr, "chkleaf(0x%08x, 0x%08x, 0x%08x)\n", tree, table, reg);*/ - if (tree->t.op!=STAR && dcalc(tree, nreg-reg) > 12) + if (tree->t_op!=STAR && dcalc(tree, nreg-reg) > 12) return(-1); - lbuf.op = LOAD; - lbuf.type = tree->t.type; - lbuf.degree = tree->t.degree; - lbuf.tr1 = tree; -#if 1 /* can't have garbage in lbuf.tr2, cexpr() will deref it if non-NULL */ - lbuf.tr2 = NULL; -#endif - return(rcexpr1((union tree *)&lbuf, table, reg)); + /* if dcalc() returns 0 then either tree == NULL or tree is a struct tnode */ +#define ttree ((struct tnode *)tree) + lbuf.tn_op = LOAD; + lbuf.tn_type = ttree->tn_type; + lbuf.tn_degree = ttree->tn_degree; + lbuf.tn_tr1 = tree; + /* can't have garbage in lbuf.tr2, cexpr() will deref it if non-NULL */ + lbuf.tn_tr2 = TNULL; + return(rcexpr1((struct tree *)&lbuf, table, reg)); } /* @@ -1176,15 +1254,15 @@ int chkleaf(tree, table, reg) register union tree *tree; struct table *table; in * Return the number of bytes pushed, * for future popping. */ -int comarg(tree, flagp) register union tree *tree; int *flagp; { +int comarg(tree, flagp) register struct tree *tree; int *flagp; { register int retval; int i; int size; - if (/*tree->t.op==STRASG*/tree->t.type==STRUCT) { - /* size = tree->F.mask; - tree = tree->t.tr1;*/ - size = tree->t.strp->S.ssize; + if (/*tree->t_op==STRASG*/tree->t_type==STRUCT) { + /* size = tree->fa_mask; + tree = tree->tn_tr1;*/ + size = tree->t_strp->S.ssize; tree = strfunc(tree); if (size <= sizeof(_INT)) { paint(tree, INT); @@ -1194,12 +1272,12 @@ int comarg(tree, flagp) register union tree *tree; int *flagp; { paint(tree, LONG); goto normal; } - if (tree->t.op!=NAME && tree->t.op!=STAR) { + if (tree->t_op!=NAME && tree->t_op!=STAR) { error1("Unimplemented structure assignment"); return(0); } - tree = tnode1(AMPER, STRUCT+PTR, tree, TNULL); - tree = tnode1(PLUS, STRUCT+PTR, tree, tconst(size, INT)); + tree = (struct tree *)tnode(AMPER, STRUCT+PTR, tree, TNULL); + tree = (struct tree *)tnode(PLUS, STRUCT+PTR, tree, (struct tree *)tconst(size, INT)); tree = optim(tree); retval = rcexpr1(tree, regtab, 0); size >>= 1; @@ -1217,9 +1295,9 @@ int comarg(tree, flagp) register union tree *tree; int *flagp; { return(size*2); } normal: - if (nstack || isfloat(tree) || tree->t.type==LONG || tree->t.type==UNLONG) { + if (nstack || isfloat(tree) || tree->t_type==LONG || tree->t_type==UNLONG) { rcexpr1(tree, sptab, 0); - retval = arlength(tree->t.type); + retval = arlength(tree->t_type); } else { (*flagp)++; rcexpr1(tree, lsptab, 0); @@ -1228,24 +1306,24 @@ normal: return(retval); } -union tree *strfunc(tp) register union tree *tp; { - if (tp->t.op != CALL) +struct tree *strfunc(tp) register struct tree *tp; { + if (tp->t_op != CALL) return(tp); paint(tp, STRUCT+PTR); - return(tnode1(STAR, STRUCT, tp, TNULL)); + return((struct tree *)tnode(STAR, STRUCT, tp, TNULL)); } /* * Compile an initializing expression */ -void doinit(type, tree) register int type; register union tree *tree; { +void doinit(type, tree) register int type; register struct tree *tree; { _FLOAT sfval; _DOUBLE fval; _LONG lval; if (type==CHAR || type==UNCHAR) { fprintf(temp_fp[temp_fi], /*printf(*/".byte "); - if (tree->t.type&XTYPE) + if (tree->t_type&XTYPE) goto illinit; type = INT; } @@ -1254,28 +1332,29 @@ void doinit(type, tree) register int type; register union tree *tree; { switch (type) { case INT: case UNSIGN: - if (tree->t.op==FTOI) { - if (tree->t.tr1->t.op!=FCON && tree->t.tr1->t.op!=SFCON) + if (tree->t_op==FTOI) { + if (((struct tnode *)tree)->tn_tr1->t_op!=FCON && ((struct tnode *)tree)->tn_tr1->t_op!=SFCON) goto illinit; - tree = tree->t.tr1; + tree = ((struct tnode *)tree)->tn_tr1; + fval = ((struct fnode *)tree)->fn_fvalue; + ((struct cnode *)tree)->cn_op = CON; #ifdef pdp11 - tree->c.value = tree->f.fvalue; + ((struct cnode *)tree)->cn_value = fval; #else - tree->c.value = fp_double_to_int(tree->f.fvalue); + ((struct cnode *)tree)->cn_value = fp_double_to_int(fval); #endif - tree->t.op = CON; - } else if (tree->t.op==LTOI) { - if (tree->t.tr1->t.op!=LCON) + } else if (tree->t_op==LTOI) { + if (((struct tnode *)tree)->tn_tr1->t_op!=LCON) goto illinit; - tree = tree->t.tr1; - lval = tree->l.lvalue; - tree->t.op = CON; - tree->c.value = lval; + tree = ((struct tnode *)tree)->tn_tr1; + lval = ((struct lnode *)tree)->ln_lvalue; + ((struct cnode *)tree)->cn_op = CON; + ((struct cnode *)tree)->cn_value = lval; } - if (tree->t.op == CON) - fprintf(temp_fp[temp_fi], /*printf(*/"%o\n", UNS(tree->c.value)); - else if (tree->t.op==AMPER) { - pname(tree->t.tr1, 0); + if (tree->t_op == CON) + fprintf(temp_fp[temp_fi], /*printf(*/"%o\n", UNS(((struct cnode *)tree)->cn_value)); + else if (tree->t_op==AMPER) { + pname(((struct tnode *)tree)->tn_tr1, 0); fputc('\n', temp_fp[temp_fi]) /*putchar('\n')*/; } else goto illinit; @@ -1283,30 +1362,33 @@ void doinit(type, tree) register int type; register union tree *tree; { case DOUBLE: case FLOAT: - if (tree->t.op==ITOF) { - if (tree->t.tr1->t.op==CON) { + if (tree->t_op==ITOF) { +#define ttree ((struct tnode *)tree) + if (ttree->tn_tr1->t_op==CON) { /* note: this should be changed to respect the signedness of the int */ #ifdef pdp11 - fval = tree->t.tr1->c.value; + fval = ((struct cnode *)ttree->tn_tr1)->cn_value; #else - fval = fp_int_to_double(tree->t.tr1->c.value); + fval = fp_int_to_double(((struct cnode *)ttree->tn_tr1)->cn_value); #endif } else goto illinit; - } else if (tree->t.op==FCON || tree->t.op==SFCON) { - fval = tree->f.fvalue; - } else if (tree->t.op==LTOF) { - if (tree->t.tr1->t.op!=LCON) +#undef ttree + } else if (tree->t_op==FCON || tree->t_op==SFCON) { + fval = ((struct fnode *)tree)->fn_fvalue; + } else if (tree->t_op==LTOF) { +#define ttree ((struct tnode *)tree) + if (ttree->tn_tr1->t_op!=LCON) goto illinit; /* note: this should be changed to respect the signedness of the long */ #ifdef pdp11 - fval = tree->t.tr1->l.lvalue; + fval = ((struct lnode *)ttree->tn_tr1)->ln_lvalue; #else - fval = fp_long_to_double(tree->t.tr1->l.lvalue); + fval = fp_long_to_double(((struct lnode *)ttree->tn_tr1)->ln_lvalue); #endif +#undef ttree } else goto illinit; - /* note: value is still in emulated r0 and used again below */ if (type==FLOAT) { #ifdef pdp11 sfval = fval; @@ -1340,26 +1422,28 @@ void doinit(type, tree) register int type; register union tree *tree; { case UNLONG: case LONG: - if (tree->t.op==FTOL) { - tree = tree->t.tr1; - if (tree->t.op==SFCON) - tree->t.op = FCON; - if (tree->t.op!= FCON) + if (tree->t_op==FTOL) { + tree = ((struct tnode *)tree)->tn_tr1; + if (tree->t_op==SFCON) + tree->t_op = FCON; + if (tree->t_op!= FCON) goto illinit; #ifdef pdp11 - lval = tree->f.fvalue; + lval = ((struct fnode *)tree)->fn_fvalue; #else - lval = fp_double_to_long(tree->f.fvalue); + lval = fp_double_to_long(((struct fnode *)tree)->fn_fvalue); #endif - } else if (tree->t.op==ITOL) { - if (tree->t.tr1->t.op != CON) + } else if (tree->t_op==ITOL) { +#define ttree ((struct tnode *)tree) + if (ttree->tn_tr1->t_op != CON) goto illinit; - if (uns(tree->t.tr1)) - lval = (_UNSIGNED_INT)tree->t.tr1->c.value; + if (uns(ttree->tn_tr1)) + lval = (_UNSIGNED_INT)((struct cnode *)ttree->tn_tr1)->cn_value; else - lval = tree->t.tr1->c.value; - } else if (tree->t.op==LCON) { - lval = tree->l.lvalue; + lval = ((struct cnode *)ttree->tn_tr1)->cn_value; +#undef ttree + } else if (tree->t_op==LCON) { + lval = ((struct lnode *)tree)->ln_lvalue; } else goto illinit; /* nonportable */ @@ -1370,13 +1454,13 @@ illinit: error1("Illegal initialization"); } -void movreg(r0, r1, tree) int r0; int r1; union tree *tree; { +void movreg(r0, r1, tree) int r0; int r1; struct tree *tree; { register char *s; char c; if (r0==r1) return; - if (tree->t.type==LONG || tree->t.type == UNLONG) { + if (tree->t_type==LONG || tree->t_type == UNLONG) { if (r0>=nreg || r1>=nreg) { error1("register overflow: compiler error"); } diff --git a/c11.c b/c11.c index 4ca0075..e1a9e9d 100644 --- a/c11.c +++ b/c11.c @@ -18,102 +18,114 @@ /*static void outname __P((char *s));*/ static void outname __P((char *buf, char *str)); -int degree(t) register union tree *t; { - register union tree *t1; +int degree(t) register struct tree *t; { + register struct tree *t1; - if (t==NULL || t->t.op==0) + if (t==NULL || t->t_op==0) return(0); - if (t->t.op == CON) + if (t->t_op == CON) return(-3); - if (t->t.op == AMPER) + if (t->t_op == AMPER) return(-2); - if (t->t.op==ITOL) { - if ((t1 = isconstant(t)) && (t1->c.value>=0 || uns(t1))) + if (t->t_op==ITOL) { + /* assume isconstant() does not return an SFCON since it's ITOL not FTOL */ + if ((t1 = isconstant(t)) && (((struct cnode *)t1)->cn_value>=0 || uns(t1))) return(-2); - if (uns(t1 = t->t.tr1) && opdope1[t1->t.op]&LEAF) + if (uns(t1 = ((struct tnode *)t)->tn_tr1) && opdope1[t1->t_op]&LEAF) return(-1); } - if ((opdope1[t->t.op] & LEAF) != 0) { - if (t->t.type==CHAR || t->t.type==UNCHAR || t->t.type==FLOAT) + if ((opdope1[t->t_op] & LEAF) != 0) { + if (t->t_type==CHAR || t->t_type==UNCHAR || t->t_type==FLOAT) return(1); return(0); } - return(t->t.degree); + return(((struct tnode *)t)->tn_degree); } -void pname(p, flag) register union tree *p; int flag; { +void pname(p, flag) register struct tree *p; int flag; { register int i; loop: - /*fprintf(stderr, "pname %p %d\n", p, p->t.op);*/ - switch(p->t.op) { + switch(p->t_op) { case LCON: - fprintf(temp_fp[temp_fi], /*printf(*/"$%o", flag<=10? UNS(p->l.lvalue>>16): - UNS(p->l.lvalue)); +#define lp ((struct lnode *)p) + fprintf(temp_fp[temp_fi], /*printf(*/"$%o", flag<=10? UNS(lp->ln_lvalue>>16): + UNS(lp->ln_lvalue)); return; +#undef lp case SFCON: case CON: +#define cp ((struct cnode *)p) fprintf(temp_fp[temp_fi], /*printf(*/"$"); - psoct(p->c.value); + psoct(cp->cn_value); return; +#undef cp case FCON: - fprintf(temp_fp[temp_fi], /*printf(*/"L%d", (p->c.value>0? p->c.value: -p->c.value)); +#define fp ((struct fnode *)p) + fprintf(temp_fp[temp_fi], /*printf(*/"L%d", (fp->fn_value>0? fp->fn_value: -fp->fn_value)); return; +#undef fp case NAME: - i = p->n.offset; +#define np ((struct nnode *)p) + i = np->nn_offset; if (flag>10) i += 2; if (i) { psoct(i); - if (p->n.class!=OFFS) + if (np->nn_class!=OFFS) fputc('+', temp_fp[temp_fi]) /*putchar('+')*/; - if (p->n.class==REG) + if (np->nn_class==REG) error1("Illegal use of register"); } - switch(p->n.class) { + switch(np->nn_class) { case SOFFS: case XOFFS: - pbase(p); + pbase(np); case OFFS: - fprintf(temp_fp[temp_fi], /*printf(*/"(r%d)", p->n.regno); + fprintf(temp_fp[temp_fi], /*printf(*/"(r%d)", np->nn_regno); return; case EXTERN: case STATIC: - pbase(p); + pbase(np); return; case REG: - fprintf(temp_fp[temp_fi], /*printf(*/"r%d", p->n.nloc); + fprintf(temp_fp[temp_fi], /*printf(*/"r%d", np->nn_nloc); return; } error1("Compiler error: pname"); return; +#undef np case AMPER: fputc('$', temp_fp[temp_fi]) /*putchar('$')*/; - p = p->t.tr1; - if (p->t.op==NAME && p->n.class==REG) + p = ((struct tnode *)p)->tn_tr1; + if (p->t_op==NAME && ((struct nnode *)p)->nn_class==REG) error1("Illegal use of register"); goto loop; case AUTOI: - fprintf(temp_fp[temp_fi], /*printf(*/"(r%d)%s", p->n.nloc, flag==1?"":"+"); +#define np ((struct nnode *)p) + fprintf(temp_fp[temp_fi], /*printf(*/"(r%d)%s", np->nn_nloc, flag==1?"":"+"); return; +#undef np case AUTOD: - fprintf(temp_fp[temp_fi], /*printf(*/"%s(r%d)", flag==2?"":"-", p->n.nloc); +#define np ((struct nnode *)p) + fprintf(temp_fp[temp_fi], /*printf(*/"%s(r%d)", flag==2?"":"-", np->nn_nloc); return; +#undef np case STAR: - p = p->t.tr1; + p = ((struct tnode *)p)->tn_tr1; fputc('*', temp_fp[temp_fi]) /*putchar('*')*/; goto loop; @@ -121,21 +133,21 @@ loop: error1("compiler error: bad pname"); } -void pbase(p) register union tree *p; { +void pbase(p) register struct nnode *p; { - if (p->n.class==SOFFS || p->n.class==STATIC) - fprintf(temp_fp[temp_fi], /*printf(*/"L%d", p->n.nloc); + if (p->nn_class==SOFFS || p->nn_class==STATIC) + fprintf(temp_fp[temp_fi], /*printf(*/"L%d", p->nn_nloc); else - fprintf(temp_fp[temp_fi], /*printf(*/"%s", p->x.name); + fprintf(temp_fp[temp_fi], /*printf(*/"%s", ((struct xnode *)p)->xn_name); } -int xdcalc(p, nrleft) register union tree *p; int nrleft; { +int xdcalc(p, nrleft) register struct tree *p; int nrleft; { register int d; if (p==NULL) return(0); d = dcalc(p, nrleft); - if (d<20 && (p->t.type==CHAR || p->t.type==UNCHAR)) { + if (d<20 && (p->t_type==CHAR || p->t_type==UNCHAR)) { if (nrleft>=1) d = 20; else @@ -144,16 +156,19 @@ int xdcalc(p, nrleft) register union tree *p; int nrleft; { return(d); } -int dcalc(p, nrleft) register union tree *p; int nrleft; { - register union tree *p1; +/* if dcalc() returns 0 then either p == NULL or p is a struct tnode */ +int dcalc(p, nrleft) register struct tree *p; int nrleft; { + register struct tree *p1; if (p==NULL) return(0); - switch (p->t.op) { + switch (p->t_op) { case NAME: - if (p->n.class==REG && p->n.type!=CHAR && p->n.type!=UNCHAR) +#define np ((struct nnode *)p) + if (np->nn_class==REG && np->nn_type!=CHAR && np->nn_type!=UNCHAR) return(9); +#undef np case AMPER: case FCON: @@ -164,29 +179,38 @@ int dcalc(p, nrleft) register union tree *p; int nrleft; { case CON: case SFCON: - if (p->c.value==0) +#define cp ((struct cnode *)p) + if (cp->cn_value==0) return(4); - if (p->c.value==1) + if (cp->cn_value==1) return(5); - if (p->c.value > 0) + if (cp->cn_value > 0) return(8); return(12); +#undef cp case STAR: - p1 = p->t.tr1; - if (p1->t.op==NAME||p1->t.op==CON||p1->t.op==AUTOI||p1->t.op==AUTOD) - if (p->t.type!=LONG && p->t.type!=UNLONG) +#define tp ((struct tnode *)p) + p1 = tp->tn_tr1; + if (p1->t_op==NAME||p1->t_op==CON||p1->t_op==AUTOI||p1->t_op==AUTOD) + if (tp->tn_type!=LONG && tp->tn_type!=UNLONG) return(12); + break; +#undef tp } - if (p->t.type==LONG || p->t.type==UNLONG) + /* above should have eliminated all of the leaf cases */ + if (opdope1[p->t_op] & LEAF) abort(); +#define tp ((struct tnode *)p) + if (tp->tn_type==LONG || tp->tn_type==UNLONG) nrleft--; - return(p->t.degree <= nrleft? 20: 24); + return(tp->tn_degree <= nrleft? 20: 24); +#undef tp } -int notcompat(p, ast, deg, op) register union tree *p; int ast; int deg; int op; { +int notcompat(p, ast, deg, op) register struct tree *p; int ast; int deg; int op; { unsigned register at, st; - at = p->t.type; + at = p->t_type; /* * an e or n UNCHAR is to be considered an UNSIGNED, * as long as it is not pointed to. @@ -207,7 +231,7 @@ int notcompat(p, ast, deg, op) register union tree *p; int ast; int deg; int op; at = at&TYPE | 020; if (st==FLOAT && at==DOUBLE) at = FLOAT; - if (p->t.op==NAME && p->n.class==REG && op==ASSIGN && st==CHAR) + if (p->t_op==NAME && ((struct nnode *)p)->nn_class==REG && op==ASSIGN && st==CHAR) return(0); return(st != at); } @@ -237,44 +261,46 @@ int prins(op, c, itable, lbl) int op; int c; struct instab *itable; int lbl; { return(skip); } -int collcon(p) register union tree *p; { +int collcon(p) register struct tree *p; { register int op; if (p==NULL) return(0); - if (p->t.op==STAR) { - if (p->t.type==LONG+PTR || p->t.type==UNLONG+PTR) /* avoid *x(r); *x+2(r) */ + if (p->t_op==STAR) { + if (p->t_type==LONG+PTR || p->t_type==UNLONG+PTR) /* avoid *x(r); *x+2(r) */ return(0); - p = p->t.tr1; + p = ((struct tnode *)p)->tn_tr1; } - if (p->t.op==PLUS) { - op = p->t.tr2->t.op; + if (p->t_op==PLUS) { + op = ((struct tnode *)p)->tn_tr2->t_op; if (op==CON || op==AMPER) return(1); } return(0); } -int isfloat(t) register union tree *t; { +int isfloat(t) register struct tree *t; { - if ((opdope1[t->t.op]&RELAT)!=0) - t = t->t.tr1; - if (t->t.type==FLOAT || t->t.type==DOUBLE) { + if ((opdope1[t->t_op]&RELAT)!=0) + t = ((struct tnode *)t)->tn_tr1; + if (t->t_type==FLOAT || t->t_type==DOUBLE) { nfloat = 1; return('f'); } return(0); } -int oddreg(t, reg) register union tree *t; register int reg; { +int oddreg(t, reg) register struct tree *t; register int reg; { if (!isfloat(t)) { - if (opdope1[t->t.op]&RELAT) { - if (t->t.tr1->t.type==LONG || t->t.tr1->t.type==UNLONG) + if (opdope1[t->t_op]&RELAT) { +#define tt ((struct tnode *)t) + if (tt->tn_tr1->t_type==LONG || tt->tn_tr1->t_type==UNLONG) return((reg+1) & ~01); return(reg); +#undef tt } - switch(t->t.op) { + switch(t->t_op) { case ULLSHIFT: case UASLSHL: case LLSHIFT: @@ -471,155 +497,177 @@ int sort(afp, alp) struct swtab *afp; struct swtab *alp; { return(0); } -int ispow2(tree) register union tree *tree; { +int ispow2(tree) register struct tnode *tree; { register int d; - if (!isfloat(tree) && tree->t.tr2->t.op==CON) { - d = tree->t.tr2->c.value; + if (!isfloat((struct tree *)tree) && tree->tn_tr2->t_op==CON) { + d = ((struct cnode *)tree->tn_tr2)->cn_value; if (d>1 && (d&(d-1))==0) return(d); } return(0); } -union tree *pow2(tree) register union tree *tree; { +struct tnode *pow2(tree) register struct tnode *tree; { register int d, i; if (d = ispow2(tree)) { for (i=0; (d>>=1)!=0; i++); - tree->t.tr2->c.value = i; - switch (tree->t.op) { + ((struct cnode *)tree->tn_tr2)->cn_value = i; + switch (tree->tn_op) { case TIMES: - tree->t.op = LSHIFT; + tree->tn_op = LSHIFT; break; case ASTIMES: - tree->t.op = ASLSH; + tree->tn_op = ASLSH; break; case PTOI: - if (i==1 && tree->t.tr1->t.op==MINUS && !isconstant(tree->t.tr1->t.tr2)) { - tree->t.op = PTOI1; - tree->t.tr1 = tnode1(LTOI, INT, tree->t.tr1, TNULL); - return(optim(tree)); + if (i==1 && tree->tn_tr1->t_op==MINUS && !isconstant(((struct tnode *)tree->tn_tr1)->tn_tr2)) { + tree->tn_op = PTOI1; + tree->tn_tr1 = (struct tree *)tnode(LTOI, INT, tree->tn_tr1, TNULL); + /* in this case optim() is guaranteed to return a struct tnode */ + /* return((struct tnode *)optim((struct tree *)tree));*/ + tree = (struct tnode *)optim((struct tree *)tree); + if (opdope1[tree->tn_op] & LEAF) abort(); + return tree; } - tree->t.op = LLSHIFT; - tree->t.tr2->c.value = -i; - i = tree->t.type; - tree->t.type = LONG; - tree = tnode1(LTOI, i, tree, TNULL); + tree->tn_op = LLSHIFT; + ((struct cnode *)tree->tn_tr2)->cn_value = -i; + i = tree->tn_type; + tree->tn_type = LONG; + tree = tnode(LTOI, i, (struct tree *)tree, TNULL); break; case DIVIDE: - tree->t.op = ULSH; - tree->t.tr2->c.value = -i; + tree->tn_op = ULSH; + ((struct cnode *)tree->tn_tr2)->cn_value = -i; break; case ASDIV: - tree->t.op = ASULSH; - tree->t.tr2->c.value = -i; + tree->tn_op = ASULSH; + ((struct cnode *)tree->tn_tr2)->cn_value = -i; break; case MOD: - tree->t.op = AND; - tree->t.tr2->c.value = (1<tn_op = AND; + ((struct cnode *)tree->tn_tr2)->cn_value = (1<t.op = ASAND; - tree->t.tr2->c.value = (1<tn_op = ASAND; + ((struct cnode *)tree->tn_tr2)->cn_value = (1<tn_op] & LEAF) abort(); } return(tree); } -void cbranch1(atree, lbl, cond, reg) union tree *atree; register int lbl; int cond; register int reg; { +void cbranch1(atree, lbl, cond, reg) struct tree *atree; register int lbl; int cond; register int reg; { int l1, op; - register union tree *tree; + register struct tree *tree; again: if ((tree=atree)==NULL) return; - switch(tree->t.op) { + switch(tree->t_op) { case LOGAND: +#define ttree ((struct tnode *)tree) if (cond) { - cbranch1(tree->t.tr1, l1=isn1++, 0, reg); - cbranch1(tree->t.tr2, lbl, 1, reg); + cbranch1(ttree->tn_tr1, l1=isn1++, 0, reg); + cbranch1(ttree->tn_tr2, lbl, 1, reg); label1(l1); } else { - cbranch1(tree->t.tr1, lbl, 0, reg); - cbranch1(tree->t.tr2, lbl, 0, reg); + cbranch1(ttree->tn_tr1, lbl, 0, reg); + cbranch1(ttree->tn_tr2, lbl, 0, reg); } return; +#undef ttree case LOGOR: +#define ttree ((struct tnode *)tree) if (cond) { - cbranch1(tree->t.tr1, lbl, 1, reg); - cbranch1(tree->t.tr2, lbl, 1, reg); + cbranch1(ttree->tn_tr1, lbl, 1, reg); + cbranch1(ttree->tn_tr2, lbl, 1, reg); } else { - cbranch1(tree->t.tr1, l1=isn1++, 1, reg); - cbranch1(tree->t.tr2, lbl, 0, reg); + cbranch1(ttree->tn_tr1, l1=isn1++, 1, reg); + cbranch1(ttree->tn_tr2, lbl, 0, reg); label1(l1); } return; +#undef ttree case EXCLA: - cbranch1(tree->t.tr1, lbl, !cond, reg); +#define ttree ((struct tnode *)tree) + cbranch1(ttree->tn_tr1, lbl, !cond, reg); return; +#undef ttree case SEQNC: - rcexpr1(tree->t.tr1, efftab, reg); - atree = tree->t.tr2; +#define ttree ((struct tnode *)tree) + rcexpr1(ttree->tn_tr1, efftab, reg); + atree = ttree->tn_tr2; goto again; +#undef ttree case ITOL: - tree = tree->t.tr1; + tree = ((struct tnode *)tree)->tn_tr1; break; case QUEST: +#define ttree ((struct tnode *)tree) l1 = isn1; isn1 += 2; - cbranch1(tree->t.tr1, l1, 0, reg); - cbranch1(tree->t.tr2->t.tr1, lbl, cond, reg); + cbranch1(ttree->tn_tr1, l1, 0, reg); + cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr1, lbl, cond, reg); branch1(l1+1, 0, 0); label1(l1); - cbranch1(tree->t.tr2->t.tr2, lbl, cond, reg); + cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr2, lbl, cond, reg); label1(l1+1); return; +#undef ttree } - op = tree->t.op; + op = tree->t_op; if (opdope1[op]&RELAT - && tree->t.tr1->t.op==ITOL && tree->t.tr2->t.op==ITOL - && uns(tree->t.tr1->t.tr1) == uns(tree->t.tr2->t.tr1)) { - tree->t.tr1 = tree->t.tr1->t.tr1; - tree->t.tr2 = tree->t.tr2->t.tr1; + && ((struct tnode *)tree)->tn_tr1->t_op==ITOL && ((struct tnode *)tree)->tn_tr2->t_op==ITOL + && uns(((struct tnode *)((struct tnode *)tree)->tn_tr1)->tn_tr1) == uns(((struct tnode *)((struct tnode *)tree)->tn_tr2)->tn_tr1)) { +#define ttree ((struct tnode *)tree) + ttree->tn_tr1 = ((struct tnode *)ttree->tn_tr1)->tn_tr1; + ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1; if (op>=LESSEQ && op<=GREAT - && uns(tree->t.tr1)) - tree->t.op = op = op+LESSEQP-LESSEQ; + && uns(ttree->tn_tr1)) + ttree->tn_op = op = op+LESSEQP-LESSEQ; +#undef ttree } - if (tree->t.type==LONG || tree->t.type==UNLONG - || opdope1[op]&RELAT&&(tree->t.tr1->t.type==LONG || tree->t.tr1->t.type==UNLONG)) { - longrel(tree, lbl, cond, reg); + if (tree->t_type==LONG || tree->t_type==UNLONG + || opdope1[op]&RELAT&&(((struct tnode *)tree)->tn_tr1->t_type==LONG || ((struct tnode *)tree)->tn_tr1->t_type==UNLONG)) { +#define ttree ((struct tnode *)tree) + longrel(ttree, lbl, cond, reg); return; +#undef ttree } rcexpr1(tree, cctab, reg); - op = tree->t.op; + op = tree->t_op; if ((opdope1[op]&RELAT)==0) op = NEQUAL; else { - l1 = tree->t.tr2->t.op; - if ((l1==CON || l1==SFCON) && tree->t.tr2->c.value==0) +#define ttree ((struct tnode *)tree) + l1 = ttree->tn_tr2->t_op; + if ((l1==CON || l1==SFCON) && ((struct cnode *)ttree->tn_tr2)->cn_value==0) op += 200; /* special for ptr tests */ else op = maprel[op-EQUAL]; +#undef ttree } if (isfloat(tree)) fprintf(temp_fp[temp_fi], /*printf(*/"cfcc\n"); @@ -642,19 +690,21 @@ void branch1(lbl, aop, c) int lbl; int aop; int c; { fprintf(temp_fp[temp_fi], /*printf(*/"\tL%d\n", lbl); } -void longrel(atree, lbl, cond, reg) union tree *atree; int lbl; int cond; int reg; { +void longrel(atree, lbl, cond, reg) struct tnode *atree; int lbl; int cond; int reg; { int xl1, xl2, xo, xz; register int op, isrel; - register union tree *tree; + register struct tnode *tree; if (reg&01) reg++; - reorder(&atree, cctab, reg); + reorder((struct tree **)&atree, cctab, reg); + /* in this case reorder is guaranteed to return a struct tnode */ + if (opdope1[atree->tn_op] & LEAF) abort(); tree = atree; isrel = 0; - if (opdope1[tree->t.op]&RELAT) { + if (opdope1[tree->tn_op]&RELAT) { isrel++; - op = tree->t.op; + op = tree->tn_op; } else op = NEQUAL; if (!cond) @@ -666,14 +716,14 @@ void longrel(atree, lbl, cond, reg) union tree *atree; int lbl; int cond; int re xlab2 = 0; xop = op; xz = xzero; - xzero = !isrel || (tree->t.tr2->t.op==ITOL && tree->t.tr2->t.tr1->t.op==CON - && tree->t.tr2->t.tr1->c.value==0); - if (tree->t.op==ANDN) { - tree->t.op = TAND; - tree->t.tr2 = optim(tnode1(COMPL, LONG, tree->t.tr2, TNULL)); + xzero = !isrel || (tree->tn_tr2->t_op==ITOL && ((struct tnode *)tree->tn_tr2)->tn_tr1->t_op==CON + && ((struct cnode *)((struct tnode *)tree->tn_tr2)->tn_tr1)->cn_value==0); + if (tree->tn_op==ANDN) { + tree->tn_op = TAND; + tree->tn_tr2 = optim((struct tree *)tnode(COMPL, LONG, tree->tn_tr2, TNULL)); } - if (cexpr(tree, cctab, reg) < 0) { - reg = rcexpr1(tree, regtab, reg); + if (cexpr((struct tree *)tree, cctab, reg) < 0) { + reg = rcexpr1((struct tree *)tree, regtab, reg); fprintf(temp_fp[temp_fi], /*printf(*/"ashc $0,r%d\n", reg); branch1(xlab1, op, 0); } @@ -813,14 +863,18 @@ void outcode(fmt, va_alist) char *fmt; va_dcl #endif { va_list argp; - /* union tree *expstack[STKS], **sp;*/ - static union tree *expstack[STKS], **sp = expstack; - register union tree *tp; + /* struct tree *expstack[STKS], **sp;*/ + static struct tree *expstack[STKS], **sp = expstack; +#if 0 /* bitrot */ + register struct tree *tp; +#endif register int t, op; char s[80]; /* big for asm() stuff & long variable names */ struct swtab *swp; +#if 0 /* bitrot */ long outloc; int lbl, cond, lbl2, lbl3; +#endif /* curbase = funcbase; sp = expstack;*/ @@ -836,7 +890,9 @@ void outcode(fmt, va_alist) char *fmt; va_dcl error1("Intermediate file error"); exit(1); }*/ +#if 0 /* bitrot */ lbl = 0; +#endif switch(op &= 0377) { case SINIT: @@ -875,7 +931,7 @@ void outcode(fmt, va_alist) char *fmt; va_dcl case SYMDEF: outname(s/*)*/, va_arg(argp, char *)); fprintf(temp_fp[temp_fi], /*printf(*/".globl\t%s\n", s); - sfuncr.nloc = 0; + sfuncr.nn_nloc = 0; break; case RETRN: @@ -945,6 +1001,7 @@ void outcode(fmt, va_alist) char *fmt; va_dcl pswitch1((struct swtab *)funcbase, swp, t); break; +#if 0 /* bitrot */ case C3BRANCH: /* for fortran [sic] */ lbl = va_arg(argp, int) /*geti()*/; lbl2 = va_arg(argp, int) /*geti()*/; @@ -978,8 +1035,8 @@ void outcode(fmt, va_alist) char *fmt; va_dcl else if (op==EXPR) rcexpr1(tp, efftab, 0); else { - if (tp->t.type==LONG || tp->t.type==UNLONG) { - rcexpr1(tnode1(RFORCE, tp->t.type, tp, TNULL), efftab, 0); + if (tp->tn_type==LONG || tp->tn_type==UNLONG) { + rcexpr1(tnode(RFORCE, tp->tn_type, tp, TNULL), efftab, 0); fprintf(temp_fp[temp_fi], /*printf(*/"ashc $0,r0\n"); } else { rcexpr1(tp, cctab, 0); @@ -996,19 +1053,19 @@ void outcode(fmt, va_alist) char *fmt; va_dcl t = va_arg(argp, int) /*geti()*/; if (t==EXTERN) { tp = getblk(sizeof(struct xnode)); - tp->t.type = va_arg(argp, int) /*geti()*/; + tp->tn_type = va_arg(argp, int) /*geti()*/; outname(s/*)*/, va_arg(argp, char *)); - tp->x.name = (char *)getblk(strlen(s) + 1); - strcpy(tp->x.name, s); + tp->xn_name = (char *)getblk(strlen(s) + 1); + strcpy(tp->xn_name, s); } else { tp = getblk(sizeof(struct nnode)); - tp->t.type = va_arg(argp, int) /*geti()*/; - tp->n.nloc = va_arg(argp, int) /*geti()*/; + tp->tn_type = va_arg(argp, int) /*geti()*/; + tp->nn_nloc = va_arg(argp, int) /*geti()*/; } - tp->t.op = NAME; - tp->n.class = t; - tp->n.regno = 0; - tp->n.offset = 0; + tp->tn_op = NAME; + tp->nn_class = t; + tp->nn_regno = 0; + tp->nn_offset = 0; *sp++ = tp; break; @@ -1022,13 +1079,13 @@ void outcode(fmt, va_alist) char *fmt; va_dcl t = va_arg(argp, int) /*geti()*/; op = va_arg(argp, int) /*geti()*/; if (t==0 && op>=0 || t == -1 && op<0) { - *sp++ = tnode1(ITOL, LONG, tconst(op, INT), TNULL); + *sp++ = (struct tree *)tnode(ITOL, LONG, tconst(op, INT), TNULL); break; } tp = getblk(sizeof(struct lnode)); - tp->t.op = LCON; - tp->t.type = LONG; - tp->l.lvalue = ((_LONG)t<<16) + UNS(op); /* nonportable */ + tp->tn_op = LCON; + tp->tn_type = LONG; + tp->ln_lvalue = ((_LONG)t<<16) + UNS(op); /* nonportable */ *sp++ = tp; break; @@ -1036,39 +1093,40 @@ void outcode(fmt, va_alist) char *fmt; va_dcl t = va_arg(argp, int) /*geti()*/; outname(s/*)*/, va_arg(argp, char *)); tp = getblk(sizeof(struct fnode)); - tp->t.op = FCON; - tp->t.type = t; - tp->f.value = isn1++; + tp->tn_op = FCON; + tp->tn_type = t; + tp->fn_value = isn1++; #ifdef pdp11 - tp->f.fvalue = atof(s); + tp->fn_fvalue = atof(s); #else - tp->f.fvalue = fp_atof(s); + tp->fn_fvalue = fp_atof(s); #endif *sp++ = tp; break; case FSEL: - tp = tnode1(FSEL, va_arg(argp, int) /*geti()*/, *--sp, TNULL); + tp = tnode(FSEL, va_arg(argp, int) /*geti()*/, *--sp, TNULL); t = va_arg(argp, int) /*geti()*/; - tp->t.tr2 = tnode1(COMMA, INT, tconst(va_arg(argp, int) /*geti()*/, INT), tconst(t, INT)); - if (tp->t.tr2->t.tr1->c.value==16) - tp = paint(tp->t.tr1, tp->t.type); + tp->tn_tr2 = (struct tree *)tnode(COMMA, INT, tconst(va_arg(argp, int) /*geti()*/, INT), tconst(t, INT)); + if (tp->tn_tr2->tn_tr1->cn_value==16) + tp = paint(tp->tn_tr1, tp->tn_type); *sp++ = tp; break; case STRASG: tp = getblk(sizeof(struct fasgn)); - tp->t.op = STRASG; - tp->t.type = va_arg(argp, int) /*geti()*/; - tp->F.mask = va_arg(argp, int) /*geti()*/; - tp->t.tr1 = *--sp; - tp->t.tr2 = NULL; + tp->tn_op = STRASG; + tp->tn_type = va_arg(argp, int) /*geti()*/; + tp->fa_mask = va_arg(argp, int) /*geti()*/; + tp->tn_tr1 = *--sp; + tp->tn_tr2 = NULL; *sp++ = tp; break; case NULLOP: - *sp++ = tnode1(0, 0, TNULL, TNULL); + *sp++ = tnode(0, 0, TNULL, TNULL); break; +#endif case LABEL: label1(va_arg(argp, int) /*geti()*/); @@ -1093,6 +1151,9 @@ void outcode(fmt, va_alist) char *fmt; va_dcl break; default: +#if 1 /* bitrot */ + abort(); +#else if (opdope1[op]&BINARY) { if (sp < &expstack[1]) { error1("Binary expression botch"); @@ -1100,13 +1161,14 @@ void outcode(fmt, va_alist) char *fmt; va_dcl } tp = *--sp; #if 1 - sp[-1] = tnode1(op, va_arg(argp, int) /*geti()*/, sp[-1], tp); + sp[-1] = tnode(op, va_arg(argp, int) /*geti()*/, sp[-1], tp); #else - *sp++ = tnode1(op, va_arg(argp, int) /*geti()*/, *--sp, tp); + *sp++ = tnode(op, va_arg(argp, int) /*geti()*/, *--sp, tp); #endif } else - sp[-1] = tnode1(op, va_arg(argp, int) /*geti()*/, sp[-1], TNULL); + sp[-1] = tnode(op, va_arg(argp, int) /*geti()*/, sp[-1], TNULL); break; +#endif } } va_end(argp); @@ -1147,54 +1209,53 @@ static void outname(s) register char *s; { } #endif -void strasg(atp) union tree *atp; { - register union tree *tp; +void strasg(atp) struct tnode *atp; { + register struct tnode *tp; register int nwords, i; - /* nwords = atp->F.mask/sizeof(_INT);*/ - nwords = atp->t.strp->S.ssize/sizeof(_INT); - tp = atp/*->t.tr1*/; - /* while (tp->t.op == SEQNC) { - rcexpr1(tp->t.tr1, efftab, 0); - tp = tp->t.tr2; + /* nwords = atp->fa_mask/sizeof(_INT);*/ + nwords = atp->tn_strp->S.ssize/sizeof(_INT); + tp = atp/*->tn_tr1*/; + /* while (tp->tn_op == SEQNC) { + rcexpr1(tp->tn_tr1, efftab, 0); + tp = tp->tn_tr2; } - if (tp->t.op != ASSIGN) {*/ - if (tp->t.op==RFORCE) { /* function return */ - if (sfuncr.nloc==0) { - sfuncr.nloc = isn1++; - fprintf(temp_fp[temp_fi], /*printf(*/".bss\nL%d:.=.+%o\n.text\n", sfuncr.nloc, + if (tp->tn_op != ASSIGN) {*/ + if (tp->tn_op==RFORCE) { /* function return */ + if (sfuncr.nn_nloc==0) { + sfuncr.nn_nloc = isn1++; + fprintf(temp_fp[temp_fi], /*printf(*/".bss\nL%d:.=.+%o\n.text\n", sfuncr.nn_nloc, UNS(nwords*sizeof(_INT))); } - atp/*->t.tr1*/ = tnode1(ASSIGN, STRUCT, (union tree *)&sfuncr, tp->t.tr1); - atp->t.strp = tp->t.strp; + atp/*->tn_tr1*/ = tnode(ASSIGN, STRUCT, (struct tree *)&sfuncr, tp->tn_tr1); + atp->tn_strp = tp->tn_strp; strasg(atp); - fprintf(temp_fp[temp_fi], /*printf(*/"mov $L%d,r0\n", sfuncr.nloc); + fprintf(temp_fp[temp_fi], /*printf(*/"mov $L%d,r0\n", sfuncr.nn_nloc); return; } - /* if (tp->t.op==CALL) { + /* if (tp->tn_op==CALL) { rcexpr1(tp, efftab, 0); return; } error1("Illegal structure operation"); return; }*/ - tp->t.tr2 = strfunc(tp->t.tr2); + tp->tn_tr2 = strfunc(tp->tn_tr2); if (nwords==1) - paint(tp, INT); + paint((struct tree *)tp, INT); else if (nwords==sizeof(_INT)) - paint(tp, LONG); + paint((struct tree *)tp, LONG); else { - if (tp->t.tr1->t.op!=NAME && tp->t.tr1->t.op!=STAR - || tp->t.tr2->t.op!=NAME && tp->t.tr2->t.op!=STAR) { + if (tp->tn_tr1->t_op!=NAME && tp->tn_tr1->t_op!=STAR + || tp->tn_tr2->t_op!=NAME && tp->tn_tr2->t_op!=STAR) { error1("unimplemented structure assignment"); return; } - tp->t.tr1 = tnode1(AMPER, STRUCT+PTR, tp->t.tr1, TNULL); - tp->t.tr2 = tnode1(AMPER, STRUCT+PTR, tp->t.tr2, TNULL); - tp->t.op = STRSET; - tp->t.type = STRUCT+PTR; - tp = optim(tp); - rcexpr1(tp, efftab, 0); + tp->tn_tr1 = (struct tree *)tnode(AMPER, STRUCT+PTR, tp->tn_tr1, TNULL); + tp->tn_tr2 = (struct tree *)tnode(AMPER, STRUCT+PTR, tp->tn_tr2, TNULL); + tp->tn_op = STRSET; + tp->tn_type = STRUCT+PTR; + rcexpr1(optim((struct tree *)tp), efftab, 0); if (nwords < 7) { for (i=0; i(b))?(a):(b)) -union tree *optim(tree) register union tree *tree; { - /*fprintf(stderr, "optim %d", tree->t.op); - if ((opdope1[tree->t.op] & LEAF) == 0) - fprintf(stderr, " left %d", tree->t.tr1->t.op); - if (opdope1[tree->t.op] & BINARY) - fprintf(stderr, " right %d", tree->t.tr2->t.op); - fprintf(stderr, "\n");*/ +struct tree *optim(tree) register struct tree *tree; { register int op, dope; - int d1, d2; - union tree *t; #ifdef pdp11 union { double dv; _INT iv[4];} fp11; #endif if (tree==NULL) return(NULL); - if ((op = tree->t.op)==0) + if ((op = tree->t_op)==0) return(tree); - if (op==NAME && tree->n.class==AUTO) { - tree->n.class = OFFS; - tree->n.regno = 5; - tree->n.offset = tree->n.nloc; + if (op==NAME && ((struct nnode *)tree)->nn_class==AUTO) { +#define ntree ((struct nnode *)tree) + ntree->nn_class = OFFS; + ntree->nn_regno = 5; + ntree->nn_offset = ntree->nn_nloc; +#undef ntree } dope = opdope1[op]; if ((dope&LEAF) != 0) { if (op==FCON) { +#define ftree ((struct fnode *)tree) #ifdef pdp11 - fp11.dv = tree->f.fvalue; + fp11.dv = ftree->fn_fvalue; if (fp11.iv[1]==0 && fp11.iv[2]==0 && fp11.iv[3]==0) { - tree->t.op = SFCON; - tree->f.value = fp11.iv[0]; + ftree->fn_op = SFCON; + ftree->fn_value = fp11.iv[0]; } #else - if (tree->f.fvalue.l==0 - && (tree->f.fvalue.h & 0xffff)==0) { - tree->t.op = SFCON; - tree->f.value = (int)(tree->f.fvalue.h >> 16) & 0xffff; + if (ftree->fn_fvalue.l==0 + && (ftree->fn_fvalue.h & 0xffff)==0) { + ftree->fn_op = SFCON; + ftree->fn_value = (int)(ftree->fn_fvalue.h >> 16) & 0xffff; } #endif +#undef ftree } return(tree); } if ((dope&BINARY) == 0) return(unoptim(tree)); - /* is known to be binary */ - if (tree->t.type==CHAR) - tree->t.type = INT; - switch(op) { + return(binoptim(tree)); +} + +/* in reality this can only be called with a struct tnode argument */ +struct tree *binoptim(tree) register struct tree *tree; { + register int op, dope; + int d1, d2; + struct tree *t; + +#define ttree ((struct tnode *)tree) + if (ttree->tn_type==CHAR) + ttree->tn_type = INT; + switch(ttree->tn_op) { /* * PDP-11 special: * generate new &=~ operator out of &= * by complementing the RHS. */ case ASAND: - tree->t.op = ASANDN; - tree->t.tr2 = tnode1(COMPL, tree->t.tr2->t.type, tree->t.tr2, TNULL); + ttree->tn_op = ASANDN; + ttree->tn_tr2 = (struct tree *)tnode(COMPL, ttree->tn_tr2->t_type, ttree->tn_tr2, TNULL); break; /* @@ -78,105 +83,111 @@ union tree *optim(tree) register union tree *tree; { * Longs are just truncated. */ case LTOP: - tree->t.op = ITOP; - tree->t.tr1 = unoptim(tnode1(LTOI,INT,tree->t.tr1, TNULL)); + ttree->tn_op = ITOP; + ttree->tn_tr1 = unoptim((struct tree *)tnode(LTOI,INT,ttree->tn_tr1, TNULL)); case ITOP: - tree->t.op = TIMES; + ttree->tn_op = TIMES; break; case MINUS: - if ((t = isconstant(tree->t.tr2)) && (!uns(t) || tree->t.type!=LONG) - && (t->t.type!=INT || t->c.value!=(_INT)0100000)) { - tree->t.op = PLUS; - if (t->t.type==DOUBLE) { + if ((t = isconstant(ttree->tn_tr2)) && (!uns(t) || ttree->tn_type!=LONG) + /* I don't think the following test matters since -0100000 == 0100000 */ + && (t->t_type!=INT || ((struct cnode *)t)->cn_value!=(_INT)0100000)) { + ttree->tn_op = PLUS; + if (t->t_type==DOUBLE) { + /* here it's an SFCON, so fn_value is filled in instead of fn_fvalue */ /* PDP-11 FP representation */ - t->f/*c*/.value ^= 0100000; + ((struct fnode *)t)->fn_value ^= 0100000; } else - t->c.value = -t->c.value; + ((struct cnode *)t)->cn_value = -((struct cnode *)t)->cn_value; } break; } - op = tree->t.op; + op = ttree->tn_op; dope = opdope1[op]; - if (dope&LVALUE && tree->t.tr1->t.op==FSEL) - return(lvfield(tree)); + if (dope&LVALUE && ttree->tn_tr1->t_op==FSEL) + return(lvfield(ttree)); if ((dope&COMMUTE)!=0) { - d1 = tree->t.type; + d1 = ttree->tn_type; +#undef ttree tree = acommute(tree); - if (tree->t.op == op) - tree->t.type = d1; + if (tree->t_op == op) + tree->t_type = d1; /* * PDP-11 special: * replace a&b by a ANDN ~ b. * This will be undone when in * truth-value context. */ - if (tree->t.op!=AND) + if (tree->t_op!=AND) return(tree); +#define ttree ((struct tnode *)tree) /* * long & pos-int is simpler */ - if ((tree->t.type==LONG || tree->t.type==UNLONG) && tree->t.tr2->t.op==ITOL - && (tree->t.tr2->t.tr1->t.op==CON && tree->t.tr2->t.tr1->c.value>=0 - || uns(tree->t.tr2->t.tr1))) { - tree->t.type = UNSIGN; - t = tree->t.tr2; - tree->t.tr2 = tree->t.tr2->t.tr1; - t->t.tr1 = tree; - tree->t.tr1 = tnode1(LTOI, UNSIGN, tree->t.tr1, TNULL); + if ((ttree->tn_type==LONG || ttree->tn_type==UNLONG) && ttree->tn_tr2->t_op==ITOL + && (((struct tnode *)ttree->tn_tr2)->tn_tr1->t_op==CON && ((struct cnode *)((struct tnode *)ttree->tn_tr2)->tn_tr1)->cn_value>=0 + || uns(((struct tnode *)ttree->tn_tr2)->tn_tr1))) { + ttree->tn_type = UNSIGN; + t = ttree->tn_tr2; + ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1; + ((struct tnode *)t)->tn_tr1 = (struct tree *)ttree; + ttree->tn_tr1 = (struct tree *)tnode(LTOI, UNSIGN, ttree->tn_tr1, TNULL); return(optim(t)); } /* * Keep constants to the right */ - if ((tree->t.tr1->t.op==ITOL && tree->t.tr1->t.tr1->t.op==CON) - || tree->t.tr1->t.op==LCON) { - t = tree->t.tr1; - tree->t.tr1 = tree->t.tr2; - tree->t.tr2 = t; + if ((ttree->tn_tr1->t_op==ITOL && ((struct tnode *)ttree->tn_tr1)->tn_tr1->t_op==CON) + || ttree->tn_tr1->t_op==LCON) { + t = ttree->tn_tr1; + ttree->tn_tr1 = ttree->tn_tr2; + ttree->tn_tr2 = t; } - tree->t.op = ANDN; + ttree->tn_op = ANDN; op = ANDN; - tree->t.tr2 = tnode1(COMPL, tree->t.tr2->t.type, tree->t.tr2, TNULL); + ttree->tn_tr2 = (struct tree *)tnode(COMPL, ttree->tn_tr2->t_type, ttree->tn_tr2, TNULL); } again: - tree->t.tr1 = optim(tree->t.tr1); - tree->t.tr2 = optim(tree->t.tr2); - if (tree->t.type == LONG || tree->t.type==UNLONG) { - t = lconst(tree->t.op, tree->t.tr1, tree->t.tr2); + ttree->tn_tr1 = optim(ttree->tn_tr1); + ttree->tn_tr2 = optim(ttree->tn_tr2); + if (ttree->tn_type == LONG || ttree->tn_type==UNLONG) { + t = (struct tree *)lconst(ttree->tn_op, ttree->tn_tr1, ttree->tn_tr2); if (t) return(t); } if ((dope&RELAT) != 0) { - if ((d1=degree(tree->t.tr1)) < (d2=degree(tree->t.tr2)) - || d1==d2 && tree->t.tr1->t.op==NAME && tree->t.tr2->t.op!=NAME) { - t = tree->t.tr1; - tree->t.tr1 = tree->t.tr2; - tree->t.tr2 = t; - tree->t.op = maprel[op-EQUAL]; + if ((d1=degree(ttree->tn_tr1)) < (d2=degree(ttree->tn_tr2)) + || d1==d2 && ttree->tn_tr1->t_op==NAME && ttree->tn_tr2->t_op!=NAME) { + t = ttree->tn_tr1; + ttree->tn_tr1 = ttree->tn_tr2; + ttree->tn_tr2 = t; + ttree->tn_op = maprel[op-EQUAL]; } - if (tree->t.tr1->t.type==CHAR && tree->t.tr2->t.op==CON - && (dcalc(tree->t.tr1, 0) <= 12 || tree->t.tr1->t.op==STAR) - && tree->t.tr2->c.value <= 127 && tree->t.tr2->c.value >= 0) - tree->t.tr2->t.type = CHAR; + if (ttree->tn_tr1->t_type==CHAR && ttree->tn_tr2->t_op==CON + && (dcalc(ttree->tn_tr1, 0) <= 12 || ttree->tn_tr1->t_op==STAR) + && ((struct cnode *)ttree->tn_tr2)->cn_value <= 127 && ((struct cnode *)ttree->tn_tr2)->cn_value >= 0) + ttree->tn_tr2->t_type = CHAR; } - d1 = max(degree(tree->t.tr1), islong(tree->t.type)); - d2 = max(degree(tree->t.tr2), 0); + d1 = max(degree(ttree->tn_tr1), islong(ttree->tn_type)); + d2 = max(degree(ttree->tn_tr2), 0); switch (op) { /* * In assignment to fields, treat all-zero and all-1 specially. */ case FSELA: - if (tree->t.tr2->t.op==CON && tree->t.tr2->c.value==0) { - tree->t.op = ASAND; - tree->t.tr2->c.value = ~tree->F.mask; - return(optim(tree)); +#define Ftree ((struct fasgn *)ttree) + if (Ftree->fa_tr2->t_op==CON && ((struct cnode *)Ftree->fa_tr2)->cn_value==0) { + Ftree->fa_op = ASAND; + ((struct cnode *)Ftree->fa_tr2)->cn_value = ~Ftree->fa_mask; + return(optim((struct tree *)Ftree)); } - if (tree->t.tr2->t.op==CON && tree->F.mask==tree->t.tr2->c.value) { - tree->t.op = ASOR; - return(optim(tree)); + if (Ftree->fa_tr2->t_op==CON && Ftree->fa_mask==((struct cnode *)Ftree->fa_tr2)->cn_value) { + Ftree->fa_op = ASOR; + return(optim((struct tree *)Ftree)); } +#undef Ftree case LTIMES: case LDIV: @@ -194,213 +205,226 @@ union tree *optim(tree) register union tree *tree; { case ULMOD: case ULASTIMES: case ULASDIV: - tree->t.degree = 10; + ttree->tn_degree = 10; break; case ANDN: - if (isconstant(tree->t.tr2) && tree->t.tr2->c.value==0) { - return(tree->t.tr1); + if (isconstant(ttree->tn_tr2) && ((struct cnode *)ttree->tn_tr2)->cn_value==0) { + return(ttree->tn_tr1); } goto def; case CALL: - tree->t.degree = 10; + ttree->tn_degree = 10; break; case QUEST: case COLON: - tree->t.degree = max(d1, d2); + ttree->tn_degree = max(d1, d2); break; case PTOI: case DIVIDE: case ASDIV: case ASTIMES: - if (tree->t.tr2->t.op==CON && tree->t.tr2->c.value==1) { + if (ttree->tn_tr2->t_op==CON && ((struct cnode *)ttree->tn_tr2)->cn_value==1) { if (op==PTOI) - return(optim(tnode1(LTOI,INT,paint(tree->t.tr1,LONG), TNULL))); - return(paint(tree->t.tr1, tree->t.type)); + return(optim((struct tree *)tnode(LTOI,INT,paint(ttree->tn_tr1,LONG), TNULL))); + return(paint(ttree->tn_tr1, ttree->tn_type)); } case MOD: case ASMOD: - if ((uns(tree->t.tr1) || tree->t.op==PTOI) && ispow2(tree)) - return(pow2(tree)); - if ((op==MOD||op==ASMOD) && tree->t.type==DOUBLE) { + if ((uns(ttree->tn_tr1) || ttree->tn_op==PTOI) && ispow2(ttree)) + return((struct tree *)pow2(ttree)); + if ((op==MOD||op==ASMOD) && ttree->tn_type==DOUBLE) { error1("Floating %% not defined"); - tree->t.type = INT; + ttree->tn_type = INT; } case ULSH: case ASULSH: d1 += 2 + regpanic; d2 += 2 + regpanic; panicposs++; - if (tree->t.type==LONG || tree->t.type==UNLONG) - return(hardlongs(tree)); + if (ttree->tn_type==LONG || ttree->tn_type==UNLONG) + return(hardlongs((struct tree *)ttree)); if ((op==MOD || op==DIVIDE || op==ASMOD || op==ASDIV) - && (uns(tree->t.tr1) || uns(tree->t.tr2)) - && (tree->t.tr2->t.op!=CON || tree->t.tr2->c.value<=1)) { + && (uns(ttree->tn_tr1) || uns(ttree->tn_tr2)) + && (ttree->tn_tr2->t_op!=CON || ((struct cnode *)ttree->tn_tr2)->cn_value<=1)) { if (op>=ASDIV) { - tree->t.op += ASUDIV - ASDIV; + ttree->tn_op += ASUDIV - ASDIV; } else - tree->t.op += UDIV - DIVIDE; + ttree->tn_op += UDIV - DIVIDE; d1 = d2 = 10; } goto constant; case ASPLUS: case ASMINUS: - if (tree->t.tr2->t.op==CON && tree->t.tr2->c.value==0) - return(tree->t.tr1); + if (ttree->tn_tr2->t_op==CON && ((struct cnode *)ttree->tn_tr2)->cn_value==0) + return(ttree->tn_tr1); goto def; case LSHIFT: case RSHIFT: case ASRSH: case ASLSH: - if (tree->t.tr2->t.op==CON && tree->t.tr2->c.value==0) - return(paint(tree->t.tr1, tree->t.type)); + if (ttree->tn_tr2->t_op==CON && ((struct cnode *)ttree->tn_tr2)->cn_value==0) + return(paint(ttree->tn_tr1, ttree->tn_type)); /* * PDP-11 special: turn right shifts into negative * left shifts */ - if (tree->t.type == LONG || tree->t.type==UNLONG) { + if (ttree->tn_type == LONG || ttree->tn_type==UNLONG) { d1++; d2++; } if (op==LSHIFT||op==ASLSH) goto constant; - if (tree->t.tr2->t.op==CON && tree->t.tr2->c.value==1 - && !uns(tree->t.tr1) && !uns(tree->t.tr2)) + if (ttree->tn_tr2->t_op==CON && ((struct cnode *)ttree->tn_tr2)->cn_value==1 + && !uns(ttree->tn_tr1) && !uns(ttree->tn_tr2)) goto constant; op += (LSHIFT-RSHIFT); - tree->t.op = op; - tree->t.tr2 = tnode1(NEG, tree->t.tr2->t.type, tree->t.tr2, TNULL); - if (uns(tree->t.tr1) || uns(tree->t.tr2)) { - if (tree->t.op==LSHIFT) - tree->t.op = ULSH; - else if (tree->t.op==ASLSH) - tree->t.op = ASULSH; + ttree->tn_op = op; + ttree->tn_tr2 = (struct tree *)tnode(NEG, ttree->tn_tr2->t_type, ttree->tn_tr2, TNULL); + if (uns(ttree->tn_tr1) || uns(ttree->tn_tr2)) { + if (ttree->tn_op==LSHIFT) + ttree->tn_op = ULSH; + else if (ttree->tn_op==ASLSH) + ttree->tn_op = ASULSH; } goto again; constant: - if (tree->t.tr1->t.op==CON && tree->t.tr2->t.op==CON) { - _const(op, &tree->t.tr1->c.value, tree->t.tr2->c.value, tree->t.type); - return(tree->t.tr1); + if (ttree->tn_tr1->t_op==CON && ttree->tn_tr2->t_op==CON) { + _const(op, &((struct cnode *)ttree->tn_tr1)->cn_value, ((struct cnode *)ttree->tn_tr2)->cn_value, ttree->tn_type); + return(ttree->tn_tr1); } def: default: if (dope&RELAT) { - if (tree->t.tr1->t.type==LONG || tree->t.tr1->t.type==UNLONG) /* long relations are a mess */ + if (ttree->tn_tr1->t_type==LONG || ttree->tn_tr1->t_type==UNLONG) /* long relations are a mess */ d1 = 10; - if (opdope1[tree->t.tr1->t.op]&RELAT && tree->t.tr2->t.op==CON - && tree->t.tr2->c.value==0) { - tree = tree->t.tr1; + if (opdope1[ttree->tn_tr1->t_op]&RELAT && ttree->tn_tr2->t_op==CON + && ((struct cnode *)ttree->tn_tr2)->cn_value==0) { switch(op) { case GREATEQ: - return((union tree *)&cone); + return((struct tree *)&cone); case LESS: - return((union tree *)&czero); + return((struct tree *)&czero); case LESSEQ: case EQUAL: - tree->t.op = notrel[tree->t.op-EQUAL]; + ttree->tn_tr1->t_op = notrel[ttree->tn_tr1->t_op-EQUAL]; } - return(tree); + return(ttree->tn_tr1); } } - tree->t.degree = d1==d2? d1+islong(tree->t.type): max(d1, d2); + ttree->tn_degree = d1==d2? d1+islong(ttree->tn_type): max(d1, d2); break; } - return(tree); + return((struct tree *)ttree); } -union tree *unoptim(tree) register union tree *tree; { - /*fprintf(stderr, "unoptim %d", tree->t.op); - if ((opdope1[tree->t.op] & LEAF) == 0) - fprintf(stderr, " left %d", tree->t.tr1->t.op); - if (opdope1[tree->t.op] & BINARY) - fprintf(stderr, " right %d", tree->t.tr2->t.op); - fprintf(stderr, "\n");*/ - register union tree *subtre, *p; +/* in reality this can only be called with a struct tnode argument */ +struct tree *unoptim(tree) register struct tree *tree; { + register struct tree *subtre, *p; - if (tree==NULL) +#define ttree ((struct tnode *)tree) + if (ttree==NULL) return(NULL); again: - if (tree->t.op==AMPER && tree->t.tr1->t.op==STAR) { - subtre = tree->t.tr1->t.tr1; - subtre->t.type = tree->t.type; + if (ttree->tn_op==AMPER && ttree->tn_tr1->t_op==STAR) { + subtre = ((struct tnode *)ttree->tn_tr1)->tn_tr1; + subtre->t_type = ttree->tn_type; return(optim(subtre)); } - subtre = tree->t.tr1 = optim(tree->t.tr1); - switch (tree->t.op) { + subtre = ttree->tn_tr1 = optim(ttree->tn_tr1); + switch (ttree->tn_op) { case INCAFT: case DECAFT: - if (tree->t.type!=subtre->t.type) - paint(subtre, tree->t.type); + if (ttree->tn_type!=subtre->t_type) + paint(subtre, ttree->tn_type); break; case ITOL: - if (subtre->t.op==CON && subtre->t.type==INT && subtre->c.value<0) { - subtre = getblk(sizeof(struct lnode)); - subtre->t.op = LCON; - subtre->t.type = LONG; - subtre->l.lvalue = tree->t.tr1->c.value; - return(subtre); + if (subtre->t_op==CON && subtre->t_type==INT && ((struct cnode *)subtre)->cn_value<0) { +#undef ttree +#define csubtre ((struct cnode *)subtre) + tree = getblk(sizeof(struct lnode)); +#define ltree ((struct lnode *)tree) + ltree->ln_op = LCON; + ltree->ln_type = LONG; + ltree->ln_lvalue = csubtre->cn_value; + return((struct tree *)ltree); +#define ttree ((struct tnode *)tree) +#undef csubtre +#undef ltree } break; case FTOI: - if (uns(tree)) { - tree->t.op = FTOL; - tree->t.type = LONG; - tree = tnode1(LTOI, UNSIGN, tree, TNULL); + if (uns((struct tree *)ttree)) { + ttree->tn_op = FTOL; + ttree->tn_type = LONG; + /*t*/tree = (struct tree *)tnode(LTOI, UNSIGN, (struct tree *)ttree, TNULL); } break; case LTOF: - if (subtre->t.op==LCON) { + if (subtre->t_op==LCON) { +#undef ttree +#define lsubtre ((struct lnode *)subtre) tree = getblk(sizeof(struct fnode)); - tree->t.op = FCON; - tree->t.type = DOUBLE; - tree->f/*c*/.value = isn1++; +#define ftree ((struct fnode *)tree) + ftree->fn_op = FCON; + ftree->fn_type = DOUBLE; + ftree->fn_value = isn1++; #ifdef pdp11 - tree->f.fvalue = subtre->l.lvalue; + ftree->fn_fvalue = lsubtre->ln_lvalue; #else - tree->f.fvalue = fp_long_to_double(subtre->l.lvalue); + ftree->fn_fvalue = fp_long_to_double(lsubtre->ln_lvalue); #endif - return(optim(tree)); + return(optim((struct tree *)ftree)); +#define ttree ((struct tnode *)tree) +#undef lsubtre +#undef ftree } - if (subtre->t.type==UNLONG) - tree->t.op = ULTOF; + if (subtre->t_type==UNLONG) + ttree->tn_op = ULTOF; break; case ITOF: - if (subtre->t.op==CON) { + if (subtre->t_op==CON) { +#undef ttree +#define csubtre ((struct cnode *)subtre) tree = getblk(sizeof(struct fnode)); - tree->t.op = FCON; - tree->t.type = DOUBLE; - tree->f.value = isn1++; +#define ftree ((struct fnode *)tree) + ftree->fn_op = FCON; + ftree->fn_type = DOUBLE; + ftree->fn_value = isn1++; #ifdef pdp11 - if (uns(subtre)) - tree->f.fvalue = (_UNSIGNED_INT)subtre->c.value; + if (uns((struct tree *)subtre)) + ftree->fn_fvalue = (_UNSIGNED_INT)csubtre->cn_value; else - tree->f.fvalue = subtre->c.value; + ftree->fn_fvalue = csubtre->cn_value; #else /* revisit the unsigned case */ - if (uns(subtre)) - tree->f.fvalue = fp_long_to_double((_LONG)(_UNSIGNED_INT)subtre->c.value); + if (uns((struct tree *)subtre)) + ftree->fn_fvalue = fp_long_to_double((_LONG)(_UNSIGNED_INT)csubtre->cn_value); else - tree->f.fvalue = fp_int_to_double(subtre->c.value); + ftree->fn_fvalue = fp_int_to_double(csubtre->cn_value); #endif - return(optim(tree)); + return(optim((struct tree *)ftree)); +#define ttree ((struct tnode *)tree) +#undef csubtre +#undef ftree } if (uns(subtre)) { - tree->t.tr1 = tnode1(ITOL, LONG, subtre, TNULL); - tree->t.op = LTOF; - return(optim(tree)); + ttree->tn_tr1 = (struct tree *)tnode(ITOL, LONG, subtre, TNULL); + ttree->tn_op = LTOF; + return(optim((struct tree *)ttree)); } break; @@ -408,40 +432,48 @@ union tree *unoptim(tree) register union tree *tree; { /* * Sign-extend PDP-11 characters */ - if (subtre->t.op==CON) { - char c; - c = subtre->c.value; - subtre->c.value = c; - subtre->t.type = tree->t.type; - return(subtre); - } else if (subtre->t.op==NAME && tree->t.type==INT) { - subtre->t.type = CHAR; + if (subtre->t_op==CON) { +#define csubtre ((struct cnode *)subtre) + csubtre->cn_type = ttree->tn_type; + csubtre->cn_value = (char)csubtre->cn_value; + return((struct tree *)csubtre); +#undef csubtre + } else if (subtre->t_op==NAME && ttree->tn_type==INT) { + subtre->t_type = CHAR; return(subtre); } break; case LTOI: - switch (subtre->t.op) { + switch (subtre->t_op) { case LCON: - subtre->t.op = CON; - subtre->t.type = tree->t.type; - subtre->c.value = subtre->l.lvalue; - return(subtre); +#define csubtre ((struct cnode *)subtre) + csubtre->cn_op = CON; + csubtre->cn_type = ttree->tn_type; + csubtre->cn_value = ((struct lnode *)csubtre)->ln_lvalue; + return((struct tree *)csubtre); +#undef csubtre case NAME: - subtre->n.offset += 2; - subtre->t.type = tree->t.type; - return(subtre); +#define nsubtre ((struct nnode *)subtre) + nsubtre->nn_offset += 2; + nsubtre->nn_type = ttree->tn_type; + return((struct tree *)nsubtre); +#undef nsubtre case STAR: - subtre->t.type = tree->t.type; - subtre->t.tr1->t.type = tree->t.type+PTR; - subtre->t.tr1 = tnode1(PLUS, tree->t.type, subtre->t.tr1, tconst(2, INT)); - return(optim(subtre)); +#define tsubtre ((struct tnode *)subtre) + tsubtre->tn_type = ttree->tn_type; + tsubtre->tn_tr1->t_type = ttree->tn_type+PTR; + tsubtre->tn_tr1 = (struct tree *)tnode(PLUS, ttree->tn_type, tsubtre->tn_tr1, (struct tree *)tconst(2, INT)); + return(optim((struct tree *)tsubtre)); +#undef tsubtre case ITOL: - return(paint(subtre->t.tr1, tree->t.type)); +#define tsubtre ((struct tnode *)subtre) + return(paint(tsubtre->tn_tr1, ttree->tn_type)); +#undef tsubtre case PLUS: case MINUS: @@ -449,194 +481,254 @@ union tree *unoptim(tree) register union tree *tree; { case ANDN: case OR: case EXOR: - subtre->t.tr2 = tnode1(LTOI, tree->t.type, subtre->t.tr2, TNULL); +#define tsubtre ((struct tnode *)subtre) + tsubtre->tn_tr2 = (struct tree *)tnode(LTOI, ttree->tn_type, tsubtre->tn_tr2, TNULL); case NEG: case COMPL: - subtre->t.tr1 = tnode1(LTOI, tree->t.type, subtre->t.tr1, TNULL); - subtre->t.type = tree->t.type; - return(optim(subtre)); + tsubtre->tn_tr1 = (struct tree *)tnode(LTOI, ttree->tn_type, tsubtre->tn_tr1, TNULL); + tsubtre->tn_type = ttree->tn_type; + return(optim((struct tree *)tsubtre)); +#undef tsubtre } break; case FSEL: - tree->t.op = AND; - /* tree->t.tr1 = tree->t.tr2->t.tr1; - tree->t.tr2->t.tr1 = subtre; - tree->t.tr2->t.op = RSHIFT; - tree->t.tr1->c.value = (1 << tree->t.tr1->c.value) - 1;*/ - tree->t.tr1 = tconst((1 << ((struct FS *)tree->t.tr2)->flen) - 1, INT); - tree->t.tr2 = tnode1(RSHIFT, INT, subtre, tconst(((struct FS *)tree->t.tr2)->bitoffs, INT)); - return(optim(tree)); + ttree->tn_op = AND; + /* ttree->tn_tr1 = ttree->tn_tr2->tn_tr1; + ttree->tn_tr2->tn_tr1 = subtre; + ttree->tn_tr2->tn_op = RSHIFT; + ttree->tn_tr1->cn_value = (1 << ttree->tn_tr1->cn_value) - 1;*/ + ttree->tn_tr1 = (struct tree *)tconst((1 << ((struct FS *)ttree->tn_tr2)->flen) - 1, INT); + ttree->tn_tr2 = (struct tree *)tnode(RSHIFT, INT, subtre, (struct tree *)tconst(((struct FS *)ttree->tn_tr2)->bitoffs, INT)); + return(optim((struct tree *)ttree)); case FSELR: - tree->t.op = LSHIFT; - tree->t.type = UNSIGN; - /* tree->t.tr1 = tree->t.tr2; - tree->t.tr1->t.op = AND; - tree->t.tr2 = tree->t.tr2->t.tr2; - tree->t.tr1->t.tr2 = subtre; - tree->t.tr1->t.tr1->c.value = (1 << tree->t.tr1->t.tr1->c.value) -1;*/ - tree->t.tr1 = tnode1(AND, INT, tconst((1 << ((struct FS *)tree->t.tr2)->flen) - 1, INT), subtre); - tree->t.tr2 = tconst(((struct FS *)tree->t.tr2)->bitoffs, INT); - return(optim(tree)); + ttree->tn_op = LSHIFT; + ttree->tn_type = UNSIGN; + /* ttree->tn_tr1 = ttree->tn_tr2; + ttree->tn_tr1->tn_op = AND; + ttree->tn_tr2 = ttree->tn_tr2->tn_tr2; + ttree->tn_tr1->tn_tr2 = subtre; + ttree->tn_tr1->tn_tr1->cn_value = (1 << ttree->tn_tr1->tn_tr1->cn_value) -1;*/ + ttree->tn_tr1 = (struct tree *)tnode(AND, INT, (struct tree *)tconst((1 << ((struct FS *)ttree->tn_tr2)->flen) - 1, INT), subtre); + ttree->tn_tr2 = (struct tree *)tconst(((struct FS *)ttree->tn_tr2)->bitoffs, INT); + return(optim((struct tree *)ttree)); case AMPER: - if (subtre->t.op==STAR) - return(subtre->t.tr1); - if (subtre->t.op==NAME && subtre->n.class == OFFS) { - p = tnode1(PLUS, tree->t.type, subtre, tree); - subtre->t.type = tree->t.type; - tree->t.op = CON; - tree->t.type = INT; - tree->t.degree = 0; - tree->c.value = subtre->n.offset; - subtre->n.class = REG; - subtre->n.nloc = subtre->n.regno; - subtre->n.offset = 0; - return(optim(p)); + if (subtre->t_op==STAR) + return(((struct tnode *)subtre)->tn_tr1); + if (subtre->t_op==NAME && ((struct nnode *)subtre)->nn_class == OFFS) { +#define nsubtre ((struct nnode *)subtre) + nsubtre->nn_type = ttree->tn_type; +#undef ttree +#define ctree ((struct cnode *)tree) + ctree->cn_op = CON; + ctree->cn_type = INT; + /* the below seems to have been an oversight, probably a harmless one */ + /* ctree->cn_degree = 0;*/ + ctree->cn_value = nsubtre->nn_offset; + nsubtre->nn_class = REG; + nsubtre->nn_nloc = nsubtre->nn_regno; + nsubtre->nn_offset = 0; + return(optim((struct tree *)tnode(PLUS, nsubtre->nn_type, (struct tree *)nsubtre, (struct tree *)ctree))); +#undef nsubtre +#define ttree ((struct tnode *)tree) +#undef ctree } - if (subtre->t.op==LOAD) { - tree->t.tr1 = subtre->t.tr1; + if (subtre->t_op==LOAD) { + ttree->tn_tr1 = ((struct tnode *)subtre)->tn_tr1; goto again; } break; case STAR: - if (subtre->t.op==AMPER) { - subtre->t.tr1->t.type = tree->t.type; - return(subtre->t.tr1); + if (subtre->t_op==AMPER) { +#define tsubtre ((struct tnode *)subtre) + tsubtre->tn_tr1->t_type = ttree->tn_type; + return(tsubtre->tn_tr1); +#undef tsubtre } - if (tree->t.type==STRUCT) + if (ttree->tn_type==STRUCT) break; - if (subtre->t.op==NAME && subtre->n.class==REG) { - subtre->t.type = tree->t.type; - subtre->n.class = OFFS; - subtre->n.regno = subtre->n.nloc; - return(subtre); + if (subtre->t_op==NAME && ((struct nnode *)subtre)->nn_class==REG) { +#define nsubtre ((struct nnode *)subtre) + nsubtre->nn_type = ttree->tn_type; + nsubtre->nn_class = OFFS; + nsubtre->nn_regno = nsubtre->nn_nloc; + return((struct tree *)nsubtre); +#undef nsubtre } - p = subtre->t.tr1; - if ((subtre->t.op==INCAFT||subtre->t.op==DECBEF) - && tree->t.type!=LONG && tree->t.type!=UNLONG - && p->t.op==NAME && p->n.class==REG && p->t.type==subtre->t.type) { - p->t.type = tree->t.type; - p->t.op = subtre->t.op==INCAFT? AUTOI: AUTOD; - return(p); + if ((subtre->t_op==INCAFT||subtre->t_op==DECBEF) + && ttree->tn_type!=LONG && ttree->tn_type!=UNLONG + && (p = ((struct tnode *)subtre)->tn_tr1)->t_op==NAME && ((struct nnode *)p)->nn_class==REG && ((struct nnode *)p)->nn_type==((struct tnode *)subtre)->tn_type) { +#define tsubtre ((struct tnode *)subtre) +#define np ((struct nnode *)p) + np->nn_type = ttree->tn_type; + np->nn_op = tsubtre->tn_op==INCAFT? AUTOI: AUTOD; + return((struct tree *)p); +#undef tsubtre +#undef np } - if (subtre->t.op==PLUS && p->t.op==NAME && p->n.class==REG) { - if (subtre->t.tr2->t.op==CON) { - p->n.offset += subtre->t.tr2->c.value; - p->n.class = OFFS; - p->t.type = tree->t.type; - p->n.regno = p->n.nloc; - return(p); + if (subtre->t_op==PLUS && (p = ((struct tnode *)subtre)->tn_tr1)->t_op==NAME && ((struct nnode *)p)->nn_class==REG) { +#define tsubtre ((struct tnode *)subtre) +#define np ((struct nnode *)p) + if (tsubtre->tn_tr2->t_op==CON) { + np->nn_offset += ((struct cnode *)tsubtre->tn_tr2)->cn_value; + np->nn_class = OFFS; + np->nn_type = ttree->tn_type; + np->nn_regno = np->nn_nloc; + return((struct tree *)np); } - if (subtre->t.tr2->t.op==AMPER) { - subtre = subtre->t.tr2->t.tr1; - subtre->n.class += XOFFS-EXTERN; - subtre->n.regno = p->n.nloc; - subtre->t.type = tree->t.type; - return(subtre); + if (tsubtre->tn_tr2->t_op==AMPER) { +#undef tsubtre + subtre = ((struct tnode *)((struct tnode *)subtre)->tn_tr2)->tn_tr1; + if (subtre->t_op != NAME) abort(); +#define nsubtre ((struct nnode *)subtre) + nsubtre->nn_class += XOFFS-EXTERN; + nsubtre->nn_regno = np->nn_nloc; + nsubtre->nn_type = ttree->tn_type; + return((struct tree *)nsubtre); +#define tsubtre ((struct tnode *)subtre) +#undef nsubtre } +#undef tsubtre +#undef np } - if (subtre->t.op==MINUS && p->t.op==NAME && p->n.class==REG - && subtre->t.tr2->t.op==CON) { - p->n.offset -= subtre->t.tr2->c.value; - p->n.class = OFFS; - p->t.type = tree->t.type; - p->n.regno = p->n.nloc; - return(p); + if (subtre->t_op==MINUS && (p = ((struct tnode *)subtre)->tn_tr1)->t_op==NAME && ((struct nnode *)p)->nn_class==REG + && ((struct tnode *)subtre)->tn_tr2->t_op==CON) { +#define tsubtre ((struct tnode *)subtre) +#define np ((struct nnode *)p) + np->nn_offset -= ((struct cnode *)tsubtre->tn_tr2)->cn_value; + np->nn_class = OFFS; + np->nn_type = ttree->tn_type; + np->nn_regno = np->nn_nloc; + return((struct tree *)np); +#undef tsubtre +#undef np } break; case EXCLA: - if ((opdope1[subtre->t.op]&RELAT)==0) +#undef ttree + if ((opdope1[subtre->t_op]&RELAT)==0) break; tree = subtre; - tree->t.op = notrel[tree->t.op-EQUAL]; + tree->t_op = notrel[tree->t_op-EQUAL]; break; +#define ttree ((struct tnode *)tree) case COMPL: - if (tree->t.type==CHAR) - tree->t.type = INT; - if (tree->t.op == subtre->t.op) - return(paint(subtre->t.tr1, tree->t.type)); - if (subtre->t.op==CON) { - subtre->c.value = ~subtre->c.value; - return(paint(subtre, tree->t.type)); + if (ttree->tn_type==CHAR) + ttree->tn_type = INT; + if (subtre->t_op == COMPL) + return(paint(((struct tnode *)subtre)->tn_tr1, ttree->tn_type)); + if (subtre->t_op==CON) { +#define csubtre ((struct cnode *)subtre) + csubtre->cn_value = ~csubtre->cn_value; + return(paint((struct tree *)csubtre, ttree->tn_type)); +#undef csubtre } - if (subtre->t.op==LCON) { - subtre->l.lvalue = ~subtre->l.lvalue; - return(subtre); + if (subtre->t_op==LCON) { +#define lsubtre ((struct lnode *)subtre) + lsubtre->ln_lvalue = ~lsubtre->ln_lvalue; + return((struct tree *)lsubtre); +#undef lsubtre } - if (subtre->t.op==ITOL) { - if (subtre->t.tr1->t.op==CON) { + if (subtre->t_op==ITOL) { +#define tsubtre ((struct tnode *)subtre) + if (tsubtre->tn_tr1->t_op==CON) { +#undef ttree tree = getblk(sizeof(struct lnode)); - tree->t.op = LCON; - tree->t.type = LONG; - if (uns(subtre->t.tr1)) - tree->l.lvalue = ~(_LONG)(_UNSIGNED_INT) - subtre->t.tr1->c.value; +#define ltree ((struct lnode *)tree) + ltree->ln_op = LCON; + ltree->ln_type = LONG; + if (uns(tsubtre->tn_tr1)) + ltree->ln_lvalue = ~(_LONG)(_UNSIGNED_INT) + ((struct cnode *)tsubtre->tn_tr1)->cn_value; else - tree->l.lvalue = - ~subtre->t.tr1->c.value; - return(tree); + ltree->ln_lvalue = + ~((struct cnode *)tsubtre->tn_tr1)->cn_value; + return((struct tree *)ltree); +#define ttree ((struct tnode *)tree) +#undef ltree } - if (uns(subtre->t.tr1)) + if (uns(tsubtre->tn_tr1)) break; - subtre->t.op = tree->t.op; - subtre->t.type = subtre->t.tr1->t.type; - tree->t.op = ITOL; - tree->t.type = LONG; + tsubtre->tn_op = ttree->tn_op; + tsubtre->tn_type = tsubtre->tn_tr1->t_type; + ttree->tn_op = ITOL; + ttree->tn_type = LONG; goto again; +#undef tsubtre } + /* previously was a fallthru, but I think it must have been an oversight */ + break; case NEG: - if (tree->t.type==CHAR) - tree->t.type = INT; - if (tree->t.op==subtre->t.op) - return(paint(subtre->t.tr1, tree->t.type)); - if (subtre->t.op==CON) { - subtre->c.value = -subtre->c.value; - return(paint(subtre, tree->t.type)); + if (ttree->tn_type==CHAR) + ttree->tn_type = INT; + if (subtre->t_op == NEG) + return(paint(((struct tnode *)subtre)->tn_tr1, ttree->tn_type)); + if (subtre->t_op==CON) { +#define csubtre ((struct cnode *)subtre) + csubtre->cn_value = -csubtre->cn_value; + return(paint((struct tree *)csubtre, ttree->tn_type)); +#undef csubtre } - if (subtre->t.op==LCON) { - subtre->l.lvalue = -subtre->l.lvalue; - return(subtre); + if (subtre->t_op==LCON) { +#define lsubtre ((struct lnode *)subtre) + lsubtre->ln_lvalue = -lsubtre->ln_lvalue; + return((struct tree *)lsubtre); +#undef lsubtre } - if (subtre->t.op==ITOL && subtre->t.tr1->t.op==CON) { + if (subtre->t_op==ITOL && ((struct tnode *)subtre)->tn_tr1->t_op==CON) { +#define tsubtre ((struct tnode *)subtre) +#undef ttree tree = getblk(sizeof(struct lnode)); - tree->t.op = LCON; - tree->t.type = LONG; - if (uns(subtre->t.tr1)) - tree->l.lvalue = -(_LONG)(_UNSIGNED_INT) - subtre->t.tr1->c.value; +#define ltree ((struct lnode *)tree) + ltree->ln_op = LCON; + ltree->ln_type = LONG; + if (uns(tsubtre->tn_tr1)) + ltree->ln_lvalue = -(_LONG)(_UNSIGNED_INT) + ((struct cnode *)tsubtre->tn_tr1)->cn_value; else - tree->l.lvalue = -subtre->t.tr1->c.value; - return(tree); + ltree->ln_lvalue = -((struct cnode *)tsubtre->tn_tr1)->cn_value; + return((struct tree *)ltree); +#undef tsubtre +#define ttree ((struct tnode *)tree) +#undef ltree } /* * PDP-11 FP negation */ - if (subtre->t.op==SFCON) { - subtre->c.value ^= 0100000; + if (subtre->t_op==SFCON) { +#define fsubtre ((struct fnode *)subtre) + fsubtre->fn_value ^= 0100000; #ifdef pdp11 - subtre->f.fvalue = -subtre->f.fvalue; + fsubtre->fn_fvalue = -fsubtre->fn_fvalue; #else - subtre->f.fvalue = fp_neg(subtre->f.fvalue); + fsubtre->fn_fvalue = fp_neg(fsubtre->fn_fvalue); #endif - return(subtre); + return((struct tree *)fsubtre); +#undef fsubtre } - if (subtre->t.op==FCON) { + if (subtre->t_op==FCON) { +#define fsubtre ((struct fnode *)subtre) #ifdef pdp11 - subtre->f.fvalue = -subtre->f.fvalue; + fsubtre->fn_fvalue = -fsubtre->fn_fvalue; #else - subtre->f.fvalue = fp_neg(subtre->f.fvalue); + fsubtre->fn_fvalue = fp_neg(fsubtre->fn_fvalue); #endif - return(subtre); + return((struct tree *)fsubtre); +#undef fsubtre } + break; } - if ((opdope1[tree->t.op]&LEAF)==0) - tree->t.degree = max(islong(tree->t.type), degree(subtre)); - return(tree); +#undef ttree + if ((opdope1[tree->t_op]&LEAF)==0) +#define ttree ((struct tnode *)tree) + ttree->tn_degree = max(islong(ttree->tn_type), degree(subtre)); +#undef ttree + return((struct tree *)tree); } /* @@ -649,23 +741,26 @@ union tree *unoptim(tree) register union tree *tree; { * Pure assignment is handled specially. */ -/* note that t->t.tr1->t.op == FSEL */ -union tree *lvfield(t) register union tree *t; { - register union tree *t1, *t2; +/* note that t->tn_tr1->t_op == FSEL */ +struct tree *lvfield(t) register struct tnode *t; { + register struct tnode *t1; + register struct fasgn *t2; - switch (t->t.op) { + switch (t->tn_op) { case ASSIGN: - t2 = getblk(sizeof(struct fasgn)); - t2->t.op = FSELA; - t2->t.type = UNSIGN; - t1 = t->t.tr1->t.tr2; + t2 = (struct fasgn *)getblk(sizeof(struct fasgn)); + t2->fa_op = FSELA; + t2->fa_type = UNSIGN; + t1 = (struct tnode *)((struct tnode *)t->tn_tr1)->tn_tr2; /* t1 formerly pointed to a COMMA node holding 2 constants */ /* now it contains its pass 0 value which is the field descriptor */ - t2->F.mask = ((1<t.tr1->c.value*/((struct FS *)t1)->flen)-1)<t.tr2->c.value*/((struct FS *)t1)->bitoffs; - t2->t.tr1 = t->t.tr1; - t2->t.tr2 = t->t.tr2; - t = t2; +#define FSt1 ((struct FS *)t1) + t2->fa_tr1 = t->tn_tr1; + t2->fa_tr2 = t->tn_tr2; + t2->fa_mask = ((1<tn_tr1->cn_value*/FSt1->flen)-1)<tn_tr2->cn_value*/FSt1->bitoffs; + t = (struct tnode *)t2; +#undef FSt1 case ASANDN: case ASPLUS: @@ -677,26 +772,28 @@ union tree *lvfield(t) register union tree *t; { case DECBEF: case DECAFT: /*t=ASANDN(FSEL(mos,COMMA(flen,bitoffs)),arg)*/ - t1 = t->t.tr1; + t1 = (struct tnode *)t->tn_tr1; /*t1=FSEL(mos,COMMA(flen,bitoffs))*/ - t1->t.op = FSELR; + t1->tn_op = FSELR; /*t1=FSELR(mos,COMMA(flen,bitoffs))*/ - t->t.tr1 = t1->t.tr1; + t->tn_tr1 = t1->tn_tr1; /*t=ASANDN(mos,arg)*/ - t1->t.tr1 = t->t.tr2; + t1->tn_tr1 = t->tn_tr2; /*t1=FSELR(arg,COMMA(flen,bitoffs))*/ - t->t.tr2 = t1; + t->tn_tr2 = (struct tree *)t1; /*t=ASANDN(mos,FSELR(arg,COMMA(flen,bitoffs)))*/ - t1 = t1->t.tr2; - /*t1=COMMA(flen,bitoffs)*/ - /*t1 = tnode1(COMMA, INT, tconst(t1->t.tr1->c.value, INT), - tconst(t1->t.tr2->c.value, INT));*/ + t1 = (struct tnode *)t1->tn_tr2; /*t1=COMMA(flen,bitoffs)*/ - return(optim(tnode1(FSELT, UNSIGN, t, t1))); - + /*t1 = (struct tree *)tnode(COMMA, INT, (struct tree *)tconst(t1->tn_tr1->cn_value, INT), + (struct tree *)tconst(t1->tn_tr2->cn_value, INT));*/ + /* t1 formerly pointed to a COMMA node holding 2 constants */ + /* now it contains its pass 0 value which is the field descriptor */ +#define FSt1 ((struct FS *)t1) + return(optim((struct tree *)tnode(FSELT, UNSIGN, (struct tree *)t, (struct tree *)FSt1))); +#undef FSt1 } error1("Unimplemented field operator"); - return(t); + return((struct tree *)t); } #if 0 /* now moved to c1.h */ @@ -704,35 +801,37 @@ union tree *lvfield(t) register union tree *t; { struct acl { int nextl; int nextn; - union tree *nlist[LSTSIZ]; - union tree *llist[LSTSIZ+1]; + struct tnode *nlist[LSTSIZ]; + struct tree *llist[LSTSIZ+1]; }; #endif -union tree *acommute(tree) register union tree *tree; { +/* in reality this can only be called with a struct tnode argument */ +struct tree *acommute(tree) register struct tree *tree; { struct acl acl; int d, i, op, flt, d1, type; - register union tree *t1, **t2; - union tree *t; + register struct tree *t1, **t2; + struct tree *t; +#define ttree ((struct tnode *)tree) acl.nextl = 0; acl.nextn = 0; - op = tree->t.op; - type = tree->t.type; - flt = isfloat(tree); - insert(op, tree, &acl); + op = ttree->tn_op; + type = ttree->tn_type; + flt = isfloat((struct tree *)ttree); + insert(op, (struct tree *)ttree, &acl); acl.nextl--; t2 = &acl.llist[acl.nextl]; if (!flt) { /* put constants together */ for (i=acl.nextl; i>0; i--) { - d = t2[-1]->t.type==UNSIGN||t2[0]->t.type==UNSIGN?UNSIGN:INT; - if (t2[0]->t.op==CON && t2[-1]->t.op==CON) { + d = t2[-1]->t_type==UNSIGN||t2[0]->t_type==UNSIGN?UNSIGN:INT; + if (t2[0]->t_op==CON && t2[-1]->t_op==CON) { acl.nextl--; t2--; - _const(op, &t2[0]->c.value, t2[1]->c.value, d); - t2[0]->t.type = d; - } else if (t = lconst(op, t2[-1], t2[0])) { + _const(op, &((struct cnode *)t2[0])->cn_value, ((struct cnode *)t2[1])->cn_value, d); + t2[0]->t_type = d; + } else if (t = (struct tree *)lconst(op, t2[-1], t2[0])) { acl.nextl--; t2--; t2[0] = t; @@ -741,108 +840,123 @@ union tree *acommute(tree) register union tree *tree; { } if (op==PLUS || op==OR) { /* toss out "+0" */ - if (acl.nextl>0 && ((t1 = isconstant(*t2)) && t1->c.value==0 - || (*t2)->t.op==LCON && (*t2)->l.lvalue==0)) { + /* isconstant() may return fnode, so need cn_value compatible with fn_value */ + if (acl.nextl>0 && ((t1 = isconstant(*t2)) && ((struct cnode *)t1)->cn_value==0 + || (*t2)->t_op==LCON && ((struct lnode *)*t2)->ln_lvalue==0)) { acl.nextl--; t2--; } if (acl.nextl <= 0) { - if ((*t2)->t.type==CHAR || (*t2)->t.type==UNCHAR) - *t2 = tnode1(LOAD, tree->t.type, *t2, TNULL); - (*t2)->t.type = tree->t.type; + if ((*t2)->t_type==CHAR || (*t2)->t_type==UNCHAR) + *t2 = (struct tree *)tnode(LOAD, ttree->tn_type, *t2, TNULL); + (*t2)->t_type = ttree->tn_type; return(*t2); } /* subsume constant in "&x+c" */ - if (op==PLUS && t2[0]->t.op==CON && t2[-1]->t.op==AMPER) { + if (op==PLUS && t2[0]->t_op==CON && t2[-1]->t_op==AMPER) { t2--; - t2[0]->t.tr1->n.offset += t2[1]->c.value; + ((struct nnode *)((struct tnode *)t2[0])->tn_tr1)->nn_offset += ((struct cnode *)t2[1])->cn_value; acl.nextl--; } } else if (op==TIMES || op==AND) { t1 = acl.llist[acl.nextl]; - if (t1->t.op==CON) { - if (t1->c.value==0) { + if (t1->t_op==CON) { +#define ct1 ((struct cnode *)t1) + if (ct1->cn_value==0) { for (i=0; ic.value==1 && acl.nextl>0) + if (op==TIMES && ct1->cn_value==1 && acl.nextl>0) if (--acl.nextl <= 0) { t1 = acl.llist[0]; - if (uns(tree)) - paint(t1, tree->t.type); + if (uns((struct tree *)ttree)) + paint(t1, ttree->tn_type); return(t1); } +#undef ct1 } } +#undef ttree if (op==PLUS && !flt) distrib(&acl); tree = *(t2 = &acl.llist[0]); - d = max(degree(tree), islong(tree->t.type)); + d = max(degree(tree), islong(tree->t_type)); if (op==TIMES && !flt) { d += regpanic+1; panicposs++; } for (i=0; it.tr2 = t = *++t2; + t1 = (struct tree *)acl.nlist[i]; +#define tt1 ((struct tnode *)t1) + tt1->tn_tr2 = t = *++t2; d1 = degree(t); /* * PDP-11 strangeness: * rt. op of ^ must be in a register. */ if (op==EXOR && dcalc(t, 0)<=12) { - t1->t.tr2 = t = optim(tnode1(LOAD, t->t.type, t, TNULL)); - d1 = t->t.degree; + tt1->tn_tr2 = t = optim((struct tree *)tnode(LOAD, t->t_type, t, TNULL)); + /* in this case optim() is guaranteed to return a struct tnode */ + if (opdope1[t->t_op] & LEAF) abort(); + d1 = ((struct tnode *)t)->tn_degree; } - t1->t.degree = d = d==d1? d+islong(t1->t.type): max(d, d1); - t1->t.tr1 = tree; - tree = t1; - if (tree->t.type==LONG || tree->t.type==UNLONG) { - if (tree->t.op==TIMES) + tt1->tn_degree = d = d==d1? d+islong(tt1->tn_type): max(d, d1); + tt1->tn_tr1 = tree; + tree = (struct tree *)tt1; + if (tree->t_type==LONG || tree->t_type==UNLONG) { + if (tree->t_op==TIMES) tree = hardlongs(tree); - else if (tree->t.op==PLUS && (t = isconstant(tree->t.tr1)) - && t->c.value < 0 && !uns(t)) { - tree->t.op = MINUS; - t->c.value = - t->c.value; - t = tree->t.tr1; - tree->t.tr1 = tree->t.tr2; - tree->t.tr2 = t; + /* assume isconstant() returns cnode (CON) not fnode (SFCON) since long */ + else if (tree->t_op==PLUS && (t = isconstant(((struct tnode *)tree)->tn_tr1)) + && ((struct cnode *)t)->cn_value < 0 && !uns(t)) { +#define ttree ((struct tnode *)tree) + ttree->tn_op = MINUS; + ((struct cnode *)t)->cn_value = -((struct cnode *)t)->cn_value; + t = ttree->tn_tr1; + ttree->tn_tr1 = ttree->tn_tr2; + ttree->tn_tr2 = t; +#undef ttree } } +#undef tt1 } - if (tree->t.op==TIMES && ispow2(tree)) - tree->t.degree = max(degree(tree->t.tr1), islong(tree->t.type)); + if (tree->t_op==TIMES && ispow2((struct tnode *)tree)) +#define ttree ((struct tnode *)tree) + ttree->tn_degree = max(degree(ttree->tn_tr1), islong(ttree->tn_type)); +#undef ttree paint(tree, type); return(tree); } -int sideeffects(tp) register union tree *tp; { +int sideeffects(tp) register struct tree *tp; { register int dope; if (tp==NULL) return(0); - dope = opdope1[tp->t.op]; + dope = opdope1[tp->t_op]; if (dope&LEAF) { - if (tp->t.op==AUTOI || tp->t.op==AUTOD) + if (tp->t_op==AUTOI || tp->t_op==AUTOD) return(1); return(0); } +#define ttp ((struct tnode *)tp) if (dope&ASSGOP) return(1); - switch(tp->t.op) { + switch(ttp->tn_op) { case CALL: case FSELA: case STRASG: return(1); } - if (sideeffects(tp->t.tr1)) + if (sideeffects(ttp->tn_tr1)) return(1); if (dope&BINARY) - return(sideeffects(tp->t.tr2)); + return(sideeffects(ttp->tn_tr2)); return(0); +#undef ttp } void distrib(list) struct acl *list; { @@ -853,35 +967,35 @@ void distrib(list) struct acl *list; { * fewest divisors. Reduce this pair to c1*(y+c2*x) * and iterate until no reductions occur. */ - register union tree **p1, **p2; - union tree *t; + register struct tree **p1, **p2; + struct tree *t; int ndmaj, ndmin; - union tree **dividend, **divisor; - union tree **maxnod, **mindiv; + struct tree **dividend, **divisor; + struct tree **maxnod, **mindiv; loop: maxnod = &list->llist[list->nextl]; ndmaj = 1000; dividend = 0; for (p1 = list->llist; p1 <= maxnod; p1++) { - if ((*p1)->t.op!=TIMES || (*p1)->t.tr2->t.op!=CON) + if ((*p1)->t_op!=TIMES || ((struct tnode *)*p1)->tn_tr2->t_op!=CON) continue; ndmin = 0; for (p2 = list->llist; p2 <= maxnod; p2++) { - if (p1==p2 || (*p2)->t.op!=TIMES || (*p2)->t.tr2->t.op!=CON) + if (p1==p2 || (*p2)->t_op!=TIMES || ((struct tnode *)*p2)->tn_tr2->t_op!=CON) continue; - if ((*p1)->t.tr2->c.value == (*p2)->t.tr2->c.value) { - (*p2)->t.tr2 = (*p1)->t.tr1; - (*p2)->t.op = PLUS; - (*p1)->t.tr1 = (*p2); + if (((struct cnode *)((struct tnode *)*p1)->tn_tr2)->cn_value == ((struct cnode *)((struct tnode *)*p2)->tn_tr2)->cn_value) { + ((struct tnode *)*p2)->tn_tr2 = ((struct tnode *)*p1)->tn_tr1; + ((struct tnode *)*p2)->tn_op = PLUS; + ((struct tnode *)*p1)->tn_tr1 = (struct tree *)((struct tnode *)*p2); *p1 = optim(*p1); squash(p2, maxnod); list->nextl--; goto loop; } - if (((*p2)->t.tr2->c.value % (*p1)->t.tr2->c.value) == 0) + if ((((struct cnode *)((struct tnode *)*p2)->tn_tr2)->cn_value % ((struct cnode *)((struct tnode *)*p1)->tn_tr2)->cn_value) == 0) goto contmaj; - if (((*p1)->t.tr2->c.value % (*p2)->t.tr2->c.value) == 0) { + if ((((struct cnode *)((struct tnode *)*p1)->tn_tr2)->cn_value % ((struct cnode *)((struct tnode *)*p2)->tn_tr2)->cn_value) == 0) { ndmin++; mindiv = p2; } @@ -895,15 +1009,18 @@ void distrib(list) struct acl *list; { } if (dividend==0) return; - t = list->nlist[--list->nextn]; +#define tt (*(struct tnode **)&t) + if (list->nextn == 0) abort(); + tt = list->nlist[--list->nextn]; p1 = dividend; p2 = divisor; - t->t.op = PLUS; - t->t.type = (*p1)->t.type; - t->t.tr1 = (*p1); - t->t.tr2 = (*p2)->t.tr1; - (*p1)->t.tr2->c.value /= (*p2)->t.tr2->c.value; - (*p2)->t.tr1 = t; + tt->tn_op = PLUS; + tt->tn_type = ((struct tnode *)*p1)->tn_type; + tt->tn_tr1 = (struct tree *)((struct tnode *)*p1); + tt->tn_tr2 = ((struct tnode *)*p2)->tn_tr1; + ((struct cnode *)((struct tnode *)*p1)->tn_tr2)->cn_value /= ((struct cnode *)((struct tnode *)*p2)->tn_tr2)->cn_value; + ((struct tnode *)*p2)->tn_tr1 = (struct tree *)tt; +#undef tt t = optim(*p2); if (p1 < p2) { *p1 = t; @@ -916,8 +1033,8 @@ void distrib(list) struct acl *list; { goto loop; } -void squash(p, maxp) union tree **p; union tree **maxp; { - register union tree **np; +void squash(p, maxp) struct tree **p; struct tree **maxp; { + register struct tree **np; for (np = p; np < maxp; np++) *np = *(np+1); @@ -1020,25 +1137,29 @@ void _const(op, vp, v, type) int op; register _INT *vp; register _INT v; int typ error1("C error: const"); } -union tree *lconst(op, lp, rp) int op; register union tree *lp; register union tree *rp; { +struct lnode *lconst(op, lp, rp) int op; register struct tree *lp; register struct tree *rp; { _UNSIGNED_LONG l, r; - if (lp->t.op==LCON) - l = lp->l.lvalue; - else if (lp->t.op==ITOL && lp->t.tr1->t.op==CON) { - if (lp->t.tr1->t.type==INT) - l = lp->t.tr1->c.value; + if (lp->t_op==LCON) + l = ((struct lnode *)lp)->ln_lvalue; + else if (lp->t_op==ITOL && ((struct tnode *)lp)->tn_tr1->t_op==CON) { +#define tlp ((struct tnode *)lp) + if (tlp->tn_tr1->t_type==INT) + l = ((struct cnode *)tlp->tn_tr1)->cn_value; else - l = (_UNSIGNED_INT)lp->t.tr1->c.value; + l = (_UNSIGNED_INT)((struct cnode *)tlp->tn_tr1)->cn_value; +#undef tlp } else return(0); - if (rp->t.op==LCON) - r = rp->l.lvalue; - else if (rp->t.op==ITOL && rp->t.tr1->t.op==CON) { - if (rp->t.tr1->t.type==INT) - r = rp->t.tr1->c.value; + if (rp->t_op==LCON) + r = ((struct lnode *)rp)->ln_lvalue; + else if (rp->t_op==ITOL && ((struct tnode *)rp)->tn_tr1->t_op==CON) { +#define trp ((struct tnode *)rp) + if (trp->tn_tr1->t_type==INT) + r = ((struct cnode *)trp->tn_tr1)->cn_value; else - r = (_UNSIGNED_INT)rp->t.tr1->c.value; + r = (_UNSIGNED_INT)((struct cnode *)trp->tn_tr1)->cn_value; +#undef trp } else return(0); switch (op) { @@ -1099,44 +1220,52 @@ union tree *lconst(op, lp, rp) int op; register union tree *lp; register union t default: return(0); } - if (lp->t.op==LCON) { - lp->l.lvalue = l; - return(lp); + if (lp->t_op==LCON) { +#define llp ((struct lnode *)lp) + llp->ln_lvalue = l; + return(llp); +#undef llp } lp = getblk(sizeof(struct lnode)); - lp->t.op = LCON; - lp->t.type = LONG; - lp->l.lvalue = l; - return(lp); +#define llp ((struct lnode *)lp) + llp->ln_op = LCON; + llp->ln_type = LONG; + llp->ln_lvalue = l; + return(llp); +#undef llp } -void insert(op, tree, list) int op; register union tree *tree; register struct acl *list; { +void insert(op, tree, list) int op; register struct tree *tree; register struct acl *list; { register int d; int d1, i; - union tree *t; + struct tree *t; ins: - if (tree->t.op != op) + if (tree->t_op != op) tree = optim(tree); - if (tree->t.op == op && list->nextn < LSTSIZ-2) { - list->nlist[list->nextn++] = tree; - insert(op, tree->t.tr1, list); - insert(op, tree->t.tr2, list); + if (tree->t_op == op && list->nextn < LSTSIZ-2) { +#define ttree ((struct tnode *)tree) + list->nlist[list->nextn++] = ttree; + insert(op, ttree->tn_tr1, list); + insert(op, ttree->tn_tr2, list); return; +#undef ttree } if (!isfloat(tree)) { /* c1*(x+c2) -> c1*x+c1*c2 */ - if ((tree->t.op==TIMES||tree->t.op==LSHIFT) - && tree->t.tr2->t.op==CON && tree->t.tr2->c.value>0 - && tree->t.tr1->t.op==PLUS && tree->t.tr1->t.tr2->t.op==CON) { - d = tree->t.tr2->c.value; - if (tree->t.op==TIMES) - tree->t.tr2->c.value *= tree->t.tr1->t.tr2->c.value; + if ((tree->t_op==TIMES||tree->t_op==LSHIFT) + && ((struct tnode *)tree)->tn_tr2->t_op==CON && ((struct cnode *)((struct tnode *)tree)->tn_tr2)->cn_value>0 + && ((struct tnode *)tree)->tn_tr1->t_op==PLUS && ((struct tnode *)((struct tnode *)tree)->tn_tr1)->tn_tr2->t_op==CON) { +#define ttree ((struct tnode *)tree) + d = ((struct cnode *)ttree->tn_tr2)->cn_value; + if (ttree->tn_op==TIMES) + ((struct cnode *)ttree->tn_tr2)->cn_value *= ((struct cnode *)((struct tnode *)ttree->tn_tr1)->tn_tr2)->cn_value; else - tree->t.tr2->c.value = tree->t.tr1->t.tr2->c.value << d; - tree->t.tr1->t.tr2->c.value = d; - tree->t.tr1->t.op = tree->t.op; - tree->t.op = PLUS; + ((struct cnode *)ttree->tn_tr2)->cn_value = ((struct cnode *)((struct tnode *)ttree->tn_tr1)->tn_tr2)->cn_value << d; + ((struct cnode *)((struct tnode *)ttree->tn_tr1)->tn_tr2)->cn_value = d; + ((struct tnode *)ttree->tn_tr1)->tn_op = ttree->tn_op; + ttree->tn_op = PLUS; +#undef ttree tree = optim(tree); if (op==PLUS) goto ins; @@ -1154,40 +1283,41 @@ ins: list->llist[list->nextl++] = tree; } -union tree *tnode1(op, type, tr1, tr2) int op; int type; union tree *tr1; union tree *tr2; { - register union tree *p; - - p = getblk(sizeof(struct tnode)); - p->t.op = op; - p->t.type = type; - /* p->t.degree = 0;*/ - p->t.subsp = 0; - p->t.strp = 0; - p->t.tr1 = tr1; - p->t.tr2 = tr2; - p->t.degree = 0; +struct tnode *tnode(op, type, tr1, tr2) int op; int type; struct tree *tr1; struct tree *tr2; { + register struct tnode *p; + + p = (struct tnode *)getblk(sizeof(struct tnode)); + p->tn_op = op; + p->tn_type = type; + p->tn_subsp = (int *)NULL; + p->tn_strp = (union str *)NULL; + p->tn_tr1 = tr1; + p->tn_tr2 = tr2; + p->tn_degree = 0; return(p); } -union tree *tconst(val, type) int val; int type; { - register union tree *p; +struct cnode *tconst(val, type) int val; int type; { + register struct cnode *p; - p = getblk(sizeof(struct cnode)); - p->t.op = CON; - p->t.type = type; - p->c.value = val; + p = (struct cnode *)getblk(sizeof(struct cnode)); + p->cn_op = CON; + p->cn_type = type; + p->cn_subsp = (int *)NULL; + p->cn_strp = (union str *)NULL; + p->cn_value = val; return(p); } -union tree *getblk(size) int size; { +struct tree *getblk(size) int size; { #if 1 - return (union tree *)Tblock(size); + return (struct tree *)Tblock(size); #else - register union tree *p; + register struct tree *p; if (size&01) size++; - p = (union tree *)curbase; + p = (struct tree *)curbase; if ((curbase += size) >= coremax) { #ifdef pdp11 if (sbrk(1024) == (char *)-1) { @@ -1209,35 +1339,39 @@ int islong(t) int t; { return(1); } -union tree *isconstant(t) register union tree *t; { - if (t->t.op==CON || t->t.op==SFCON) +struct tree *isconstant(t) register struct tree *t; { + if (t->t_op==CON || t->t_op==SFCON) return(t); - if (t->t.op==ITOL && t->t.tr1->t.op==CON) - return(t->t.tr1); + if (t->t_op==ITOL && ((struct tnode *)t)->tn_tr1->t_op==CON) + return(((struct tnode *)t)->tn_tr1); return(NULL); } -union tree *hardlongs(t) register union tree *t; { - switch(t->t.op) { +struct tree *hardlongs(t) register struct tree *t; { + switch(t->t_op) { case TIMES: case DIVIDE: case MOD: - if (t->t.type == UNLONG) - t->t.op += ULTIMES-TIMES; +#define tt ((struct tnode *)t) + if (tt->tn_type == UNLONG) + tt->tn_op += ULTIMES-TIMES; else - t->t.op += LTIMES-TIMES; + tt->tn_op += LTIMES-TIMES; break; +#undef tt case ASTIMES: case ASDIV: case ASMOD: - if (t->t.type == UNLONG) - t->t.op += ULASTIMES-ASTIMES; +#define tt ((struct tnode *)t) + if (tt->tn_type == UNLONG) + tt->tn_op += ULASTIMES-ASTIMES; else - t->t.op += LASTIMES-ASTIMES; - t->t.tr1 = tnode1(AMPER, LONG+PTR, t->t.tr1, TNULL); + tt->tn_op += LASTIMES-ASTIMES; + tt->tn_tr1 = (struct tree *)tnode(AMPER, LONG+PTR, tt->tn_tr1, TNULL); break; +#undef tt default: return(t); @@ -1248,10 +1382,10 @@ union tree *hardlongs(t) register union tree *t; { /* * Is tree of unsigned type? */ -int uns(tp) union tree *tp; { +int uns(tp) struct tree *tp; { register int t; - t = tp->t.type; + t = tp->t_type; if (t==UNSIGN || t==UNCHAR || t==UNLONG || t&XTYPE) return(1); return(0); diff --git a/c13.c b/c13.c index aadc709..203ee69 100644 --- a/c13.c +++ b/c13.c @@ -10,6 +10,11 @@ static char sccsid[] = "@(#)c13.c 2.1 (2.11BSD GTE) 10/4/94"; /* * Operator dope table-- see description in c0. */ +/* notes on type safety: */ +/* LEAF=0 implies node is a tnode and tn_tr1 is valid */ +/* CNVRT=1 implies node is a tnode and tn_tr1 is valid */ +/* BINARY=1 implies node is a tnode and tn_tr1, tn_tr2 are valid */ +/* ASSGOP=1 implies node is a tnode and tn_tr1, tn_tr2 are valid */ int opdope1[] = { 000000, /* EOFC (0) */ 000000, /* ; */ diff --git a/ccom.h b/ccom.h index a4fc6ee..d9f1246 100644 --- a/ccom.h +++ b/ccom.h @@ -23,12 +23,14 @@ typedef struct { uint32_t l; uint32_t h; } _DOUBLE; #ifndef NULL #define NULL 0 #endif -#define TNULL (union tree *)NULL +#define TNULL (struct tree *)NULL /* * Structure of namelist */ struct nmlist { + /* note: this must be compatible with struct tree in respect of the */ + /* htype and hsubsp fields, because of length(), rlength() computations */ char hclass; /* storage class */ char hflag; /* various flags */ int htype; /* type */ @@ -71,102 +73,106 @@ struct tdim { /* * Tree node for unary and binary */ +struct tree { + int t_op; + int t_type; + int *t_subsp; /* subscript list for arrays; pass 0 only */ + union str *t_strp; /* structure descr for structs; pass 0 only */ +}; + struct tnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - union tree *tr1; - union tree *tr2; - int degree; /* pass 1 only */ + struct tree tn_tree; +#define tn_op tn_tree.t_op +#define tn_type tn_tree.t_type +#define tn_subsp tn_tree.t_subsp +#define tn_strp tn_tree.t_strp + struct tree *tn_tr1; + struct tree *tn_tr2; + int tn_degree; /* pass 1 only */ }; /* * tree names for locals */ struct nnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - union tree *tr1; /* really struct nmlist pointer; pass 0 only */ - char class; /* pass 1 only */ - char regno; /* pass 1 only */ - int offset; /* pass 1 only */ - int nloc; /* pass 1 only */ + struct tree nn_tree; +#define nn_op nn_tree.t_op +#define nn_type nn_tree.t_type +#define nn_subsp nn_tree.t_subsp +#define nn_strp nn_tree.t_strp + struct nmlist *nn_tr1; /* pass 0 only */ + char nn_class; /* pass 1 only */ + char nn_regno; /* pass 1 only */ + int nn_offset; /* pass 1 only */ + int nn_nloc; /* pass 1 only */ }; /* * tree names for externals */ struct xnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - union tree *tr1; /* really struct nmlist pointer; pass 0 only */ - char class; /* pass 1 only */ - char regno; /* pass 1 only */ - int offset; /* pass 1 only */ - char *name; /* pass 1 only */ + struct tree xn_tree; +#define xn_op xn_tree.t_op +#define xn_type xn_tree.t_type +#define xn_subsp xn_tree.t_subsp +#define xn_strp xn_tree.t_strp + struct nmlist *xn_tr1; /* pass 0 only */ + char xn_class; /* pass 1 only */ + char xn_regno; /* pass 1 only */ + int xn_offset; /* pass 1 only */ + char *xn_name; /* pass 1 only */ }; /* * short constants */ struct cnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - _INT value; + struct tree cn_tree; +#define cn_op cn_tree.t_op +#define cn_type cn_tree.t_type +#define cn_subsp cn_tree.t_subsp +#define cn_strp cn_tree.t_strp + _INT cn_value; }; /* * long constants */ struct lnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - _LONG lvalue; + struct tree ln_tree; +#define ln_op ln_tree.t_op +#define ln_type ln_tree.t_type +#define ln_subsp ln_tree.t_subsp +#define ln_strp ln_tree.t_strp + _LONG ln_lvalue; }; /* * Floating constants */ struct fnode { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - int value; - _DOUBLE fvalue; + struct tree fn_tree; +#define fn_op fn_tree.t_op +#define fn_type fn_tree.t_type +#define fn_subsp fn_tree.t_subsp +#define fn_strp fn_tree.t_strp + int fn_value; + _DOUBLE fn_fvalue; }; /* * Node used for field assignments */ struct fasgn { - int op; - int type; - int *subsp; /* subscript list for arrays; pass 0 only */ - union str *strp; /* structure descr for structs; pass 0 only */ - union tree *tr1; - union tree *tr2; - int degree; /* pass 1 only */ - int mask; -}; - -union tree { - struct tnode t; - struct nnode n; /* pass 1 only */ - struct xnode x; /* pass 1 only */ - struct cnode c; - struct lnode l; - struct fnode f; - struct fasgn F; /* pass 1 only */ + struct tree fa_tree; +#define fa_op fa_tree.t_op +#define fa_type fa_tree.t_type +#define fa_subsp fa_tree.t_subsp +#define fa_strp fa_tree.t_strp + struct tree *fa_tr1; + struct tree *fa_tr2; + int fa_degree; /* pass 1 only */ + int fa_mask; /* pass 1 only */ }; /* diff --git a/fields.sed b/fields.sed new file mode 100644 index 0000000..58966ae --- /dev/null +++ b/fields.sed @@ -0,0 +1,73 @@ +s/@/ATSIGN/g +s/^/@/ +s/$/@/ +s/[^A-Za-z0-9_]\+/@&@/g + +# types +s/@union\(@[ ]*@tree\)@/@struct\1@/g + +# tnode +s/@t@\.@op@/@tn_op@/g +s/@t@\.@type@/@tn_type@/g +s/@t@\.@subsp@/@tn_subsp@/g +s/@t@\.@strp@/@tn_strp@/g +s/@t@\.@tr1@/@tn_tr1@/g +s/@t@\.@tr2@/@tn_tr2@/g +s/@t@\.@degree@/@tn_degree@/g + +# nnode +s/@n@\.@op@/@nn_op@/g +s/@n@\.@type@/@nn_type@/g +s/@n@\.@subsp@/@nn_subsp@/g +s/@n@\.@strp@/@nn_strp@/g +s/@n@\.@tr1@/@nn_tr1@/g +s/@n@\.@class@/@nn_class@/g +s/@n@\.@regno@/@nn_regno@/g +s/@n@\.@offset@/@nn_offset@/g +s/@n@\.@nloc@/@nn_nloc@/g + +# xnode +s/@x@\.@op@/@xn_op@/g +s/@x@\.@type@/@xn_type@/g +s/@x@\.@subsp@/@xn_subsp@/g +s/@x@\.@strp@/@xn_strp@/g +s/@x@\.@tr1@/@xn_tr1@/g +s/@x@\.@class@/@xn_class@/g +s/@x@\.@regno@/@xn_regno@/g +s/@x@\.@offset@/@xn_offset@/g +s/@x@\.@name@/@xn_name@/g + +# cnode +s/@c@\.@op@/@cn_op@/g +s/@c@\.@type@/@cn_type@/g +s/@c@\.@subsp@/@cn_subsp@/g +s/@c@\.@strp@/@cn_strp@/g +s/@c@\.@value@/@cn_value@/g + +# lnode +s/@l@\.@op@/@ln_op@/g +s/@l@\.@type@/@ln_type@/g +s/@l@\.@subsp@/@ln_subsp@/g +s/@l@\.@strp@/@ln_strp@/g +s/@l@\.@lvalue@/@ln_lvalue@/g + +# lnode +s/@f@\.@op@/@fn_op@/g +s/@f@\.@type@/@fn_type@/g +s/@f@\.@subsp@/@fn_subsp@/g +s/@f@\.@strp@/@fn_strp@/g +s/@f@\.@value@/@fn_value@/g +s/@f@\.@fvalue@/@fn_fvalue@/g + +# fasgn +s/@F@\.@op@/@fa_op@/g +s/@F@\.@type@/@fa_type@/g +s/@F@\.@subsp@/@fa_subsp@/g +s/@F@\.@strp@/@fa_strp@/g +s/@F@\.@tr1@/@fa_tr1@/g +s/@F@\.@tr2@/@fa_tr2@/g +s/@F@\.@degree@/@fa_degree@/g +s/@F@\.@mask@/@fa_mask@/g + +s/@//g +s/ATSIGN/@/g -- 2.34.1