📄 asm.c
字号:
v = 3; o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg); } else { a = AOR; if(p->as == AMOVL) a = AADDL; if(p->as == AMOVLU) a = AEXTLL; o1 = OP_RRR(opcode(a), REGZERO, p->from.reg, p->to.reg); } break; case 2: /* <operate> r1,[r2],r3 */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg); break; case 3: /* <operate> $n,[r2],r3 */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(opcode(p->as), v, r, p->to.reg); break; case 4: /* beq r1,sbra */ if(p->cond == P) v = -4 >> 2; else v = (p->cond->pc - pc-4) >> 2; o1 = OP_BR(opcode(p->as), v, p->from.reg); break; case 5: /* jmp [r1],0(r2) */ r = p->reg; a = p->as; if(r == NREG) { r = o->param;/* if(a == AJMP && p->to.reg == REGLINK) a = ARET; /* this breaks the kernel -- maybe we need to clear prediction stack on each context switch... */ } o1 = OP_MEM(opcode(a), 0, p->to.reg, r); break; case 6: /* movq $n,r1 and movq $soreg,r1 */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg); break; case 7: /* movbu r1, r2 */ v = 1; if (p->as == AMOVWU) v = 3; o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg); break; case 8: /* mov r, soreg ==> stq o(r) */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if (p->as == AMOVQ || p->as == AMOVT) if ((r == REGSP || r == REGSB) && (v&7) != 0) diag("bad alignment: %P", p); o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg); break; case 9: /* mov soreg, r ==> ldq o(r) */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if (p->as == AMOVQ || p->as == AMOVT) if ((r == REGSP || r == REGSB) && (v&7) != 0) diag("bad alignment: %P", p); o1 = OP_MEM(opcode(p->as), v, r, p->to.reg); break; case 10: /* movb r1,r2 */ v = 64 - 8; if (p->as == AMOVW) v = 64 - 16; o1 = OP_IRR(opcode(ASLLQ), v, p->from.reg, p->to.reg); o2 = OP_IRR(opcode(ASRAQ), v, p->to.reg, p->to.reg); break; case 11: /* jmp lbra */ if(p->cond == P) v = -4 >> 2; else v = (p->cond->pc - pc-4) >> 2; a = ABR; r = REGZERO; if (p->as == AJSR) { a = ABSR; r = REGLINK; } o1 = OP_BR(opcode(a), v, r); break; case 12: /* addq $n,[r2],r3 ==> lda */ v = regoff(&p->from); if (p->as == ASUBQ) v = -v; r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg); break; case 13: /* <op> $scon,[r2],r3 */ v = regoff(&p->from); if(p->to.reg == REGTMP || p->reg == REGTMP) diag("cant synthesize large constant\n%P", p); r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP); o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg); break; case 14: /* <op> $lcon,[r2],r3 */ v = regoff(&p->from); if(v & 0x8000) v += 0x10000; if(p->to.reg == REGTMP || p->reg == REGTMP) diag("cant synthesize large constant\n%P", p); r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP); o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg); break; case 15: /* mov $lcon,r1 */ v = regoff(&p->from); if(v & 0x8000) v += 0x10000; o1 = OP_MEM(opcode(AMOVA), v, o->param, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg); break; case 16: /* mov $qcon,r1 */ v = regoff(&p->from); if(v & 0x8000) v += 0x10000; if((v>>31)&1) v += (1LL<<32); if((v>>47)&1) v += (1LL<<48); o1 = OP_MEM(opcode(AMOVA), v>>32, o->param, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP); o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP); o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP); o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg); break; case 17: /* mov f1,f2 ==> fcpys f1,f1,f2 */ o1 = OP_RRR(opcode(ACPYS), p->from.reg, p->from.reg, p->to.reg); break; case 18: /* call_pal imm */ v = regoff(&p->from); o1 = OP_MEM(opcode(ACALL_PAL), v, 0, 0); break; case 19: /* mov r, loreg ==> ldah,stq */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if (p->as == AMOVQ || p->as == AMOVT) if ((r == REGSP || r == REGSB) && (v&7) != 0) diag("bad alignment: %P", p); if(v & 0x8000) v += 0x10000; o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP); o2 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg); break; case 20: /* mov loreg, r ==> ldah,ldq */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if (p->as == AMOVQ || p->as == AMOVT) if ((r == REGSP || r == REGSB) && (v&7) != 0) diag("bad alignment: %P", p); if(v & 0x8000) v += 0x10000; o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP); o2 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg); break;#ifdef NEVER case 21: /* mov r1,$qoreg */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if(v & 0x8000) v += 0x10000; if((v>>31)&1) v += (1LL<<32); if((v>>47)&1) v += (1LL<<48); o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP); o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP); o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP); o5 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg); break; case 22: /* mov $qoreg,r1 */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if(v & 0x8000) v += 0x10000; if((v>>31)&1) v += (1LL<<32); if((v>>47)&1) v += (1LL<<48); o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP); o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP); o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP); o5 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg); break;#endif case 23: /* <op> $qcon,r1 */ if(p->to.reg == REGTMP || p->reg == REGTMP) diag("cant synthesize large constant\n%P", p); v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; if(v & 0x8000) v += 0x10000; if((v>>31)&1) v += (1LL<<32); if((v>>47)&1) v += (1LL<<48); o1 = OP_MEM(opcode(AMOVA), v>>32, REGZERO, REGTMP); o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP); o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP); o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP); o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP); o6 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg); break; case 24: /* movq Fn, FPCR */ r = p->from.reg; o1 = OP_RRR(opcode(AADDT+AEND), r, r, r); break; case 25: /* movq FPCR, Fn */ r = p->to.reg; o1 = OP_RRR(opcode(AADDS+AEND), r, r, r); break; case 26: /* movq Rn, C_PREG */ r = p->from.reg; o1 = OP_RRR(opcode(ASUBQ+AEND), r, r, 0) | p->to.reg & 255; break; case 27: /* movq C_PREG, Rn */ r = p->to.reg; o1 = OP_RRR(opcode(AADDQ+AEND), r, r, 0) | p->from.reg & 255; break; case 28: /* cvttq r1,r3 */ r = p->from.reg; o1 = OP_RRR(opcode(p->as), r, REGZERO, p->to.reg); break; case 29: /* movq pcc, rpcc -> Rn */ o1 = OP_MEM(opcode(ARPCC), 0, REGZERO, p->to.reg); break; case 30: /* rei/mb/trapb */ o1 = OP_MEM(opcode(p->as), 0, REGZERO, REGZERO); break; case 31: /* fetch (Rn) */ o1 = OP_MEM(opcode(p->as), 0, REGZERO, p->from.reg); break; case 32: /* movqp r, soreg ==> stqp o(r) */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if (v < -0x800 || v >= 0x800) diag("physical store out of range\n%P", p); v &= 0xfff; o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg); break; case 33: /* movqp soreg, r ==> ldqp o(r) */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if (v < -0x800 || v >= 0x800) diag("physical load out of range\n%P", p); v &= 0xfff; o1 = OP_MEM(opcode(p->as), v, r, p->to.reg); break; case 34: /* <operate> $-n,[r2],r3 */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; switch (a = p->as) { case AAND: a = AANDNOT; break; case AANDNOT: a = AAND; break; case AOR: a = AORNOT; break; case AORNOT: a = AOR; break; case AXOR: a = AXORNOT; break; case AXORNOT: a = AXOR; break; default: diag("bad in NCON case: %P", p); } v = ~v; o1 = OP_IRR(opcode(a), v, r, p->to.reg); break; case 40: /* word */ o1 = regoff(&p->to); break; } switch(o->size) { default: if(debug['a']) Bprint(&bso, " %.8lux:\t\t%P\n", p->pc, p); break; case 4: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux\t%P\n", p->pc, o1, p); LPUT(o1); break; case 8: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %P\n", p->pc, o1, o2, p); LPUT(o1); LPUT(o2); break; case 12: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %P\n", p->pc, 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", p->pc, 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", p->pc, o1, o2, o3, o4, o5, p); LPUT(o1); LPUT(o2); LPUT(o3); LPUT(o4); LPUT(o5); break; case 24: if(debug['a']) Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %P\n", p->pc, o1, o2, o3, o4, o5, o6, p); LPUT(o1); LPUT(o2); LPUT(o3); LPUT(o4); LPUT(o5); LPUT(o6); break; } return 0;}#define OP(x,y) (((x)<<26)|((y)<<5))#define FP(x) OP(22, (x)|0xc0) /* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */#define FP2(x) OP(22, (x) /*|0x080*/) /* note: this sets round/trap modes (chopped, software?). used for cvtxx? */#define FP3(x) OP(22, (x)|0x080) /* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */longopcode(int a){ switch (a) { /* loads */ case AMOVB: /* misnomer; pretend it's ok for now */diag("opcode(AMOVB)"); case AMOVBU: return OP(10, 0); /* v 3 */ case AMOVW: /* misnomer; pretend it's ok for now */diag("opcode(AMOVW)"); case AMOVWU: return OP(12, 0); /* v 3 */ case AMOVL: return OP(40, 0); case AMOVQ: return OP(41, 0); case AMOVQU: return OP(11, 0); case AMOVS: return OP(34, 0); case AMOVT: return OP(35, 0); /* stores */ case AMOVB+AEND: /* misnomer; pretend it's ok for now */ case AMOVBU+AEND: return OP(14, 0); /* v 3 */ case AMOVW+AEND: /* misnomer; pretend it's ok for now */ case AMOVWU+AEND: return OP(13, 0); /* v 3 */ case AMOVL+AEND: return OP(44, 0); case AMOVQ+AEND: return OP(45, 0); case AMOVQU+AEND: return OP(15, 0); case AMOVS+AEND: return OP(38, 0); case AMOVT+AEND: return OP(39, 0); /* physical */ case AMOVLP+AEND: return OP(31, 0)|0x8000; case AMOVQP+AEND: return OP(31, 0)|0x9000; case AMOVLP: return OP(27, 0)|0x8000; case AMOVQP: return OP(27, 0)|0x9000; /* load address */ case AMOVA: return OP(8, 0); case AMOVAH: return OP(9, 0); /* locking */ case AMOVLL: return OP(42, 0); /* load locked */ case AMOVQL: return OP(43, 0); /* load locked */ case AMOVLC+AEND: return OP(46, 0); /* store cond */ case AMOVQC+AEND: return OP(47, 0); /* store cond */ case AADDL: return OP(16, 0); case AADDLV: return OP(16, 64); case AADDQ: return OP(16, 32); case AADDQV: return OP(16, 96); case AS4ADDL: return OP(16, 2); case AS4ADDQ: return OP(16, 34); case AS8ADDL: return OP(16, 18); case AS8ADDQ: return OP(16, 50); case AS4SUBL: return OP(16, 11); case AS4SUBQ: return OP(16, 43); case AS8SUBL: return OP(16, 27); case AS8SUBQ: return OP(16, 59); case ASUBL: return OP(16, 9); case ASUBLV: return OP(16, 73); case ASUBQ: return OP(16, 41); case ASUBQV: return OP(16, 105); case ACMPEQ: return OP(16, 45); case ACMPGT: return OP(16, 77); case ACMPGE: return OP(16, 109); case ACMPUGT: return OP(16, 29); case ACMPUGE: return OP(16, 61); case ACMPBLE: return OP(16, 15); case AAND: return OP(17, 0); case AANDNOT: return OP(17, 8); case AOR: return OP(17, 32); case AORNOT: return OP(17, 40); case AXOR: return OP(17, 64); case AXORNOT: return OP(17, 72); case ACMOVEQ: return OP(17, 36); case ACMOVNE: return OP(17, 38); case ACMOVLT: return OP(17, 68); case ACMOVGE: return OP(17, 70); case ACMOVLE: return OP(17, 100); case ACMOVGT: return OP(17, 102); case ACMOVLBS: return OP(17, 20); case ACMOVLBC: return OP(17, 22); case AMULL: return OP(19, 0); case AMULQ: return OP(19, 32); case AMULLV: return OP(19, 64); case AMULQV: return OP(19, 96); case AUMULH: return OP(19, 48); case ASLLQ: return OP(18, 57); case ASRLQ: return OP(18, 52); case ASRAQ: return OP(18, 60); case AEXTBL: return OP(18, 6); case AEXTWL: return OP(18, 22); case AEXTLL: return OP(18, 38); case AEXTQL: return OP(18, 54); case AEXTWH: return OP(18, 90); case AEXTLH: return OP(18, 106); case AEXTQH: return OP(18, 122); case AINSBL: return OP(18, 11); case AINSWL: return OP(18, 27); case AINSLL: return OP(18, 43); case AINSQL: return OP(18, 59); case AINSWH: return OP(18, 87); case AINSLH: return OP(18, 103); case AINSQH: return OP(18, 119); case AMSKBL: return OP(18, 2); case AMSKWL: return OP(18, 18); case AMSKLL: return OP(18, 34); case AMSKQL: return OP(18, 50); case AMSKWH: return OP(18, 82); case AMSKLH: return OP(18, 98); case AMSKQH: return OP(18, 114); case AZAP: return OP(18, 48); case AZAPNOT: return OP(18, 49); case AJMP: return OP(26, 0); case AJSR: return OP(26, 512); case ARET: return OP(26, 1024); case ABR: return OP(48, 0); case ABSR: return OP(52, 0); case ABEQ: return OP(57, 0); case ABNE: return OP(61, 0); case ABLT: return OP(58, 0); case ABGE: return OP(62, 0); case ABLE: return OP(59, 0); case ABGT: return OP(63, 0); case ABLBC: return OP(56, 0); case ABLBS: return OP(60, 0); case AFBEQ: return OP(49, 0); case AFBNE: return OP(53, 0); case AFBLT: return OP(50, 0); case AFBGE: return OP(54, 0); case AFBLE: return OP(51, 0); case AFBGT: return OP(55, 0); case ATRAPB: return OP(24, 0); case AMB: return OP(24, 0x200); case AFETCH: return OP(24, 0x400); case AFETCHM: return OP(24, 0x500); case ARPCC: return OP(24, 0x600); case ACPYS: return OP(23, 32); case ACPYSN: return OP(23, 33); case ACPYSE: return OP(23, 34); case AADDS+AEND: return OP(23, 37); /* MF_FPCR */ case AADDT+AEND: return OP(23, 36); /* MT_FPCR */ case ACVTLQ: return OP(23, 16); case ACVTQL: return OP(23, 48); /* XXX trap mode */ case AFCMOVEQ: return OP(23, 42); case AFCMOVNE: return OP(23, 43); case AFCMOVLT: return OP(23, 44); case AFCMOVGE: return OP(23, 45); case AFCMOVLE: return OP(23, 46); case AFCMOVGT: return OP(23, 47); case AADDS: return FP(0); case AADDT: return FP(32); case ACMPTEQ: return FP3(37); case ACMPTGT: return FP3(38); case ACMPTGE: return FP3(39); case ACMPTUN: return FP3(36); case ACVTQS: return FP2(60); case ACVTQT: return FP2(62); case ACVTTS: return FP2(44); case ACVTTQ: return FP2(47); case ADIVS: return FP(3); case ADIVT: return FP(35); case AMULS: return FP(2); case AMULT: return FP(34); case ASUBS: return FP(1); case ASUBT: return FP(33); case ACALL_PAL: return 0; case AREI: return OP(30, 0x400); /* HW_REI */ case AADDQ+AEND: return OP(25,0); /* HW_MFPR */ case ASUBQ+AEND: return OP(29,0); /* HW_MTPR */ } diag("bad op %A(%d)", a, a); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -