/*
* C compiler, part 2
*
- * (long)btodb(l) produced 'no code table error1 for op: >>(17) type: 6'
+ * (long)btodb(l) produced 'no code table error for op: >>(17) type: 6'
* allow both long and ulong at line ~341. 1996/6/19
*/
#include "c1.h"
#ifdef DEBUG
-#define dbprint(op) fprintf(temp_fp[temp_fi], /*printf(*/" / %s", opntab[op])
+#define dbprint(op) fprintf(temp_fp[temp_fi], " / %s", opntab[op])
#else
#define dbprint(op) /* */
#endif
LESSEQ, GREATP, GREATQP, LESSP, LESSEQP
};
-struct tconst czero = { CON, INT, 0};
-struct tconst cone = { CON, INT, 1};
-
-struct tname sfuncr = { NAME, STRUCT, STATIC, 0, 0, 0 };
+struct cnode czero = { { CON, INT, (int *)NULL, (union str *)NULL }, 0};
+struct cnode cone = { { CON, INT, (int *)NULL, (union str *)NULL }, 1};
+struct locnnode sfuncr = { { { NAME, STRUCT, (int *)NULL, (union str *)NULL }, (struct nmlist *)NULL, STATIC/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/ }, 0/*locnn_nloc*/ };
struct table *cregtab;
int nreg = 3;
* pulls in the floating-point part of printf.
*/
if (nfloat)
- fprintf(temp_fp[temp_fi], /*printf(*/".globl fltused\n");
+ fprintf(temp_fp[temp_fi], ".globl fltused\n");
/*
* tack on the string file.
*/
- fprintf(temp_fp[temp_fi], /*printf(*/".globl\n.data\n");
+ fprintf(temp_fp[temp_fi], ".globl\n.data\n");
if (*argv[2] != '-') {
if (freopen(argv[2], "r", stdin)==NULL) {
error1("Missing temp file");
#endif
/*
- * Given a tree1, a code table, and a
+ * Given a tree, a code table, and a
* count of available registers, find the code table
* for the appropriate operator such that the operands
* are of the right type and the number of registers
* required is not too large.
* Return a ptr to the table entry or 0 if none found.
*/
-struct optab *match(tree1, table, nrleft, nocvt) union tree1 *tree1; struct table *table; int nrleft; int nocvt; {
+struct optab *match(tree, table, nrleft, nocvt) struct node *tree; struct table *table; int nrleft; int nocvt; {
#define NOCVL 1
#define NOCVR 2
int op, d1, d2, dope;
- union tree1 *p2;
- register union tree1 *p1;
+ struct node *p2;
+ register struct node *p1;
register struct optab *opt;
- if (tree1==NULL)
+ if (tree==NULL)
return(NULL);
if (table==lsptab)
table = sptab;
- if ((op = tree1->t.op)==0)
+ if ((op = tree->n_op)==0)
return(0);
dope = opdope1[op];
if ((dope&LEAF) == 0)
- p1 = tree1->t.tr1;
+ p1 = ((struct tnode *)tree)->tn_tr1;
else
- p1 = tree1;
+ p1 = tree;
d1 = dcalc(p1, nrleft);
if ((dope&BINARY)!=0) {
- p2 = tree1->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) {
- tree1->t.tr2 = p2->t.tr1;
- if (opt = match(tree1, table, nrleft, NOCVL))
+ if (opdope1[p2->n_op]&CNVRT && (nocvt&NOCVR)==0
+ && (opdope1[((struct tnode *)p2)->tn_tr1->n_op]&CNVRT)==0) {
+ ttree->tn_tr2 = ((struct tnode *)p2)->tn_tr1;
+ if (opt = match((struct node *)ttree, table, nrleft, NOCVL))
return(opt);
- tree1->t.tr2 = p2;
- } else if (opdope1[p1->t.op]&CNVRT && (nocvt&NOCVL)==0
- && (opdope1[p1->t.tr1->t.op]&CNVRT)==0) {
- tree1->t.tr1 = p1->t.tr1;
- if (opt = match(tree1, table, nrleft, NOCVR))
+ ttree->tn_tr2 = p2;
+ } else if (opdope1[p1->n_op]&CNVRT && (nocvt&NOCVL)==0
+ && (opdope1[((struct tnode *)p1)->tn_tr1->n_op]&CNVRT)==0) {
+ ttree->tn_tr1 = ((struct tnode *)p1)->tn_tr1;
+ if (opt = match((struct node *)ttree, table, nrleft, NOCVR))
return(opt);
- tree1->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->n_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->n_op != STAR) )
continue;
if (notcompat(p2,opt->tabtyp2, opt->tabdeg2, 0))
continue;
}
/*
- * Given a tree1, a code table, and a register,
- * produce code to evaluate the tree1 with the appropriate table.
+ * Given a tree, a code table, and a register,
+ * produce code to evaluate the tree with the appropriate table.
* Registers reg and upcan be used.
* If there is a value, it is desired that it appear in reg.
* The routine returns the register in which the value actually appears.
- * This routine must work or there is an error1.
+ * This routine must work or there is an error.
* If the table called for is cctab, sptab, or efftab,
- * and tree1 can't be done using the called-for table,
+ * and tree can't be done using the called-for table,
* another try is made.
- * If the tree1 can't be compiled using cctab, regtab is
+ * If the tree can't be compiled using cctab, regtab is
* used and a "tst" instruction is produced.
- * If the tree1 can't be compiled using sptab,
+ * If the tree can't be compiled using sptab,
* regtab is used and the register is pushed on the stack.
- * If the tree1 can't be compiled using efftab,
+ * If the tree can't be compiled using efftab,
* just use regtab.
- * Regtab must succeed or an "op not found" error1 results.
+ * Regtab must succeed or an "op not found" error results.
*
* A number of special cases are recognized, and
* there is an interaction with the optimizer routines.
*/
-int rcexpr1(atree, atable, reg) union tree1 *atree; struct table *atable; int reg; {
+int rcexpr1(atree, atable, reg) struct node *atree; struct table *atable; int reg; {
register int r;
int modf, nargs, recurf;
- register union tree1 *tree1;
+ register struct node *tree;
register struct table *table;
/*fprintf(stderr, "rcexpr1(0x%08x, 0x%08x, 0x%08x)\n", atree, atable, reg);*/
}
}
again:
- if((tree1=atree)==0)
+ if((tree=atree)==0)
return(0);
- if (tree1->t.type==VOID) {
+ if (tree->n_type==VOID) {
if (table!=efftab)
error1("Illegal use of void");
- tree1->t.type = INT;
+ tree->n_type = INT;
}
- if (opdope1[tree1->t.op]&RELAT && tree1->t.tr2->t.op==CON
- && tree1->t.tr2->c.value==0
+ if (opdope1[tree->n_op]&RELAT && ((struct tnode *)tree)->tn_tr2->n_op==CON
+ && ((struct cnode *)((struct tnode *)tree)->tn_tr2)->cn_value==0
&& table==cctab)
- tree1 = atree = tree1->t.tr1;
+ tree = atree = ((struct tnode *)tree)->tn_tr1;
/*
* fieldselect(...) : in efftab mode,
* ignore the select, otherwise
* do the shift and mask.
*/
- if (tree1->t.op == FSELT) {
+ if (tree->n_op == FSELT) {
if (table==efftab)
- atree = tree1 = tree1->t.tr1;
+ atree = tree = ((struct tnode *)tree)->tn_tr1;
else {
- tree1->t.op = FSEL;
- atree = tree1 = optim(tree1);
+ tree->n_op = FSEL;
+ atree = tree = optim(tree);
}
}
- switch (tree1->t.op) {
+ switch (tree->n_op) {
/*
* Structure assignments
*/
- case STRASG:
- strasg(tree1);
+ /* case STRASG:*/
+ case ASSIGN:
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_type != STRUCT)
+ break;
+ strasg(ttree);
return(0);
+#undef ttree
/*
* An initializing expression
*/
case INIT:
- tree1 = optim(tree1);
- doinit(tree1->t.type, tree1->t.tr1);
+ tree = optim(tree);
+#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:
- tree1 = tree1->t.tr1;
- if((r=rcexpr1(tree1, regtab, reg)) != 0)
- movreg(r, 0, tree1);
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_type == STRUCT) {
+ strasg(ttree);
+ return(0);
+ }
+#undef ttree
+ tree = ((struct tnode *)tree)->tn_tr1;
+ if((r=rcexpr1(tree, regtab, reg)) != 0)
+ movreg(r, 0, tree);
return(0);
/*
* sequential execution
*/
case SEQNC:
- r = nstack;
- rcexpr1(tree1->t.tr1, efftab, reg);
+#define ttree ((struct tnode *)tree)
+ r = nstack;
+ rcexpr1(ttree->tn_tr1, efftab, reg);
nstack = r;
- atree = tree1 = tree1->t.tr2;
+#undef ttree
+ atree = tree = ((struct tnode *)tree)->tn_tr2;
goto again;
/*
* instruction will be produced when cctab is used.
*/
case ANDN:
+#define ttree ((struct tnode *)tree)
if (table==cctab) {
- tree1->t.op = TAND;
- tree1->t.tr2 = optim(tnode1(COMPL, tree1->t.type, tree1->t.tr2, TNULL1));
+ ttree->tn_op = TAND;
+ ttree->tn_tr2 = optim((struct node *)tnode(COMPL, ttree->tn_type, ttree->tn_tr2, (struct node *)NULL));
}
break;
+#undef ttree
/*
* Handle a subroutine call. It has to be done
* stop working. The compiler has been tested in all these
* different cases with the catch commented out and all the
* code generated was correct. So what was it here for?
- * If a strange error1 crops up, uncommenting the catch might
+ * If a strange error crops up, uncommenting the catch might
* be tried ...
*/
- if (tree1->t.tr1->t.op!=NAME || tree1->t.tr1->n.class!=EXTERN) {
+ if (tree->tn_tr1->tn_op!=NAME || tree->tn_tr1->nn_class!=EXTERN) {
nargs++;
nstack++;
}
#endif
- tree1 = tree1->t.tr2;
- if(tree1->t.op) {
- while (tree1->t.op==COMMA) {
- r += comarg(tree1->t.tr2, &modf);
- tree1 = tree1->t.tr1;
+ tree = ((struct tnode *)tree)->tn_tr2;
+ if(tree->n_op) {
+ while (tree->n_op==COMMA) {
+ r += comarg(((struct tnode *)tree)->tn_tr2, &modf);
+ tree = ((struct tnode *)tree)->tn_tr1;
nargs++;
}
- r += comarg(tree1, &modf);
+ r += comarg(tree, &modf);
nargs++;
}
- tree1 = atree;
- tree1->t.op = CALL2;
- if (modf && tree1->t.tr1->t.op==NAME
- && tree1->t.tr1->n.class==EXTERN)
- tree1->t.op = CALL1;
- if (cexpr(tree1, regtab, reg)<0)
+ tree = atree;
+#define ttree ((struct tnode *)tree)
+ ttree->tn_op = CALL2;
+ if (modf && ttree->tn_tr1->n_op==NAME
+ && ((struct nnode *)ttree->tn_tr1)->nn_class==EXTERN)
+ ttree->tn_op = CALL1;
+ if (cexpr((struct node *)ttree, regtab, reg)<0)
error1("compiler botch: call");
popstk(r);
nstack -= nargs;
return(0);
r = 0;
goto fixup;
+#undef ttree
/*
* Longs need special treatment.
*/
case ASULSH: /* 18 */
case ULSH: /* 17 */
- if (tree1->t.type != LONG && tree1->t.type != UNLONG)
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_type != LONG && ttree->tn_type != UNLONG)
break;
- if (tree1->t.tr2->t.op==ITOL)
- tree1->t.tr2 = tree1->t.tr2->t.tr1;
+ if (ttree->tn_tr2->n_op==ITOL)
+ ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1;
else
- tree1->t.tr2 = optim(tnode1(LTOI,INT,tree1->t.tr2,TNULL1));
- if (tree1->t.op==ASULSH)
+ ttree->tn_tr2 = optim((struct node *)tnode(LTOI,INT,ttree->tn_tr2,(struct node *)NULL));
+ if (ttree->tn_op==ASULSH)
{
- tree1->t.op = UASLSHL;
- tree1->t.tr1 = tnode1(AMPER, LONG+PTR, tree1->t.tr1, TNULL1);
+ ttree->tn_op = UASLSHL;
+ ttree->tn_tr1 = (struct node *)tnode(AMPER, LONG+PTR, ttree->tn_tr1, (struct node *)NULL);
}
else
- tree1->t.op = ULLSHIFT;
+ ttree->tn_op = ULLSHIFT;
break;
+#undef ttree
case ASLSH:
case LSHIFT:
- if (tree1->t.type==LONG || tree1->t.type==UNLONG) {
- if (tree1->t.tr2->t.op==ITOL)
- tree1->t.tr2 = tree1->t.tr2->t.tr1;
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_type==LONG || ttree->tn_type==UNLONG) {
+ if (ttree->tn_tr2->n_op==ITOL)
+ ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1;
else
- tree1->t.tr2 = optim(tnode1(LTOI,INT,tree1->t.tr2,TNULL1));
- if (tree1->t.op==ASLSH)
- tree1->t.op = ASLSHL;
+ ttree->tn_tr2 = optim((struct node *)tnode(LTOI,INT,ttree->tn_tr2,(struct node *)NULL));
+ if (ttree->tn_op==ASLSH)
+ ttree->tn_op = ASLSHL;
else
- tree1->t.op = LLSHIFT;
+ ttree->tn_op = LLSHIFT;
}
break;
+#undef ttree
/*
* Try to change * to shift.
*/
case TIMES:
case ASTIMES:
- tree1 = pow2(tree1);
+ tree = (struct node *)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[tree1->t.op]&LEAF)==0) {
+ && (opdope1[tree->n_op]&LEAF)==0) {
if (r=delay(&atree, table, reg)) {
- tree1 = atree;
+ tree = atree;
table = efftab;
reg = r-1;
}
* 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->n_op==NAME)
return(reg);
}
- tree1 = atree;
- if (table==efftab && tree1->t.op==NAME)
+ tree = atree;
+ if (table==efftab && tree->n_op==NAME)
return(reg);
- if ((r=cexpr(tree1, table, reg))>=0) {
- if (table==cregtab && (tree1->t.op==INCAFT
- || tree1->t.op==DECAFT || tree1->t.op==TIMES))
+ if ((r=cexpr(tree, table, reg))>=0) {
+ if (table==cregtab && (tree->n_op==INCAFT
+ || tree->n_op==DECAFT || tree->n_op==TIMES))
goto fixup;
return(r);
}
- if (table!=regtab && (table!=cctab||(opdope1[tree1->t.op]&RELAT)==0)) {
- if((r=cexpr(tree1, regtab, reg))>=0) {
+ if (table!=regtab && (table!=cctab||(opdope1[tree->n_op]&RELAT)==0)) {
+ if((r=cexpr(tree, regtab, reg))>=0) {
fixup:
- modf = isfloat(tree1);
- dbprint(tree1->t.op);
+ modf = isfloat(tree);
+ dbprint(tree->n_op);
if (table==sptab || table==lsptab) {
- if (tree1->t.type==LONG || tree1->t.type==UNLONG){
- fprintf(temp_fp[temp_fi], /*printf(*/"mov\tr%d,-(sp)\n",r+1);
+ if (tree->n_type==LONG || tree->n_type==UNLONG){
+ fprintf(temp_fp[temp_fi], "mov\tr%d,-(sp)\n",r+1);
nstack++;
}
- fprintf(temp_fp[temp_fi], /*printf(*/"mov%s r%d,%s(sp)\n", modf=='f'?"f":"", r,
+ fprintf(temp_fp[temp_fi], "mov%s r%d,%s(sp)\n", modf=='f'?"f":"", r,
table==sptab? "-":"");
nstack++;
}
if (table==cctab || table==cregtab)
- fprintf(temp_fp[temp_fi], /*printf(*/"tst%s r%d\n", modf=='f'?"f":"", r);
+ fprintf(temp_fp[temp_fi], "tst%s r%d\n", modf=='f'?"f":"", r);
return(r);
}
}
/*
* Special grace for unsigned chars as right operands
*/
- if (opdope1[tree1->t.op]&BINARY && tree1->t.tr2->t.type==UNCHAR) {
- tree1->t.tr2 = tnode1(LOAD, UNSIGN, tree1->t.tr2, TNULL1);
- return(rcexpr1(tree1, table, reg));
+ if (opdope1[tree->n_op]&BINARY && ((struct tnode *)tree)->tn_tr2->n_type==UNCHAR) {
+#define ttree ((struct tnode *)tree)
+ ttree->tn_tr2 = (struct node *)tnode(LOAD, UNSIGN, ttree->tn_tr2, (struct node *)NULL);
+ return(rcexpr1((struct node *)ttree, table, reg));
+#undef ttree
}
/*
* There's a last chance for this operator
*/
- if (tree1->t.op==LTOI) {
- r = rcexpr1(tree1->t.tr1, regtab, reg);
+ if (tree->n_op==LTOI) {
+#define ttree ((struct tnode *)tree)
+ r = rcexpr1(ttree->tn_tr1, regtab, reg);
if (r >= 0) {
r++;
goto fixup;
}
+#undef ttree
}
- r = tree1->t.op;
- if (tree1->t.type == STRUCT)
+ r = tree->n_op;
+ if (tree->n_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,
- tree1->t.type);
+ tree->n_type);
else
error1("No code table for op %d", r);
return(reg);
}
/*
- * Try to compile the tree1 with the code table using
+ * Try to compile the tree with the code table using
* registers areg and up. If successful,
* return the register where the value actually ended up.
* If unsuccessful, return -1.
* Most of the work is the macro-expansion of the
* code table.
*/
-int cexpr(tree1, table, areg) register union tree1 *tree1; struct table *table; int areg; {
+int cexpr(tree, table, areg) register struct node *tree; struct table *table; int areg; {
int c, r;
- register union tree1 *p, *p1;
+ register struct node *p, *p1;
struct table *ctable;
- union tree1 *p2;
+ struct node *p2;
char *string;
int reg, reg1, rreg, flag, opd;
struct optab *opt;
reg = areg;
- p1 = tree1->t.tr2;
- c = tree1->t.op;
+ c = tree->n_op;
opd = opdope1[c];
/*
* When the value of a relational or a logical expression is
* desired, more work must be done.
*/
if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {
- cbranch1(tree1, c=isn1++, 1, reg);
- rcexpr1((union tree1 *)&czero, table, reg);
+ cbranch1(tree, c=isn1++, 1, reg);
+ rcexpr1((struct node *)&czero, table, reg);
branch1(isn1, 0, 0);
label1(c);
- rcexpr1((union tree1 *)&cone, table, reg);
+ rcexpr1((struct node *)&cone, table, reg);
label1(isn1++);
return(reg);
}
if(c==QUEST) {
+#define ttree ((struct tnode *)tree)
if (table==cctab)
return(-1);
- cbranch1(tree1->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, tree1->t.tr2);
+ movreg(reg, rreg, ttree->tn_tr2);
label1(r);
return(rreg);
+#undef ttree
}
- reg = oddreg(tree1, reg);
+ reg = oddreg(tree, reg);
reg1 = reg+1;
/*
* long values take 2 registers.
*/
- if ((tree1->t.type==LONG||tree1->t.type==UNLONG||opd&RELAT&&(tree1->t.tr1->t.type==LONG||tree1->t.tr1->t.type==UNLONG))
- && tree1->t.op!=ITOL)
+ if ((tree->n_type==LONG||tree->n_type==UNLONG||opd&RELAT&&(((struct tnode *)tree)->tn_tr1->n_type==LONG||((struct tnode *)tree)->tn_tr1->n_type==UNLONG))
+ && tree->n_op!=ITOL)
reg1++;
/*
- * Leaves of the expression tree1
+ * Leaves of the expression tree
*/
- if ((r = chkleaf(tree1, table, reg)) >= 0)
+ 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 (tree1->t.op==PLUS||tree1->t.op==ASPLUS) {
- if ((p1=tree1->t.tr2)->t.op==CON && p1->c.value==-1) {
- p1->c.value = -p1->c.value;
- tree1->t.op += (MINUS-PLUS);
+ if (ttree->tn_op==PLUS||ttree->tn_op==ASPLUS) {
+ if ((p1=ttree->tn_tr2)->n_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 (tree1->t.tr2 && (tree1->t.tr2->t.op==AUTOI||tree1->t.tr2->t.op==AUTOD)
- && (tree1->t.tr1->t.type==CHAR || tree1->t.tr1->t.type==UNCHAR)
- && tree1->t.tr2->t.type!=CHAR && tree1->t.tr2->t.type!=UNCHAR)
- tree1->t.tr2 = tnode1(LOAD, tree1->t.tr2->t.type, tree1->t.tr2, TNULL1);
+ if (ttree->tn_tr2 && (ttree->tn_tr2->n_op==AUTOI||ttree->tn_tr2->n_op==AUTOD)
+ && (ttree->tn_tr1->n_type==CHAR || ttree->tn_tr1->n_type==UNCHAR)
+ && ttree->tn_tr2->n_type!=CHAR && ttree->tn_tr2->n_type!=UNCHAR)
+ ttree->tn_tr2 = (struct node *)tnode(LOAD, ttree->tn_tr2->n_type, ttree->tn_tr2, (struct node *)NULL);
/*
* Another peculiarity of the PDP11 table manifested itself when
* amplifying the move3: table. The same case which optimizes
* 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 (tree1->t.tr2 && tree1->t.tr1->t.op == NAME
- && tree1->t.tr1->n.class == REG && tree1->t.op == ASSIGN
- && tree1->t.tr2->t.type == UNCHAR)
- tree1->t.tr2 = tnode1(LOAD, UNSIGN, tree1->t.tr2, TNULL1);
+ if (ttree->tn_tr2 && ttree->tn_tr1->n_op == NAME
+ && ((struct nnode *)ttree->tn_tr1)->nn_class == REG && ttree->tn_op == ASSIGN
+ && ttree->tn_tr2->n_type == UNCHAR)
+ ttree->tn_tr2 = (struct node *)tnode(LOAD, UNSIGN, ttree->tn_tr2, (struct node *)NULL);
if (table==cregtab)
table = regtab;
/*
* 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.
*/
* r = nreg - reg - (reg-areg) - (reg1-reg-1);
*/
r = nreg - reg + areg - reg1 + 1;
- if (table!=cctab || c==INCAFT || c==DECAFT || tree1->t.type==LONG || tree1->t.type==UNLONG
-/* || c==ASRSH || c==ASLSH || c==ASULSH || tree1->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(tree1, efftab, r, 0)) == 0)
- if ((opt=match(tree1, table, r, 0))==0)
+ || (opt = match((struct node *)ttree, efftab, r, 0)) == 0)
+ if ((opt=match((struct node *)ttree, table, r, 0))==0)
return(-1);
string = opt->tabstring;
- p1 = tree1->t.tr1;
- if (p1->t.op==FCON && p1->f.value>0) {
-#ifdef pdp11
+ p1 = ttree->tn_tr1;
+ if (p1->n_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], ".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], ".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[tree1->t.op]&BINARY) {
- p2 = tree1->t.tr2;
- if (p2->t.op==FCON && p2->f.value>0) {
+ if (opdope1[ttree->tn_op]&BINARY) {
+ p2 = ttree->tn_tr2;
+ if (p2->n_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], ".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], ".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:
switch (c) {
case '\n':
- dbprint(tree1->t.op);
+ dbprint(ttree->tn_op);
break;
case '\0':
- if (!isfloat(tree1))
- if (tree1->t.op==DIVIDE||tree1->t.op==ASDIV)
+ if (!isfloat((struct node *)ttree))
+ if (ttree->tn_op==DIVIDE||ttree->tn_op==ASDIV)
reg--;
- if (table==regtab && (opdope1[tree1->t.op]&ASSGOP)) {
- if (tree1->t.tr1->t.type==CHAR)
- fprintf(temp_fp[temp_fi], /*printf(*/"movb r%d,r%d\n", reg, reg);
+ if (table==regtab && (opdope1[ttree->tn_op]&ASSGOP)) {
+ if (ttree->tn_tr1->n_type==CHAR)
+ fprintf(temp_fp[temp_fi], "movb r%d,r%d\n", reg, reg);
}
return(reg);
string++;
else
c = 0;
- prins(tree1->t.op, c, instab, 0);
+ prins(ttree->tn_op, c, instab, 0);
goto loop;
/* B1 */
case 'C':
if ((opd&LEAF) != 0)
- p = tree1;
+ p = (struct node *)ttree;
else
p = p1;
goto pbyte;
/* BF */
case 'P':
- p = tree1;
+ p = (struct node *)ttree;
goto pb1;
/* B2 */
case 'D':
p = p2;
pbyte:
- if (p->t.type==CHAR || p->t.type==UNCHAR)
- fputc('b', temp_fp[temp_fi]) /*putchar('b')*/;
+ if (p->n_type==CHAR || p->n_type==UNCHAR)
+ fputc('b', temp_fp[temp_fi]);
pb1:
if (isfloat(p))
- fputc('f', temp_fp[temp_fi]) /*putchar('f')*/;
+ fputc('f', temp_fp[temp_fi]);
goto loop;
/* BE */
case 'L':
- 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 = tree1;
+ if (p1->n_type==CHAR || p2->n_type==CHAR
+ || p1->n_type==UNCHAR || p2->n_type==UNCHAR)
+ fputc('b', temp_fp[temp_fi]);
+ p = (struct node *)ttree;
goto pb1;
/* F */
/* H */
case 'H':
- p = tree1;
+ p = (struct node *)ttree;
flag = 04;
subtre:
if ((c&04)!=0)
ctable = cctab;
if ((flag&01) && ctable==regtab && (c&01)==0
- && ((c&040)||tree1->t.op==DIVIDE||tree1->t.op==MOD
- || tree1->t.op==ASDIV||tree1->t.op==ASMOD||tree1->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->n_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->n_op==STAR)
+ p = ((struct tnode *)p)->tn_tr1;
+ p = ((struct tnode *)p)->tn_tr1;
}
}
if (table==lsptab && ctable==sptab)
if (c&010)
r = reg1;
else
- if (opdope1[p->t.op]&LEAF || p->t.degree < 2)
+ if (opdope1[p->n_op]&LEAF || ((struct tnode *)p)->tn_degree < 2)
r = reg;
else
r = areg;
else
reg1 = rreg;
} else if (rreg!=reg)
- if ((c&020)==0 && oddreg(tree1, 0)==0 && tree1->t.type!=LONG
- && tree1->t.type!=UNLONG
+ if ((c&020)==0 && oddreg((struct node *)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))) {
string++;
r++;
}
- if (r>nreg || r>=4 && tree1->t.type==DOUBLE) {
+ if (r>nreg || r>=4 && ttree->tn_type==DOUBLE) {
if (regpanic)
error1("Register overflow: simplify expression");
else
+ {
+ fprintf(stderr, "warning: register overflow\n");
longjmp(jmpbuf, 1);
+ }
}
- fprintf(temp_fp[temp_fi], /*printf(*/"r%d", r);
+ fprintf(temp_fp[temp_fi], "r%d", r);
goto loop;
case '-': /* check -(sp) */
if (*string=='(') {
nstack++;
if (table!=lsptab)
- fputc('-', temp_fp[temp_fi]) /*putchar('-')*/;
+ fputc('-', temp_fp[temp_fi]);
goto loop;
}
break;
case ')': /* check (sp)+ */
- fputc(')', temp_fp[temp_fi]) /*putchar(')')*/;
+ fputc(')', temp_fp[temp_fi]);
if (*string=='+')
nstack--;
goto loop;
/* #1 */
case '#':
- p = p1->t.tr1;
+ /* previous code was accessing tn_tr1 without a type check */
+ if (opdope1[p1->n_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->n_op] & LEAF) abort();
+ p = ((struct tnode *)p2)->tn_tr1;
nmbr:
if(collcon(p)) {
- if (p->t.op==STAR) {
- fprintf(temp_fp[temp_fi], /*printf(*/"*");
- p = p->t.tr1;
+ if (p->n_op==STAR) {
+ fprintf(temp_fp[temp_fi], "*");
+ 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)->n_op == CON) {
+#define cp ((struct cnode *)p)
+ if (cp->cn_value)
+ psoct(cp->cn_value);
+#undef cp
+ } else if (p->n_op==AMPER)
+ pname(((struct tnode *)p)->tn_tr1, 0);
}
goto loop;
case 'T':
c = reg-1;
if (uns(p1) || uns(p2)) {
- fprintf(temp_fp[temp_fi], /*printf(*/"clr r%d\n", c);
+ fprintf(temp_fp[temp_fi], "clr r%d\n", c);
goto loop;
}
if (dcalc(p1, 5)>12 && !match(p1, cctab, 10, 0))
- fprintf(temp_fp[temp_fi], /*printf(*/"tst r%d\n", reg);
- fprintf(temp_fp[temp_fi], /*printf(*/"sxt r%d\n", c);
+ fprintf(temp_fp[temp_fi], "tst r%d\n", reg);
+ fprintf(temp_fp[temp_fi], "sxt r%d\n", c);
goto loop;
case 'V': /* adc sbc, clr, or sxt as required for longs */
- switch(tree1->t.op) {
+ switch(ttree->tn_op) {
case PLUS:
case ASPLUS:
case INCBEF:
case INCAFT:
- fprintf(temp_fp[temp_fi], /*printf(*/"adc");
+ fprintf(temp_fp[temp_fi], "adc");
break;
case MINUS:
case NEG:
case DECBEF:
case DECAFT:
- fprintf(temp_fp[temp_fi], /*printf(*/"sbc");
+ fprintf(temp_fp[temp_fi], "sbc");
break;
case ASSIGN:
- p = tree1->t.tr2;
+ p = ttree->tn_tr2;
goto lcasev;
case ASDIV:
case ASMOD:
case ASULSH:
- p = tree1->t.tr1;
+ p = ttree->tn_tr1;
lcasev:
- if (p->t.type!=LONG && p->t.type!=UNLONG) {
- if (uns(p) || uns(tree1->t.tr2))
- fprintf(temp_fp[temp_fi], /*printf(*/"clr");
+ if (p->n_type!=LONG && p->n_type!=UNLONG) {
+ if (uns(p) || uns(ttree->tn_tr2))
+ fprintf(temp_fp[temp_fi], "clr");
else
- fprintf(temp_fp[temp_fi], /*printf(*/"sxt");
+ fprintf(temp_fp[temp_fi], "sxt");
goto loop;
}
default:
+ /* no conversion needed, skip to end of line */
while ((c = *string++)!='\n' && c!='\0');
break;
}
* Mask used in field assignments
*/
case 'Z':
- fprintf(temp_fp[temp_fi], /*printf(*/"$%o", UNS(tree1->F.mask));
+ /* previous code was accessing fa_mask without a type check */
+ if (ttree->tn_op != FSELA) abort();
+ fprintf(temp_fp[temp_fi], "$%o", UNS(((struct fasgn *)ttree)->fa_mask));
goto loop;
/*
return(reg);
goto loop;
}
- fputc(c, temp_fp[temp_fi]) /*putchar(c)*/;
+ fputc(c, temp_fp[temp_fi]);
goto loop;
+#undef ttree
}
/*
* This routine just calls sreorder (below)
- * on the subtrees and then on the tree1 itself.
+ * on the subtrees and then on the tree itself.
* It returns non-zero if anything changed.
*/
-int reorder(treep, table, reg) union tree1 **treep; struct table *table; int reg; {
+int reorder(treep, table, reg) struct node **treep; struct table *table; int reg; {
register int r, o;
- register union tree1 *p;
+ register struct node *p;
p = *treep;
- o = p->t.op;
+ o = p->n_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)
r++;
*treep = optim(*treep);
return(r);
+#undef tp
}
/*
* Basically this routine carries out two kinds of optimization.
* First, it observes that "x + (reg = y)" where actually
* the = is any assignment op is better done as "reg=y; x+reg".
- * In this case rcexpr1 is called to do the first part and the
- * tree1 is modified so the name of the register
+ * In this case rcexpr is called to do the first part and the
+ * tree is modified so the name of the register
* replaces the assignment.
* 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 tree1 **treep; struct table *table; int reg; int recurf; {
- register union tree1 *p, *p1;
+int sreorder(treep, table, reg, recurf) struct node **treep; struct table *table; int reg; int recurf; {
+ register struct node *p, *p1;
p = *treep;
- if (opdope1[p->t.op]&LEAF)
+ if (opdope1[p->n_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)==TNULL1)
+#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 node *)tp);
+ if (opdope1[p->n_op] & LEAF) abort();
+ }
+ if ((p1 = tp->tn_tr1)==(struct node *)NULL)
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 node *)tp);
+ if (opdope1[p->n_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->n_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->n_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 node *)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;
+ /* here tp->tn_tr1 (former p1) is a locnnode of class REG, checked above */
+ /* XXX formerly nn_class was not checked in the below, so random values of */
+ /* nloc/name could (rarely) have caused the optimization not to be applied */
+ if (xdcalc(p1, 16) > 12
+ || p1->n_op==NAME
+ &&(((struct nnode *)p1)->nn_class == REG && ((struct locnnode *)p1)->locnn_nloc==((struct locnnode *)tp->tn_tr1)->locnn_nloc
+ || (((struct nnode *)p1)->nn_class == OFFS || ((struct nnode *)p1)->nn_class == SOFFS || ((struct nnode *)p1)->nn_class == XOFFS) && ((struct nnode *)p1)->nn_regno==((struct locnnode *)tp->tn_tr1)->locnn_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->n_op!=NAME
+ || ((struct nnode *)tp1->tn_tr1)->nn_class!=REG
+ || ((struct locnnode *)tp1->tn_tr1)->locnn_nloc!=((struct locnnode *)tp->tn_tr1)->locnn_nloc)
+ rcexpr1((struct node *)tp, efftab, reg);
+ tp->tn_tr2 = tp1->tn_tr2;
+ tp->tn_op = tp1->tn_op + ASPLUS - PLUS;
+ *treep = (struct node *)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 node *)tp), efftab, ~reg);
+ *treep = p1;
+ return(1);
}
return(0);
+#undef tp
}
/*
* It observes that "x + y++" is better
* treated as "x + y; y++".
* If the operator is ++ or -- itself,
- * it calls rcexpr1 to load the operand, letting
- * the calling instance of rcexpr1 to do the
+ * it calls rcexpr to load the operand, letting
+ * the calling instance of rcexpr to do the
* ++ using efftab.
* Otherwise it uses sdelay to search for inc/dec
* among the operands.
*/
-int delay(treep, table, reg) union tree1 **treep; struct table *table; int reg; {
- register union tree1 *p, *p1;
+int delay(treep, table, reg) struct node **treep; struct table *table; int reg; {
+ register struct tnode *p;
+ register struct node *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->n_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->n_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 node *)p), table, reg);
*treep = p1;
return(r+1);
}
return(0);
}
-union tree1 *sdelay(ap) union tree1 **ap; {
- register union tree1 *p, *p1;
+struct node *sdelay(ap) struct node **ap; {
+ register struct node *p, *p1;
- if ((p = *ap)==TNULL1)
- return(TNULL1);
- 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 = *ap)==(struct node *)NULL)
+ return((struct node *)NULL);
+ if ((p->n_op==INCAFT||p->n_op==DECAFT) && ((struct tnode *)p)->tn_tr1->n_op==NAME) {
+#define tp ((struct tnode *)p)
+ *ap = paint((struct node *)ncopy((struct nnode *)tp->tn_tr1), tp->tn_type);
+ return((struct node *)tp);
+#undef tp
}
- if (p->t.op==STAR || p->t.op==PLUS)
- if (p1=sdelay(&p->t.tr1))
+ if (p->n_op==STAR || p->n_op==PLUS)
+ if (p1=sdelay(&((struct tnode *)p)->tn_tr1))
return(p1);
- if (p->t.op==PLUS)
- return(sdelay(&p->t.tr2));
+ if (p->n_op==PLUS)
+ return(sdelay(&((struct tnode *)p)->tn_tr2));
return(0);
}
/*
* Propagate possible implicit type-changing operation
*/
-union tree1 *paint(tp, type) register union tree1 *tp; register int type; {
+struct node *paint(tp, type) register struct node *tp; register int type; {
- if (tp->t.type==type)
+ if (tp->n_type==type)
return(tp);
- if (tp->t.type==CHAR && type==INT)
+ if (tp->n_type==CHAR && type==INT)
return(tp);
- if (tp->t.type==CHAR || tp->t.type==UNCHAR)
- return(optim(tnode1(LOAD, type, tp, TNULL1)));
- 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->n_type==CHAR || tp->n_type==UNCHAR)
+ return(optim((struct node *)tnode(LOAD, type, tp, (struct node *)NULL)));
+ tp->n_type = type;
+ if (tp->n_op==AMPER && type&XTYPE)
+#define ttp ((struct tnode *)tp)
+ ttp->tn_tr1 = paint(ttp->tn_tr1, decref1(type));
+#undef ttp
+ else if (tp->n_op==STAR)
+#define ttp ((struct tnode *)tp)
+ ttp->tn_tr1 = paint(ttp->tn_tr1, incref1(type));
+#undef ttp
+ else if (tp->n_op==ASSIGN) {
+#define ttp ((struct tnode *)tp)
+ /* previous code was not saving back return value from paint() ??? */
+ struct node *temp =
+ paint(ttp->tn_tr1, type);
+ if (temp != ttp->tn_tr1) fprintf(stderr, "warning: possible paint() issue\n");
+ temp =
+ paint(ttp->tn_tr2, type);
+ if (temp != ttp->tn_tr2) fprintf(stderr, "warning: possible paint() issue\n");
+#undef ttp
}
return(tp);
}
/*
- * Copy a tree1 node for a register variable.
+ * Copy a tree node for a register variable.
* Used by sdelay because if *reg-- is turned
* into *reg; reg-- the *reg will in turn
* be changed to some offset class, accidentally
* modifying the reg--.
*/
-union tree1 *ncopy(p) register union tree1 *p; {
- register union tree1 *q;
-
- q = getblk(sizeof(struct xtname));
- 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 extp ((struct extnnode *)p)
+#define extq (*(struct extnnode **)&q)
+ extq = (struct extnnode *)getblk(sizeof(struct extnnode));
+ extq->extnn_name = extp->extnn_name;
+#undef extp
+#undef extq
+ }
+ else {
+#define locp ((struct locnnode *)p)
+#define locq (*(struct locnnode **)&q)
+ locq = (struct locnnode *)getblk(sizeof(struct locnnode));
+ locq->locnn_nloc = locp->locnn_nloc;
+#undef locp
+#undef locq
+ }
+ 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);
}
/*
- * If the tree1 can be immediately loaded into a register,
+ * If the tree can be immediately loaded into a register,
* produce code to do so and return success.
*/
-int chkleaf(tree1, table, reg) register union tree1 *tree1; struct table *table; int reg; {
- struct tnode1 lbuf;
+int chkleaf(tree, table, reg) register struct node *tree; struct table *table; int reg; {
+ struct tnode lbuf;
- /*fprintf(stderr, "chkleaf(0x%08x, 0x%08x, 0x%08x)\n", tree1, table, reg);*/
- if (tree1->t.op!=STAR && dcalc(tree1, nreg-reg) > 12)
+ if (tree->n_op!=STAR && dcalc(tree, nreg-reg) > 12)
return(-1);
- lbuf.op = LOAD;
- lbuf.type = tree1->t.type;
- lbuf.degree = tree1->t.degree;
- lbuf.tr1 = tree1;
-#if 1 /* can't have garbage in lbuf.tr2, cexpr() will deref it if non-NULL */
- lbuf.tr2 = NULL;
-#endif
- return(rcexpr1((union tree1 *)&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 = (struct node *)NULL;
+ return(rcexpr1((struct node *)&lbuf, table, reg));
}
/*
* Return the number of bytes pushed,
* for future popping.
*/
-int comarg(tree1, flagp) register union tree1 *tree1; int *flagp; {
+int comarg(tree, flagp) register struct node *tree; int *flagp; {
register int retval;
int i;
int size;
- if (tree1->t.op==STRASG) {
- size = tree1->F.mask;
- tree1 = tree1->t.tr1;
- tree1 = strfunc(tree1);
+ if (/*tree->n_op==STRASG*/tree->n_type==STRUCT) {
+ /* size = tree->fa_mask;
+ tree = tree->tn_tr1;*/
+ size = tree->n_strp->S.ssize;
+ tree = strfunc(tree);
if (size <= sizeof(_INT)) {
- paint(tree1, INT);
+ paint(tree, INT);
goto normal;
}
if (size <= sizeof(_LONG)) {
- paint(tree1, LONG);
+ paint(tree, LONG);
goto normal;
}
- if (tree1->t.op!=NAME && tree1->t.op!=STAR) {
+ if (tree->n_op!=NAME && tree->n_op!=STAR) {
error1("Unimplemented structure assignment");
return(0);
}
- tree1 = tnode1(AMPER, STRUCT+PTR, tree1, TNULL1);
- tree1 = tnode1(PLUS, STRUCT+PTR, tree1, tconst(size, INT));
- tree1 = optim(tree1);
- retval = rcexpr1(tree1, regtab, 0);
+ tree = (struct node *)tnode(AMPER, STRUCT+PTR, tree, (struct node *)NULL);
+ tree = (struct node *)tnode(PLUS, STRUCT+PTR, tree, (struct node *)tconst(size, INT));
+ tree = optim(tree);
+ retval = rcexpr1(tree, regtab, 0);
size >>= 1;
if (size <= 5) {
for (i=0; i<size; i++)
- fprintf(temp_fp[temp_fi], /*printf(*/"mov -(r%d),-(sp)\n", retval);
+ fprintf(temp_fp[temp_fi], "mov -(r%d),-(sp)\n", retval);
} else {
if (retval!=0)
- fprintf(temp_fp[temp_fi], /*printf(*/"mov r%d,r0\n", retval);
- fprintf(temp_fp[temp_fi], /*printf(*/"mov $%o,r1\n", UNS(size));
- fprintf(temp_fp[temp_fi], /*printf(*/"L%d:mov -(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn1, isn1);
+ fprintf(temp_fp[temp_fi], "mov r%d,r0\n", retval);
+ fprintf(temp_fp[temp_fi], "mov $%o,r1\n", UNS(size));
+ fprintf(temp_fp[temp_fi], "L%d:mov -(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn1, isn1);
isn1++;
}
nstack++;
return(size*2);
}
normal:
- if (nstack || isfloat(tree1) || tree1->t.type==LONG || tree1->t.type==UNLONG) {
- rcexpr1(tree1, sptab, 0);
- retval = arlength(tree1->t.type);
+ if (nstack || isfloat(tree) || tree->n_type==LONG || tree->n_type==UNLONG) {
+ rcexpr1(tree, sptab, 0);
+ retval = arlength(tree->n_type);
} else {
(*flagp)++;
- rcexpr1(tree1, lsptab, 0);
+ rcexpr1(tree, lsptab, 0);
retval = 0;
}
return(retval);
}
-union tree1 *strfunc(tp) register union tree1 *tp; {
- if (tp->t.op != CALL)
+struct node *strfunc(tp) register struct node *tp; {
+ if (tp->n_op != CALL)
return(tp);
paint(tp, STRUCT+PTR);
- return(tnode1(STAR, STRUCT, tp, TNULL1));
+ return((struct node *)tnode(STAR, STRUCT, tp, (struct node *)NULL));
}
/*
* Compile an initializing expression
*/
-void doinit(type, tree1) register int type; register union tree1 *tree1; {
+void doinit(type, tree) register int type; register struct node *tree; {
_FLOAT sfval;
_DOUBLE fval;
_LONG lval;
if (type==CHAR || type==UNCHAR) {
- fprintf(temp_fp[temp_fi], /*printf(*/".byte ");
- if (tree1->t.type&XTYPE)
+ fprintf(temp_fp[temp_fi], ".byte ");
+ if (tree->n_type&XTYPE)
goto illinit;
type = INT;
}
switch (type) {
case INT:
case UNSIGN:
- if (tree1->t.op==FTOI) {
- if (tree1->t.tr1->t.op!=FCON && tree1->t.tr1->t.op!=SFCON)
+ if (tree->n_op==FTOI) {
+ if (((struct tnode *)tree)->tn_tr1->n_op!=FCON && ((struct tnode *)tree)->tn_tr1->n_op!=SFCON)
goto illinit;
- tree1 = tree1->t.tr1;
+ tree = ((struct tnode *)tree)->tn_tr1;
+ fval = ((struct fnode *)tree)->fn_fvalue;
+ ((struct cnode *)tree)->cn_op = CON;
#ifdef pdp11
- tree1->c.value = tree1->f.fvalue;
+ ((struct cnode *)tree)->cn_value = fval;
#else
- tree1->c.value = fp_double_to_int(tree1->f.fvalue);
+ ((struct cnode *)tree)->cn_value = fp_double_to_int(fval);
#endif
- tree1->t.op = CON;
- } else if (tree1->t.op==LTOI) {
- if (tree1->t.tr1->t.op!=LCON)
+ } else if (tree->n_op==LTOI) {
+ if (((struct tnode *)tree)->tn_tr1->n_op!=LCON)
goto illinit;
- tree1 = tree1->t.tr1;
- lval = tree1->l.lvalue;
- tree1->t.op = CON;
- tree1->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 (tree1->t.op == CON)
- fprintf(temp_fp[temp_fi], /*printf(*/"%o\n", UNS(tree1->c.value));
- else if (tree1->t.op==AMPER) {
- pname(tree1->t.tr1, 0);
+ if (tree->n_op == CON)
+ fprintf(temp_fp[temp_fi], "%o\n", UNS(((struct cnode *)tree)->cn_value));
+ else if (tree->n_op==AMPER) {
+ pname(((struct tnode *)tree)->tn_tr1, 0);
fputc('\n', temp_fp[temp_fi]) /*putchar('\n')*/;
} else
goto illinit;
case DOUBLE:
case FLOAT:
- if (tree1->t.op==ITOF) {
- if (tree1->t.tr1->t.op==CON) {
+ if (tree->n_op==ITOF) {
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_tr1->n_op==CON) {
/* note: this should be changed to respect the signedness of the int */
#ifdef pdp11
- fval = tree1->t.tr1->c.value;
+ fval = ((struct cnode *)ttree->tn_tr1)->cn_value;
#else
- fval = fp_int_to_double(tree1->t.tr1->c.value);
+ fval = fp_int_to_double(((struct cnode *)ttree->tn_tr1)->cn_value);
#endif
} else
goto illinit;
- } else if (tree1->t.op==FCON || tree1->t.op==SFCON) {
- fval = tree1->f.fvalue;
- } else if (tree1->t.op==LTOF) {
- if (tree1->t.tr1->t.op!=LCON)
+#undef ttree
+ } else if (tree->n_op==FCON || tree->n_op==SFCON) {
+ fval = ((struct fnode *)tree)->fn_fvalue;
+ } else if (tree->n_op==LTOF) {
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_tr1->n_op!=LCON)
goto illinit;
/* note: this should be changed to respect the signedness of the long */
#ifdef pdp11
- fval = tree1->t.tr1->l.lvalue;
+ fval = ((struct lnode *)ttree->tn_tr1)->ln_lvalue;
#else
- fval = fp_long_to_double(tree1->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;
/*nonportable*/
- fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n",
+ fprintf(temp_fp[temp_fi], "%o; %o\n",
((_UNSIGNED_INT *)&sfval)[0],
((_UNSIGNED_INT *)&sfval)[1]);
#else
sfval = fp_double_to_float(fval);
- fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n",
+ fprintf(temp_fp[temp_fi], "%o; %o\n",
(int)(sfval.h >> 16) & 0xffff,
(int)sfval.h & 0xffff);
#endif
} else {
#ifdef pdp11
/* nonportable */
- fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o; %o; %o\n",
+ fprintf(temp_fp[temp_fi], "%o; %o; %o; %o\n",
((_UNSIGNED_INT *)&fval)[0],
((_UNSIGNED_INT *)&fval)[1],
((_UNSIGNED_INT *)&fval)[2],
((_UNSIGNED_INT *)&fval)[3]);
#else
- fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o; %o; %o\n",
+ fprintf(temp_fp[temp_fi], "%o; %o; %o; %o\n",
(int)(fval.h >> 16) & 0xffff,
(int)fval.h & 0xffff,
(int)(fval.l >> 16) & 0xffff,
case UNLONG:
case LONG:
- if (tree1->t.op==FTOL) {
- tree1 = tree1->t.tr1;
- if (tree1->t.op==SFCON)
- tree1->t.op = FCON;
- if (tree1->t.op!= FCON)
+ if (tree->n_op==FTOL) {
+ tree = ((struct tnode *)tree)->tn_tr1;
+ if (tree->n_op==SFCON)
+ tree->n_op = FCON;
+ if (tree->n_op!= FCON)
goto illinit;
#ifdef pdp11
- lval = tree1->f.fvalue;
+ lval = ((struct fnode *)tree)->fn_fvalue;
#else
- lval = fp_double_to_long(tree1->f.fvalue);
+ lval = fp_double_to_long(((struct fnode *)tree)->fn_fvalue);
#endif
- } else if (tree1->t.op==ITOL) {
- if (tree1->t.tr1->t.op != CON)
+ } else if (tree->n_op==ITOL) {
+#define ttree ((struct tnode *)tree)
+ if (ttree->tn_tr1->n_op != CON)
goto illinit;
- if (uns(tree1->t.tr1))
- lval = (_UNSIGNED_INT)tree1->t.tr1->c.value;
+ if (uns(ttree->tn_tr1))
+ lval = (_UNSIGNED_INT)((struct cnode *)ttree->tn_tr1)->cn_value;
else
- lval = tree1->t.tr1->c.value;
- } else if (tree1->t.op==LCON) {
- lval = tree1->l.lvalue;
+ lval = ((struct cnode *)ttree->tn_tr1)->cn_value;
+#undef ttree
+ } else if (tree->n_op==LCON) {
+ lval = ((struct lnode *)tree)->ln_lvalue;
} else
goto illinit;
/* nonportable */
- fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n", UNS((lval>>16)), UNS(lval));
+ fprintf(temp_fp[temp_fi], "%o; %o\n", UNS((lval>>16)), UNS(lval));
return;
}
illinit:
error1("Illegal initialization");
}
-void movreg(r0, r1, tree1) int r0; int r1; union tree1 *tree1; {
+void movreg(r0, r1, tree) int r0; int r1; struct node *tree; {
register char *s;
char c;
if (r0==r1)
return;
- if (tree1->t.type==LONG || tree1->t.type == UNLONG) {
+ if (tree->n_type==LONG || tree->n_type == UNLONG) {
if (r0>=nreg || r1>=nreg) {
- error1("register overflow: compiler error1");
+ error1("register overflow: compiler error");
}
s = "mov r%d,r%d\nmov r%d,r%d\n";
if (r0 < r1)
- fprintf(temp_fp[temp_fi], /*printf(*/s, r0+1,r1+1,r0,r1);
+ fprintf(temp_fp[temp_fi], s, r0+1,r1+1,r0,r1);
else
- fprintf(temp_fp[temp_fi], /*printf(*/s, r0,r1,r0+1,r1+1);
+ fprintf(temp_fp[temp_fi], s, r0,r1,r0+1,r1+1);
return;
}
- c = isfloat(tree1);
- fprintf(temp_fp[temp_fi], /*printf(*/"mov%.1s r%d,r%d\n", &c, r0, r1);
+ c = isfloat(tree);
+ fprintf(temp_fp[temp_fi], "mov%.1s r%d,r%d\n", &c, r0, r1);
}