mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-17 19:07:05 +02:00
Updated to dmdfe 2.054
This commit is contained in:
+149
@@ -0,0 +1,149 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by KennyTM
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
#ifndef DMD_SXNUM_H
|
||||
#define DMD_SXNUM_H
|
||||
|
||||
#include "mars.h" // for uinteger_t
|
||||
struct Type;
|
||||
struct Expression;
|
||||
|
||||
/**
|
||||
This class represents a "sign-extended number", i.e. a 65-bit number, which can
|
||||
represent all built-in integer types in D. This class is mainly used for
|
||||
performing value-range propagation only, therefore all arithmetic are done with
|
||||
saturation, not wrapping as usual.
|
||||
*/
|
||||
struct SignExtendedNumber
|
||||
{
|
||||
/// The lower 64-bit of the number.
|
||||
uinteger_t value;
|
||||
/// The sign (i.e. the most significant bit) of the number.
|
||||
bool negative;
|
||||
|
||||
/// Create an uninitialized sign-extended number.
|
||||
SignExtendedNumber() {}
|
||||
|
||||
/// Create a sign-extended number from an unsigned 64-bit number.
|
||||
SignExtendedNumber(uinteger_t value_)
|
||||
: value(value_), negative(false) {}
|
||||
/// Create a sign-extended number from the lower 64-bit and the sign bit.
|
||||
SignExtendedNumber(uinteger_t value_, bool negative_)
|
||||
: value(value_), negative(negative_) {}
|
||||
|
||||
/// Create a sign-extended number from a signed 64-bit number.
|
||||
static SignExtendedNumber fromInteger(uinteger_t value_);
|
||||
|
||||
/// Get the minimum or maximum value of a sign-extended number.
|
||||
static SignExtendedNumber extreme(bool minimum);
|
||||
static SignExtendedNumber max();
|
||||
static SignExtendedNumber min() { return SignExtendedNumber(0, true); }
|
||||
|
||||
/// Check if the sign-extended number is minimum or zero.
|
||||
bool isMinimum() const { return negative && value == 0; }
|
||||
|
||||
/// Compare two sign-extended number.
|
||||
bool operator==(const SignExtendedNumber&) const;
|
||||
bool operator!=(const SignExtendedNumber& a) const { return !(*this == a); }
|
||||
bool operator<(const SignExtendedNumber&) const;
|
||||
bool operator>(const SignExtendedNumber& a) const { return a < *this; }
|
||||
bool operator<=(const SignExtendedNumber& a) const { return !(a < *this); }
|
||||
bool operator>=(const SignExtendedNumber& a) const { return !(*this < a); }
|
||||
|
||||
/// Compute the saturated negation of a sign-extended number.
|
||||
SignExtendedNumber operator-() const;
|
||||
|
||||
/// Compute the saturated sum of two sign-extended number.
|
||||
SignExtendedNumber operator+(const SignExtendedNumber&) const;
|
||||
/// Compute the saturated difference of two sign-extended number.
|
||||
SignExtendedNumber operator-(const SignExtendedNumber& a) const;
|
||||
/// Compute the saturated product of two sign-extended number.
|
||||
SignExtendedNumber operator*(const SignExtendedNumber&) const;
|
||||
/// Compute the saturated quotient of two sign-extended number.
|
||||
SignExtendedNumber operator/(const SignExtendedNumber&) const;
|
||||
/// Compute the saturated modulus of two sign-extended number.
|
||||
SignExtendedNumber operator%(const SignExtendedNumber&) const;
|
||||
|
||||
/// Increase the sign-extended number by 1 (saturated).
|
||||
SignExtendedNumber& operator++();
|
||||
|
||||
/// Compute the saturated shifts of two sign-extended number.
|
||||
SignExtendedNumber operator<<(const SignExtendedNumber&) const;
|
||||
SignExtendedNumber operator>>(const SignExtendedNumber&) const;
|
||||
};
|
||||
|
||||
/**
|
||||
This class represents a range of integers, denoted by its lower and upper bounds
|
||||
(inclusive).
|
||||
*/
|
||||
struct IntRange
|
||||
{
|
||||
SignExtendedNumber imin, imax;
|
||||
|
||||
/// Create an uninitialized range.
|
||||
IntRange() {}
|
||||
|
||||
/// Create a range consisting of a single number.
|
||||
IntRange(const SignExtendedNumber& a)
|
||||
: imin(a), imax(a) {}
|
||||
/// Create a range with the lower and upper bounds.
|
||||
IntRange(const SignExtendedNumber& lower, const SignExtendedNumber& upper)
|
||||
: imin(lower), imax(upper) {}
|
||||
|
||||
/// Create the tightest range containing all valid integers in the specified
|
||||
/// type.
|
||||
static IntRange fromType(Type *type);
|
||||
/// Create the tightest range containing all valid integers in the type with
|
||||
/// a forced signedness.
|
||||
static IntRange fromType(Type *type, bool isUnsigned);
|
||||
|
||||
|
||||
/// Create the tightest range containing all specified numbers.
|
||||
static IntRange fromNumbers2(const SignExtendedNumber numbers[2]);
|
||||
static IntRange fromNumbers4(const SignExtendedNumber numbers[4]);
|
||||
|
||||
/// Create the widest range possible.
|
||||
static IntRange widest();
|
||||
|
||||
/// Cast the integer range to a signed type with the given size mask.
|
||||
IntRange& castSigned(uinteger_t mask);
|
||||
/// Cast the integer range to an unsigned type with the given size mask.
|
||||
IntRange& castUnsigned(uinteger_t mask);
|
||||
/// Cast the integer range to the dchar type.
|
||||
IntRange& castDchar();
|
||||
|
||||
/// Cast the integer range to a specific type.
|
||||
IntRange& cast(Type *type);
|
||||
/// Cast the integer range to a specific type, forcing it to be unsigned.
|
||||
IntRange& castUnsigned(Type *type);
|
||||
|
||||
/// Check if this range contains another range.
|
||||
bool contains(const IntRange& a) const;
|
||||
|
||||
/// Check if this range contains 0.
|
||||
bool containsZero() const;
|
||||
|
||||
/// Compute the range of the negated absolute values of the original range.
|
||||
IntRange absNeg() const;
|
||||
|
||||
/// Compute the union of two ranges.
|
||||
IntRange unionWith(const IntRange& other) const;
|
||||
void unionOrAssign(const IntRange& other, bool& union_);
|
||||
|
||||
/// Dump the content of the integer range to the console.
|
||||
const IntRange& dump(const char* funcName, Expression *e) const;
|
||||
|
||||
/// Split the range into two nonnegative- and negative-only subintervals.
|
||||
void splitBySign(IntRange& negRange, bool& hasNegRange,
|
||||
IntRange& nonNegRange, bool& hasNonNegRange) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user