9328fa95138fc417d042a5d76bed617afb971b05
[fw/sdcc] / support / regression / tests / bitfields.c
1 /** Bitfield tests.
2
3 */
4 #include <testfwk.h>
5
6 struct {
7   char c0_3 : 3;
8   char c3_5 : 5;
9 } c_bf;
10
11 struct {
12   int i0_7 : 7;
13   int i7_9 : 9;
14 } i_bf;
15
16 struct {
17   long l0_7 : 7;
18   long l7_10 : 10;
19   long l17_15 : 15;
20 } l_bf;
21
22
23 struct {
24   unsigned int b0 : 1;
25   unsigned int b1 : 1;
26   unsigned int b2 : 1;
27   unsigned int b3 : 1;
28   unsigned int b4 : 1;
29   unsigned int b5 : 1;
30   unsigned int b6 : 1;
31   unsigned int b7 : 1;
32   unsigned int b8 : 1;
33   unsigned int b9 : 1;
34 } sb_bf;
35
36 struct {
37   unsigned int b0 : 1;
38   unsigned int b2 : 1;
39 } size1a_bf;
40
41 struct {
42   unsigned int b0 : 1;
43   unsigned int b1 : 1;
44   unsigned int    : 0;
45 } size1b_bf;
46
47 struct {
48   unsigned int b0 : 1;
49   unsigned int b1 : 1;
50   unsigned int b2 : 6;
51 } size1c_bf;
52
53 struct {
54   unsigned int b0 : 1;
55   unsigned int    : 0;
56   unsigned int b1 : 1;
57 } size2a_bf;
58
59 struct {
60   unsigned int b0 : 1;
61   unsigned int b1 : 1;
62   unsigned int b2 : 1;
63   unsigned int b3 : 1;
64   unsigned int b4 : 1;
65   unsigned int b5 : 1;
66   unsigned int b6 : 1;
67   unsigned int b7 : 1;
68   unsigned int b8 : 1;
69   unsigned int b9 : 1;
70 } size2b_bf;
71
72 struct {
73   unsigned int b0 : 4;
74   unsigned int b1 : 5;
75 } size2c_bf;
76
77 struct {
78   unsigned int b0 : 12;
79   unsigned int b1 : 3;
80 } size2d_bf;
81
82 struct {
83   unsigned int b0 : 3;
84   unsigned int b1 : 12;
85 } size3a_bf;
86
87
88 void
89 testBitfieldSizeof(void)
90 {
91   /* Although bitfields are extremely implementation dependant, these
92      assertions should hold for all implementations with storage units
93      of 8 bits or larger (nearly universal).
94   */
95   ASSERT( sizeof(size1a_bf) >= 1);
96   ASSERT( sizeof(size1b_bf) >= 1);
97   ASSERT( sizeof(size1c_bf) >= 1);
98 #if !defined (__amd64__) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
99   /* assertion fails on amd64, cygwin and mingw.
100      Maybe it depends on gcc version?
101   */
102   ASSERT( sizeof(size2a_bf) >= 2);
103 #endif
104   ASSERT( sizeof(size2b_bf) >= 2);
105   ASSERT( sizeof(size2c_bf) >= 2);
106   ASSERT( sizeof(size2d_bf) >= 2);
107   ASSERT( sizeof(size3a_bf) >= 2);
108   ASSERT( sizeof(size1a_bf) <= sizeof(size1b_bf));
109 #if !defined (__amd64__) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
110   /* assertion fails on amd64, cygwin and mingw.
111      Maybe it depends on gcc version?
112    */
113   ASSERT( sizeof(size1a_bf) < sizeof(size2a_bf));
114 #endif
115
116   /* Some SDCC specific assertions. SDCC uses 8 bit storage units.
117      Bitfields that are less than 8 bits, but would (due to earlier
118      bitfield declarations) span a storage unit boundary are
119      realigned to the next storage unit boundary. Bitfields of
120      8 or greater bits are always aligned to start on a storage
121      unit boundary.
122   */
123 #ifdef SDCC
124   ASSERT( sizeof(size1a_bf) == 1);
125   ASSERT( sizeof(size1b_bf) == 1);
126   ASSERT( sizeof(size1c_bf) == 1);
127   ASSERT( sizeof(size2a_bf) == 2);
128   ASSERT( sizeof(size2b_bf) == 2);
129   ASSERT( sizeof(size2c_bf) == 2);
130   ASSERT( sizeof(size2d_bf) == 2);
131   ASSERT( sizeof(size3a_bf) == 3);
132 #endif
133 }
134
135
136 void
137 testBitfieldsSingleBitLiteral(void)
138 {
139   size2b_bf.b0 = 0; 
140   size2b_bf.b1 = 0; 
141   size2b_bf.b2 = 0; 
142   size2b_bf.b3 = 0; 
143   size2b_bf.b4 = 0; 
144   size2b_bf.b5 = 0; 
145   size2b_bf.b6 = 0; 
146   size2b_bf.b7 = 0; 
147   size2b_bf.b8 = 0; 
148   size2b_bf.b9 = 0; 
149
150   /* make sure modulo 2 truncation works */
151   size2b_bf.b0 = 0x3fe;
152   ASSERT(size2b_bf.b0==0);
153   ASSERT(size2b_bf.b1==0);
154   ASSERT(size2b_bf.b2==0);
155   ASSERT(size2b_bf.b3==0);
156   ASSERT(size2b_bf.b4==0);
157   ASSERT(size2b_bf.b5==0);
158   ASSERT(size2b_bf.b6==0);
159   ASSERT(size2b_bf.b7==0);
160   ASSERT(size2b_bf.b8==0);
161   ASSERT(size2b_bf.b9==0);
162   size2b_bf.b0 = 0x3ff;
163   ASSERT(size2b_bf.b0==1);
164   ASSERT(size2b_bf.b1==0);
165   ASSERT(size2b_bf.b2==0);
166   ASSERT(size2b_bf.b3==0);
167   ASSERT(size2b_bf.b4==0);
168   ASSERT(size2b_bf.b5==0);
169   ASSERT(size2b_bf.b6==0);
170   ASSERT(size2b_bf.b7==0);
171   ASSERT(size2b_bf.b8==0);
172   ASSERT(size2b_bf.b9==0);
173
174   /* make sure both bytes work */
175   size2b_bf.b9 = 0x3ff;
176   ASSERT(size2b_bf.b0==1);
177   ASSERT(size2b_bf.b1==0);
178   ASSERT(size2b_bf.b2==0);
179   ASSERT(size2b_bf.b3==0);
180   ASSERT(size2b_bf.b4==0);
181   ASSERT(size2b_bf.b5==0);
182   ASSERT(size2b_bf.b6==0);
183   ASSERT(size2b_bf.b7==0);
184   ASSERT(size2b_bf.b8==0);
185   ASSERT(size2b_bf.b9==1);
186 }
187
188 void
189 testBitfieldsSingleBit(void)
190 {
191   volatile unsigned char c;
192
193   c = 0;
194   size2b_bf.b0 = c; 
195   size2b_bf.b1 = c; 
196   size2b_bf.b2 = c; 
197   size2b_bf.b3 = c; 
198   size2b_bf.b4 = c; 
199   size2b_bf.b5 = c; 
200   size2b_bf.b6 = c; 
201   size2b_bf.b7 = c; 
202   size2b_bf.b8 = c; 
203   size2b_bf.b9 = c; 
204
205   /* make sure modulo 2 truncation works */
206   c = 0xfe;
207   size2b_bf.b0 = c;
208   ASSERT(size2b_bf.b0==0);
209   ASSERT(size2b_bf.b1==0);
210   ASSERT(size2b_bf.b2==0);
211   ASSERT(size2b_bf.b3==0);
212   ASSERT(size2b_bf.b4==0);
213   ASSERT(size2b_bf.b5==0);
214   ASSERT(size2b_bf.b6==0);
215   ASSERT(size2b_bf.b7==0);
216   ASSERT(size2b_bf.b8==0);
217   ASSERT(size2b_bf.b9==0);
218   c++;
219   size2b_bf.b0 = c;
220   ASSERT(size2b_bf.b0==1);
221   ASSERT(size2b_bf.b1==0);
222   ASSERT(size2b_bf.b2==0);
223   ASSERT(size2b_bf.b3==0);
224   ASSERT(size2b_bf.b4==0);
225   ASSERT(size2b_bf.b5==0);
226   ASSERT(size2b_bf.b6==0);
227   ASSERT(size2b_bf.b7==0);
228   ASSERT(size2b_bf.b8==0);
229   ASSERT(size2b_bf.b9==0);
230
231   /* make sure both bytes work */
232   size2b_bf.b9 = c;
233   ASSERT(size2b_bf.b0==1);
234   ASSERT(size2b_bf.b1==0);
235   ASSERT(size2b_bf.b2==0);
236   ASSERT(size2b_bf.b3==0);
237   ASSERT(size2b_bf.b4==0);
238   ASSERT(size2b_bf.b5==0);
239   ASSERT(size2b_bf.b6==0);
240   ASSERT(size2b_bf.b7==0);
241   ASSERT(size2b_bf.b8==0);
242   ASSERT(size2b_bf.b9==1);
243 }
244
245 void
246 testBitfieldsMultibitLiteral(void)
247 {
248   size2c_bf.b0 = 0xff;  /* should truncate to 0x0f */
249   size2c_bf.b1 = 0;
250   ASSERT(size2c_bf.b0==0x0f);
251   ASSERT(size2c_bf.b1==0);
252
253   size2c_bf.b1 = 0xff;  /* should truncate to 0x1f */
254   size2c_bf.b0 = 0;
255   ASSERT(size2c_bf.b0==0);
256   ASSERT(size2c_bf.b1==0x1f);
257
258   size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
259   size2d_bf.b1 = 0;
260   ASSERT(size2d_bf.b0==0x0fff);
261   ASSERT(size2d_bf.b1==0);
262
263   size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
264   size2d_bf.b0 = 0;
265   ASSERT(size2d_bf.b0==0);
266   ASSERT(size2d_bf.b1==0x07);
267
268   size2d_bf.b0 = 0x0321;
269   size2d_bf.b1 = 1;
270   ASSERT(size2d_bf.b0==0x0321);
271   ASSERT(size2d_bf.b1==1);
272
273   size2d_bf.b0 = 0x0a46;
274   size2d_bf.b1 = 5;
275   ASSERT(size2d_bf.b0==0x0a46);
276   ASSERT(size2d_bf.b1==5);
277 }
278
279 void
280 testBitfieldsMultibit(void)
281 {
282   volatile int allones = 0xffff;
283   volatile int zero = 0;
284   volatile int x;
285   
286   size2c_bf.b0 = allones;       /* should truncate to 0x0f */
287   size2c_bf.b1 = zero;
288   ASSERT(size2c_bf.b0==0x0f);
289   ASSERT(size2c_bf.b1==0);
290
291   size2c_bf.b1 = allones;       /* should truncate to 0x1f */
292   size2c_bf.b0 = zero;
293   ASSERT(size2c_bf.b0==0);
294   ASSERT(size2c_bf.b1==0x1f);
295
296   size2d_bf.b0 = allones; /* should truncate to 0x0fff */
297   size2d_bf.b1 = zero;
298   ASSERT(size2d_bf.b0==0x0fff);
299   ASSERT(size2d_bf.b1==0);
300
301   size2d_bf.b1 = allones; /* should truncate to 0x07 */
302   size2d_bf.b0 = zero;
303   ASSERT(size2d_bf.b0==0);
304   ASSERT(size2d_bf.b1==0x07);
305
306   x = 0x0321;
307   size2d_bf.b0 = x;
308   x = 1;
309   size2d_bf.b1 = x;
310   ASSERT(size2d_bf.b0==0x0321);
311   ASSERT(size2d_bf.b1==1);
312
313   x = 0x0a46;
314   size2d_bf.b0 = x;
315   x = 5;
316   size2d_bf.b1 = x;
317   ASSERT(size2d_bf.b0==0x0a46);
318   ASSERT(size2d_bf.b1==5);
319 }
320
321 void
322 testBitfields(void)
323 {
324 #if 0 // not yet
325   c_bitfield.c0_3 = 2;
326   c_bitfield.c3_5 = 3;
327   ASSERT(*(char *)(&c_bitfield) == (2 + (3<<3)) );
328
329   i_bitfield.i0_7 = 23;
330   i_bitfield.i7_9 = 234;
331   ASSERT(*(int *)(&i_bitfield) == (23 + (234<<7)) );
332
333   l_bitfield.l0_7 = 23;
334   l_bitfield.l7_10 = 234;
335   l_bitfield.l17_15 = 2345;
336   ASSERT(*(long *)(&l_bitfield) == (23 + (234<<7) + (2345<<17)) );
337 #endif
338 }