📄 asm.c
字号:
case 17: /* floating ea,Fn */ *op++ = o->opcode1; a = asmea(p, &p->from); b = asmea(p, &p->to); if((b & 0170) != 0100) /* dst Fn */ goto bad; if((a & 0170) == 0100) { /* both Fn */ opa[1] |= (a&7) << 10; opa[1] |= (b&7) << 7; break; } t |= a; opa[1] = o->opcode2; opa[1] |= (b&7) << 7; break; case 18: /* floating branchs */ if(p->to.type != D_BRANCH) goto bad; v = p->pcond->pc - p->pc - 2; if(v < -32768L || v >= 32768L) goto bad; *op++ = v; break; case 19: /* floating dec and branch */ if(p->to.type != D_BRANCH) goto bad; *op++ = o->opcode1; v = p->pcond->pc - p->pc - 2; if(v < -32768L || v >= 32768L) goto bad; *op++ = v; a = asmea(p, &p->from); if((a & 0170) != 0) goto bad; t |= a; break; case 20: /* ftst ea */ *op++ = o->opcode1; if(p->from.type != D_NONE) goto bad; a = asmea(p, &p->to); if((a & 0170) == 0100) { /* Fn */ opa[1] |= (a&7) << 10; break; } t |= a; opa[1] = o->opcode2; break; case 21: /* fneg */ *op++ = o->opcode1; if(p->from.type == D_NONE) { b = asmea(p, &p->to); a = b; } else { a = asmea(p, &p->from); b = asmea(p, &p->to); } if((b & 0170) != 0100) /* dst Fn */ goto bad; if((a & 0170) == 0100) { /* both Fn */ opa[1] |= (a&7) << 10; opa[1] |= (b&7) << 7; break; } t |= a; opa[1] = o->opcode2; opa[1] |= (b&7) << 7; break; case 22: /* floating cmp Fn,ea */ *op++ = o->opcode1; a = asmea(p, &p->from); b = asmea(p, &p->to); if((a & 0170) != 0100) /* dst Fn */ goto bad; if((b & 0170) == 0100) { /* both Fn */ opa[1] |= (b&7) << 10; opa[1] |= (a&7) << 7; break; } t |= b; opa[1] = o->opcode2; opa[1] |= (a&7) << 7; break; case 23: /* word, long */ op = opa; a = asmea(p, &p->to); if(a == ((7<<3)|4)) return; if(a == ((7<<3)|1)) { if(p->as == AWORD) { op = opa; *op++ = opa[1]; } return; } if(a == ((7<<3)|0)) { if(p->as == ALONG) { *op++ = opa[0]; opa[0] = 0; } return; } goto bad; case 24: /* bit field */ a = ((p->to.field&31)<<6) | (p->from.field&31); if(p->as == ABFINS) { b = asmea(p, &p->from); if((b&0170) != 0) goto bad; a |= b<<12; *op++ = a; a = asmea(p, &p->to); } else { if(p->to.type != D_NONE) { b = asmea(p, &p->to); if((b&0170) != 0) goto bad; a |= b<<12; } *op++ = a; a = asmea(p, &p->from); } t |= a; a &= 0170; if(a == 010 || a == 030 || a == 040 || a == 074) goto bad; break; case 25: /* movem */ if(p->from.type == D_CONST) { /* registers -> memory */ asmea(p, &p->from); a = asmea(p, &p->to); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 030) goto bad; t |= a; break; } if(p->to.type == D_CONST) { /* memory -> registers */ t |= 0x400; asmea(p, &p->to); a = asmea(p, &p->from); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 040) goto bad; t |= a; break; } goto bad; case 26: /* chk */ a = asmea(p, &p->from); if((a&0170) == 010) goto bad; b = asmea(p, &p->to); if((b&0170) != 0) goto bad; t |= a; t |= b<<9; break; case 27: /* btst */ a = asmea(p, &p->from); if(a == 074) { t = o->opcode1; } else if((a&0170) != 0) goto bad; b = asmea(p, &p->to); if(b == 074 || (b&0170) == 010) goto bad; t |= b; break; case 28: /* fmovem */ if(p->from.type == D_CONST) { /* registers -> memory */ b = p->from.offset & 0xff; b |= 0xf000; /* control or postinc */ *op++ = b; a = asmea(p, &p->to); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 030) goto bad; if(b == 040) op[-1] &= ~0x1000; /* predec */ t |= a; break; } if(p->to.type == D_CONST) { /* memory -> registers */ b = p->to.offset & 0xff; b |= 0xd000; /* control or postinc */ *op++ = b; a = asmea(p, &p->from); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 040) goto bad; t |= a; break; } goto bad; case 29: /* fmovemc */ if(p->from.type == D_CONST) { /* registers -> memory */ b = (p->from.offset & 0x7) << 10; b |= 0xa000; *op++ = b; a = asmea(p, &p->to); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 030) goto bad; t |= a; break; } if(p->to.type == D_CONST) { /* memory -> registers */ b = (p->to.offset & 0x7) << 10; b |= 0x8000; *op++ = b; a = asmea(p, &p->from); if(a == 074) goto bad; b = a & 0170; if(b == 000 || b == 010 || b == 040) goto bad; t |= a; break; } goto bad; case 30: /* trap */ if(p->to.type == D_CONST) { t |= p->to.offset & 0xf; break; } goto bad; case 31: /* chk2, cmp2 */ b = asmea(p, &p->to); a = b & 0170; if(a == 000 || a == 010) { *op++ = o->opcode1 | (b << 12); t |= asmea(p, &p->from); break; } goto bad; case 32: /* casew */ /* jmp (0,pc,r0.w*1) */ casepc = p->pc; *op++ = o->opcode1; break; case 33: /* bcase */ q = copyp(p); q->as = ADATA; q->to.type = D_CONST; q->to.offset = p->pcond->pc - casepc - 2; q->from.displace = 2; q->link = datap; datap = q; if(debug['a']) Bprint(&bso, "%P\n", q); op = opa; return; case 34: /* moves */ op++; a = asmea(p, &p->from); b = a & 0170; if(b == 0 || b == 010) { opa[1] = (a << 12) | 0x800; b = asmea(p, &p->to); a = b & 0170; if(a == 0 || a == 010) goto bad; t |= b; break; } t |= a; b = asmea(p, &p->to); a = b & 0170; if(a != 0 && a != 010) goto bad; opa[1] = (b << 12); break; case 35: /* swap */ a = asmea(p, &p->to); if((a & 0170) == 0) { t |= a; break; } goto bad; } opa[0] = t; return;bad: if(!debug['a']) print("%P\n", p); diag("bad combination of addressing in %s", TNAME); opa[0] = 0;}intasmea(Prog *p, Adr *a){ Optab *o; int f, t, r, i; short *top; long v; if(a->index != D_NONE) goto index; t = a->type; r = simple[t]; v = a->offset; if(r != 0177) { if(v == 0) return r; if((r & 070) != 020) return r; if(v >= -32768L && v < 32768L) { *op++ = v; return t-D_A0-I_INDIR+050; /* d(Ax) */ } *op++ = 0x170; /* is, no indirect */ *op++ = v>>16; *op++ = v; return t-D_A0-I_INDIR+060; /* (d,Ax) */ } f = 0; if(a == &p->from) f++; o = &optab[p->as]; switch(t) { case D_TOS: if(f) { if(o->srcsp) return (3<<3) | 7; /* (A7)+ */ } else if(o->dstsp) return (4<<3) | 7; /* -(A7) */ return (2<<3) | 7; /* (A7) */ case D_BRANCH: v = p->pcond->pc - p->pc - 2; if(v < -32768L || v >= 32768L) { *op++ = v>>16; *op++ = v; return 0xff; } if(v < -128 || v >= 128 || p->mark == 4) { *op++ = v; return 0; } return v & 0xff; case I_ADDR|D_STATIC: case I_ADDR|D_EXTERN: t = a->sym->type; if(t == 0 || t == SXREF) { diag("undefined external: %s in %s", a->sym->name, TNAME); a->sym->type = SDATA; } v = a->sym->value + a->offset; if(t != STEXT) v += INITDAT; case D_CONST: switch(f? o->srcsp: o->dstsp) { case 4: *op++ = v>>16; case 2: *op++ = v; break; default: diag("unknown srcsp asmea in %s", TNAME); } return (7<<3) | 4; case D_FCONST: r = f? o->srcsp: o->dstsp; for(i=0; i<r; i++) ((char*)op)[i] = gnuxi(&a->ieee, i, r); op += r/2; return (7<<3) | 4; case D_QUICK: v = a->offset & 0xff; return 0110 | (v<<7); case D_STACK: case D_AUTO: case D_PARAM: if(v == 0) return (2<<3) | 7; /* (A7) */ if(v >= -32768L && v < 32768L) { *op++ = v; return (5<<3) | 7; /* d(A7) */ } *op++ = 0x170; /* is, no indirect */ *op++ = v>>16; *op++ = v; return (6<<3) | 7; /* (d,A7) */ case I_INDIR|D_CONST: goto adr; case D_STATIC: case D_EXTERN: t = a->sym->type; if(t == 0 || t == SXREF) { diag("undefined external: %s in %s", a->sym->name, TNAME); a->sym->type = SDATA; } if(t == STEXT) { v = a->sym->value + a->offset; *op++ = v>>16; *op++ = v; return (7<<3) | 1; } v = a->sym->value + a->offset - A6OFFSET; if(debug['6']) { v += INITDAT + A6OFFSET; goto adr; } if(v == 0) return (2<<3) | 6; if(v >= -32768L && v < 32768L) { *op++ = v; return (5<<3) | 6; } v += INITDAT + A6OFFSET; adr: if(v >= -32768L && v < 32768L) { *op++ = v; return (7<<3) | 0; } *op++ = v>>16; *op++ = v; return (7<<3) | 1; } if(!debug['a']) print("%P\n", p); diag("unknown addressing mode: %d in %s", t, TNAME); return 0;index: top = op++; t = a->index & D_MASK; f = (a->scale & 7) << 9; /* w/l scale */ f |= (t & 7) << 12; /* register */ if(t < D_R0 || t >= D_R0+8) { if(t >= D_A0 && t < D_A0+8) { f |= 0x8000; /* d/a */ } else if(t == D_NONE) f = 0x40; /* is */ else goto bad; } t = a->type; r = t & 7; v = a->offset; if(t < (I_INDIR|D_A0) || t >= (I_INDIR|(D_A0+8))) switch(t) { default: goto bad; case I_INDIR|D_NONE: f |= 0x80; /* bs */ r = 0; break; case D_AUTO: case D_PARAM: case D_STACK: r = 7; break; case D_STATIC: case D_EXTERN: t = a->sym->type; if(t == 0 || t == SXREF) { diag("undefined external: %s in %s", a->sym->name, TNAME); a->sym->type = SDATA; } r = 6; v += a->sym->value - A6OFFSET; if(t == STEXT) { f |= 0x80; /* bs */ r = 0; v += A6OFFSET; goto bdlong; } if(debug['6']) { f |= 0x80; /* bs */ r = 0; v += INITDAT + A6OFFSET; } } if(v == 0) f |= 0x10; /* bd size = null */ else if(v >= -32768L && v < 32768L) { f |= 0x20; /* bd size = word */ *op++ = v; } else { bdlong: f |= 0x30; /* bd size = long */ *op++ = v>>16; *op++ = v; } v = a->displace; t = a->index & I_MASK; if(t != I_INDEX1) { /* non-memory index */ if(t == I_INDEX2) f |= 5; /* post indexing */ else if(t == I_INDEX3) f |= 1; /* pre indexing */ else goto bad; } if(v != 0) { if(v >= -32768L && v < 32768L) { f++; /* is size = word */ *op++ = v; } else { f += 2; /* is size = long */ *op++ = v>>16; *op++ = v; } } *top = f | 0x100; return (6<<3) | r;bad: if(!debug['a']) print("%P\n", p); diag("bad operand in %s", TNAME); return 0;}voidlput(long l){ CPUT(l>>24) CPUT(l>>16) CPUT(l>>8) CPUT(l)}voids16put(char *n){ char name[16]; int i; strncpy(name, n, sizeof(name)); for(i=0; i<sizeof(name); i++) CPUT(name[i])}voidcflush(void){ int n; n = sizeof(buf.cbuf) - cbc; if(n) write(cout, buf.cbuf, n); cbp = buf.cbuf; cbc = sizeof(buf.cbuf);}voiddatblk(long s, long n){ Prog *p; char *cast; long l, fl, j; int i, c; memset(buf.dbuf, 0, n+100); for(p = datap; p != P; p = p->link) { curp = p; l = p->from.sym->value + p->from.offset - s; c = p->from.displace; i = 0; if(l < 0) { if(l+c <= 0) continue; while(l < 0) { l++; i++; } } if(l >= n) continue; 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) { case D_FCONST: switch(c) { default: case 4: fl = ieeedtof(&p->to.ieee); cast = (char*)&fl; if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux", cast[fnuxi8[j+4]] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = cast[fnuxi8[i+4]]; l++; } break; case 8: cast = (char*)&p->to.ieee; if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = cast[fnuxi8[i]]; l++; } break; } break; case D_SCONST: if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = p->to.scon[i]; l++; } break; default: fl = p->to.offset; if(p->to.sym) { if(p->to.sym->type == STEXT) fl += p->to.sym->value; if(p->to.sym->type == SDATA) fl += p->to.sym->value + INITDAT; if(p->to.sym->type == SBSS) fl += p->to.sym->value + INITDAT; } cast = (char*)&fl; switch(c) { default: diag("bad nuxi %d %d\n%P", c, i, curp); break; case 1: if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux",cast[inuxi1[j]] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = cast[inuxi1[i]]; l++; } break; case 2: if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux",cast[inuxi2[j]] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = cast[inuxi2[i]]; l++; } break; case 4: if(debug['a'] && i == 0) { Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp); for(j=0; j<c; j++) Bprint(&bso, "%.2ux",cast[inuxi4[j]] & 0xff); Bprint(&bso, "\n"); } for(; i<c; i++) { buf.dbuf[l] = cast[inuxi4[i]]; l++; } break; } break; } } write(cout, buf.dbuf, n);}intgnuxi(Ieee *d, int i, int c){ char *p; long l; switch(c) { default: diag("bad nuxi %d %d\n%P", c, i, curp); return 0; /* * 2301 vax * 0123 68k */ case 4: l = ieeedtof(d); p = (char*)&l; i = gnuxi8[i+4]; break; /* * 67452301 vax * 45670123 68k */ case 8: p = (char*)d; i = gnuxi8[i]; break; } return p[i];}longrnd(long v, long r){ long c; if(r <= 0) return v; v += r - 1; c = v % r; if(c < 0) c += r; v -= c; return v;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -