📄 asm.c
字号:
v = regoff(&p->from); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg); break; case 20: /* mov lohi,r */ r = OP(2,0); /* mfhi */ if(p->from.type == D_LO) r = OP(2,2); /* mflo */ o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg); break; case 21: /* mov r,lohi */ r = OP(2,1); /* mthi */ if(p->to.type == D_LO) r = OP(2,3); /* mtlo */ o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO); break; case 22: /* mul r1,r2 */ o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO); break; case 23: /* add $lcon,r1,r2 ==> lu+or+add */ v = regoff(&p->from); if(p->to.reg == REGTMP || p->reg == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); r = p->reg; if(r == NREG) r = p->to.reg; o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); break; case 24: /* mov $ucon,,r ==> lu r */ v = regoff(&p->from); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); break; case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */ v = regoff(&p->from); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); r = p->reg; if(r == NREG) r = p->to.reg; o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); break; case 26: /* mov $lsext/auto/oreg,,r2 ==> lu+or+add */ v = regoff(&p->from); if(p->to.reg == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); r = p->from.reg; if(r == NREG) r = o->param; o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg); break; case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); switch(o->size) { case 20: o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1); o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg); break; case 16: o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg); break; case 8: o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1); o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg); break; case 4: o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg); break; } break; case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); switch(o->size) { case 20: if(r == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1); o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg); break; case 16: if(r == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg); break; case 8: o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1); o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg); break; case 4: o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg); break; } break; case 30: /* movw r,fr */ r = SP(2,1)|(4<<21); /* mtc1 */ o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); break; case 31: /* movw fr,r */ r = SP(2,1)|(0<<21); /* mfc1 */ o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); break; case 32: /* fadd fr1,[fr2],fr3 */ r = p->reg; if(r == NREG) o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg); else o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg); break; case 33: /* fabs fr1,fr3 */ o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg); break; case 34: /* mov $con,fr ==> or/add $i,r,r2 */ v = regoff(&p->from); r = AADDU; if(o->a1 == C_ANDCON) r = AOR; o1 = OP_IRR(opirr(r), v, 0, REGTMP); o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg); /* mtc1 */ break; case 35: /* mov r,lext/luto/oreg ==> sw o(r) */ /* * the lowbits of the constant cannot * be moved into the offset of the load * because the mips 4000 in 64-bit mode * does a 64-bit add and it will screw up. */ v = regoff(&p->to); r = p->to.reg; if(r == NREG) r = o->param; if(r == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg); break; case 36: /* mov lext/lauto/lreg,r ==> lw o(r30) */ v = regoff(&p->from); r = p->from.reg; if(r == NREG) r = o->param; if(r == REGTMP) diag("cant synthesize large constant\n%P", p); o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg); break; case 37: /* movw r,mr */ r = SP(2,0)|(4<<21); /* mtc0 */ if(p->as == AMOVV) r = SP(2,0)|(5<<21); /* dmtc0 */ o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); break; case 38: /* movw mr,r */ r = SP(2,0)|(0<<21); /* mfc0 */ if(p->as == AMOVV) r = SP(2,0)|(1<<21); /* dmfc0 */ o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); break; case 39: /* rfe ==> jmp+rfe */ if(aflag) return 0; o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO); o2 = oprrr(p->as); break; case 40: /* word */ if(aflag) return 0; o1 = regoff(&p->to); break; case 41: /* movw r,fcr */ o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); /* mfcc1 */ o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */ break; case 42: /* movw fcr,r */ o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */ break; case 45: /* case r */ if(p->link == P) v = p->pc+28; else v = p->link->pc; if(v & (1<<15)) o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP); else o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg); o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP); o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP); o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO); o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO); o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO); break; case 46: /* bcase $con,lbra */ if(p->cond == P) v = p->pc; else v = p->cond->pc; o1 = v; break; } if(aflag) return o1; v = p->pc; switch(o->size) { default: if(debug['a']) Bprint(&bso, " %.8lux:\t\t%P\n", v, p); break; case 4: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p); LPUT(o1); break; case 8: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p); LPUT(o1); LPUT(o2); break; case 12: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p); LPUT(o1); LPUT(o2); LPUT(o3); break; case 16: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, o4, p); LPUT(o1); LPUT(o2); LPUT(o3); LPUT(o4); break; case 20: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, o4, o5, p); LPUT(o1); LPUT(o2); LPUT(o3); LPUT(o4); LPUT(o5); break; case 28: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, o4, o5, o6, o7, p); LPUT(o1); LPUT(o2); LPUT(o3); LPUT(o4); LPUT(o5); LPUT(o6); LPUT(o7); break; } return 0;}intisnop(Prog *p){ if(p->as != ANOR) return 0; if(p->reg != REGZERO && p->reg != NREG) return 0; if(p->from.type != D_REG || p->from.reg != REGZERO) return 0; if(p->to.type != D_REG || p->to.reg != REGZERO) return 0; return 1;}longoprrr(int a){ switch(a) { case AADD: return OP(4,0); case AADDU: return OP(4,1); case ASGT: return OP(5,2); case ASGTU: return OP(5,3); case AAND: return OP(4,4); case AOR: return OP(4,5); case AXOR: return OP(4,6); case ASUB: return OP(4,2); case ASUBU: return OP(4,3); case ANOR: return OP(4,7); case ASLL: return OP(0,4); case ASRL: return OP(0,6); case ASRA: return OP(0,7); case AREM: case ADIV: return OP(3,2); case AREMU: case ADIVU: return OP(3,3); case AMUL: return OP(3,0); case AMULU: return OP(3,1); case AJMP: return OP(1,0); case AJAL: return OP(1,1); case ABREAK: return OP(1,5); case ASYSCALL: return OP(1,4); case ATLBP: return MMU(1,0); case ATLBR: return MMU(0,1); case ATLBWI: return MMU(0,2); case ATLBWR: return MMU(0,6); case ARFE: return MMU(2,0); case ADIVF: return FPF(0,3); case ADIVD: return FPD(0,3); case AMULF: return FPF(0,2); case AMULD: return FPD(0,2); case ASUBF: return FPF(0,1); case ASUBD: return FPD(0,1); case AADDF: return FPF(0,0); case AADDD: return FPD(0,0); case AMOVFW: return FPF(4,4); case AMOVDW: return FPD(4,4); case AMOVWF: return FPW(4,0); case AMOVDF: return FPD(4,0); case AMOVWD: return FPW(4,1); case AMOVFD: return FPF(4,1); case AABSF: return FPF(0,5); case AABSD: return FPD(0,5); case AMOVF: return FPF(0,6); case AMOVD: return FPD(0,6); case ANEGF: return FPF(0,7); case ANEGD: return FPD(0,7); case ACMPEQF: return FPF(6,2); case ACMPEQD: return FPD(6,2); case ACMPGTF: return FPF(7,4); case ACMPGTD: return FPD(7,4); case ACMPGEF: return FPF(7,6); case ACMPGED: return FPD(7,6); case ADIVV: return OP(3,6); case ADIVVU: return OP(3,7); case AADDV: return OP(5,4); case AADDVU: return OP(5,5); } diag("bad rrr %d", a); return 0;}longopirr(int a){ switch(a) { case AADD: return SP(1,0); case AADDU: return SP(1,1); case ASGT: return SP(1,2); case ASGTU: return SP(1,3); case AAND: return SP(1,4); case AOR: return SP(1,5); case AXOR: return SP(1,6); case ALAST: return SP(1,7); case ASLL: return OP(0,0); case ASRL: return OP(0,2); case ASRA: return OP(0,3); case AJMP: return SP(0,2); case AJAL: return SP(0,3); case ABEQ: return SP(0,4); case ABNE: return SP(0,5); case ABGEZ: return SP(0,1)|BCOND(0,1); case ABGEZAL: return SP(0,1)|BCOND(2,1); case ABGTZ: return SP(0,7); case ABLEZ: return SP(0,6); case ABLTZ: return SP(0,1)|BCOND(0,0); case ABLTZAL: return SP(0,1)|BCOND(2,0); case ABFPT: return SP(2,1)|(257<<16); case ABFPF: return SP(2,1)|(256<<16); case AMOVB: case AMOVBU: return SP(5,0); case AMOVH: case AMOVHU: return SP(5,1); case AMOVW: return SP(5,3); case AMOVV: return SP(7,7); case AMOVF: return SP(7,1); case AMOVWL: return SP(5,2); case AMOVWR: return SP(5,6); case AMOVVL: return SP(5,4); case AMOVVR: return SP(5,5); case ABREAK: return SP(5,7); case AMOVWL+ALAST: return SP(4,2); case AMOVWR+ALAST: return SP(4,6); case AMOVVL+ALAST: return SP(3,2); case AMOVVR+ALAST: return SP(3,3); case AMOVB+ALAST: return SP(4,0); case AMOVBU+ALAST: return SP(4,4); case AMOVH+ALAST: return SP(4,1); case AMOVHU+ALAST: return SP(4,5); case AMOVW+ALAST: return SP(4,3); case AMOVV+ALAST: return SP(6,7); case AMOVF+ALAST: return SP(6,1); case ASLLV: return OP(7,0); case ASRLV: return OP(7,2); case ASRAV: return OP(7,3); case ASLLV+ALAST: return OP(7,4); case ASRLV+ALAST: return OP(7,6); case ASRAV+ALAST: return OP(7,7); case AADDV: return SP(3,0); case AADDVU: return SP(3,1); } diag("bad irr %d", a);abort(); return 0;}intvshift(int a){ switch(a){ case ASLLV: return 1; case ASRLV: return 1; case ASRAV: return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -