xref: /openbsd-src/gnu/usr.bin/gcc/gcc/testsuite/g++.old-deja/g++.abi/bitfields.C (revision c87b03e512fc05ed6e0222f6fb0ae86264b1d05b)
1 // Skip if not target: i?86-*-linux* i?86-*-freebsd*
2 // Special g++ Options: -malign-double
3 // Origin: Alex Samuel <samuel@codesourcery.com>
4 
5 /* Test the layout of bitfields in C aggretagtes for compliance with
6    the IA-64 ABI.  */
7 
8 #include <cstring>
9 
10 template<typename T>
11 inline unsigned
alignmentof()12 alignmentof ()
13 {
14   struct S
15   {
16     char start_;
17     T object_;
18   };
19 
20   return (unsigned) & ((S *) 0)->object_;
21 }
22 
23 /* Computes the alignment, in bytes, of TYPE.  */
24 
25 #define alignof(type) (alignmentof<type> ())
26 
27 /* Returns true iff all the bits in the range
28    START_BIT <= bit < START_BIT + NUM_BITS, and only those bits, are
29    set in the region of memory starting at BUF of LENGTH bytes.  */
30 
31 bool
check_bits(char * buf,unsigned length,unsigned start_bit,unsigned num_bits)32 check_bits (char *buf,
33 	    unsigned length,
34 	    unsigned start_bit,
35 	    unsigned num_bits)
36 {
37   for (unsigned bit = 0; bit < 8 * length; ++bit) {
38     bool is_set = (buf[bit / 8] & (1 << (bit % 8))) != 0;
39     if (start_bit <= bit && bit < start_bit + num_bits) {
40       if (! is_set)
41 	return false;
42     }
43     else {
44       if (is_set)
45 	return false;
46     }
47   }
48   return true;
49 }
50 
51 /* Creates a variable of type AGGREGATE, sets FIELD to -1, and
52    verifies that NUM_BITS bits starting at START_BIT, and no other
53    bits, are set.  If the check fails, returns with value RVAL.  */
54 
55 #define CHECK_FIELD(AGGREGATE, FIELD, START_BIT, NUM_BITS, RVAL)          \
56   do {                                                                    \
57     AGGREGATE a__;                                                        \
58     std::memset (& a__, 0, sizeof (a__));                                 \
59     a__.FIELD = -1;                                                       \
60     if (! check_bits ((char *) & a__, sizeof (a__), START_BIT, NUM_BITS)) \
61       return RVAL;                                                        \
62   } while (0);
63 
64 
65 
66 /* Structs S1, S2, S3, S4, and union U5 are taken from Intel, "IA-64
67    Software Conventions and Runtime Architecture Guide", version of
68    August 1999.  */
69 
70 struct S1
71 {
72   int       j : 5;
73   int       k : 6;
74   int       m : 7;
75 };
76 
77 #ifdef HAVE_IA64_TYPES
78 struct S2
79 {
80   short     s : 9;
81   __int64   j : 9;
82   char      c    ;
83   short     t : 9;
84   short     u : 9;
85   char      d    ;
86 };
87 #endif  /* HAVE_IA64_TYPES  */
88 
89 struct S3
90 {
91   char      c    ;
92   short     s : 8;
93 };
94 
95 union U4
96 {
97   char      c    ;
98   short     s : 8;
99 };
100 
101 struct S5
102 {
103   char      c    ;
104   int         : 0;
105   char      d    ;
106   short       : 9;
107   char      e    ;
108   char        : 0;
109 };
110 
111 
112 int
main()113 main ()
114 {
115   if (sizeof (struct S1)		!=  4)
116     return 1;
117   if (alignof (struct S1)		!=  4)
118     return 2;
119   CHECK_FIELD (S1, j,  0,  5,  3);
120   CHECK_FIELD (S1, k,  5,  6,  4);
121   CHECK_FIELD (S1, m, 11,  7,  5);
122 
123 #ifdef HAVE_IA64_TYPES
124   if (sizeof (struct S2)		!= 16)
125     return 6;
126   if (alignof (struct S2)		!=  8)
127     return 7;
128   CHECK_FIELD (S2, s,  0,  9,  8);
129   CHECK_FIELD (S2, j,  9,  9,  9);
130   CHECK_FIELD (S2, c, 24,  8, 10);
131   CHECK_FIELD (S2, t, 32,  9, 11);
132   CHECK_FIELD (S2, u, 48,  9, 12);
133   CHECK_FIELD (S2, d, 64,  8, 13);
134 #endif  /* HAVE_IA64_TYPES  */
135 
136   if (sizeof (struct S3)		!=  2)
137     return 14;
138   if (sizeof (struct S3)		!=  2)
139     return 15;
140   CHECK_FIELD (S3, c,  0,  8, 16);
141   CHECK_FIELD (S3, s,  8,  8, 17);
142 
143   if (sizeof (union U4) 		!=  2)
144     return 18;
145   if (alignof (union U4)		!=  2)
146     return 19;
147   CHECK_FIELD (U4, c,  0,  8, 20);
148   CHECK_FIELD (U4, s,  0,  8, 21);
149 
150   if (sizeof (struct S5)		!=  9)
151     return 22;
152   if (alignof (struct S5)		!=  1)
153     return 23;
154   CHECK_FIELD (S5, c,  0,  8, 24);
155   CHECK_FIELD (S5, d, 32,  8, 25);
156   CHECK_FIELD (S5, e, 64,  8, 26);
157 
158   return 0;
159 }
160