📄 asmout.c
字号:
o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6); break; case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */ v = regoff(&p->to); if(v & 0x8000L) v += 0x10000L; r = p->to.reg; if(r == NREG) r = o->param; o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16); o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v); break; case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */ v = regoff(&p->from); if(v & 0x8000L) v += 0x10000L; r = p->from.reg; if(r == NREG) r = o->param; o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16); o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v); break; case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */ v = regoff(&p->from); if(v & 0x8000L) v += 0x10000L; r = p->from.reg; if(r == NREG) r = o->param; o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16); o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v); o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0); break; case 40: /* word */ if(aflag) return 0; o1 = regoff(&p->from); break; case 41: /* stswi */ o1 = AOP_RRR(opirr(p->as), p->from.reg, p->to.reg, 0) | ((regoff(&p->from3)&0x7F)<<11); break; case 42: /* lswi */ o1 = AOP_RRR(opirr(p->as), p->to.reg, p->from.reg, 0) | ((regoff(&p->from3)&0x7F)<<11); break; case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */ r = p->reg; if(r == NREG) r = 0; o1 = AOP_RRR(oprrr(p->as), 0, r, p->from.reg); break; case 44: /* indexed store */ r = p->reg; if(r == NREG) r = 0; o1 = AOP_RRR(opstorex(p->as), p->from.reg, r, p->to.reg); break; case 45: /* indexed load */ r = p->reg; if(r == NREG) r = 0; o1 = AOP_RRR(oploadx(p->as), p->to.reg, r, p->from.reg); break; case 46: /* plain op */ o1 = oprrr(p->as); break; case 47: /* op Ra, Rd; also op [Ra,] Rd */ r = p->from.reg; if(r == NREG) r = p->to.reg; o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0); break; case 48: /* op Rs, Ra */ r = p->from.reg; if(r == NREG) r = p->to.reg; o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, 0); break; case 49: /* op Rb */ o1 = AOP_RRR(oprrr(p->as), 0, 0, p->from.reg); break;/*50*/ case 51: /* rem[u] r1[,r2],r3 */ r = p->reg; if(r == NREG) r = p->to.reg; v = oprrr(p->as); t = v & ((1<<10)|1); /* OE|Rc */ o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg); o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg); o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r); break; case 52: /* mtfsbNx cr(n) */ v = regoff(&p->from)&31L; o1 = AOP_RRR(oprrr(p->as), v, 0, 0); break; case 53: /* mffsX ,fr1 */ o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0); break; case 54: /* mov msr,r1; mov r1, msr*/ if(oclass(p->from) == C_REG) o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0); else o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0); break; case 55: /* mov sreg,r1; mov r1,sreg */ v = 0; if(p->from.type == D_SREG) { r = p->from.reg; o1 = OP_MFSR; if(r == NREG && p->reg != NREG) { r = 0; v = p->reg; o1 = OP_MFSRIN; } o1 = AOP_RRR(o1, p->to.reg, r&15L, v); } else { r = p->to.reg; o1 = OP_MTSR; if(r == NREG && p->reg != NREG) { r = 0; v = p->reg; o1 = OP_MTSRIN; } o1 = AOP_RRR(o1, p->from.reg, r&15L, v); } if(r == NREG) diag("illegal move indirect to/from segment register\n%P", p); break; case 56: /* sra $sh,[s,]a */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = AOP_RRR(opirr(p->as), r, p->to.reg, v&31L); break; case 57: /* slw $sh,[s,]a -> rlwinm ... */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; /* * Let user (gs) shoot himself in the foot. * qc has already complained. * if(v < 0 || v > 31) diag("illegal shift %ld\n%P", v, p); */ if(v < 0) v = 0; else if(v > 32) v = 32; if(p->as == ASRW || p->as == ASRWCC) { /* shift right */ mask[0] = v; mask[1] = 31; v = 32-v; } else { mask[0] = 0; mask[1] = 31-v; } o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]); if(p->as == ASLWCC || p->as == ASRWCC) o1 |= 1; /* Rc */ break; case 58: /* logical $andcon,[s],a */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = LOP_IRR(opirr(p->as), p->to.reg, r, v); break; case 59: /* or/and $ucon,,r */ v = regoff(&p->from); r = p->reg; if(r == NREG) r = p->to.reg; o1 = LOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16); /* oris, xoris, andis */ break; case 60: /* tw to,a,b */ r = regoff(&p->from)&31L; o1 = AOP_RRR(oprrr(p->as), r, p->reg, p->to.reg); break; case 61: /* tw to,a,$simm */ r = regoff(&p->from)&31L; v = regoff(&p->to); o1 = AOP_IRR(opirr(p->as), r, p->reg, v); break; case 62: /* rlwmi $sh,s,$mask,a */ v = regoff(&p->from); maskgen(p, mask, regoff(&p->from3)); o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, v); o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1); break; case 63: /* rlwmi b,s,$mask,a */ maskgen(p, mask, regoff(&p->from3)); o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, p->from.reg); o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1); break; case 64: /* mtfsf fr[, $m] {,fpcsr} */ if(p->from3.type != D_NONE) v = regoff(&p->from3)&255L; else v = 255; o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11); break; case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */ if(p->to.reg == NREG) diag("must specify FPSCR(n)\n%P", p); o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(&p->from)&31L)<<12); break; case 66: /* mov spr,r1; mov r1,spr, also dcr */ if(p->from.type == D_REG) { r = p->from.reg; v = p->to.offset; if(p->to.type == D_DCR) o1 = OPVCC(31,451,0,0); /* mtdcr */ else o1 = OPVCC(31,467,0,0); /* mtspr */ } else { r = p->to.reg; v = p->from.offset; if(p->from.type == D_DCR) o1 = OPVCC(31,323,0,0); /* mfdcr */ else o1 = OPVCC(31,339,0,0); /* mfspr */ } o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11); break; case 67: /* mcrf crfD,crfS */ if(p->from.type != D_CREG || p->from.reg == NREG || p->to.type != D_CREG || p->to.reg == NREG) diag("illegal CR field number\n%P", p); o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0); break; case 68: /* mfcr rD */ if(p->from.type == D_CREG && p->from.reg != NREG) diag("must move whole CR to register\n%P", p); o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0); break; case 69: /* mtcrf CRM,rS */ if(p->from3.type != D_NONE) { if(p->to.reg != NREG) diag("can't use both mask and CR(n)\n%P", p); v = regoff(&p->from3) & 0xff; } else { if(p->to.reg == NREG) v = 0xff; /* CR */ else v = 1<<(7-(p->to.reg&7)); /* CR(n) */ } o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12); break; case 70: /* [f]cmp r,r,cr*/ if(p->reg == NREG) r = 0; else r = (p->reg&7)<<2; o1 = AOP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg); break; case 71: /* cmp[l] r,i,cr*/ if(p->reg == NREG) r = 0; else r = (p->reg&7)<<2; o1 = AOP_RRR(opirr(p->as), r, p->from.reg, 0) | (regoff(&p->to)&0xffff); break; case 72: /* mcrxr crfD */ if(p->to.reg == NREG) diag("must move XER to CR(n)\n%P", p); o1 = AOP_RRR(OP_MCRXR, ((p->to.reg&7L)<<2), 0, 0); break; case 73: /* mcrfs crfD,crfS */ if(p->from.type != D_FPSCR || p->from.reg == NREG || p->to.type != D_CREG || p->to.reg == NREG) diag("illegal FPSCR/CR field number\n%P", p); o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0); break; /* relocation operations */ case 74: v = regoff(&p->to); o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16); o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v); if(dlm) reloc(&p->to, p->pc, 1); break; case 75: v = regoff(&p->from); o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16); o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v); if(dlm) reloc(&p->from, p->pc, 1); break; case 76: v = regoff(&p->from); o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16); o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v); o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0); if(dlm) reloc(&p->from, p->pc, 1); 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;}longoprrr(int a){ switch(a) { case AADD: return OPVCC(31,266,0,0); case AADDCC: return OPVCC(31,266,0,1); case AADDV: return OPVCC(31,266,1,0); case AADDVCC: return OPVCC(31,266,1,1); case AADDC: return OPVCC(31,10,0,0); case AADDCCC: return OPVCC(31,10,0,1); case AADDCV: return OPVCC(31,10,1,0); case AADDCVCC: return OPVCC(31,10,1,1); case AADDE: return OPVCC(31,138,0,0); case AADDECC: return OPVCC(31,138,0,1); case AADDEV: return OPVCC(31,138,1,0); case AADDEVCC: return OPVCC(31,138,1,1); case AADDME: return OPVCC(31,234,0,0); case AADDMECC: return OPVCC(31,234,0,1); case AADDMEV: return OPVCC(31,234,1,0); case AADDMEVCC: return OPVCC(31,234,1,1); case AADDZE: return OPVCC(31,202,0,0); case AADDZECC: return OPVCC(31,202,0,1); case AADDZEV: return OPVCC(31,202,1,0); case AADDZEVCC: return OPVCC(31,202,1,1); case AAND: return OPVCC(31,28,0,0); case AANDCC: return OPVCC(31,28,0,1); case AANDN: return OPVCC(31,60,0,0); case AANDNCC: return OPVCC(31,60,0,1); case ACMP: return OPVCC(31,0,0,0); case ACMPU: return OPVCC(31,32,0,0); case ACNTLZW: return OPVCC(31,26,0,0); case ACNTLZWCC: return OPVCC(31,26,0,1); case ACRAND: return OPVCC(19,257,0,0); case ACRANDN: return OPVCC(19,129,0,0); case ACREQV: return OPVCC(19,289,0,0); case ACRNAND: return OPVCC(19,225,0,0); case ACRNOR: return OPVCC(19,33,0,0); case ACROR: return OPVCC(19,449,0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -