4 * (long)btodb(l) produced 'no code table error1 for op: >>(17) type: 6'
5 * allow both long and ulong at line ~341. 1996/6/19
8 #if !defined(lint) && defined(DOSCCS)
9 static char sccsid[] = "@(#)c10.c 2.1 (2.11BSD GTE) 10/4/94";
17 #define dbprint(op) fprintf(temp_fp[temp_fi], /*printf(*/" / %s", opntab[op])
19 #define dbprint(op) /* */
22 char maprel[] = { EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ,
23 LESS, GREATQP, GREATP, LESSEQP, LESSP
26 char notrel[] = { NEQUAL, EQUAL, GREAT, GREATEQ, LESS,
27 LESSEQ, GREATP, GREATQP, LESSP, LESSEQP
30 struct tconst czero = { CON, INT, 0/*subsp*/, 0/*strp*/, 0};
31 struct tconst cone = { CON, INT, 0/*subsp*/, 0/*strp*/, 1};
33 struct tname sfuncr = { NAME, STRUCT, STATIC, 0, 0, 0 };
35 struct table *cregtab;
41 int main(argc, argv) int argc; char *argv[]; {
49 if (freopen(argv[1], "r", stdin)==NULL) {
50 error1("Missing temp file");
53 setbuf(stdin,buf1); /* sbrk problems */
54 if ((freopen(argv[3], "w", stdout)) == NULL) {
55 error1("Can't create %s", argv[3]);
58 setbuf(stdout,buf2); /* sbrk problems */
59 funcbase = curbase = coremax = sbrk(0);
62 * If any floating-point instructions
63 * were used, generate a reference that
64 * pulls in the floating-point part of printf.
67 fprintf(temp_fp[temp_fi], /*printf(*/".globl fltused\n");
69 * tack on the string file.
71 fprintf(temp_fp[temp_fi], /*printf(*/".globl\n.data\n");
72 if (*argv[2] != '-') {
73 if (freopen(argv[2], "r", stdin)==NULL) {
74 error1("Missing temp file");
77 setbuf(stdin,buf1); /* sbrk problems */
80 if (totspace >= (_UNSIGNED_INT)56000)
81 werror1("possibly too much data");
87 * Given a tree1, a code table, and a
88 * count of available registers, find the code table
89 * for the appropriate operator such that the operands
90 * are of the right type and the number of registers
91 * required is not too large.
92 * Return a ptr to the table entry or 0 if none found.
94 struct optab *match(tree1, table, nrleft, nocvt) union tree *tree1; struct table *table; int nrleft; int nocvt; {
99 register union tree *p1;
100 register struct optab *opt;
106 if ((op = tree1->t.op)==0)
109 if ((dope&LEAF) == 0)
113 d1 = dcalc(p1, nrleft);
114 if ((dope&BINARY)!=0) {
117 * If a subtree starts off with a conversion operator,
118 * try for a match with the conversion eliminated.
119 * E.g. int = double can be done without generating
120 * the converted int in a register by
121 * movf double,fr0; movfi fr0,int .
123 if (opdope1[p2->t.op]&CNVRT && (nocvt&NOCVR)==0
124 && (opdope1[p2->t.tr1->t.op]&CNVRT)==0) {
125 tree1->t.tr2 = p2->t.tr1;
126 if (opt = match(tree1, table, nrleft, NOCVL))
129 } else if (opdope1[p1->t.op]&CNVRT && (nocvt&NOCVL)==0
130 && (opdope1[p1->t.tr1->t.op]&CNVRT)==0) {
131 tree1->t.tr1 = p1->t.tr1;
132 if (opt = match(tree1, table, nrleft, NOCVR))
136 d2 = dcalc(p2, nrleft);
138 for (; table->tabop!=op; table++)
141 for (opt = table->tabp; opt->tabdeg1!=0; opt++) {
142 if (d1 > (opt->tabdeg1&077)
143 || (opt->tabdeg1 >= 0100 && (p1->t.op != STAR)))
145 if (notcompat(p1, opt->tabtyp1, opt->tabdeg1, op))
147 if ((opdope1[op]&BINARY)!=0 && p2!=0) {
148 if (d2 > (opt->tabdeg2&077)
149 || (opt->tabdeg2 >= 0100) && (p2->t.op != STAR) )
151 if (notcompat(p2,opt->tabtyp2, opt->tabdeg2, 0))
153 if ((opt->tabdeg2&077)==20 && xdcalc(p2,nrleft)>20)
162 * Given a tree1, a code table, and a register,
163 * produce code to evaluate the tree1 with the appropriate table.
164 * Registers reg and upcan be used.
165 * If there is a value, it is desired that it appear in reg.
166 * The routine returns the register in which the value actually appears.
167 * This routine must work or there is an error1.
168 * If the table called for is cctab, sptab, or efftab,
169 * and tree1 can't be done using the called-for table,
170 * another try is made.
171 * If the tree1 can't be compiled using cctab, regtab is
172 * used and a "tst" instruction is produced.
173 * If the tree1 can't be compiled using sptab,
174 * regtab is used and the register is pushed on the stack.
175 * If the tree1 can't be compiled using efftab,
177 * Regtab must succeed or an "op not found" error1 results.
179 * A number of special cases are recognized, and
180 * there is an interaction with the optimizer routines.
182 int rcexpr1(atree, atable, reg) union tree *atree; struct table *atable; int reg; {
184 int modf, nargs, recurf;
185 register union tree *tree1;
186 register struct table *table;
188 /*fprintf(stderr, "rcexpr1(0x%08x, 0x%08x, 0x%08x)\n", atree, atable, reg);*/
202 if (tree1->t.type==VOID) {
204 error1("Illegal use of void");
207 if (opdope1[tree1->t.op]&RELAT && tree1->t.tr2->t.op==CON
208 && tree1->t.tr2->c.value==0
210 tree1 = atree = tree1->t.tr1;
212 * fieldselect(...) : in efftab mode,
213 * ignore the select, otherwise
214 * do the shift and mask.
216 if (tree1->t.op == FSELT) {
218 atree = tree1 = tree1->t.tr1;
221 atree = tree1 = optim(tree1);
224 switch (tree1->t.op) {
227 * Structure assignments
234 * An initializing expression
237 tree1 = optim(tree1);
238 doinit(tree1->t.type, tree1->t.tr1);
242 * Put the value of an expression in r0,
243 * for a switch or a return
246 tree1 = tree1->t.tr1;
247 if((r=rcexpr1(tree1, regtab, reg)) != 0)
252 * sequential execution
256 rcexpr1(tree1->t.tr1, efftab, reg);
258 atree = tree1 = tree1->t.tr2;
262 * In the generated &~ operator,
263 * fiddle things so a PDP-11 "bit"
264 * instruction will be produced when cctab is used.
269 tree1->t.tr2 = optim(tnode1(COMPL, tree1->t.type, tree1->t.tr2, TNULL));
274 * Handle a subroutine call. It has to be done
275 * here because if cexpr got called twice, the
276 * arguments might be compiled twice.
277 * There is also some fiddling so the
278 * first argument, in favorable circumstances,
279 * goes to (sp) instead of -(sp), reducing
280 * the amount of stack-popping.
288 * The following code would catch instances of foo(...) where
289 * "foo" was anything other than a simple name. In particular
290 * f(...), (fp(...))(...) and (ffp(...))(...) where "f" is a
291 * pointer to a function, "fp" is a function returning a
292 * pointer to a function and "ffp" is a pointer to a function
293 * returning a pointer to a function. The catch would among
294 * other things cause the (sp)/-(sp) stack optimization to
295 * stop working. The compiler has been tested in all these
296 * different cases with the catch commented out and all the
297 * code generated was correct. So what was it here for?
298 * If a strange error1 crops up, uncommenting the catch might
301 if (tree1->t.tr1->t.op!=NAME || tree1->t.tr1->n.class!=EXTERN) {
306 tree1 = tree1->t.tr2;
308 while (tree1->t.op==COMMA) {
309 r += comarg(tree1->t.tr2, &modf);
310 tree1 = tree1->t.tr1;
313 r += comarg(tree1, &modf);
318 if (modf && tree1->t.tr1->t.op==NAME
319 && tree1->t.tr1->n.class==EXTERN)
321 if (cexpr(tree1, regtab, reg)<0)
322 error1("compiler botch: call");
325 if (table==efftab || table==regtab)
331 * Longs need special treatment.
333 case ASULSH: /* 18 */
335 if (tree1->t.type != LONG && tree1->t.type != UNLONG)
337 if (tree1->t.tr2->t.op==ITOL)
338 tree1->t.tr2 = tree1->t.tr2->t.tr1;
340 tree1->t.tr2 = optim(tnode1(LTOI,INT,tree1->t.tr2,TNULL));
341 if (tree1->t.op==ASULSH)
343 tree1->t.op = UASLSHL;
344 tree1->t.tr1 = tnode1(AMPER, LONG+PTR, tree1->t.tr1, TNULL);
347 tree1->t.op = ULLSHIFT;
352 if (tree1->t.type==LONG || tree1->t.type==UNLONG) {
353 if (tree1->t.tr2->t.op==ITOL)
354 tree1->t.tr2 = tree1->t.tr2->t.tr1;
356 tree1->t.tr2 = optim(tnode1(LTOI,INT,tree1->t.tr2,TNULL));
357 if (tree1->t.op==ASLSH)
358 tree1->t.op = ASLSHL;
360 tree1->t.op = LLSHIFT;
365 * Try to change * to shift.
372 * Try to find postfix ++ and -- operators that can be
373 * pulled out and done after the rest of the expression
375 if (table!=cctab && table!=cregtab && recurf<2
376 && (opdope1[tree1->t.op]&LEAF)==0) {
377 if (r=delay(&atree, table, reg)) {
384 * Basically, try to reorder the computation
385 * so reg = x+y is done as reg = x; reg += y
387 if (recurf==0 && reorder(&atree, table, reg)) {
388 if (table==cctab && atree->t.op==NAME)
392 if (table==efftab && tree1->t.op==NAME)
394 if ((r=cexpr(tree1, table, reg))>=0) {
395 if (table==cregtab && (tree1->t.op==INCAFT
396 || tree1->t.op==DECAFT || tree1->t.op==TIMES))
400 if (table!=regtab && (table!=cctab||(opdope1[tree1->t.op]&RELAT)==0)) {
401 if((r=cexpr(tree1, regtab, reg))>=0) {
403 modf = isfloat(tree1);
404 dbprint(tree1->t.op);
405 if (table==sptab || table==lsptab) {
406 if (tree1->t.type==LONG || tree1->t.type==UNLONG){
407 fprintf(temp_fp[temp_fi], /*printf(*/"mov\tr%d,-(sp)\n",r+1);
410 fprintf(temp_fp[temp_fi], /*printf(*/"mov%s r%d,%s(sp)\n", modf=='f'?"f":"", r,
411 table==sptab? "-":"");
414 if (table==cctab || table==cregtab)
415 fprintf(temp_fp[temp_fi], /*printf(*/"tst%s r%d\n", modf=='f'?"f":"", r);
420 * Special grace for unsigned chars as right operands
422 if (opdope1[tree1->t.op]&BINARY && tree1->t.tr2->t.type==UNCHAR) {
423 tree1->t.tr2 = tnode1(LOAD, UNSIGN, tree1->t.tr2, TNULL);
424 return(rcexpr1(tree1, table, reg));
427 * There's a last chance for this operator
429 if (tree1->t.op==LTOI) {
430 r = rcexpr1(tree1->t.tr1, regtab, reg);
438 if (tree1->t.type == STRUCT)
439 error1("Illegal operation on structure");
440 else if (r > 0 && r < UASLSHL && opntab[r])
441 error1("No code table for op: %s(%d) type: %d", opntab[r], r,
444 error1("No code table for op %d", r);
449 * Try to compile the tree1 with the code table using
450 * registers areg and up. If successful,
451 * return the register where the value actually ended up.
452 * If unsuccessful, return -1.
454 * Most of the work is the macro-expansion of the
457 int cexpr(tree1, table, areg) register union tree *tree1; struct table *table; int areg; {
459 register union tree *p, *p1;
460 struct table *ctable;
463 int reg, reg1, rreg, flag, opd;
471 * When the value of a relational or a logical expression is
472 * desired, more work must be done.
474 if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {
475 cbranch1(tree1, c=isn1++, 1, reg);
476 rcexpr1((union tree *)&czero, table, reg);
479 rcexpr1((union tree *)&cone, table, reg);
486 cbranch1(tree1->t.tr1, c=isn1++, 0, reg);
488 rreg = rcexpr1(p1->t.tr1, table, reg);
490 branch1(r=isn1++, 0, 0);
492 reg = rcexpr1(p1->t.tr2, table, rreg);
494 movreg(reg, rreg, tree1->t.tr2);
498 reg = oddreg(tree1, reg);
501 * long values take 2 registers.
503 if ((tree1->t.type==LONG||tree1->t.type==UNLONG||opd&RELAT&&(tree1->t.tr1->t.type==LONG||tree1->t.tr1->t.type==UNLONG))
504 && tree1->t.op!=ITOL)
507 * Leaves of the expression tree1
509 if ((r = chkleaf(tree1, table, reg)) >= 0)
512 * x + (-1) is better done as x-1.
514 if (tree1->t.op==PLUS||tree1->t.op==ASPLUS) {
515 if ((p1=tree1->t.tr2)->t.op==CON && p1->c.value==-1) {
516 p1->c.value = -p1->c.value;
517 tree1->t.op += (MINUS-PLUS);
521 * Because of a peculiarity of the PDP11 table
522 * char = *intreg++ and *--intreg cannot go through.
524 if (tree1->t.tr2 && (tree1->t.tr2->t.op==AUTOI||tree1->t.tr2->t.op==AUTOD)
525 && (tree1->t.tr1->t.type==CHAR || tree1->t.tr1->t.type==UNCHAR)
526 && tree1->t.tr2->t.type!=CHAR && tree1->t.tr2->t.type!=UNCHAR)
527 tree1->t.tr2 = tnode1(LOAD, tree1->t.tr2->t.type, tree1->t.tr2, TNULL);
529 * Another peculiarity of the PDP11 table manifested itself when
530 * amplifying the move3: table. The same case which optimizes
531 * u_char to char moves is used to move a u_char to a register. This
532 * is wrong, leading to sign extension. Rather than lose the ability
533 * to generate better code when moving a u_char to a char, a check
534 * is made here to prevent sign extension.
536 * If the opcode is assign, the destination is a register and the
537 * source is u_char then do a conversion.
539 * u_char handling in the compiler is a bit awkward, it would be nice
540 * if %aub in the tables had a more unique meaning.
542 if (tree1->t.tr2 && tree1->t.tr1->t.op == NAME
543 && tree1->t.tr1->n.class == REG && tree1->t.op == ASSIGN
544 && tree1->t.tr2->t.type == UNCHAR)
545 tree1->t.tr2 = tnode1(LOAD, UNSIGN, tree1->t.tr2, TNULL);
549 * The following peculiar code depends on the fact that
550 * if you just want the codition codes set, efftab
551 * will generate the right code unless the operator is
553 * postfix ++ or --. Unravelled, if the table is
554 * cctab and the operator is not special, try first
555 * for efftab; if the table isn1't, if the operator is,
556 * or the first match fails, try to match
557 * with the table actually asked for.
560 * Account for longs and oddregs; below is really
561 * r = nreg - reg - (reg-areg) - (reg1-reg-1);
563 r = nreg - reg + areg - reg1 + 1;
564 if (table!=cctab || c==INCAFT || c==DECAFT || tree1->t.type==LONG || tree1->t.type==UNLONG
565 /* || c==ASRSH || c==ASLSH || c==ASULSH || tree1->t.tr1->t.type==UNCHAR */
566 || c==ASRSH || c==ASLSH || c==ASULSH
567 || (opt = match(tree1, efftab, r, 0)) == 0)
568 if ((opt=match(tree1, table, r, 0))==0)
570 string = opt->tabstring;
572 if (p1->t.op==FCON && p1->f.value>0) {
575 fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value,
576 ((_UNSIGNED_INT *)&(p1->f.fvalue))[0],
577 ((_UNSIGNED_INT *)&(p1->f.fvalue))[1],
578 ((_UNSIGNED_INT *)&(p1->f.fvalue))[2],
579 ((_UNSIGNED_INT *)&(p1->f.fvalue))[3] );
581 fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value,
582 (int)(p1->f.fvalue.h >> 16) & 0xffff,
583 (int)p1->f.fvalue.h & 0xffff,
584 (int)(p1->f.fvalue.l >> 16) & 0xffff,
585 (int)p1->f.fvalue.l & 0xffff );
587 p1->f/*c*/.value = -p1->f/*c*/.value;
590 if (opdope1[tree1->t.op]&BINARY) {
592 if (p2->t.op==FCON && p2->f.value>0) {
595 fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value,
596 ((_UNSIGNED_INT *)&(p2->f.fvalue))[0],
597 ((_UNSIGNED_INT *)&(p2->f.fvalue))[1],
598 ((_UNSIGNED_INT *)&(p2->f.fvalue))[2],
599 ((_UNSIGNED_INT *)&(p2->f.fvalue))[3] );
601 fprintf(temp_fp[temp_fi], /*printf(*/".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value,
602 (int)(p2->f.fvalue.h >> 16) & 0xffff,
603 (int)p2->f.fvalue.h & 0xffff,
604 (int)(p2->f.fvalue.l >> 16) & 0xffff,
605 (int)p2->f.fvalue.l & 0xffff );
607 p2->f.value = -p2->f.value;
612 * The 0200 bit asks for a tab.
614 if ((c = *string++) & 0200) {
616 fputc('\t', temp_fp[temp_fi]) /*putchar('\t')*/;
621 dbprint(tree1->t.op);
626 if (tree1->t.op==DIVIDE||tree1->t.op==ASDIV)
628 if (table==regtab && (opdope1[tree1->t.op]&ASSGOP)) {
629 if (tree1->t.tr1->t.type==CHAR)
630 fprintf(temp_fp[temp_fi], /*printf(*/"movb r%d,r%d\n", reg, reg);
646 while (*string=='\'') {
659 if ((c = *string)=='\'')
663 prins(tree1->t.op, c, instab, 0);
683 if (p->t.type==CHAR || p->t.type==UNCHAR)
684 fputc('b', temp_fp[temp_fi]) /*putchar('b')*/;
687 fputc('f', temp_fp[temp_fi]) /*putchar('f')*/;
692 if (p1->t.type==CHAR || p2->t.type==CHAR
693 || p1->t.type==UNCHAR || p2->t.type==UNCHAR)
694 fputc('b', temp_fp[temp_fi]) /*putchar('b')*/;
722 c |= 020; /* force right register */
726 c |= 040; /* force condition codes */
732 if ((flag&01) && ctable==regtab && (c&01)==0
733 && ((c&040)||tree1->t.op==DIVIDE||tree1->t.op==MOD
734 || tree1->t.op==ASDIV||tree1->t.op==ASMOD||tree1->t.op==ITOL))
738 if(collcon(p) && ctable!=sptab) {
744 if (table==lsptab && ctable==sptab)
749 if (opdope1[p->t.op]&LEAF || p->t.degree < 2)
753 rreg = rcexpr1(p, ctable, r);
754 if (ctable!=regtab && ctable!=cregtab)
757 if (c&020 && rreg!=reg1)
758 movreg(rreg, reg1, p);
761 } else if (rreg!=reg)
762 if ((c&020)==0 && oddreg(tree1, 0)==0 && tree1->t.type!=LONG
763 && tree1->t.type!=UNLONG
765 || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077)
766 || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) {
770 movreg(rreg, reg, p);
790 if (r>nreg || r>=4 && tree1->t.type==DOUBLE) {
792 error1("Register overflow: simplify expression");
796 fprintf(temp_fp[temp_fi], /*printf(*/"r%d", r);
799 case '-': /* check -(sp) */
803 fputc('-', temp_fp[temp_fi]) /*putchar('-')*/;
808 case ')': /* check (sp)+ */
809 fputc(')', temp_fp[temp_fi]) /*putchar(')')*/;
826 fprintf(temp_fp[temp_fi], /*printf(*/"*");
829 if ((p = p->t.tr2)->t.op == CON) {
832 } else if (p->t.op==AMPER)
838 * Certain adjustments for / %
842 if (uns(p1) || uns(p2)) {
843 fprintf(temp_fp[temp_fi], /*printf(*/"clr r%d\n", c);
846 if (dcalc(p1, 5)>12 && !match(p1, cctab, 10, 0))
847 fprintf(temp_fp[temp_fi], /*printf(*/"tst r%d\n", reg);
848 fprintf(temp_fp[temp_fi], /*printf(*/"sxt r%d\n", c);
851 case 'V': /* adc sbc, clr, or sxt as required for longs */
852 switch(tree1->t.op) {
857 fprintf(temp_fp[temp_fi], /*printf(*/"adc");
865 fprintf(temp_fp[temp_fi], /*printf(*/"sbc");
877 if (p->t.type!=LONG && p->t.type!=UNLONG) {
878 if (uns(p) || uns(tree1->t.tr2))
879 fprintf(temp_fp[temp_fi], /*printf(*/"clr");
881 fprintf(temp_fp[temp_fi], /*printf(*/"sxt");
885 while ((c = *string++)!='\n' && c!='\0');
891 * Mask used in field assignments
894 fprintf(temp_fp[temp_fi], /*printf(*/"$%o", UNS(tree1->F.mask));
898 * Relational on long values.
899 * Might bug out early. E.g.,
900 * (long<0) can be determined with only 1 test.
903 if (xlongrel(*string++ - '0'))
907 fputc(c, temp_fp[temp_fi]) /*putchar(c)*/;
912 * This routine just calls sreorder (below)
913 * on the subtrees and then on the tree1 itself.
914 * It returns non-zero if anything changed.
916 int reorder(treep, table, reg) union tree **treep; struct table *table; int reg; {
918 register union tree *p;
922 if (opdope1[o]&LEAF||o==LOGOR||o==LOGAND||o==SEQNC||o==QUEST||o==COLON)
924 while(sreorder(&p->t.tr1, regtab, reg, 1))
926 if (opdope1[o]&BINARY)
927 while(sreorder(&p->t.tr2, regtab, reg, 1))
931 while (sreorder(treep, table, reg, 0))
933 *treep = optim(*treep);
938 * Basically this routine carries out two kinds of optimization.
939 * First, it observes that "x + (reg = y)" where actually
940 * the = is any assignment op is better done as "reg=y; x+reg".
941 * In this case rcexpr1 is called to do the first part and the
942 * tree1 is modified so the name of the register
943 * replaces the assignment.
944 * Moreover, expressions like "reg = x+y" are best done as
945 * "reg = x; reg += y" (so long as "reg" and "y" are not the same!).
947 int sreorder(treep, table, reg, recurf) union tree **treep; struct table *table; int reg; int recurf; {
948 register union tree *p, *p1;
951 if (opdope1[p->t.op]&LEAF)
953 if (p->t.op==PLUS && recurf)
954 if (reorder(&p->t.tr2, table, reg))
955 *treep = p = optim(p);
956 if ((p1 = p->t.tr1)==TNULL)
958 if (p->t.op==STAR || p->t.op==PLUS) {
959 if (recurf && reorder(&p->t.tr1, table, reg)) {
960 *treep = p = optim(p);
961 if (opdope1[p->t.op]&LEAF)
966 if (p1->t.op==NAME) switch(p->t.op) {
970 if (p1->n.class != REG || p1->n.type==CHAR
971 || isfloat(p->t.tr2))
973 if (p->t.op==ASSIGN) switch (p->t.tr2->t.op) {
975 if (p->t.type==UNSIGN)
979 if (!ispow2(p->t.tr2))
981 p->t.tr2 = pow2(p->t.tr2);
990 p1 = p->t.tr2->t.tr2;
991 if (xdcalc(p1, 16) > 12
993 &&(p1->n.nloc==p->t.tr1->n.nloc
994 || p1->n.regno==p->t.tr1->n.nloc))
997 p->t.tr2 = p1->t.tr1;
998 if (p1->t.tr1->t.op!=NAME
999 || p1->t.tr1->n.class!=REG
1000 || p1->t.tr1->n.nloc!=p->t.tr1->n.nloc)
1001 rcexpr1(p, efftab, reg);
1002 p->t.tr2 = p1->t.tr2;
1003 p->t.op = p1->t.op + ASPLUS - PLUS;
1021 if (table==cctab||table==cregtab)
1023 rcexpr1(optim(p), efftab, ~reg);
1031 * Delay handles postfix ++ and --
1032 * It observes that "x + y++" is better
1033 * treated as "x + y; y++".
1034 * If the operator is ++ or -- itself,
1035 * it calls rcexpr1 to load the operand, letting
1036 * the calling instance of rcexpr1 to do the
1038 * Otherwise it uses sdelay to search for inc/dec
1039 * among the operands.
1041 int delay(treep, table, reg) union tree **treep; struct table *table; int reg; {
1042 register union tree *p, *p1;
1046 if ((p->t.op==INCAFT||p->t.op==DECAFT)
1047 && p->t.tr1->t.op==NAME) {
1048 r = p->t.tr1->n.class;
1049 if (r == EXTERN || r == OFFS || r == STATIC &&
1050 p->t.tr1->t.type == UNCHAR)
1051 return(1+rcexpr1(p->t.tr1, table, reg));
1053 return(1+rcexpr1(paint(p->t.tr1, p->t.type), table,reg));
1057 * typo fix, original code.
1058 * if (opdope1[p->t.op]&BINARY) {
1059 * if (p->t.op==LOGAND || p->t.op==LOGOR
1060 * || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC)
1063 * p1 = sdelay(&p->t.tr2);
1065 * p1 = sdelay(&p->t.tr1);
1067 if (opdope1[p->t.op]&BINARY) {
1068 if (p->t.op==LOGAND || p->t.op==LOGOR
1069 || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC)
1071 p1 = sdelay(&p->t.tr2);
1074 p1 = sdelay(&p->t.tr1);
1076 r = rcexpr1(optim(p), table, reg);
1083 union tree *sdelay(ap) union tree **ap; {
1084 register union tree *p, *p1;
1086 if ((p = *ap)==TNULL)
1088 if ((p->t.op==INCAFT||p->t.op==DECAFT) && p->t.tr1->t.op==NAME) {
1089 *ap = paint(ncopy(p->t.tr1), p->t.type);
1092 if (p->t.op==STAR || p->t.op==PLUS)
1093 if (p1=sdelay(&p->t.tr1))
1096 return(sdelay(&p->t.tr2));
1101 * Propagate possible implicit type-changing operation
1103 union tree *paint(tp, type) register union tree *tp; register int type; {
1105 if (tp->t.type==type)
1107 if (tp->t.type==CHAR && type==INT)
1109 if (tp->t.type==CHAR || tp->t.type==UNCHAR)
1110 return(optim(tnode1(LOAD, type, tp, TNULL)));
1112 if (tp->t.op==AMPER && type&XTYPE)
1113 tp->t.tr1 = paint(tp->t.tr1, decref1(type));
1114 else if (tp->t.op==STAR)
1115 tp->t.tr1 = paint(tp->t.tr1, incref1(type));
1116 else if (tp->t.op==ASSIGN) {
1117 paint(tp->t.tr1, type);
1118 paint(tp->t.tr2, type);
1124 * Copy a tree1 node for a register variable.
1125 * Used by sdelay because if *reg-- is turned
1126 * into *reg; reg-- the *reg will in turn
1127 * be changed to some offset class, accidentally
1128 * modifying the reg--.
1130 union tree *ncopy(p) register union tree *p; {
1131 register union tree *q;
1133 q = getblk(sizeof(struct xtname));
1135 q->n.type = p->n.type;
1136 q->n.class = p->n.class;
1137 q->n.regno = p->n.regno;
1138 q->n.offset = p->n.offset;
1139 if (q->n.class==EXTERN || q->n.class==XOFFS)
1140 q->x.name = p->x.name;
1142 q->n.nloc = p->n.nloc;
1147 * If the tree1 can be immediately loaded into a register,
1148 * produce code to do so and return success.
1150 int chkleaf(tree1, table, reg) register union tree *tree1; struct table *table; int reg; {
1153 /*fprintf(stderr, "chkleaf(0x%08x, 0x%08x, 0x%08x)\n", tree1, table, reg);*/
1154 if (tree1->t.op!=STAR && dcalc(tree1, nreg-reg) > 12)
1157 lbuf.type = tree1->t.type;
1158 lbuf.degree = tree1->t.degree;
1160 #if 1 /* can't have garbage in lbuf.tr2, cexpr() will deref it if non-NULL */
1163 return(rcexpr1((union tree *)&lbuf, table, reg));
1167 * Compile a function argument.
1168 * If the stack is currently empty, put it in (sp)
1169 * rather than -(sp); this will save a pop.
1170 * Return the number of bytes pushed,
1171 * for future popping.
1173 int comarg(tree1, flagp) register union tree *tree1; int *flagp; {
1174 register int retval;
1178 if (tree1->t.op==STRASG) {
1179 size = tree1->F.mask;
1180 tree1 = tree1->t.tr1;
1181 tree1 = strfunc(tree1);
1182 if (size <= sizeof(_INT)) {
1186 if (size <= sizeof(_LONG)) {
1190 if (tree1->t.op!=NAME && tree1->t.op!=STAR) {
1191 error1("Unimplemented structure assignment");
1194 tree1 = tnode1(AMPER, STRUCT+PTR, tree1, TNULL);
1195 tree1 = tnode1(PLUS, STRUCT+PTR, tree1, tconst1(size, INT));
1196 tree1 = optim(tree1);
1197 retval = rcexpr1(tree1, regtab, 0);
1200 for (i=0; i<size; i++)
1201 fprintf(temp_fp[temp_fi], /*printf(*/"mov -(r%d),-(sp)\n", retval);
1204 fprintf(temp_fp[temp_fi], /*printf(*/"mov r%d,r0\n", retval);
1205 fprintf(temp_fp[temp_fi], /*printf(*/"mov $%o,r1\n", UNS(size));
1206 fprintf(temp_fp[temp_fi], /*printf(*/"L%d:mov -(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn1, isn1);
1213 if (nstack || isfloat(tree1) || tree1->t.type==LONG || tree1->t.type==UNLONG) {
1214 rcexpr1(tree1, sptab, 0);
1215 retval = arlength(tree1->t.type);
1218 rcexpr1(tree1, lsptab, 0);
1224 union tree *strfunc(tp) register union tree *tp; {
1225 if (tp->t.op != CALL)
1227 paint(tp, STRUCT+PTR);
1228 return(tnode1(STAR, STRUCT, tp, TNULL));
1232 * Compile an initializing expression
1234 void doinit(type, tree1) register int type; register union tree *tree1; {
1239 if (type==CHAR || type==UNCHAR) {
1240 fprintf(temp_fp[temp_fi], /*printf(*/".byte ");
1241 if (tree1->t.type&XTYPE)
1250 if (tree1->t.op==FTOI) {
1251 if (tree1->t.tr1->t.op!=FCON && tree1->t.tr1->t.op!=SFCON)
1253 tree1 = tree1->t.tr1;
1255 tree1->c.value = tree1->f.fvalue;
1257 tree1->c.value = fp_double_to_int(tree1->f.fvalue);
1260 } else if (tree1->t.op==LTOI) {
1261 if (tree1->t.tr1->t.op!=LCON)
1263 tree1 = tree1->t.tr1;
1264 lval = tree1->l.lvalue;
1266 tree1->c.value = lval;
1268 if (tree1->t.op == CON)
1269 fprintf(temp_fp[temp_fi], /*printf(*/"%o\n", UNS(tree1->c.value));
1270 else if (tree1->t.op==AMPER) {
1271 pname(tree1->t.tr1, 0);
1272 fputc('\n', temp_fp[temp_fi]) /*putchar('\n')*/;
1279 if (tree1->t.op==ITOF) {
1280 if (tree1->t.tr1->t.op==CON) {
1281 /* note: this should be changed to respect the signedness of the int */
1283 fval = tree1->t.tr1->c.value;
1285 fval = fp_int_to_double(tree1->t.tr1->c.value);
1289 } else if (tree1->t.op==FCON || tree1->t.op==SFCON) {
1290 fval = tree1->f.fvalue;
1291 } else if (tree1->t.op==LTOF) {
1292 if (tree1->t.tr1->t.op!=LCON)
1294 /* note: this should be changed to respect the signedness of the long */
1296 fval = tree1->t.tr1->l.lvalue;
1298 fval = fp_long_to_double(tree1->t.tr1->l.lvalue);
1302 /* note: value is still in emulated r0 and used again below */
1307 fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n",
1308 ((_UNSIGNED_INT *)&sfval)[0],
1309 ((_UNSIGNED_INT *)&sfval)[1]);
1311 sfval = fp_double_to_float(fval);
1312 fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n",
1313 (int)(sfval.h >> 16) & 0xffff,
1314 (int)sfval.h & 0xffff);
1319 fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o; %o; %o\n",
1320 ((_UNSIGNED_INT *)&fval)[0],
1321 ((_UNSIGNED_INT *)&fval)[1],
1322 ((_UNSIGNED_INT *)&fval)[2],
1323 ((_UNSIGNED_INT *)&fval)[3]);
1325 fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o; %o; %o\n",
1326 (int)(fval.h >> 16) & 0xffff,
1327 (int)fval.h & 0xffff,
1328 (int)(fval.l >> 16) & 0xffff,
1329 (int)fval.l & 0xffff);
1336 if (tree1->t.op==FTOL) {
1337 tree1 = tree1->t.tr1;
1338 if (tree1->t.op==SFCON)
1340 if (tree1->t.op!= FCON)
1343 lval = tree1->f.fvalue;
1345 lval = fp_double_to_long(tree1->f.fvalue);
1347 } else if (tree1->t.op==ITOL) {
1348 if (tree1->t.tr1->t.op != CON)
1350 if (uns(tree1->t.tr1))
1351 lval = (_UNSIGNED_INT)tree1->t.tr1->c.value;
1353 lval = tree1->t.tr1->c.value;
1354 } else if (tree1->t.op==LCON) {
1355 lval = tree1->l.lvalue;
1359 fprintf(temp_fp[temp_fi], /*printf(*/"%o; %o\n", UNS((lval>>16)), UNS(lval));
1363 error1("Illegal initialization");
1366 void movreg(r0, r1, tree1) int r0; int r1; union tree *tree1; {
1372 if (tree1->t.type==LONG || tree1->t.type == UNLONG) {
1373 if (r0>=nreg || r1>=nreg) {
1374 error1("register overflow: compiler error1");
1376 s = "mov r%d,r%d\nmov r%d,r%d\n";
1378 fprintf(temp_fp[temp_fi], /*printf(*/s, r0+1,r1+1,r0,r1);
1380 fprintf(temp_fp[temp_fi], /*printf(*/s, r0,r1,r0+1,r1+1);
1384 fprintf(temp_fp[temp_fi], /*printf(*/"mov%.1s r%d,r%d\n", &c, r0, r1);