| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactoring (no logical changes):
- use memcpy in tccgen.c:ieee_finite(double d)
- use union to store attribute flags in Sym
Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary
anymore but I left it for now because gcc sometimes behaves
unexpectedly without.
Also:
- configure: back to mode 100755
- tcc.h: remove unused variables tdata/tbss_section
- x86_64-gen.c: adjust gfunc_sret for prototype
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- tccgen: error out for cast to void, as in
void foo(void) { return 1; }
This avoids an assertion failure in x86_64-gen.c, also.
also fix tests2/03_struct.c accordingly
- Error: "memory full" - be more specific
- Makefiles: remove circular dependencies, lookup tcctest.c from VPATH
- tcc.h: cleanup lib, include, crt and libgcc search paths"
avoid duplication or trailing slashes with no CONFIG_MULTIARCHDIR
(as from 9382d6f1a0e2d0104a82ed805207d9e742c6b068)
- tcc.h: remove ";{B}" from PE search path
in ce5e12c2f950052d8109b6b7a56d900547705c08 James Lyon wrote:
"... I'm not sure this is the right way to fix this problem."
And the answer is: No, please. (copying libtcc1.a for tests instead)
- win32/build_tcc.bat: do not move away a versioned file
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The procedure calling standard for ARM architecture mandate the use of
the base standard for variadic function. Therefore, hgen float aggregate
must be returned via stack when greater than 4 bytes and via core
registers else in case of variadic function.
This patch improve gfunc_sret() to take into account whether the
function is variadic or not and make use of gfunc_sret() return value to
determine whether to pass a structure via stack in gfunc_prolog(). It
also take advantage of knowing if a function is variadic or not move
float result value from VFP register to core register in gfunc_epilog().
|
| |
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
- avoid assumption "ret_align == register_size" which is
false for non-arm targets
- rename symbol "sret" to more descriptive "ret_nregs"
This fixes commit dcec8673f21da86ae3dcf1ca3e9498127715b795
Also:
- remove multiple definitions in win32/include/math.h
|
| |
|
|
|
|
|
|
| |
On ARM with hardfloat calling convention, structure containing 4 fields
or less of the same float type are returned via float registers. This
means that a structure can be returned in up to 4 double registers in a
structure is composed of 4 doubles. This commit adds support for return
of structures in several registers.
|
| |
|
|
|
|
|
|
|
|
| |
TLS support in tinyCC is absolutely not ready:
- segment register not select in load and store
- no relocation added for computing offset of per-thread symbol
- no support for TLS-specific relocations
- no program header added as per Drepper document about TLS
This reverts commit 1c4afd13501f07a673aed5f130166f2ee0f30927.
|
| | |
|
| |
|
|
|
| |
Make sure the only exception is for a flexible array member
as the last element of a structure
|
| | |
|
| |
|
|
|
|
|
| |
Prevent the following code from compiling:
enum color {RED, GREEN, BLUE};
enum rgb {RED, G, B};
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Prevent the following code from compiling:
int main(void)
{
enum rgb c = 42;
return c;
}
Reported-by: John Haque <j.eh@mchsi.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Prevent the following code from compiling:
enum color {RED, GREEN, BLUE};
enum color {R, G, B};
int main()
{
return R;
}
Reported-by: John Haque <j.eh@mchsi.com>
|
| |
|
|
|
|
|
|
| |
Prevent the following code from compiling:
int (*fct)[42](int x);
Reported-by: Abdul Wadud Mohammad Mohibur Rashid <mohibur_rashid@yahoo.com>
|
| |
|
|
|
|
|
|
|
| |
Use one more bit in AttributeDef to differenciate between declared
function (only its prototype is known) and defined function (its body is
also known). This allows to generate an error in cases like:
int f(){return 0;}
int f(){return 1;}
|
| |
|
|
|
|
|
|
|
|
|
| |
... as in:
#include<stdio.h>
int main()
{
struct asdasd x;
printf("%d\n", sizeof(x));
}
This fixes commit 17571298f30bf204fafe9cf1aca5258d2d087d63
|
| |
|
|
| |
for compiling tcc with msc
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VLA storage is now freed when it goes out of scope. This makes it
possible to use a VLA inside a loop without consuming an unlimited
amount of memory.
Combining VLAs with alloca() should work as in GCC - when a VLA is
freed, memory allocated by alloca() after the VLA was created is also
freed. There are some exceptions to this rule when using goto: if a VLA
is in scope at the goto, jumping to a label will reset the stack pointer
to where it was immediately after the last VLA was created prior to the
label, or to what it was before the first VLA was created if the label
is outside the scope of any VLA. This means that in some cases combining
alloca() and VLAs will free alloca() memory where GCC would not.
|
| |
|
|
|
| |
tcctest1-3 fail, but this appears to be due to bugs in GCC rather than TCC
(from manual inspection of the output).
|
| |
|
|
|
|
| |
Win32 build and tests work under CMake, however I haven't added
install code yet. Win64 build fails due to chkstk.S failing to
assemble.
|
| |
|
|
| |
Now I need to check that the x86-64 stuff still works.
|
| |
|
|
|
|
|
| |
Also made XMM0-7 available for use as temporary registers, since they
are not used by the ABI. I'd like to do the same with RSI and RDI but
that's trickier since they can be used by gv() as temporary registers
and there isn't a way to disable that.
|
| |
|
|
|
|
| |
All tests pass. I think I've caught all the cases assuming only XMM0 is
used. I expect that Win64 is horribly broken by this point though,
because I haven't altered it to cope with XMM1.
|
| |
|
|
|
|
| |
I've had to introduce the XMM1 register to get the calling convention
to work properly, unfortunately this has broken a fair bit of code
which assumes that only XMM0 is used.
|
| |
|
|
|
|
| |
There are probably still issues on x86-64 I've missed.
I've added a few new tests to abitest, which fail (2x long long and 2x double
in a struct should be passed in registers).
|
| |
|
|
|
|
|
|
|
| |
abitest now passes; however test1-3 fail in init_test. All other tests
pass. I need to re-test Win32 and Linux-x86.
I've added a dummy implementation of gfunc_sret to c67-gen.c so it
should now compile, and I think it should behave as before I created
gfunc_sret.
|
| |
|
|
|
|
|
| |
I expect that Linux-x86 is probably fine. All other architectures
except ARM are definitely broken since I haven't yet implemented
gfunc_sret for these, although replicating the current behaviour
should be straightforward.
|
| |
|
|
|
|
|
|
| |
Should fix some warnings wrt. access out of array bounds.
tccelf.c: fix "static function unused" warning
x86_64-gen.c: fix "ctype.ref uninitialzed" warning and cleanup
tcc-win32.txt: remove obsolete limitation notes.
|
| |
|
|
| |
This reverts commit 93785149ed61b7165510ff30149f297cf0821c88.
|
| | |
|
| |
|
|
| |
This reverts commit 981eb84d8ab91aafe73d5eeb218ffe31d28b1014.
|
| | |
|
| |
|
|
|
|
| |
Initialize the ref field to 0 when manipulating a CType.
Signed-off-by: Thomas Preud'homme <robotux@celest.fr>
|
| |
|
|
|
|
|
|
|
|
| |
This reverts commit 63193d1794b037eb4f3b6551596fa8a6d423e0c3.
Had some problems (_STATIC_ASSERT) and was too ugly anyway.
For retry, I'd suggest to implement a general function
static inline void memswap (void *p1, void* p2, size_t n);
and then use that. If you do so, please keep the original code
as comment.
|
| |
|
|
|
| |
Declare vtopl in vswap at the beginning of the function before any
assignments. Doing otherwise means C99 is assumed when compiling.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This replaces commit 3d409b08893873b917ccb8c34398bc41a4e84d7c
- revert old fix in libtcc.c
- #include_next: look up the file in the include stack to see
if it is already included.
Also:
- streamline include code
- remove 'type' from struct CachedInclude (obsolete because we check
full filename anyway)
- remove inc_type & inc_filename from struct Bufferedfile (obsolete)
- fix bug with TOK_FLAG_ENDIF not being reset
- unrelated: get rid of an 'variable potentially uninitialized' warning
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
vswap() is called often enough and shows in profile and it was easy to
hand optimize swapping vtop[-1] and vtop[0] - instead of large (28 bytes
on i386) tmp variable and two memory to memory copies, let's swap areas
by longs through registers with streamlined assembly.
For
$ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c
before:
# Overhead Command Shared Object Symbol
# ........ ........... ................... ..............................................
#
15.19% tcc tcc [.] next_nomacro1
5.19% tcc libc-2.13.so [.] _int_malloc
4.57% tcc tcc [.] next
3.36% tcc tcc [.] tok_str_add2
3.03% tcc tcc [.] macro_subst_tok
2.93% tcc tcc [.] macro_subst
2.53% tcc tcc [.] next_nomacro_spc
2.49% tcc tcc [.] vswap
2.36% tcc libc-2.13.so [.] _int_free
│ ST_FUNC void vswap(void)
│ {
1,96 │ push %edi
2,65 │ push %esi
1,08 │ sub $0x20,%esp
│ SValue tmp;
│
│ /* cannot let cpu flags if other instruction are generated. Also
│ avoid leaving VT_JMP anywhere except on the top of the stack
│ because it would complicate the code generator. */
│ if (vtop >= vstack) {
0,98 │ mov 0x8078cac,%eax
│ cmp $0x8078d3c,%eax
1,18 │ ┌──jb 24
│ │ int v = vtop->r & VT_VALMASK;
1,08 │ │ mov 0x8(%eax),%edx
0,78 │ │ and $0x3f,%edx
│ │ if (v == VT_CMP || (v & ~1) == VT_JMP)
0,78 │ │ cmp $0x33,%edx
0,69 │ │↓ je 54
0,59 │ │ and $0xfffffffe,%edx
0,49 │ │ cmp $0x34,%edx
0,29 │ │↓ je 54
│ │ gv(RC_INT);
│ │ }
│ │ tmp = vtop[0];
1,08 │24:└─→lea 0x4(%esp),%edi
0,39 │ mov $0x7,%ecx
│ mov %eax,%esi
14,41 │ rep movsl %ds:(%esi),%es:(%edi)
│ vtop[0] = vtop[-1];
9,51 │ lea -0x1c(%eax),%esi
1,96 │ mov $0x7,%cl
│ mov %eax,%edi
17,06 │ rep movsl %ds:(%esi),%es:(%edi)
│ vtop[-1] = tmp;
10,20 │ mov 0x8078cac,%edi
2,35 │ sub $0x1c,%edi
0,78 │ lea 0x4(%esp),%esi
│ mov $0x7,%cl
15,20 │ rep movsl %ds:(%esi),%es:(%edi)
│ }
9,90 │ add $0x20,%esp
2,25 │ pop %esi
1,67 │ pop %edi
0,69 │ ret
after:
# Overhead Command Shared Object Symbol
# ........ ........... ................... ..............................................
#
15.27% tcc tcc [.] next_nomacro1
5.08% tcc libc-2.13.so [.] _int_malloc
4.57% tcc tcc [.] next
3.17% tcc tcc [.] tok_str_add2
3.12% tcc tcc [.] macro_subst
2.99% tcc tcc [.] macro_subst_tok
2.43% tcc tcc [.] next_nomacro_spc
2.32% tcc libc-2.13.so [.] _int_free
. . .
0.71% tcc tcc [.] vswap
│ ST_FUNC void vswap(void)
│ {
7,22 │ push %eax
│ /* cannot let cpu flags if other instruction are generated. Also
│ avoid leaving VT_JMP anywhere except on the top of the stack
│ because it would complicate the code generator. */
│ if (vtop >= vstack) {
11,34 │ mov 0x8078cac,%eax
2,75 │ cmp $0x8078d3c,%eax
0,34 │ ┌──jb 20
│ │ int v = vtop->r & VT_VALMASK;
0,34 │ │ mov 0x8(%eax),%edx
8,93 │ │ and $0x3f,%edx
│ │ if (v == VT_CMP || (v & ~1) == VT_JMP)
2,06 │ │ cmp $0x33,%edx
2,41 │ │↓ je 74
2,41 │ │ and $0xfffffffe,%edx
0,34 │ │ cmp $0x34,%edx
2,41 │ │↓ je 74
│ │ vtopl[-1*VSIZEL + i] = tmpl; \
│ │ } do {} while (0)
│ │
│ │ VSWAPL(15); VSWAPL(14); VSWAPL(13); VSWAPL(12);
│ │ VSWAPL(11); VSWAPL(10); VSWAPL( 9); VSWAPL( 8);
│ │ VSWAPL( 7); VSWAPL( 6); VSWAPL( 5); VSWAPL( 4);
2,06 │20:└─→mov 0x18(%eax),%edx
1,37 │ mov -0x4(%eax),%ecx
2,06 │ mov %ecx,0x18(%eax)
1,37 │ mov %edx,-0x4(%eax)
2,06 │ mov 0x14(%eax),%edx
2,06 │ mov -0x8(%eax),%ecx
2,41 │ mov %ecx,0x14(%eax)
3,09 │ mov %edx,-0x8(%eax)
3,09 │ mov 0x10(%eax),%edx
1,72 │ mov -0xc(%eax),%ecx
2,75 │ mov %ecx,0x10(%eax)
1,72 │ mov %edx,-0xc(%eax)
│ VSWAPL( 3); VSWAPL( 2); VSWAPL( 1); VSWAPL( 0);
2,41 │ mov 0xc(%eax),%edx
2,41 │ mov -0x10(%eax),%ecx
2,41 │ mov %ecx,0xc(%eax)
0,69 │ mov %edx,-0x10(%eax)
1,72 │ mov 0x8(%eax),%edx
0,69 │ mov -0x14(%eax),%ecx
1,03 │ mov %ecx,0x8(%eax)
1,37 │ mov %edx,-0x14(%eax)
1,37 │ mov 0x4(%eax),%edx
0,69 │ mov -0x18(%eax),%ecx
3,09 │ mov %ecx,0x4(%eax)
2,06 │ mov %edx,-0x18(%eax)
1,37 │ mov (%eax),%edx
2,41 │ mov -0x1c(%eax),%ecx
1,37 │ mov %ecx,(%eax)
4,12 │ mov %edx,-0x1c(%eax)
│ }
│
│ # undef VSWAPL
│ # undef VSIZEL
│ }
1,03 │ pop %eax
3,44 │ ret
Overal speedup:
# best of 5 runs
before: 8268 idents, 47203 lines, 1526763 bytes, 0.148 s, 319217 lines/s, 10.3 MB/s
after: 8273 idents, 47231 lines, 1527685 bytes, 0.146 s, 324092 lines/s, 10.5 MB/s
Static ASSERT macro taken from CCAN's[1] build_assert[2] which is in
public domain.
[1] http://ccodearchive.net/
[2] http://git.ozlabs.org/?p=ccan;a=blob;f=ccan/build_assert/build_assert.h;h=24e59c44cd930173178ac9b6e101b0af64a879e9;hb=HEAD
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For vstack Fabrice used the trick to initialize vtop to &vstack[-1], so
that on first push, vtop becomes &vstack[0] and a value is also stored
there - everything works.
Except that when tcc is compiled with bounds-checking enabled, vstack - 1
returns INVALID_POINTER and oops...
Let's workaround it with artificial 1 vstack slot which will not be
used, but only serve as an indicator that pointing to &vstack[-1] is ok.
Now, tcc, after being self-compiled with -b works:
$ ./tcc -B. -o tccb -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" tcc.c -ldl
$ cd tests
$ ../tcc -B.. -run tcctest.c >1
$ ../tccb -B.. -run tcctest.c >2
$ diff -u 1 2
and note, tcc's compilation speed is not affected:
$ ./tcc -B. -bench -DONE_SOURCE -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -c tcc.c
before: 8270 idents, 47221 lines, 1527730 bytes, 0.152 s, 309800 lines/s, 10.0 MB/s
after: 8271 idents, 47221 lines, 1527733 bytes, 0.152 s, 310107 lines/s, 10.0 MB/s
But note, that `tcc -b -run tcc` is still broken - for example it crashes
on
$ cat x.c
double get100 () { return 100.0; }
$ ./tcc -B. -b -DTCC_TARGET_I386 -DCONFIG_MULTIARCHDIR=\"i386-linux-gnu\" -run \
-DONE_SOURCE ./tcc.c -B. -c x.c
Runtime error: dereferencing invalid pointer
./tccpp.c:1953: at 0xa7beebdf parse_number() (included from ./libtcc.c, ./tcc.c)
./tccpp.c:3003: by 0xa7bf0708 next() (included from ./libtcc.c, ./tcc.c)
./tccgen.c:4465: by 0xa7bfe348 block() (included from ./libtcc.c, ./tcc.c)
./tccgen.c:4440: by 0xa7bfe212 block() (included from ./libtcc.c, ./tcc.c)
./tccgen.c:5529: by 0xa7c01929 gen_function() (included from ./libtcc.c, ./tcc.c)
./tccgen.c:5767: by 0xa7c02602 decl0() (included from ./libtcc.c, ./tcc.c)
that's because lib/bcheck.c runtime needs more fixes -- see next
patches.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Continuing d6072d37 (Add __builtin_frame_address(0)) implement
__builtin_frame_address for levels greater than zero, in order for
tinycc to be able to compile its own lib/bcheck.c after
cffb7af9 (lib/bcheck: Prevent __bound_local_new / __bound_local_delete
from being miscompiled).
I'm new to the internals, and used the most simple way to do it.
Generated code is not very good for levels >= 2, compare
gcc tcc
level=0 mov %ebp,%eax lea 0x0(%ebp),%eax
level=1 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
level=2 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov %eax,-0x10(%ebp)
mov -0x10(%ebp),%eax
mov (%eax),%eax
level=3 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov (%eax),%ecx
mov (%eax),%eax mov (%ecx),%eax
But this is still an improvement and for bcheck we need level=1 for
which the code is good.
For the tests I had to force gcc use -O0 to not inline the functions.
And -fno-omit-frame-pointer just in case.
If someone knows how to improve the generated code - help is
appreciated.
Thanks,
Kirill
Cc: Michael Matz <matz@suse.de>
Cc: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
|
| |
|
|
|
| |
Current tcc permits comparison of structs and comparison between
struct and other typed values.
|
| |
|
|
|
| |
Don't reset nocode_wanted with saved_nocode_wanted if it hasn't been
modified (and hence saved_nocode_wanted is uninitialized).
|
| |
|
|
|
| |
Error out when two local variable with same name are defined in the same
scope. This fixes bug #15597 in savannah's BTS.
|
| |
|
|
|
|
|
|
|
|
|
| |
Currently, VLA are not forbidden for static variable. This leads to
problems even if for fixed-size array when the size expression uses the
ternary operator (cond ? then-value : else-value) because it is parsed
as a general expression which leads to code generated in this case.
This commit solve the problem by forbidding VLA for static variables.
Although not required for the fix, avoiding code generation when the
expression is constant would be a nice addition though.
|
| |
|
|
|
|
|
|
|
|
| |
To be able to load a long long value correctly on i386, gv() rely on the
fact that when get_reg() look at an SValue it tries first to free the
register in r2 and then r. More information about the context can be
found at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-06/msg00017.html
and later at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-07/msg00021.html
|
| |
|
|
|
|
| |
The code for shifts is now similar to code for binary arithmetic operations,
except that only the first argument is considered, as required by the ISO C
standard.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On 2012-06-26 15:07:57 +0200, Vincent Lefevre wrote:
> ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
> each of the operands. The type of the result is that of the promoted
> left operand."
I've written a patch (attached). Now the shift problems no longer
occur with the testcase and with GNU MPFR's "make check".
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
|
| |
|
|
|
| |
See Procedure Call Standard for the ARM Architecture (AAPCS) for more
details.
|
| |
|
|
| |
Make vrotb ST_FUNC so that arm-gen.c can use vrotb.
|
| |
|
|
|
|
|
|
|
|
|
| |
Sometimes the result of a comparison is not directly used in a jump,
but in arithmetic or further comparisons. If those further things
do a vswap() with the VT_CMP as current top, and then generate
instructions for the new top, this most probably destroys the flags
(e.g. if it's a bitfield load like in the example).
vswap() must do the same like vsetc() and not allow VT_CMP vtops
to be moved down.
|