History

bitfields: Implement MS compatible layout

Bit-fields are layed out differently in visual C, this implements a compatible mode. Checked against Visual C/C++ 2016. Unfortunately the GCC implementation of MS layout (behind -mms-bitfields) actually is different, and hence not compatible with MS in all cases :-/

Michael Matz committed 10 years ago

Commit bd69bce1 parent 78c70961 file · +30 −7Browse files

Unified · Split

tccgen.c+30−7
@@ -3266,7 +3266,7 @@ static void struct_add_offset (Sym *s, int offset) · 3265 unmodified lines
3266 3266
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;3269 int align, maxalign, offset, c, bit_pos, bt, prevbt;
3270 Sym *f;3270 Sym *f;
3271 if (ad->a.aligned)3271 if (ad->a.aligned)
3272 maxalign = ad->a.aligned;3272 maxalign = ad->a.aligned;
@@ -3275,6 +3275,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 2 unmodified lines
3275 offset = 0;3275 offset = 0;
3276 c = 0;3276 c = 0;
3277 bit_pos = 0;3277 bit_pos = 0;
3278 prevbt = VT_STRUCT; /* make it never match */
3278 for (f = type->ref->next; f; f = f->next) {3279 for (f = type->ref->next; f; f = f->next) {
3279 int extra_bytes = 0;3280 int extra_bytes = 0;
3280 int typealign, bit_size;3281 int typealign, bit_size;
@@ -3312,7 +3313,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 31 unmodified lines
3312 }3313 }
3313 /*if (extra_bytes) c += extra_bytes;3314 /*if (extra_bytes) c += extra_bytes;
3314 else*/ if (bit_size < 0) {3315 else*/ if (bit_size < 0) {
3315 int addbytes = (bit_pos + 7) >> 3;3316 int addbytes = pcc ? (bit_pos + 7) >> 3 : 0;
3316 if (type->ref->type.t == TOK_STRUCT) {3317 if (type->ref->type.t == TOK_STRUCT) {
3317 c = (c + addbytes + align - 1) & -align;3318 c = (c + addbytes + align - 1) & -align;
3318 offset = c;3319 offset = c;
@@ -3328,6 +3329,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 9 unmodified lines
3328 if (align > maxalign)3329 if (align > maxalign)
3329 maxalign = align;3330 maxalign = align;
3330 bit_pos = 0;3331 bit_pos = 0;
3332 prevbt = VT_STRUCT;
3331 } else {3333 } else {
3332 /* A bit-field. Layout is more complicated. There are two3334 /* A bit-field. Layout is more complicated. There are two
3333 options TCC implements: PCC compatible and MS compatible3335 options TCC implements: PCC compatible and MS compatible
@@ -3347,9 +3349,9 @@ static void struct_layout(CType *type, AttributeDef *ad) · 13 unmodified lines
3347 its container (depending on base type) or it's a zero-width3349 its container (depending on base type) or it's a zero-width
3348 bit-field. Packed non-zero-width bit-fields always are3350 bit-field. Packed non-zero-width bit-fields always are
3349 placed adjacent. */3351 placed adjacent. */
3350 if (typealign != 1 &&3352 if ((typealign != 1 &&
3351 (bit_pos + bit_size > size * 8 ||3353 bit_pos + bit_size > size * 8) ||
3352 bit_size == 0)) {3354 bit_size == 0) {
3353 c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;3355 c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;
3354 offset = c;3356 offset = c;
3355 bit_pos = 0;3357 bit_pos = 0;
@@ -3364,12 +3366,31 @@ static void struct_layout(CType *type, AttributeDef *ad) · 8 unmodified lines
3364 maxalign = typealign;3366 maxalign = typealign;
3365 }3367 }
3366 } else {3368 } else {
3367 tcc_error("ms bit-field layout not implemented");3369 bt = f->type.t & VT_BTYPE;
3370 if (
3371 ((
3372 bit_pos + bit_size > size * 8) ||
3373 (bit_size == 0 && prevbt == bt) ||
3374 (bit_size > 0 && bt != prevbt))) {
3375 c = (c + typealign - 1) & -typealign;
3376 offset = c;
3377 bit_pos = 0;
3378 /* In MS bitfield mode a bit-field run always uses
3379 at least as many bits as the underlying type. */
3380 c += size;
3381 }
3382 if (bit_size > 0 || prevbt == bt) {
3383 if (align > maxalign)
3384 maxalign = align;
3385 if (typealign > maxalign)
3386 maxalign = typealign;
3387 }
3388 prevbt = bt;
3368 }3389 }
3369 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))3390 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3370 | (bit_pos << VT_STRUCT_SHIFT);3391 | (bit_pos << VT_STRUCT_SHIFT);
3371 bit_pos += bit_size;3392 bit_pos += bit_size;
3372 if (bit_pos >= size * 8) {3393 if (pcc && bit_pos >= size * 8) {
3373 c += size;3394 c += size;
3374 bit_pos -= size * 8;3395 bit_pos -= size * 8;
3375 }3396 }
@@ -3573,6 +3594,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 197 unmodified lines
3573 if (v && bit_size == 0)3594 if (v && bit_size == 0)
3574 tcc_error("zero width for bit-field '%s'", 3595 tcc_error("zero width for bit-field '%s'",
3575 get_tok_str(v, NULL));3596 get_tok_str(v, NULL));
3597 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3598 parse_attribute(&ad1);
3576 }3599 }
3577 size = type_size(&type1, &align);3600 size = type_size(&type1, &align);
3578 /* Only remember non-default alignment. */3601 /* Only remember non-default alignment. */

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