📄 c11.c
字号:
#/* * C compiler */#include "c1.h"max(a, b){ if (a>b) return(a); return(b);}degree(at)struct tnode *at;{ register struct tnode *t, *t1; if ((t=at)==0 || t->op==0) return(0); if (t->op == CON) return(-3); if (t->op == AMPER) return(-2); if (t->op==ITOL) { if ((t1 = isconstant(t)) && (t1->value>=0 || t1->type==UNSIGN)) return(-2); if ((t1=t->tr1)->type==UNSIGN && opdope[t1->op]&LEAF) return(-1); } if ((opdope[t->op] & LEAF) != 0) { if (t->type==CHAR || t->type==FLOAT) return(1); return(0); } return(t->degree);}pname(ap, flag)struct tnode *ap;{ register i; register struct tnode *p; struct { int intx[2]; }; p = ap;loop: switch(p->op) { case LCON: printf("$%o", flag>10? p->lvalue.intx[1]:p->lvalue.intx[0]); return; case SFCON: case CON: printf("$"); psoct(p->value); return; case FCON: printf("L%d", (p->value>0? p->value: -p->value)); return; case NAME: i = p->offset; if (flag>10) i =+ 2; if (i) { psoct(i); if (p->class!=OFFS) putchar('+'); if (p->class==REG) regerr(); } switch(p->class) { case SOFFS: case XOFFS: pbase(p); case OFFS: printf("(r%d)", p->regno); return; case EXTERN: case STATIC: pbase(p); return; case REG: printf("r%d", p->nloc); return; } error("Compiler error: pname"); return; case AMPER: putchar('$'); p = p->tr1; if (p->op==NAME && p->class==REG) regerr(); goto loop; case AUTOI: printf("(r%d)%c", p->nloc, flag==1?0:'+'); return; case AUTOD: printf("%c(r%d)", flag==2?0:'-', p->nloc); return; case STAR: p = p->tr1; putchar('*'); goto loop; } error("pname called illegally");}regerr(){ error("Illegal use of register");}pbase(ap)struct tnode *ap;{ register struct tnode *p; p = ap; if (p->class==SOFFS || p->class==STATIC) printf("L%d", p->nloc); else printf("%.8s", &(p->nloc));}xdcalc(ap, nrleft)struct tnode *ap;{ register struct tnode *p; register d; p = ap; d = dcalc(p, nrleft); if (d<20 && p->type==CHAR) { if (nrleft>=1) d = 20; else d = 24; } return(d);}dcalc(ap, nrleft)struct tnode *ap;{ register struct tnode *p, *p1; if ((p=ap)==0) return(0); switch (p->op) { case NAME: if (p->class==REG) return(9); case AMPER: case FCON: case LCON: case AUTOI: case AUTOD: return(12); case CON: case SFCON: if (p->value==0) return(4); if (p->value==1) return(5); if (p->value > 0) return(8); return(12); case STAR: p1 = p->tr1; if (p1->op==NAME||p1->op==CON||p1->op==AUTOI||p1->op==AUTOD) if (p->type!=LONG) return(12); } if (p->type==LONG) nrleft--; return(p->degree <= nrleft? 20: 24);}notcompat(ap, ast, op)struct tnode *ap;{ register at, st; register struct tnode *p; p = ap; at = p->type; st = ast; if (st==0) /* word, byte */ return(at!=CHAR && at!=INT && at!=UNSIGN && at<PTR); if (st==1) /* word */ return(at!=INT && at!=UNSIGN && at<PTR); if (st==9 && (at&XTYPE)) return(0); st =- 2; if ((at&(~(TYPE+XTYPE))) != 0) at = 020; if ((at&(~TYPE)) != 0) at = at&TYPE | 020; if (st==FLOAT && at==DOUBLE) at = FLOAT; if (p->op==NAME && p->class==REG && op==ASSIGN && st==CHAR) return(0); return(st != at);}prins(op, c, itable)struct instab *itable;{ register struct instab *insp; register char *ip; for (insp=itable; insp->op != 0; insp++) { if (insp->op == op) { ip = c? insp->str2: insp->str1; if (ip==0) break; printf("%s", ip); return; } } error("No match' for op %d", op);}collcon(ap)struct tnode *ap;{ register op; register struct tnode *p; p = ap; if (p->op==STAR) { if (p->type==LONG+PTR) /* avoid *x(r); *x+2(r) */ return(0); p = p->tr1; } if (p->op==PLUS) { op = p->tr2->op; if (op==CON || op==AMPER) return(1); } return(0);}isfloat(at)struct tnode *at;{ register struct tnode *t; t = at; if ((opdope[t->op]&RELAT)!=0) t = t->tr1; if (t->type==FLOAT || t->type==DOUBLE) { nfloat = 1; return('f'); } return(0);}oddreg(t, areg)struct tnode *t;{ register reg; reg = areg; if (!isfloat(t)) { if (opdope[t->op]&RELAT) { if (t->tr1->type==LONG) return((reg+1) & ~01); return(reg); } switch(t->op) { case LLSHIFT: case ASLSHL: return((reg+1)&~01); case DIVIDE: case MOD: case ASDIV: case ASMOD: case PTOI: case ULSH: case ASULSH: reg++; case TIMES: case ASTIMES: return(reg|1); } } return(reg);}arlength(t){ if (t>=PTR) return(2); switch(t) { case INT: case CHAR: case UNSIGN: return(2); case LONG: return(4); case FLOAT: case DOUBLE: return(8); } return(1024);}/* * Strings for switch code. */char dirsw[] {"\cmp r0,$%o\n\jhi L%d\n\asl r0\n\jmp *L%d(r0)\n\.data\n\L%d:\" };char hashsw[] {"\mov r0,r1\n\clr r0\n\div $%o,r0\n\asl r1\n\jmp *L%d(r1)\n\.data\n\L%d:\"};/* * If the unsigned casts below won't compile, * try using the calls to lrem and ldiv. */pswitch(afp, alp, deflab)struct swtab *afp, *alp;{ int ncase, i, j, tabs, worst, best, range; register struct swtab *swp, *fp, *lp; int *poctab; fp = afp; lp = alp; if (fp==lp) { printf("jbr L%d\n", deflab); return; } isn++; if (sort(fp, lp)) return; ncase = lp-fp; lp--; range = lp->swval - fp->swval; /* direct switch */ if (range>0 && range <= 3*ncase) { if (fp->swval) printf("sub $%o,r0\n", fp->swval); printf(dirsw, range, deflab, isn, isn); isn++; for (i=fp->swval; ; i++) { if (i==fp->swval) { printf("L%d\n", fp->swlab); if (fp==lp) break; fp++; } else printf("L%d\n", deflab); } printf(".text\n"); return; } /* simple switch */ if (ncase<10) { for (fp = afp; fp<=lp; fp++) breq(fp->swval, fp->swlab); printf("jbr L%d\n", deflab); return; } /* hash switch */ best = 077777; poctab = getblk(((ncase+2)/2) * sizeof(*poctab)); for (i=ncase/4; i<=ncase/2; i++) { for (j=0; j<i; j++) poctab[j] = 0; for (swp=fp; swp<=lp; swp++) /* lrem(0, swp->swval, i) */ poctab[(unsigned)swp->swval%i]++; worst = 0; for (j=0; j<i; j++) if (poctab[j]>worst) worst = poctab[j]; if (i*worst < best) { tabs = i; best = i*worst; } } i = isn++; printf(hashsw, tabs, i, i); isn++; for (i=0; i<tabs; i++) printf("L%d\n", isn+i); printf(".text\n"); for (i=0; i<tabs; i++) { printf("L%d:", isn++); for (swp=fp; swp<=lp; swp++) { /* lrem(0, swp->swval, tabs) */ if ((unsigned)swp->swval%tabs == i) { /* ldiv(0, swp->swval, tabs) */ breq((unsigned)swp->swval/tabs, swp->swlab); } } printf("jbr L%d\n", deflab); }}breq(v, l){ if (v==0) printf("tst r0\n"); else printf("cmp r0,$%o\n", v); printf("jeq L%d\n", l);}sort(afp, alp)struct swtab *afp, *alp;{ register struct swtab *cp, *fp, *lp; int intch, t; fp = afp; lp = alp; while (fp < --lp) { intch = 0; for (cp=fp; cp<lp; cp++) { if (cp->swval == cp[1].swval) { error("Duplicate case (%d)", cp->swval); return(1); } if (cp->swval > cp[1].swval) { intch++; t = cp->swval; cp->swval = cp[1].swval; cp[1].swval = t; t = cp->swlab; cp->swlab = cp[1].swlab; cp[1].swlab = t; } } if (intch==0) break; } return(0);}ispow2(atree){ register int d; register struct tnode *tree; tree = atree; if (!isfloat(tree) && tree->tr2->op==CON) { d = tree->tr2->value; if (d>1 && (d&(d-1))==0) return(d); } return(0);}pow2(atree)struct tnode *atree;{ register int d, i; register struct tnode *tree; tree = atree; if (d = ispow2(tree)) { for (i=0; (d=>>1)!=0; i++); tree->tr2->value = i; switch (tree->op) { case TIMES: tree->op = LSHIFT; break; case ASTIMES: tree->op = ASLSH; break; case DIVIDE: tree->op = ULSH; tree->tr2->value = -i; break; case ASDIV: tree->op = ASULSH; tree->tr2->value = -i; break; case MOD: tree->op = AND; tree->tr2->value = (1<<i)-1; break; case ASMOD: tree->op = ASAND; tree->tr2->value = (1<<i)-1; break; default: error("pow2 botch"); } tree = optim(tree); } return(tree);}cbranch(atree, albl, cond, areg)struct tnode *atree;{ int l1, op; register lbl, reg; register struct tnode *tree; lbl = albl; reg = areg;again: if ((tree=atree)==0) return; switch(tree->op) { case LOGAND: if (cond) { cbranch(tree->tr1, l1=isn++, 0, reg); cbranch(tree->tr2, lbl, 1, reg); label(l1); } else { cbranch(tree->tr1, lbl, 0, reg); cbranch(tree->tr2, lbl, 0, reg); } return; case LOGOR: if (cond) { cbranch(tree->tr1, lbl, 1, reg); cbranch(tree->tr2, lbl, 1, reg); } else { cbranch(tree->tr1, l1=isn++, 1, reg); cbranch(tree->tr2, lbl, 0, reg); label(l1); } return; case EXCLA: cbranch(tree->tr1, lbl, !cond, reg); return; case SEQNC:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -