Add tests, fixes for tests, reinstate and type-convert stuff marked "bitrot"
[ccom.git] / c11.c
1 /*
2  *  C compiler
3  */
4
5 #include <math.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #ifdef __STDC__
9 #include <stdarg.h>
10 #define _va_start(argp, arg) va_start(argp, arg)
11 #else
12 #include <varargs.h>
13 #define _va_start(argp, arg) va_start(argp)
14 #endif
15 #include "c0.h" /* for outcode() prototype as getree() changed to outcode() */
16 #include "c1.h"
17
18 /*static void outname __P((char *s));*/
19 static void outname __P((char *buf, char *str));
20
21 int degree(t) register struct node *t; {
22         register struct node *t1;
23
24         if (t==NULL || t->n_op==0)
25                 return(0);
26         if (t->n_op == CON)
27                 return(-3);
28         if (t->n_op == AMPER)
29                 return(-2);
30         if (t->n_op==ITOL) {
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)))
33                         return(-2);
34                 if (uns(t1 = ((struct tnode *)t)->tn_tr1) && opdope1[t1->n_op]&LEAF)
35                         return(-1);
36         }
37         if ((opdope1[t->n_op] & LEAF) != 0) {
38                 if (t->n_type==CHAR || t->n_type==UNCHAR || t->n_type==FLOAT)
39                         return(1);
40                 return(0);
41         }
42         return(((struct tnode *)t)->tn_degree);
43 }
44
45 void pname(p, flag) register struct node *p; int flag; {
46         register int i;
47
48 loop:
49  /*fprintf(stderr, "pname %p\n", p);*/
50         switch(p->n_op) {
51
52         case LCON:
53 #define lp ((struct lnode *)p)
54                 fprintf(temp_fp[temp_fi], "$%o", flag<=10? UNS(lp->ln_lvalue>>16):
55                    UNS(lp->ln_lvalue));
56                 return;
57 #undef lp
58
59         case SFCON:
60         case CON:
61 #define cp ((struct cnode *)p)
62                 fprintf(temp_fp[temp_fi], "$");
63                 psoct(cp->cn_value);
64                 return;
65 #undef cp
66
67         case FCON:
68 #define fp ((struct fnode *)p)
69                 fprintf(temp_fp[temp_fi], "L%d", (fp->fn_value>0? fp->fn_value: -fp->fn_value));
70                 return;
71 #undef fp
72
73         case NAME:
74 #define np ((struct nnode *)p)
75  /*fprintf(stderr, "nn_class %d\n", np->nn_class);*/
76                 i = np->nn_offset;
77                 if (flag>10)
78                         i += 2;
79                 if (i) {
80                         psoct(i);
81                         if (np->nn_class!=OFFS)
82                                 fputc('+', temp_fp[temp_fi]);
83                         if (np->nn_class==REG)
84                                 error1("Illegal use of register");
85                 }
86                 switch(np->nn_class) {
87
88                 case SOFFS:
89 #define locnp ((struct locnnode *)np)
90                         fprintf(temp_fp[temp_fi], "L%d(r%d)", locnp->locnn_nloc, locnp->locnn_regno);
91                         break;
92 #undef locnp
93
94                 case XOFFS:
95 #define extnp ((struct extnnode *)np)
96                         fprintf(temp_fp[temp_fi], "%s(r%d)", extnp->extnn_name, extnp->extnn_regno);
97                         break;
98 #undef extnp
99
100                 case OFFS:
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);
104                         break;
105 #undef locnp
106
107                 case EXTERN:
108 #define extnp ((struct extnnode *)np)
109                         fprintf(temp_fp[temp_fi], "%s", extnp->extnn_name);
110                         break;
111 #undef extnp
112
113                 case STATIC:
114 #define locnp ((struct locnnode *)np)
115                         fprintf(temp_fp[temp_fi], "L%d", locnp->locnn_nloc);
116                         break;
117 #undef locnp
118
119                 case REG:
120 #define locnp ((struct locnnode *)np)
121                         fprintf(temp_fp[temp_fi], "r%d", locnp->locnn_nloc);
122                         break;
123 #undef locnp
124
125                 default:
126                         error1("Compiler error: pname");
127                         break;
128
129                 }
130                 return;
131 #undef np
132
133         case AMPER:
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");
138                 goto loop;
139
140         case AUTOI:
141 #define locnp ((struct locnnode *)p)
142                 fprintf(temp_fp[temp_fi], "(r%d)%s", locnp->locnn_nloc, flag==1?"":"+");
143                 return;
144 #undef locnp
145
146         case AUTOD:
147 #define locnp ((struct locnnode *)p)
148                 fprintf(temp_fp[temp_fi], "%s(r%d)", flag==2?"":"-", locnp->locnn_nloc);
149                 return;
150 #undef locnp
151
152         case STAR:
153                 p = ((struct tnode *)p)->tn_tr1;
154                 fputc('*', temp_fp[temp_fi]);
155                 goto loop;
156
157         }
158         error1("compiler error: bad pname");
159 }
160
161 int xdcalc(p, nrleft) register struct node *p; int nrleft; {
162         register int d;
163
164         if (p==NULL)
165                 return(0);
166         d = dcalc(p, nrleft);
167         if (d<20 && (p->n_type==CHAR || p->n_type==UNCHAR)) {
168                 if (nrleft>=1)
169                         d = 20;
170                 else
171                         d = 24;
172         }
173         return(d);
174 }
175
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;
179
180         if (p==NULL)
181                 return(0);
182         switch (p->n_op) {
183
184         case NAME:
185 #define np ((struct nnode *)p)
186                 if (np->nn_class==REG && np->nn_type!=CHAR && np->nn_type!=UNCHAR)
187                         return(9);
188 #undef np
189
190         case AMPER:
191         case FCON:
192         case LCON:
193         case AUTOI:
194         case AUTOD:
195                 return(12);
196
197         case CON:
198         case SFCON:
199 #define cp ((struct cnode *)p)
200                 if (cp->cn_value==0)
201                         return(4);
202                 if (cp->cn_value==1)
203                         return(5);
204                 if (cp->cn_value > 0)
205                         return(8);
206                 return(12);
207 #undef cp
208
209         case STAR:
210 #define tp ((struct tnode *)p)
211                 p1 = tp->tn_tr1;
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)
214                                 return(12);
215                 break;
216 #undef tp
217         }
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)
222                 nrleft--;
223         return(tp->tn_degree <= nrleft? 20: 24);
224 #undef tp
225 }
226
227 int notcompat(p, ast, deg, op) register struct node *p; int ast; int deg; int op; {
228         unsigned register at, st;
229
230         at = p->n_type;
231         /*
232          * an e or n UNCHAR is to be considered an UNSIGNED,
233          * as long as it is not pointed to.
234          */
235         if (at==UNCHAR && deg<0100 && deg>=20)
236                 at = UNSIGN;
237         st = ast;
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))
243                 return(0);
244         st -= 2;
245         if ((at&(~(TYPE+XTYPE))) != 0)
246                 at = 020;
247         if ((at&(~TYPE)) != 0)
248                 at = at&TYPE | 020;
249         if (st==FLOAT && at==DOUBLE)
250                 at = FLOAT;
251         if (p->n_op==NAME && ((struct nnode *)p)->nn_class==REG && op==ASSIGN && st==CHAR)
252                 return(0);
253         return(st != at);
254 }
255
256 int prins(op, c, itable, lbl) int op; int c; struct instab *itable; int lbl; {
257         register struct instab  *insp;
258         register char   *ip;
259         register int    skip;
260
261         skip = 0;
262         for (insp = itable; insp->iop != 0; insp++) {
263                 if (insp->iop == op) {
264                         ip = c ? insp->str2: insp->str1;
265                         if (!ip)
266                                 break;
267                         if (ip != jmijne) {
268                                 fprintf(temp_fp[temp_fi], ip, lbl);
269                         }
270                         else {
271                                 skip = isn1++;
272                                 fprintf(temp_fp[temp_fi], ip, skip);
273                         }
274                         return(skip);
275                 }
276         }
277         error1("No match' for op %d", op);
278         return(skip);
279 }
280
281 int collcon(p) register struct node *p; {
282         register int op;
283
284         if (p==NULL)
285                 return(0);
286         if (p->n_op==STAR) {
287                 if (p->n_type==LONG+PTR || p->n_type==UNLONG+PTR) /* avoid *x(r); *x+2(r) */
288                         return(0);
289                 p = ((struct tnode *)p)->tn_tr1;
290         }
291         if (p->n_op==PLUS) {
292                 op = ((struct tnode *)p)->tn_tr2->n_op;
293                 if (op==CON || op==AMPER)
294                         return(1);
295         }
296         return(0);
297 }
298
299 int isfloat(t) register struct node *t; {
300
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) {
304                 nfloat = 1;
305                 return('f');
306         }
307         return(0);
308 }
309
310 int oddreg(t, reg) register struct node *t; register int reg; {
311
312         if (!isfloat(t)) {
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);
317                         return(reg);
318 #undef tt
319                 }
320                 switch(t->n_op) {
321                 case ULLSHIFT:
322                 case UASLSHL:
323                 case LLSHIFT:
324                 case ASLSHL:
325                 case PTOI:
326                         return((reg+1)&~01);
327
328                 case DIVIDE:
329                 case MOD:
330                 case ASDIV:
331                 case ASMOD:
332                 case ULSH:
333                 case ASULSH:
334                         reg++;
335
336                 case TIMES:
337                 case ASTIMES:
338                         return(reg|1);
339                 }
340         }
341         return(reg);
342 }
343
344 int arlength(t) int t; {
345         if (t>=PTR)
346                 return(2);
347         switch(t) {
348
349         case INT:
350         case CHAR:
351         case UNSIGN:
352         case UNCHAR:
353                 return(2);
354
355         case UNLONG:
356         case LONG:
357                 return(4);
358
359         case FLOAT:
360         case DOUBLE:
361                 return(8);
362         }
363         error1("botch: peculiar type %d", t);
364         return(1024);
365 }
366
367 /*
368  * Strings for switch code.
369  */
370
371 /*
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.
375  * wfj 5/80 
376  */
377 char    dirsw[] = {"\
378 cmp     r0,$%o\n\
379 jhi     L%d\n\
380 asl     r0\n\
381 jmp     *L%d(r0)\n\
382 \t.data\n\
383 L%d:\
384 " };
385
386 char    hashsw[] = {"\
387 mov     r0,r1\n\
388 clr     r0\n\
389 div     $%o,r0\n\
390 asl     r1\n\
391 jmp     *L%d(r1)\n\
392 \t.data\n\
393 L%d:\
394 "};
395
396 /*
397  * If the unsigned casts below won't compile,
398  * try using the calls to lrem and ldiv.
399  */
400
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;
404         int *poctab;
405
406         fp = afp;
407         lp = alp;
408         if (fp==lp) {
409                 fprintf(temp_fp[temp_fi], "jbr  L%d\n", deflab);
410                 return;
411         }
412         isn1++;
413         if (sort(fp, lp))
414                 return;
415         ncase = lp-fp;
416         lp--;
417         range = lp->swval - fp->swval;
418         /* direct switch */
419         if (range>0 && range <= 3*ncase) {
420                 if (fp->swval)
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);
423                 isn1++;
424                 for (i=fp->swval; ; i++) {
425                         if (i==fp->swval) {
426                                 fprintf(temp_fp[temp_fi], "L%d\n", fp->swlab);
427                                 if (fp==lp)
428                                         break;
429                                 fp++;
430                         } else
431                                 fprintf(temp_fp[temp_fi], "L%d\n", deflab);
432                 }
433                 fprintf(temp_fp[temp_fi], ".text\n");
434                 return;
435         }
436         /* simple switch */
437         if (ncase<10) {
438                 for (fp = afp; fp<=lp; fp++)
439                         breq(fp->swval, fp->swlab);
440                 fprintf(temp_fp[temp_fi], "jbr  L%d\n", deflab);
441                 return;
442         }
443         /* hash switch */
444         best = 077777;
445         poctab = (int *)getblk(((ncase+2)/2) * sizeof(*poctab));
446         for (i=ncase/4; i<=ncase/2; i++) {
447                 for (j=0; j<i; j++)
448                         poctab[j] = 0;
449                 for (swp=fp; swp<=lp; swp++)
450                         /* lrem(0, swp->swval, i) */
451                         poctab[(_UNSIGNED_INT)swp->swval%i]++;
452                 worst = 0;
453                 for (j=0; j<i; j++)
454                         if (poctab[j]>worst)
455                                 worst = poctab[j];
456                 if (i*worst < best) {
457                         tabs = i;
458                         best = i*worst;
459                 }
460         }
461         i = isn1++;
462         fprintf(temp_fp[temp_fi], hashsw, UNS(tabs), i, i);
463         isn1++;
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);
474                         }
475                 }
476                 fprintf(temp_fp[temp_fi], "jbr  L%d\n", deflab);
477         }
478 }
479
480 void breq(v, l) int v; int l; {
481         if (v==0)
482                 fprintf(temp_fp[temp_fi], "tst  r0\n");
483         else
484                 fprintf(temp_fp[temp_fi], "cmp  r0,$%o\n", UNS(v));
485         fprintf(temp_fp[temp_fi], "jeq  L%d\n", l);
486 }
487
488 int sort(afp, alp) struct swtab *afp; struct swtab *alp; {
489         register struct swtab *cp, *fp, *lp;
490         int intch, t;
491
492         fp = afp;
493         lp = alp;
494         while (fp < --lp) {
495                 intch = 0;
496                 for (cp=fp; cp<lp; cp++) {
497                         if (cp->swval == cp[1].swval) {
498                                 error1("Duplicate case (%d)", cp->swval);
499                                 return(1);
500                         }
501                         if (cp->swval > cp[1].swval) {
502                                 intch++;
503                                 t = cp->swval;
504                                 cp->swval = cp[1].swval;
505                                 cp[1].swval = t;
506                                 t = cp->swlab;
507                                 cp->swlab = cp[1].swlab;
508                                 cp[1].swlab = t;
509                         }
510                 }
511                 if (intch==0)
512                         break;
513         }
514         return(0);
515 }
516
517 int ispow2(tree) register struct tnode *tree; {
518         register int d;
519
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)
523                         return(d);
524         }
525         return(0);
526 }
527
528 struct tnode *pow2(tree) register struct tnode *tree; {
529         register int d, i;
530
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) {
535
536                 case TIMES:
537                         tree->tn_op = LSHIFT;
538                         break;
539
540                 case ASTIMES:
541                         tree->tn_op = ASLSH;
542                         break;
543
544                 case PTOI:
545                         if (i==1 && tree->tn_tr1->n_op==MINUS && !isconstant(((struct tnode *)tree->tn_tr1)->tn_tr2)) {
546                                 tree->tn_op = PTOI1;
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();
552  return tree;
553                         }
554                         tree->tn_op = LLSHIFT;
555                         ((struct cnode *)tree->tn_tr2)->cn_value = -i;
556                         i = tree->tn_type;
557                         tree->tn_type = LONG;
558                         tree = tnode(LTOI, i, (struct node *)tree, (struct node *)NULL);
559                         break;
560
561                 case DIVIDE:
562                         tree->tn_op = ULSH;
563                         ((struct cnode *)tree->tn_tr2)->cn_value = -i;
564                         break;
565
566                 case ASDIV:
567                         tree->tn_op = ASULSH;
568                         ((struct cnode *)tree->tn_tr2)->cn_value = -i;
569                         break;
570
571                 case MOD:
572                         tree->tn_op = AND;
573                         ((struct cnode *)tree->tn_tr2)->cn_value = (1<<i)-1;
574                         break;
575
576                 case ASMOD:
577                         tree->tn_op = ASAND;
578                         ((struct cnode *)tree->tn_tr2)->cn_value = (1<<i)-1;
579                         break;
580
581                 default:
582                         error1("pow2 botch");
583                 }
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();
587         }
588         return(tree);
589 }
590
591 void cbranch1(atree, lbl, cond, reg) struct node *atree; register int lbl; int cond; register int reg; {
592         int l1, op;
593         register struct node *tree;
594
595 again:
596         if ((tree=atree)==NULL)
597                 return;
598         switch(tree->n_op) {
599
600         case LOGAND:
601 #define ttree ((struct tnode *)tree)
602                 if (cond) {
603                         cbranch1(ttree->tn_tr1, l1=isn1++, 0, reg);
604                         cbranch1(ttree->tn_tr2, lbl, 1, reg);
605                         label1(l1);
606                 } else {
607                         cbranch1(ttree->tn_tr1, lbl, 0, reg);
608                         cbranch1(ttree->tn_tr2, lbl, 0, reg);
609                 }
610                 return;
611 #undef ttree
612
613         case LOGOR:
614 #define ttree ((struct tnode *)tree)
615                 if (cond) {
616                         cbranch1(ttree->tn_tr1, lbl, 1, reg);
617                         cbranch1(ttree->tn_tr2, lbl, 1, reg);
618                 } else {
619                         cbranch1(ttree->tn_tr1, l1=isn1++, 1, reg);
620                         cbranch1(ttree->tn_tr2, lbl, 0, reg);
621                         label1(l1);
622                 }
623                 return;
624 #undef ttree
625
626         case EXCLA:
627 #define ttree ((struct tnode *)tree)
628                 cbranch1(ttree->tn_tr1, lbl, !cond, reg);
629                 return;
630 #undef ttree
631
632         case SEQNC:
633 #define ttree ((struct tnode *)tree)
634                 rcexpr1(ttree->tn_tr1, efftab, reg);
635                 atree = ttree->tn_tr2;
636                 goto again;
637 #undef ttree
638
639         case ITOL:
640                 tree = ((struct tnode *)tree)->tn_tr1;
641                 break;
642
643         case QUEST:
644 #define ttree ((struct tnode *)tree)
645                 l1 = isn1;
646                 isn1 += 2;
647                 cbranch1(ttree->tn_tr1, l1, 0, reg);
648                 cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr1, lbl, cond, reg);
649                 branch1(l1+1, 0, 0);
650                 label1(l1);
651                 cbranch1(((struct tnode *)ttree->tn_tr2)->tn_tr2, lbl, cond, reg);
652                 label1(l1+1);
653                 return;
654 #undef ttree
655
656         }
657         op = tree->n_op;
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;
667 #undef ttree
668         }
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);
673                 return;
674 #undef ttree
675         }
676         rcexpr1(tree, cctab, reg);
677         op = tree->n_op;
678         if ((opdope1[op]&RELAT)==0)
679                 op = NEQUAL;
680         else {
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 */
685                 else
686                         op = maprel[op-EQUAL];
687 #undef ttree
688         }
689         if (isfloat(tree))
690                 fprintf(temp_fp[temp_fi], "cfcc\n");
691         branch1(lbl, op, !cond);
692 }
693
694 void branch1(lbl, aop, c) int lbl; int aop; int c; {
695         register int    op,
696                         skip;
697
698         if(op = aop) {
699                 skip = prins(op, c, branchtab, lbl);
700         } else {
701                 fprintf(temp_fp[temp_fi], "jbr");
702                 skip = 0;
703         }
704         if (skip)
705                 fprintf(temp_fp[temp_fi], "\tL%d\nL%d:", lbl, skip);
706         else
707                 fprintf(temp_fp[temp_fi], "\tL%d\n", lbl);
708 }
709
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;
714
715         if (reg&01)
716                 reg++;
717         reorder((struct node **)&atree, cctab, reg);
718         tree = (struct node *)atree;
719         isrel = 0;
720         if (opdope1[tree->n_op]&RELAT) {
721                 isrel++;
722                 op = tree->n_op;
723         } else
724                 op = NEQUAL;
725         if (!cond)
726                 op = notrel[op-EQUAL];
727         xl1 = xlab1;
728         xl2 = xlab2;
729         xo = xop;
730         xlab1 = lbl;
731         xlab2 = 0;
732         xop = op;
733         xz = xzero;
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)
738                 ttree->tn_op = TAND;
739                 ttree->tn_tr2 = optim((struct node *)tnode(COMPL, LONG, ttree->tn_tr2, (struct node *)NULL));
740 #undef ttree
741         }
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);
746         }
747         xlab1 = xl1;
748         xlab2 = xl2;
749         xop = xo;
750         xzero = xz;
751 }
752
753 /*
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->
757  *      cmp     a,b
758  *      bgt     YES             (first)
759  *      blt     NO              (second)
760  *      cmp     a+2,b+2
761  *      bhi     YES             (third)
762  *  NO: ...
763  * Note some tests may not be needed.
764  *
765  * EQUAL = 60
766  * NEQUAL= 61
767  * LESSEQ= 62
768  * LESS  = 63
769  * GREATEQ=64
770  * GREAT  =65
771  * LESSEQP=66
772  * LESSP  =67
773  * GREATQP=68
774  * GREATP =69
775  *
776  * Third dimension (lrtab[][][x]) indexed by "x - EQUAL".
777  */
778 char    lrtab[2][3][10] = {
779         {
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}
783         },
784         {
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}
788         }
789 };
790
791 int xlongrel(f) int f; {
792         register int op, bno;
793
794         op = xop;
795         if (f==0) {
796                 if (bno = lrtab[xzero][0][op-EQUAL])
797                         branch1(xlab1, bno, 0);
798                 if (bno = lrtab[xzero][1][op-EQUAL]) {
799                         xlab2 = isn1++;
800                         branch1(xlab2, bno, 0);
801                 }
802                 if (lrtab[xzero][2][op-EQUAL]==0)
803                         return(1);
804         } else {
805                 branch1(xlab1, lrtab[xzero][2][op-EQUAL], 0);
806                 if (xlab2)
807                         label1(xlab2);
808         }
809         return(0);
810 }
811
812 void label1(l) int l; {
813         fprintf(temp_fp[temp_fi], "L%d:", l);
814 }
815
816 void popstk(a) int a; {
817         switch(a) {
818
819         case 0:
820                 return;
821
822         case 2:
823                 fprintf(temp_fp[temp_fi], "tst  (sp)+\n");
824                 return;
825
826         case 4:
827                 fprintf(temp_fp[temp_fi], "cmp  (sp)+,(sp)+\n");
828                 return;
829         }
830         fprintf(temp_fp[temp_fi], "add  $%o,sp\n", UNS(a));
831 }
832
833 void werror1(s) char *s; {
834
835         fprintf(stderr, "%d: %s\n",line,s);
836 }
837
838 #ifdef __STDC__
839 void error1(char *s, ...)
840 #else
841 void error1(s, va_alist) char *s; va_dcl
842 #endif
843 {
844         va_list argp;
845
846         nerror++;
847         fprintf(stderr, "%d: ", line);
848         _va_start(argp, s);
849         vfprintf(stderr, s, argp);
850         va_end(argp);
851         putc('\n', stderr);
852  abort();
853 }       
854
855 void psoct(an) int an; {
856         register int n;
857         register char *sign;
858
859         sign = "";
860         if ((n = an) < 0) {
861                 n = -n;
862                 sign = "-";
863         }
864         fprintf(temp_fp[temp_fi], "%s%o", sign, n);
865 }
866
867 /*
868  * Read in an intermediate file.
869  */
870 #define STKS    100
871 void getree() {
872  int c;
873  while ((c = fgetc(temp_fp[temp_fi])) != 0 && c != EOF)
874   putchar(c);
875 }
876 #ifdef __STDC__
877 void outcode(char *fmt, ...)
878 #else
879 void outcode(fmt, va_alist) char *fmt; va_dcl
880 #endif
881 {
882  va_list argp;
883  /*     struct node *expstack[STKS], **sp;*/
884  static struct node *expstack[STKS], **sp = expstack;
885         register struct node *tp;
886         register int t, op;
887         char s[80];             /* big for asm() stuff & long variable names */
888         struct swtab *swp;
889         long outloc;
890         int lbl, cond, lbl2, lbl3;
891  char *svtree = starttree();
892
893  /*     curbase = funcbase;
894         sp = expstack;*/
895  /*     for (;;) {*/
896  _va_start(argp, fmt);
897  for (; *fmt; ++fmt)
898   if (*fmt == 'B') {
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");
905                         exit(1);
906                 }*/
907                 lbl = 0;
908                 switch(op &= 0377) {
909
910         case SINIT:
911                 fprintf(temp_fp[temp_fi], "%o\n", UNS((_INT)va_arg(argp, int) /*geti()*/));
912                 break;
913
914         case EOFC:
915  va_end(argp);
916  endtree(svtree);
917                 return;
918
919         case BDATA:
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)));
923 #else
924                 if ((_INT)va_arg(argp, int) /*geti()*/ == 1) {
925                         fprintf(temp_fp[temp_fi], ".byte ");
926                         for (;;)  {
927                                 fprintf(temp_fp[temp_fi], "%o", UNS((_INT)va_arg(argp, int) /*geti()*/));
928                                 if ((_INT)va_arg(argp, int) /*geti()*/ != 1)
929                                         break;
930                                 fprintf(temp_fp[temp_fi], ",");
931                         }
932                         fprintf(temp_fp[temp_fi], "\n");
933                 }
934 #endif
935                 break;
936
937         case PROG:
938                 fprintf(temp_fp[temp_fi], ".text\n");
939                 break;
940
941         case DATA:
942                 fprintf(temp_fp[temp_fi], ".data\n");
943                 break;
944
945         case BSS:
946                 fprintf(temp_fp[temp_fi], ".bss\n");
947                 break;
948
949         case SYMDEF:
950                 outname(s/*)*/, va_arg(argp, char *));
951                 fprintf(temp_fp[temp_fi], ".globl\t%s\n", s);
952                 sfuncr.locnn_nloc = 0;
953                 break;
954
955         case RETRN:
956                 fprintf(temp_fp[temp_fi], "jmp\tcret\n");
957                 break;
958
959         case CSPACE:
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()*/));
962                 break;
963
964         case SSPACE:
965                 fprintf(temp_fp[temp_fi], ".=.+%o\n", UNS(t=(_INT)va_arg(argp, int) /*geti()*/));
966                 totspace += (_UNSIGNED_INT)t;
967                 break;
968
969         case EVEN:
970                 fprintf(temp_fp[temp_fi], ".even\n");
971                 break;
972
973         case SAVE:
974                 fprintf(temp_fp[temp_fi], "jsr  r5,csv\n");
975                 break;
976
977         case SETSTK:
978                 t = (_INT)va_arg(argp, int) /*geti()*/;
979                 if (t==2)
980                         fprintf(temp_fp[temp_fi], "tst  -(sp)\n");
981                 else if (t != 0)
982                         fprintf(temp_fp[temp_fi], "sub  $%o,sp\n", UNS(t));
983                 break;
984
985         case PROFIL:
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);
990                 break;
991
992         case ASSEM:
993                 outname(s/*)*/, va_arg(argp, char *));
994                 fprintf(temp_fp[temp_fi], "%s\n", s);
995                 break;
996
997         case SNAME:
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()*/);
1000                 break;
1001
1002         case ANAME:
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()*/));
1005                 break;
1006
1007         case RNAME:
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()*/);
1010                 break;
1011
1012         case SWIT:
1013                 t = (_INT)va_arg(argp, int) /*geti()*/;
1014                 line = (_INT)va_arg(argp, int) /*geti()*/;
1015  /*             curbase = funcbase;*/
1016  funcbase = locbase;
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);
1020                 break;
1021
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()*/;
1026                 goto xpr;
1027
1028         case CBRANCH:
1029                 lbl = (_INT)va_arg(argp, int) /*geti()*/;
1030                 cond = (_INT)va_arg(argp, int) /*geti()*/;
1031
1032         case EXPR:
1033         xpr:
1034                 line = (_INT)va_arg(argp, int) /*geti()*/;
1035                 if (sp != &expstack[1]) {
1036                         error1("Expression input botch");
1037                         exit(1);
1038                 }
1039                 --sp;
1040                 regpanic = 0;
1041                 if (setjmp(jmpbuf)) {
1042                         regpanic = 10;
1043                         fseek(/*stdout*/temp_fp[temp_fi], outloc, 0);
1044                 }
1045                 nstack = 0;
1046                 panicposs = 0;
1047                 *sp = tp = optim(*sp);
1048                 if (regpanic==0 && panicposs)
1049                         outloc = ftell(/*stdout*/temp_fp[temp_fi]);
1050                 if (op==CBRANCH)
1051                         cbranch1(tp, lbl, cond, 0);
1052                 else if (op==EXPR)
1053                         rcexpr1(tp, efftab, 0);
1054                 else {
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");
1058                         } else {
1059                                 rcexpr1(tp, cctab, 0);
1060                                 if (isfloat(tp))
1061                                         fprintf(temp_fp[temp_fi], "cfcc\n");
1062                         }
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);
1065                 }
1066  /*             curbase = funcbase;*/
1067                 break;
1068
1069         case NAME:
1070                 t = (_INT)va_arg(argp, int) /*geti()*/;
1071                 if (t==EXTERN) {
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);
1078 #undef extntp
1079                 } else {
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()*/;
1084 #undef locntp
1085                 }
1086 #define ntp ((struct nnode *)tp)
1087                 ntp->nn_op = NAME;
1088                 ntp->nn_class = t;
1089                 ntp->nn_regno = 0;
1090                 ntp->nn_offset = 0;
1091                 *sp++ = (struct node *)ntp;
1092                 break;
1093 #undef ntp
1094
1095         case CON:
1096                 t = (_INT)va_arg(argp, int) /*geti()*/;
1097                 *sp++ = (struct node *)tconst((_INT)va_arg(argp, int) /*geti()*/, t);
1098                 break;
1099
1100         case LCON:
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);
1107                         break;
1108                 }
1109                 tp = getblk(sizeof(struct lnode));
1110 #define ltp ((struct lnode *)tp)
1111                 ltp->ln_op = LCON;
1112                 ltp->ln_type = LONG;
1113                 ltp->ln_lvalue = ((_LONG)t<<16) + UNS(op); /* nonportable */
1114                 *sp++ = (struct node *)ltp;
1115                 break;
1116 #undef ltp
1117
1118         case FCON:
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)
1123                 ftp->fn_op = FCON;
1124                 ftp->fn_type = t;
1125                 ftp->fn_value = isn1++;
1126 #ifdef pdp11
1127                 ftp->fn_fvalue = atof(s);
1128 #else
1129                 ftp->fn_fvalue = fp_atof(s);
1130 #endif
1131                 *sp++ = tp;
1132                 break;
1133 #undef ftp
1134
1135         case FSEL:
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)
1145 #undef ttp
1146                         tp = paint(((struct tnode *)tp)->tn_tr1, ((struct tnode *)tp)->tn_type);
1147                 *sp++ = (struct node *)tp;
1148                 break;
1149
1150  /*     case STRASG:
1151                 tp = getblk(sizeof(struct fasgn));
1152                 tp->tn_op = STRASG;
1153                 tp->tn_type = (_INT)va_arg(argp, int) *//*geti()*//*;
1154                 tp->fa_mask = (_INT)va_arg(argp, int) *//*geti()*//*;
1155                 tp->tn_tr1 = *--sp;
1156                 tp->tn_tr2 = NULL;
1157                 *sp++ = tp;
1158                 break;*/
1159
1160         case NULLOP:
1161                 *sp++ = (struct node *)tnode(0, 0, (struct node *)NULL, (struct node *)NULL);
1162                 break;
1163
1164         case LABEL:
1165                 label1((_INT)va_arg(argp, int) /*geti()*/);
1166                 break;
1167
1168         case NLABEL:
1169                 outname(s/*)*/, va_arg(argp, char *));
1170                 fprintf(temp_fp[temp_fi], "%s:\n", s);
1171                 break;
1172
1173         case RLABEL:
1174                 outname(s/*)*/, va_arg(argp, char *));
1175                 fprintf(temp_fp[temp_fi], "%s:\n~~%s:\n", s, s+1);
1176                 break;
1177
1178         case BRANCH:
1179                 branch1((_INT)va_arg(argp, int) /*geti()*/, 0, 0);
1180                 break;
1181
1182         case SETREG:
1183                 nreg = (_INT)va_arg(argp, int) /*geti()*/-1;
1184                 break;
1185
1186         default:
1187                 if (opdope1[op]&BINARY) {
1188                         if (sp < &expstack[1]) {
1189                                 error1("Binary expression botch");
1190                                 exit(1);
1191                         }
1192                         tp = *--sp;
1193 #if 1
1194                         sp[-1] = (struct node *)tnode(op, (_INT)va_arg(argp, int) /*geti()*/, sp[-1], tp);
1195 #else
1196                         *sp++ = tnode(op, (_INT)va_arg(argp, int) /*geti()*/, *--sp, tp);
1197 #endif
1198                 } else
1199                         sp[-1] = (struct node *)tnode(op, (_INT)va_arg(argp, int) /*geti()*/, sp[-1], (struct node *)NULL);
1200                 break;
1201         }
1202         }
1203  va_end(argp);
1204  endtree(svtree);
1205 }
1206
1207 #if 0
1208 int geti() {
1209         register _INT i;
1210
1211         i = fgetc(temp_fp[temp_fi])/*getchar()*/ & 0xff;
1212         i |= (fgetc(temp_fp[temp_fi])/*getchar()*/ & 0xff) << 8;
1213         return(i);
1214 }
1215 #endif
1216
1217 #if 1
1218 static void outname(buf, str) char *buf; char *str; {
1219  if (*str)
1220   *buf++ = '_';
1221  strcpy(buf, str);
1222 }
1223 #else
1224 static void outname(s) register char *s; {
1225         register int c;
1226
1227 #if 1
1228         while ((c = fgetc(temp_fp[temp_fi])) != 0 && c != EOF)
1229 #else
1230         while (c = getchar())
1231 #endif
1232                 *s++ = c;
1233         *s++ = '\0';
1234 }
1235 #endif
1236
1237 void strasg(atp) struct tnode *atp; {
1238         register struct tnode *tp;
1239         register int nwords, i;
1240
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);
1246                 tp = tp->tn_tr2;
1247         }
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)));
1254                         }
1255                         atp/*->tn_tr1*/ = tnode(ASSIGN, STRUCT, (struct node *)&sfuncr, tp->tn_tr1);
1256  atp->tn_strp = tp->tn_strp;
1257                         strasg(atp);
1258                         fprintf(temp_fp[temp_fi], "mov  $L%d,r0\n", sfuncr.locnn_nloc);
1259                         return;
1260                 }
1261  /*             if (tp->tn_op==CALL) {
1262                         rcexpr1(tp, efftab, 0);
1263                         return;
1264                 }
1265                 error1("Illegal structure operation");
1266                 return;
1267         }*/
1268         tp->tn_tr2 = strfunc(tp->tn_tr2);
1269         if (nwords==1)
1270                 paint((struct node *)tp, INT);
1271         else if (nwords==sizeof(_INT))
1272                 paint((struct node *)tp, LONG);
1273         else {
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");
1277                         return;
1278                 }
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);
1281                 tp->tn_op = STRSET;
1282                 tp->tn_type = STRUCT+PTR;
1283                 rcexpr1(optim((struct node *)tp), efftab, 0);
1284                 if (nwords < 7) {
1285                         for (i=0; i<nwords; i++)
1286                                 fprintf(temp_fp[temp_fi], "mov  (r1)+,(r0)+\n");
1287                         return;
1288                 }
1289                 if (nreg<=1)
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);
1293                 isn1++;
1294                 if (nreg<=1)
1295                         fprintf(temp_fp[temp_fi], "mov  (sp)+,r2\n");
1296                 return;
1297         }
1298         rcexpr1((struct node *)tp, efftab, 0);
1299 }
1300
1301 /*
1302  * Reduce the degree-of-reference by one.
1303  * e.g. turn "ptr-to-int" into "int".
1304  */
1305 int decref1(t) register int t; {
1306         if ((t & ~TYPE) == 0) {
1307                 error1("Illegal indirection");
1308                 return(t);
1309         }
1310         return(((_UNSIGNED_INT)t>>TYLEN) & ~TYPE | t&TYPE);
1311 }
1312
1313 /*
1314  * Increase the degree of reference by
1315  * one; e.g. turn "int" to "ptr-to-int".
1316  */
1317 int incref1(t) register int t; {
1318         return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
1319 }