[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] bitfield handling
From: |
grischka |
Subject: |
Re: [Tinycc-devel] bitfield handling |
Date: |
Wed, 03 May 2017 10:58:59 +0200 |
User-agent: |
Thunderbird 2.0.0.23 (Windows/20090812) |
Michael Matz wrote:
OTOH your mentioning of "to the point where it actually was producing
the correct layout" indicates that it's not producing correct (i.e.
expected) layout/code anymore. Examples? Because, really, I fixed
struct bit-field incompatibilities with both MSVC and GCC, and hence am
interested where it's getting things still wrong. (Yes, the recent
report was an example. I haven't checked if it got everything right
before by design or luck, or superstition.) Still, other examples where
things go wrong would be appreciated. :)
Sorry, my mistake. It now appears to me that it probably never
did produce entirely correct results in the case of "packed pcc
bitfields" (including the time before you started to implement
them at all).
Also I must have assumed that what I've just seen with my brand-new
test case, you already must have seen long before, naturally.
However, suppose we have a field with bit_pos=5,bit_size=32.
In order to read it we need to read 40 bits, yes? How do we
do that on a 32-bit target, for example?
Here is the test:
Using gcc/tcc in pcc mode on i386-win32:
struct _s
{
int x: 12;
char y: 6;
long long z:63;
char w:6;
// total:87
}
__attribute__((packed))
;
-------- gcc -------
sizeof struct: 11
bits in use: 7FFFFFFFFFFFFFFFFFFFFF
values:
s.x: 00000003
s.y: 0000001e
s.z: 123456789abcdef0
s.w: 0000001f
all bits: 3E48D159E26AF37BC1E003
-------- tcc -------
sizeof struct: 12
bits in use: FFC0000000000000003F0FFF
values:
s.x: 00000003
s.y: 0000001e
s.z: 1abcde7c00000000
s.w: 0000001f
all bits: 9F00000000000000001E0003
Test code attached, have fun ... (no hurry ;)
--- grischka
#include <stdio.h>
#include <string.h>
//# pragma pack(1)
struct _s
{
int x: 12;
char y: 6;
long long z:63;
char w:6;
// total:87
}
__attribute__((packed))
;
void dump_r(struct _s *s)
{
int i;
for (i = sizeof *s; --i >= 0;)
printf("%02X", ((unsigned char*)s)[i]);
printf("\n");
}
void test_s(struct _s *s)
{
memset(s, 0, sizeof *s);
s->x = -1;
s->y = -1;
s->z = -1;
s->w = -1;
printf("sizeof struct: %d\n", sizeof *s);
printf("bits in use: "); dump_r(s);
s->x = 3;
s->y = 30;
s->z = 0x123456789abcdef0LL;
s->w = 31;
printf("values:\n");
printf(" s.x: %08x\n", s->x);
printf(" s.y: %08x\n", s->y);
printf(" s.z: %08x%08x\n", (unsigned)(s->z>>32), (unsigned)s->z);
printf(" s.w: %08x\n", s->w);
printf("all bits: "); dump_r(s);
printf("\n");
}
int main()
{
#ifdef __TINYC__
char some_stack_to_corrupt[8]; // ;)
#endif
struct _s s;
test_s(&s);
return 0;
}