* src/SDCCcse.c (ReplaceOpWithCheaperOp): minor fix for debugging only
[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 struct {
89   signed int s0_7  : 7;
90   signed int s7_1  : 1;
91   signed int s8_9  : 9;
92 } s_bf;
93
94
95 void
96 testBitfieldSizeof(void)
97 {
98   /* Although bitfields are extremely implementation dependant, these
99      assertions should hold for all implementations with storage units
100      of 8 bits or larger (nearly universal).
101   */
102   ASSERT( sizeof(size1a_bf) >= 1);
103   ASSERT( sizeof(size1b_bf) >= 1);
104   ASSERT( sizeof(size1c_bf) >= 1);
105 #if !defined (__amd64__) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
106   /* assertion fails on amd64, cygwin and mingw.
107      Maybe it depends on gcc version?
108   */
109   ASSERT( sizeof(size2a_bf) >= 2);
110 #endif
111   ASSERT( sizeof(size2b_bf) >= 2);
112   ASSERT( sizeof(size2c_bf) >= 2);
113   ASSERT( sizeof(size2d_bf) >= 2);
114   ASSERT( sizeof(size3a_bf) >= 2);
115   ASSERT( sizeof(size1a_bf) <= sizeof(size1b_bf));
116 #if !defined (__amd64__) && !defined(__CYGWIN32__) && !defined(__MINGW32__)
117   /* assertion fails on amd64, cygwin and mingw.
118      Maybe it depends on gcc version?
119    */
120   ASSERT( sizeof(size1a_bf) < sizeof(size2a_bf));
121 #endif
122
123   /* Some SDCC specific assertions. SDCC uses 8 bit storage units.
124      Bitfields that are less than 8 bits, but would (due to earlier
125      bitfield declarations) span a storage unit boundary are
126      realigned to the next storage unit boundary. Bitfields of
127      8 or greater bits are always aligned to start on a storage
128      unit boundary.
129   */
130 #ifdef SDCC
131   ASSERT( sizeof(size1a_bf) == 1);
132   ASSERT( sizeof(size1b_bf) == 1);
133   ASSERT( sizeof(size1c_bf) == 1);
134   ASSERT( sizeof(size2a_bf) == 2);
135   ASSERT( sizeof(size2b_bf) == 2);
136   ASSERT( sizeof(size2c_bf) == 2);
137   ASSERT( sizeof(size2d_bf) == 2);
138   ASSERT( sizeof(size3a_bf) == 3);
139 #endif
140 }
141
142
143 void
144 testBitfieldsSingleBitLiteral(void)
145 {
146   size2b_bf.b0 = 0; 
147   size2b_bf.b1 = 0; 
148   size2b_bf.b2 = 0; 
149   size2b_bf.b3 = 0; 
150   size2b_bf.b4 = 0; 
151   size2b_bf.b5 = 0; 
152   size2b_bf.b6 = 0; 
153   size2b_bf.b7 = 0; 
154   size2b_bf.b8 = 0; 
155   size2b_bf.b9 = 0; 
156
157   /* make sure modulo 2 truncation works */
158   size2b_bf.b0 = 0x3fe;
159   ASSERT(size2b_bf.b0==0);
160   ASSERT(size2b_bf.b1==0);
161   ASSERT(size2b_bf.b2==0);
162   ASSERT(size2b_bf.b3==0);
163   ASSERT(size2b_bf.b4==0);
164   ASSERT(size2b_bf.b5==0);
165   ASSERT(size2b_bf.b6==0);
166   ASSERT(size2b_bf.b7==0);
167   ASSERT(size2b_bf.b8==0);
168   ASSERT(size2b_bf.b9==0);
169   size2b_bf.b0 = 0x3ff;
170   ASSERT(size2b_bf.b0==1);
171   ASSERT(size2b_bf.b1==0);
172   ASSERT(size2b_bf.b2==0);
173   ASSERT(size2b_bf.b3==0);
174   ASSERT(size2b_bf.b4==0);
175   ASSERT(size2b_bf.b5==0);
176   ASSERT(size2b_bf.b6==0);
177   ASSERT(size2b_bf.b7==0);
178   ASSERT(size2b_bf.b8==0);
179   ASSERT(size2b_bf.b9==0);
180
181   /* make sure both bytes work */
182   size2b_bf.b9 = 0x3ff;
183   ASSERT(size2b_bf.b0==1);
184   ASSERT(size2b_bf.b1==0);
185   ASSERT(size2b_bf.b2==0);
186   ASSERT(size2b_bf.b3==0);
187   ASSERT(size2b_bf.b4==0);
188   ASSERT(size2b_bf.b5==0);
189   ASSERT(size2b_bf.b6==0);
190   ASSERT(size2b_bf.b7==0);
191   ASSERT(size2b_bf.b8==0);
192   ASSERT(size2b_bf.b9==1);
193 }
194
195 void
196 testBitfieldsSingleBit(void)
197 {
198   volatile unsigned char c;
199
200   c = 0;
201   size2b_bf.b0 = c; 
202   size2b_bf.b1 = c; 
203   size2b_bf.b2 = c; 
204   size2b_bf.b3 = c; 
205   size2b_bf.b4 = c; 
206   size2b_bf.b5 = c; 
207   size2b_bf.b6 = c; 
208   size2b_bf.b7 = c; 
209   size2b_bf.b8 = c; 
210   size2b_bf.b9 = c; 
211
212   /* make sure modulo 2 truncation works */
213   c = 0xfe;
214   size2b_bf.b0 = c;
215   ASSERT(size2b_bf.b0==0);
216   ASSERT(size2b_bf.b1==0);
217   ASSERT(size2b_bf.b2==0);
218   ASSERT(size2b_bf.b3==0);
219   ASSERT(size2b_bf.b4==0);
220   ASSERT(size2b_bf.b5==0);
221   ASSERT(size2b_bf.b6==0);
222   ASSERT(size2b_bf.b7==0);
223   ASSERT(size2b_bf.b8==0);
224   ASSERT(size2b_bf.b9==0);
225   c++;
226   size2b_bf.b0 = c;
227   ASSERT(size2b_bf.b0==1);
228   ASSERT(size2b_bf.b1==0);
229   ASSERT(size2b_bf.b2==0);
230   ASSERT(size2b_bf.b3==0);
231   ASSERT(size2b_bf.b4==0);
232   ASSERT(size2b_bf.b5==0);
233   ASSERT(size2b_bf.b6==0);
234   ASSERT(size2b_bf.b7==0);
235   ASSERT(size2b_bf.b8==0);
236   ASSERT(size2b_bf.b9==0);
237
238   /* make sure both bytes work */
239   size2b_bf.b9 = c;
240   ASSERT(size2b_bf.b0==1);
241   ASSERT(size2b_bf.b1==0);
242   ASSERT(size2b_bf.b2==0);
243   ASSERT(size2b_bf.b3==0);
244   ASSERT(size2b_bf.b4==0);
245   ASSERT(size2b_bf.b5==0);
246   ASSERT(size2b_bf.b6==0);
247   ASSERT(size2b_bf.b7==0);
248   ASSERT(size2b_bf.b8==0);
249   ASSERT(size2b_bf.b9==1);
250 }
251
252 void
253 testBitfieldsMultibitLiteral(void)
254 {
255   size2c_bf.b0 = 0xff;  /* should truncate to 0x0f */
256   size2c_bf.b1 = 0;
257   ASSERT(size2c_bf.b0==0x0f);
258   ASSERT(size2c_bf.b1==0);
259
260   size2c_bf.b1 = 0xff;  /* should truncate to 0x1f */
261   size2c_bf.b0 = 0;
262   ASSERT(size2c_bf.b0==0);
263   ASSERT(size2c_bf.b1==0x1f);
264
265   size2c_bf.b0 = 0xff;  /* should truncate to 0x0f */
266   size2c_bf.b1 = 0xff;  /* should truncate to 0x1f */
267   ASSERT(size2c_bf.b0==0x0f);
268   ASSERT(size2c_bf.b1==0x1f);
269
270   size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
271   size2d_bf.b1 = 0;
272   ASSERT(size2d_bf.b0==0x0fff);
273   ASSERT(size2d_bf.b1==0);
274
275   size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
276   size2d_bf.b0 = 0;
277   ASSERT(size2d_bf.b0==0);
278   ASSERT(size2d_bf.b1==0x07);
279
280   size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
281   size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
282   ASSERT(size2d_bf.b0==0x0fff);
283   ASSERT(size2d_bf.b1==0x07);
284
285   size2d_bf.b0 = 0x0321;
286   size2d_bf.b1 = 1;
287   ASSERT(size2d_bf.b0==0x0321);
288   ASSERT(size2d_bf.b1==1);
289
290   size2d_bf.b0 = 0x0a46;
291   size2d_bf.b1 = 5;
292   ASSERT(size2d_bf.b0==0x0a46);
293   ASSERT(size2d_bf.b1==5);
294 }
295
296 void
297 testBitfieldsMultibit(void)
298 {
299   volatile int allones = 0xffff;
300   volatile int zero = 0;
301   volatile int x;
302   
303   size2c_bf.b0 = allones;       /* should truncate to 0x0f */
304   size2c_bf.b1 = zero;
305   ASSERT(size2c_bf.b0==0x0f);
306   ASSERT(size2c_bf.b1==0);
307
308   size2c_bf.b1 = allones;       /* should truncate to 0x1f */
309   size2c_bf.b0 = zero;
310   ASSERT(size2c_bf.b0==0);
311   ASSERT(size2c_bf.b1==0x1f);
312
313   size2d_bf.b0 = allones; /* should truncate to 0x0fff */
314   size2d_bf.b1 = zero;
315   ASSERT(size2d_bf.b0==0x0fff);
316   ASSERT(size2d_bf.b1==0);
317
318   size2d_bf.b1 = allones; /* should truncate to 0x07 */
319   size2d_bf.b0 = zero;
320   ASSERT(size2d_bf.b0==0);
321   ASSERT(size2d_bf.b1==0x07);
322
323   x = 0x0321;
324   size2d_bf.b0 = x;
325   x = 1;
326   size2d_bf.b1 = x;
327   ASSERT(size2d_bf.b0==0x0321);
328   ASSERT(size2d_bf.b1==1);
329
330   x = 0x0a46;
331   size2d_bf.b0 = x;
332   x = 5;
333   size2d_bf.b1 = x;
334   ASSERT(size2d_bf.b0==0x0a46);
335   ASSERT(size2d_bf.b1==5);
336 }
337
338 void
339 testBitfields(void)
340 {
341   c_bf.c0_3 = 2;
342   c_bf.c3_5 = 3;
343   ASSERT(*(char *)(&c_bf) == (2 + (3<<3)) );
344
345 #if 0 // not yet
346   i_bf.i0_7 = 23;
347   i_bf.i7_9 = 234;
348   ASSERT(*(int *)(&i_bf) == (23 + (234<<7)) );
349
350   l_bitfield.l0_7 = 23;
351   l_bitfield.l7_10 = 234;
352   l_bitfield.l17_15 = 2345;
353   ASSERT(*(long *)(&l_bf) == (23 + (234<<7) + (2345<<17)) );
354 #endif
355 }
356
357 void
358 testSignedBitfields(void)
359 {
360 #if !defined(SDCC_hc08) && !defined(SDCC_z80) && !defined(SDCC_gbz80)
361   s_bf.s0_7 =   0xf0;
362   s_bf.s7_1 =      1;
363   s_bf.s8_9 = 0xfff8;
364   ASSERT(s_bf.s0_7 == -16);
365   ASSERT(s_bf.s7_1 == - 1);
366   ASSERT(s_bf.s8_9 == - 8);
367   ASSERT(s_bf.s0_7 < 0);
368   ASSERT(s_bf.s7_1 < 0);
369   ASSERT(s_bf.s8_9 < 0);
370
371   s_bf.s0_7 =   0x3f;
372   s_bf.s7_1 =      2;
373   s_bf.s8_9 = 0x00ff;
374   ASSERT(s_bf.s0_7 == 0x3f);
375   ASSERT(s_bf.s7_1 ==    0);
376   ASSERT(s_bf.s8_9 == 0xff);
377   ASSERT(s_bf.s0_7 > 0);
378   ASSERT(s_bf.s8_9 > 0);
379 #endif
380 }