long double on risc-v is 128bit, but there are no registers
for that type (without the Q ISA extension). They are passed
like two 64bit integers values (with an exception for varargs,
where it's an aligned register pair). This all requires some
hacks in generic code as otherwise RC_FLOAT regs are tried for
holding values of long double type, but we need a RC_INT register
pair. This really could all use some cleanup for all archs.
This doesn't implement any conversions of operations for long
double, but it's enough to get 70_floating_point_literals working.
* more ops: umod and udiv
* large immediates: suboptimal code, e.g. when loading
0xffffffffU (which is what a cast from long to int does).
tests2 work up to 67_macro_concat.
* load/store of FP ops
* load/store from symbols, VT_LLOCAL, some with large addend
* load of VT_JMP result
* calls with many args (stack slots)
* calls with FP args
* more operations: and/or/xor/div
* register indirect loads and stores
* load of local addresses
* indirect calls (uses ra as temporary reg if necessary)
* operations *, -, <<
* gen_cvt_sxtw: is not needed in most cases, let's see
tests2 runs until (incl) 09_do_while.
* implement compares, gtst and gsym/gjmp and add
* implement stores (simple cases)
* fix arg passing with more than one register arg, fix
loads to not always use 8byte loads
* add some predefined macros: __riscv, __riscv_xlen,
__SIZEOF_POINTER__ (needed by glibc header)
The first 5 tests of tests2 run now.
this is enough to let me link a tcctest.c compiled by GCC
using some current debian sid riscv64 system. It needs
linking against libgcc.a for various floating point TFmode
routines. The result runs.
the uninitialized cumofs was leading to random sizes for
the memset when initializing local structures, potentially
leading to segfaults from it. Only a problem with GNU
designated initializers, which we didn't test very well.
See testcase.
- libtcc.c/tccpp.c: fix -U option for multiple input files
- libtcc: remove decl of tcc_add_crt() for PE
- tcc.h: define __i386__ and __x86_64__ for msvc
- tcc.h: undef __attribute__ for __TINYC__ on gnu/linux platforms
- tccelf.c: disable prepare_dynamic_rel unless x86/x64
- tccpe.c: construct rather than predefine PE section flags
- tccpp.c: (alt.) fix access of dead stack variable after error/longjmp
- x86_64-gen.c: fix func_alloca chain for nocode_wanted
- tccpp.c/tccgen.c: improve file:line info for inline functions
- winapi/winnt.h: correct position for DECLSPEC_ALIGN attribute
- win32/lib/crt: simplify top exception handler (needed for signal)
- arm64-gen.c: remove dprintf left from VT_CMP commit
- tccgen.c: limit binary scan with gcase to > 8 (= smaller code)
- tccgen.c: call save_regs(4) in gen_opl for cmp-ops (see test in tcctest.c)
This removes a spurious \r at $gcc_{major,minor} in configure on cygwin.
Details:
The EOL output of conftest.exe for windows was \r\n . Now it's only \n .
The output of conftest is used with sh command substitutions which trim
trailing newlines, but not all windows shells consider \r\n as newline.
E.g. msys2 and busybox (for windows) were designed for tight integration
with windows apps and their shells do trim \r\n, but cygwin sh is closer
to POSIX and trims only \n - leaving \r at the string.
Adds a tool `ppif` at configure which can test preprocessor conditions
even when $cc is a cross compiler to any foreign platform.
Currently used only to identify i386 or x86_64 (including when cross
compiling) as a mini-demonstration.
Hopefully will be used in the future to test more compiler features
and/or replace uname-related tests with more accurate results.
A more automatic approach to code suppression (aka. nocode_wanted)
The simple rules are:
- Clear 'nocode_wanted' at (im/explicit) label IF it was used
- Set 'nocode_wanted' after unconditional jumps
Also in order to test this then I did add the "function might
return no value" warning, and then to make that work again I
did add the __attribute__((noreturn)).
Also moved the look ahead label check into the type parser
to gain a little speed.
Example:
int a = 1;
void f(void)
{
int a = 2;
{
extern int a; // = 1 !!
....
To get this (more) correctly there is a new function to copy
syms between local to global stacks.
Also, this patch changes the meaning of VT_EXTERN back
to the simpler and IMO more useful notion of
DECLARED but not (yet) DEFINED.
and that for both variables and functions. That is, VT_EXTERN
in tcc doesn't have to do with the keyword 'extern' necessarily.
Also this patch does allow
int x[];
as alias for
extern int x[];
(as do gcc and msvc)
new glibc really can't avoid it anymore, so let's provide it.
I've tried doing it only on systems that possibly are glibc
based. (For others it would be harmless as it simply wouldn't
be picked up from libtcc1.a)
... which IMO are:
1) files don't need a _test suffix because all files in
the directory are tests ;)
2) we test the BEHAVIOR of the program, rather than its
binary bit contents.
Ok, but nobody said a test can't use two files ;)
(where the 104+_ construct is meant to prevent the file
from being picked up by the makefile as a test on its own).
Previously test 104 used a combination of *nix tools and system() calls
to emulate a `sh` script, which required split code paths for windows
due to different shell and different absolute path representation.
Also, it used a hardcoded tcc binary path, didn't set locale for sort.
Now the tools are used from a `sh` script which the program generates
and invokes, tmp files are at CWD and no conversion is required, tcc
path is taken from Makefile (exported), and `sort` uses LC_ALL=C.
my last inline changes caused parameter names to be overwritten
always (as VT_EXTERN now doesn't mark the current def anymore),
leading to a compile error when including windows.h. Rework this.
Also silence a warning that currently happens for mingw, which is
written with gnu-inline behaviour in mind. Our work-arounds
of using "static inline" actually create invalid C (which we warn
about). Until we implement this properly, just silence the warning.
there's no need for two new flags in type.t . We just can't use
VT_EXTERN as marker if functions are defined or not (like we can
for objects), and then can simply implement the rules of C99/C11
by not overwriting VT_STATIC/VT_EXTERN at all but rather only
look at them. A function already on the inline list can be
forced by removing the VT_INLINE flag, and then linkage
follows from some combination of VT_STATIC, VT_EXTERN and VT_INLINE.
build_got might realloc the symbol table (for the _GLOBAL_OFFSET_TABLE_
symbol), so we can't reuse sym (a pointer into it) after build_got.
Using it isn't necessary, as we pass the sym_index to put_got_entry,
and that recomputes sym.
By always instantiating extern inlines, the patch has discovered
2 assembly errors, which were fixed in the original mingw64 in 2009.
This fixes those errors.
Additionally it changes __CRT_INLINE in win32/include/_mingw.h
from `extern __inline__` to `static __inline__`.
__CRT_INLINE is used exclusively in header files and as such
it should not create externally visible instantiations like a `extern
inline` would (as per the C standard).
- add tests for standard conformant inline functions
- implement it
The old tinycc failed to provide a conforming implementation
of non-static inlines. It would expose external symbols where it
shouldn't and hide them where it should expose them.
This commit provides a hopefully comprehensive test suite
for how things should be done. The .expect file can be obtained
by compiling the example c file (embedded in the test)
with a conforming compiler such as gcc, clang or icc and then
printing the exported symbols (e.g., with nm+awk+sort).
(The implementation currently reserves two new VT_ flags.
If anyone can provide an implementation without reserving
two extra flags, please replace mine.)
The macro conflicts (=> redef warnings in a simple hello world)
with a definition introduced by glibc headers and
it's probably not "necessary" anyway since clang doesn't use it.