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