⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
   that the stack red zone (viz, -288(r1) .. -1(r1)) becomes   undefined.  That is at function calls and returns.  Only in 64-bit   mode - ELF ppc32 doesn't have this "feature".*/static void make_redzone_AbiHint ( HChar* who ){   if (0) vex_printf("AbiHint: %s\n", who);   vassert(mode64);   stmt( IRStmt_AbiHint(             binop(Iop_Sub64, getIReg(1), mkU64(288)),             288    ));}/*------------------------------------------------------------*//*--- 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 is 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==0   ->  guest_CRn_321 >> 3        off==1   ->  guest_CRn_321 >> 2        off==2   ->  guest_CRn_321 >> 1        off==3   ->  guest_CRn_SO   Bear in mind the only significant bit in guest_CRn_SO is bit 0   (normal notation) and in guest_CRn_321 the significant bits are   3, 2 and 1 (normal notation).*/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);}/* 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(toUChar(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 ){   UInt    n, off;   IRExpr* safe;   vassert(typeOfIRExpr(irbb->tyenv,bit) == Ity_I32);   safe = binop(Iop_And32, bit, mkU32(1));   n   = bi / 4;   off = bi % 4;   vassert(bi < 32);   if (off == 3) {      /* This is the SO bit for this CR field */      putCR0(n, unop(Iop_32to8, safe));   } else {      off = 3 - off;      vassert(off == 1 || off == 2 || off == 3);      putCR321(         n,         unop( Iop_32to8,               binop( Iop_Or32,                      /* old value with field masked out */                      binop(Iop_And32, unop(Iop_8Uto32, getCR321(n)),                                       mkU32(~(1 << off))),                      /* new value in the right place */                      binop(Iop_Shl32, safe, mkU8(toUChar(off)))               )         )      );   }}/* Fetch the specified CR bit (as per IBM/hardware notation) and   return it somewhere in an I32; it does not matter where, but   whichever bit it is, all other bits are guaranteed to be zero.  In   other words, the I32-typed expression will be zero if the bit is   zero and nonzero if the bit is 1.  Write into *where the index   of where the bit will be. */staticIRExpr* /* :: Ity_I32 */ getCRbit_anywhere ( UInt bi, Int* where ){   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. */      *where = 0;      return binop(Iop_And32, unop(Iop_8Uto32, getCR0(n)), mkU32(1));   } else {      /* Fetch the <, > or == bit for this CR field */      *where = 3-off;      return binop( Iop_And32,                     unop(Iop_8Uto32, getCR321(n)),                    mkU32(1 << (3-off)) );   }}/* Set the CR0 flags following an arithmetic operation.   (Condition Register CR0 Field Definition, PPC32 p60)*/static IRExpr* getXER_SO ( void );static void set_CR0 ( IRExpr* result ){   vassert(typeOfIRExpr(irbb->tyenv,result) == Ity_I32 ||           typeOfIRExpr(irbb->tyenv,result) == Ity_I64);   if (mode64) {      putCR321( 0, unop(Iop_64to8,                        binop(Iop_CmpORD64S, result, mkU64(0))) );   } else {      putCR321( 0, unop(Iop_32to8,                        binop(Iop_CmpORD32S, result, mkU32(0))) );   }   putCR0( 0, getXER_SO() );}/* Set the CR6 flags following an AltiVec compare operation. */static void set_AV_CR6 ( IRExpr* result, Bool test_all_ones ){   /* CR6[0:3] = {all_ones, 0, all_zeros, 0}      all_ones  = (v[0] && v[1] && v[2] && v[3])      all_zeros = ~(v[0] || v[1] || v[2] || v[3])   */   IRTemp v0 = newTemp(Ity_V128);   IRTemp v1 = newTemp(Ity_V128);   IRTemp v2 = newTemp(Ity_V128);   IRTemp v3 = newTemp(Ity_V128);   IRTemp rOnes  = newTemp(Ity_I8);   IRTemp rZeros = newTemp(Ity_I8);   vassert(typeOfIRExpr(irbb->tyenv,result) == Ity_V128);   assign( v0, result );   assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );   assign( v2, binop(Iop_ShrV128, result, mkU8(64)) );   assign( v3, binop(Iop_ShrV128, result, mkU8(96)) );   assign( rZeros, unop(Iop_1Uto8,       binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),             unop(Iop_Not32,                  unop(Iop_V128to32,                       binop(Iop_OrV128,                             binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)),                             binop(Iop_OrV128, mkexpr(v2), mkexpr(v3))))                  ))) );   if (test_all_ones) {      assign( rOnes, unop(Iop_1Uto8,         binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),               unop(Iop_V128to32,                    binop(Iop_AndV128,                          binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)),                          binop(Iop_AndV128, mkexpr(v2), mkexpr(v3)))                    ))) );      putCR321( 6, binop(Iop_Or8,                         binop(Iop_Shl8, mkexpr(rOnes),  mkU8(3)),                         binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) );   } else {      putCR321( 6, binop(Iop_Shl8, mkexpr(rZeros), mkU8(1)) );   }   putCR0( 6, mkU8(0) );} /*------------------------------------------------------------*//*--- Helpers for XER flags.                               ---*//*------------------------------------------------------------*/static void putXER_SO ( IRExpr* e ){   IRExpr* so;   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);   so = binop(Iop_And8, e, mkU8(1));   stmt( IRStmt_Put( OFFB_XER_SO, so ) );}static void putXER_OV ( IRExpr* e ){   IRExpr* ov;   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);   ov = binop(Iop_And8, e, mkU8(1));   stmt( IRStmt_Put( OFFB_XER_OV, ov ) );}static void putXER_CA ( IRExpr* e ){   IRExpr* ca;   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);   ca = binop(Iop_And8, e, mkU8(1));   stmt( IRStmt_Put( OFFB_XER_CA, ca ) );}static void putXER_BC ( IRExpr* e ){   IRExpr* bc;   vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_I8);   bc = binop(Iop_And8, e, mkU8(0x7F));   stmt( IRStmt_Put( OFFB_XER_BC, bc ) );}static IRExpr* /* :: Ity_I8 */ getXER_SO ( void ){   return IRExpr_Get( OFFB_XER_SO, Ity_I8 );}static IRExpr* /* :: Ity_I32 */ getXER_SO32 ( void ){   return binop( Iop_And32, unop(Iop_8Uto32, getXER_SO()), mkU32(1) );}static IRExpr* /* :: Ity_I8 */ getXER_OV ( void ){   return IRExpr_Get( OFFB_XER_OV, Ity_I8 );}static IRExpr* /* :: Ity_I32 */ getXER_OV32 ( void ){   return binop( Iop_And32, unop(Iop_8Uto32, getXER_OV()), mkU32(1) );}static IRExpr* /* :: Ity_I32 */ getXER_CA32 ( void ){   IRExpr* ca = IRExpr_Get( OFFB_XER_CA, Ity_I8 );   return binop( Iop_And32, unop(Iop_8Uto32, ca ), mkU32(1) );}static IRExpr* /* :: Ity_I8 */ getXER_BC ( void ){   return IRExpr_Get( OFFB_XER_BC, Ity_I8 );}static IRExpr* /* :: Ity_I32 */ getXER_BC32 ( void ){   IRExpr* bc = IRExpr_Get( OFFB_XER_BC, Ity_I8 );   return binop( Iop_And32, unop(Iop_8Uto32, bc), mkU32(0x7F) );}/* RES is the result of doing OP on ARGL and ARGR.  Set %XER.OV and   %XER.SO accordingly. */static void set_XER_OV_32( UInt op, IRExpr* res,                           IRExpr* argL, IRExpr* argR ){   IRTemp  t64;   IRExpr* xer_ov;   vassert(op < PPCG_FLAG_OP_NUMBER);   vassert(typeOfIRExpr(irbb->tyenv,res)  == Ity_I32);   vassert(typeOfIRExpr(irbb->tyenv,argL) == Ity_I32);   vassert(typeOfIRExpr(irbb->tyenv,argR) == Ity_I32);#  define INT32_MIN 0x80000000#  define XOR2(_aa,_bb) \      binop(Iop_Xor32,(_aa),(_bb))#  define XOR3(_cc,_dd,_ee) \      binop(Iop_Xor32,binop(Iop_Xor32,(_cc),(_dd)),(_ee))#  define AND3(_ff,_gg,_hh) \      binop(Iop_And32,binop(Iop_And32,(_ff),(_gg)),(_hh))#define NOT(_jj) \      unop(Iop_Not32, (_jj))   switch (op) {   case /* 0  */ PPCG_FLAG_OP_ADD:   case /* 1  */ PPCG_FLAG_OP_ADDE:      /* (argL^argR^-1) & (argL^res) & (1<<31)  ?1:0 */      // i.e. ((both_same_sign) & (sign_changed) & (sign_mask))      xer_ov          = AND3( XOR3(argL,argR,mkU32(-1)),                 XOR2(argL,res),                 mkU32(INT32_MIN) );      /* xer_ov can only be 0 or 1<<31 */      xer_ov          = binop(Iop_Shr32, xer_ov, mkU8(31) );      break;         case /* 2  */ PPCG_FLAG_OP_DIVW:      /* (argL == INT32_MIN && argR == -1) || argR == 0 */      xer_ov         = mkOR1(              mkAND1(                  binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)),                 binop(Iop_CmpEQ32, argR, mkU32(-1))               ),              binop(Iop_CmpEQ32, argR, mkU32(0) )            );      xer_ov          = unop(Iop_1Uto32, xer_ov);      break;         case /* 3  */ PPCG_FLAG_OP_DIVWU:      /* argR == 0 */      xer_ov          = unop(Iop_1Uto32, binop(Iop_CmpEQ32, argR, mkU32(0)));      break;         case /* 4  */ PPCG_FLAG_OP_MULLW:      /* OV true if result can't be represented in 32 bits         i.e sHi != sign extension of sLo */      t64 = newTemp(Ity_I64);      assign( t64, binop(Iop_MullS32, argL, argR) );      xer_ov          = binop( Iop_CmpNE32,                  unop(Iop_64HIto32, mkexpr(t64)),                  binop( Iop_Sar32,                          unop(Iop_64to32, mkexpr(t64)),                          mkU8(31))                  );      xer_ov         = unop(Iop_1Uto32, xer_ov);      break;         case /* 5  */ PPCG_FLAG_OP_NEG:      /* argL == INT32_MIN */      xer_ov         = unop( Iop_1Uto32,                  binop(Iop_CmpEQ32, argL, mkU32(INT32_MIN)) );      break;         case /* 6  */ PPCG_FLAG_OP_SUBF:   case /* 7  */ PPCG_FLAG_OP_SUBFC:   case /* 8  */ PPCG_FLAG_OP_SUBFE:      /* ((~argL)^argR^-1) & ((~argL)^res) & (1<<31) ?1:0; */      xer_ov          = AND3( XOR3(NOT(argL),argR,mkU32(-1)),                 XOR2(NOT(argL),res),                 mkU32(INT32_MIN) );      /* xer_ov can only be 0 or 1<<31 */      xer_ov          = binop(Iop_Shr32, xer_ov, mkU8(31) );      break;         default:       vex_printf("set_XER_OV: op = %u\n", op);      vpanic("set_XER_OV(ppc)");   }   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -