📄 toir.c
字号:
/* NOTREACHED */ vpanic("integerGuestRegOffset(x86,le)");}static Int segmentGuestRegOffset ( UInt sreg ){ switch (sreg) { case R_ES: return OFFB_ES; case R_CS: return OFFB_CS; case R_SS: return OFFB_SS; case R_DS: return OFFB_DS; case R_FS: return OFFB_FS; case R_GS: return OFFB_GS; default: vpanic("segmentGuestRegOffset(x86)"); }}static Int xmmGuestRegOffset ( UInt xmmreg ){ switch (xmmreg) { case 0: return OFFB_XMM0; case 1: return OFFB_XMM1; case 2: return OFFB_XMM2; case 3: return OFFB_XMM3; case 4: return OFFB_XMM4; case 5: return OFFB_XMM5; case 6: return OFFB_XMM6; case 7: return OFFB_XMM7; default: vpanic("xmmGuestRegOffset"); }}/* Lanes of vector registers are always numbered from zero being the least significant lane (rightmost in the register). */static Int xmmGuestRegLane16offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 8); return xmmGuestRegOffset( xmmreg ) + 2 * laneno;}static Int xmmGuestRegLane32offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 4); return xmmGuestRegOffset( xmmreg ) + 4 * laneno;}static Int xmmGuestRegLane64offset ( UInt xmmreg, Int laneno ){ /* Correct for little-endian host only. */ vassert(!host_is_bigendian); vassert(laneno >= 0 && laneno < 2); return xmmGuestRegOffset( xmmreg ) + 8 * laneno;}static IRExpr* getIReg ( Int sz, UInt archreg ){ vassert(sz == 1 || sz == 2 || sz == 4); vassert(archreg < 8); return IRExpr_Get( integerGuestRegOffset(sz,archreg), szToITy(sz) );}/* Ditto, but write to a reg instead. */static void putIReg ( Int sz, UInt archreg, IRExpr* e ){ IRType ty = typeOfIRExpr(irbb->tyenv, e); switch (sz) { case 1: vassert(ty == Ity_I8); break; case 2: vassert(ty == Ity_I16); break; case 4: vassert(ty == Ity_I32); break; default: vpanic("putIReg(x86)"); } vassert(archreg < 8); stmt( IRStmt_Put(integerGuestRegOffset(sz,archreg), e) );}static IRExpr* getSReg ( UInt sreg ){ return IRExpr_Get( segmentGuestRegOffset(sreg), Ity_I16 );}static void putSReg ( UInt sreg, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16); stmt( IRStmt_Put( segmentGuestRegOffset(sreg), e ) );}static IRExpr* getXMMReg ( UInt xmmreg ){ return IRExpr_Get( xmmGuestRegOffset(xmmreg), Ity_V128 );}static IRExpr* getXMMRegLane64 ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane64offset(xmmreg,laneno), Ity_I64 );}static IRExpr* getXMMRegLane64F ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane64offset(xmmreg,laneno), Ity_F64 );}static IRExpr* getXMMRegLane32 ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane32offset(xmmreg,laneno), Ity_I32 );}static IRExpr* getXMMRegLane32F ( UInt xmmreg, Int laneno ){ return IRExpr_Get( xmmGuestRegLane32offset(xmmreg,laneno), Ity_F32 );}static void putXMMReg ( UInt xmmreg, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_V128); stmt( IRStmt_Put( xmmGuestRegOffset(xmmreg), e ) );}static void putXMMRegLane64 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I64); stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );}static void putXMMRegLane64F ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_F64); stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );}static void putXMMRegLane32F ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_F32); stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );}static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I32); stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );}static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e ){ vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16); stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );}static void assign ( IRTemp dst, IRExpr* e ){ stmt( IRStmt_Tmp(dst, e) );}static void storeLE ( IRExpr* addr, IRExpr* data ){ stmt( IRStmt_Store(Iend_LE,addr,data) );}static IRExpr* unop ( IROp op, IRExpr* a ){ return IRExpr_Unop(op, a);}static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 ){ return IRExpr_Binop(op, a1, a2);}static IRExpr* mkexpr ( IRTemp tmp ){ return IRExpr_Tmp(tmp);}static IRExpr* mkU8 ( UInt i ){ vassert(i < 256); return IRExpr_Const(IRConst_U8( (UChar)i ));}static IRExpr* mkU16 ( UInt i ){ vassert(i < 65536); return IRExpr_Const(IRConst_U16( (UShort)i ));}static IRExpr* mkU32 ( UInt i ){ return IRExpr_Const(IRConst_U32(i));}static IRExpr* mkU64 ( ULong i ){ return IRExpr_Const(IRConst_U64(i));}static IRExpr* mkU ( IRType ty, UInt i ){ if (ty == Ity_I8) return mkU8(i); if (ty == Ity_I16) return mkU16(i); if (ty == Ity_I32) return mkU32(i); /* If this panics, it usually means you passed a size (1,2,4) value as the IRType, rather than a real IRType. */ vpanic("mkU(x86)");}static IRExpr* mkV128 ( UShort mask ){ return IRExpr_Const(IRConst_V128(mask));}static IRExpr* loadLE ( IRType ty, IRExpr* data ){ return IRExpr_Load(Iend_LE,ty,data);}static IROp mkSizedOp ( IRType ty, IROp op8 ){ Int adj; vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32); vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 || op8 == Iop_Mul8 || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 || op8 == Iop_Not8 || op8 == Iop_Neg8); adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2); return adj + op8;}static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd ){ if (szSmall == 1 && szBig == 4) { return signd ? Iop_8Sto32 : Iop_8Uto32; } if (szSmall == 1 && szBig == 2) { return signd ? Iop_8Sto16 : Iop_8Uto16; } if (szSmall == 2 && szBig == 4) { return signd ? Iop_16Sto32 : Iop_16Uto32; } vpanic("mkWidenOp(x86,guest)");}/*------------------------------------------------------------*//*--- Helpers for %eflags. ---*//*------------------------------------------------------------*//* -------------- Evaluating the flags-thunk. -------------- *//* Build IR to calculate all the eflags from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_I32. */static IRExpr* mk_x86g_calculate_eflags_all ( void ){ IRExpr** args = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 0/*regparm*/, "x86g_calculate_eflags_all", &x86g_calculate_eflags_all, args ); /* Exclude OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3); return call;}/* Build IR to calculate some particular condition from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_Bit. */static IRExpr* mk_x86g_calculate_condition ( X86Condcode cond ){ IRExpr** args = mkIRExprVec_5( mkU32(cond), IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 0/*regparm*/, "x86g_calculate_condition", &x86g_calculate_condition, args ); /* Exclude the requested condition, OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4); return unop(Iop_32to1, call);}/* Build IR to calculate just the carry flag from stored CC_OP/CC_DEP1/CC_DEP2/CC_NDEP. Returns an expression :: Ity_I32. */static IRExpr* mk_x86g_calculate_eflags_c ( void ){ IRExpr** args = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_DEP1, Ity_I32), IRExpr_Get(OFFB_CC_DEP2, Ity_I32), IRExpr_Get(OFFB_CC_NDEP, Ity_I32) ); IRExpr* call = mkIRExprCCall( Ity_I32, 3/*regparm*/, "x86g_calculate_eflags_c", &x86g_calculate_eflags_c, args ); /* Exclude OP and NDEP from definedness checking. We're only interested in DEP1 and DEP2. */ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3); return call;}/* -------------- Building the flags-thunk. -------------- *//* The machinery in this section builds the flag-thunk following a flag-setting operation. Hence the various setFlags_* functions.*/static Bool isAddSub ( IROp op8 ){ return toBool(op8 == Iop_Add8 || op8 == Iop_Sub8);}static Bool isLogic ( IROp op8 ){ return toBool(op8 == Iop_And8 || op8 == Iop_Or8 || op8 == Iop_Xor8);}/* U-widen 8/16/32 bit int expr to 32. */static IRExpr* widenUto32 ( IRExpr* e ){ switch (typeOfIRExpr(irbb->tyenv,e)) { case Ity_I32: return e; case Ity_I16: return unop(Iop_16Uto32,e); case Ity_I8: return unop(Iop_8Uto32,e); default: vpanic("widenUto32"); }}/* S-widen 8/16/32 bit int expr to 32. */static IRExpr* widenSto32 ( IRExpr* e ){ switch (typeOfIRExpr(irbb->tyenv,e)) { case Ity_I32: return e; case Ity_I16: return unop(Iop_16Sto32,e); case Ity_I8: return unop(Iop_8Sto32,e); default: vpanic("widenSto32"); }}/* Narrow 8/16/32 bit int expr to 8/16/32. Clearly only some of these combinations make sense. */static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e ){ IRType src_ty = typeOfIRExpr(irbb->tyenv,e); if (src_ty == dst_ty) return e; if (src_ty == Ity_I32 && dst_ty == Ity_I16) return unop(Iop_32to16, e); if (src_ty == Ity_I32 && dst_ty == Ity_I8) return unop(Iop_32to8, e); vex_printf("\nsrc, dst tys are: "); ppIRType(src_ty); vex_printf(", "); ppIRType(dst_ty); vex_printf("\n"); vpanic("narrowTo(x86)");}/* Set the flags thunk OP, DEP1 and DEP2 fields. The supplied op is auto-sized up to the real op. */static void setFlags_DEP1_DEP2 ( IROp op8, IRTemp dep1, IRTemp dep2, IRType ty ){ Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2); vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32); switch (op8) { case Iop_Add8: ccOp += X86G_CC_OP_ADDB; break; case Iop_Sub8: ccOp += X86G_CC_OP_SUBB; break; default: ppIROp(op8); vpanic("setFlags_DEP1_DEP2(x86)"); } stmt( IRStmt_Put( OFFB_CC_OP, mkU32(ccOp)) ); stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) ); stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(dep2))) ); /* Set NDEP even though it isn't used. This makes redundant-PUT elimination of previous stores to this field work better. */ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));}/* Set the OP and DEP1 fields only, and write zero to DEP2. */static
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -