📄 toir.c
字号:
case 0x07: // mulli (Multiply Low Immediate, PPC32 p490) DIP("mulli r%d,r%d,0x%x\n", Rd_addr, Ra_addr, SIMM_16); assign( res64, binop(Iop_MullS32, mkexpr(Ra), mkU32(EXTS_SIMM)) ); assign( Rd, unop(Iop_64to32, mkexpr(res64)) ); break; case 0x08: // subfic (Subtract from Immediate Carrying, PPC32 p540) DIP("subfic r%d,r%d,0x%x\n", Rd_addr, Ra_addr, SIMM_16); // rD = exts_simm - rA assign( Rd, binop(Iop_Sub32, mkU32(EXTS_SIMM), mkexpr(Ra)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFI, mkexpr(Rd), mkexpr(Ra), mkU32(EXTS_SIMM), mkU32(0)/*old xer.ca, which is ignored*/ ); break; /* XO-Form */ case 0x1F: do_rc = True; // All below record to CR switch (opc2) { case 0x10A: // add (Add, PPC32 p347) DIP("add%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADD, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x00A: // addc (Add Carrying, PPC32 p348) DIP("addc%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) ); set_XER_CA( PPC32G_FLAG_OP_ADD, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), mkU32(0)/*old xer.ca, which is ignored*/ ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADD, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x08A: { // adde (Add Extended, PPC32 p349) IRTemp old_xer_ca = newTemp(Ity_I32); DIP("adde%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = rA + rB + XER[CA] assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, mkexpr(Ra), binop(Iop_Add32, mkexpr(Rb), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; } case 0x0EA: { // addme (Add to Minus One Extended, PPC32 p354) IRTemp old_xer_ca = newTemp(Ity_I32); if (Rb_addr != 0) { vex_printf("dis_int_arith(PPC32)(addme,Rb_addr)\n"); return False; } DIP("addme%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = rA + (-1) + XER[CA] // => Just another form of adde assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, mkexpr(Ra), binop(Iop_Add32, mkU32(-1), mkexpr(old_xer_ca)) )); set_XER_CA( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkU32(-1), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkU32(-1) ); } break; } case 0x0CA: { // addze (Add to Zero Extended, PPC32 p355) IRTemp old_xer_ca = newTemp(Ity_I32); if (Rb_addr != 0) { vex_printf("dis_int_arith(PPC32)(addze,Rb_addr)\n"); return False; } DIP("addze%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = rA + (0) + XER[CA] // => Just another form of adde assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, mkexpr(Ra), mkexpr(old_xer_ca)) ); set_XER_CA( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkU32(0), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_ADDE, mkexpr(Rd), mkexpr(Ra), mkU32(0) ); } break; } case 0x1EB: // divw (Divide Word, PPC32 p388) DIP("divw%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( Rd, binop(Iop_DivS32, mkexpr(Ra), mkexpr(Rb)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_DIVW, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } /* Note: if (0x8000_0000 / -1) or (x / 0) => Rd=undef, if(flag_Rc) CR7=undef, if(flag_OE) XER_OV=1 => But _no_ exception raised. */ break; case 0x1CB: // divwu (Divide Word Unsigned, PPC32 p389) DIP("divwu%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( Rd, binop(Iop_DivU32, mkexpr(Ra), mkexpr(Rb)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_DIVWU, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } /* Note: ditto comment divw, for (x / 0) */ break; case 0x04B: // mulhw (Multiply High Word, PPC32 p488) if (flag_OE != 0) { vex_printf("dis_int_arith(PPC32)(mulhw,flag_OE)\n"); return False; } DIP("mulhw%s r%d,r%d,r%d\n", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( res64, binop(Iop_MullS32, mkexpr(Ra), mkexpr(Rb)) ); assign( Rd, unop(Iop_64HIto32, mkexpr(res64)) ); break; case 0x00B: // mulhwu (Multiply High Word Unsigned, PPC32 p489) if (flag_OE != 0) { vex_printf("dis_int_arith(PPC32)(mulhwu,flag_OE)\n"); return False; } DIP("mulhwu%s r%d,r%d,r%d\n", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( res64, binop(Iop_MullU32, mkexpr(Ra), mkexpr(Rb)) ); assign( Rd, unop(Iop_64HIto32, mkexpr(res64)) ); break; case 0x0EB: // mullw (Multiply Low Word, PPC32 p491) DIP("mullw%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); assign( res64, binop(Iop_MullU32, mkexpr(Ra), mkexpr(Rb)) ); assign( Rd, unop(Iop_64to32, mkexpr(res64)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_MULLW, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x068: // neg (Negate, PPC32 p493) if (Rb_addr != 0) { vex_printf("dis_int_arith(PPC32)(neg,Rb_addr)\n"); return False; } DIP("neg%s%s r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr); // rD = (log not)rA + 1 assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), mkU32(1)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_NEG, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x028: // subf (Subtract From, PPC32 p537) DIP("subf%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = rB - rA assign( Rd, binop(Iop_Sub32, mkexpr(Rb), mkexpr(Ra)) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBF, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x008: // subfc (Subtract from Carrying, PPC32 p538) DIP("subfc%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = rB - rA assign( Rd, binop(Iop_Sub32, mkexpr(Rb), mkexpr(Ra)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFC, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), mkU32(0)/*old xer.ca, which is ignored*/ ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFC, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; case 0x088: {// subfe (Subtract from Extended, PPC32 p539) IRTemp old_xer_ca = newTemp(Ity_I32); DIP("subfe%s%s r%d,r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr, Rb_addr); // rD = (log not)rA + rB + XER[CA] assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), binop(Iop_Add32, mkexpr(Rb), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkexpr(Rb) ); } break; } case 0x0E8: { // subfme (Subtract from Minus One Extended, PPC32 p541) IRTemp old_xer_ca = newTemp(Ity_I32); if (Rb_addr != 0) { vex_printf("dis_int_arith(PPC32)(subfme,Rb_addr)\n"); return False; } DIP("subfme%s%s r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr); // rD = (log not)rA + (-1) + XER[CA] // => Just another form of subfe assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), binop(Iop_Add32, mkU32(-1), mkexpr(old_xer_ca))) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkU32(-1), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkU32(-1) ); } break; } case 0x0C8: { // subfze (Subtract from Zero Extended, PPC32 p542) IRTemp old_xer_ca = newTemp(Ity_I32); if (Rb_addr != 0) { vex_printf("dis_int_arith(PPC32)(subfze,Rb_addr)\n"); return False; } DIP("subfze%s%s r%d,r%d\n", flag_OE ? "o" : "", flag_Rc ? "." : "", Rd_addr, Ra_addr); // rD = (log not)rA + (0) + XER[CA] // => Just another form of subfe assign( old_xer_ca, get_XER_CA() ); assign( Rd, binop(Iop_Add32, unop(Iop_Not32, mkexpr(Ra)), mkexpr(old_xer_ca)) ); set_XER_CA( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkU32(0), mkexpr(old_xer_ca) ); if (flag_OE) { set_XER_OV( PPC32G_FLAG_OP_SUBFE, mkexpr(Rd), mkexpr(Ra), mkU32(0) ); } break; } default: vex_printf("dis_int_arith(PPC32)(opc2)\n"); return False; } break; default: vex_printf("dis_int_arith(PPC32)(opc1)\n"); return False; } putIReg( Rd_addr, mkexpr(Rd) ); if (do_rc && flag_Rc) { set_CR0( mkexpr(Rd) ); } return True;}/* Integer Compare Instructions*/static Bool dis_int_cmp ( UInt theInstr ){ UChar opc1 = toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:31] */ UChar crfD = toUChar((theInstr >> 23) & 0x7); /* theInstr[23:25] */ UChar b9 = toUChar((theInstr >> 22) & 0x1); /* theInstr[22] */ UChar flag_L = toUChar((theInstr >> 21) & 0x1); /* theInstr[21] */ UChar Ra_addr = toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:20] */ /* D-Form */ UInt UIMM_16 = (theInstr >> 0) & 0xFFFF; /* theInstr[0:15] */ /* X-Form */ UChar Rb_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */ UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */ UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ UInt EXTS_SIMM = 0; IRTemp Ra = newTemp(Ity_I32); IRTemp Rb = newTemp(Ity_I32);//uu IRTemp xer_so = newTemp(Ity_I32);//uu IRTemp cr7 = newTemp(Ity_I32);//uu IRTemp mux1 = newTemp(Ity_I32);//uu IRTemp mux2 = newTemp(Ity_I32);//uu IRExpr* irx_cmp_lt;//uu IRExpr* irx_cmp_eq; assign( Ra, getIReg(Ra_addr) ); if (flag_L==1) { // L==1 invalid for 32 bit. vex_printf("dis_int_cmp(PPC32)(flag_L)\n"); return False; } if (b9 != 0) { vex_printf("dis_int_cmp(PPC32)(b9)\n"); return False; } switch (opc1) { case 0x0B: // cmpi (Compare Immediate, PPC32 p368) EXTS_SIMM = extend_s_16to32(UIMM_16); DIP("cmp cr%d,r%d,%d\n", crfD, Ra_addr, EXTS_SIMM); putCR321( crfD, unop(Iop_32to8, binop(Iop_CmpORD32S, mkexpr(Ra), mkU32(EXTS_SIMM))) ); putCR0( crfD, getXER_SO() ); break; case 0x0A: // cmpli (Compare Logical Immediate, PPC32 p370) DIP("cmpli cr%d,r%d,0x%x\n", crfD, Ra_addr, UIMM_16); putCR321( crfD, unop(Iop_32to8, binop(Iop_CmpORD32U, mkexpr(Ra), mkU32(UIMM_16))) ); putCR0( crfD, getXER_SO() ); break; /* X Form */ case 0x1F: if (b0 != 0) { vex_printf("dis_int_cmp(PPC32)(0x1F,b0)\n"); return False; } assign( Rb, getIReg(Rb_addr) );//zz irx_cmp_eq = binop(Iop_CmpEQ32, mkexpr(Ra), mkexpr(Rb)); switch (opc2) { case 0x000: // cmp (Compare, PPC32 p367) DIP("cmp cr%d,r%d,r%d\n", crfD, Ra_addr, Rb_addr); putCR321( crfD, unop(Iop_32to8, binop(Iop_CmpORD32S, mkexpr(Ra), mkexpr(Rb))) ); putCR0( crfD, getXER_SO() ); b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -