mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-30 12:20:06 +08:00
Implement gcc bitfield algorithm; add -mms-bitfields
This commit is contained in:
parent
3c68a8c6c0
commit
d2e2f42382
6
libtcc.c
6
libtcc.c
@ -752,6 +752,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||||||
s->alacarte_link = 1;
|
s->alacarte_link = 1;
|
||||||
s->nocommon = 1;
|
s->nocommon = 1;
|
||||||
s->warn_implicit_function_declaration = 1;
|
s->warn_implicit_function_declaration = 1;
|
||||||
|
s->ms_bitfields = 0;
|
||||||
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
#ifdef CHAR_IS_UNSIGNED
|
||||||
s->char_is_unsigned = 1;
|
s->char_is_unsigned = 1;
|
||||||
@ -1508,6 +1509,7 @@ enum {
|
|||||||
TCC_OPTION_Wl,
|
TCC_OPTION_Wl,
|
||||||
TCC_OPTION_W,
|
TCC_OPTION_W,
|
||||||
TCC_OPTION_O,
|
TCC_OPTION_O,
|
||||||
|
TCC_OPTION_mms_bitfields,
|
||||||
TCC_OPTION_m,
|
TCC_OPTION_m,
|
||||||
TCC_OPTION_f,
|
TCC_OPTION_f,
|
||||||
TCC_OPTION_isystem,
|
TCC_OPTION_isystem,
|
||||||
@ -1571,6 +1573,7 @@ static const TCCOption tcc_options[] = {
|
|||||||
{ "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
{ "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
{ "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
|
{ "mms-bitfields", TCC_OPTION_mms_bitfields, 0}, /* must go before option 'm' */
|
||||||
{ "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
|
{ "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
|
||||||
{ "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
{ "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
|
{ "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
|
||||||
@ -1854,6 +1857,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
|||||||
if (x > 0)
|
if (x > 0)
|
||||||
tcc_define_symbol(s, "__OPTIMIZE__", NULL);
|
tcc_define_symbol(s, "__OPTIMIZE__", NULL);
|
||||||
break;
|
break;
|
||||||
|
case TCC_OPTION_mms_bitfields:
|
||||||
|
s->ms_bitfields = 1;
|
||||||
|
break;
|
||||||
case TCC_OPTION_traditional:
|
case TCC_OPTION_traditional:
|
||||||
case TCC_OPTION_pedantic:
|
case TCC_OPTION_pedantic:
|
||||||
case TCC_OPTION_pipe:
|
case TCC_OPTION_pipe:
|
||||||
|
@ -176,6 +176,10 @@ In a script, it gives the following header:
|
|||||||
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
|
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@item -mms-bitfields
|
||||||
|
Use an algorithm for bitfield alignment consistent with MSVC. Default is
|
||||||
|
gcc's algorithm.
|
||||||
|
|
||||||
@item -mfloat-abi (ARM only)
|
@item -mfloat-abi (ARM only)
|
||||||
Select the float ABI. Possible values: @code{softfp} and @code{hard}
|
Select the float ABI. Possible values: @code{softfp} and @code{hard}
|
||||||
|
|
||||||
|
1
tcc.c
1
tcc.c
@ -97,6 +97,7 @@ static void help(void)
|
|||||||
" -o outfile set output filename\n"
|
" -o outfile set output filename\n"
|
||||||
" -run run compiled source\n"
|
" -run run compiled source\n"
|
||||||
" -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
|
" -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
|
||||||
|
" -mms-bitfields use bitfield alignment consistent with MSVC\n"
|
||||||
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
|
" -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
|
||||||
" -w disable all warnings\n"
|
" -w disable all warnings\n"
|
||||||
" -v show version\n"
|
" -v show version\n"
|
||||||
|
1
tcc.h
1
tcc.h
@ -605,6 +605,7 @@ struct TCCState {
|
|||||||
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
|
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
|
||||||
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
|
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
|
||||||
int dollars_in_identifiers; /* allows '$' char in indentifiers */
|
int dollars_in_identifiers; /* allows '$' char in indentifiers */
|
||||||
|
int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
|
||||||
|
|
||||||
/* warning switches */
|
/* warning switches */
|
||||||
int warn_write_strings;
|
int warn_write_strings;
|
||||||
|
30
tccgen.c
30
tccgen.c
@ -3154,7 +3154,7 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
|
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
|
||||||
static void struct_decl(CType *type, AttributeDef *ad, int u)
|
static void struct_decl(CType *type, AttributeDef *ad, int u)
|
||||||
{
|
{
|
||||||
int a, v, size, align, maxalign, c, offset, flexible;
|
int a, v, size, align, maxalign, c, offset, flexible, extra_bytes;
|
||||||
int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
|
int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
|
||||||
Sym *s, *ss, *ass, **ps;
|
Sym *s, *ss, *ass, **ps;
|
||||||
AttributeDef ad1;
|
AttributeDef ad1;
|
||||||
@ -3235,6 +3235,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
|
|||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
parse_btype(&btype, &ad1);
|
parse_btype(&btype, &ad1);
|
||||||
while (1) {
|
while (1) {
|
||||||
|
extra_bytes = 0;
|
||||||
if (flexible)
|
if (flexible)
|
||||||
tcc_error("flexible array member '%s' not at the end of struct",
|
tcc_error("flexible array member '%s' not at the end of struct",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
@ -3310,9 +3311,9 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
|
|||||||
/* zero size: means to pad */
|
/* zero size: means to pad */
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
} else {
|
} else {
|
||||||
/* we do not have enough room ?
|
/* if type change, union, or will overrun
|
||||||
did the type change?
|
* allignment slot, start at a newly
|
||||||
is it a union? */
|
* alligned slot */
|
||||||
if ((bit_pos + bit_size) > bsize ||
|
if ((bit_pos + bit_size) > bsize ||
|
||||||
bt != prevbt || a == TOK_UNION)
|
bt != prevbt || a == TOK_UNION)
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
@ -3322,15 +3323,30 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
|
|||||||
(bit_pos << VT_STRUCT_SHIFT) |
|
(bit_pos << VT_STRUCT_SHIFT) |
|
||||||
(bit_size << (VT_STRUCT_SHIFT + 6));
|
(bit_size << (VT_STRUCT_SHIFT + 6));
|
||||||
bit_pos += bit_size;
|
bit_pos += bit_size;
|
||||||
|
/* without ms-bitfields, allocate the
|
||||||
|
* minimum number of bytes necessary,
|
||||||
|
* adding single bytes as needed */
|
||||||
|
if (!tcc_state->ms_bitfields) {
|
||||||
|
if (lbit_pos == 0)
|
||||||
|
/* minimum bytes for new bitfield */
|
||||||
|
size = (bit_size + 7) / 8;
|
||||||
|
else {
|
||||||
|
/* enough spare bits already allocated? */
|
||||||
|
bit_size = (lbit_pos - 1) % 8 + 1 + bit_size;
|
||||||
|
if (bit_size > 8) /* doesn't fit */
|
||||||
|
extra_bytes = (bit_size - 1) / 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prevbt = bt;
|
prevbt = bt;
|
||||||
} else {
|
} else {
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
}
|
}
|
||||||
if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
|
if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
/* add new memory data only if starting
|
/* add new memory data only if starting bit
|
||||||
bit field */
|
field or adding bytes to existing bit field */
|
||||||
if (lbit_pos == 0) {
|
if (extra_bytes) c += extra_bytes;
|
||||||
|
else if (lbit_pos == 0) {
|
||||||
if (a == TOK_STRUCT) {
|
if (a == TOK_STRUCT) {
|
||||||
c = (c + align - 1) & -align;
|
c = (c + align - 1) & -align;
|
||||||
offset = c;
|
offset = c;
|
||||||
|
@ -1634,6 +1634,15 @@ void bitfield_test(void)
|
|||||||
st2.f3 = a;
|
st2.f3 = a;
|
||||||
st2.f2++;
|
st2.f2++;
|
||||||
printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
|
printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
|
||||||
|
struct sbf3 {
|
||||||
|
int f1 : 7;
|
||||||
|
int f2 : 1;
|
||||||
|
char f3;
|
||||||
|
int f4 : 8;
|
||||||
|
int f5 : 1;
|
||||||
|
int f6 : 16;
|
||||||
|
} st3;
|
||||||
|
printf("sizeof(st3) = %d\n", sizeof(st3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
Loading…
Reference in New Issue
Block a user