de4dot-cex/de4dot.blocks/cflow/Int32Value.cs

698 lines
19 KiB
C#
Raw Normal View History

2011-10-17 13:28:53 +08:00
/*
2013-01-02 00:03:16 +08:00
Copyright (C) 2011-2013 de4dot@gmail.com
2011-10-17 13:28:53 +08:00
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace de4dot.blocks.cflow {
2011-10-26 20:17:33 +08:00
public class Int32Value : Value {
2013-10-15 16:12:41 +08:00
public static readonly Int32Value Zero = new Int32Value(0);
public static readonly Int32Value One = new Int32Value(1);
2012-01-27 06:57:37 +08:00
2013-10-15 16:12:41 +08:00
internal const uint NO_UNKNOWN_BITS = uint.MaxValue;
2011-10-17 13:28:53 +08:00
public readonly int value;
public readonly uint validMask;
public Int32Value(int value)
: base(ValueType.Int32) {
this.value = value;
this.validMask = NO_UNKNOWN_BITS;
}
public Int32Value(int value, uint validMask)
: base(ValueType.Int32) {
this.value = value;
this.validMask = validMask;
}
2013-01-19 20:03:57 +08:00
public bool HasUnknownBits() {
2011-10-17 13:28:53 +08:00
return validMask != NO_UNKNOWN_BITS;
}
2013-01-19 20:03:57 +08:00
public bool AllBitsValid() {
return !HasUnknownBits();
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
bool IsBitValid(int n) {
return IsBitValid(validMask, n);
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
static bool IsBitValid(uint validMask, int n) {
2011-10-17 13:28:53 +08:00
return (validMask & (1U << n)) != 0;
}
2013-10-15 16:12:41 +08:00
bool AreBitsValid(uint bitsToTest) {
return (validMask & bitsToTest) == bitsToTest;
}
2013-01-19 20:03:57 +08:00
public static Int32Value CreateUnknownBool() {
2011-10-17 13:28:53 +08:00
return new Int32Value(0, NO_UNKNOWN_BITS << 1);
}
2013-01-19 20:03:57 +08:00
public static Int32Value CreateUnknownUInt8() {
2011-10-17 13:28:53 +08:00
return new Int32Value(0, NO_UNKNOWN_BITS << 8);
}
2013-01-19 20:03:57 +08:00
public static Int32Value CreateUnknownUInt16() {
2011-10-17 13:28:53 +08:00
return new Int32Value(0, NO_UNKNOWN_BITS << 16);
}
2013-01-19 20:03:57 +08:00
public static Int32Value CreateUnknown() {
2011-10-17 13:28:53 +08:00
return new Int32Value(0, 0U);
}
2013-01-19 20:03:57 +08:00
public bool IsZero() {
return HasValue(0);
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
public bool IsNonZero() {
2011-10-18 02:19:17 +08:00
return (value & validMask) != 0;
}
2013-01-19 20:03:57 +08:00
public bool HasValue(int value) {
return AllBitsValid() && this.value == value;
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
public bool HasValue(uint value) {
return HasValue((int)value);
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
public Int32Value ToBoolean() {
if (IsNonZero())
2012-01-22 03:04:13 +08:00
return new Int32Value(1, NO_UNKNOWN_BITS);
2013-01-19 20:03:57 +08:00
if (IsZero())
2012-01-22 03:04:13 +08:00
return this;
2013-01-19 20:03:57 +08:00
return CreateUnknownBool();
}
2013-01-19 20:03:57 +08:00
public Int32Value ToInt8() {
return Conv_I1(this);
}
2013-01-19 20:03:57 +08:00
public Int32Value ToUInt8() {
return Conv_U1(this);
}
2013-01-19 20:03:57 +08:00
public Int32Value ToInt16() {
return Conv_I2(this);
}
2013-01-19 20:03:57 +08:00
public Int32Value ToUInt16() {
return Conv_U2(this);
}
2011-10-17 13:28:53 +08:00
public static Int32Value Conv_U1(Int32Value a) {
return Conv_U1(a.value, a.validMask);
}
public static Int32Value Conv_U1(Int64Value a) {
return Conv_U1((int)a.value, (uint)a.validMask);
}
public static Int32Value Conv_U1(int value, uint validMask) {
value = (int)(byte)value;
validMask |= NO_UNKNOWN_BITS << 8;
return new Int32Value(value, validMask);
}
public static Int32Value Conv_U1(Real8Value a) {
return new Int32Value((int)(byte)a.value);
}
public static Int32Value Conv_I1(Int32Value a) {
return Conv_I1(a.value, a.validMask);
}
public static Int32Value Conv_I1(Int64Value a) {
return Conv_I1((int)a.value, (uint)a.validMask);
}
public static Int32Value Conv_I1(int value, uint validMask) {
value = (int)(sbyte)value;
2013-01-19 20:03:57 +08:00
if (IsBitValid(validMask, 7))
2011-10-17 13:28:53 +08:00
validMask |= NO_UNKNOWN_BITS << 8;
else
validMask &= ~(NO_UNKNOWN_BITS << 8);
return new Int32Value(value, validMask);
}
public static Int32Value Conv_I1(Real8Value a) {
return new Int32Value((int)(sbyte)a.value);
}
public static Int32Value Conv_U2(Int32Value a) {
return Conv_U2(a.value, a.validMask);
}
public static Int32Value Conv_U2(Int64Value a) {
return Conv_U2((int)a.value, (uint)a.validMask);
}
public static Int32Value Conv_U2(int value, uint validMask) {
value = (int)(ushort)value;
validMask |= NO_UNKNOWN_BITS << 16;
return new Int32Value(value, validMask);
}
public static Int32Value Conv_U2(Real8Value a) {
return new Int32Value((int)(ushort)a.value);
}
public static Int32Value Conv_I2(Int32Value a) {
return Conv_I2(a.value, a.validMask);
}
public static Int32Value Conv_I2(Int64Value a) {
return Conv_I2((int)a.value, (uint)a.validMask);
}
public static Int32Value Conv_I2(int value, uint validMask) {
value = (int)(short)value;
2013-01-19 20:03:57 +08:00
if (IsBitValid(validMask, 15))
2011-10-17 13:28:53 +08:00
validMask |= NO_UNKNOWN_BITS << 16;
else
validMask &= ~(NO_UNKNOWN_BITS << 16);
return new Int32Value(value, validMask);
}
public static Int32Value Conv_I2(Real8Value a) {
return new Int32Value((int)(short)a.value);
}
public static Int32Value Conv_U4(Int32Value a) {
return a;
}
public static Int32Value Conv_U4(Int64Value a) {
return new Int32Value((int)(uint)a.value, (uint)a.validMask);
}
public static Int32Value Conv_U4(Real8Value a) {
return new Int32Value((int)(uint)a.value);
}
public static Int32Value Conv_I4(Int32Value a) {
return a;
}
public static Int32Value Conv_I4(Int64Value a) {
return new Int32Value((int)a.value, (uint)a.validMask);
}
public static Int32Value Conv_I4(Real8Value a) {
return new Int32Value((int)a.value);
}
2013-10-15 16:12:41 +08:00
bool CheckSign(uint mask) {
return ((uint)value & mask) == 0 || ((uint)value & mask) == mask;
}
public static Int32Value Conv_Ovf_I1(Int32Value a) {
if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) ||
!a.CheckSign(NO_UNKNOWN_BITS << 7))
return CreateUnknown();
return Conv_I1(a);
}
public static Int32Value Conv_Ovf_I1_Un(Int32Value a) {
if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) ||
(uint)a.value > sbyte.MaxValue)
return CreateUnknown();
return Conv_I1(a);
}
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_I2_Un(Int32Value a) {
if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) ||
(uint)a.value > short.MaxValue)
return CreateUnknown();
return Conv_I2(a);
}
public static Int32Value Conv_Ovf_I4(Int32Value a) {
return a;
}
public static Int32Value Conv_Ovf_I4_Un(Int32Value a) {
if (!IsBitValid(a.validMask, 31) || a.value < 0)
return CreateUnknown();
return a;
}
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 Int64Value Conv_Ovf_I8_Un(Int32Value a) {
return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32));
}
public static Int32Value Conv_Ovf_U1(Int32Value a) {
if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) ||
a.value < 0 || a.value > byte.MaxValue)
return CreateUnknownUInt8();
return Conv_U1(a);
}
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 Conv_Ovf_U2(Int32Value a) {
if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) ||
a.value < 0 || a.value > ushort.MaxValue)
return CreateUnknownUInt16();
return Conv_U2(a);
}
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_Ovf_U4(Int32Value a) {
if (!IsBitValid(a.validMask, 31) || a.value < 0)
return CreateUnknown();
return a;
}
public static Int32Value Conv_Ovf_U4_Un(Int32Value a) {
return a;
}
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 Int64Value Conv_Ovf_U8_Un(Int32Value a) {
return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32));
}
2011-10-17 13:28:53 +08:00
public static Int32Value Add(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return new Int32Value(a.value + b.value);
if (ReferenceEquals(a, b))
return new Int32Value(a.value << 1, (a.validMask << 1) | 1);
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Sub(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return new Int32Value(a.value - b.value);
2011-10-17 13:55:06 +08:00
if (ReferenceEquals(a, b))
2013-10-15 16:12:41 +08:00
return Zero;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Mul(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return new Int32Value(a.value * b.value);
2013-01-19 20:03:57 +08:00
if (a.IsZero() || b.IsZero())
2013-10-15 16:12:41 +08:00
return Zero;
2013-01-19 20:03:57 +08:00
if (a.HasValue(1))
2011-10-17 13:28:53 +08:00
return b;
2013-01-19 20:03:57 +08:00
if (b.HasValue(1))
2011-10-17 13:28:53 +08:00
return a;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Div(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid()) {
2011-10-17 13:28:53 +08:00
try {
return new Int32Value(a.value / b.value);
}
catch (ArithmeticException) {
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
}
2013-01-19 20:03:57 +08:00
if (ReferenceEquals(a, b) && a.IsNonZero())
2013-10-15 16:12:41 +08:00
return One;
2013-01-19 20:03:57 +08:00
if (b.HasValue(1))
2011-10-17 13:28:53 +08:00
return a;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Div_Un(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid()) {
2011-10-17 13:28:53 +08:00
try {
return new Int32Value((int)((uint)a.value / (uint)b.value));
}
catch (ArithmeticException) {
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
}
2013-01-19 20:03:57 +08:00
if (ReferenceEquals(a, b) && a.IsNonZero())
2013-10-15 16:12:41 +08:00
return One;
2013-01-19 20:03:57 +08:00
if (b.HasValue(1))
2011-10-17 13:28:53 +08:00
return a;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Rem(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid()) {
2011-10-17 13:28:53 +08:00
try {
return new Int32Value(a.value % b.value);
}
catch (ArithmeticException) {
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
}
2013-01-19 20:03:57 +08:00
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
2013-10-15 16:12:41 +08:00
return Zero;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Rem_Un(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid() && b.AllBitsValid()) {
2011-10-17 13:28:53 +08:00
try {
return new Int32Value((int)((uint)a.value % (uint)b.value));
}
catch (ArithmeticException) {
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
}
2013-01-19 20:03:57 +08:00
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
2013-10-15 16:12:41 +08:00
return Zero;
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
public static Int32Value Neg(Int32Value a) {
2013-01-19 20:03:57 +08:00
if (a.AllBitsValid())
2011-10-17 13:28:53 +08:00
return new Int32Value(-a.value);
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
}
2013-10-15 16:12:41 +08:00
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();
}
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 Sub_Ovf(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value(checked(a.value - b.value));
}
catch (OverflowException) {
}
}
return CreateUnknown();
}
public static Int32Value Sub_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_Ovf(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value(checked(a.value * b.value));
}
catch (OverflowException) {
}
}
return CreateUnknown();
}
public static Int32Value Mul_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();
}
2011-10-17 13:28:53 +08:00
public static Int32Value And(Int32Value a, Int32Value b) {
int av = a.value, bv = b.value;
uint am = a.validMask, bm = b.validMask;
2013-10-15 16:12:41 +08:00
return new Int32Value(av & bv, (am & bm) | (((uint)av & am) ^ am) | (((uint)bv & bm) ^ bm));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Or(Int32Value a, Int32Value b) {
int av = a.value, bv = b.value;
uint am = a.validMask, bm = b.validMask;
2013-10-15 16:12:41 +08:00
return new Int32Value(av | bv, (am & bm) | ((uint)av & am) | ((uint)bv & bm));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Xor(Int32Value a, Int32Value b) {
if (ReferenceEquals(a, b))
2013-10-15 16:12:41 +08:00
return Zero;
2011-10-17 13:28:53 +08:00
int av = a.value, bv = b.value;
uint am = a.validMask, bm = b.validMask;
2013-10-15 16:12:41 +08:00
return new Int32Value(av ^ bv, am & bm);
2011-10-17 13:28:53 +08:00
}
public static Int32Value Not(Int32Value a) {
return new Int32Value(~a.value, a.validMask);
}
public static Int32Value Shl(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (b.HasUnknownBits())
return CreateUnknown();
2011-10-17 13:28:53 +08:00
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
int shift = b.value;
uint validMask = (a.validMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift));
return new Int32Value(a.value << shift, validMask);
}
public static Int32Value Shr(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (b.HasUnknownBits())
return CreateUnknown();
2011-10-17 13:28:53 +08:00
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
int shift = b.value;
uint validMask = a.validMask >> shift;
2013-01-19 20:03:57 +08:00
if (a.IsBitValid(sizeof(int) * 8 - 1))
2011-10-17 13:28:53 +08:00
validMask |= (uint.MaxValue << (sizeof(int) * 8 - shift));
return new Int32Value(a.value >> shift, validMask);
}
public static Int32Value Shr_Un(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
if (b.HasUnknownBits())
return CreateUnknown();
2011-10-17 13:28:53 +08:00
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
2013-01-19 20:03:57 +08:00
return CreateUnknown();
2011-10-17 13:28:53 +08:00
int shift = b.value;
uint validMask = (a.validMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift));
return new Int32Value((int)((uint)a.value >> shift), validMask);
}
static Int32Value create(Bool3 b) {
switch (b) {
2013-10-15 16:12:41 +08:00
case Bool3.False: return Zero;
case Bool3.True: return One;
2013-01-19 20:03:57 +08:00
default: return CreateUnknownBool();
2011-10-17 13:28:53 +08:00
}
}
public static Int32Value Ceq(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
return create(CompareEq(a, b));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Cgt(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
return create(CompareGt(a, b));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Cgt_Un(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
return create(CompareGt_Un(a, b));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Clt(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
return create(CompareLt(a, b));
2011-10-17 13:28:53 +08:00
}
public static Int32Value Clt_Un(Int32Value a, Int32Value b) {
2013-01-19 20:03:57 +08:00
return create(CompareLt_Un(a, b));
2011-10-17 13:28:53 +08:00
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareEq(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value == b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.True;
if ((a.value & a.validMask & b.validMask) != (b.value & a.validMask & b.validMask))
return Bool3.False;
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareNeq(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value != b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.False;
if ((a.value & a.validMask & b.validMask) != (b.value & a.validMask & b.validMask))
return Bool3.True;
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareGt(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value > b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(int.MinValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // min > x => false
2013-01-19 20:03:57 +08:00
if (b.HasValue(int.MaxValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareGt_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return (uint)a.value > (uint)b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(uint.MinValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // min > x => false
2013-01-19 20:03:57 +08:00
if (b.HasValue(uint.MaxValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareGe(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value >= b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(int.MaxValue))
return Bool3.True; // max >= x => true
2013-01-19 20:03:57 +08:00
if (b.HasValue(int.MinValue))
return Bool3.True; // x >= min => true
2011-10-17 13:28:53 +08:00
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareGe_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return (uint)a.value >= (uint)b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(uint.MaxValue))
return Bool3.True; // max >= x => true
2013-01-19 20:03:57 +08:00
if (b.HasValue(uint.MinValue))
return Bool3.True; // x >= min => true
2011-10-17 13:28:53 +08:00
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareLe(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value <= b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(int.MinValue))
return Bool3.True; // min <= x => true
2013-01-19 20:03:57 +08:00
if (b.HasValue(int.MaxValue))
return Bool3.True; // x <= max => true
2011-10-17 13:28:53 +08:00
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return (uint)a.value <= (uint)b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(uint.MinValue))
return Bool3.True; // min <= x => true
2013-01-19 20:03:57 +08:00
if (b.HasValue(uint.MaxValue))
return Bool3.True; // x <= max => true
2011-10-17 13:28:53 +08:00
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareLt(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value < b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(int.MaxValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // max < x => false
2013-01-19 20:03:57 +08:00
if (b.HasValue(int.MinValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
2011-10-17 13:28:53 +08:00
return (uint)a.value < (uint)b.value ? Bool3.True : Bool3.False;
2013-01-19 20:03:57 +08:00
if (a.HasValue(uint.MaxValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // max < x => false
2013-01-19 20:03:57 +08:00
if (b.HasValue(uint.MinValue))
2011-10-17 13:28:53 +08:00
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareTrue(Int32Value a) {
if (a.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value != 0 ? Bool3.True : Bool3.False;
if ((a.value & a.validMask) != 0)
return Bool3.True;
return Bool3.Unknown;
}
2013-01-19 20:03:57 +08:00
public static Bool3 CompareFalse(Int32Value a) {
if (a.AllBitsValid())
2011-10-17 13:28:53 +08:00
return a.value == 0 ? Bool3.True : Bool3.False;
if ((a.value & a.validMask) != 0)
return Bool3.False;
return Bool3.Unknown;
}
public override string ToString() {
2013-01-19 20:03:57 +08:00
if (AllBitsValid())
2011-10-17 13:28:53 +08:00
return value.ToString();
return string.Format("0x{0:X8}({1:X8})", value, validMask);
}
}
}