1 /** bit-precise integers
3 width: 2, 4, 6, 7, 8, 9, 15, 16, 17, 24, 32, 33, 40, 48, 63, 64, 65
11 // clang 11 supports bit-precise types, but deviates a bit from C23.
12 #if __clang_major__ == 11
13 #define __SDCC_BITINT_MAXWIDTH 128
14 #define _BitInt _ExtInt
17 #if __SDCC_BITINT_MAXWIDTH >= {width} // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
19 typedef {sign
} _BitInt({width
}) bitinttype
;
21 bitinttype
f(void) // The backend needs to support returning types of arbitrary width, not just powers of two.
26 bitinttype
g(bitinttype a
) // The backend needs to support parameters of arbitrary width, not just powers of two.
34 volatile long long ll
= 42;
38 #if __SDCC_BITINT_MAXWIDTH >= {width} // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
39 ASSERT(f() == (bitinttype
)42);
40 ASSERT(g(0) == (bitinttype
)1);
42 #ifndef __clang_major__ // clang 11 does not yet support addition of _BitInt of different width
43 #if __SDCC_BITINT_MAXWIDTH >= 4 // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
44 ASSERT(_Generic((_BitInt(4))(4) + (_BitInt(6))(6), default: 1, _BitInt(6): 0) == 0); // _BitInt does not promote to int, even when narrower than int.
45 //BUG! SDCC makes 6 char instead of int! ASSERT(_Generic((_BitInt(4))(4) + 6, default: 1, int: 0) == 0); // But it does promote to int when the other operand is int.
46 //BUG! SDCC makes 6 char instead of int! ASSERT(_Generic((_BitInt(CHAR_BIT * sizeof(int)))(4) + 6, default: 1, int: 0) == 0); // Even when both are the same size.
48 ASSERT(_Generic((_BitInt(4))(4) + (_BitInt(6))(300), default: 1, _BitInt(6): 0) == 0); // _BitInt does not promote to int, even when narrower than int.
49 ASSERT(_Generic((_BitInt(4))(4) + 300, default: 1, int: 0) == 0); // But it does promote to int when the other operand is int.
50 #if __SDCC_BITINT_MAXWIDTH >= 32 // 32 should work on most platforms, including hosts with 32-bit int // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
51 ASSERT(_Generic((_BitInt(CHAR_BIT
* sizeof(int)))(4) + 300, default: 1, int: 0) == 0); // Even when both are the same size.
57 ASSERT(_Generic(++b
, default: 1, bitinttype
: 0) == 0); // ++a is not the same a += 1, but a += (bitinttype)1.
60 ASSERT((bitinttype
)i
== (bitinttype
)42); // Explicit cast
61 b
= i
; // Implicit cast
62 ASSERT(b
== (bitinttype
)42);
64 b
= i
; // Implicit cast
65 ASSERT(b
== (bitinttype
)-23);
67 // Cast from long long
68 ASSERT((bitinttype
)ll
== (bitinttype
)42); // Explicit cast
69 b
= ll
; // Implicit cast
70 ASSERT(b
== (bitinttype
)42);
72 // Casts between bit-precise types
75 unsigned _BitInt(6) b6
= b
;
76 ASSERT((unsigned _BitInt(6))((bitinttype
)0x5aff) == b6
); // Bug #3371 - both casts are done at compile time, results were different - left cast done on ast (ok), right on iCode (wrong on FreeBSD13 on aarch64).
78 ASSERT((bitinttype
)b6
== (bitinttype
)(unsigned _BitInt(6))0x5aff);