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