Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions dmd2/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ static inline int getBitsizeOfType(Loc loc, Type *type)
case Tuns16: return 16;
case Tint128:
case Tuns128:
#if WANT_CENT
return 128;
#else
error(loc, "cent/ucent not supported");
break;
#endif
default:
error(loc, "unsupported type");
break;
Expand Down Expand Up @@ -273,8 +277,20 @@ Expression *eval_bswap(Loc loc, FuncDeclaration *fd, Expressions *arguments)
#define BYTEMASK 0x00FF00FF00FF00FFLL
#define SHORTMASK 0x0000FFFF0000FFFFLL
#define INTMASK 0x00000000FFFFFFFFLL
#if WANT_CENT
#define LONGMASK 0xFFFFFFFFFFFFFFFFLL
#endif
switch (type->toBasetype()->ty)
{
case Tint128:
case Tuns128:
#if WANT_CENT
// swap high and low uints
n = ((n >> 64) & LONGMASK) | ((n & LONGMASK) << 64);
#else
error(loc, "cent/ucent not supported");
break;
#endif
case Tint64:
case Tuns64:
// swap high and low uints
Expand All @@ -288,10 +304,6 @@ Expression *eval_bswap(Loc loc, FuncDeclaration *fd, Expressions *arguments)
// swap adjacent ubytes
n = ((n >> 8 ) & BYTEMASK) | ((n & BYTEMASK) << 8 );
break;
case Tint128:
case Tuns128:
error(loc, "cent/ucent not supported");
break;
default:
error(loc, "unsupported type");
break;
Expand Down
26 changes: 26 additions & 0 deletions dmd2/constfold.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,16 @@ UnionExp Shr(Type *type, Expression *e1, Expression *e2)
value = (d_uns64)(value) >> count;
break;

#if WANT_CENT
case Tint128:
value = (d_int128)(value) >> count;
break;

case Tuns128:
value = (d_uns128)(value) >> count;
break;
#endif

case Terror:
new(&ue) ErrorExp();
return ue;
Expand Down Expand Up @@ -690,10 +700,22 @@ UnionExp Ushr(Type *type, Expression *e1, Expression *e2)
value = (value & 0xFFFFFFFF) >> count;
break;

#if WANT_CENT
case Tint64:
case Tuns64:
value = (value & 0xFFFFFFFFFFFFFFFF) >> count;
break;

case Tint128:
case Tuns128:
value = (d_uns128)(value) >> count;
break;
#else
case Tint64:
case Tuns64:
value = (d_uns64)(value) >> count;
break;
#endif

case Terror:
new(&ue) ErrorExp();
Expand Down Expand Up @@ -1258,6 +1280,10 @@ UnionExp Cast(Type *type, Type *to, Expression *e1)
case Tuns32: result = (d_uns32)r; break;
case Tint64: result = (d_int64)r; break;
case Tuns64: result = (d_uns64)r; break;
#if WANT_CENT
case Tint128: result = (d_int128)r; break;
case Tuns128: result = (d_uns128)r; break;
#endif
default:
assert(0);
}
Expand Down
23 changes: 23 additions & 0 deletions dmd2/ctfeexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,17 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp
case Tuns64:
result = (d_uns64)(value) >> count;
break;

#if WANT_CENT
case Tint128:
result = (d_int128)(value) >> count;
break;

case Tuns128:
result = (d_uns128)(value) >> count;
break;
#endif

default:
assert(0);
}
Expand Down Expand Up @@ -1152,10 +1163,22 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp
result = (value & 0xFFFFFFFF) >> count;
break;

#if WANT_CENT
case Tint64:
case Tuns64:
result = (value & 0xFFFFFFFFFFFFFFFF) >> count;
break;

case Tint128:
case Tuns128:
result = (d_uns128)(value) >> count;
break;
#else
case Tint64:
case Tuns64:
result = (d_uns64)(value) >> count;
break;
#endif

default:
assert(0);
Expand Down
4 changes: 4 additions & 0 deletions dmd2/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,10 @@ void IntegerExp::normalize()
case Tuns32: value = (d_uns32) value; break;
case Tint64: value = (d_int64) value; break;
case Tuns64: value = (d_uns64) value; break;
#if WANT_CENT
case Tint128: value = (d_int128) value; break;
case Tuns128: value = (d_uns128) value; break;
#endif
case Tpointer:
if (Target::ptrsize == 4)
value = (d_uns32) value;
Expand Down
11 changes: 11 additions & 0 deletions dmd2/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#endif

#include "longdouble.h"
#include "int128.h"
#include "outbuffer.h"

// Can't include arraytypes.h here, need to declare these directly.
Expand Down Expand Up @@ -282,6 +283,11 @@ struct Global

extern Global global;

#if WANT_CENT
typedef uint128_t dinteger_t;
typedef int128_t sinteger_t;
typedef uint128_t uinteger_t;
#else
// Because int64_t and friends may be any integral type of the
// correct size, we have to explicitly ask for the correct
// integer type to get the correct mangling with ddmd
Expand All @@ -298,6 +304,7 @@ typedef unsigned long long dinteger_t;
typedef long long sinteger_t;
typedef unsigned long long uinteger_t;
#endif
#endif

typedef int8_t d_int8;
typedef uint8_t d_uns8;
Expand All @@ -307,6 +314,10 @@ typedef int32_t d_int32;
typedef uint32_t d_uns32;
typedef int64_t d_int64;
typedef uint64_t d_uns64;
#if WANT_CENT
typedef int128_t d_int128;
typedef uint128_t d_uns128;
#endif

typedef float d_float32;
typedef double d_float64;
Expand Down
18 changes: 18 additions & 0 deletions dmd2/hdrgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,24 @@ class PrettyPrintVisitor : public Visitor
buf->printf("%lluLU", v);
break;

#if WANT_CENT
case Tint128: {
char buffer[42];
sprintf_i128(buffer, v);
assert(strlen(buffer) < sizeof(buffer));
buf->writestring(buffer);
}
break;

case Tuns128: {
char buffer[42];
sprintf_u128(buffer, v);
assert(strlen(buffer) < sizeof(buffer));
buf->writestring(buffer);
}
break;
#endif

case Tbool:
buf->writestring(v ? "true" : "false");
break;
Expand Down
63 changes: 63 additions & 0 deletions dmd2/intrange.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,23 @@ static uinteger_t copySign(uinteger_t x, bool sign)
return (x - (uinteger_t)sign) ^ -(uinteger_t)sign;
}

#if WANT_CENT
#define UINT128_MAX UINT128C(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)
#else
#ifndef UINT64_MAX
#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
#endif
#endif

//==================== SignExtendedNumber ======================================

SignExtendedNumber SignExtendedNumber::fromInteger(uinteger_t value_)
{
#if WANT_CENT
return SignExtendedNumber(value_, value_ >> 128);
#else
return SignExtendedNumber(value_, value_ >> 63);
#endif
}

bool SignExtendedNumber::operator==(const SignExtendedNumber& a) const
Expand All @@ -54,7 +62,11 @@ SignExtendedNumber SignExtendedNumber::extreme(bool minimum)

SignExtendedNumber SignExtendedNumber::max()
{
#if WANT_CENT
return SignExtendedNumber(UINT128_MAX, false);
#else
return SignExtendedNumber(UINT64_MAX, false);
#endif
}

SignExtendedNumber SignExtendedNumber::operator-() const
Expand All @@ -74,7 +86,11 @@ SignExtendedNumber SignExtendedNumber::operator+(const SignExtendedNumber& a) co
else if (negative)
return SignExtendedNumber(carry ? sum : 0, true);
else
#if WANT_CENT
return SignExtendedNumber(carry ? UINT128_MAX : sum, false);
#else
return SignExtendedNumber(carry ? UINT64_MAX : sum, false);
#endif
}

SignExtendedNumber SignExtendedNumber::operator-(const SignExtendedNumber& a) const
Expand Down Expand Up @@ -114,7 +130,11 @@ SignExtendedNumber SignExtendedNumber::operator*(const SignExtendedNumber& a) co
uinteger_t tAbs = copySign(value, negative);
uinteger_t aAbs = copySign(a.value, a.negative);
rv.negative = negative != a.negative;
#if WANT_CENT
if (UINT128_MAX / tAbs < aAbs)
#else
if (UINT64_MAX / tAbs < aAbs)
#endif
rv.value = rv.negative-1;
else
rv.value = copySign(tAbs * aAbs, rv.negative);
Expand Down Expand Up @@ -145,20 +165,34 @@ SignExtendedNumber SignExtendedNumber::operator/(const SignExtendedNumber& a) co
// Special handling for INT65_MIN
// if the denominator is not a power of 2, it is same as UINT64_MAX / x.
else if (aAbs & (aAbs-1))
#if WANT_CENT
rvVal = UINT128_MAX / aAbs;
#else
rvVal = UINT64_MAX / aAbs;
#endif
// otherwise, it's the same as reversing the bits of x.
else
{
if (aAbs == 1)
return extreme(!a.negative);
rvVal = 1ULL << 63;
aAbs >>= 1;
#if WANT_CENT
if (aAbs & UINT128C(0xAAAAAAAAAAAAAAAAULL, 0xAAAAAAAAAAAAAAAA)) rvVal >>= 1;
if (aAbs & UINT128C(0xCCCCCCCCCCCCCCCCULL, 0xCCCCCCCCCCCCCCCC)) rvVal >>= 2;
if (aAbs & UINT128C(0xF0F0F0F0F0F0F0F0ULL, 0xF0F0F0F0F0F0F0F0)) rvVal >>= 4;
if (aAbs & UINT128C(0xFF00FF00FF00FF00ULL, 0xFF00FF00FF00FF00)) rvVal >>= 8;
if (aAbs & UINT128C(0xFFFF0000FFFF0000ULL, 0xFFFF0000FFFF0000)) rvVal >>= 16;
if (aAbs & UINT128C(0xFFFFFFFF00000000ULL, 0xFFFFFFFF00000000)) rvVal >>= 32;
if (aAbs & UINT128C(0xFFFFFFFFFFFFFFFFULL, 0x0000000000000000)) rvVal >>= 64;
#else
if (aAbs & 0xAAAAAAAAAAAAAAAAULL) rvVal >>= 1;
if (aAbs & 0xCCCCCCCCCCCCCCCCULL) rvVal >>= 2;
if (aAbs & 0xF0F0F0F0F0F0F0F0ULL) rvVal >>= 4;
if (aAbs & 0xFF00FF00FF00FF00ULL) rvVal >>= 8;
if (aAbs & 0xFFFF0000FFFF0000ULL) rvVal >>= 16;
if (aAbs & 0xFFFFFFFF00000000ULL) rvVal >>= 32;
#endif
}
bool rvNeg = negative != a.negative;
rvVal = copySign(rvVal, rvNeg);
Expand All @@ -180,7 +214,11 @@ SignExtendedNumber SignExtendedNumber::operator%(const SignExtendedNumber& a) co
// Special handling for INT65_MIN
// if the denominator is not a power of 2, it is same as UINT64_MAX%x + 1.
else if (aAbs & (aAbs - 1))
#if WANT_CENT
rvVal = UINT128_MAX % aAbs + 1;
#else
rvVal = UINT64_MAX % aAbs + 1;
#endif
// otherwise, the modulus is trivially zero.
else
rvVal = 0;
Expand All @@ -191,7 +229,11 @@ SignExtendedNumber SignExtendedNumber::operator%(const SignExtendedNumber& a) co

SignExtendedNumber& SignExtendedNumber::operator++()
{
#if WANT_CENT
if (value != UINT128_MAX)
#else
if (value != UINT64_MAX)
#endif
++ value;
else if (negative)
{
Expand All @@ -218,14 +260,23 @@ SignExtendedNumber SignExtendedNumber::operator<<(const SignExtendedNumber& a) c
// Why is this a size_t? Looks like a bug.
size_t r, s;

#if WANT_CENT
r = (v > 0xFFFFFFFFFFFFFFFFULL) << 6; v >>= r;
r = (v > 0xFFFFFFFFULL) << 5; v >>= r; r |= s;
#else
r = (v > 0xFFFFFFFFULL) << 5; v >>= r;
#endif
s = (v > 0xFFFFULL ) << 4; v >>= s; r |= s;
s = (v > 0xFFULL ) << 3; v >>= s; r |= s;
s = (v > 0xFULL ) << 2; v >>= s; r |= s;
s = (v > 0x3ULL ) << 1; v >>= s; r |= s;
r |= (v >> 1);

#if WANT_CEMT
uinteger_t allowableShift = 127 - r;
#else
uinteger_t allowableShift = 63 - r;
#endif
if (a.value > allowableShift)
return extreme(negative);
else
Expand All @@ -234,10 +285,17 @@ SignExtendedNumber SignExtendedNumber::operator<<(const SignExtendedNumber& a) c

SignExtendedNumber SignExtendedNumber::operator>>(const SignExtendedNumber& a) const
{
#if WANT_CENT
if (a.negative || a.value > 128)
return negative ? SignExtendedNumber(-1, true) : SignExtendedNumber(0);
else if (isMinimum())
return a.value == 0 ? *this : SignExtendedNumber(-1ULL << (128-a.value), true);
#else
if (a.negative || a.value > 64)
return negative ? SignExtendedNumber(-1, true) : SignExtendedNumber(0);
else if (isMinimum())
return a.value == 0 ? *this : SignExtendedNumber(-1ULL << (64-a.value), true);
#endif

uinteger_t x = value ^ -negative;
x >>= a.value;
Expand Down Expand Up @@ -400,8 +458,13 @@ IntRange& IntRange::cast(Type *type)

IntRange& IntRange::castUnsigned(Type *type)
{
#if WANT_CENT
if (!type->isintegral())
return castUnsigned(UINT128_MAX);
#else
if (!type->isintegral())
return castUnsigned(UINT64_MAX);
#endif
else if (type->toBasetype()->ty == Tdchar)
return castDchar();
else
Expand Down
Loading