The common code to move a returned structure packed into
registers into memory on the caller side didn't take the
register size into account when allocating local storage,
so sometimes that lead to stack overwrites (e.g. in 73_arm64.c),
on x86_64. This fixes it by generally making gfunc_sret also return
the register size.
__clear_cache is defined in lib-arm64.c with a single call to
__arm64_clear_cache, which is the real built-in function and is
turned into inline assembler by gen_clear_cache in arm64-gen.c
More precisely, treat (0 << x) and so on as constant expressions, but
not if const_wanted as we do not want to allow "case (x*0):", ...
Do not optimise (0 / x) and (0 % x) here as x might be zero, though
for an architecture that does not generate an exception for division
by zero the back end might choose to optimise those.
a test program:
struct {
int a[2], b[2];
} cases[] = {
{ ((int)0), (((int)0)) },
((int)0), (((int)0)) /* error: ',' expected (got ")") */
};
int main() { return 0; }
This commit allow to skip ')' in the decl_initializer() and to see ','
A test program:
/* result of the new version inroduced in 4ad186c5ef: t2a = 44100312 */
#include<stdio.h>
int main() {
int t1 = 176401255;
float f = 0.25f;
int t2a = (int)(t1 * f); // must be 44100313
int t2b = (int)(t1 * (float)0.25f);
printf("t2a=%d t2b=%d \n",t2a,t2b);
return 0;
}
* Don't use /usr/local/lib/tcc/libtcc1.a for i386 and x86_64
A $(tccdir)/i386 directory was used to install a libtcc1.a
but only when cross compiling. And no x86_64 directory.
* Build/install i386-tcc/x86_64-tcc and not a tcc
* Build/install i386-win-tcc/x86_64-win-tcc and not a i386-win-mingw32-tcc/...
* DEFINES = -DTCC_TARGET_I386... also for i386-tcc and i386-win-tcc
* Make a symlink tcc to the i386-tcc/x86_64-tcc for a "make test"
* Build a $(ARCH) directory with a symlink to the libtcc1.a for a "make test"
* Remove a /usr/local/lib/tcc directory on uninstall
* Remove a /usr/local/share/doc/tcc directory on uninstall
* Remove a $(ARCH) directory on "make clean"
* Remove a *-tcc files on "make clean"
produce a
i386-win-mingw32-tcc
i386-win-tcc
x86_64-win-mingw32-tcc
x86_64-win-tcc
arm-win-mingw32ce-tcc
arm-win-tcc
instead of the
i386-w64-mingw32-tcc
i386-win32-tcc
x86_64-w64-mingw32-tcc
x86_64-win32-tcc
arm-wince-mingw32ce-tcc
arm-win32-tcc
Replacing a *-win32 directory names with a *-win names
because this names are based on the names of the tcc
x86_64-win32-tcc, i386-win32-tcc
* x86_64-tcc: use /usr/lib64,.. instead of /usr/lib,..
* don't set tcc_lddir="lib64" if cpu="x86"
* put a definition of the CONFIG_LDDIR into config.h instead
of the config.mak Otherwise a "lib" string may be used by default.
This is a usual case when building a x86_64-tcc (there was
no -DCONFIG_LDDIR building this binary).
* suppress -Wdeprecated-declarations for gcc which complain on malloc hooks
in bcheck.c if glibc is quite new.
Set CONFIG_MULTIARCHDIR for cross compilers.
Chances a cross-compiler will find a working crt*.o
in /usr/lib are more or less 0.
This commit breaks x86 / x86_64 compilres for linux. A solution for the crt*.o
must be discussed.
must be:
# ./x86_64-tcc -vv
tcc version 0.9.26 (x86-64, Linux)
install: /usr/local/lib/tcc
crt:
/usr/lib64
libraries:
/usr/lib64
/lib64
/usr/local/lib64
include:
/usr/local/include
/usr/include
/usr/local/lib/tcc/include
elfinterp:
/lib64/ld-linux-x86-64.so.2
and with MULTIARCH we have:
# ./x86_64-tcc -vv
tcc version 0.9.26 (x86-64 Linux)
install: /usr/local/lib/tcc/
crt:
/usr/lib/x86_64-linux-gnu ???????????????????
libraries:
/usr/lib/x86_64-linux-gnu
/usr/lib ???????????????????
/lib/x86_64-linux-gnu
/lib ???????????????????
/usr/local/lib/x86_64-linux-gnu
/usr/local/lib ???????????????????
include:
/usr/local/include/x86_64-linux-gnu
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
/usr/local/lib/tcc/include
elfinterp:
/lib64/ld-linux-x86-64.so.2
And CONFIG_MULTIARCHDIR don't handle C67.
On Linux x86 we have:
# ./c67-tcc -vv
tcc version 0.9.26 (C67, Linux)
install: /usr/local/lib/tcc
crt:
/usr/lib
libraries:
/usr/lib
/lib
/usr/local/lib
include:
/usr/local/include
/usr/include
/usr/local/lib/tcc/include
elfinterp:
/lib/ld-linux.so.2
* don't setup a cpu before scanning for --cpu=
* --cpu= option sets a 'cpu' variable, not a 'build_cpu', 'build_cpu' was not used anywhere.
* if cpu="" and ARCH != "" then cpu=$ARCH else cpu=`uname -m`
* replace "Build CPU" with "Target CPU" in the output of the configure script.
output this value only when not builing a cross compilers.
* remove a HOST_I386, ... defines from a config.h file.
thise defines are not used anywhere and cpu is now used to define a target cpu
From: Matteo Cypriani <mcy@lm7.fr>
Date: Fri, 5 Sep 2014 23:22:56 -0400
Subject: Disable floating-point test for ARM soft-float
tcc is not yet capable of doing softfloat floating-point operations on
ARM, therefore we disable this test for these platforms. Note that tcc
displays a warning to warn ARM users about this limitation
(debian)
Win32, Win64, WinCE when executing "tcc -v". Example
$ ./i386-win-tcc -v
tcc version 0.9.26 (i386, mingw)
instead of the
tcc version 0.9.26 (i386, Win32)
There is a cpu info already about bits of the excution environment
And display C67 for the TCC_TARGET_C67
Don't use /usr/local/lib/tcc/libtcc1.a for i386 and x86_64
A $(tccdir)/i386 directory was used to install a libtcc1.a
but only when cross compiling. And no x86_64 directory.
And this directory location was unknown inside tccelf.c
From: Matteo Cypriani <mcy@lm7.fr>
Date: Fri, 5 Sep 2014 23:22:56 -0400
Subject: Disable floating-point test for ARM soft-float
tcc is not yet capable of doing softfloat floating-point operations on
ARM, therefore we disable this test for these platforms. Note that tcc
displays a warning to warn ARM users about this limitation
(debian)
arm-gen.c: In function `gfunc_call':
arm-gen.c:1202: warning: unused variable `variadic'
arm-gen.c: In function `gfunc_prolog':
arm-gen.c:1258: warning: unused variable `avregs'
arm-gen.c:1340: warning: label `from_stack' defined but not used
arm-gen.c:222: warning: 'default_elfinterp' defined but not used
A non declared function leads to a seriuos problems. And while
gcc don't turn this warning on lets tcc do it. This warning
can be turned off by -Wno-implicit-function-declaration option.
And autor must explicitly do this if program must be compiled
with this warning off.
tcc version 0.9.26 (i386 Linux)
Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard
Usage: tcc [options...] [-o outfile] [-c] infile(s)...
tcc [options...] -run infile [arguments...]
...
instead of the
tcc version 0.9.26 - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard
Usage: tcc [options...] [-o outfile] [-c] infile(s)...
tcc [options...] -run infile [arguments...]
...
Displaing a "Hard Float" info for the ARM arch is restored. It was broken by the AArm64 patch.
Author: Thomas Preud'homme <robotux@celest.fr>
Date: Tue Dec 31 23:51:20 2013 +0800
Move logic for if (int value) to tccgen.c
Move the logic to do a test of an integer value (ex if (0)) out of
arch-specific code to tccgen.c to avoid code duplication. This also
fixes test of long long value which was only testing the bottom half of
such values on 32 bits architectures.
I don't understand why if () in gtst(i) was removed.
This patch allows to compile a linux kernel v.2.4.26
W/o this patch a tcc simply crashes.
A test program:
//////////////
int main()
{
void *p = ({ 0 ; ((void *)1); });
}
/////////////
Porblem is introduced in a commit a80acab: Display error on statement expressions with complex return type
This error is exposed when compiling a linux 2.4.26. tcc 0.9.23 can sucessfully compile
this version of the linux.
Current tcc don't understand an initialization of the empty struct
This problem was found trying to compile a linux kernel 2.4.26
which can be compiled by tcc 0.9.23
A test program:
////////////////////
// ./tcc -c test_3.c
// test_3.c:31: error: too many field init
#undef __GNUC__
#undef __GNUC_MINOR__
#define __GNUC__ 2
#define __GNUC_MINOR__ 95
typedef struct { } rwlock_t;
struct fs_struct {
int count;
rwlock_t lock;
int umask;
};
#define INIT_FS { \
1, \
RW_LOCK_UNLOCKED, \
0022, \
}
#if (__GNUC__ > 2 || __GNUC_MINOR__ > 91)
typedef struct { } rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { }
#else
typedef struct { int gcc_is_buggy; } rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
#endif
static struct fs_struct init_fs = INIT_FS;
// static struct fs_struct init_fs = { { (1) }, (rwlock_t) { 0 }, 0022, };
// ^ with this all Ok
// static struct fs_struct init_fs = { { (1) }, (rwlock_t) { }, 0022, };
// ^ current tcc don't understand, but tcc 0.9.23 can
int main()
{
return 0;
}
////////////////////
A regression is detected after a patch 69fdb57edd
////////////////////
// A test for patch 69fdb57edd
// Author: grischka <grischka>
// Date: Wed Jun 17 02:09:07 2009 +0200
// unions: initzialize only one field
// struct {
// union {
// int a,b;
// };
// int c;
// } sss = { 1,2 };
// This had previously assigned 1,2 to a,b and 0 to c which is wrong.
//
// Expected: sss.a=1 sss.b=1 sss.c=2
int main()
{
struct {
union {
int a,b;
};
int c;
} sss = { 1, 2 };
printf ("sss.a=%d sss.b=%d sss.c=%d\n", sss.a, sss.b, sss.c);
return 0;
}
////////////////////
A regression was found trying to compile a linux kernel 2.4.26
which can be compiled by tcc 0.9.23
///////////////////
#include <stdio.h>
// test for a bug:
// compiler don't understand am extern array of structs
// $ tcc test_1.c
// test_1.c:8: error: unknown struct/union/enum
extern struct FILE std_files[4];
int main()
{
return 0;
}
//////////////////
tcc-current
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
static void struct_decl(CType *type, int u, int tdef)
...
if (tok != '{') {
v = tok;
next();
/* struct already defined ? return it */
if (v < TOK_IDENT)
expect("struct/union/enum name");
s = struct_find(v);
if (s) {
if (s->type.t != a)
tcc_error("invalid type");
goto do_decl;
} else if (tok >= TOK_IDENT && !tdef)
tcc_error("unknown struct/union/enum");
} else {
v = anon_sym++;
}
tcc-0.9.23 which don't have such error
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
static void struct_decl(CType *type, int u)
....
if (tok != '{') {
v = tok;
next();
/* struct already defined ? return it */
if (v < TOK_IDENT)
expect("struct/union/enum name");
s = struct_find(v);
if (s) {
if (s->type.t != a)
error("invalid type");
goto do_decl;
}
} else {
v = anon_sym++;
}