1 /** rotation of bit-precise integers
3 width: 2, 4, 6, 7, 8, 9, 15, 16, 17, 24, 32, 33, 40, 48, 63, 64, 65
4 dist: 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 20, 32
12 // clang 11 supports bit-precise types, but deviates a bit from C23.
13 #if __clang_major__ == 11
14 #define __SDCC_BITINT_MAXWIDTH 128
15 #define _BitInt _ExtInt
18 #if __SDCC_BITINT_MAXWIDTH >= {width} && ({width} <= 8 || !defined(__SDCC_pdk14)) && ({width} <= 16 || !defined(__SDCC_pdk15)) // Lack of memory for pdk. TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
19 typedef unsigned _BitInt({width
}) bitinttype
;
22 typedef unsigned int bitinttype
;
23 #define WIDTH (sizeof(unsigned int) * CHAR_BIT)
26 #define DIST ({dist} % WIDTH)
27 #define ROL(a) ((a << DIST) | (a >> ((WIDTH - DIST) % WIDTH))) // Rotate left
28 #define ROR(a) ((a >> DIST) | (a << ((WIDTH - DIST) % WIDTH))) // Rotate right
29 #define NROL(a) ((a << 8) | (a >> ((WIDTH - DIST) % WIDTH))) // Nearly a rotation, was sometimes assumed to be a real one by optimizations though (e.g. for WIDTH == 15, DIST == 8).
30 #define NROL2(a) ((a >> 8) | (a << ((WIDTH - DIST) % WIDTH))) // Nearly a rotation, was sometimes assumed to be a real one by optimizations though (e.g. for WIDTH == 15, DIST == 8).
32 #define TESTVECT1 ((bitinttype)0xa5)
33 #define TESTVECT2 ((bitinttype)0xaa55)
38 volatile {storage
} bitinttype t1
= TESTVECT1
;
39 volatile {storage
} bitinttype t2
= TESTVECT2
;
41 ASSERT (ROL (t1
) == ROL (TESTVECT1
));
42 ASSERT (ROL (t2
) == ROL (TESTVECT2
));
43 ASSERT (ROR (t1
) == ROR (TESTVECT1
));
44 ASSERT (ROR (t2
) == ROR (TESTVECT2
));
45 ASSERT (NROL (t1
) == NROL (TESTVECT1
));
46 ASSERT (NROL (t2
) == NROL (TESTVECT2
));
47 ASSERT (NROL2 (t1
) == NROL2 (TESTVECT1
));
48 ASSERT (NROL2 (t2
) == NROL2 (TESTVECT2
));
52 ASSERT (t1
== ROL (TESTVECT1
));
53 ASSERT (t2
== ROL (TESTVECT2
));
57 ASSERT (t1
== TESTVECT1
);
58 ASSERT (t2
== TESTVECT2
);