History

bitfields: fix PCC layout

Fixes some corner cases in PCC layout. Testcases coming up.

Michael Matz committed 10 years ago

Commit ed680da1 parent bd69bce1 file · +28 −23Browse files

Unified · Split

tccgen.c+28−23
@@ -3267,6 +3267,7 @@ static void struct_add_offset (Sym *s, int offset) · 3266 unmodified lines
3267static void struct_layout(CType *type, AttributeDef *ad)3267static void struct_layout(CType *type, AttributeDef *ad)
3268{3268{
3269 int align, maxalign, offset, c, bit_pos, bt, prevbt;3269 int align, maxalign, offset, c, bit_pos, bt, prevbt;
3270 int pcc = !tcc_state->ms_bitfields;
3270 Sym *f;3271 Sym *f;
3271 if (ad->a.aligned)3272 if (ad->a.aligned)
3272 maxalign = ad->a.aligned;3273 maxalign = ad->a.aligned;
@@ -3280,13 +3281,12 @@ static void struct_layout(CType *type, AttributeDef *ad) · 7 unmodified lines
3280 int extra_bytes = 0;3281 int extra_bytes = 0;
3281 int typealign, bit_size;3282 int typealign, bit_size;
3282 int size = type_size(&f->type, &typealign);3283 int size = type_size(&f->type, &typealign);
3283 int pcc = !tcc_state->ms_bitfields;
3284 if (f->type.t & VT_BITFIELD) {3284 if (f->type.t & VT_BITFIELD) {
3285 bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;3285 bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3286 /* without ms-bitfields, allocate the3286 /* without ms-bitfields, allocate the
3287 * minimum number of bytes necessary,3287 * minimum number of bytes necessary,
3288 * adding single bytes as needed */3288 * adding single bytes as needed */
3289 if (!tcc_state->ms_bitfields) {3289 if (0 && !tcc_state->ms_bitfields) {
3290 if (bit_pos == 0)3290 if (bit_pos == 0)
3291 /* minimum bytes for new bitfield */3291 /* minimum bytes for new bitfield */
3292 size = (bit_size + 7) / 8;3292 size = (bit_size + 7) / 8;
@@ -3311,55 +3311,59 @@ static void struct_layout(CType *type, AttributeDef *ad) · 18 unmodified lines
3311 } else {3311 } else {
3312 align = typealign;3312 align = typealign;
3313 }3313 }
3314 /*if (extra_bytes) c += extra_bytes;3314 if (extra_bytes) c += extra_bytes;
3315 else*/ if (bit_size < 0) {3315 else if (bit_size < 0) {
3316 int addbytes = pcc ? (bit_pos + 7) >> 3 : 0;3316 prevbt = VT_STRUCT;
3317 if (type->ref->type.t == TOK_STRUCT) {3317 if (type->ref->type.t == TOK_STRUCT) {
3318 int addbytes = pcc ? (bit_pos + 7) >> 3 : 0;
3318 c = (c + addbytes + align - 1) & -align;3319 c = (c + addbytes + align - 1) & -align;
3319 offset = c;3320 offset = c;
3320 if (size > 0)3321 if (size > 0)
3321 c += size;3322 c += size;
3322 } else {3323 } else {
3324 union_tail:
3323 offset = 0;3325 offset = 0;
3324 if (addbytes > c)
3325 c = addbytes;
3326 if (size > c)3326 if (size > c)
3327 c = size;3327 c = size;
3328 }3328 }
3329 if (align > maxalign)3329 if (align > maxalign)
3330 maxalign = align;3330 maxalign = align;
3331 bit_pos = 0;3331 bit_pos = 0;
3332 prevbt = VT_STRUCT;3332 } else if (type->ref->type.t != TOK_STRUCT) {
3333 if (pcc)
3334 size = (bit_size + 7) >> 3;
3335 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3336 | (0 << VT_STRUCT_SHIFT);
3337 goto union_tail;
3333 } else {3338 } else {
3334 /* A bit-field. Layout is more complicated. There are two3339 /* A bit-field. Layout is more complicated. There are two
3335 options TCC implements: PCC compatible and MS compatible3340 options TCC implements: PCC compatible and MS compatible
3336 (PCC compatible is what GCC uses for almost all targets). */3341 (PCC compatible is what GCC uses for almost all targets). */
3337 if (!bit_pos) {
3338 if (type->ref->type.t == TOK_STRUCT) {
3339 /* Don't align c here. That's only to be done
3340 in certain cases. */
3341 offset = c;
3342 } else {
3343 offset = 0;
3344 }
3345 }
3346 if (pcc) {3342 if (pcc) {
3347 /* In PCC layout a non-packed bit-field is placed adjacent3343 /* In PCC layout a non-packed bit-field is placed adjacent
3348 to the preceding bit-fields, except if it would overflow3344 to the preceding bit-fields, except if it would overflow
3349 its container (depending on base type) or it's a zero-width3345 its container (depending on base type) or it's a zero-width
3350 bit-field. Packed non-zero-width bit-fields always are3346 bit-field. Packed non-zero-width bit-fields always are
3351 placed adjacent. */3347 placed adjacent. */
3352 if ((typealign != 1 &&3348 int ofs = (c * 8 + bit_pos) % (typealign * 8);
3353 bit_pos + bit_size > size * 8) ||3349 int ofs2 = ofs + bit_size + (typealign * 8) - 1;
3354 bit_size == 0) {3350 /*if ((typealign != 1 &&
3351 //bit_pos + bit_size > size * 8) ||
3352 (((c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign)
3353 != ((c + ((bit_pos + bit_size + 7) >> 3) + typealign - 1) & -typealign))) ||
3354 bit_size == 0 ||
3355 (bit_pos + bit_size > size * 8)
3356 ) {*/
3357 if (bit_size == 0 ||
3358 (typealign != 1 && (ofs2 / (typealign * 8)) > ((size*8)/(typealign*8)))) {
3355 c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;3359 c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;
3356 offset = c;
3357 bit_pos = 0;3360 bit_pos = 0;
3358 }3361 }
3362 offset = c;
3359 /* In PCC layout named bit-fields influence the alignment3363 /* In PCC layout named bit-fields influence the alignment
3360 of the containing struct using the base types alignment,3364 of the containing struct using the base types alignment,
3361 except for packed fields or zero-width fields. */3365 except for packed fields or zero-width fields. */
3362 if (bit_size > 0) {3366 if (!(f->v & SYM_FIRST_ANOM)) {
3363 if (align > maxalign)3367 if (align > maxalign)
3364 maxalign = align;3368 maxalign = align;
3365 if (typealign > maxalign)3369 if (typealign > maxalign)
@@ -3444,7 +3448,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 78 unmodified lines
3444 f->r = 0;3448 f->r = 0;
3445 }3449 }
3446 /* store size and alignment */3450 /* store size and alignment */
3447 type->ref->c = (c + ((bit_pos + 7) >> 3) + maxalign - 1) & -maxalign;3451 type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0)
3452 + maxalign - 1) & -maxalign;
3448 type->ref->r = maxalign;3453 type->ref->r = maxalign;
3449}3454}
3450 3455

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t