📄 asm.c
字号:
/* 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); if(s->type == STEXT) putsymb(s->name, 'T', s->value, s->version); else putsymb(s->name, 'L', 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);}voidputsymb(char *s, int t, long v, int ver){ int i, f; if(t == 'f') s++; LBEPUT(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); }}#define MINLC 4voidasmlc(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);}voiddatblk(long s, long n, int str){ Prog *p; char *cast; long l, fl, j, d; int i, c; memset(buf.dbuf, 0, n+100); for(p = datap; p != P; p = p->link) { curp = p; if(str != (p->from.sym->type == SSTRING)) continue; l = p->from.sym->value + p->from.offset - s; c = p->reg; i = 0; if(l < 0) { if(l+c <= 0) continue; while(l < 0) { l++; i++; } } if(l >= n) continue; if(p->as != AINIT && p->as != ADYNT) { for(j=l+(c-i)-1; j>=l; j--) if(buf.dbuf[j]) { print("%P\n", p); diag("multiple initialization"); break; } } switch(p->to.type) { default: diag("unknown mode in initialization\n%P", p); break; case D_FCONST: switch(c) { default: case 4: fl = ieeedtof(p->to.ieee); cast = (char*)&fl; for(; i<c; i++) { buf.dbuf[l] = cast[fnuxi8[i+4]]; l++; } break; case 8: cast = (char*)p->to.ieee; for(; i<c; i++) { buf.dbuf[l] = cast[fnuxi8[i]]; l++; } break; } break; case D_SCONST: for(; i<c; i++) { buf.dbuf[l] = p->to.sval[i]; l++; } break; case D_CONST: d = p->to.offset; if(p->to.sym) { switch(p->to.sym->type) { case STEXT: case SLEAF: case SSTRING: d += p->to.sym->value; break; case SDATA: case SBSS: d += p->to.sym->value + INITDAT; break; } } cast = (char*)&d; switch(c) { default: diag("bad nuxi %d %d\n%P", c, i, curp); break; case 1: for(; i<c; i++) { buf.dbuf[l] = cast[inuxi1[i]]; l++; } break; case 2: for(; i<c; i++) { buf.dbuf[l] = cast[inuxi2[i]]; l++; } break; case 4: for(; i<c; i++) { buf.dbuf[l] = cast[inuxi4[i]]; l++; } break; } break; } } write(cout, buf.dbuf, n);}#define OP_RRR(op,r1,r2,r3)\ (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))#define OP_IRR(op,i,r2,r3)\ (op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))#define OP_SRR(op,s,r2,r3)\ (op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))#define OP_FRRR(op,r1,r2,r3)\ (op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))#define OP_JMP(op,i)\ ((op)|((i)&0x3ffffffL))#define OP(x,y)\ (((x)<<3)|((y)<<0))#define SP(x,y)\ (((x)<<29)|((y)<<26))#define BCOND(x,y)\ (((x)<<19)|((y)<<16))#define MMU(x,y)\ (SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))#define FPF(x,y)\ (SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))#define FPD(x,y)\ (SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))#define FPW(x,y)\ (SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))int vshift(int);intasmout(Prog *p, Optab *o, int aflag){ long o1, o2, o3, o4, o5, o6, o7, v; Prog *ct; int r, a; o1 = 0; o2 = 0; o3 = 0; o4 = 0; o5 = 0; o6 = 0; o7 = 0; switch(o->type) { default: diag("unknown type %d", o->type); if(!debug['a']) prasm(p); break; case 0: /* pseudo ops */ if(aflag) { if(p->link) { if(p->as == ATEXT) { ct = curtext; o2 = autosize; curtext = p; autosize = p->to.offset + 4; o1 = asmout(p->link, oplook(p->link), aflag); curtext = ct; autosize = o2; } else o1 = asmout(p->link, oplook(p->link), aflag); } return o1; } break; case 1: /* mov[v] r1,r2 ==> OR r1,r0,r2 */ o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg); break; case 2: /* add/sub r1,[r2],r3 */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg); break; case 3: /* mov $soreg, r ==> or/add $i,o,r */ v = regoff(&p->from); r = p->from.reg; if(r == NREG) r = o->param; a = AADDU; if(o->a1 == C_ANDCON) a = AOR; o1 = OP_IRR(opirr(a), v, r, p->to.reg); break; case 4: /* add $scon,[r1],r2 */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(opirr(p->as), v, r, p->to.reg); break; case 5: /* syscall */ if(aflag) return 0; o1 = oprrr(p->as); break; case 6: /* beq r1,[r2],sbra */ if(aflag) return 0; if(p->cond == P) v = -4 >> 2; else v = (p->cond->pc - pc-4) >> 2; if(((v << 16) >> 16) != v) diag("short branch too far: %d\n%P", v, p); o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg); break; case 7: /* mov r, soreg ==> sw o(r) */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); o1 = OP_IRR(opirr(p->as), v, r, p->from.reg); break; case 8: /* mov soreg, r ==> lw o(r) */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg); break; case 9: /* asl r1,[r2],r3 */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg); break; case 10: /* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */ v = regoff(&p->from); r = AOR; if(v < 0) r = AADDU; o1 = OP_IRR(opirr(r), v, 0, REGTMP); r = p->reg; if(r == NREG) r = p->to.reg; o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); break; case 11: /* jmp lbra */ if(aflag) return 0; if(p->cond == P) v = p->pc >> 2; else v = p->cond->pc >> 2; o1 = OP_JMP(opirr(p->as), v); if(!debug['Y'] && p->link && p->cond && isnop(p->link)) { nop.branch.count--; nop.branch.outof--; nop.jump.outof++; o2 = asmout(p->cond, oplook(p->cond), 1); if(o2) { o1 += 1; if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p); LPUT(o1); LPUT(o2); return 1; } } break; case 12: /* movbs r,r */ v = 16; if(p->as == AMOVB) v = 24; o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg); o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg); break; case 13: /* movbu r,r */ if(p->as == AMOVBU) o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg); else o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg); break; case 16: /* sll $c,[r1],r2 */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; /* OP_SRR will use only the low 5 bits of the shift value */ if(v >= 32 && vshift(p->as)) o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg); else o1 = OP_SRR(opirr(p->as), v, r, p->to.reg); break; case 18: /* jmp [r1],0(r2) */ if(aflag) return 0; r = p->reg; if(r == NREG) r = o->param; o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r); break; case 19: /* mov $lcon,r ==> lu+or */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -