mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
#pragma comment(option,"-..."), bitfields test, etc...
tccpp.c: * #pragma comment(option,"-some-option") to set commandline option from C code. May work only for some options. libtcc.c: * option "-d1..9": sets a 'g_debug' global variable. (for development) tests2/Makefile: * new make targets: tests2.37 / tests2.37+ run single test from tests2, optionally update .expect * new variable GEN-ALWAYS to always generate certain .expects * bitfields test tccgen.c: * bitfields: fix a bug and improve slightly more * _Generic: ignore "type match twice"
This commit is contained in:
parent
04418c7add
commit
69a137ff88
13
Makefile
13
Makefile
@ -345,9 +345,12 @@ tar: tcc-doc.html
|
|||||||
config.mak:
|
config.mak:
|
||||||
$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
|
$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
|
||||||
|
|
||||||
# in tests subdir
|
# run all tests
|
||||||
test:
|
test:
|
||||||
$(MAKE) -C tests
|
$(MAKE) -C tests
|
||||||
|
# run test(s) from tests2 subdir (see make help)
|
||||||
|
tests2.%:
|
||||||
|
$(MAKE) -C tests/tests2 $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod
|
rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod
|
||||||
@ -389,8 +392,14 @@ help:
|
|||||||
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
||||||
@echo " DEF-i386 += -D__linux__"
|
@echo " DEF-i386 += -D__linux__"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
@echo "make test"
|
||||||
|
@echo " run all tests"
|
||||||
|
@echo ""
|
||||||
|
@echo "make tests2.all / make tests2.37 / make tests2.37+"
|
||||||
|
@echo " run all/single test(s) from tests2, optionally update .expect"
|
||||||
|
@echo ""
|
||||||
@echo "Other supported make targets:"
|
@echo "Other supported make targets:"
|
||||||
@echo " install install-strip test tags ETAGS tar clean distclean help"
|
@echo " install install-strip tags ETAGS tar clean distclean help"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
2
libtcc.c
2
libtcc.c
@ -1801,6 +1801,8 @@ reparse:
|
|||||||
s->dflag = 3;
|
s->dflag = 3;
|
||||||
else if (*optarg == 'M')
|
else if (*optarg == 'M')
|
||||||
s->dflag = 7;
|
s->dflag = 7;
|
||||||
|
else if (isnum(*optarg))
|
||||||
|
g_debug = atoi(optarg);
|
||||||
else
|
else
|
||||||
goto unsupported_option;
|
goto unsupported_option;
|
||||||
break;
|
break;
|
||||||
|
1
tcc.h
1
tcc.h
@ -1289,6 +1289,7 @@ ST_DATA int func_var; /* true if current function is variadic */
|
|||||||
ST_DATA int func_vc;
|
ST_DATA int func_vc;
|
||||||
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
||||||
ST_DATA const char *funcname;
|
ST_DATA const char *funcname;
|
||||||
|
ST_DATA int g_debug;
|
||||||
|
|
||||||
ST_FUNC void tcc_debug_start(TCCState *s1);
|
ST_FUNC void tcc_debug_start(TCCState *s1);
|
||||||
ST_FUNC void tcc_debug_end(TCCState *s1);
|
ST_FUNC void tcc_debug_end(TCCState *s1);
|
||||||
|
67
tccgen.c
67
tccgen.c
@ -57,6 +57,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in
|
|||||||
ST_DATA int func_vc;
|
ST_DATA int func_vc;
|
||||||
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
||||||
ST_DATA const char *funcname;
|
ST_DATA const char *funcname;
|
||||||
|
ST_DATA int g_debug;
|
||||||
|
|
||||||
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
||||||
|
|
||||||
@ -1083,8 +1084,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size)
|
|||||||
{
|
{
|
||||||
int n, o, bits;
|
int n, o, bits;
|
||||||
save_reg_upstack(vtop->r, 1);
|
save_reg_upstack(vtop->r, 1);
|
||||||
vpushi(0); // B X
|
vpush64(type->t & VT_BTYPE, 0); // B X
|
||||||
vtop->type.t |= type->t;
|
|
||||||
bits = 0, o = bit_pos >> 3, bit_pos &= 7;
|
bits = 0, o = bit_pos >> 3, bit_pos &= 7;
|
||||||
do {
|
do {
|
||||||
vswap(); // X B
|
vswap(); // X B
|
||||||
@ -1113,7 +1113,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* single-byte store mode for packed or otherwise unaligned bitfields */
|
/* single-byte store mode for packed or otherwise unaligned bitfields */
|
||||||
void store_packed_bf(int bit_pos, int bit_size)
|
static void store_packed_bf(int bit_pos, int bit_size)
|
||||||
{
|
{
|
||||||
int bits, n, o, m, c;
|
int bits, n, o, m, c;
|
||||||
|
|
||||||
@ -1148,7 +1148,7 @@ void store_packed_bf(int bit_pos, int bit_size)
|
|||||||
vpop(), vpop();
|
vpop(), vpop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int adjust_bf(SValue *sv, int bit_pos, int bit_size)
|
static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
if (0 == sv->type.ref)
|
if (0 == sv->type.ref)
|
||||||
@ -2781,7 +2781,7 @@ static void type_to_str(char *buf, int buf_size,
|
|||||||
pstrcat(buf, buf_size, "inline ");
|
pstrcat(buf, buf_size, "inline ");
|
||||||
buf_size -= strlen(buf);
|
buf_size -= strlen(buf);
|
||||||
buf += strlen(buf);
|
buf += strlen(buf);
|
||||||
if (IS_ENUM(type->t)) {
|
if (IS_ENUM(t)) {
|
||||||
tstr = "enum ";
|
tstr = "enum ";
|
||||||
goto tstruct;
|
goto tstruct;
|
||||||
}
|
}
|
||||||
@ -3405,9 +3405,12 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||||||
//#define BF_DEBUG
|
//#define BF_DEBUG
|
||||||
|
|
||||||
for (f = type->ref->next; f; f = f->next) {
|
for (f = type->ref->next; f; f = f->next) {
|
||||||
if (f->type.t & VT_BITFIELD)
|
if (f->type.t & VT_BITFIELD) {
|
||||||
bit_size = BIT_SIZE(f->type.t);
|
bit_size = BIT_SIZE(f->type.t);
|
||||||
else
|
/* in pcc mode, long long bitfields have type int if they fit */
|
||||||
|
if (pcc && (f->type.t & VT_BTYPE) == VT_LLONG && bit_size <= 32)
|
||||||
|
f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT;
|
||||||
|
} else
|
||||||
bit_size = -1;
|
bit_size = -1;
|
||||||
size = type_size(&f->type, &align);
|
size = type_size(&f->type, &align);
|
||||||
a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
|
a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
|
||||||
@ -3476,16 +3479,10 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||||||
goto new_field;
|
goto new_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in pcc mode, long long bitfields have type int if they fit */
|
while (bit_pos >= align * 8)
|
||||||
if (size == 8 && bit_size <= 32) {
|
c += align, bit_pos -= align * 8;
|
||||||
f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT;
|
|
||||||
size = 4;
|
|
||||||
}
|
|
||||||
if (bit_pos >= size * 8) {
|
|
||||||
c += size;
|
|
||||||
bit_pos -= size * 8;
|
|
||||||
}
|
|
||||||
offset = c;
|
offset = c;
|
||||||
|
|
||||||
/* In PCC layout named bit-fields influence the alignment
|
/* In PCC layout named bit-fields influence the alignment
|
||||||
of the containing struct using the base types alignment,
|
of the containing struct using the base types alignment,
|
||||||
except for packed fields (which here have correct align). */
|
except for packed fields (which here have correct align). */
|
||||||
@ -3576,14 +3573,20 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||||||
if (pcc)
|
if (pcc)
|
||||||
c += (bit_pos + 7) >> 3;
|
c += (bit_pos + 7) >> 3;
|
||||||
|
|
||||||
a = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 0;
|
/* store size and alignment */
|
||||||
|
a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
|
||||||
if (a < maxalign)
|
if (a < maxalign)
|
||||||
a = maxalign;
|
a = maxalign;
|
||||||
c = (c + a - 1) & -a;
|
|
||||||
|
|
||||||
/* store size and alignment */
|
|
||||||
type->ref->c = c;
|
|
||||||
type->ref->r = a;
|
type->ref->r = a;
|
||||||
|
if (pragma_pack && pragma_pack < maxalign) {
|
||||||
|
/* can happen if individual align for some member was given. In
|
||||||
|
this case MSVC ignores maxalign when aligning the size */
|
||||||
|
a = pragma_pack;
|
||||||
|
if (a < bt)
|
||||||
|
a = bt;
|
||||||
|
}
|
||||||
|
c = (c + a - 1) & -a;
|
||||||
|
type->ref->c = c;
|
||||||
|
|
||||||
#ifdef BF_DEBUG
|
#ifdef BF_DEBUG
|
||||||
printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
|
printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
|
||||||
@ -3603,7 +3606,6 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||||||
continue;
|
continue;
|
||||||
bit_pos = BIT_POS(f->type.t);
|
bit_pos = BIT_POS(f->type.t);
|
||||||
size = type_size(&f->type, &align);
|
size = type_size(&f->type, &align);
|
||||||
|
|
||||||
if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
|
if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3637,19 +3639,20 @@ static void struct_layout(CType *type, AttributeDef *ad)
|
|||||||
| (bit_pos << VT_STRUCT_SHIFT);
|
| (bit_pos << VT_STRUCT_SHIFT);
|
||||||
if (s != size)
|
if (s != size)
|
||||||
f->auxtype = t.t;
|
f->auxtype = t.t;
|
||||||
|
#ifdef BF_DEBUG
|
||||||
|
printf("FIX field %s offset %-2d size %-2d align %-2d "
|
||||||
|
"pos %-2d bits %-2d\n",
|
||||||
|
get_tok_str(f->v & ~SYM_FIELD, NULL),
|
||||||
|
cx, s, align, px, bit_size);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* fall back to load/store single-byte wise */
|
/* fall back to load/store single-byte wise */
|
||||||
f->auxtype = VT_STRUCT;
|
f->auxtype = VT_STRUCT;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BF_DEBUG
|
#ifdef BF_DEBUG
|
||||||
printf("FIX field %s offset %-2d size %-2d align %-2d "
|
printf("FIX field %s : load byte-wise\n",
|
||||||
"pos %-2d bits %-2d %s\n",
|
get_tok_str(f->v & ~SYM_FIELD, NULL));
|
||||||
get_tok_str(f->v & ~SYM_FIELD, NULL),
|
|
||||||
cx, s, align, px, bit_size,
|
|
||||||
f->auxtype == VT_PTR ? " byte-wise" : ""
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4915,9 +4918,9 @@ ST_FUNC void unary(void)
|
|||||||
type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
|
type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
|
||||||
if (compare_types(&controlling_type, &cur_type, 0)) {
|
if (compare_types(&controlling_type, &cur_type, 0)) {
|
||||||
if (has_match) {
|
if (has_match) {
|
||||||
tcc_error("type march twice");
|
// tcc_error("type march twice");
|
||||||
}
|
}
|
||||||
if (has_default)
|
if (str)
|
||||||
tok_str_free(str);
|
tok_str_free(str);
|
||||||
has_match = 1;
|
has_match = 1;
|
||||||
learn = 1;
|
learn = 1;
|
||||||
|
22
tccpp.c
22
tccpp.c
@ -1658,24 +1658,28 @@ static void pragma_parse(TCCState *s1)
|
|||||||
goto pragma_err;
|
goto pragma_err;
|
||||||
|
|
||||||
} else if (tok == TOK_comment) {
|
} else if (tok == TOK_comment) {
|
||||||
char *file;
|
char *p; int t;
|
||||||
next();
|
next();
|
||||||
skip('(');
|
skip('(');
|
||||||
if (tok != TOK_lib)
|
t = tok;
|
||||||
goto pragma_warn;
|
|
||||||
next();
|
next();
|
||||||
skip(',');
|
skip(',');
|
||||||
if (tok != TOK_STR)
|
if (tok != TOK_STR)
|
||||||
goto pragma_err;
|
goto pragma_err;
|
||||||
file = tcc_strdup((char *)tokc.str.data);
|
p = tcc_strdup((char *)tokc.str.data);
|
||||||
dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, file);
|
|
||||||
next();
|
next();
|
||||||
if (tok != ')')
|
if (tok != ')')
|
||||||
goto pragma_err;
|
goto pragma_err;
|
||||||
} else {
|
if (t == TOK_lib) {
|
||||||
pragma_warn:
|
dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
|
||||||
if (s1->warn_unsupported)
|
} else {
|
||||||
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
|
if (t == TOK_option)
|
||||||
|
tcc_set_options(s1, p);
|
||||||
|
tcc_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (s1->warn_unsupported) {
|
||||||
|
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
1
tcctok.h
1
tcctok.h
@ -167,6 +167,7 @@
|
|||||||
DEF(TOK_push_macro, "push_macro")
|
DEF(TOK_push_macro, "push_macro")
|
||||||
DEF(TOK_pop_macro, "pop_macro")
|
DEF(TOK_pop_macro, "pop_macro")
|
||||||
DEF(TOK_once, "once")
|
DEF(TOK_once, "once")
|
||||||
|
DEF(TOK_option, "option")
|
||||||
|
|
||||||
/* builtin functions or variables */
|
/* builtin functions or variables */
|
||||||
#ifndef TCC_ARM_EABI
|
#ifndef TCC_ARM_EABI
|
||||||
|
215
tests/tests2/95_bitfields.c
Normal file
215
tests/tests2/95_bitfields.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#if TEST == 1
|
||||||
|
{
|
||||||
|
struct M P A __s
|
||||||
|
{
|
||||||
|
unsigned x : 12;
|
||||||
|
unsigned char y : 7;
|
||||||
|
unsigned z : 28;
|
||||||
|
unsigned a: 4;
|
||||||
|
unsigned b: 5;
|
||||||
|
};
|
||||||
|
TEST_STRUCT(0x333,0x44,0x555555,6,7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif TEST == 2
|
||||||
|
{
|
||||||
|
struct M P __s
|
||||||
|
{
|
||||||
|
int x: 12;
|
||||||
|
char y: 6;
|
||||||
|
long long z:63;
|
||||||
|
A char a:4;
|
||||||
|
long long b:2;
|
||||||
|
|
||||||
|
};
|
||||||
|
TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif TEST == 3
|
||||||
|
{
|
||||||
|
struct M P __s
|
||||||
|
{
|
||||||
|
unsigned x:5, y:5, :0, z:5; char a:5; A short b:5;
|
||||||
|
};
|
||||||
|
TEST_STRUCT(21,23,25,6,14);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif TEST == 4
|
||||||
|
{
|
||||||
|
struct M P __s {
|
||||||
|
int x : 3;
|
||||||
|
int : 2;
|
||||||
|
int y : 1;
|
||||||
|
int : 0;
|
||||||
|
int z : 5;
|
||||||
|
int a : 7;
|
||||||
|
unsigned int b : 7;
|
||||||
|
};
|
||||||
|
TEST_STRUCT(3,1,15,120,120);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif TEST == 5
|
||||||
|
{
|
||||||
|
struct M P __s {
|
||||||
|
long long x : 45;
|
||||||
|
long long : 2;
|
||||||
|
long long y : 35;
|
||||||
|
unsigned long long z : 38;
|
||||||
|
char a; short b;
|
||||||
|
};
|
||||||
|
TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif TEST == 6
|
||||||
|
{
|
||||||
|
struct M P __s {
|
||||||
|
int a;
|
||||||
|
char b;
|
||||||
|
int x : 12, y : 4, : 0, : 4, z : 3;
|
||||||
|
char d;
|
||||||
|
};
|
||||||
|
TEST_STRUCT(1,2,3,4,-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif defined PACK
|
||||||
|
|
||||||
|
#if PACK
|
||||||
|
# pragma pack(push,1)
|
||||||
|
# define P //_P
|
||||||
|
#else
|
||||||
|
# define P
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TEST 1
|
||||||
|
#include SELF
|
||||||
|
#define TEST 2
|
||||||
|
#include SELF
|
||||||
|
#define TEST 3
|
||||||
|
#include SELF
|
||||||
|
#define TEST 4
|
||||||
|
#include SELF
|
||||||
|
#define TEST 5
|
||||||
|
#include SELF
|
||||||
|
#define TEST 6
|
||||||
|
#include SELF
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
#if PACK
|
||||||
|
# pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef P
|
||||||
|
#undef PACK
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif defined ALIGN
|
||||||
|
|
||||||
|
#if ALIGN
|
||||||
|
# define A _A(16)
|
||||||
|
#else
|
||||||
|
# define A
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PACK 0
|
||||||
|
#include SELF
|
||||||
|
#define PACK 1
|
||||||
|
#include SELF
|
||||||
|
|
||||||
|
#undef A
|
||||||
|
#undef ALIGN
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#elif defined MS_BF
|
||||||
|
|
||||||
|
#if MS_BF
|
||||||
|
# ifdef __TINYC__
|
||||||
|
# pragma comment(option, "-mms-bitfields")
|
||||||
|
# elif defined __GNUC__
|
||||||
|
# define M __attribute__((ms_struct))
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifdef __TINYC__
|
||||||
|
# pragma comment(option, "-mno-ms-bitfields")
|
||||||
|
# elif defined __GNUC__
|
||||||
|
# define M __attribute__((gcc_struct))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef M
|
||||||
|
# define M
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALIGN 0
|
||||||
|
#include SELF
|
||||||
|
#define ALIGN 1
|
||||||
|
#include SELF
|
||||||
|
|
||||||
|
#undef M
|
||||||
|
#undef MS_BF
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
/* some gcc headers #define __attribute__ to empty if it's not gcc */
|
||||||
|
#undef __attribute__
|
||||||
|
|
||||||
|
void dump(void *p, int s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = s; --i >= 0;)
|
||||||
|
printf("%02X", ((unsigned char*)p)[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pv(m) \
|
||||||
|
printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
|
||||||
|
|
||||||
|
#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
|
||||||
|
struct __s _s, *s = & _s; \
|
||||||
|
printf("---- TEST %d%s%s%s ----\n", \
|
||||||
|
TEST, MS_BF?" - MS-BITFIELDS":"", \
|
||||||
|
PACK?" - PACKED":"", \
|
||||||
|
ALIGN?" - WITH ALIGN":""); \
|
||||||
|
memset(s, 0, sizeof *s); \
|
||||||
|
s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
|
||||||
|
printf("bits in use : "), dump(s, sizeof *s); \
|
||||||
|
s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
|
||||||
|
printf("bits as set : "), dump(s, sizeof *s); \
|
||||||
|
printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
|
||||||
|
printf("align/size : %d %d\n\n", alignof(struct __s),sizeof(struct __s)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define _A(n) __declspec(align(n))
|
||||||
|
# define _P
|
||||||
|
# define alignof(x) __alignof(x)
|
||||||
|
#else
|
||||||
|
# define _A(n) __attribute__((aligned(n)))
|
||||||
|
# define _P __attribute__((packed))
|
||||||
|
# define alignof(x) __alignof__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MS_BITFIELDS
|
||||||
|
# define MS_BITFIELDS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SELF "95_bitfields.c"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#define MS_BF MS_BITFIELDS
|
||||||
|
#include SELF
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
#endif
|
||||||
|
#undef TEST
|
2
tests/tests2/95_bitfields_ms.c
Normal file
2
tests/tests2/95_bitfields_ms.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define MS_BITFIELDS 1
|
||||||
|
#include "95_bitfields.c"
|
152
tests/tests2/95_bitfields_ms.expect
Normal file
152
tests/tests2/95_bitfields_ms.expect
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
---- TEST 1 - MS-BITFIELDS ----
|
||||||
|
bits in use : 0000001FFFFFFFFF0000007F00000FFF
|
||||||
|
bits as set : 00000007605555550000004400000333
|
||||||
|
values : 333 44 555555 06 07
|
||||||
|
align/size : 4 16
|
||||||
|
|
||||||
|
---- TEST 2 - MS-BITFIELDS ----
|
||||||
|
bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
|
||||||
|
bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
|
||||||
|
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
|
||||||
|
align/size : 8 32
|
||||||
|
|
||||||
|
---- TEST 3 - MS-BITFIELDS ----
|
||||||
|
bits in use : 001F001F0000001F000003FF
|
||||||
|
bits as set : 000E000600000019000002F5
|
||||||
|
values : 15 17 19 06 0e
|
||||||
|
align/size : 4 12
|
||||||
|
|
||||||
|
---- TEST 4 - MS-BITFIELDS ----
|
||||||
|
bits in use : 0007FFFF00000027
|
||||||
|
bits as set : 00078F0F00000023
|
||||||
|
values : 03 ffffffff 0f fffffff8 78
|
||||||
|
align/size : 4 8
|
||||||
|
|
||||||
|
---- TEST 5 - MS-BITFIELDS ----
|
||||||
|
bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
|
||||||
|
bits as set : 0000000000770044000000000000007800000007F00000000000000123456789
|
||||||
|
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
|
||||||
|
align/size : 8 32
|
||||||
|
|
||||||
|
---- TEST 6 - MS-BITFIELDS ----
|
||||||
|
bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
|
||||||
|
bits as set : 000000000000003000002001000000FD00000004
|
||||||
|
values : 01 02 03 04 fffffffd
|
||||||
|
align/size : 4 20
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---- TEST 1 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : 0000001FFFFFFFFF7F00000FFF
|
||||||
|
bits as set : 00000007605555554400000333
|
||||||
|
values : 333 44 555555 06 07
|
||||||
|
align/size : 1 13
|
||||||
|
|
||||||
|
---- TEST 2 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF
|
||||||
|
bits as set : 000000000000000205123456789ABCDEF01E00000003
|
||||||
|
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
|
||||||
|
align/size : 1 22
|
||||||
|
|
||||||
|
---- TEST 3 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : 001F1F0000001F000003FF
|
||||||
|
bits as set : 000E0600000019000002F5
|
||||||
|
values : 15 17 19 06 0e
|
||||||
|
align/size : 1 11
|
||||||
|
|
||||||
|
---- TEST 4 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : 0007FFFF00000027
|
||||||
|
bits as set : 00078F0F00000023
|
||||||
|
values : 03 ffffffff 0f fffffff8 78
|
||||||
|
align/size : 1 8
|
||||||
|
|
||||||
|
---- TEST 5 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
|
||||||
|
bits as set : 007744000000000000007800000007F00000000000000123456789
|
||||||
|
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
|
||||||
|
align/size : 1 27
|
||||||
|
|
||||||
|
---- TEST 6 - MS-BITFIELDS - PACKED ----
|
||||||
|
bits in use : 00000000700000FFFFFFFFFFFFFF
|
||||||
|
bits as set : 000000003000002001FD00000004
|
||||||
|
values : 01 02 03 04 fffffffd
|
||||||
|
align/size : 1 14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---- TEST 1 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 0000001FFFFFFFFF0000007F00000FFF
|
||||||
|
bits as set : 00000007605555550000004400000333
|
||||||
|
values : 333 44 555555 06 07
|
||||||
|
align/size : 16 16
|
||||||
|
|
||||||
|
---- TEST 2 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
|
||||||
|
bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
|
||||||
|
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
|
||||||
|
align/size : 16 32
|
||||||
|
|
||||||
|
---- TEST 3 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF
|
||||||
|
bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5
|
||||||
|
values : 15 17 19 06 0e
|
||||||
|
align/size : 16 32
|
||||||
|
|
||||||
|
---- TEST 4 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 0007FFFF00000027
|
||||||
|
bits as set : 00078F0F00000023
|
||||||
|
values : 03 ffffffff 0f fffffff8 78
|
||||||
|
align/size : 4 8
|
||||||
|
|
||||||
|
---- TEST 5 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
|
||||||
|
bits as set : 0000000000770044000000000000007800000007F00000000000000123456789
|
||||||
|
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
|
||||||
|
align/size : 8 32
|
||||||
|
|
||||||
|
---- TEST 6 - MS-BITFIELDS - WITH ALIGN ----
|
||||||
|
bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
|
||||||
|
bits as set : 000000000000003000002001000000FD00000004
|
||||||
|
values : 01 02 03 04 fffffffd
|
||||||
|
align/size : 4 20
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : 0000000000001FFFFFFFFF7F00000FFF
|
||||||
|
bits as set : 00000000000007605555554400000333
|
||||||
|
values : 333 44 555555 06 07
|
||||||
|
align/size : 16 16
|
||||||
|
|
||||||
|
---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF
|
||||||
|
bits as set : 000000000000000205000000123456789ABCDEF01E00000003
|
||||||
|
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
|
||||||
|
align/size : 16 25
|
||||||
|
|
||||||
|
---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : 001F000000000000001F0000001F000003FF
|
||||||
|
bits as set : 000E000000000000000600000019000002F5
|
||||||
|
values : 15 17 19 06 0e
|
||||||
|
align/size : 16 18
|
||||||
|
|
||||||
|
---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : 0007FFFF00000027
|
||||||
|
bits as set : 00078F0F00000023
|
||||||
|
values : 03 ffffffff 0f fffffff8 78
|
||||||
|
align/size : 1 8
|
||||||
|
|
||||||
|
---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
|
||||||
|
bits as set : 007744000000000000007800000007F00000000000000123456789
|
||||||
|
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
|
||||||
|
align/size : 1 27
|
||||||
|
|
||||||
|
---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ----
|
||||||
|
bits in use : 00000000700000FFFFFFFFFFFFFF
|
||||||
|
bits as set : 000000003000002001FD00000004
|
||||||
|
values : 01 02 03 04 fffffffd
|
||||||
|
align/size : 1 14
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,6 +18,9 @@ NORUN =
|
|||||||
FLAGS =
|
FLAGS =
|
||||||
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
|
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
|
||||||
|
|
||||||
|
# Always generate certain .expects (don't put these in the GIT),
|
||||||
|
GEN-ALWAYS = 95_bitfields.expect
|
||||||
|
|
||||||
# Filter source directory in warnings/errors (out-of-tree builds)
|
# Filter source directory in warnings/errors (out-of-tree builds)
|
||||||
FILTER = 2>&1 | sed 's,$(SRC)/,,g'
|
FILTER = 2>&1 | sed 's,$(SRC)/,,g'
|
||||||
# Filter some always-warning
|
# Filter some always-warning
|
||||||
@ -40,26 +43,55 @@ endif
|
|||||||
ifeq (,$(filter i386 x86_64,$(ARCH)))
|
ifeq (,$(filter i386 x86_64,$(ARCH)))
|
||||||
SKIP += 85_asm-outside-function.test
|
SKIP += 85_asm-outside-function.test
|
||||||
endif
|
endif
|
||||||
|
ifeq (-$(findstring gcc,$(CC)-)-,--)
|
||||||
|
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
|
||||||
|
endif
|
||||||
|
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
|
||||||
|
SKIP += 95_bitfields_ms.test # type_align is differnt on 32bit-non-windows
|
||||||
|
endif
|
||||||
|
|
||||||
all test: $(filter-out $(SKIP),$(TESTS))
|
all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
|
||||||
|
|
||||||
%.test: %.c %.expect
|
%.test: %.c %.expect
|
||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
# test -run
|
@$(if $(NORUN),\
|
||||||
@if test -z "$(NORUN)"; then \
|
($(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)),\
|
||||||
$(TCC) $(FLAGS) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \
|
$(TCC) $(FLAGS) -run $< $(ARGS)\
|
||||||
else \
|
) $(FILTER) >$*.output 2>&1 || true
|
||||||
$(TCC) $(FLAGS) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \
|
@diff -Nbu $(filter %.expect,$^) $*.output \
|
||||||
./$*.exe $(ARGS) >>$*.output 2>&1 || true; \
|
&& rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
|
||||||
fi
|
|
||||||
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe
|
F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
|
||||||
|
F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
|
||||||
|
|
||||||
|
# run single test and update .expect file, e.g. "make tests2.37+"
|
||||||
|
tests2.%+:
|
||||||
|
@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
|
||||||
|
|
||||||
|
# run single test, e.g. "make tests2.37"
|
||||||
|
tests2.%:
|
||||||
|
@$(MAKE) $(call F1,$*) --no-print-directory
|
||||||
|
|
||||||
# automatically generate .expect files with gcc:
|
# automatically generate .expect files with gcc:
|
||||||
%.expect : # %.c
|
%.expect :
|
||||||
(gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) $(FILTER) >$*.expect 2>&1; rm -f a.exe
|
@echo Generating: $@
|
||||||
|
@$(CC) -w -std=gnu99 $(FLAGS) $(SRC)/$*.c -o a.exe
|
||||||
|
@./a.exe $(ARGS) $(FILTER) >$@ 2>&1
|
||||||
|
@rm -f a.exe
|
||||||
|
|
||||||
|
# using the ms compiler for the really ms-compatible bitfields
|
||||||
|
MS-CC = cl
|
||||||
|
95_bitfields_ms.expect :
|
||||||
|
@echo Generating: $@
|
||||||
|
@$(MS-CC) $(basename $@).c
|
||||||
|
@./$(basename $@).exe >$@ 2>&1
|
||||||
|
@rm -f *.exe *.obj *.pdb
|
||||||
|
|
||||||
# tell make not to delete
|
# tell make not to delete
|
||||||
.PRECIOUS: %.expect
|
.PRECIOUS: %.expect
|
||||||
|
|
||||||
|
$(sort $(GEN-ALWAYS) $(UPDATE)) : force
|
||||||
|
force:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f fred.txt *.output a.exe
|
rm -f fred.txt *.output a.exe $(GEN-ALWAYS)
|
||||||
|
Loading…
Reference in New Issue
Block a user