public static Int32Value Add(Int32Value a, Int32Value b) { if (a.allBitsValid() && b.allBitsValid()) return new Int32Value(a.value + b.value); if (ReferenceEquals(a, b)) return new Int32Value(a.value << 1, (a.validMask << 1) | 1); return createUnknown(); }
bool IBranchHandler.HandleSwitch(Int32Value switchIndex) { var target = CflowUtils.GetSwitchTarget(block.Targets, block.FallThrough, switchIndex); if (target == null) return false; PopPushedArgs(1); block.ReplaceSwitchWithBranch(target); return true; }
public static Block GetSwitchTarget(IList<Block> targets, Block fallThrough, Int32Value intValue) { if (!intValue.AllBitsValid()) return null; int index = intValue.Value; if (targets == null || index < 0 || index >= targets.Count) return fallThrough; else return targets[index]; }
public static Int32Value Add_Ovf(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { return new Int32Value(checked(a.Value + b.Value)); } catch (OverflowException) { } } return CreateUnknown(); }
bool IBranchHandler.HandleSwitch(Int32Value switchIndex) { if (!switchIndex.AllBitsValid()) return false; var instr = instructions[emulateIndex]; var targets = (Instruction[])instr.Operand; if (switchIndex.Value >= 0 && switchIndex.Value < targets.Length) emulateIndex = instructions.IndexOf(targets[switchIndex.Value]); else emulateIndex++; return true; }
public static Int32Value Add_Ovf_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { uint aa = (uint)a.Value, bb = (uint)b.Value; try { return new Int32Value((int)checked(aa + bb)); } catch (OverflowException) { } } return CreateUnknown(); }
public static Int32Value Mul(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return new Int32Value(a.Value * b.Value); if (a.IsZero() || b.IsZero()) return Zero; if (a.HasValue(1)) return b; if (b.HasValue(1)) return a; return CreateUnknown(); }
public static Int32Value Conv_Ovf_U4_Un(Int32Value a) { return(a); }
public static Bool3 CompareGe(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return a.Value >= b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MaxValue)) return Bool3.True; // max >= x => true if (b.HasValue(int.MinValue)) return Bool3.True; // x >= min => true return Bool3.Unknown; }
public static Int32Value Clt(Int64Value a, Int64Value b) => Int32Value.Create(CompareLt(a, b));
public static Int32Value Not(Int32Value a) { return new Int32Value(~a.Value, a.ValidMask); }
public static Int32Value Cgt(Int32Value a, Int32Value b) { return Create(CompareGt(a, b)); }
public static Int32Value Conv_Ovf_I2(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || !a.CheckSign(NO_UNKNOWN_BITS << 15)) return CreateUnknown(); return Conv_I2(a); }
public static Int32Value Conv_Ovf_I4(Int32Value a) => a;
public static Int32Value Clt(Int32Value a, Int32Value b) { return(Create(CompareLt(a, b))); }
public static Int32Value Conv_U4(Int32Value a) => a;
public static Int32Value Cgt_Un(Int32Value a, Int32Value b) { return(Create(CompareGt_Un(a, b))); }
public static Int32Value Ceq(Int32Value a, Int32Value b) { return(Create(CompareEq(a, b))); }
public static Int32Value Not(Int32Value a) { return(new Int32Value(~a.Value, a.ValidMask)); }
public static Int32Value Rem_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { return new Int32Value((int)((uint)a.Value % (uint)b.Value)); } catch (ArithmeticException) { return CreateUnknown(); } } if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1)) return Zero; return CreateUnknown(); }
public static Int64Value Conv_Ovf_I8(Int32Value a) { ulong validMask = a.ValidMask; if (IsBitValid(a.ValidMask, 31)) validMask |= Int64Value.NO_UNKNOWN_BITS << 32; return new Int64Value(a.Value, validMask); }
public static Int32Value Or(Int32Value a, Int32Value b) { int av = a.Value, bv = b.Value; uint am = a.ValidMask, bm = b.ValidMask; return new Int32Value(av | bv, (am & bm) | ((uint)av & am) | ((uint)bv & bm)); }
public static Int32Value Conv_Ovf_U1_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 8) || (uint)a.Value > byte.MaxValue) return CreateUnknownUInt8(); return Conv_U1(a); }
public static Int32Value Shr_Un(Int32Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); if (b.Value == 0) return a; if (b.Value < 0 || b.Value >= sizeof(int) * 8) return CreateUnknown(); int shift = b.Value; uint validMask = (a.ValidMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift)); return new Int32Value((int)((uint)a.Value >> shift), validMask); }
public static Int32Value Conv_I2(Int32Value a) { return(Conv_I2(a.Value, a.ValidMask)); }
public static Bool3 CompareNeq(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return a.Value != b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.False; if (((uint)a.Value & a.ValidMask & b.ValidMask) != ((uint)b.Value & a.ValidMask & b.ValidMask)) return Bool3.True; return Bool3.Unknown; }
public static Int32Value Conv_Ovf_U4(Int32Value a) { if (!IsBitValid(a.ValidMask, 31) || a.Value < 0) return CreateUnknown(); return a; }
public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return (uint)a.Value < (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MaxValue)) return Bool3.False; // max < x => false if (b.HasValue(uint.MinValue)) return Bool3.False; // x < min => false return Bool3.Unknown; }
public static Int64Value Conv_Ovf_U8(Int32Value a) { if (!IsBitValid(a.ValidMask, 31) || a.Value < 0) return Int64Value.CreateUnknown(); return new Int64Value(a.Value, (ulong)a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32)); }
public static Int32Value Ceq(Int64Value a, Int64Value b) => Int32Value.Create(CompareEq(a, b));
public static Real8Value Conv_R8(Int32Value a) { if (a.AllBitsValid()) return new Real8Value((double)(int)a.Value); return Real8Value.CreateUnknown(); }
public static Int32Value Conv_Ovf_U2_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 16) || (uint)a.Value > ushort.MaxValue) return CreateUnknownUInt16(); return Conv_U2(a); }
public static Int32Value Conv_I4(Int32Value a) { return(a); }
public static Int32Value Conv_Ovf_U4_Un(Int32Value a) => a;
public static Int32Value Conv_Ovf_U4_Un(Int32Value a) { return a; }
public static Int64Value Conv_Ovf_U8_Un(Int32Value a) { return new Int64Value((long)(uint)a.Value, a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32)); }
public static Int64Value Conv_Ovf_U8_Un(Int32Value a) => new Int64Value((long)(uint)a.Value, a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32));
public static Int32Value Sub(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return new Int32Value(a.Value - b.Value); if (ReferenceEquals(a, b)) return Zero; return CreateUnknown(); }
public static Int32Value Div(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { return new Int32Value(a.Value / b.Value); } catch (ArithmeticException) { return CreateUnknown(); } } if (ReferenceEquals(a, b) && a.IsNonZero()) return One; if (b.HasValue(1)) return a; return CreateUnknown(); }
public static Int32Value Neg(Int32Value a) { if (a.AllBitsValid()) return new Int32Value(-a.Value); return CreateUnknown(); }
public static Int32Value Xor(Int32Value a, Int32Value b) { if (ReferenceEquals(a, b)) return Zero; int av = a.Value, bv = b.Value; uint am = a.ValidMask, bm = b.ValidMask; return new Int32Value(av ^ bv, am & bm); }
public static Int32Value Not(Int32Value a) => new Int32Value(~a.Value, a.ValidMask);
public static Int32Value Shr(Int32Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); if (b.Value == 0) return a; if (b.Value < 0 || b.Value >= sizeof(int) * 8) return CreateUnknown(); int shift = b.Value; uint validMask = a.ValidMask >> shift; if (a.IsBitValid(sizeof(int) * 8 - 1)) validMask |= (uint.MaxValue << (sizeof(int) * 8 - shift)); return new Int32Value(a.Value >> shift, validMask); }
public static Int32Value Cgt(Int32Value a, Int32Value b) => Create(CompareGt(a, b));
public static Int32Value Ceq(Int32Value a, Int32Value b) { return Create(CompareEq(a, b)); }
public static Int32Value Clt_Un(Int32Value a, Int32Value b) => Create(CompareLt_Un(a, b));
public static Int32Value Clt_Un(Int32Value a, Int32Value b) { return Create(CompareLt_Un(a, b)); }
public static Int32Value Conv_I1(Int32Value a) => Conv_I1(a.Value, a.ValidMask);
public static Bool3 CompareGt(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return a.Value > b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MinValue)) return Bool3.False; // min > x => false if (b.HasValue(int.MaxValue)) return Bool3.False; // x > max => false return Bool3.Unknown; }
public static Int32Value Cgt(Int64Value a, Int64Value b) { return(Int32Value.Create(CompareGt(a, b))); }
public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return (uint)a.Value <= (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MinValue)) return Bool3.True; // min <= x => true if (b.HasValue(uint.MaxValue)) return Bool3.True; // x <= max => true return Bool3.Unknown; }
public static Int32Value Clt_Un(Int64Value a, Int64Value b) { return(Int32Value.Create(CompareLt_Un(a, b))); }
public static Bool3 CompareFalse(Int32Value a) { if (a.AllBitsValid()) return a.Value == 0 ? Bool3.True : Bool3.False; if (((uint)a.Value & a.ValidMask) != 0) return Bool3.False; return Bool3.Unknown; }
public static Int32Value Cgt_Un(Int64Value a, Int64Value b) => Int32Value.Create(CompareGt_Un(a, b));