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 Int64Value : Value {
|
2012-01-27 06:57:37 +08:00
|
|
|
|
public static readonly Int64Value zero = new Int64Value(0);
|
|
|
|
|
public static readonly Int64Value one = new Int64Value(1);
|
|
|
|
|
|
2011-10-17 13:28:53 +08:00
|
|
|
|
const ulong NO_UNKNOWN_BITS = ulong.MaxValue;
|
|
|
|
|
public readonly long value;
|
|
|
|
|
public readonly ulong validMask;
|
|
|
|
|
|
|
|
|
|
public Int64Value(long value)
|
|
|
|
|
: base(ValueType.Int64) {
|
|
|
|
|
this.value = value;
|
|
|
|
|
this.validMask = NO_UNKNOWN_BITS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Int64Value(long value, ulong validMask)
|
|
|
|
|
: base(ValueType.Int64) {
|
|
|
|
|
this.value = value;
|
|
|
|
|
this.validMask = validMask;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
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(ulong validMask, int n) {
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return (validMask & (1UL << n)) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public static Int64Value CreateUnknown() {
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return new Int64Value(0, 0UL);
|
|
|
|
|
}
|
|
|
|
|
|
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 ((ulong)value & validMask) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public bool HasValue(long 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(ulong value) {
|
|
|
|
|
return HasValue((long)value);
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_U8(Int32Value a) {
|
|
|
|
|
long value = (long)(ulong)(uint)a.value;
|
|
|
|
|
ulong validMask = a.validMask | (NO_UNKNOWN_BITS << 32);
|
|
|
|
|
return new Int64Value(value, validMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_U8(Int64Value a) {
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_U8(Real8Value a) {
|
|
|
|
|
return new Int64Value((long)(ulong)a.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_I8(Int32Value a) {
|
|
|
|
|
long value = a.value;
|
|
|
|
|
ulong validMask = a.validMask;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (IsBitValid(validMask, 31))
|
2011-10-17 13:28:53 +08:00
|
|
|
|
validMask |= NO_UNKNOWN_BITS << 32;
|
|
|
|
|
else
|
|
|
|
|
validMask &= ~(NO_UNKNOWN_BITS << 32);
|
|
|
|
|
return new Int64Value(value, validMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_I8(Int64Value a) {
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Conv_I8(Real8Value a) {
|
|
|
|
|
return new Int64Value((long)a.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Add(Int64Value a, Int64Value b) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return new Int64Value(a.value + b.value);
|
2011-10-17 15:06:46 +08:00
|
|
|
|
if (ReferenceEquals(a, b))
|
|
|
|
|
return new Int64Value(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 Int64Value Sub(Int64Value a, Int64Value b) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return new Int64Value(a.value - b.value);
|
2011-10-17 13:55:06 +08:00
|
|
|
|
if (ReferenceEquals(a, b))
|
2012-01-27 06:57:37 +08:00
|
|
|
|
return zero;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Mul(Int64Value a, Int64Value b) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return new Int64Value(a.value * b.value);
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.IsZero() || b.IsZero())
|
2012-01-27 06:57:37 +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 Int64Value Div(Int64Value a, Int64Value 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 Int64Value(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())
|
2012-01-27 06:57:37 +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 Int64Value Div_Un(Int64Value a, Int64Value b) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
2011-10-17 13:28:53 +08:00
|
|
|
|
try {
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return new Int64Value((long)((ulong)a.value / (ulong)b.value));
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
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())
|
2012-01-27 06:57:37 +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 Int64Value Rem(Int64Value a, Int64Value 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 Int64Value(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))
|
2012-01-27 06:57:37 +08:00
|
|
|
|
return zero;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Rem_Un(Int64Value a, Int64Value b) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
2011-10-17 13:28:53 +08:00
|
|
|
|
try {
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return new Int64Value((long)((ulong)a.value % (ulong)b.value));
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
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))
|
2012-01-27 06:57:37 +08:00
|
|
|
|
return zero;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Neg(Int64Value a) {
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return new Int64Value(-a.value);
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value And(Int64Value a, Int64Value b) {
|
|
|
|
|
long av = a.value, bv = b.value;
|
|
|
|
|
ulong am = a.validMask, bm = b.validMask;
|
|
|
|
|
return new Int64Value(av & bv, (am & bm) | (((ulong)av & am) ^ am) | (((ulong)bv & bm) ^ bm));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Or(Int64Value a, Int64Value b) {
|
|
|
|
|
long av = a.value, bv = b.value;
|
|
|
|
|
ulong am = a.validMask, bm = b.validMask;
|
|
|
|
|
return new Int64Value(av | bv, (am & bm) | ((ulong)av & am) | ((ulong)bv & bm));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Xor(Int64Value a, Int64Value b) {
|
|
|
|
|
if (ReferenceEquals(a, b))
|
2012-01-27 06:57:37 +08:00
|
|
|
|
return zero;
|
2011-10-17 13:28:53 +08:00
|
|
|
|
long av = a.value, bv = b.value;
|
|
|
|
|
ulong am = a.validMask, bm = b.validMask;
|
|
|
|
|
return new Int64Value(av ^ bv, am & bm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Not(Int64Value a) {
|
|
|
|
|
return new Int64Value(~a.value, a.validMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Shl(Int64Value 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(long) * 8)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
int shift = b.value;
|
|
|
|
|
ulong validMask = (a.validMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift));
|
|
|
|
|
return new Int64Value(a.value << shift, validMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Shr(Int64Value 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(long) * 8)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
int shift = b.value;
|
|
|
|
|
ulong validMask = a.validMask >> shift;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.IsBitValid(sizeof(long) * 8 - 1))
|
2011-10-17 13:28:53 +08:00
|
|
|
|
validMask |= (ulong.MaxValue << (sizeof(long) * 8 - shift));
|
|
|
|
|
return new Int64Value(a.value >> shift, validMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int64Value Shr_Un(Int64Value 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(long) * 8)
|
2013-01-19 20:03:57 +08:00
|
|
|
|
return CreateUnknown();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
int shift = b.value;
|
|
|
|
|
ulong validMask = (a.validMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift));
|
|
|
|
|
return new Int64Value((long)((ulong)a.value >> shift), validMask);
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
static Int32Value Create(Bool3 b) {
|
2011-10-17 13:28:53 +08:00
|
|
|
|
switch (b) {
|
2012-01-27 06:57:37 +08:00
|
|
|
|
case Bool3.False: return Int32Value.zero;
|
|
|
|
|
case Bool3.True: return Int32Value.one;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
default: return Int32Value.CreateUnknownBool();
|
2011-10-17 13:28:53 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Int32Value Ceq(Int64Value a, Int64Value 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(Int64Value a, Int64Value 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(Int64Value a, Int64Value 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(Int64Value a, Int64Value 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(Int64Value a, Int64Value 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(Int64Value a, Int64Value 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 (((ulong)a.value & a.validMask & b.validMask) != ((ulong)b.value & a.validMask & b.validMask))
|
|
|
|
|
return Bool3.False;
|
|
|
|
|
return Bool3.Unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public static Bool3 CompareNeq(Int64Value a, Int64Value 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 (((ulong)a.value & a.validMask & b.validMask) != ((ulong)b.value & a.validMask & b.validMask))
|
|
|
|
|
return Bool3.True;
|
|
|
|
|
return Bool3.Unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public static Bool3 CompareGt(Int64Value a, Int64Value 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(long.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(long.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(Int64Value a, Int64Value b) {
|
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return (ulong)a.value > (ulong)b.value ? Bool3.True : Bool3.False;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.HasValue(ulong.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(ulong.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(Int64Value a, Int64Value 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(long.MaxValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return Bool3.True; // max >= x => true
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (b.HasValue(long.MinValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
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(Int64Value a, Int64Value b) {
|
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return (ulong)a.value >= (ulong)b.value ? Bool3.True : Bool3.False;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.HasValue(ulong.MaxValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return Bool3.True; // max >= x => true
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (b.HasValue(ulong.MinValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
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(Int64Value a, Int64Value 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(long.MinValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return Bool3.True; // min <= x => true
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (b.HasValue(long.MaxValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
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(Int64Value a, Int64Value b) {
|
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return (ulong)a.value <= (ulong)b.value ? Bool3.True : Bool3.False;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.HasValue(ulong.MinValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return Bool3.True; // min <= x => true
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (b.HasValue(ulong.MaxValue))
|
2011-10-17 15:06:46 +08:00
|
|
|
|
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(Int64Value a, Int64Value 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(long.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(long.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(Int64Value a, Int64Value b) {
|
|
|
|
|
if (a.AllBitsValid() && b.AllBitsValid())
|
2011-10-17 15:06:46 +08:00
|
|
|
|
return (ulong)a.value < (ulong)b.value ? Bool3.True : Bool3.False;
|
2013-01-19 20:03:57 +08:00
|
|
|
|
if (a.HasValue(ulong.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(ulong.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(Int64Value a) {
|
|
|
|
|
if (a.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return a.value != 0 ? Bool3.True : Bool3.False;
|
|
|
|
|
if (((ulong)a.value & a.validMask) != 0)
|
|
|
|
|
return Bool3.True;
|
|
|
|
|
return Bool3.Unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-19 20:03:57 +08:00
|
|
|
|
public static Bool3 CompareFalse(Int64Value a) {
|
|
|
|
|
if (a.AllBitsValid())
|
2011-10-17 13:28:53 +08:00
|
|
|
|
return a.value == 0 ? Bool3.True : Bool3.False;
|
|
|
|
|
if (((ulong)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}L({1:X8})", value, validMask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|