📄 span.c
字号:
#include "l.h"voidspan(void){ Prog *p, *q; long v, c, idat; int m, n, again; xdefine("etext", STEXT, 0L); idat = INITDAT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; n = 0; if(p->to.type == D_BRANCH) if(p->pcond == P) p->pcond = p; if((q = p->pcond) != P) if(q->back != 2) n = 1; p->back = n; if(p->as == AADJSP) { p->to.type = D_SP; v = -p->from.offset; p->from.offset = v; p->as = AADDL; if(v < 0) { p->as = ASUBL; v = -v; p->from.offset = v; } if(v == 0) p->as = ANOP; } } n = 0;start: if(debug['v']) Bprint(&bso, "%5.2f span\n", cputime()); Bflush(&bso); c = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->to.type == D_BRANCH) if(p->back) p->pc = c; asmins(p); p->pc = c; m = andptr-and; p->mark = m; c += m; }loop: n++; if(debug['v']) Bprint(&bso, "%5.2f span %d\n", cputime(), n); Bflush(&bso); if(n > 50) { print("span must be looping\n"); errorexit(); } again = 0; c = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->to.type == D_BRANCH) { if(p->back) p->pc = c; asmins(p); m = andptr-and; if(m != p->mark) { p->mark = m; again++; } } p->pc = c; c += p->mark; } if(again) { textsize = c; goto loop; } if(INITRND) { INITDAT = rnd(c, INITRND); if(INITDAT != idat) { idat = INITDAT; goto start; } } xdefine("etext", STEXT, c); if(debug['v']) Bprint(&bso, "etext = %lux\n", c); Bflush(&bso); for(p = textp; p != P; p = p->pcond) p->from.sym->value = p->pc; textsize = c - INITTEXT;}voidxdefine(char *p, int t, long v){ Sym *s; s = lookup(p, 0); if(s->type == 0 || s->type == SXREF) { s->type = t; s->value = v; } if(s->type == STEXT && s->value == 0) s->value = v;}voidputsymb(char *s, int t, long v, int ver){ int i, f; if(t == 'f') s++; lput(v); if(ver) t += 'a' - 'A'; cput(t+0x80); /* 0x80 is variable length */ if(t == 'Z' || t == 'z') { cput(s[0]); for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { cput(s[i]); cput(s[i+1]); } cput(0); cput(0); i++; } else { for(i=0; s[i]; i++) cput(s[i]); cput(0); } symsize += 4 + 1 + i + 1; if(debug['n']) { if(t == 'z' || t == 'Z') { Bprint(&bso, "%c %.8lux ", t, v); for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); Bprint(&bso, "/%x", f); } Bprint(&bso, "\n"); return; } if(ver) Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver); else Bprint(&bso, "%c %.8lux %s\n", t, v, s); }}voidasmsym(void){ Prog *p; Auto *a; Sym *s; int h; s = lookup("etext", 0); if(s->type == STEXT) putsymb(s->name, 'T', s->value, s->version); for(h=0; h<NHASH; h++) for(s=hash[h]; s!=S; s=s->link) switch(s->type) { case SCONST: putsymb(s->name, 'D', s->value, s->version); continue; case SDATA: putsymb(s->name, 'D', s->value+INITDAT, s->version); continue; case SBSS: putsymb(s->name, 'B', s->value+INITDAT, s->version); continue; case SFILE: putsymb(s->name, 'f', s->value, s->version); continue; } for(p=textp; p!=P; p=p->pcond) { s = p->from.sym; if(s->type != STEXT) continue; /* filenames first */ for(a=p->to.autom; a; a=a->link) if(a->type == D_FILE) putsymb(a->asym->name, 'z', a->aoffset, 0); else if(a->type == D_FILE1) putsymb(a->asym->name, 'Z', a->aoffset, 0); putsymb(s->name, 'T', s->value, s->version); /* frame, auto and param after */ putsymb(".frame", 'm', p->to.offset+4, 0); for(a=p->to.autom; a; a=a->link) if(a->type == D_AUTO) putsymb(a->asym->name, 'a', -a->aoffset, 0); else if(a->type == D_PARAM) putsymb(a->asym->name, 'p', a->aoffset, 0); } if(debug['v'] || debug['n']) Bprint(&bso, "symsize = %lud\n", symsize); Bflush(&bso);}voidasmlc(void){ long oldpc, oldlc; Prog *p; long v, s; oldpc = INITTEXT; oldlc = 0; for(p = firstp; p != P; p = p->link) { if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { if(p->as == ATEXT) curtext = p; if(debug['L']) Bprint(&bso, "%6lux %P\n", p->pc, p); continue; } if(debug['L']) Bprint(&bso, "\t\t%6ld", lcsize); v = (p->pc - oldpc) / MINLC; while(v) { s = 127; if(v < 127) s = v; cput(s+128); /* 129-255 +pc */ if(debug['L']) Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); v -= s; lcsize++; } s = p->line - oldlc; oldlc = p->line; oldpc = p->pc + MINLC; if(s > 64 || s < -64) { cput(0); /* 0 vv +lc */ cput(s>>24); cput(s>>16); cput(s>>8); cput(s); if(debug['L']) { if(s > 0) Bprint(&bso, " lc+%ld(%d,%ld)\n", s, 0, s); else Bprint(&bso, " lc%ld(%d,%ld)\n", s, 0, s); Bprint(&bso, "%6lux %P\n", p->pc, p); } lcsize += 5; continue; } if(s > 0) { cput(0+s); /* 1-64 +lc */ if(debug['L']) { Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } else { cput(64-s); /* 65-128 -lc */ if(debug['L']) { Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); Bprint(&bso, "%6lux %P\n", p->pc, p); } } lcsize++; } while(lcsize & 1) { s = 129; cput(s); lcsize++; } if(debug['v'] || debug['L']) Bprint(&bso, "lcsize = %ld\n", lcsize); Bflush(&bso);}intoclass(Adr *a){ long v; if(a->type >= D_INDIR || a->index != D_NONE) { if(a->index != D_NONE && a->scale == 0) { if(a->type == D_ADDR) { switch(a->index) { case D_EXTERN: case D_STATIC: return Yi32; case D_AUTO: case D_PARAM: return Yiauto; } return Yxxx; } return Ycol; } return Ym; } switch(a->type) { case D_AL: return Yal; case D_AX: return Yax; case D_CL: case D_DL: case D_BL: case D_AH: case D_CH: case D_DH: case D_BH: return Yrb; case D_CX: return Ycx; case D_DX: case D_BX: return Yrx; case D_SP: case D_BP: case D_SI: case D_DI: return Yrl; case D_F0+0: return Yf0; case D_F0+1: case D_F0+2: case D_F0+3: case D_F0+4: case D_F0+5: case D_F0+6: case D_F0+7: return Yrf; case D_NONE: return Ynone; case D_CS: return Ycs; case D_SS: return Yss; case D_DS: return Yds; case D_ES: return Yes; case D_FS: return Yfs; case D_GS: return Ygs; case D_GDTR: return Ygdtr; case D_IDTR: return Yidtr; case D_LDTR: return Yldtr; case D_MSW: return Ymsw; case D_TASK: return Ytask; case D_CR+0: return Ycr0; case D_CR+1: return Ycr1; case D_CR+2: return Ycr2; case D_CR+3: return Ycr3; case D_CR+4: return Ycr4; case D_CR+5: return Ycr5; case D_CR+6: return Ycr6; case D_CR+7: return Ycr7; case D_DR+0: return Ydr0; case D_DR+1: return Ydr1; case D_DR+2: return Ydr2; case D_DR+3: return Ydr3; case D_DR+4: return Ydr4; case D_DR+5: return Ydr5; case D_DR+6: return Ydr6; case D_DR+7: return Ydr7; case D_TR+0: return Ytr0; case D_TR+1: return Ytr1; case D_TR+2: return Ytr2; case D_TR+3: return Ytr3; case D_TR+4: return Ytr4; case D_TR+5: return Ytr5; case D_TR+6: return Ytr6; case D_TR+7: return Ytr7; case D_EXTERN: case D_STATIC: case D_AUTO: case D_PARAM: return Ym; case D_CONST: case D_ADDR: if(a->sym == S) { v = a->offset; if(v == 0) return Yi0; if(v == 1) return Yi1; if(v >= -128 && v <= 127) return Yi8; } return Yi32; case D_BRANCH: return Ybr; } return Yxxx;}voidasmidx(Adr *a, int base){ int i; switch(a->index) { default: goto bad; case D_NONE: i = 4 << 3; goto bas; case D_AX: case D_CX: case D_DX: case D_BX: case D_BP: case D_SI: case D_DI: i = reg[a->index] << 3; break; } switch(a->scale) { default: goto bad; case 1: break; case 2: i |= (1<<6); break; case 4: i |= (2<<6); break; case 8: i |= (3<<6); break; }bas: switch(base) { default: goto bad; case D_NONE: /* must be mod=00 */ i |= 5; break; case D_AX: case D_CX: case D_DX: case D_BX: case D_SP: case D_BP: case D_SI: case D_DI: i |= reg[base]; break; } *andptr++ = i; return;bad: diag("asmidx: bad address %D", a); *andptr++ = 0; return;}static voidput4(long v){ if(dlm && curp != P && reloca != nil){ dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1); reloca = nil; } andptr[0] = v; andptr[1] = v>>8; andptr[2] = v>>16; andptr[3] = v>>24; andptr += 4;}longvaddr(Adr *a){ int t; long v; Sym *s; t = a->type; v = a->offset; if(t == D_ADDR) t = a->index; switch(t) { case D_STATIC: case D_EXTERN: s = a->sym; if(s != nil) { if(dlm && curp != P) reloca = a; switch(s->type) { case SUNDEF: ckoff(s, v); case STEXT: case SCONST: v += s->value; break; default: v += INITDAT + s->value; } } } return v;}voidasmand(Adr *a, int r){ long v; int t; Adr aa; v = a->offset; t = a->type; if(a->index != D_NONE) { if(t >= D_INDIR) { t -= D_INDIR; if(t == D_NONE) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a, t); put4(v); return; } if(v == 0 && t != D_BP) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a, t); return; } if(v >= -128 && v < 128) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(a, t); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(a, t); put4(v); return; } switch(t) { default: goto bad; case D_STATIC: case D_EXTERN: aa.type = D_NONE+D_INDIR; break; case D_AUTO: case D_PARAM: aa.type = D_SP+D_INDIR; break; } aa.offset = vaddr(a); aa.index = a->index; aa.scale = a->scale; asmand(&aa, r); return; } if(t >= D_AL && t <= D_F0+7) { if(v) goto bad; *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3); return; } if(t >= D_INDIR) { t -= D_INDIR; if(t == D_NONE) { *andptr++ = (0 << 6) | (5 << 0) | (r << 3); put4(v); return; } if(t == D_SP) { if(v == 0) { *andptr++ = (0 << 6) | (4 << 0) | (r << 3); asmidx(a, D_SP); return; } if(v >= -128 && v < 128) { *andptr++ = (1 << 6) | (4 << 0) | (r << 3); asmidx(a, D_SP); *andptr++ = v; return; } *andptr++ = (2 << 6) | (4 << 0) | (r << 3); asmidx(a, D_SP); put4(v); return; } if(t >= D_AX && t <= D_DI) { if(v == 0 && t != D_BP) { *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3); return; } if(v >= -128 && v < 128) { andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3); andptr[1] = v; andptr += 2; return; } *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3); put4(v); return; } goto bad; } switch(a->type) { default: goto bad; case D_STATIC: case D_EXTERN: aa.type = D_NONE+D_INDIR; break; case D_AUTO: case D_PARAM: aa.type = D_SP+D_INDIR; break; } aa.index = D_NONE; aa.scale = 1; aa.offset = vaddr(a); asmand(&aa, r); return;bad: diag("asmand: bad address %D", a); return;}#define E 0xffuchar ymovtab[] ={/* push */ APUSHL, Ycs, Ynone, 0, 0x0e,E,0,0, APUSHL, Yss, Ynone, 0, 0x16,E,0,0, APUSHL, Yds, Ynone, 0, 0x1e,E,0,0, APUSHL, Yes, Ynone, 0, 0x06,E,0,0, APUSHL, Yfs, Ynone, 0, 0x0f,0xa0,E,0, APUSHL, Ygs, Ynone, 0, 0x0f,0xa8,E,0, APUSHW, Ycs, Ynone, 0, Pe,0x0e,E,0, APUSHW, Yss, Ynone, 0, Pe,0x16,E,0, APUSHW, Yds, Ynone, 0, Pe,0x1e,E,0, APUSHW, Yes, Ynone, 0, Pe,0x06,E,0, APUSHW, Yfs, Ynone, 0, Pe,0x0f,0xa0,E, APUSHW, Ygs, Ynone, 0, Pe,0x0f,0xa8,E,/* pop */ APOPL, Ynone, Yds, 0, 0x1f,E,0,0, APOPL, Ynone, Yes, 0, 0x07,E,0,0, APOPL, Ynone, Yss, 0, 0x17,E,0,0, APOPL, Ynone, Yfs, 0, 0x0f,0xa1,E,0, APOPL, Ynone, Ygs, 0, 0x0f,0xa9,E,0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -