iropt.c

来自「The Valgrind distribution has multiple t」· C语言 代码 · 共 1,868 行 · 第 1/5 页

C
1,868
字号
            case Iop_Xor64:               e2 = IRExpr_Const(IRConst_U64(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));               break;            /* -- And -- */            case Iop_And8:               e2 = IRExpr_Const(IRConst_U8(toUChar(                        (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8                        & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))));               break;            case Iop_And32:               e2 = IRExpr_Const(IRConst_U32(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        & e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));               break;            case Iop_And64:               e2 = IRExpr_Const(IRConst_U64(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        & e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));               break;            /* -- Add -- */            case Iop_Add8:               e2 = IRExpr_Const(IRConst_U8(toUChar(                        (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8                        + e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))));               break;            case Iop_Add32:               e2 = IRExpr_Const(IRConst_U32(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        + e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));               break;            case Iop_Add64:               e2 = IRExpr_Const(IRConst_U64(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        + e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));               break;            /* -- Sub -- */            case Iop_Sub8:               e2 = IRExpr_Const(IRConst_U8(toUChar(                        (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8                        - e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))));               break;            case Iop_Sub32:               e2 = IRExpr_Const(IRConst_U32(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        - e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));               break;            case Iop_Sub64:               e2 = IRExpr_Const(IRConst_U64(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        - e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));               break;            /* -- Mul -- */            case Iop_Mul32:               e2 = IRExpr_Const(IRConst_U32(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        * e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));               break;            case Iop_Mul64:               e2 = IRExpr_Const(IRConst_U64(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        * e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)));               break;            case Iop_MullS32: {               /* very paranoid */               UInt  u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;               UInt  u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;               Int   s32a = (Int)u32a;               Int   s32b = (Int)u32b;               Long  s64a = (Long)s32a;               Long  s64b = (Long)s32b;               Long  sres = s64a * s64b;               ULong ures = (ULong)sres;               e2 = IRExpr_Const(IRConst_U64(ures));               break;            }            /* -- Shl -- */            case Iop_Shl32:               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 31)                  e2 = IRExpr_Const(IRConst_U32(                          (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                           << shift)));               break;            case Iop_Shl64:               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 63)                  e2 = IRExpr_Const(IRConst_U64(                          (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                           << shift)));               break;            /* -- Sar -- */            case Iop_Sar32: {               /* paranoid ... */               /*signed*/ Int s32;               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               s32   = (Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 31) {                  s32 >>=/*signed*/ shift;                  e2 = IRExpr_Const(IRConst_U32((UInt)s32));               }               break;            }            case Iop_Sar64: {               /* paranoid ... */               /*signed*/ Long s64;               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               s64   = (Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 63) {                  s64 >>=/*signed*/ shift;                  e2 = IRExpr_Const(IRConst_U64((ULong)s64));               }               break;            }            /* -- Shr -- */            case Iop_Shr32: {               /* paranoid ... */               /*unsigned*/ UInt u32;               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               u32   = (UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 31) {                  u32 >>=/*unsigned*/ shift;                  e2 = IRExpr_Const(IRConst_U32(u32));               }               break;            }            case Iop_Shr64: {               /* paranoid ... */               /*unsigned*/ ULong u64;               vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);               u64   = (ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64);               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8);               if (shift >= 0 && shift <= 63) {                  u64 >>=/*unsigned*/ shift;                  e2 = IRExpr_Const(IRConst_U64(u64));               }               break;            }            /* -- CmpEQ -- */            case Iop_CmpEQ32:               e2 = IRExpr_Const(IRConst_U1(toBool(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        == e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))));               break;            case Iop_CmpEQ64:               e2 = IRExpr_Const(IRConst_U1(toBool(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        == e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))));               break;            /* -- CmpNE -- */            case Iop_CmpNE8:               e2 = IRExpr_Const(IRConst_U1(toBool(                       ((0xFF & e->Iex.Binop.arg1->Iex.Const.con->Ico.U8)                        != (0xFF & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))));               break;            case Iop_CmpNE32:               e2 = IRExpr_Const(IRConst_U1(toBool(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32                        != e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))));               break;            case Iop_CmpNE64:               e2 = IRExpr_Const(IRConst_U1(toBool(                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64                        != e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))));               break;            /* -- CmpLEU -- */            case Iop_CmpLE32U:               e2 = IRExpr_Const(IRConst_U1(toBool(                       ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)                        <= (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))));               break;            /* -- CmpLES -- */            case Iop_CmpLE32S:               e2 = IRExpr_Const(IRConst_U1(toBool(                       ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)                        <= (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))));               break;            /* -- CmpLTS -- */            case Iop_CmpLT32S:               e2 = IRExpr_Const(IRConst_U1(toBool(                       ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)                        < (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))));               break;            /* -- CmpLTU -- */            case Iop_CmpLT32U:               e2 = IRExpr_Const(IRConst_U1(toBool(                       ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)                        < (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))));               break;            /* -- CmpORD -- */            case Iop_CmpORD32S: {               /* very paranoid */               UInt  u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;               UInt  u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;               Int   s32a = (Int)u32a;               Int   s32b = (Int)u32b;               Int   r = 0x2; /* EQ */               if (s32a < s32b) {                  r = 0x8; /* LT */               }                else if (s32a > s32b) {                  r = 0x4; /* GT */               }               e2 = IRExpr_Const(IRConst_U32(r));               break;            }            /* -- nHLto2n -- */            case Iop_32HLto64:               e2 = IRExpr_Const(IRConst_U64(                       (((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32)) << 32)                       | ((ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))                     ));               break;            case Iop_64HLto128:               /* We can't fold this, because there is no way to                  express he result in IR, but at least pretend to                  handle it, so as to stop getting blasted with                  no-rule-for-this-primop messages. */               break;            default:               goto unhandled;         }      } else {         /* other cases (identities, etc) */         /* Shl64/Shr64(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Shl64 || e->Iex.Binop.op == Iop_Shr64)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U8 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* Shl32/Shr32(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Shl32 || e->Iex.Binop.op == Iop_Shr32)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U8 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* Or8(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Or8)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U8 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* Or16(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Or16)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U16 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* Or32/Add32(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Add32 || e->Iex.Binop.op == Iop_Or32)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* Add32(t,t) ==> t << 1.  Memcheck doesn't understand that            x+x produces a defined least significant bit, and it seems            simplest just to get rid of the problem by rewriting it            out, since the opportunity to do so exists. */         if (e->Iex.Binop.op == Iop_Add32             && e->Iex.Binop.arg1->tag == Iex_Tmp             && e->Iex.Binop.arg2->tag == Iex_Tmp             && e->Iex.Binop.arg1->Iex.Tmp.tmp                 == e->Iex.Binop.arg2->Iex.Tmp.tmp) {            e2 = IRExpr_Binop(Iop_Shl32,                              e->Iex.Binop.arg1,                              IRExpr_Const(IRConst_U8(1)));         } else         /* Add64(t,t) ==> t << 1;  rationale as for Add32(t,t) above. */         if (e->Iex.Binop.op == Iop_Add64             && e->Iex.Binop.arg1->tag == Iex_Tmp             && e->Iex.Binop.arg2->tag == Iex_Tmp             && e->Iex.Binop.arg1->Iex.Tmp.tmp                 == e->Iex.Binop.arg2->Iex.Tmp.tmp) {            e2 = IRExpr_Binop(Iop_Shl64,                              e->Iex.Binop.arg1,                              IRExpr_Const(IRConst_U8(1)));         } else         /* Or64/Add64(x,0) ==> x */         if ((e->Iex.Binop.op == Iop_Add64 || e->Iex.Binop.op == Iop_Or64)             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U64 == 0) {            e2 = e->Iex.Binop.arg1;         } else         /* And32(x,0xFFFFFFFF) ==> x */         if (e->Iex.Binop.op == Iop_And32             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 == 0xFFFFFFFF) {            e2 = e->Iex.Binop.arg1;         } else         /* And32(x,0) ==> 0 */         if (e->Iex.Binop.op == Iop_And32             && e->Iex.Binop.arg2->tag == Iex_Const             && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 == 0) {            e2 = IRExpr_Const(IRConst_U32(0));         } else         /* And32(0,x) ==> 0 */         if (e->Iex.Binop.op == Iop_And32             && e->Iex.Binop.arg1->tag == Iex_Const             && e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 == 0) {            e2 = IRExpr_Const(IRConst_U32(0));         } else         /* Or32(0,x) ==> x */         if (e->Iex.Binop.op == Iop_Or32             && e->Iex.Binop.arg1->tag == Iex_Const             && e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 == 0) {            e2 = e->Iex.Binop.arg2;         } else         /* Or64(0,x) ==> x */         if (e->Iex.Binop.op == Iop_Or64             && e->Iex.Binop.arg1->tag == Iex_Const             && e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 == 0) {            e2 = e->Iex.Binop.arg2;         } else         /* Or8/16/32/64(t,t) ==> t, for some IRTemp t */         /* And8/16/32/64(t,t) ==> t, for some IRTemp t */         if (   (e->Iex.Binop.op == Iop_And64              || e->Iex.Binop.op == Iop_And32              || e->Iex.Binop.op == Iop_And16              || e->Iex.Binop.op == Iop_And8              || e->Iex.Binop.op == Iop_Or64              || e->Iex.Binop.op == Iop_Or32              || e->Iex.Binop.op == Iop_Or16              || e->Iex.Binop.op == Iop_Or8)             && sameIRTemps(e->Iex.Binop.arg1, e->Iex.Binop.arg2)) {            e2 = e->Iex.Binop.arg1;         }         /* Xor8/16/32/64(t,t) ==> 0, for some IRTemp t */         if (   (e->Iex.Binop.op == Iop_Xor64              || e->Iex.Binop.op == Iop_Xor32              || e->Iex.Binop.op == Iop_Xor16              || e->Iex.Binop.op == Iop_Xor8)             && sameIRTemps(e->Iex.Binop.arg1, e->Iex.Binop.arg2)) {            e2 = mkZeroForXor(e->Iex.Binop.op);         }

⌨️ 快捷键说明

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