@@ -25,15 +25,23 @@ static uinteger_t copySign(uinteger_t x, bool sign)
2525 return (x - (uinteger_t )sign ) ^ - (uinteger_t )sign ;
2626}
2727
28+ #if WANT_CENT
29+ #define UINT128_MAX UINT128C(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)
30+ #else
2831#ifndef UINT64_MAX
2932#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
3033#endif
34+ #endif
3135
3236//==================== SignExtendedNumber ======================================
3337
3438SignExtendedNumber SignExtendedNumber ::fromInteger (uinteger_t value_ )
3539{
40+ #if WANT_CENT
41+ return SignExtendedNumber (value_ , value_ >> 128 );
42+ #else
3643 return SignExtendedNumber (value_ , value_ >> 63 );
44+ #endif
3745}
3846
3947bool SignExtendedNumber ::operator == (const SignExtendedNumber & a ) const
@@ -54,7 +62,11 @@ SignExtendedNumber SignExtendedNumber::extreme(bool minimum)
5462
5563SignExtendedNumber SignExtendedNumber ::max ()
5664{
65+ #if WANT_CENT
66+ return SignExtendedNumber (UINT128_MAX , false);
67+ #else
5768 return SignExtendedNumber (UINT64_MAX , false);
69+ #endif
5870}
5971
6072SignExtendedNumber SignExtendedNumber ::operator - () const
@@ -74,7 +86,11 @@ SignExtendedNumber SignExtendedNumber::operator+(const SignExtendedNumber& a) co
7486 else if (negative )
7587 return SignExtendedNumber (carry ? sum : 0 , true);
7688 else
89+ #if WANT_CENT
90+ return SignExtendedNumber (carry ? UINT128_MAX : sum , false);
91+ #else
7792 return SignExtendedNumber (carry ? UINT64_MAX : sum , false);
93+ #endif
7894}
7995
8096SignExtendedNumber SignExtendedNumber ::operator - (const SignExtendedNumber & a ) const
@@ -114,7 +130,11 @@ SignExtendedNumber SignExtendedNumber::operator*(const SignExtendedNumber& a) co
114130 uinteger_t tAbs = copySign (value , negative );
115131 uinteger_t aAbs = copySign (a .value , a .negative );
116132 rv .negative = negative != a .negative ;
133+ #if WANT_CENT
134+ if (UINT128_MAX / tAbs < aAbs )
135+ #else
117136 if (UINT64_MAX / tAbs < aAbs )
137+ #endif
118138 rv .value = rv .negative - 1 ;
119139 else
120140 rv .value = copySign (tAbs * aAbs , rv .negative );
@@ -145,20 +165,34 @@ SignExtendedNumber SignExtendedNumber::operator/(const SignExtendedNumber& a) co
145165 // Special handling for INT65_MIN
146166 // if the denominator is not a power of 2, it is same as UINT64_MAX / x.
147167 else if (aAbs & (aAbs - 1 ))
168+ #if WANT_CENT
169+ rvVal = UINT128_MAX / aAbs ;
170+ #else
148171 rvVal = UINT64_MAX / aAbs ;
172+ #endif
149173 // otherwise, it's the same as reversing the bits of x.
150174 else
151175 {
152176 if (aAbs == 1 )
153177 return extreme (!a .negative );
154178 rvVal = 1ULL << 63 ;
155179 aAbs >>= 1 ;
180+ #if WANT_CENT
181+ if (aAbs & UINT128C (0xAAAAAAAAAAAAAAAAULL , 0xAAAAAAAAAAAAAAAA )) rvVal >>= 1 ;
182+ if (aAbs & UINT128C (0xCCCCCCCCCCCCCCCCULL , 0xCCCCCCCCCCCCCCCC )) rvVal >>= 2 ;
183+ if (aAbs & UINT128C (0xF0F0F0F0F0F0F0F0ULL , 0xF0F0F0F0F0F0F0F0 )) rvVal >>= 4 ;
184+ if (aAbs & UINT128C (0xFF00FF00FF00FF00ULL , 0xFF00FF00FF00FF00 )) rvVal >>= 8 ;
185+ if (aAbs & UINT128C (0xFFFF0000FFFF0000ULL , 0xFFFF0000FFFF0000 )) rvVal >>= 16 ;
186+ if (aAbs & UINT128C (0xFFFFFFFF00000000ULL , 0xFFFFFFFF00000000 )) rvVal >>= 32 ;
187+ if (aAbs & UINT128C (0xFFFFFFFFFFFFFFFFULL , 0x0000000000000000 )) rvVal >>= 64 ;
188+ #else
156189 if (aAbs & 0xAAAAAAAAAAAAAAAAULL ) rvVal >>= 1 ;
157190 if (aAbs & 0xCCCCCCCCCCCCCCCCULL ) rvVal >>= 2 ;
158191 if (aAbs & 0xF0F0F0F0F0F0F0F0ULL ) rvVal >>= 4 ;
159192 if (aAbs & 0xFF00FF00FF00FF00ULL ) rvVal >>= 8 ;
160193 if (aAbs & 0xFFFF0000FFFF0000ULL ) rvVal >>= 16 ;
161194 if (aAbs & 0xFFFFFFFF00000000ULL ) rvVal >>= 32 ;
195+ #endif
162196 }
163197 bool rvNeg = negative != a .negative ;
164198 rvVal = copySign (rvVal , rvNeg );
@@ -180,7 +214,11 @@ SignExtendedNumber SignExtendedNumber::operator%(const SignExtendedNumber& a) co
180214 // Special handling for INT65_MIN
181215 // if the denominator is not a power of 2, it is same as UINT64_MAX%x + 1.
182216 else if (aAbs & (aAbs - 1 ))
217+ #if WANT_CENT
218+ rvVal = UINT128_MAX % aAbs + 1 ;
219+ #else
183220 rvVal = UINT64_MAX % aAbs + 1 ;
221+ #endif
184222 // otherwise, the modulus is trivially zero.
185223 else
186224 rvVal = 0 ;
@@ -191,7 +229,11 @@ SignExtendedNumber SignExtendedNumber::operator%(const SignExtendedNumber& a) co
191229
192230SignExtendedNumber & SignExtendedNumber ::operator ++ ()
193231{
232+ #if WANT_CENT
233+ if (value != UINT128_MAX )
234+ #else
194235 if (value != UINT64_MAX )
236+ #endif
195237 ++ value ;
196238 else if (negative )
197239 {
@@ -218,14 +260,23 @@ SignExtendedNumber SignExtendedNumber::operator<<(const SignExtendedNumber& a) c
218260 // Why is this a size_t? Looks like a bug.
219261 size_t r , s ;
220262
263+ #if WANT_CENT
264+ r = (v > 0xFFFFFFFFFFFFFFFFULL ) << 6 ; v >>= r ;
265+ r = (v > 0xFFFFFFFFULL ) << 5 ; v >>= r ; r |= s ;
266+ #else
221267 r = (v > 0xFFFFFFFFULL ) << 5 ; v >>= r ;
268+ #endif
222269 s = (v > 0xFFFFULL ) << 4 ; v >>= s ; r |= s ;
223270 s = (v > 0xFFULL ) << 3 ; v >>= s ; r |= s ;
224271 s = (v > 0xFULL ) << 2 ; v >>= s ; r |= s ;
225272 s = (v > 0x3ULL ) << 1 ; v >>= s ; r |= s ;
226273 r |= (v >> 1 );
227274
275+ #if WANT_CEMT
276+ uinteger_t allowableShift = 127 - r ;
277+ #else
228278 uinteger_t allowableShift = 63 - r ;
279+ #endif
229280 if (a .value > allowableShift )
230281 return extreme (negative );
231282 else
@@ -234,10 +285,17 @@ SignExtendedNumber SignExtendedNumber::operator<<(const SignExtendedNumber& a) c
234285
235286SignExtendedNumber SignExtendedNumber ::operator >>(const SignExtendedNumber & a ) const
236287{
288+ #if WANT_CENT
289+ if (a .negative || a .value > 128 )
290+ return negative ? SignExtendedNumber (-1 , true) : SignExtendedNumber (0 );
291+ else if (isMinimum ())
292+ return a .value == 0 ? * this : SignExtendedNumber (-1ULL << (128 - a .value ), true);
293+ #else
237294 if (a .negative || a .value > 64 )
238295 return negative ? SignExtendedNumber (-1 , true) : SignExtendedNumber (0 );
239296 else if (isMinimum ())
240297 return a .value == 0 ? * this : SignExtendedNumber (-1ULL << (64 - a .value ), true);
298+ #endif
241299
242300 uinteger_t x = value ^ - negative ;
243301 x >>= a .value ;
@@ -400,8 +458,13 @@ IntRange& IntRange::cast(Type *type)
400458
401459IntRange & IntRange ::castUnsigned (Type * type )
402460{
461+ #if WANT_CENT
462+ if (!type -> isintegral ())
463+ return castUnsigned (UINT128_MAX );
464+ #else
403465 if (!type -> isintegral ())
404466 return castUnsigned (UINT64_MAX );
467+ #endif
405468 else if (type -> toBasetype ()-> ty == Tdchar )
406469 return castDchar ();
407470 else
0 commit comments