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

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
   /* xer_ov MUST denote either 0 or 1, no other value allowed */   putXER_OV( unop(Iop_32to8, xer_ov) );   /* Update the summary overflow */   putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) );#  undef INT32_MIN#  undef AND3#  undef XOR3#  undef XOR2#  undef NOT}static void set_XER_OV_64( UInt op, IRExpr* res,                           IRExpr* argL, IRExpr* argR ){   IRExpr* xer_ov;   vassert(op < PPCG_FLAG_OP_NUMBER);   vassert(typeOfIRExpr(irbb->tyenv,res)  == Ity_I64);   vassert(typeOfIRExpr(irbb->tyenv,argL) == Ity_I64);   vassert(typeOfIRExpr(irbb->tyenv,argR) == Ity_I64);#  define INT64_MIN 0x8000000000000000ULL#  define XOR2(_aa,_bb) \      binop(Iop_Xor64,(_aa),(_bb))#  define XOR3(_cc,_dd,_ee) \      binop(Iop_Xor64,binop(Iop_Xor64,(_cc),(_dd)),(_ee))#  define AND3(_ff,_gg,_hh) \      binop(Iop_And64,binop(Iop_And64,(_ff),(_gg)),(_hh))#define NOT(_jj) \      unop(Iop_Not64, (_jj))   switch (op) {   case /* 0  */ PPCG_FLAG_OP_ADD:   case /* 1  */ PPCG_FLAG_OP_ADDE:      /* (argL^argR^-1) & (argL^res) & (1<<63)  ? 1:0 */      // i.e. ((both_same_sign) & (sign_changed) & (sign_mask))      xer_ov          = AND3( XOR3(argL,argR,mkU64(-1)),                 XOR2(argL,res),                 mkU64(INT64_MIN) );      /* xer_ov can only be 0 or 1<<63 */      xer_ov          = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63)));      break;         case /* 2  */ PPCG_FLAG_OP_DIVW:      /* (argL == INT64_MIN && argR == -1) || argR == 0 */      xer_ov         = mkOR1(              mkAND1(                  binop(Iop_CmpEQ64, argL, mkU64(INT64_MIN)),                 binop(Iop_CmpEQ64, argR, mkU64(-1))               ),              binop(Iop_CmpEQ64, argR, mkU64(0) )            );      break;   case /* 3  */ PPCG_FLAG_OP_DIVWU:      /* argR == 0 */      xer_ov          = binop(Iop_CmpEQ64, argR, mkU64(0));      break;         case /* 4  */ PPCG_FLAG_OP_MULLW: {      /* OV true if result can't be represented in 64 bits         i.e sHi != sign extension of sLo */      xer_ov          = binop( Iop_CmpNE32,                  unop(Iop_64HIto32, res),                  binop( Iop_Sar32,                          unop(Iop_64to32, res),                          mkU8(31))                  );      break;   }         case /* 5  */ PPCG_FLAG_OP_NEG:      /* argL == INT64_MIN */      xer_ov         = binop(Iop_CmpEQ64, argL, mkU64(INT64_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<<63) ?1:0; */      xer_ov          = AND3( XOR3(NOT(argL),argR,mkU64(-1)),                 XOR2(NOT(argL),res),                 mkU64(INT64_MIN) );      /* xer_ov can only be 0 or 1<<63 */      xer_ov          = unop(Iop_64to1, binop(Iop_Shr64, xer_ov, mkU8(63)));      break;         default:       vex_printf("set_XER_OV: op = %u\n", op);      vpanic("set_XER_OV(ppc64)");   }      /* xer_ov MUST denote either 0 or 1, no other value allowed */   putXER_OV( unop(Iop_1Uto8, xer_ov) );   /* Update the summary overflow */   putXER_SO( binop(Iop_Or8, getXER_SO(), getXER_OV()) );#  undef INT64_MIN#  undef AND3#  undef XOR3#  undef XOR2#  undef NOT}static void set_XER_OV ( IRType ty, UInt op, IRExpr* res,                         IRExpr* argL, IRExpr* argR ){   if (ty == Ity_I32)      set_XER_OV_32( op, res, argL, argR );   else      set_XER_OV_64( op, res, argL, argR );}/* RES is the result of doing OP on ARGL and ARGR with the old %XER.CA   value being OLDCA.  Set %XER.CA accordingly. */static void set_XER_CA_32 ( UInt op, IRExpr* res,                            IRExpr* argL, IRExpr* argR, IRExpr* oldca ){   IRExpr* xer_ca;   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);   vassert(typeOfIRExpr(irbb->tyenv,oldca) == Ity_I32);   /* Incoming oldca is assumed to hold the values 0 or 1 only.  This      seems reasonable given that it's always generated by      getXER_CA32(), which masks it accordingly.  In any case it being      0 or 1 is an invariant of the ppc guest state representation;      if it has any other value, that invariant has been violated. */   switch (op) {   case /* 0 */ PPCG_FLAG_OP_ADD:      /* res <u argL */      xer_ca         = unop(Iop_1Uto32, binop(Iop_CmpLT32U, res, argL));      break;         case /* 1 */ PPCG_FLAG_OP_ADDE:      /* res <u argL || (old_ca==1 && res==argL) */      xer_ca          = mkOR1(               binop(Iop_CmpLT32U, res, argL),              mkAND1(                  binop(Iop_CmpEQ32, oldca, mkU32(1)),                 binop(Iop_CmpEQ32, res, argL)               )            );      xer_ca          = unop(Iop_1Uto32, xer_ca);      break;         case /* 8 */ PPCG_FLAG_OP_SUBFE:      /* res <u argR || (old_ca==1 && res==argR) */      xer_ca          = mkOR1(               binop(Iop_CmpLT32U, res, argR),              mkAND1(                  binop(Iop_CmpEQ32, oldca, mkU32(1)),                 binop(Iop_CmpEQ32, res, argR)               )            );      xer_ca          = unop(Iop_1Uto32, xer_ca);      break;         case /* 7 */ PPCG_FLAG_OP_SUBFC:   case /* 9 */ PPCG_FLAG_OP_SUBFI:      /* res <=u argR */      xer_ca         = unop(Iop_1Uto32, binop(Iop_CmpLE32U, res, argR));      break;         case /* 10 */ PPCG_FLAG_OP_SRAW:      /* The shift amount is guaranteed to be in 0 .. 63 inclusive.         If it is <= 31, behave like SRAWI; else XER.CA is the sign         bit of argL. */      /* This term valid for shift amount < 32 only */      xer_ca         = binop(              Iop_And32,              binop(Iop_Sar32, argL, mkU8(31)),              binop( Iop_And32,                     argL,                     binop( Iop_Sub32,                            binop(Iop_Shl32, mkU32(1),                                             unop(Iop_32to8,argR)),                            mkU32(1) )                     )              );      xer_ca          = IRExpr_Mux0X(              /* shift amt > 31 ? */              unop(Iop_1Uto8, binop(Iop_CmpLT32U, mkU32(31), argR)),              /* no -- be like srawi */              unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))),              /* yes -- get sign bit of argL */              binop(Iop_Shr32, argL, mkU8(31))           );      break;   case /* 11 */ PPCG_FLAG_OP_SRAWI:      /* xer_ca is 1 iff src was negative and bits_shifted_out !=          0.  Since the shift amount is known to be in the range         0 .. 31 inclusive the following seems viable:         xer.ca == 1 iff the following is nonzero:         (argL >>s 31)           -- either all 0s or all 1s         & (argL & (1<<argR)-1)  -- the stuff shifted out */      xer_ca         = binop(              Iop_And32,              binop(Iop_Sar32, argL, mkU8(31)),              binop( Iop_And32,                     argL,                     binop( Iop_Sub32,                            binop(Iop_Shl32, mkU32(1),                                             unop(Iop_32to8,argR)),                            mkU32(1) )                     )              );      xer_ca          = unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0)));      break;         default:       vex_printf("set_XER_CA: op = %u\n", op);      vpanic("set_XER_CA(ppc)");   }   /* xer_ca MUST denote either 0 or 1, no other value allowed */   putXER_CA( unop(Iop_32to8, xer_ca) );}static void set_XER_CA_64 ( UInt op, IRExpr* res,                            IRExpr* argL, IRExpr* argR, IRExpr* oldca ){   IRExpr* xer_ca;   vassert(op < PPCG_FLAG_OP_NUMBER);   vassert(typeOfIRExpr(irbb->tyenv,res)   == Ity_I64);   vassert(typeOfIRExpr(irbb->tyenv,argL)  == Ity_I64);   vassert(typeOfIRExpr(irbb->tyenv,argR)  == Ity_I64);   vassert(typeOfIRExpr(irbb->tyenv,oldca) == Ity_I64);   /* Incoming oldca is assumed to hold the values 0 or 1 only.  This      seems reasonable given that it's always generated by      getXER_CA32(), which masks it accordingly.  In any case it being      0 or 1 is an invariant of the ppc guest state representation;      if it has any other value, that invariant has been violated. */   switch (op) {   case /* 0 */ PPCG_FLAG_OP_ADD:      /* res <u argL */      xer_ca         = unop(Iop_1Uto32, binop(Iop_CmpLT64U, res, argL));      break;         case /* 1 */ PPCG_FLAG_OP_ADDE:      /* res <u argL || (old_ca==1 && res==argL) */      xer_ca          = mkOR1(               binop(Iop_CmpLT64U, res, argL),              mkAND1(                  binop(Iop_CmpEQ64, oldca, mkU64(1)),                 binop(Iop_CmpEQ64, res, argL)                  )               );      xer_ca          = unop(Iop_1Uto32, xer_ca);      break;         case /* 8 */ PPCG_FLAG_OP_SUBFE:      /* res <u argR || (old_ca==1 && res==argR) */      xer_ca          = mkOR1(               binop(Iop_CmpLT64U, res, argR),              mkAND1(                  binop(Iop_CmpEQ64, oldca, mkU64(1)),                 binop(Iop_CmpEQ64, res, argR)               )            );      xer_ca          = unop(Iop_1Uto32, xer_ca);      break;         case /* 7 */ PPCG_FLAG_OP_SUBFC:   case /* 9 */ PPCG_FLAG_OP_SUBFI:      /* res <=u argR */      xer_ca         = unop(Iop_1Uto32, binop(Iop_CmpLE64U, res, argR));      break;               case /* 10 */ PPCG_FLAG_OP_SRAW:      /* The shift amount is guaranteed to be in 0 .. 31 inclusive.         If it is <= 31, behave like SRAWI; else XER.CA is the sign         bit of argL. */         /* This term valid for shift amount < 31 only */      xer_ca         = binop(              Iop_And64,              binop(Iop_Sar64, argL, mkU8(31)),              binop( Iop_And64,                     argL,                     binop( Iop_Sub64,                            binop(Iop_Shl64, mkU64(1),                                             unop(Iop_64to8,argR)),                            mkU64(1) )              )           );      xer_ca          = IRExpr_Mux0X(              /* shift amt > 31 ? */              unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(31), argR)),              /* no -- be like srawi */              unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))),              /* yes -- get sign bit of argL */              unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63)))           );      break;         case /* 11 */ PPCG_FLAG_OP_SRAWI:      /* xer_ca is 1 iff src was negative and bits_shifted_out != 0.         Since the shift amount is known to be in the range 0 .. 31         inclusive the following seems viable:         xer.ca == 1 iff the following is nonzero:         (argL >>s 31)           -- either all 0s or all 1s         & (argL & (1<<argR)-1)  -- the stuff shifted out */      xer_ca         = binop(              Iop_And64,              binop(Iop_Sar64, argL, mkU8(31)),              binop( Iop_And64,                     argL,                     binop( Iop_Sub64,                            binop(Iop_Shl64, mkU64(1),                                             unop(Iop_64to8,argR)),                            mkU64(1) )              )           );      xer_ca          = unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0)));      break;         case /* 12 */ PPCG_FLAG_OP_SRAD:      /* The shift amount is guaranteed to be in 0 .. 63 inclusive.         If it is <= 63, behave like SRADI; else XER.CA is the sign         bit of argL. */         /* This term valid for shift amount < 63 only */      xer_ca         = binop(              Iop_And64,              binop(Iop_Sar64, argL, mkU8(63)),              binop( Iop_And64,                     argL,                     binop( Iop_Sub64,                            binop(Iop_Shl64, mkU64(1),                                             unop(Iop_64to8,argR)),                            mkU64(1) )              )           );      xer_ca          = IRExpr_Mux0X(              /* shift amt > 63 ? */              unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(63), argR)),              /* no -- be like sradi */              unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))),              /* yes -- get sign bit of argL */              unop(Iop_64to32, binop(Iop_Shr64, argL, mkU8(63)))           );      break;   case /* 13 */ PPCG_FLAG_OP_SRADI:      /* xer_ca is 1 iff src was negative and bits_shifted_out != 0.         Since the shift amount is known to be in the range 0 .. 63         inclusive, the following seems viable:         xer.ca == 1 iff the following is nonzero:         (argL >>s 63)           -- either all 0s or all 

⌨️ 快捷键说明

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