📄 toir.c
字号:
{ vassert(isPlausibleIRType(ty)); return newIRTemp( irbb->tyenv, ty );}/* Various simple conversions */static UChar extend_s_5to8 ( UChar x ){ return toUChar((((Int)x) << 27) >> 27);}static UInt extend_s_8to32( UChar x ){ return (UInt)((((Int)x) << 24) >> 24);}static UInt extend_s_16to32 ( UInt x ){ return (UInt)((((Int)x) << 16) >> 16);}static ULong extend_s_16to64 ( UInt x ){ return (ULong)((((Long)x) << 48) >> 48);}static ULong extend_s_26to64 ( UInt x ){ return (ULong)((((Long)x) << 38) >> 38);}static ULong extend_s_32to64 ( UInt x ){ return (ULong)((((Long)x) << 32) >> 32);}/* Do a big-endian load of a 32-bit word, regardless of the endianness of the underlying host. */static UInt getUIntBigendianly ( UChar* p ){ UInt w = 0; w = (w << 8) | p[0]; w = (w << 8) | p[1]; w = (w << 8) | p[2]; w = (w << 8) | p[3]; return w;}/*------------------------------------------------------------*//*--- Helpers for constructing IR. ---*//*------------------------------------------------------------*/static void assign ( IRTemp dst, IRExpr* e ){ stmt( IRStmt_Tmp(dst, e) );}static void storeBE ( IRExpr* addr, IRExpr* data ){ vassert(typeOfIRExpr(irbb->tyenv, addr) == Ity_I32 || typeOfIRExpr(irbb->tyenv, addr) == Ity_I64); stmt( IRStmt_Store(Iend_BE,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* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 ){ return IRExpr_Triop(op, a1, a2, a3);}static IRExpr* qop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3, IRExpr* a4 ){ return IRExpr_Qop(op, a1, a2, a3, a4);}static IRExpr* mkexpr ( IRTemp tmp ){ return IRExpr_Tmp(tmp);}static IRExpr* mkU8 ( UChar i ){ return IRExpr_Const(IRConst_U8(i));}static IRExpr* mkU16 ( UInt i ){ return IRExpr_Const(IRConst_U16(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* 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)));}/* expand V128_8Ux16 to 2x V128_16Ux8's */static void expand8Ux16( IRExpr* vIn, /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ){ IRTemp ones8x16 = newTemp(Ity_V128); vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128); vassert(vEvn && *vEvn == IRTemp_INVALID); vassert(vOdd && *vOdd == IRTemp_INVALID); *vEvn = newTemp(Ity_V128); *vOdd = newTemp(Ity_V128); assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); assign( *vOdd, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), vIn) ); assign( *vEvn, binop(Iop_MullEven8Ux16, mkexpr(ones8x16), binop(Iop_ShrV128, vIn, mkU8(8))) );}/* expand V128_8Sx16 to 2x V128_16Sx8's */static void expand8Sx16( IRExpr* vIn, /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ){ IRTemp ones8x16 = newTemp(Ity_V128); vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128); vassert(vEvn && *vEvn == IRTemp_INVALID); vassert(vOdd && *vOdd == IRTemp_INVALID); *vEvn = newTemp(Ity_V128); *vOdd = newTemp(Ity_V128); assign( ones8x16, unop(Iop_Dup8x16, mkU8(0x1)) ); assign( *vOdd, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), vIn) ); assign( *vEvn, binop(Iop_MullEven8Sx16, mkexpr(ones8x16), binop(Iop_ShrV128, vIn, mkU8(8))) );}/* expand V128_16Uto8 to 2x V128_32Ux4's */static void expand16Ux8( IRExpr* vIn, /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ){ IRTemp ones16x8 = newTemp(Ity_V128); vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128); vassert(vEvn && *vEvn == IRTemp_INVALID); vassert(vOdd && *vOdd == IRTemp_INVALID); *vEvn = newTemp(Ity_V128); *vOdd = newTemp(Ity_V128); assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); assign( *vOdd, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), vIn) ); assign( *vEvn, binop(Iop_MullEven16Ux8, mkexpr(ones16x8), binop(Iop_ShrV128, vIn, mkU8(16))) );}/* expand V128_16Sto8 to 2x V128_32Sx4's */static void expand16Sx8( IRExpr* vIn, /*OUTs*/ IRTemp* vEvn, IRTemp* vOdd ){ IRTemp ones16x8 = newTemp(Ity_V128); vassert(typeOfIRExpr(irbb->tyenv, vIn) == Ity_V128); vassert(vEvn && *vEvn == IRTemp_INVALID); vassert(vOdd && *vOdd == IRTemp_INVALID); *vEvn = newTemp(Ity_V128); *vOdd = newTemp(Ity_V128); assign( ones16x8, unop(Iop_Dup16x8, mkU16(0x1)) ); assign( *vOdd, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), vIn) ); assign( *vEvn, binop(Iop_MullEven16Sx8, mkexpr(ones16x8), binop(Iop_ShrV128, vIn, mkU8(16))) );}/* break V128 to 4xI32's, then sign-extend to I64's */static void breakV128to4x64S( IRExpr* t128, /*OUTs*/ IRTemp* t3, IRTemp* t2, IRTemp* t1, IRTemp* t0 ){ IRTemp hi64 = newTemp(Ity_I64); IRTemp lo64 = newTemp(Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t128) == Ity_V128); vassert(t0 && *t0 == IRTemp_INVALID); vassert(t1 && *t1 == IRTemp_INVALID); vassert(t2 && *t2 == IRTemp_INVALID); vassert(t3 && *t3 == IRTemp_INVALID); *t0 = newTemp(Ity_I64); *t1 = newTemp(Ity_I64); *t2 = newTemp(Ity_I64); *t3 = newTemp(Ity_I64); assign( hi64, unop(Iop_V128HIto64, t128) ); assign( lo64, unop(Iop_V128to64, t128) ); assign( *t3, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(hi64))) ); assign( *t2, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(hi64))) ); assign( *t1, unop(Iop_32Sto64, unop(Iop_64HIto32, mkexpr(lo64))) ); assign( *t0, unop(Iop_32Sto64, unop(Iop_64to32, mkexpr(lo64))) );}/* break V128 to 4xI32's, then zero-extend to I64's */static void breakV128to4x64U ( IRExpr* t128, /*OUTs*/ IRTemp* t3, IRTemp* t2, IRTemp* t1, IRTemp* t0 ){ IRTemp hi64 = newTemp(Ity_I64); IRTemp lo64 = newTemp(Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t128) == Ity_V128); vassert(t0 && *t0 == IRTemp_INVALID); vassert(t1 && *t1 == IRTemp_INVALID); vassert(t2 && *t2 == IRTemp_INVALID); vassert(t3 && *t3 == IRTemp_INVALID); *t0 = newTemp(Ity_I64); *t1 = newTemp(Ity_I64); *t2 = newTemp(Ity_I64); *t3 = newTemp(Ity_I64); assign( hi64, unop(Iop_V128HIto64, t128) ); assign( lo64, unop(Iop_V128to64, t128) ); assign( *t3, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(hi64))) ); assign( *t2, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(hi64))) ); assign( *t1, unop(Iop_32Uto64, unop(Iop_64HIto32, mkexpr(lo64))) ); assign( *t0, unop(Iop_32Uto64, unop(Iop_64to32, mkexpr(lo64))) );}/* Signed saturating narrow 64S to 32 */static IRExpr* mkQNarrow64Sto32 ( IRExpr* t64 ){ IRTemp hi32 = newTemp(Ity_I32); IRTemp lo32 = newTemp(Ity_I32); vassert(typeOfIRExpr(irbb->tyenv, t64) == Ity_I64); assign( hi32, unop(Iop_64HIto32, t64)); assign( lo32, unop(Iop_64to32, t64)); return IRExpr_Mux0X( /* if (hi32 == (lo32 >>s 31)) */ unop(Iop_1Uto8, binop(Iop_CmpEQ32, mkexpr(hi32), binop( Iop_Sar32, mkexpr(lo32), mkU8(31)))), /* else: sign dep saturate: 1->0x80000000, 0->0x7FFFFFFF */ binop(Iop_Add32, mkU32(0x7FFFFFFF), binop(Iop_Shr32, mkexpr(hi32), mkU8(31))), /* then: within signed-32 range: lo half good enough */ mkexpr(lo32) );}/* Unsigned saturating narrow 64S to 32 */static IRExpr* mkQNarrow64Uto32 ( IRExpr* t64 ){ IRTemp hi32 = newTemp(Ity_I32); IRTemp lo32 = newTemp(Ity_I32); vassert(typeOfIRExpr(irbb->tyenv, t64) == Ity_I64); assign( hi32, unop(Iop_64HIto32, t64)); assign( lo32, unop(Iop_64to32, t64)); return IRExpr_Mux0X( /* if (top 32 bits of t64 are 0) */ unop(Iop_1Uto8, binop(Iop_CmpEQ32, mkexpr(hi32), mkU32(0))), /* else: positive saturate -> 0xFFFFFFFF */ mkU32(0xFFFFFFFF), /* then: within unsigned-32 range: lo half good enough */ mkexpr(lo32) );}/* Signed saturate narrow 64->32, combining to V128 */static IRExpr* mkV128from4x64S ( IRExpr* t3, IRExpr* t2, IRExpr* t1, IRExpr* t0 ){ vassert(typeOfIRExpr(irbb->tyenv, t3) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t2) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t1) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t0) == Ity_I64); return binop(Iop_64HLtoV128, binop(Iop_32HLto64, mkQNarrow64Sto32( t3 ), mkQNarrow64Sto32( t2 )), binop(Iop_32HLto64, mkQNarrow64Sto32( t1 ), mkQNarrow64Sto32( t0 )));}/* Unsigned saturate narrow 64->32, combining to V128 */static IRExpr* mkV128from4x64U ( IRExpr* t3, IRExpr* t2, IRExpr* t1, IRExpr* t0 ){ vassert(typeOfIRExpr(irbb->tyenv, t3) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t2) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t1) == Ity_I64); vassert(typeOfIRExpr(irbb->tyenv, t0) == Ity_I64); return binop(Iop_64HLtoV128, binop(Iop_32HLto64, mkQNarrow64Uto32( t3 ), mkQNarrow64Uto32( t2 )), binop(Iop_32HLto64, mkQNarrow64Uto32( t1 ), mkQNarrow64Uto32( t0 )));}/* Simulate irops Iop_MullOdd*, since we don't have them */#define MK_Iop_MullOdd8Ux16( expr_vA, expr_vB ) \ binop(Iop_MullEven8Ux16, \ binop(Iop_ShrV128, expr_vA, mkU8(8)), \ binop(Iop_ShrV128, expr_vB, mkU8(8)))#define MK_Iop_MullOdd8Sx16( expr_vA, expr_vB ) \ binop(Iop_MullEven8Sx16, \ binop(Iop_ShrV128, expr_vA, mkU8(8)), \ binop(Iop_ShrV128, expr_vB, mkU8(8)))#define MK_Iop_MullOdd16Ux8( expr_vA, expr_vB ) \ binop(Iop_MullEven16Ux8, \ binop(Iop_ShrV128, expr_vA, mkU8(16)), \ binop(Iop_ShrV128, expr_vB, mkU8(16)))#define MK_Iop_MullOdd16Sx8( expr_vA, expr_vB ) \ binop(Iop_MullEven16Sx8, \ binop(Iop_ShrV128, expr_vA, mkU8(16)), \ binop(Iop_ShrV128, expr_vB, mkU8(16)))static IRExpr* /* :: Ity_I64 */ mk64lo32Sto64 ( IRExpr* src ){ vassert(typeOfIRExpr(irbb->tyenv, src) == Ity_I64); return unop(Iop_32Sto64, unop(Iop_64to32, src));}static IRExpr* /* :: Ity_I64 */ mk64lo32Uto64 ( IRExpr* src ){ vassert(typeOfIRExpr(irbb->tyenv, src) == Ity_I64); return unop(Iop_32Uto64, unop(Iop_64to32, src));}static IROp mkSzOp ( IRType ty, IROp op8 ){ Int adj; vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64); 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 : (ty==Ity_I32 ? 2 : 3)); return adj + op8;}/* Make sure we get valid 32 and 64bit addresses */static Addr64 mkSzAddr ( IRType ty, Addr64 addr ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ( ty == Ity_I64 ? (Addr64)addr : (Addr64)extend_s_32to64( toUInt(addr) ) );}/* sz, ULong -> IRExpr */static IRExpr* mkSzImm ( IRType ty, ULong imm64 ){ vassert(ty == Ity_I32 || ty == Ity_I64); return ty == Ity_I64 ? mkU64(imm64) : mkU32((UInt)imm64);}/* sz, ULong -> IRConst */static IRConst* mkSzConst ( IRType ty, ULong imm64 ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -