📄 swt.c
字号:
#include "gc.h"intswcmp(const void *a1, const void *a2){ C1 *p1, *p2; p1 = (C1*)a1; p2 = (C1*)a2; if(p1->val < p2->val) return -1; return p1->val > p2->val;}voiddoswit(int g, Node *n){ Case *c; C1 *q, *iq; long def, nc, i; def = 0; nc = 0; for(c = cases; c->link != C; c = c->link) { if(c->def) { if(def) diag(n, "more than one default in switch"); def = c->label; continue; } nc++; } iq = alloc(nc*sizeof(C1)); q = iq; for(c = cases; c->link != C; c = c->link) { if(c->def) continue; q->label = c->label; q->val = c->val; q++; } qsort(iq, nc, sizeof(C1), swcmp); if(def == 0) def = breakpc; for(i=0; i<nc-1; i++) if(iq[i].val == iq[i+1].val) diag(n, "duplicate cases in switch %ld", iq[i].val); swit1(iq, nc, def, g, n);}#define N1 4 /* ncase: always linear */ /* else binary */voidswit1(C1 *q, int nc, long def, int g, Node *n){ C1 *r; int i; long v; Prog *sp1, *sp2; /* note that g and g+1 are not allocated */ if(nc <= N1) goto linear; /* * divide and conquer */ i = nc / 2; r = q+i; v = r->val; /* compare median */ if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g, n, g+1, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OLT); sp1 = p; gbranch(OGT); sp2 = p; gbranch(OGOTO); patch(p, r->label); patch(sp1, pc); swit1(q, i, def, g, n); patch(sp2, pc); swit1(r+1, nc-i-1, def, g, n); return;linear: for(i=0; i<nc; i++) { v = q->val; if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g+1, n, g, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OEQ); patch(p, q->label); q++; } gbranch(OGOTO); patch(p, def);}voidcas(void){ Case *c; c = alloc(sizeof(*c)); c->link = cases; cases = c;}intbitload(Node *b, int n1, int n2, int n3, Node *nn){ int sh, g, gs; long v; Node *l; Type *t; /* * n1 gets adjusted/masked value * n2 gets address of cell * n3 gets contents of cell */ gs = 0; t = tfield; l = b->left; g = regalloc(t, n3); if(n2 != D_NONE) { lcgen(l, n2, Z); n2 |= I_INDIR; gmove(t, t, n2, l, g, l); gmove(t, t, g, l, n1, l); } else cgen(l, g, nn); if(b->type->shift == 0 && typeu[b->type->etype]) { v = ~0 + (1L << b->type->nbits); gopcode(OAND, t, D_CONST, nodconst(v), g, l); } else { sh = 32 - b->type->shift - b->type->nbits; if(sh > 0) if(sh >= 8) { gs = regalloc(t, D_NONE); gmove(t, t, D_CONST, nodconst(sh), gs, l); gopcode(OASHL, t, gs, l, g, l); if(b->type->shift) regfree(gs); } else gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); sh += b->type->shift; if(sh > 0) { if(sh >= 8) { if(b->type->shift) { gs = regalloc(t, D_NONE); gmove(t, t, D_CONST, nodconst(sh), gs, l); } if(typeu[b->type->etype]) gopcode(OLSHR, t, gs, l, g, l); else gopcode(OASHR, t, gs, l, g, l); regfree(gs); } else { if(typeu[b->type->etype]) gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l); else gopcode(OASHR, t, D_CONST, nodconst(sh), g, l); } } } return g;}voidbitstore(Node *b, int n1, int n2, int n3, int result, Node *nn){ long v; Node *l; Type *t; int sh, g, gs; /* * n1 has adjusted/masked value * n2 has address of cell * n3 has contents of cell */ t = tfield; l = b->left; g = regalloc(t, D_NONE); v = ~0 + (1L << b->type->nbits); gopcode(OAND, t, D_CONST, nodconst(v), n1, l); gmove(t, t, n1, l, g, l); if(result != D_NONE) gmove(t, nn->type, n1, l, result, nn); sh = b->type->shift; if(sh > 0) { if(sh >= 8) { gs = regalloc(t, D_NONE); gmove(t, t, D_CONST, nodconst(sh), gs, l); gopcode(OASHL, t, gs, l, g, l); regfree(gs); } else gopcode(OASHL, t, D_CONST, nodconst(sh), g, l); } v <<= sh; gopcode(OAND, t, D_CONST, nodconst(~v), n3, l); gopcode(OOR, t, n3, l, g, l); gmove(t, t, g, l, n2|I_INDIR, l); regfree(g); regfree(n1); regfree(n2); regfree(n3);}longoutstring(char *s, long n){ long r; r = nstring; while(n) { string[mnstring] = *s++; mnstring++; nstring++; if(mnstring >= NSNAME) { gpseudo(ADATA, symstring, D_SCONST, 0L); memmove(p->to.sval, string, NSNAME); p->from.offset = nstring - NSNAME; p->from.displace = NSNAME; mnstring = 0; } n--; } return r;}longoutlstring(ushort *s, long n){ char buf[2]; int c; long r; while(nstring & 1) outstring("", 1); r = nstring; while(n > 0) { c = *s++; if(align(0, types[TCHAR], Aarg1)) { buf[0] = c>>8; buf[1] = c; } else { buf[0] = c; buf[1] = c>>8; } outstring(buf, 2); n -= sizeof(ushort); } return r;}intdoinc(Node *n, int f){ Node *l; int a;loop: if(n == Z) return 0; l = n->left; switch(n->op) { case OPOSTINC: case OPOSTDEC: if(f & POST) { a = n->addable; if(a >= INDEXED) { if(f & TEST) return 1; n->addable = 0; cgen(n, D_NONE, n); n->addable = a; } } break; case OAS: case OASLMUL: case OASLDIV: case OASLMOD: case OASMUL: case OASDIV: case OASMOD: case OASXOR: case OASOR: case OASADD: case OASSUB: case OASLSHR: case OASASHR: case OASASHL: case OASAND: case OPREINC: case OPREDEC: if(f & PRE) { a = n->addable; if(a >= INDEXED) { if(f & TEST) return 1; n->addable = 0; doinc(n, PRE); cgen(n, D_NONE, n); n->addable = a; return 0; } } break; case OFUNC: if(f & PRE) break; return 0; case ONAME: case OREGISTER: case OSTRING: case OCONST: case OANDAND: case OOROR: return 0; case OCOND: return 0; case OCOMMA: n = n->right; if(f & PRE) n = l; goto loop; } if(l != Z) if(doinc(l, f)) return 1; n = n->right; goto loop;}voidsetsp(void){ nextpc(); p->as = AADJSP; p->from.type = D_CONST; p->from.offset = 0;}voidadjsp(long o){ if(o != 0) { nextpc(); p->as = AADJSP; p->from.type = D_CONST; p->from.offset = o; argoff += o; }}intsimplv(Node *n){ if(n->addable <= INDEXED) return 0; while(n->op == OIND) n = n->left; if(n->op == ONAME) return 1; return 0;}inteval(Node *n, int g){ if(n->addable >= INDEXED) return D_TREE; g = regalloc(n->type, g); cgen(n, g, n); return g;}void outhist(Biobuf*);void zname(Biobuf*, Sym*, int);void zaddr(Biobuf*, Adr*, int);void zwrite(Biobuf*, Prog*, int, int);voidoutcode(void){ struct { Sym *sym; short type; } h[NSYM]; Prog *p; Sym *s; int f, sf, st, t, sym; Biobuf b; if(debug['S']) { for(p = firstp; p != P; p = p->link) if(p->as != ADATA && p->as != AGLOBL) pc--; for(p = firstp; p != P; p = p->link) { print("%P\n", p); if(p->as != ADATA && p->as != AGLOBL) pc++; } } f = open(outfile, OWRITE); if(f < 0) { diag(Z, "cant open %s", outfile); errorexit(); } Binit(&b, f, OWRITE); Bseek(&b, 0L, 2); outhist(&b); for(sym=0; sym<NSYM; sym++) { h[sym].sym = S; h[sym].type = 0; } sym = 1; for(p = firstp; p != P; p = p->link) { jackpot: sf = 0; s = p->from.sym; while(s != S) { sf = s->sym; if(sf < 0 || sf >= NSYM) sf = 0; t = p->from.type & D_MASK; if(h[sf].type == t) if(h[sf].sym == s) break; s->sym = sym; zname(&b, s, t); h[sym].sym = s; h[sym].type = t; sf = sym; sym++; if(sym >= NSYM) sym = 1; break; } st = 0; s = p->to.sym; while(s != S) { st = s->sym; if(st < 0 || st >= NSYM) st = 0; t = p->to.type & D_MASK; if(h[st].type == t) if(h[st].sym == s) break; s->sym = sym; zname(&b, s, t); h[sym].sym = s; h[sym].type = t; st = sym; sym++; if(sym >= NSYM) sym = 1; if(st == sf)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -