⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inttypes.hh

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 HH
字号:
#ifndef simtypes_hh_included#define simtypes_hh_included#include <stdlib.h>#include "assert.hh"// GCC before 2.95 doesn't work.#ifdef __GNUC__# if (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95))#  error Sulima cannot be compiled with versions of GCC earlier than 2.9x# endif#endif// This header defines a set of minimum-width integer types. There is no need// for fixed-width types, although in many places it may improve performance.// There are four minimum-width signed types Int8, Int16, Int32 and Int64, and// four corresponding unsigned types UInt8, UInt16, UInt32 and UInt64.// Currently, two models are supported, ANSI (use ANSI restrictions on types// up to 32 bit and some unportable 64 bit type) and SIM64 (32 bit integers// and 64 bit longs). The first is currently supported only on GCC and TenDRA// as well as any C99-compatible compilers. Note that all eight types MUST be// distinct, as they are frequently used in overload resolution.typedef signed char    Int8;typedef unsigned char  UInt8;typedef signed short   Int16;typedef unsigned short UInt16;#if defined SIM64typedef signed int     Int32;typedef unsigned int   UInt32;#elsetypedef signed long    Int32;typedef unsigned long  UInt32;#endif#if defined SIM64 typedef signed long    Int64; typedef unsigned long  UInt64;#elif defined __TenDRA__ // We must enable long long first. #pragma TenDRA longlong type allow typedef signed long long   Int64; typedef unsigned long long UInt64;#elif defined __GNUC__ // This mess is here so we can use -pedantic without warnings. typedef __typeof__(__extension__ 1LL)  Int64; typedef __typeof__(__extension__ 1ULL) UInt64;#elif __STDC_VERSION__ >= 199901L // C99 supports long long from the box. typedef signed long long   Int64; typedef unsigned long long UInt64;#else# error Cannot find a suitible 64 bit type.#endif// A template intended to obtain a type given its width.template <int n> struct FixedWidth { };template <> struct FixedWidth<8> {    typedef Int8  Signed;	// signed type of at least <n> bytse    typedef UInt8 Unsigned;	// unsigned type of at least <n> bytes};template <> struct FixedWidth<16> {    typedef Int16  Signed;    typedef UInt16 Unsigned;};template <> struct FixedWidth<32> {    typedef Int32  Signed;    typedef UInt32 Unsigned;};template <> struct FixedWidth<64> {    typedef Int64  Signed;    typedef UInt64 Unsigned;};// Some type traits used by various templates.  For each type T, I define the// following parameters:////	IntTraits<T>::width		working width of the type//	typename IntTraits<T>::Signed	signed counterpart of T//	typename IntTraits<T>::Unsigned	unsigned counterpart of T//	typename IntTraits<T>::Half	a type with half of the width of T//	typename IntTraits<T>::Double	a type with twice the width of T//// Obviously, Half is not defined for 8-bit types and Double is not defined// for 64-bit types.template <typename T> struct IntTraits { };template <> struct IntTraits<Int8> {    static const int width = 8;    typedef Int8   Signed;    typedef UInt8  Unsigned;    typedef Int16  Double;};template <> struct IntTraits<Int16> {    static const int width = 16;    typedef Int16  Signed;    typedef UInt16 Unsigned;    typedef Int8   Half;    typedef Int32  Double;};template <> struct IntTraits<Int32> {    static const int width = 32;    typedef Int32  Signed;    typedef UInt32 Unsigned;    typedef Int16   Half;    typedef Int64  Double;};template <> struct IntTraits<Int64> {    static const int width = 64;    typedef Int64  Signed;    typedef UInt64 Unsigned;    typedef Int32   Half;};template <> struct IntTraits<UInt8> {    static const int width = 8;    typedef Int8   Signed;    typedef UInt8  Unsigned;    typedef UInt16 Double;};template <> struct IntTraits<UInt16> {    static const int width = 16;    typedef Int16  Signed;    typedef UInt16 Unsigned;    typedef UInt8  Half;    typedef UInt32 Double;};template <> struct IntTraits<UInt32> {    static const int width = 32;    typedef Int32  Signed;    typedef UInt32 Unsigned;    typedef UInt16 Half;    typedef UInt64 Double;};template <> struct IntTraits<UInt64> {    static const int width = 64;    typedef Int64  Signed;    typedef UInt64 Unsigned;    typedef UInt32 Half;};// Useful multiplier suffixes.static const int KB = 1024;static const int MB = 1024*KB;static const int GB = 1024*MB;static const int TB = 1024*GB;// Interfaces to ANSI # and ## preprocessing operators.  The STR2() and// GLUE2() differ from STR() and GLUE() in that the later macro-expand the// arguments before applying the operator.#define STR2(x)		#x#define STR(x)		STR2(x)#define GLUE2(x,y)	x##y#define GLUE(x,y)	GLUE2(x,y)// Two macros used to construct fixed-width constants from unsuffixed// literals. They serve two purposes: (1) to make it possible to define// portable 64 bit constants on 32 bit systems, and (2) to make huge constant// easier to read.#define C32(a,b)							  \	((UInt32)((UInt32)GLUE2(0x,a) << 16 | (UInt32)GLUE2(0x,b)))#define C64(a,b,c,d)							  \	((UInt64)((UInt64)GLUE2(0x,a) << 48 | (UInt64)GLUE2(0x,b) << 32 | \		  (UInt64)GLUE2(0x,c) << 16 | (UInt64)GLUE2(0x,d)))// Returns true iff the host system uses big-endian byte ordering.inline bool big_endian_host(){    const int sample = 1;    return !reinterpret_cast<const char &>(sample);}// Return false iff (x) != log2(x) (computed to infinite precision)template <typename T> inline bool is_power_of_two(T x){    return (x & -x) == x;}// Some important bit-swizzling functions. In most cases, these allows me to// avoid computing huge hexadecimal bitmask, which certainly is a good thing.// Return (x) rounded toward -inf to the nearest multiple of (size).// Precondition: size == (1 << x), 0 <= x < 8 * sizeof(T) - 1template <typename T, typename Int> inline T round_down(T x, Int size){    return x & -typename IntTraits<T>::Signed(size);}// Return (x) rounded toward +inf to the nearest multiple of (size).// Precondition: size == (1 << x), 0 <= x < 8 * sizeof(T) - 1template <typename T, typename Int> inline T round_up(T x, Int size){    return (x + size - 1) & -typename IntTraits<T>::Signed(size);}// Create a bit mask with the (n)th bit set.// Precondition: 0 <= n < 64inline UInt64 bitmask(int n){    return (UInt64)1 << n;}// Create a bit mask with the bits in the range [m, n] set. // Precondition: 0 <= m <= n < 64inline UInt64 bitmask(int n, int m){    return ~(UInt64)0 >> m << (63 - n + m) >> (63 - n);}// Return the (n)th bit from (x).// Precondition: 0 <= n < 8 * sizeof(T)template <typename T, typename Int> inline T bit(T x, Int n){    return (x >> n) & 1;}// Return (x) with the (n)th bit cleared.// Precondition: 0 <= n < 8 * sizeof(T).template <typename T, typename Int> inline T clear_bit(T x, Int n){    return x & ~bitmask(n);}// Return (x) with the (n)th bit set.// Precondition: 0 <= n < 8 * sizeof(T).template <typename T, typename Int> inline T set_bit(T x, Int n){    return x | bitmask(n);}// Return (x) with the (n)th bit set to bit(y, 0).// Precondition: 0 <= n < 8 * sizeof(T). template <typename T, typename Int> inline T set_bit(T x, T y, Int n){    return clear_bit(x, n) | (bit(y, 0) << n);}// Return the bit range [m, n] from (x).// Precondition: 0 <= m <= n < 8 * sizeof(T).template <typename T, typename Int> inline T bits(T x, Int n, Int m){    UInt64 y = x;    return y << (63 - n) >> (63 - n + m);}// Return (x) with bits in the range [m, n] cleared.// Precondition: 0 <= m <= n < 8 * sizeof(T).template <typename T, typename Int> inline T clear_bits(T x, Int n, Int m){    return x & ~bitmask(n, m);}// Return (x) with bits in the range [m, n] set.// Precondition: 0 <= m <= n < 8 * sizeof(T).template <typename T, typename Int> inline T set_bits(T x, Int n, Int m){    return x | bitmask(n, m);}// Return (x) with bits in the range [m, n] set to bits(y, n - m, 0).// Precondition: 0 <= m <= n < 8 * sizeof(T).template <typename T, typename Int> inline T set_bits(T x, T y, Int n, Int m){    return clear_bits(x, n, m) | (bits(y, n - m, Int(0)) << m);}// Return bits(x, n-1, 0) zero-extended to (8 * sizeof(T)).// Precondition: 0 < n <= 8 * sizeof(T)template <typename T> inline T zero_extend(T x, int n){    return bits(x, n-1, 0);}// Return bits(x, n-1, 0) sign-extended to (8 * sizeof(T)).// Precondition: 0 < n <= 8 * sizeof(T)template <typename T> inline T sign_extend(T x, int n){    if (((typename IntTraits<T>::Signed)-1 >> 1) < 0) {	// Host platform does arithmetic right shifts.	typename IntTraits<T>::Signed y = x;	return y << (8 * sizeof(T) - n) >> (8 * sizeof(T) - n);    }    else if (size_t(n) < 8 * sizeof(T)) {	// We have to manually patch the high-order bits.	if (bit(x, n - 1))	    return set_bits(x, 8 * sizeof(T) - 1, size_t(n));	else {	    return clear_bits(x, 8 * sizeof(T) - 1, size_t(n));	}    }}// Return (x) with the byte order reversed. byte_swap(x) recursively swaps// each half of (x), until (x) contains only a single byte.template <typename T> inline T byte_swap(T x){    typedef typename IntTraits<T>::Unsigned U;    typedef typename IntTraits<U>::Half Half;    return (U(byte_swap(Half(x))) << IntTraits<Half>::width) |	byte_swap(Half(x >> IntTraits<Half>::width));}template <> inline Int8 byte_swap(Int8 x){    return x;}template <> inline UInt8 byte_swap(UInt8 x){    return x;}// Return floor(log2(x)).// Precondition: x > 0template <typename T> int log2(T x){    assert(x > 0);    int i = 0;    do {	++i;    } while (x >>= 1);    return i;}// Perform a long multiplication.// Preconditions: a == sign_extend(a, IntTraits<T>::width)//                b == sign_extend(b, IntTraits<T>::width)template <typename T> struct MulResult {    T lo, hi;    MulResult() { }    MulResult(T h, T l) : lo(l), hi(h) { }};template <typename T> MulResult<T> multiply(T a, T b){    const int n = IntTraits<T>::width;    typename IntTraits<T>::Double x = a, y = b, z = x * y;    return MulResult<T>(bits(z, 2 * n - 1, n), bits(z, n - 1, 0));}// Specializations for 64 bit types are in "sulima/multiply.cc"template <> MulResult<Int64> multiply(Int64 a, Int64 b);template <> MulResult<UInt64> multiply(UInt64 a, UInt64 b);// Perform a portable division, using the standard library div() and ldiv()// functions if possible.  The result is always rounded toward zero; I assume// that the compiler is consistent with its treatment of negative arguments to// the / and % operators, which is a reasonable assumption, although not// strictly portable according to ISO.// Preconditions: a == sign_extend(a, IntTraits<T>::width)//                b == sign_extend(b, IntTraits<T>::width) != 0template <typename T> struct DivResult {    T quot, rem;    DivResult() { }    DivResult(T q, T r) : quot(q), rem(r) { }};template <typename T> DivResult<T> divide(T a, T b){    const size_t n = IntTraits<T>::width;    if (n < sizeof(int)) {	div_t r = div(int(a), int(b));	return DivResult<T>(r.quot, r.rem);    }    else if (n < sizeof(long)) {	ldiv_t r = ldiv(long(a), long(b));	return DivResult<T>(r.quot, r.rem);    }    else {	// This has to be specialized for signed types.	return DivResult<T>(a / b, a % b);    }}// Specialisations for 32 and 64 bit types.template <> inline DivResult<Int32> divide(Int32 a, Int32 b){    if (32 <= sizeof(int)) {	div_t r = div(int(a), int(b));	return DivResult<Int32>(r.quot, r.rem);    }    else {	ldiv_t r = ldiv(long(a), long(b));	return DivResult<Int32>(r.quot, r.rem);    }}template <> inline DivResult<UInt32> divide(UInt32 a, UInt32 b){    if (32 < sizeof(long)) {	ldiv_t r = ldiv(long(a), long(b));	return DivResult<UInt32>(r.quot, r.rem);    }    else {	return DivResult<UInt32>(a / b, a % b);    }}template <> inline DivResult<Int64> divide(Int64 a, Int64 b){    if (64 <= sizeof(long)) {	ldiv_t r = ldiv(long(a), long(b));	return DivResult<Int64>(r.quot, r.rem);    }    else if (Int64(-2) % Int64(3) < 0) {	// Hardware division rounds towards zero.	return DivResult<Int64>(a / b, a % b);    }    else {	// Hardware division rounds towards negative infinity, so fix it.	if ((a ^ b) >= 0)	    return DivResult<Int64>(a / b, a % b);	else if (a < 0)	    return DivResult<Int64>(-(-a / b), -(-a % b));	else {	    return DivResult<Int64>(-(a / -b), -(a % -b));	}    }}/* this may seem completely unnecessary, but these extra definitions * allow the above functions to be used when the last template type is * an enumeration (which has no particular type). In that case, int * will be used, which should be sufficient for any enumerations. */template <typename T> inline T bit(T x, int n){	return bit <T, int> (x, n);}template <typename T> inline T clear_bit(T x, int n){    return clear_bit <T, int> (x, n);}template <typename T> inline T set_bit(T x, int n){	return set_bit <T, int> (x, n);}template <typename T> inline T set_bit(T x, T y, int n){	return set_bit <T, int> (x, y, n);}template <typename T> inline T bits(T x, int n, int m){	return bits <T, int> (x, n, m);}template <typename T> inline T clear_bits(T x, int n, int m){	return clear_bits <T, int> (x, n, m);}template <typename T> inline T set_bits(T x, int n, int m){	return set_bits <T, int> (x, n, m);}template <typename T> inline T set_bits(T x, T y, int n, int m){	return set_bits <T, int> (x, y, n, m);}#endif // simtypes_hh_included

⌨️ 快捷键说明

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