mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
tcctest.c: sizeof (long) != 8
Bad assumption make bad things happen: long d3; asm(..."1:\tdec %3\n\t" : ... "=&c" (d3) Which wants 'dec RDI' but did 'dec EDI' on _WIN64. Also: - tcctest.c: enable more asm tests for win64 - configure: show errors if any with 'gcc conftest.c' - tccgen.c: remove decl0(x, y, z)
This commit is contained in:
parent
c60f1d953c
commit
bb80cbe0d9
2
configure
vendored
2
configure
vendored
@ -357,7 +357,7 @@ fi
|
|||||||
|
|
||||||
if test -z "$cross_prefix" ; then
|
if test -z "$cross_prefix" ; then
|
||||||
CONFTEST=./conftest$EXESUF
|
CONFTEST=./conftest$EXESUF
|
||||||
if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
|
if ! $cc -o $CONFTEST $source_path/conftest.c ; then
|
||||||
echo "configure: error: '$cc' failed to compile conftest.c."
|
echo "configure: error: '$cc' failed to compile conftest.c."
|
||||||
else
|
else
|
||||||
cc_name="$($CONFTEST compiler)"
|
cc_name="$($CONFTEST compiler)"
|
||||||
|
43
tccgen.c
43
tccgen.c
@ -130,8 +130,7 @@ static void init_putv(init_params *p, CType *type, unsigned long c);
|
|||||||
static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags);
|
static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags);
|
||||||
static void block(int is_expr);
|
static void block(int is_expr);
|
||||||
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
|
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
|
||||||
static void decl(int l);
|
static int decl(int l);
|
||||||
static int decl0(int l, int is_for_loop_init, Sym *);
|
|
||||||
static void expr_eq(void);
|
static void expr_eq(void);
|
||||||
static void vpush_type_size(CType *type, int *a);
|
static void vpush_type_size(CType *type, int *a);
|
||||||
static int is_compatible_unqualified_types(CType *type1, CType *type2);
|
static int is_compatible_unqualified_types(CType *type1, CType *type2);
|
||||||
@ -6881,7 +6880,7 @@ again:
|
|||||||
skip('(');
|
skip('(');
|
||||||
if (tok != ';') {
|
if (tok != ';') {
|
||||||
/* c99 for-loop init decl? */
|
/* c99 for-loop init decl? */
|
||||||
if (!decl0(VT_LOCAL, 1, NULL)) {
|
if (!decl(VT_JMP)) {
|
||||||
/* no, regular for-loop init expr */
|
/* no, regular for-loop init expr */
|
||||||
gexpr();
|
gexpr();
|
||||||
vpop();
|
vpop();
|
||||||
@ -7795,7 +7794,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f
|
|||||||
is put in the value stack. If 'has_init' is 2, a special parsing
|
is put in the value stack. If 'has_init' is 2, a special parsing
|
||||||
is done to handle string constants. */
|
is done to handle string constants. */
|
||||||
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
int has_init, int v, int scope)
|
int has_init, int v, int global)
|
||||||
{
|
{
|
||||||
int size, align, addr;
|
int size, align, addr;
|
||||||
TokenString *init_str = NULL;
|
TokenString *init_str = NULL;
|
||||||
@ -7932,7 +7931,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sym = NULL;
|
sym = NULL;
|
||||||
if (v && scope == VT_CONST) {
|
if (v && global) {
|
||||||
/* see if the symbol was already defined */
|
/* see if the symbol was already defined */
|
||||||
sym = sym_find(v);
|
sym = sym_find(v);
|
||||||
if (sym) {
|
if (sym) {
|
||||||
@ -8198,9 +8197,10 @@ static void free_inline_functions(TCCState *s)
|
|||||||
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
|
dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
|
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
||||||
if parsing old style parameter decl list (and FUNC_SYM is set then) */
|
or VT_CMP if parsing old style parameter list
|
||||||
static int decl0(int l, int is_for_loop_init, Sym *func_sym)
|
or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
|
||||||
|
static int decl(int l)
|
||||||
{
|
{
|
||||||
int v, has_init, r, oldint;
|
int v, has_init, r, oldint;
|
||||||
CType type, btype;
|
CType type, btype;
|
||||||
@ -8236,7 +8236,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
|
|||||||
|
|
||||||
oldint = 0;
|
oldint = 0;
|
||||||
if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) {
|
if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) {
|
||||||
if (is_for_loop_init)
|
if (l == VT_JMP)
|
||||||
return 0;
|
return 0;
|
||||||
/* skip redundant ';' if not in old parameter decl scope */
|
/* skip redundant ';' if not in old parameter decl scope */
|
||||||
if (tok == ';' && l != VT_CMP) {
|
if (tok == ';' && l != VT_CMP) {
|
||||||
@ -8288,13 +8288,15 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((type.t & VT_BTYPE) == VT_FUNC) {
|
if ((type.t & VT_BTYPE) == VT_FUNC) {
|
||||||
if ((type.t & VT_STATIC) && (l == VT_LOCAL))
|
if ((type.t & VT_STATIC) && (l != VT_CONST))
|
||||||
tcc_error("function without file scope cannot be static");
|
tcc_error("function without file scope cannot be static");
|
||||||
/* if old style function prototype, we accept a
|
/* if old style function prototype, we accept a
|
||||||
declaration list */
|
declaration list */
|
||||||
sym = type.ref;
|
sym = type.ref;
|
||||||
if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
|
if (sym->f.func_type == FUNC_OLD && l == VT_CONST) {
|
||||||
decl0(VT_CMP, 0, sym);
|
func_vt = type;
|
||||||
|
decl(VT_CMP);
|
||||||
|
}
|
||||||
#if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID
|
#if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID
|
||||||
if (sym->f.func_alwinl
|
if (sym->f.func_alwinl
|
||||||
&& ((type.t & (VT_EXTERN | VT_INLINE))
|
&& ((type.t & (VT_EXTERN | VT_INLINE))
|
||||||
@ -8388,12 +8390,12 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
|
|||||||
} else {
|
} else {
|
||||||
if (l == VT_CMP) {
|
if (l == VT_CMP) {
|
||||||
/* find parameter in function parameter list */
|
/* find parameter in function parameter list */
|
||||||
for (sym = func_sym->next; sym; sym = sym->next)
|
for (sym = func_vt.ref->next; sym; sym = sym->next)
|
||||||
if ((sym->v & ~SYM_FIELD) == v)
|
if ((sym->v & ~SYM_FIELD) == v)
|
||||||
goto found;
|
goto found;
|
||||||
tcc_error("declaration for parameter '%s' but no such parameter",
|
tcc_error("declaration for parameter '%s' but no such parameter",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
found:
|
found:
|
||||||
if (type.t & VT_STORAGE) /* 'register' is okay */
|
if (type.t & VT_STORAGE) /* 'register' is okay */
|
||||||
tcc_error("storage class specified for '%s'",
|
tcc_error("storage class specified for '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
@ -8460,20 +8462,20 @@ found:
|
|||||||
esym->st_value, esym->st_size, 1);
|
esym->st_value, esym->st_size, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type.t & VT_STATIC)
|
if (l == VT_CONST || (type.t & VT_STATIC))
|
||||||
r |= VT_CONST;
|
r |= VT_CONST;
|
||||||
else
|
else
|
||||||
r |= l;
|
r |= VT_LOCAL;
|
||||||
if (has_init)
|
if (has_init)
|
||||||
next();
|
next();
|
||||||
else if (l == VT_CONST)
|
else if (l == VT_CONST)
|
||||||
/* uninitialized global variables may be overridden */
|
/* uninitialized global variables may be overridden */
|
||||||
type.t |= VT_EXTERN;
|
type.t |= VT_EXTERN;
|
||||||
decl_initializer_alloc(&type, &ad, r, has_init, v, l);
|
decl_initializer_alloc(&type, &ad, r, has_init, v, l == VT_CONST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tok != ',') {
|
if (tok != ',') {
|
||||||
if (is_for_loop_init)
|
if (l == VT_JMP)
|
||||||
return 1;
|
return 1;
|
||||||
skip(';');
|
skip(';');
|
||||||
break;
|
break;
|
||||||
@ -8485,11 +8487,6 @@ found:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decl(int l)
|
|
||||||
{
|
|
||||||
decl0(l, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
#undef gjmp_addr
|
#undef gjmp_addr
|
||||||
#undef gjmp
|
#undef gjmp
|
||||||
|
@ -3251,10 +3251,12 @@ void local_label_test(void)
|
|||||||
/* inline assembler test */
|
/* inline assembler test */
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
|
||||||
|
typedef __SIZE_TYPE__ word;
|
||||||
|
|
||||||
/* from linux kernel */
|
/* from linux kernel */
|
||||||
static char * strncat1(char * dest,const char * src,size_t count)
|
static char * strncat1(char * dest,const char * src,size_t count)
|
||||||
{
|
{
|
||||||
long d0, d1, d2, d3;
|
word d0, d1, d2, d3;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"repne\n\t"
|
"repne\n\t"
|
||||||
"scasb\n\t"
|
"scasb\n\t"
|
||||||
@ -3276,7 +3278,7 @@ return dest;
|
|||||||
|
|
||||||
static char * strncat2(char * dest,const char * src,size_t count)
|
static char * strncat2(char * dest,const char * src,size_t count)
|
||||||
{
|
{
|
||||||
long d0, d1, d2, d3;
|
word d0, d1, d2, d3;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"repne scasb\n\t" /* one-line repne prefix + string op */
|
"repne scasb\n\t" /* one-line repne prefix + string op */
|
||||||
"dec %1\n\t"
|
"dec %1\n\t"
|
||||||
@ -3297,7 +3299,7 @@ return dest;
|
|||||||
|
|
||||||
static inline void * memcpy1(void * to, const void * from, size_t n)
|
static inline void * memcpy1(void * to, const void * from, size_t n)
|
||||||
{
|
{
|
||||||
size_t d0, d1, d2;
|
word d0, d1, d2;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"rep ; movsl\n\t"
|
"rep ; movsl\n\t"
|
||||||
"testb $2,%b4\n\t"
|
"testb $2,%b4\n\t"
|
||||||
@ -3308,14 +3310,14 @@ __asm__ __volatile__(
|
|||||||
"movsb\n"
|
"movsb\n"
|
||||||
"2:"
|
"2:"
|
||||||
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
||||||
:"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from)
|
:"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from)
|
||||||
: "memory");
|
: "memory");
|
||||||
return (to);
|
return (to);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void * memcpy2(void * to, const void * from, size_t n)
|
static inline void * memcpy2(void * to, const void * from, size_t n)
|
||||||
{
|
{
|
||||||
size_t d0, d1, d2;
|
word d0, d1, d2;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"rep movsl\n\t" /* one-line rep prefix + string op */
|
"rep movsl\n\t" /* one-line rep prefix + string op */
|
||||||
"testb $2,%b4\n\t"
|
"testb $2,%b4\n\t"
|
||||||
@ -3326,7 +3328,7 @@ __asm__ __volatile__(
|
|||||||
"movsb\n"
|
"movsb\n"
|
||||||
"2:"
|
"2:"
|
||||||
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
||||||
:"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from)
|
:"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from)
|
||||||
: "memory");
|
: "memory");
|
||||||
return (to);
|
return (to);
|
||||||
}
|
}
|
||||||
@ -3395,12 +3397,12 @@ struct struct123 {
|
|||||||
int b;
|
int b;
|
||||||
};
|
};
|
||||||
struct struct1231 {
|
struct struct1231 {
|
||||||
unsigned long addr;
|
word addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long mconstraint_test(struct struct1231 *r)
|
word mconstraint_test(struct struct1231 *r)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
word ret;
|
||||||
unsigned int a[2];
|
unsigned int a[2];
|
||||||
a[0] = 0;
|
a[0] = 0;
|
||||||
__asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
|
__asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
|
||||||
@ -3422,11 +3424,11 @@ int fls64(unsigned long long x)
|
|||||||
|
|
||||||
void other_constraints_test(void)
|
void other_constraints_test(void)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
word ret;
|
||||||
int var;
|
int var;
|
||||||
#if !defined(_WIN64) && CC_NAME != CC_clang
|
#if CC_NAME != CC_clang
|
||||||
__asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
|
__asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
|
||||||
printf ("oc1: %d\n", ret == (unsigned long)&var);
|
printf ("oc1: %d\n", ret == (word)&var);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3510,6 +3512,7 @@ void asm_local_label_diff (void)
|
|||||||
printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
|
printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This checks that static local variables are available from assembler. */
|
/* This checks that static local variables are available from assembler. */
|
||||||
void asm_local_statics (void)
|
void asm_local_statics (void)
|
||||||
@ -3518,7 +3521,6 @@ void asm_local_statics (void)
|
|||||||
asm("incl %0" : "+m" (localint));
|
asm("incl %0" : "+m" (localint));
|
||||||
printf ("asm_local_statics: %d\n", localint);
|
printf ("asm_local_statics: %d\n", localint);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static
|
static
|
||||||
unsigned int set;
|
unsigned int set;
|
||||||
@ -3533,7 +3535,7 @@ void fancy_copy2 (unsigned *in, unsigned *out)
|
|||||||
asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
|
asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __x86_64__ && !defined _WIN64
|
#if defined __x86_64__
|
||||||
void clobber_r12(void)
|
void clobber_r12(void)
|
||||||
{
|
{
|
||||||
asm volatile("mov $1, %%r12" ::: "r12");
|
asm volatile("mov $1, %%r12" ::: "r12");
|
||||||
@ -3542,9 +3544,9 @@ void clobber_r12(void)
|
|||||||
|
|
||||||
void test_high_clobbers_really(void)
|
void test_high_clobbers_really(void)
|
||||||
{
|
{
|
||||||
#if defined __x86_64__ && !defined _WIN64
|
#if defined __x86_64__
|
||||||
register long val asm("r12");
|
register word val asm("r12");
|
||||||
long val2;
|
word val2;
|
||||||
/* This tests if asm clobbers correctly save/restore callee saved
|
/* This tests if asm clobbers correctly save/restore callee saved
|
||||||
registers if they are clobbered and if it's the high 8 x86-64
|
registers if they are clobbered and if it's the high 8 x86-64
|
||||||
registers. This is fragile for GCC as the constraints do not
|
registers. This is fragile for GCC as the constraints do not
|
||||||
@ -3558,8 +3560,8 @@ void test_high_clobbers_really(void)
|
|||||||
|
|
||||||
void test_high_clobbers(void)
|
void test_high_clobbers(void)
|
||||||
{
|
{
|
||||||
#if defined __x86_64__ && !defined _WIN64
|
#if defined __x86_64__
|
||||||
long x1, x2;
|
word x1, x2;
|
||||||
asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */
|
asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */
|
||||||
test_high_clobbers_really();
|
test_high_clobbers_really();
|
||||||
asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */
|
asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */
|
||||||
@ -3625,7 +3627,7 @@ void trace_console(long len, long len2)
|
|||||||
|
|
||||||
void test_asm_dead_code(void)
|
void test_asm_dead_code(void)
|
||||||
{
|
{
|
||||||
long rdi;
|
word rdi;
|
||||||
/* Try to make sure that xdi contains a zero, and hence will
|
/* Try to make sure that xdi contains a zero, and hence will
|
||||||
lead to a segfault if the next asm is evaluated without
|
lead to a segfault if the next asm is evaluated without
|
||||||
arguments being set up. */
|
arguments being set up. */
|
||||||
@ -3727,12 +3729,12 @@ void asm_test(void)
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
unsigned int val, val2;
|
unsigned int val, val2;
|
||||||
struct struct123 s1;
|
struct struct123 s1;
|
||||||
struct struct1231 s2 = { (unsigned long)&s1 };
|
struct struct1231 s2 = { (word)&s1 };
|
||||||
/* Hide the outer base_func, but check later that the inline
|
/* Hide the outer base_func, but check later that the inline
|
||||||
asm block gets the outer one. */
|
asm block gets the outer one. */
|
||||||
int base_func = 42;
|
int base_func = 42;
|
||||||
void override_func3 (void);
|
void override_func3 (void);
|
||||||
unsigned long asmret;
|
word asmret;
|
||||||
#ifdef BOOL_ISOC99
|
#ifdef BOOL_ISOC99
|
||||||
_Bool somebool;
|
_Bool somebool;
|
||||||
#endif
|
#endif
|
||||||
@ -3783,8 +3785,8 @@ void asm_test(void)
|
|||||||
printf("asmstr: %s\n", get_asm_string());
|
printf("asmstr: %s\n", get_asm_string());
|
||||||
asm_local_label_diff();
|
asm_local_label_diff();
|
||||||
#endif
|
#endif
|
||||||
asm_local_statics();
|
|
||||||
#endif
|
#endif
|
||||||
|
asm_local_statics();
|
||||||
#ifndef __clang__
|
#ifndef __clang__
|
||||||
/* clang can't deal with the type change */
|
/* clang can't deal with the type change */
|
||||||
/* Check that we can also load structs of appropriate layout
|
/* Check that we can also load structs of appropriate layout
|
||||||
|
Loading…
Reference in New Issue
Block a user