Fixes some corner cases in PCC layout. Testcases coming up.
Unified · Split
| @@ -3267,6 +3267,7 @@ static void struct_add_offset (Sym *s, int offset) · 3266 unmodified lines | |||
| 3267 | static void struct_layout(CType *type, AttributeDef *ad) | 3267 | static 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 the | 3286 | /* 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 two | 3339 | /* A bit-field. Layout is more complicated. There are two |
| 3335 | options TCC implements: PCC compatible and MS compatible | 3340 | 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 adjacent | 3343 | /* In PCC layout a non-packed bit-field is placed adjacent |
| 3348 | to the preceding bit-fields, except if it would overflow | 3344 | to the preceding bit-fields, except if it would overflow |
| 3349 | its container (depending on base type) or it's a zero-width | 3345 | its container (depending on base type) or it's a zero-width |
| 3350 | bit-field. Packed non-zero-width bit-fields always are | 3346 | 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 alignment | 3363 | /* 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 | ||