📄 asm.c
字号:
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; v = p->to.sym; if(v) { switch(v->type) { case SUNDEF: ckoff(v, d); case STEXT: case SLEAF: case SSTRING: d += p->to.sym->value; break; case SDATA: case SBSS: d += p->to.sym->value + INITDAT; } if(dlm) dynreloc(v, a+INITDAT, 1); } cast = (char*)&d; switch(c) { default: diag("bad nuxi %d %d%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);}voidasmout(Prog *p, Optab *o){ long o1, o2, o3, o4, o5, o6, v; int r, rf, rt, rt2; Sym *s;PP = p; o1 = 0; o2 = 0; o3 = 0; o4 = 0; o5 = 0; o6 = 0; switch(o->type) { default: diag("unknown asm %d", o->type); prasm(p); break; case 0: /* pseudo ops */ break; case 1: /* op R,[R],R */ o1 = oprrr(p->as, p->scond); rf = p->from.reg; rt = p->to.reg; r = p->reg; if(p->to.type == D_NONE) rt = 0; if(r == NREG) r = rt; o1 |= rf | (r<<16) | (rt<<12); break; case 2: /* movbu $I,[R],R */ aclass(&p->from); o1 = oprrr(p->as, p->scond); o1 |= immrot(instoffset); rt = p->to.reg; r = p->reg; if(p->to.type == D_NONE) rt = 0; if(r == NREG) r = rt; o1 |= (r<<16) | (rt<<12); break; case 3: /* add R<<[IR],[R],R */ mov: aclass(&p->from); o1 = oprrr(p->as, p->scond); o1 |= p->from.offset; rt = p->to.reg; r = p->reg; if(p->to.type == D_NONE) rt = 0; if(r == NREG) r = rt; o1 |= (r<<16) | (rt<<12); break; case 4: /* add $I,[R],R */ aclass(&p->from); o1 = oprrr(AADD, p->scond); o1 |= immrot(instoffset); r = p->from.reg; if(r == NREG) r = o->param; o1 |= r << 16; o1 |= p->to.reg << 12; break; case 5: /* bra s */ v = -8; if(p->cond == UP) { s = p->to.sym; if(s->type != SUNDEF) diag("bad branch sym type"); v = (ulong)s->value >> (Roffset-2); dynreloc(s, p->pc, 0); } else if(p->cond != P) v = (p->cond->pc - pc) - 8; o1 = opbra(p->as, p->scond); o1 |= (v >> 2) & 0xffffff; break; case 6: /* b ,O(R) -> add $O,R,PC */ aclass(&p->to); o1 = oprrr(AADD, p->scond); o1 |= immrot(instoffset); o1 |= p->to.reg << 16; o1 |= REGPC << 12; break; case 7: /* bl ,O(R) -> mov PC,link; add $O,R,PC */ aclass(&p->to); o1 = oprrr(AADD, p->scond); o1 |= immrot(0); o1 |= REGPC << 16; o1 |= REGLINK << 12; o2 = oprrr(AADD, p->scond); o2 |= immrot(instoffset); o2 |= p->to.reg << 16; o2 |= REGPC << 12; break; case 8: /* sll $c,[R],R -> mov (R<<$c),R */ aclass(&p->from); o1 = oprrr(p->as, p->scond); r = p->reg; if(r == NREG) r = p->to.reg; o1 |= r; o1 |= (instoffset&31) << 7; o1 |= p->to.reg << 12; break; case 9: /* sll R,[R],R -> mov (R<<R),R */ o1 = oprrr(p->as, p->scond); r = p->reg; if(r == NREG) r = p->to.reg; o1 |= r; o1 |= (p->from.reg << 8) | (1<<4); o1 |= p->to.reg << 12; break; case 10: /* swi [$con] */ o1 = oprrr(p->as, p->scond); if(p->to.type != D_NONE) { aclass(&p->to); o1 |= instoffset & 0xffffff; } break; case 11: /* word */ switch(aclass(&p->to)) { case C_LCON: if(!dlm) break; if(p->to.name != D_EXTERN && p->to.name != D_STATIC) break; case C_ADDR: if(p->to.sym->type == SUNDEF) ckoff(p->to.sym, p->to.offset); dynreloc(p->to.sym, p->pc, 1); } o1 = instoffset; break; case 12: /* movw $lcon, reg */ o1 = omvl(p, &p->from, p->to.reg); break; case 13: /* op $lcon, [R], R */ o1 = omvl(p, &p->from, REGTMP); if(!o1) break; o2 = oprrr(p->as, p->scond); o2 |= REGTMP; r = p->reg; if(r == NREG) r = p->to.reg; o2 |= r << 16; if(p->to.type != D_NONE) o2 |= p->to.reg << 12; break; case 14: /* movb/movbu/movh/movhu R,R */ o1 = oprrr(ASLL, p->scond); if(p->as == AMOVBU || p->as == AMOVHU) o2 = oprrr(ASRL, p->scond); else o2 = oprrr(ASRA, p->scond); r = p->to.reg; o1 |= (p->from.reg)|(r<<12); o2 |= (r)|(r<<12); if(p->as == AMOVB || p->as == AMOVBU) { o1 |= (24<<7); o2 |= (24<<7); } else { o1 |= (16<<7); o2 |= (16<<7); } break; case 15: /* mul r,[r,]r */ o1 = oprrr(p->as, p->scond); rf = p->from.reg; rt = p->to.reg; r = p->reg; if(r == NREG) r = rt; if(rt == r) { r = rf; rf = rt; } if(0) if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) { diag("bad registers in MUL"); prasm(p); } o1 |= (rf<<8) | r | (rt<<16); break; case 16: /* div r,[r,]r */ o1 = 0xf << 28; o2 = 0; break; case 17: o1 = oprrr(p->as, p->scond); rf = p->from.reg; rt = p->to.reg; rt2 = p->to.offset; r = p->reg; o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12); break; case 20: /* mov/movb/movbu R,O(R) */ aclass(&p->to); r = p->to.reg; if(r == NREG) r = o->param; o1 = osr(p->as, p->from.reg, instoffset, r, p->scond); break; case 21: /* mov/movbu O(R),R -> lr */ aclass(&p->from); r = p->from.reg; if(r == NREG) r = o->param; o1 = olr(instoffset, r, p->to.reg, p->scond); if(p->as != AMOVW) o1 |= 1<<22; break; case 22: /* movb/movh/movhu O(R),R -> lr,shl,shr */ aclass(&p->from); r = p->from.reg; if(r == NREG) r = o->param; o1 = olr(instoffset, r, p->to.reg, p->scond); o2 = oprrr(ASLL, p->scond); o3 = oprrr(ASRA, p->scond); r = p->to.reg; if(p->as == AMOVB) { o2 |= (24<<7)|(r)|(r<<12); o3 |= (24<<7)|(r)|(r<<12); } else { o2 |= (16<<7)|(r)|(r<<12); if(p->as == AMOVHU) o3 = oprrr(ASRL, p->scond); o3 |= (16<<7)|(r)|(r<<12); } break; case 23: /* movh/movhu R,O(R) -> sb,sb */ aclass(&p->to); r = p->to.reg; if(r == NREG) r = o->param; o1 = osr(AMOVH, p->from.reg, instoffset, r, p->scond); o2 = oprrr(ASRL, p->scond); o2 |= (8<<7)|(p->from.reg)|(REGTMP<<12); o3 = osr(AMOVH, REGTMP, instoffset+1, r, p->scond); break; case 30: /* mov/movb/movbu R,L(R) */ o1 = omvl(p, &p->to, REGTMP); if(!o1) break; r = p->to.reg; if(r == NREG) r = o->param; o2 = osrr(p->from.reg, REGTMP,r, p->scond); if(p->as != AMOVW) o2 |= 1<<22; break; case 31: /* mov/movbu L(R),R -> lr[b] */ case 32: /* movh/movb L(R),R -> lr[b] */ o1 = omvl(p, &p->from, REGTMP); if(!o1) break; r = p->from.reg; if(r == NREG) r = o->param; o2 = olrr(REGTMP,r, p->to.reg, p->scond); if(p->as == AMOVBU || p->as == AMOVB) o2 |= 1<<22; if(o->type == 31) break; o3 = oprrr(ASLL, p->scond); if(p->as == AMOVBU || p->as == AMOVHU) o4 = oprrr(ASRL, p->scond); else o4 = oprrr(ASRA, p->scond); r = p->to.reg; o3 |= (r)|(r<<12); o4 |= (r)|(r<<12); if(p->as == AMOVB || p->as == AMOVBU) { o3 |= (24<<7); o4 |= (24<<7); } else { o3 |= (16<<7); o4 |= (16<<7); } break; case 33: /* movh/movhu R,L(R) -> sb, sb */ o1 = omvl(p, &p->to, REGTMP); if(!o1) break; r = p->to.reg; if(r == NREG) r = o->param; o2 = osrr(p->from.reg, REGTMP, r, p->scond); o2 |= (1<<22) ; o3 = oprrr(ASRL, p->scond); o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12); o3 |= (1<<6); /* ROR 8 */ o4 = oprrr(AADD, p->scond); o4 |= (REGTMP << 12) | (REGTMP << 16); o4 |= immrot(1); o5 = osrr(p->from.reg, REGTMP,r,p->scond); o5 |= (1<<22); o6 = oprrr(ASRL, p->scond); o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12); o6 |= (1<<6); /* ROL 8 */ break; case 34: /* mov $lacon,R */ o1 = omvl(p, &p->from, REGTMP); if(!o1) break; o2 = oprrr(AADD, p->scond); o2 |= REGTMP; r = p->from.reg; if(r == NREG) r = o->param; o2 |= r << 16; if(p->to.type != D_NONE) o2 |= p->to.reg << 12; break; case 35: /* mov PSR,R */ o1 = (2<<23) | (0xf<<16) | (0<<0); o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->from.reg & 1) << 22; o1 |= p->to.reg << 12; break; case 36: /* mov R,PSR */ o1 = (2<<23) | (0x29f<<12) | (0<<4); if(p->scond & C_FBIT) o1 ^= 0x010 << 12; o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->to.reg & 1) << 22; o1 |= p->from.reg << 0; break; case 37: /* mov $con,PSR */ aclass(&p->from); o1 = (2<<23) | (0x29f<<12) | (0<<4); if(p->scond & C_FBIT) o1 ^= 0x010 << 12; o1 |= (p->scond & C_SCOND) << 28; o1 |= immrot(instoffset); o1 |= (p->to.reg & 1) << 22; o1 |= p->from.reg << 0; break; case 38: /* movm $con,oreg -> stm */ o1 = (0x4 << 25); o1 |= p->from.offset & 0xffff; o1 |= p->to.reg << 16; aclass(&p->to); goto movm; case 39: /* movm oreg,$con -> ldm */ o1 = (0x4 << 25) | (1 << 20); o1 |= p->to.offset & 0xffff; o1 |= p->from.reg << 16; aclass(&p->from); movm: if(instoffset != 0) diag("offset must be zero in MOVM"); o1 |= (p->scond & C_SCOND) << 28; if(p->scond & C_PBIT) o1 |= 1 << 24; if(p->scond & C_UBIT) o1 |= 1 << 23; if(p->scond & C_SBIT) o1 |= 1 << 22; if(p->scond & C_WBIT) o1 |= 1 << 21; break; case 40: /* swp oreg,reg,reg */ aclass(&p->from); if(instoffset != 0) diag("offset must be zero in SWP"); o1 = (0x2<<23) | (0x9<<4); if(p->as != ASWPW) o1 |= 1 << 22; o1 |= p->from.reg << 16; o1 |= p->reg << 0; o1 |= p->to.reg << 12; o1 |= (p->scond & C_SCOND) << 28; break; case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */ o1 = 0xe8fd8000; break; case 50: /* floating point store */ v = regoff(&p->to); r = p->to.reg; if(r == NREG) r = o->param; o1 = ofsr(p->as, p->from.reg, v, r, p->scond, p); break; case 51: /* floating point load */ v = regoff(&p->from); r = p->from.reg; if(r == NREG) r = o->param; o1 = ofsr(p->as, p->to.reg, v, r, p->scond, p) | (1<<20); break; case 52: /* floating point store, long offset UGLY */ o1 = omvl(p, &p->to, REGTMP); if(!o1) break; r = p->to.reg; if(r == NREG) r = o->param; o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; o3 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p); break; case 53: /* floating point load, long offset UGLY */ o1 = omvl(p, &p->from, REGTMP); if(!o1) break; r = p->from.reg; if(r == NREG) r = o->param; o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r; o3 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20); break; case 54: /* floating point arith */ o1 = oprrr(p->as, p->scond); if(p->from.type == D_FCONST) { rf = chipfloat(p->from.ieee); if(rf < 0){ diag("invalid floating-point immediate\n%P", p); rf = 0; } rf |= (1<<3); } else rf = p->from.reg; rt = p->to.reg; r = p->reg; if(p->to.type == D_NONE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -