📄 asm.c
字号:
o1 = OP2(40); /* rdy */ break; case D_PSR: o1 = OP2(41); /* rdpsr */ break; case D_WIM: o1 = OP2(42); /* rdwim */ break; case D_TBR: o1 = OP2(43); /* rdtbr */ break; } o1 = OP_RRR(o1, 0, 0, r); break; } break; case 9: /* movb r,r */ v = 24; if(p->as == AMOVH || p->as == AMOVHU) v = 16; r = ASRA; if(p->as == AMOVBU || p->as == AMOVHU) r = ASRL; o1 = OP_IRR(opcode(ASLL), v, p->from.reg, p->to.reg); o2 = OP_IRR(opcode(r), v, p->to.reg, p->to.reg); break; case 10: /* mov $loreg, reg */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg); break; case 11: /* mov loreg, r */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(opcode(p->as), (v&0x3ff), REGTMP, p->to.reg); break; case 12: /* mov r, loreg */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(opcode(p->as+AEND), (v&0x3ff), REGTMP, p->from.reg); break; case 13: /* mov $ucon, r */ v = regoff(&p->from); o1 = 0x1000000 | (p->to.reg<<25) | ((v>>10) & 0x3fffff); /* sethi */ break; case 20: /* op $scon,r */ 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 21: /* op r1,r2 */ 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 22: /* op $lcon,r */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, REGTMP); o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg); break; case 23: /* cmp r,r */ o1 = OP_RRR(opcode(ASUBCC), p->to.reg, p->from.reg, REGZERO); break; case 24: /* cmp r,$c */ v = regoff(&p->to); o1 = OP_IRR(opcode(ASUBCC), v, p->from.reg, REGZERO); break; case 25: /* cmp $c,r BOTCH, fix compiler */ v = regoff(&p->from); o1 = OP_IRR(opcode(AADD), v, NREG, REGTMP); o2 = OP_RRR(opcode(ASUBCC), p->to.reg, REGTMP, REGZERO); break; case 26: /* op $ucon,r */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg); break; case 30: /* jmp/jmpl soreg */ if(aflag) return 0; v = regoff(&p->to); r = p->reg; if(r == NREG && p->as == AJMPL) r = 15; o1 = OP_IRR(opcode(AJMPL), v, p->to.reg, r); break; case 31: /* ba jmp */ if(aflag) return 0; r = p->as; if(r == AJMP) r = ABA; v = 0; if(p->cond) v = p->cond->pc - p->pc; o1 = OP_BRA(opcode(r), v/4); if(r == ABA && p->link && p->cond && isnop(p->link)) { 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; } /* cant set annul here because pc has already been counted */ } break; case 32: /* jmpl lbra */ if(aflag) return 0; v = 0; if(p->cond) v = p->cond->pc - p->pc; r = p->reg; if(r != NREG && r != 15) diag("cant jmpl other than R15"); o1 = 0x40000000 | ((v/4) & 0x3fffffffL); /* call */ if(p->link && p->cond && isnop(p->link)) { 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 33: /* trap r */ if(aflag) return 0; o1 = opcode(p->as) | (p->from.reg<<14); break; case 34: /* rett r1,r2 -> jmpl (r1); rett (r2) */ if(aflag) return 0; o1 = OP_IRR(opcode(AJMPL), 0, p->from.reg, REGZERO); o2 = OP_IRR(opcode(ARETT), 0, p->to.reg, REGZERO); break; case 40: /* ldfsr, stfsr, stdq */ if(p->to.type == D_PREG) { r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if(p->to.reg == D_FSR) { o1 = OP_IRR(OP3(33), v, r, 0); break; } diag("unknown reg load %d", p->to.reg); } else { r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if(p->from.reg == D_FSR) { o1 = OP_IRR(OP3(37), v, r, 0); break; } if(p->as == AMOVD && p->from.reg == D_FPQ) { o1 = OP_IRR(OP3(38), v, r, 0); break; } diag("unknown reg store %d", p->from.reg); } break; case 41: /* ldf,ldd */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); if(p->as == AFMOVF || p->as == AMOVW) { o1 = OP_IRR(OP3(32), v, r, p->to.reg); break; } if(p->as == AMOVD || p->as == AFMOVD) { o1 = OP_IRR(OP3(35), v, r, p->to.reg); break; } diag("only MOVD and MOVW to FREG"); break; case 42: /* ldd -> ldf,ldf */ /* note should be ldd with proper allignment */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = OP_IRR(OP3(32), v, r, p->to.reg); o2 = OP_IRR(OP3(32), v+4, r, p->to.reg+1); break; case 43: /* stf */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); if(p->as == AFMOVF || p->as == AMOVW) { o1 = OP_IRR(OP3(36), v, r, p->from.reg); break; } if(p->as == AMOVD || p->as == AFMOVD) { o1 = OP_IRR(OP3(39), v, r, p->from.reg); break; } diag("only MOVD and MOVW from FREG"); break; case 44: /* std -> stf,stf */ /* note should be std with proper allignment */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); o1 = OP_IRR(OP3(36), v, r, p->from.reg); o2 = OP_IRR(OP3(36), v+4, r, p->from.reg+1); break; case 45: /* ldf lorg */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(OP3(32), v&0x3ff, REGTMP, p->to.reg); break; case 46: /* ldd lorg -> ldf,ldf */ /* note should be ldd with proper allignment */ r = p->from.reg; if(r == NREG) r = o->param; v = regoff(&p->from); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(OP3(32), (v&0x3ff), REGTMP, p->to.reg); o4 = OP_IRR(OP3(32), (v&0x3ff)+4, REGTMP, p->to.reg+1); break; case 47: /* stf lorg */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(OP3(36), v&0x3ff, REGTMP, p->from.reg); break; case 48: /* std lorg -> stf,stf */ /* note should be std with proper allignment */ r = p->to.reg; if(r == NREG) r = o->param; v = regoff(&p->to); o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */ o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP); o3 = OP_IRR(OP3(36), (v&0x3ff), REGTMP, p->from.reg); o4 = OP_IRR(OP3(36), (v&0x3ff)+4, REGTMP, p->from.reg+1); break; case 49: /* fmovd -> fmovf,fmovf */ o1 = OP_RRR(opcode(AFMOVF), p->from.reg, 0, p->to.reg); o2 = OP_RRR(opcode(AFMOVF), p->from.reg+1, 0, p->to.reg+1); break; case 50: /* fcmp */ o1 = OP_RRR(opcode(p->as), p->to.reg, p->from.reg, 0); break; case 51: /* word */ if(aflag) return 0; o1 = regoff(&p->from); break; case 52: /* div */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP); o2 = OP_IRR(OP2(48), 0, REGTMP, 0); o3 = OP_RRR(opcode(ADIV), p->from.reg, r, p->to.reg); break; case 53: /* divl */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(OP2(48), 0, REGZERO, 0); o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, p->to.reg); break; case 54: /* mod */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP); o2 = OP_IRR(OP2(48), 0, REGTMP, 0); o3 = OP_RRR(opcode(ADIV), p->from.reg, r, REGTMP); o4 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP); o5 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg); break; case 55: /* modl */ r = p->reg; if(r == NREG) r = p->to.reg; o1 = OP_IRR(OP2(48), 0, REGZERO, 0); o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, REGTMP); o3 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP); o4 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg); break; case 56: /* b(cc) -- annullable */ if(aflag) return 0; r = p->as; v = 0; if(p->cond) v = p->cond->pc - p->pc; o1 = OP_BRA(opcode(r), v/4); if(p->link && p->cond && isnop(p->link)) if(!debug['A']) { o2 = asmout(p->cond, oplook(p->cond), 2); if(o2) { o1 |= 1<<29; /* annul */ 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 57: /* op r1,r2 with reserved rs1 */ r = 0; o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg); 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; } return 0;}intisnop(Prog *p){ if(p->as != AORN) 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;}longopcode(int a){ switch(a) { case AADD: return OP2(0); case AADDCC: return OP2(16); case AADDX: return OP2(8); case AADDXCC: return OP2(24); case AMUL: return OP2(10); case ADIV: return OP2(15); case ADIVL: return OP2(14); case ATADDCC: return OP2(32); case ATADDCCTV: return OP2(34); case ASUB: return OP2(4); case ASUBCC: return OP2(20); case ASUBX: return OP2(12); case ASUBXCC: return OP2(28); case ATSUBCC: return OP2(33); case ATSUBCCTV: return OP2(35); case AMULSCC: return OP2(36); case ASAVE: return OP2(60); case ARESTORE: return OP2(61); case AAND: return OP2(1); case AANDCC: return OP2(17); case AANDN: return OP2(5); case AANDNCC: return OP2(21); case AOR: return OP2(2); case AORCC: return OP2(18); case AORN: return OP2(6); case AORNCC: return OP2(22); case AXOR: return OP2(3); case AXORCC: return OP2(19); case AXNOR: return OP2(7); case AXNORCC: return OP2(23); case ASLL: return OP2(37); case ASRL: return OP2(38); case ASRA: return OP2(39); case AJMPL: case AJMP: return OP2(56); case ARETT: return OP2(57); case AMOVBU: return OP3(1); /* ldub */ case AMOVB: return OP3(9); /* ldsb */ case AMOVHU: return OP3(2); /* lduh */ case AMOVH: return OP3(10); /* ldsh */ case AMOVW: return OP3(0); /* ld */ case AMOVD: return OP3(3); /* ldd */ case AMOVBU+AEND: case AMOVB+AEND:return OP3(5); /* stb */ case AMOVHU+AEND: case AMOVH+AEND:return OP3(6); /* sth */ case AMOVW+AEND:return OP3(4); /* st */ case AMOVD+AEND:return OP3(7); /* std */ case ASWAP: /* swap is symmetric */ case ASWAP+AEND:return OP3(15); case ATAS: return OP3(13); /* tas is really ldstub */ case ABN: return OPB(0); case ABE: return OPB(1); case ABLE: return OPB(2); case ABL: return OPB(3); case ABLEU: return OPB(4); case ABCS: return OPB(5); case ABNEG: return OPB(6); case ABVS: return OPB(7); case ABA: return OPB(8); case ABNE: return OPB(9); case ABG: return OPB(10); case ABGE: return OPB(11); case ABGU: return OPB(12); case ABCC: return OPB(13); case ABPOS: return OPB(14); case ABVC: return OPB(15); case AFBA: return OPFB(8); case AFBE: return OPFB(9); case AFBG: return OPFB(6); case AFBGE: return OPFB(11); case AFBL: return OPFB(4); case AFBLE: return OPFB(13); case AFBLG: return OPFB(2); case AFBN: return OPFB(0); case AFBNE: return OPFB(1); case AFBO: return OPFB(15); case AFBU: return OPFB(7); case AFBUE: return OPFB(10); case AFBUG: return OPFB(5); case AFBUGE: return OPFB(12); case AFBUL: return OPFB(3); case AFBULE: return OPFB(14); case ATN: return OPT(0); case ATE: return OPT(1); case ATLE: return OPT(2); case ATL: return OPT(3); case ATLEU: return OPT(4); case ATCS: return OPT(5); case ATNEG: return OPT(6); case ATVS: return OPT(7); case ATA: return OPT(8); case ATNE: return OPT(9); case ATG: return OPT(10); case ATGE: return OPT(11); case ATGU: return OPT(12); case ATCC: return OPT(13); case ATPOS: return OPT(14); case ATVC: return OPT(15); case AFADDF: return OPF1(65); case AFADDD: return OPF1(66); case AFADDX: return OPF1(67); case AFSUBF: return OPF1(69); case AFSUBD: return OPF1(70); case AFSUBX: return OPF1(71); case AFMULF: return OPF1(73); case AFMULD: return OPF1(74); case AFMULX: return OPF1(75); case AFDIVF: return OPF1(77); case AFDIVD: return OPF1(78); case AFDIVX: return OPF1(79); case AFMOVF: return OPF1(1); case AFNEGF: return OPF1(5); case AFABSF: return OPF1(9); case AFSQRTF: return OPF1(41); case AFSQRTD: return OPF1(42); case AFSQRTX: return OPF1(43); case AFMOVWF: return OPF1(196); case AFMOVWD: return OPF1(200); case AFMOVWX: return OPF1(204); case AFMOVFW: return OPF1(209); case AFMOVDW: return OPF1(210); case AFMOVXW: return OPF1(211); case AFMOVFD: return OPF1(201); case AFMOVFX: return OPF1(205); case AFMOVDF: return OPF1(198); case AFMOVDX: return OPF1(206); case AFMOVXF: return OPF1(199); case AFMOVXD: return OPF1(203); case AFCMPF: return OPF2(81); case AFCMPD: return OPF2(82); case AFCMPX: return OPF2(83); case AFCMPEF: return OPF2(85); case AFCMPED: return OPF2(86); case AFCMPEX: return OPF2(87); case AUNIMP: return 0; } diag("bad opcode %A", a); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -