📄 c11.c
字号:
rcexpr(tree->tr1, efftab, reg); atree = tree->tr2; goto again; case ITOL: tree = tree->tr1; break; } op = tree->op; if (opdope[op]&RELAT && tree->tr1->op==ITOL && tree->tr2->op==ITOL) { tree->tr1 = tree->tr1->tr1; tree->tr2 = tree->tr2->tr1; if (op>=LESSEQ && op<=GREAT && (tree->tr1->type==UNSIGN || tree->tr2->type==UNSIGN)) tree->op = op = op+LESSEQP-LESSEQ; } if (tree->type==LONG || opdope[op]&RELAT&&tree->tr1->type==LONG) { longrel(tree, lbl, cond, reg); return; } rcexpr(tree, cctab, reg); op = tree->op; if ((opdope[op]&RELAT)==0) op = NEQUAL; else { l1 = tree->tr2->op; if ((l1==CON || l1==SFCON) && tree->tr2->value==0) op =+ 200; /* special for ptr tests */ else op = maprel[op-EQUAL]; } if (isfloat(tree)) printf("cfcc\n"); branch(lbl, op, !cond);}branch(lbl, aop, c){ register op; if(op=aop) prins(op, c, branchtab); else printf("jbr"); printf("\tL%d\n", lbl);}longrel(atree, lbl, cond, reg)struct tnode *atree;{ int xl1, xl2, xo, xz; register int op, isrel; register struct tnode *tree; if (reg&01) reg++; reorder(&atree, cctab, reg); tree = atree; isrel = 0; if (opdope[tree->op]&RELAT) { isrel++; op = tree->op; } else op = NEQUAL; if (!cond) op = notrel[op-EQUAL]; xl1 = xlab1; xl2 = xlab2; xo = xop; xlab1 = lbl; xlab2 = 0; xop = op; xz = xzero; xzero = !isrel || tree->tr2->op==ITOL && tree->tr2->tr1->op==CON && tree->tr2->tr1->value==0; if (tree->op==ANDN) { tree->op = TAND; tree->tr2 = optim(tnode(COMPL, LONG, tree->tr2)); } if (cexpr(tree, cctab, reg) < 0) { reg = rcexpr(tree, regtab, reg); printf("ashc $0,r%d\n", reg); branch(xlab1, op, 0); } xlab1 = xl1; xlab2 = xl2; xop = xo; xzero = xz;}/* * Tables for finding out how best to do long comparisons. * First dimen is whether or not the comparison is with 0. * Second is which test: e.g. a>b-> * cmp a,b * bgt YES (first) * blt NO (second) * cmp a+2,b+2 * bhi YES (third) * NO: ... * Note some tests may not be needed. */char lrtab[2][3][6] { 0, NEQUAL, LESS, LESS, GREAT, GREAT, NEQUAL, 0, GREAT, GREAT, LESS, LESS, EQUAL, NEQUAL, LESSEQP,LESSP, GREATQP,GREATP, 0, NEQUAL, LESS, LESS, GREATEQ,GREAT, NEQUAL, 0, GREAT, 0, 0, LESS, EQUAL, NEQUAL, EQUAL, 0, 0, NEQUAL,};xlongrel(f){ register int op, bno; op = xop; if (f==0) { if (bno = lrtab[xzero][0][op-EQUAL]) branch(xlab1, bno, 0); if (bno = lrtab[xzero][1][op-EQUAL]) { xlab2 = isn++; branch(xlab2, bno, 0); } if (lrtab[xzero][2][op-EQUAL]==0) return(1); } else { branch(xlab1, lrtab[xzero][2][op-EQUAL], 0); if (xlab2) label(xlab2); } return(0);}label(l){ printf("L%d:", l);}popstk(a){ switch(a) { case 0: return; case 2: printf("tst (sp)+\n"); return; case 4: printf("cmp (sp)+,(sp)+\n"); return; } printf("add $%o,sp\n", a);}error(s, p1, p2, p3, p4, p5, p6){ nerror++; fprintf(stderr, "%d: ", line); fprintf(stderr, s, p1, p2, p3, p4, p5, p6); putc('\n', stderr);}psoct(an){ register int n, sign; sign = 0; if ((n = an) < 0) { n = -n; sign = '-'; } printf("%c%o", sign, n);}/* * Read in an intermediate file. */#define STKS 100getree(){ struct tnode *expstack[STKS]; register struct tnode **sp; register t, op; static char s[9]; struct swtab *swp; double atof(); char numbuf[64]; struct tname *np; struct xtname *xnp; struct ftconst *fp; struct lconst *lp; struct fasgn *sap; int lbl, cond, lbl2, lbl3; curbase = funcbase; sp = expstack; for (;;) { if (sp >= &expstack[STKS]) error("Stack overflow botch"); op = geti(); if ((op&0177400) != 0177000) { error("Intermediate file error"); exit(1); } lbl = 0; switch(op =& 0377) { case SINIT: printf("%o\n", geti()); break; case EOFC: return; case BDATA: if (geti() == 1) { printf(".byte "); for (;;) { printf("%o", geti()); if (geti() != 1) break; printf(","); } printf("\n"); } break; case PROG: printf(".text\n"); break; case DATA: printf(".data\n"); break; case BSS: printf(".bss\n"); break; case SYMDEF: outname(s); printf(".globl%s%.8s\n", s[0]?" ":"", s); sfuncr.nloc = 0; break; case RETRN: printf("jmp cret\n"); break; case CSPACE: t = outname(s); printf(".comm %.8s,%o\n", t, geti()); break; case SSPACE: printf(".=.+%o\n", (t=geti())); totspace += (unsigned)t; break; case EVEN: printf(".even\n"); break; case SAVE: printf("jsr r5,csv\n"); break; case SETSTK: t = geti()-6; if (t==2) printf("tst -(sp)\n"); else if (t != 0) printf("sub $%o,sp\n", t); break; case PROFIL: t = geti(); printf("mov $L%d,r0\njsr pc,mcount\n", t); printf(".bss\nL%d:.=.+2\n.text\n", t); break; case SNAME: t = outname(s); printf("~%s=L%d\n", t+1, geti()); break; case ANAME: t = outname(s); printf("~%s=%o\n", t+1, geti()); break; case RNAME: t = outname(s); printf("~%s=r%d\n", t+1, geti()); break; case SWIT: t = geti(); line = geti(); curbase = funcbase; while(swp=getblk(sizeof(*swp)), swp->swlab = geti()) swp->swval = geti(); pswitch(funcbase, swp, t); break; case C3BRANCH: /* for fortran [sic] */ lbl = geti(); lbl2 = geti(); lbl3 = geti(); goto xpr; case CBRANCH: lbl = geti(); cond = geti(); case EXPR: xpr: line = geti(); if (sp != &expstack[1]) { error("Expression input botch"); exit(1); } nstack = 0; *sp = optim(*--sp); if (op==CBRANCH) cbranch(*sp, lbl, cond, 0); else if (op==EXPR) rcexpr(*sp, efftab, 0); else { if ((*sp)->type==LONG) { rcexpr(tnode(RFORCE, (*sp)->type, *sp), efftab, 0); printf("ashc $0,r0\n"); } else { rcexpr(*sp, cctab, 0); if (isfloat(*sp)) printf("cfcc\n"); } printf("jgt L%d\n", lbl3); printf("jlt L%d\njbr L%d\n", lbl, lbl2); } curbase = funcbase; break; case NAME: t = geti(); if (t==EXTERN) { np = getblk(sizeof(*xnp)); np->type = geti(); outname(np->name); } else { np = getblk(sizeof(*np)); np->type = geti(); np->nloc = geti(); } np->op = NAME; np->class = t; np->regno = 0; np->offset = 0; *sp++ = np; break; case CON: t = geti(); *sp++ = tconst(geti(), t); break; case LCON: geti(); /* ignore type, assume long */ t = geti(); op = geti(); if (t==0 && op>=0 || t == -1 && op<0) { *sp++ = tnode(ITOL, LONG, tconst(op, INT)); break; } lp = getblk(sizeof(*lp)); lp->op = LCON; lp->type = LONG; lp->lvalue = ((long)t<<16) + (unsigned)op; /* nonportable */ *sp++ = lp; break; case FCON: t = geti(); outname(numbuf); fp = getblk(sizeof(*fp)); fp->op = FCON; fp->type = t; fp->value = isn++; fp->fvalue = atof(numbuf); *sp++ = fp; break; case FSEL: *sp = tnode(FSEL, geti(), *--sp, NULL); t = geti(); (*sp++)->tr2 = tnode(COMMA, INT, tconst(geti(), INT), tconst(t, INT)); break; case STRASG: sap = getblk(sizeof(*sap)); sap->op = STRASG; sap->type = geti(); sap->mask = geti(); sap->tr1 = *--sp; sap->tr2 = NULL; *sp++ = sap; break; case NULLOP: *sp++ = tnode(0, 0, NULL, NULL); break; case LABEL: label(geti()); break; case NLABEL: t = outname(s); printf("%.8s:\n", t, t); break; case RLABEL: t = outname(s); printf("%.8s:\n~~%s:\n", t, t+1); break; case BRANCH: branch(geti(), 0); break; case SETREG: nreg = geti()-1; break; default: if (opdope[op]&BINARY) { if (sp < &expstack[1]) { error("Binary expression botch"); exit(1); } t = *--sp; *sp++ = tnode(op, geti(), *--sp, t); } else sp[-1] = tnode(op, geti(), sp[-1]); break; } }}geti(){ register i; i = getchar(); i += getchar()<<8; return(i);}outname(s){ register char *p, c; register n; p = s; n = 0; while (c = getchar()) { *p++ = c; n++; } do { *p++ = 0; } while (n++ < 8); return(s);}strasg(atp)struct fasgn *atp;{ register struct tnode *tp; register nwords, i; nwords = atp->mask/sizeof(int); tp = atp->tr1; if (tp->op != ASSIGN) { if (tp->op==RFORCE) { /* function return */ if (sfuncr.nloc==0) { sfuncr.nloc = isn++; printf(".bss\nL%d:.=.+%o\n.text\n", sfuncr.nloc, nwords*sizeof(int)); } atp->tr1 = tnode(ASSIGN, STRUCT, &sfuncr, tp->tr1); strasg(atp); printf("mov $L%d,r0\n", sfuncr.nloc); return; } if (tp->op==CALL) { rcexpr(tp, efftab, 0); return; } error("Illegal structure operation"); return; } tp->tr2 = strfunc(tp->tr2); if (nwords==1) setype(tp, INT); else if (nwords==sizeof(int)) setype(tp, LONG); else { if (tp->tr1->op!=NAME && tp->tr1->op!=STAR || tp->tr2->op!=NAME && tp->tr2->op!=STAR) { error("unimplemented structure assignment"); return; } tp->tr1 = tnode(AMPER, STRUCT+PTR, tp->tr1); tp->tr2 = tnode(AMPER, STRUCT+PTR, tp->tr2); tp->op = STRSET; tp->type = STRUCT+PTR; tp = optim(tp); rcexpr(tp, efftab, 0); if (nwords < 7) { for (i=0; i<nwords; i++) printf("mov (r1)+,(r0)+\n"); return; } if (nreg<=1) printf("mov r2,-(sp)\n"); printf("mov $%o,r2\n", nwords); printf("L%d:mov (r1)+,(r0)+\ndec\tr2\njne\tL%d\n", isn, isn); isn++; if (nreg<=1) printf("mov (sp)+,r2\n"); return; } rcexpr(tp, efftab, 0);}setype(p, t)register struct tnode *p;register t;{ for (;; p = p->tr1) { p->type = t; if (p->op==AMPER) t = decref(t); else if (p->op==STAR) t = incref(t); else if (p->op==ASSIGN) setype(p->tr2, t); else if (p->op!=PLUS) break; }}/* * Reduce the degree-of-reference by one. * e.g. turn "ptr-to-int" into "int". */decref(at){ register t; t = at; if ((t & ~TYPE) == 0) { error("Illegal indirection"); return(t); } return((t>>TYLEN) & ~TYPE | t&TYPE);}/* * Increase the degree of reference by * one; e.g. turn "int" to "ptr-to-int". */incref(t){ return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -