10 #define _va_start(argp, arg) va_start(argp, arg)
13 #define _va_start(argp, arg) va_start(argp)
15 #include "c0.h" /* for outcode() prototype as getree() changed to outcode() */
18 /*static void outname __P((char *s));*/
19 static void outname __P((char *buf, char *str));
21 int degree(t) register struct node *t; {
22 register struct node *t1;
24 if (t==NULL || t->n_op==0)
31 /* assume isconstant() does not return an SFCON since it's ITOL not FTOL */
32 if ((t1 = (struct node *)isconstant(t)) && (((struct cnode *)t1)->cn_value>=0 || uns(t1)))
34 if (uns(t1 = ((struct tnode *)t)->tn_tr1) && opdope1[t1->n_op]&LEAF)
37 if ((opdope1[t->n_op] & LEAF) != 0) {
38 if (t->n_type==CHAR || t->n_type==UNCHAR || t->n_type==FLOAT)
42 return(((struct tnode *)t)->tn_degree);
45 void pname(p, flag) register struct node *p; int flag; {
49 /*fprintf(stderr, "pname %p\n", p);*/
53 #define lp ((struct lnode *)p)
54 fprintf(temp_fp[temp_fi], "$%o", flag<=10? UNS(lp->ln_lvalue>>16):
61 #define cp ((struct cnode *)p)
62 fprintf(temp_fp[temp_fi], "$");
68 #define fp ((struct fnode *)p)
69 fprintf(temp_fp[temp_fi], "L%d", (fp->fn_value>0? fp->fn_value: -fp->fn_value));
74 #define np ((struct nnode *)p)
75 /*fprintf(stderr, "nn_class %d\n", np->nn_class);*/
81 if (np->nn_class!=OFFS)
82 fputc('+', temp_fp[temp_fi]);
83 if (np->nn_class==REG)
84 error1("Illegal use of register");
86 switch(np->nn_class) {
89 #define locnp ((struct locnnode *)np)
90 fprintf(temp_fp[temp_fi], "L%d(r%d)", locnp->locnn_nloc, locnp->locnn_regno);
95 #define extnp ((struct extnnode *)np)
96 fprintf(temp_fp[temp_fi], "%s(r%d)", extnp->extnn_name, extnp->extnn_regno);
101 /* considered to be a locnnode even though locnn_nloc is wasted space */
102 #define locnp ((struct locnnode *)np)
103 fprintf(temp_fp[temp_fi], "(r%d)", locnp->locnn_regno);
108 #define extnp ((struct extnnode *)np)
109 fprintf(temp_fp[temp_fi], "%s", extnp->extnn_name);
114 #define locnp ((struct locnnode *)np)
115 fprintf(temp_fp[temp_fi], "L%d", locnp->locnn_nloc);
120 #define locnp ((struct locnnode *)np)
121 fprintf(temp_fp[temp_fi], "r%d", locnp->locnn_nloc);
126 error1("Compiler error: pname");
134 fputc('$', temp_fp[temp_fi]);
135 p = ((struct tnode *)p)->tn_tr1;
136 if (p->n_op==NAME && ((struct nnode *)p)->nn_class==REG)
137 error1("Illegal use of register");
141 #define locnp ((struct locnnode *)p)
142 fprintf(temp_fp[temp_fi], "(r%d)%s", locnp->locnn_nloc, flag==1?"":"+");
147 #define locnp ((struct locnnode *)p)
148 fprintf(temp_fp[temp_fi], "%s(r%d)", flag==2?"":"-", locnp->locnn_nloc);
153 p = ((struct tnode *)p)->tn_tr1;
154 fputc('*', temp_fp[temp_fi]);
158 error1("compiler error: bad pname");
161 int xdcalc(p, nrleft) register struct node *p; int nrleft; {
166 d = dcalc(p, nrleft);
167 if (d<20 && (p->n_type==CHAR || p->n_type==UNCHAR)) {
176 /* if dcalc() returns 0 then either p == NULL or p is a struct tnode */
177 int dcalc(p, nrleft) register struct node *p; int nrleft; {
178 register struct node *p1;
185 #define np ((struct nnode *)p)
186 if (np->nn_class==REG && np->nn_type!=CHAR && np->nn_type!=UNCHAR)
199 #define cp ((struct cnode *)p)
204 if (cp->cn_value > 0)
210 #define tp ((struct tnode *)p)
212 if (p1->n_op==NAME||p1->n_op==CON||p1->n_op==AUTOI||p1->n_op==AUTOD)
213 if (tp->tn_type!=LONG && tp->tn_type!=UNLONG)
218 /* above should have eliminated all of the leaf cases */
219 if (opdope1[p->n_op] & LEAF) abort();
220 #define tp ((struct tnode *)p)
221 if (tp->tn_type==LONG || tp->tn_type==UNLONG)
223 return(tp->tn_degree <= nrleft? 20: 24);
227 int notcompat(p, ast, deg, op) register struct node *p; int ast; int deg; int op; {
228 unsigned register at, st;
232 * an e or n UNCHAR is to be considered an UNSIGNED,
233 * as long as it is not pointed to.
235 if (at==UNCHAR && deg<0100 && deg>=20)
238 if (st==0) /* word, byte */
239 return(at!=CHAR && at!=INT && at!=UNSIGN && at<PTR);
240 if (st==1) /* word */
241 return(at!=INT && at!=UNSIGN && at<PTR);
242 if (st==9 && (at&XTYPE))
245 if ((at&(~(TYPE+XTYPE))) != 0)
247 if ((at&(~TYPE)) != 0)
249 if (st==FLOAT && at==DOUBLE)
251 if (p->n_op==NAME && ((struct nnode *)p)->nn_class==REG && op==ASSIGN && st==CHAR)
256 int prins(op, c, itable, lbl) int op; int c; struct instab *itable; int lbl; {
257 register struct instab *insp;
262 for (insp = itable; insp->iop != 0; insp++) {
263 if (insp->iop == op) {
264 ip = c ? insp->str2: insp->str1;
268 fprintf(temp_fp[temp_fi], ip, lbl);
272 fprintf(temp_fp[temp_fi], ip, skip);
277 error1("No match' for op %d", op);
281 int collcon(p) register struct node *p; {
287 if (p->n_type==LONG+PTR || p->n_type==UNLONG+PTR) /* avoid *x(r); *x+2(r) */
289 p = ((struct tnode *)p)->tn_tr1;
292 op = ((struct tnode *)p)->tn_tr2->n_op;
293 if (op==CON || op==AMPER)
299 int isfloat(t) register struct node *t; {
301 if ((opdope1[t->n_op]&RELAT)!=0)
302 t = ((struct tnode *)t)->tn_tr1;
303 if (t->n_type==FLOAT || t->n_type==DOUBLE) {
310 int oddreg(t, reg) register struct node *t; register int reg; {
313 if (opdope1[t->n_op]&RELAT) {
314 #define tt ((struct tnode *)t)
315 if (tt->tn_tr1->n_type==LONG || tt->tn_tr1->n_type==UNLONG)
316 return((reg+1) & ~01);
344 int arlength(t) int t; {
363 error1("botch: peculiar type %d", t);
368 * Strings for switch code.
372 * Modified Memorial day May 80 to uniquely identify switch tables
373 * (as on Vax) so a shell script can optionally include them in RO code.
374 * This is useful in overlays to reduce the size of data space load.
397 * If the unsigned casts below won't compile,
398 * try using the calls to lrem and ldiv.
401 void pswitch1(afp, alp, deflab) struct swtab *afp; struct swtab *alp; int deflab; {
402 int ncase, i, j, tabs, worst, best, range;
403 register struct swtab *swp, *fp, *lp;
409 fprintf(temp_fp[temp_fi], "jbr L%d\n", deflab);
417 range = lp->swval - fp->swval;
419 if (range>0 && range <= 3*ncase) {
421 fprintf(temp_fp[temp_fi], "sub $%o,r0\n", UNS(fp->swval));
422 fprintf(temp_fp[temp_fi], dirsw, UNS(range), deflab, isn1, isn1);
424 for (i=fp->swval; ; i++) {
426 fprintf(temp_fp[temp_fi], "L%d\n", fp->swlab);
431 fprintf(temp_fp[temp_fi], "L%d\n", deflab);
433 fprintf(temp_fp[temp_fi], ".text\n");
438 for (fp = afp; fp<=lp; fp++)
439 breq(fp->swval, fp->swlab);
440 fprintf(temp_fp[temp_fi], "jbr L%d\n", deflab);
445 poctab = (int *)getblk(((ncase+2)/2) * sizeof(*poctab));
446 for (i=ncase/4; i<=ncase/2; i++) {
449 for (swp=fp; swp<=lp; swp++)
450 /* lrem(0, swp->swval, i) */
451 poctab[(_UNSIGNED_INT)swp->swval%i]++;
456 if (i*worst < best) {
462 fprintf(temp_fp[temp_fi], hashsw, UNS(tabs), i, i);
464 for (i=0; i<tabs; i++)
465 fprintf(temp_fp[temp_fi], "L%d\n", isn1+i);
466 fprintf(temp_fp[temp_fi], ".text\n");
467 for (i=0; i<tabs; i++) {
468 fprintf(temp_fp[temp_fi], "L%d:", isn1++);
469 for (swp=fp; swp<=lp; swp++) {
470 /* lrem(0, swp->swval, tabs) */
471 if ((_UNSIGNED_INT)swp->swval%tabs == i) {
472 /* ldiv(0, swp->swval, tabs) */
473 breq((int)((_UNSIGNED_INT)swp->swval/tabs), swp->swlab);
476 fprintf(temp_fp[temp_fi], "jbr L%d\n", deflab);
480 void breq(v, l) int v; int l; {
482 fprintf(temp_fp[temp_fi], "tst r0\n");
484 fprintf(temp_fp[temp_fi], "cmp r0,$%o\n", UNS(v));
485 fprintf(temp_fp[temp_fi], "jeq L%d\n", l);
488 int sort(afp, alp) struct swtab *afp; struct swtab *alp; {
489 register struct swtab *cp, *fp, *lp;
496 for (cp=fp; cp<lp; cp++) {
497 if (cp->swval == cp[1].swval) {
498 error1("Duplicate case (%d)", cp->swval);
501 if (cp->swval > cp[1].swval) {
504 cp->swval = cp[1].swval;
507 cp->swlab = cp[1].swlab;
517 int ispow2(tree) register struct tnode *tree; {
520 if (!isfloat((struct node *)tree) && tree->tn_tr2->n_op==CON) {
521 d = ((struct cnode *)tree->tn_tr2)->cn_value;
522 if (d>1 && (d&(d-1))==0)
528 struct tnode *pow2(tree) register struct tnode *tree; {
531 if (d = ispow2(tree)) {
532 for (i=0; (d>>=1)!=0; i++);
533 ((struct cnode *)tree->tn_tr2)->cn_value = i;
534 switch (tree->tn_op) {
537 tree->tn_op = LSHIFT;
545 if (i==1 && tree->tn_tr1->n_op==MINUS && !isconstant(((struct tnode *)tree->tn_tr1)->tn_tr2)) {
547 tree->tn_tr1 = (struct node *)tnode(LTOI, INT, tree->tn_tr1, (struct node *)NULL);
548 /* in this case optim() is guaranteed to return a struct tnode */
549 /* return((struct tnode *)optim((struct node *)tree));*/
550 tree = (struct tnode *)optim((struct node *)tree);
551 if (opdope1[tree->tn_op] & LEAF) abort();
554 tree->tn_op = LLSHIFT;
555 ((struct cnode *)tree->tn_tr2)->cn_value = -i;
557 tree->tn_type = LONG;
558 tree = tnode(LTOI, i, (struct node *)tree, (struct node *)NULL);
563 ((struct cnode *)tree->tn_tr2)->cn_value = -i;
567 tree->tn_op = ASULSH;
568 ((struct cnode *)tree->tn_tr2)->cn_value = -i;
573 ((struct cnode *)tree->tn_tr2)->cn_value = (1<<i)-1;
578 ((struct cnode *)tree->tn_tr2)->cn_value = (1<<i)-1;
582 error1("pow2 botch");
584 /* in this case optim() is guaranteed to return a struct tnode */
585 tree = (struct tnode *)optim((struct node *)tree);
586 if (opdope1[tree->tn_op] & LEAF) abort();
591 void cbranch1(atree, lbl, cond, reg) struct node *atree; register int lbl; int cond; register int reg; {
593 register struct node *tree;
596 if ((tree=atree)==NULL)
601 #define ttree ((struct tnode *)tree)
603 cbranch1(ttree->tn_tr1, l1=isn1++, 0, reg);
604 cbranch1(ttree->tn_tr2, lbl, 1, reg);
607 cbranch1(ttree->tn_tr1, lbl, 0, reg);
608 cbranch1(ttree->tn_tr2, lbl, 0, reg);
614 #define ttree ((struct tnode *)tree)
616 cbranch1(ttree->tn_tr1, lbl, 1, reg);
617 cbranch1(ttree->tn_tr2, lbl, 1, reg);
619 cbranch1(ttree->tn_tr1, l1=isn1++, 1, reg);
620 cbranch1(ttree->tn_tr2, lbl, 0, reg);
627 #define ttree ((struct tnode *)tree)
628 cbranch1(ttree->tn_tr1, lbl, !cond, reg);
633 #define ttree ((struct tnode *)tree)
634 rcexpr1(ttree->tn_tr1, efftab, reg);
635 atree = ttree->tn_tr2;
640 tree = ((struct tnode *)tree)->tn_tr1;
644 #define ttree ((struct tnode *)tree)
647 cbranch1(ttree->tn_tr1, l1, 0, reg);
648 cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr1, lbl, cond, reg);
651 cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr2, lbl, cond, reg);
658 if (opdope1[op]&RELAT
659 && ((struct tnode *)tree)->tn_tr1->n_op==ITOL && ((struct tnode *)tree)->tn_tr2->n_op==ITOL
660 && uns(((struct tnode *)((struct tnode *)tree)->tn_tr1)->tn_tr1) == uns(((struct tnode *)((struct tnode *)tree)->tn_tr2)->tn_tr1)) {
661 #define ttree ((struct tnode *)tree)
662 ttree->tn_tr1 = ((struct tnode *)ttree->tn_tr1)->tn_tr1;
663 ttree->tn_tr2 = ((struct tnode *)ttree->tn_tr2)->tn_tr1;
664 if (op>=LESSEQ && op<=GREAT
665 && uns(ttree->tn_tr1))
666 ttree->tn_op = op = op+LESSEQP-LESSEQ;
669 if (tree->n_type==LONG || tree->n_type==UNLONG
670 || opdope1[op]&RELAT&&(((struct tnode *)tree)->tn_tr1->n_type==LONG || ((struct tnode *)tree)->tn_tr1->n_type==UNLONG)) {
671 #define ttree ((struct tnode *)tree)
672 longrel(ttree, lbl, cond, reg);
676 rcexpr1(tree, cctab, reg);
678 if ((opdope1[op]&RELAT)==0)
681 #define ttree ((struct tnode *)tree)
682 l1 = ttree->tn_tr2->n_op;
683 if ((l1==CON || l1==SFCON) && ((struct cnode *)ttree->tn_tr2)->cn_value==0)
684 op += 200; /* special for ptr tests */
686 op = maprel[op-EQUAL];
690 fprintf(temp_fp[temp_fi], "cfcc\n");
691 branch1(lbl, op, !cond);
694 void branch1(lbl, aop, c) int lbl; int aop; int c; {
699 skip = prins(op, c, branchtab, lbl);
701 fprintf(temp_fp[temp_fi], "jbr");
705 fprintf(temp_fp[temp_fi], "\tL%d\nL%d:", lbl, skip);
707 fprintf(temp_fp[temp_fi], "\tL%d\n", lbl);
710 void longrel(atree, lbl, cond, reg) struct tnode *atree; int lbl; int cond; int reg; {
711 int xl1, xl2, xo, xz;
712 register int op, isrel;
713 register struct node *tree;
717 reorder((struct node **)&atree, cctab, reg);
718 tree = (struct node *)atree;
720 if (opdope1[tree->n_op]&RELAT) {
726 op = notrel[op-EQUAL];
734 xzero = !isrel || (((struct tnode *)tree)->tn_tr2->n_op==ITOL && ((struct tnode *)((struct tnode *)tree)->tn_tr2)->tn_tr1->n_op==CON
735 && ((struct cnode *)((struct tnode *)((struct tnode *)tree)->tn_tr2)->tn_tr1)->cn_value==0);
736 if (tree->n_op==ANDN) {
737 #define ttree ((struct tnode *)tree)
739 ttree->tn_tr2 = optim((struct node *)tnode(COMPL, LONG, ttree->tn_tr2, (struct node *)NULL));
742 if (cexpr(tree, cctab, reg) < 0) {
743 reg = rcexpr1(tree, regtab, reg);
744 fprintf(temp_fp[temp_fi], "ashc $0,r%d\n", reg);
745 branch1(xlab1, op, 0);
754 * Tables for finding out how best to do long comparisons.
755 * First dimen is whether or not the comparison is with 0.
756 * Second is which test: e.g. a>b->
763 * Note some tests may not be needed.
776 * Third dimension (lrtab[][][x]) indexed by "x - EQUAL".
778 char lrtab[2][3][10] = {
780 {0, NEQUAL, LESS, LESS, GREAT, GREAT, LESSP, LESSP, GREATP, GREATP},
781 {NEQUAL, 0, GREAT, GREAT, LESS, LESS, GREATP, GREATP, LESSP, LESSP},
782 {EQUAL,NEQUAL,LESSEQP,LESSP, GREATQP,GREATP,LESSEQP,LESSP,GREATQP,GREATP}
785 {0, NEQUAL, LESS, LESS, GREATEQ,GREAT, LESSP, LESSP, GREATQP, GREATP},
786 {NEQUAL, 0, GREAT, 0, 0, LESS, GREATP, 0, 0, LESSP},
787 {EQUAL, NEQUAL, EQUAL, 0, 0, NEQUAL, EQUAL, 0, 0, NEQUAL}
791 int xlongrel(f) int f; {
792 register int op, bno;
796 if (bno = lrtab[xzero][0][op-EQUAL])
797 branch1(xlab1, bno, 0);
798 if (bno = lrtab[xzero][1][op-EQUAL]) {
800 branch1(xlab2, bno, 0);
802 if (lrtab[xzero][2][op-EQUAL]==0)
805 branch1(xlab1, lrtab[xzero][2][op-EQUAL], 0);
812 void label1(l) int l; {
813 fprintf(temp_fp[temp_fi], "L%d:", l);
816 void popstk(a) int a; {
823 fprintf(temp_fp[temp_fi], "tst (sp)+\n");
827 fprintf(temp_fp[temp_fi], "cmp (sp)+,(sp)+\n");
830 fprintf(temp_fp[temp_fi], "add $%o,sp\n", UNS(a));
833 void werror1(s) char *s; {
835 fprintf(stderr, "%d: %s\n",line,s);
839 void error1(char *s, ...)
841 void error1(s, va_alist) char *s; va_dcl
847 fprintf(stderr, "%d: ", line);
849 vfprintf(stderr, s, argp);
855 void psoct(an) int an; {
864 fprintf(temp_fp[temp_fi], "%s%o", sign, n);
868 * Read in an intermediate file.
873 while ((c = fgetc(temp_fp[temp_fi])) != 0 && c != EOF)
877 void outcode(char *fmt, ...)
879 void outcode(fmt, va_alist) char *fmt; va_dcl
883 /* struct node *expstack[STKS], **sp;*/
884 static struct node *expstack[STKS], **sp = expstack;
885 register struct node *tp;
887 char s[80]; /* big for asm() stuff & long variable names */
890 int lbl, cond, lbl2, lbl3;
891 char *svtree = starttree();
893 /* curbase = funcbase;
896 _va_start(argp, fmt);
899 if (sp >= &expstack[STKS])
900 error1("Stack overflow botch");
901 op = (_INT)va_arg(argp, int) /*geti()*/;
902 /*fprintf(stderr, "%d %d\n", op, (int)(sp - expstack));*/
903 /* if ((op&0177400) != 0177000) {
904 error1("Intermediate file error");
911 fprintf(temp_fp[temp_fi], "%o\n", UNS((_INT)va_arg(argp, int) /*geti()*/));
920 #if 1 /* one-pass version */
921 /* this is necessary because it's done as "B1N0" instead of "BNNN" */
922 fprintf(temp_fp[temp_fi], ".byte %o\n", UNS((_INT)va_arg(argp, int)));
924 if ((_INT)va_arg(argp, int) /*geti()*/ == 1) {
925 fprintf(temp_fp[temp_fi], ".byte ");
927 fprintf(temp_fp[temp_fi], "%o", UNS((_INT)va_arg(argp, int) /*geti()*/));
928 if ((_INT)va_arg(argp, int) /*geti()*/ != 1)
930 fprintf(temp_fp[temp_fi], ",");
932 fprintf(temp_fp[temp_fi], "\n");
938 fprintf(temp_fp[temp_fi], ".text\n");
942 fprintf(temp_fp[temp_fi], ".data\n");
946 fprintf(temp_fp[temp_fi], ".bss\n");
950 outname(s/*)*/, va_arg(argp, char *));
951 fprintf(temp_fp[temp_fi], ".globl\t%s\n", s);
952 sfuncr.locnn_nloc = 0;
956 fprintf(temp_fp[temp_fi], "jmp\tcret\n");
960 outname(s/*)*/, va_arg(argp, char *));
961 fprintf(temp_fp[temp_fi], ".comm\t%s,%o\n", s, UNS((_INT)va_arg(argp, int) /*geti()*/));
965 fprintf(temp_fp[temp_fi], ".=.+%o\n", UNS(t=(_INT)va_arg(argp, int) /*geti()*/));
966 totspace += (_UNSIGNED_INT)t;
970 fprintf(temp_fp[temp_fi], ".even\n");
974 fprintf(temp_fp[temp_fi], "jsr r5,csv\n");
978 t = (_INT)va_arg(argp, int) /*geti()*/;
980 fprintf(temp_fp[temp_fi], "tst -(sp)\n");
982 fprintf(temp_fp[temp_fi], "sub $%o,sp\n", UNS(t));
986 t = (_INT)va_arg(argp, int) /*geti()*/;
987 outname(s/*)*/, va_arg(argp, char *));
988 fprintf(temp_fp[temp_fi], "mov $L%d,r0\njsr pc,mcount\n", t);
989 fprintf(temp_fp[temp_fi], ".data\nL%d:%s+1\n.text\n", t, s);
993 outname(s/*)*/, va_arg(argp, char *));
994 fprintf(temp_fp[temp_fi], "%s\n", s);
998 outname(s/*)*/, va_arg(argp, char *));
999 fprintf(temp_fp[temp_fi], "~%s=L%d\n", s+1, (_INT)va_arg(argp, int) /*geti()*/);
1003 outname(s/*)*/, va_arg(argp, char *));
1004 fprintf(temp_fp[temp_fi], "~%s=%o\n", s+1, UNS((_INT)va_arg(argp, int) /*geti()*/));
1008 outname(s/*)*/, va_arg(argp, char *));
1009 fprintf(temp_fp[temp_fi], "~%s=r%d\n", s+1, (_INT)va_arg(argp, int) /*geti()*/);
1013 t = (_INT)va_arg(argp, int) /*geti()*/;
1014 line = (_INT)va_arg(argp, int) /*geti()*/;
1015 /* curbase = funcbase;*/
1017 while(swp=(struct swtab *)getblk(sizeof(*swp)), swp->swlab = (_INT)va_arg(argp, int) /*geti()*/)
1018 swp->swval = (_INT)va_arg(argp, int) /*geti()*/;
1019 pswitch1((struct swtab *)funcbase, swp, t);
1022 case C3BRANCH: /* for fortran [sic] */
1023 lbl = (_INT)va_arg(argp, int) /*geti()*/;
1024 lbl2 = (_INT)va_arg(argp, int) /*geti()*/;
1025 lbl3 = (_INT)va_arg(argp, int) /*geti()*/;
1029 lbl = (_INT)va_arg(argp, int) /*geti()*/;
1030 cond = (_INT)va_arg(argp, int) /*geti()*/;
1034 line = (_INT)va_arg(argp, int) /*geti()*/;
1035 if (sp != &expstack[1]) {
1036 error1("Expression input botch");
1041 if (setjmp(jmpbuf)) {
1043 fseek(/*stdout*/temp_fp[temp_fi], outloc, 0);
1047 *sp = tp = optim(*sp);
1048 if (regpanic==0 && panicposs)
1049 outloc = ftell(/*stdout*/temp_fp[temp_fi]);
1051 cbranch1(tp, lbl, cond, 0);
1053 rcexpr1(tp, efftab, 0);
1055 if (tp->n_type==LONG || tp->n_type==UNLONG) {
1056 rcexpr1((struct node *)tnode(RFORCE, tp->n_type, tp, (struct node *)NULL), efftab, 0);
1057 fprintf(temp_fp[temp_fi], "ashc $0,r0\n");
1059 rcexpr1(tp, cctab, 0);
1061 fprintf(temp_fp[temp_fi], "cfcc\n");
1063 fprintf(temp_fp[temp_fi], "jgt L%d\n", lbl3);
1064 fprintf(temp_fp[temp_fi], "jlt L%d\njbr L%d\n", lbl, lbl2);
1066 /* curbase = funcbase;*/
1070 t = (_INT)va_arg(argp, int) /*geti()*/;
1072 tp = getblk(sizeof(struct extnnode));
1073 #define extntp ((struct extnnode *)tp)
1074 extntp->extnn_type = (_INT)va_arg(argp, int) /*geti()*/;
1075 outname(s/*)*/, va_arg(argp, char *));
1076 extntp->extnn_name = (char *)getblk(strlen(s) + 1);
1077 strcpy(extntp->extnn_name, s);
1080 tp = getblk(sizeof(struct locnnode));
1081 #define locntp ((struct locnnode *)tp)
1082 locntp->locnn_type = (_INT)va_arg(argp, int) /*geti()*/;
1083 locntp->locnn_nloc = (_INT)va_arg(argp, int) /*geti()*/;
1086 #define ntp ((struct nnode *)tp)
1091 *sp++ = (struct node *)ntp;
1096 t = (_INT)va_arg(argp, int) /*geti()*/;
1097 *sp++ = (struct node *)tconst((_INT)va_arg(argp, int) /*geti()*/, t);
1101 va_arg(argp, int) /*geti()*/; /* ignore type, assume long */
1102 t = (_INT)va_arg(argp, int) /*geti()*/;
1103 op = (_INT)va_arg(argp, int) /*geti()*/;
1104 /* warning: below relies on geti() sign extending lo 16 bits into hi 16 bits */
1105 if (t==0 && op>=0 || t == -1 && op<0) {
1106 *sp++ = (struct node *)tnode(ITOL, LONG, (struct node *)tconst(op, INT), (struct node *)NULL);
1109 tp = getblk(sizeof(struct lnode));
1110 #define ltp ((struct lnode *)tp)
1112 ltp->ln_type = LONG;
1113 ltp->ln_lvalue = ((_LONG)t<<16) + UNS(op); /* nonportable */
1114 *sp++ = (struct node *)ltp;
1119 t = (_INT)va_arg(argp, int) /*geti()*/;
1120 outname(s/*)*/, va_arg(argp, char *));
1121 tp = getblk(sizeof(struct fnode));
1122 #define ftp ((struct fnode *)tp)
1125 ftp->fn_value = isn1++;
1127 ftp->fn_fvalue = atof(s);
1129 ftp->fn_fvalue = fp_atof(s);
1136 tp = (struct node *)tnode(FSEL, (_INT)va_arg(argp, int) /*geti()*/, *--sp, (struct node *)NULL);
1137 #define ttp ((struct tnode *)tp)
1138 /* t = (_INT)va_arg(argp, int) *//*geti()*//*;
1139 ttp->tn_tr2 = (struct node *)tnode(COMMA, INT, tconst((_INT)va_arg(argp, int) *//*geti()*//*, INT), tconst(t, INT));
1140 if (((struct cnode *)((struct tnode *)((struct tnode *)tp)->tn_tr2)->tn_tr1)->cn_value==16)*/
1141 ttp->tn_tr2 = getblk(sizeof(struct FS));;
1142 ((struct FS *)ttp->tn_tr2)->bitoffs = (_INT)va_arg(argp, int) /*geti()*/;
1143 ((struct FS *)ttp->tn_tr2)->flen = (_INT)va_arg(argp, int) /*geti()*/;
1144 if (((struct FS *)ttp->tn_tr2)->flen == 16)
1146 tp = paint(((struct tnode *)tp)->tn_tr1, ((struct tnode *)tp)->tn_type);
1147 *sp++ = (struct node *)tp;
1151 tp = getblk(sizeof(struct fasgn));
1153 tp->tn_type = (_INT)va_arg(argp, int) *//*geti()*//*;
1154 tp->fa_mask = (_INT)va_arg(argp, int) *//*geti()*//*;
1161 *sp++ = (struct node *)tnode(0, 0, (struct node *)NULL, (struct node *)NULL);
1165 label1((_INT)va_arg(argp, int) /*geti()*/);
1169 outname(s/*)*/, va_arg(argp, char *));
1170 fprintf(temp_fp[temp_fi], "%s:\n", s);
1174 outname(s/*)*/, va_arg(argp, char *));
1175 fprintf(temp_fp[temp_fi], "%s:\n~~%s:\n", s, s+1);
1179 branch1((_INT)va_arg(argp, int) /*geti()*/, 0, 0);
1183 nreg = (_INT)va_arg(argp, int) /*geti()*/-1;
1187 if (opdope1[op]&BINARY) {
1188 if (sp < &expstack[1]) {
1189 error1("Binary expression botch");
1194 sp[-1] = (struct node *)tnode(op, (_INT)va_arg(argp, int) /*geti()*/, sp[-1], tp);
1196 *sp++ = tnode(op, (_INT)va_arg(argp, int) /*geti()*/, *--sp, tp);
1199 sp[-1] = (struct node *)tnode(op, (_INT)va_arg(argp, int) /*geti()*/, sp[-1], (struct node *)NULL);
1211 i = fgetc(temp_fp[temp_fi])/*getchar()*/ & 0xff;
1212 i |= (fgetc(temp_fp[temp_fi])/*getchar()*/ & 0xff) << 8;
1218 static void outname(buf, str) char *buf; char *str; {
1224 static void outname(s) register char *s; {
1228 while ((c = fgetc(temp_fp[temp_fi])) != 0 && c != EOF)
1230 while (c = getchar())
1237 void strasg(atp) struct tnode *atp; {
1238 register struct tnode *tp;
1239 register int nwords, i;
1241 /* nwords = atp->fa_mask/sizeof(_INT);*/
1242 nwords = atp->tn_strp->S.ssize/sizeof(_INT);
1243 tp = atp/*->tn_tr1*/;
1244 /* while (tp->tn_op == SEQNC) {
1245 rcexpr1(tp->tn_tr1, efftab, 0);
1248 if (tp->tn_op != ASSIGN) {*/
1249 if (tp->tn_op==RFORCE) { /* function return */
1250 if (sfuncr.locnn_nloc==0) {
1251 sfuncr.locnn_nloc = isn1++;
1252 fprintf(temp_fp[temp_fi], ".bss\nL%d:.=.+%o\n.text\n", sfuncr.locnn_nloc,
1253 UNS(nwords*sizeof(_INT)));
1255 atp/*->tn_tr1*/ = tnode(ASSIGN, STRUCT, (struct node *)&sfuncr, tp->tn_tr1);
1256 atp->tn_strp = tp->tn_strp;
1258 fprintf(temp_fp[temp_fi], "mov $L%d,r0\n", sfuncr.locnn_nloc);
1261 /* if (tp->tn_op==CALL) {
1262 rcexpr1(tp, efftab, 0);
1265 error1("Illegal structure operation");
1268 tp->tn_tr2 = strfunc(tp->tn_tr2);
1270 paint((struct node *)tp, INT);
1271 else if (nwords==sizeof(_INT))
1272 paint((struct node *)tp, LONG);
1274 if (tp->tn_tr1->n_op!=NAME && tp->tn_tr1->n_op!=STAR
1275 || tp->tn_tr2->n_op!=NAME && tp->tn_tr2->n_op!=STAR) {
1276 error1("unimplemented structure assignment");
1279 tp->tn_tr1 = (struct node *)tnode(AMPER, STRUCT+PTR, tp->tn_tr1, (struct node *)NULL);
1280 tp->tn_tr2 = (struct node *)tnode(AMPER, STRUCT+PTR, tp->tn_tr2, (struct node *)NULL);
1282 tp->tn_type = STRUCT+PTR;
1283 rcexpr1(optim((struct node *)tp), efftab, 0);
1285 for (i=0; i<nwords; i++)
1286 fprintf(temp_fp[temp_fi], "mov (r1)+,(r0)+\n");
1290 fprintf(temp_fp[temp_fi], "mov r2,-(sp)\n");
1291 fprintf(temp_fp[temp_fi], "mov $%o,r2\n", UNS(nwords));
1292 fprintf(temp_fp[temp_fi], "L%d:mov (r1)+,(r0)+\ndec\tr2\njne\tL%d\n", isn1, isn1);
1295 fprintf(temp_fp[temp_fi], "mov (sp)+,r2\n");
1298 rcexpr1((struct node *)tp, efftab, 0);
1302 * Reduce the degree-of-reference by one.
1303 * e.g. turn "ptr-to-int" into "int".
1305 int decref1(t) register int t; {
1306 if ((t & ~TYPE) == 0) {
1307 error1("Illegal indirection");
1310 return(((_UNSIGNED_INT)t>>TYLEN) & ~TYPE | t&TYPE);
1314 * Increase the degree of reference by
1315 * one; e.g. turn "int" to "ptr-to-int".
1317 int incref1(t) register int t; {
1318 return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);