📄 toir.c
字号:
return IRExpr_Binop(op, a1, a2);}static IRExpr* mkexpr ( IRTemp tmp ){ return IRExpr_Tmp(tmp);}//uu static IRExpr* mkU1 ( UInt i )//uu {//uu vassert(i < 2);//uu return IRExpr_Const(IRConst_U1( toBool(i) ));//uu }static IRExpr* mkU8 ( UChar i ){ return IRExpr_Const(IRConst_U8(i));}static IRExpr* mkU32 ( UInt i ){ return IRExpr_Const(IRConst_U32(i));}static IRExpr* loadBE ( IRType ty, IRExpr* data ){ return IRExpr_Load(Iend_BE,ty,data);}static IRExpr* mkOR1 ( IRExpr* arg1, IRExpr* arg2 ){ vassert(typeOfIRExpr(irbb->tyenv, arg1) == Ity_I1); vassert(typeOfIRExpr(irbb->tyenv, arg2) == Ity_I1); return unop(Iop_32to1, binop(Iop_Or32, unop(Iop_1Uto32, arg1), unop(Iop_1Uto32, arg2)));}static IRExpr* mkAND1 ( IRExpr* arg1, IRExpr* arg2 ){ vassert(typeOfIRExpr(irbb->tyenv, arg1) == Ity_I1); vassert(typeOfIRExpr(irbb->tyenv, arg2) == Ity_I1); return unop(Iop_32to1, binop(Iop_And32, unop(Iop_1Uto32, arg1), unop(Iop_1Uto32, arg2)));}static Int integerGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); // jrs: probably not necessary; only matters if we reference sub-parts // of the ppc32 registers, but that isn't the case // later: this might affect Altivec though? vassert(host_is_bigendian); switch (archreg) { case 0: return offsetof(VexGuestPPC32State, guest_GPR0); case 1: return offsetof(VexGuestPPC32State, guest_GPR1); case 2: return offsetof(VexGuestPPC32State, guest_GPR2); case 3: return offsetof(VexGuestPPC32State, guest_GPR3); case 4: return offsetof(VexGuestPPC32State, guest_GPR4); case 5: return offsetof(VexGuestPPC32State, guest_GPR5); case 6: return offsetof(VexGuestPPC32State, guest_GPR6); case 7: return offsetof(VexGuestPPC32State, guest_GPR7); case 8: return offsetof(VexGuestPPC32State, guest_GPR8); case 9: return offsetof(VexGuestPPC32State, guest_GPR9); case 10: return offsetof(VexGuestPPC32State, guest_GPR10); case 11: return offsetof(VexGuestPPC32State, guest_GPR11); case 12: return offsetof(VexGuestPPC32State, guest_GPR12); case 13: return offsetof(VexGuestPPC32State, guest_GPR13); case 14: return offsetof(VexGuestPPC32State, guest_GPR14); case 15: return offsetof(VexGuestPPC32State, guest_GPR15); case 16: return offsetof(VexGuestPPC32State, guest_GPR16); case 17: return offsetof(VexGuestPPC32State, guest_GPR17); case 18: return offsetof(VexGuestPPC32State, guest_GPR18); case 19: return offsetof(VexGuestPPC32State, guest_GPR19); case 20: return offsetof(VexGuestPPC32State, guest_GPR20); case 21: return offsetof(VexGuestPPC32State, guest_GPR21); case 22: return offsetof(VexGuestPPC32State, guest_GPR22); case 23: return offsetof(VexGuestPPC32State, guest_GPR23); case 24: return offsetof(VexGuestPPC32State, guest_GPR24); case 25: return offsetof(VexGuestPPC32State, guest_GPR25); case 26: return offsetof(VexGuestPPC32State, guest_GPR26); case 27: return offsetof(VexGuestPPC32State, guest_GPR27); case 28: return offsetof(VexGuestPPC32State, guest_GPR28); case 29: return offsetof(VexGuestPPC32State, guest_GPR29); case 30: return offsetof(VexGuestPPC32State, guest_GPR30); case 31: return offsetof(VexGuestPPC32State, guest_GPR31); default: break; } vpanic("integerGuestRegOffset(ppc32,be)"); /*notreached*/}static IRExpr* getIReg ( UInt archreg ){ vassert(archreg < 32); return IRExpr_Get( integerGuestRegOffset(archreg), Ity_I32 );}/* Ditto, but write to a reg instead. */static void putIReg ( UInt archreg, IRExpr* e ){ vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I32); stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) );}static Int floatGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); switch (archreg) { case 0: return offsetof(VexGuestPPC32State, guest_FPR0); case 1: return offsetof(VexGuestPPC32State, guest_FPR1); case 2: return offsetof(VexGuestPPC32State, guest_FPR2); case 3: return offsetof(VexGuestPPC32State, guest_FPR3); case 4: return offsetof(VexGuestPPC32State, guest_FPR4); case 5: return offsetof(VexGuestPPC32State, guest_FPR5); case 6: return offsetof(VexGuestPPC32State, guest_FPR6); case 7: return offsetof(VexGuestPPC32State, guest_FPR7); case 8: return offsetof(VexGuestPPC32State, guest_FPR8); case 9: return offsetof(VexGuestPPC32State, guest_FPR9); case 10: return offsetof(VexGuestPPC32State, guest_FPR10); case 11: return offsetof(VexGuestPPC32State, guest_FPR11); case 12: return offsetof(VexGuestPPC32State, guest_FPR12); case 13: return offsetof(VexGuestPPC32State, guest_FPR13); case 14: return offsetof(VexGuestPPC32State, guest_FPR14); case 15: return offsetof(VexGuestPPC32State, guest_FPR15); case 16: return offsetof(VexGuestPPC32State, guest_FPR16); case 17: return offsetof(VexGuestPPC32State, guest_FPR17); case 18: return offsetof(VexGuestPPC32State, guest_FPR18); case 19: return offsetof(VexGuestPPC32State, guest_FPR19); case 20: return offsetof(VexGuestPPC32State, guest_FPR20); case 21: return offsetof(VexGuestPPC32State, guest_FPR21); case 22: return offsetof(VexGuestPPC32State, guest_FPR22); case 23: return offsetof(VexGuestPPC32State, guest_FPR23); case 24: return offsetof(VexGuestPPC32State, guest_FPR24); case 25: return offsetof(VexGuestPPC32State, guest_FPR25); case 26: return offsetof(VexGuestPPC32State, guest_FPR26); case 27: return offsetof(VexGuestPPC32State, guest_FPR27); case 28: return offsetof(VexGuestPPC32State, guest_FPR28); case 29: return offsetof(VexGuestPPC32State, guest_FPR29); case 30: return offsetof(VexGuestPPC32State, guest_FPR30); case 31: return offsetof(VexGuestPPC32State, guest_FPR31); default: break; } vpanic("floatGuestRegOffset(ppc32)"); /*notreached*/}static IRExpr* getFReg ( UInt archreg ){ vassert(archreg < 32); return IRExpr_Get( floatGuestRegOffset(archreg), Ity_F64 );}/* Ditto, but write to a reg instead. */static void putFReg ( UInt archreg, IRExpr* e ){ vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_F64); stmt( IRStmt_Put(floatGuestRegOffset(archreg), e) );}static Int vectorGuestRegOffset ( UInt archreg ){ vassert(archreg < 32); switch (archreg) { case 0: return offsetof(VexGuestPPC32State, guest_VR0); case 1: return offsetof(VexGuestPPC32State, guest_VR1); case 2: return offsetof(VexGuestPPC32State, guest_VR2); case 3: return offsetof(VexGuestPPC32State, guest_VR3); case 4: return offsetof(VexGuestPPC32State, guest_VR4); case 5: return offsetof(VexGuestPPC32State, guest_VR5); case 6: return offsetof(VexGuestPPC32State, guest_VR6); case 7: return offsetof(VexGuestPPC32State, guest_VR7); case 8: return offsetof(VexGuestPPC32State, guest_VR8); case 9: return offsetof(VexGuestPPC32State, guest_VR9); case 10: return offsetof(VexGuestPPC32State, guest_VR10); case 11: return offsetof(VexGuestPPC32State, guest_VR11); case 12: return offsetof(VexGuestPPC32State, guest_VR12); case 13: return offsetof(VexGuestPPC32State, guest_VR13); case 14: return offsetof(VexGuestPPC32State, guest_VR14); case 15: return offsetof(VexGuestPPC32State, guest_VR15); case 16: return offsetof(VexGuestPPC32State, guest_VR16); case 17: return offsetof(VexGuestPPC32State, guest_VR17); case 18: return offsetof(VexGuestPPC32State, guest_VR18); case 19: return offsetof(VexGuestPPC32State, guest_VR19); case 20: return offsetof(VexGuestPPC32State, guest_VR20); case 21: return offsetof(VexGuestPPC32State, guest_VR21); case 22: return offsetof(VexGuestPPC32State, guest_VR22); case 23: return offsetof(VexGuestPPC32State, guest_VR23); case 24: return offsetof(VexGuestPPC32State, guest_VR24); case 25: return offsetof(VexGuestPPC32State, guest_VR25); case 26: return offsetof(VexGuestPPC32State, guest_VR26); case 27: return offsetof(VexGuestPPC32State, guest_VR27); case 28: return offsetof(VexGuestPPC32State, guest_VR28); case 29: return offsetof(VexGuestPPC32State, guest_VR29); case 30: return offsetof(VexGuestPPC32State, guest_VR30); case 31: return offsetof(VexGuestPPC32State, guest_VR31); default: break; } vpanic("vextorGuestRegOffset(ppc32)"); /*notreached*/}static IRExpr* getVReg ( UInt archreg ){ vassert(archreg < 32); return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_V128 );}/* Ditto, but write to a reg instead. */static void putVReg ( UInt archreg, IRExpr* e ){ vassert(archreg < 32); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_V128); stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) );}static Int guestCR321offset ( UInt cr ){ switch (cr) { case 0: return offsetof(VexGuestPPC32State, guest_CR0_321 ); case 1: return offsetof(VexGuestPPC32State, guest_CR1_321 ); case 2: return offsetof(VexGuestPPC32State, guest_CR2_321 ); case 3: return offsetof(VexGuestPPC32State, guest_CR3_321 ); case 4: return offsetof(VexGuestPPC32State, guest_CR4_321 ); case 5: return offsetof(VexGuestPPC32State, guest_CR5_321 ); case 6: return offsetof(VexGuestPPC32State, guest_CR6_321 ); case 7: return offsetof(VexGuestPPC32State, guest_CR7_321 ); default: vpanic("guestCR321offset(ppc32)"); }} static Int guestCR0offset ( UInt cr ){ switch (cr) { case 0: return offsetof(VexGuestPPC32State, guest_CR0_0 ); case 1: return offsetof(VexGuestPPC32State, guest_CR1_0 ); case 2: return offsetof(VexGuestPPC32State, guest_CR2_0 ); case 3: return offsetof(VexGuestPPC32State, guest_CR3_0 ); case 4: return offsetof(VexGuestPPC32State, guest_CR4_0 ); case 5: return offsetof(VexGuestPPC32State, guest_CR5_0 ); case 6: return offsetof(VexGuestPPC32State, guest_CR6_0 ); case 7: return offsetof(VexGuestPPC32State, guest_CR7_0 ); default: vpanic("guestCR3offset(ppc32)"); }} static void putCR321 ( UInt cr, IRExpr* e ){ vassert(cr < 8); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8); stmt( IRStmt_Put(guestCR321offset(cr), e) );}static void putCR0 ( UInt cr, IRExpr* e ){ vassert(cr < 8); vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8); stmt( IRStmt_Put(guestCR0offset(cr), e) );}static IRExpr* /* :: Ity_I8 */ getCR0 ( UInt cr ){ vassert(cr < 8); return IRExpr_Get(guestCR0offset(cr), Ity_I8);}static IRExpr* /* :: Ity_I8 */ getCR321 ( UInt cr ){ vassert(cr < 8); return IRExpr_Get(guestCR321offset(cr), Ity_I8);}static IRExpr* /* :: Ity_I8 */ getXER_SO ( void ){ return IRExpr_Get( OFFB_XER_SO, Ity_I8 );}// ROTL(src32, rot_amt5)static IRExpr* ROTL32 ( IRExpr* src, IRExpr* rot_amt ){ IRExpr* masked; vassert(typeOfIRExpr(irbb->tyenv,src) == Ity_I32); vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I32); masked = unop(Iop_32to8, binop(Iop_And32, rot_amt, mkU32(31))); // (src << rot_amt) | (src >> (32-rot_amt)) /* Note: the MuxOX is not merely an optimisation; it's needed because otherwise the Shr32 is a shift by the word size when masked denotes zero. For rotates by immediates, a lot of this junk gets folded out. */ return IRExpr_Mux0X( masked, /* zero rotate. */ src, /* non-zero rotate */ binop( Iop_Or32, binop(Iop_Shl32, src, masked), binop(Iop_Shr32, src, binop(Iop_Sub8, mkU8(32), masked)) ) );}/*------------------------------------------------------------*//*--- Helpers for condition codes. ---*//*------------------------------------------------------------*//* Condition register layout. In the hardware, CR is laid out like this. The leftmost end is the most significant bit in the register; however the IBM documentation numbers the bits backwards for some reason. CR0 CR1 .......... CR6 CR7 0 .. 3 ....................... 28 .. 31 (IBM bit numbering) 31 28 3 0 (normal bit numbering) Each CR field is 4 bits: < > == SO Hence in IBM's notation, BI=0 indicates CR7.SO, BI=1 is CR7.==, etc. Indexing from BI to guest state: let n = BI / 4 off = BI % 4 this references CR n: off==3 -> guest_CRn_SO off==2 -> guest_CRn_123 >> 1 off==1 -> guest_CRn_123 >> 2 off==0 -> guest_CRn_123 >> 3 Bear in mind the only significant bit in guest_CRn_SO is bit 0 (normal notation) and in guest_CRn_123 the significant bits are 3, 2 and 1 (normal notation).*//* Fetch the specified CR bit (as per IBM/hardware notation) and return it at the bottom of an I32; the top 31 bits are guaranteed to be zero. */static IRExpr* /* :: Ity_I32 */ getCRbit ( UInt bi ){ UInt n = bi / 4; UInt off = bi % 4; vassert(bi < 32); if (off == 3) { /* Fetch the SO bit for this CR field */ /* Note: And32 is redundant paranoia iff guest state only has 0 or 1 in that slot. */ return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1)); } else { /* Fetch the <, > or == bit for this CR field */ return binop( Iop_And32, binop( Iop_Shr32, unop(Iop_8Uto32, getCR321(n)), mkU8(3-off) ), mkU32(1) ); }}/* Dually, write the least significant bit of BIT to the specified CR bit. Indexing as per getCRbit. */static void putCRbit ( UInt bi, IRExpr* bit ){ IRExpr* safe; vassert(typeOfIRExpr(irbb->tyenv,bit) == Ity_I32); safe = binop(Iop_And32, bit, mkU32(1)); UInt n = bi / 4; UInt off = bi % 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -