| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
If a symbolic reference is offsetted by a constant > 32bit
the backends can't deal with that, so don't construct such
values.
|
| |
|
|
|
|
|
| |
The callee saved registers (among them r12-r15) really need
saving/restoring if mentioned in asm clobbers, even if TCC
itself doesn't use them. E.g. the linux kernel relies on that
in its switch_to() implementation.
|
| |
|
|
|
|
|
|
|
| |
Similar to GCC a local asm register variable enforces the use of a
specified register in asm operands (and doesn't otherwise
matter). Works only if the variable is directly mentioned as
operand. For that we now generally store a backpointer from
an SValue to a Sym when the SValue was the result of unary()
parsing a symbol identifier.
|
| |
|
|
| |
See testcase.
|
| |
|
|
|
| |
A pointer is 64 bit as well, so it needs a full
register for register operands.
|
| |
|
|
|
|
| |
If the destination is an indirect pointer access (which ends up
as VT_LLOCAL) the intermediate pointer must be loaded as VT_PTR,
not as whatever the pointed to type is.
|
| |
|
|
|
| |
Inside dead code don't regard inline functions as being
referenced.
|
| |
|
|
|
| |
Our architectures don't need anything special for this
builtin, just pass through the argument.
|
| |
|
|
|
|
| |
We didn't handle constants in logical expressions when they weren't
the first operand. Some reordering in the loop structure is enough
to handle them.
|
| |
|
|
|
| |
As we can optimize dead code a bit already it's fitting
to disable code emission after break and goto.
|
| |
|
|
|
|
|
| |
If a condition is always zero/non-zero we can omit the
then or else code. This is complicated a bit by having to
deal with labels that might make such code reachable without
us yet knowing during parsing.
|
| |
|
|
| |
Use correct width ELF structure.
|
| |
|
|
|
| |
The sizes of VLAs need to be evaluated even inside sizeof,
i.e. when nocode_wanted is set.
|
| |
|
|
|
| |
was incorrectly treated as constant because the vpop removed
all traces of non-constness.
|
| |
|
|
|
|
|
| |
This happens when e.g. string constants (or other static data)
are passed as operands to inline asm as immediates. The produced
symbol ref wouldn't be found. So tighten the connection between
C and asm-local symbol table even more.
|
| |
|
|
|
| |
VT_ENUM types use the .ref member and can be VT_BITFIELD,
so we need to copy it as well. Simply do it always.
|
| |
|
|
| |
Use this fact in some foldings of comparisons. See testcase.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The return value of statement expressions might refer to local
symbols, so those can't be popped. The old error message always
was just a band-aid, and since disabling it for pointer types it
wasn't effective anyway. It also never considered that also the
vtop->sym member might have referred to such symbols (see the
testcase with the local static, that used to segfault).
For fixing this (can be seen better with valgrind and SYM_DEBUG)
simply leave local symbols of stmt exprs on the stack.
|
| |
|
|
|
|
| |
The include directive needs to be parsed as pp-tokens, not
as token (i.e. no conversion to TOK_STR or TOK_NUM). Also fix
parsing computed includes using quoted strings.
|
| |
|
|
|
|
| |
Register operands of type _Bool weren't correctly getting
the 8-bit sized registers (but rather used the default 32-bit
ones).
|
| |
|
|
|
|
| |
GCC allows register loads for asms based on type mode,
and correctly sized structs/union have an allowed mode
(basically 1,2,4,8 sized aggregates).
|
| |
|
|
|
| |
It's now possible to use symbols defined in C code to be used
from later inline asm blocks. See testcase.
|
| |
|
|
|
|
|
| |
But like GCC do warn about changes in signedness. The latter
leads to some changes in gen_assign_cast to not also warn about
unsigned* = int*
(where GCC warns, but only with extra warnings).
|
| | |
|
| | |
|
| |
|
|
| |
"int * __attribute__((something)) *" is supported by GCC.
|
| |
|
|
|
|
|
|
| |
This snippet is valid:
void foo(void);
... foo + 42 ...
the function designator is converted to pointer to function
implicitely. gen_op didn't do that and bailed out.
|
| |
|
|
|
|
|
|
|
|
|
| |
This must compile:
typedef int arrtype1[];
arrtype1 sinit19 = {1};
arrtype1 sinit20 = {2,3};
and generate two arrays of one resp. two elements. Before the fix
the determined size of the first array was encoded in the type
directly, so sinit20 couldn't be parsed anymore (because arrtype1
was thought to be only one element long).
|
| |
|
|
|
| |
Like __FILE__ but always refers to the command line file name also
from inside headers.
|
| |
|
|
| |
Follows GCC implementation.
|
| |
|
|
|
|
|
|
|
|
|
| |
Given this code:
struct __attribute__((...)) Name {...};
TCC was eating "Name", hence generating an anonymous struct.
It also didn't apply any packed attributes to the parsed
members. Both fixed. The testcase also contains a case
that isn't yet handled by TCC (under a BROKEN #define).
|
| |
|
|
|
| |
This really should be handled implicitly in the preprocessor,
but for now this is enough.
|
| |
|
|
| |
Those should use long or long long type, and generate a 64bit reloc.
|
| |
|
|
|
| |
'p' is conservatively the same as 'r' and 'P' as template
modifier can be ignored in TCC.
|
| |
|
|
|
|
|
| |
struct S { /*nothing*/; int a; };
is an acceptable struct declaration, there may be stray semicolons
in the member list.
|
| |
|
|
| |
In inline extended asm '%q1' refers to the 64bit register of operand 1.
|
| |
|
|
|
| |
Also remove bitfield test from tcctest.c because gcc
versions don't agree among each other.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem was with tcctest.c:
unsigned set;
__asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
when with tcc compiled with the HAVE_SELINUX option, run with
tcc -run, it would use large addresses far beyond the 32bits
range when tcc did not use the pc-relative mode for accessing
'set' in global data memory. In fact the assembler did not
know about %rip at all.
Changes:
- memory operands use (%rax) not (%eax)
- conversion from VT_LLOCAL: use type VT_PTR
- support 'k' modifier
- support %rip register
- support X(%rip) pc-relative addresses
The test in tcctest.c is from Michael Matz.
|
| |
|
|
|
|
|
|
|
| |
Also:
- regenerate all tests/pp/*.expect with gcc
- test "insert one space" feature
- test "0x1E-1" in asm mode case
- PARSE_FLAG_SPACES: ignore \f\v\r better
- tcc.h: move some things
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
tccgen.c:gv() when loading long long from lvalue, before
was saving all registers which caused problems in the arm
function call register parameter preparation, as with
void foo(long long y, int x);
int main(void)
{
unsigned int *xx[1], x;
unsigned long long *yy[1], y;
foo(**yy, **xx);
return 0;
}
Now only the modified register is saved if necessary,
as in this case where it is used to store the result
of the post-inc:
long long *p, v, **pp;
v = 1;
p = &v;
p[0]++;
printf("another long long spill test : %lld\n", *p);
i386-gen.c :
- found a similar problem with TOK_UMULL caused by the
vstack juggle in tccgen:gen_opl()
(bug seen only when using EBX as 4th register)
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On 2016-08-11 09:24 +0100, Balazs Kezes wrote:
> I think it's just that that copy_params() never restores the spilled
> registers. Maybe it needs some extra code at the end to see if any
> parameters have been spilled to stack and then restore them?
I've spent some time on this and I've found an alternative solution.
Although I'm not entirely sure about it but I've attached a patch
nevertheless.
And while poking at that I've found another problem affecting the
unsigned long long division on arm and I've attached a patch for that
too.
More details in the patches themselves. Please review and consider them
for merging! Thank you!
--
Balazs
[PATCH 1/2] Fix slow unsigned long long division on ARM
The macro AEABI_UXDIVMOD expands to this bit:
#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
...
while (num >= den) { \
...
while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
q <<= 1; \
...
With the current ULONG_MAX version the inner loop goes only until 4
billion so the outer loop will progress very slowly if num is large.
With ULLONG_MAX the inner loop works as expected. The current version is
probably a result of a typo.
The following bash snippet demonstrates the bug:
$ uname -a
Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux
$ cat div.c
int printf(const char *, ...);
int main(void) {
unsigned long long num, denom;
num = 12345678901234567ULL;
denom = 7;
printf("%lld\n", num / denom);
return 0;
}
$ time tcc -run div.c
1763668414462081
real 0m16.291s
user 0m15.860s
sys 0m0.020s
[PATCH 2/2] Fix long long dereference during argument passing on ARMv6
For some reason the code spills the register to the stack. copy_params
in arm-gen.c doesn't expect this so bad code is generated. It's not
entirely clear why the saving part is necessary. It was added in commit
59c35638 with the comment "fixed long long code gen bug" with no further
clarification. Given that tcctest.c passes without this, maybe it's no
longer needed? Let's remove it.
Also add a new testcase just for this. After I've managed to make the
tests compile on a raspberry pi, I get the following diff without this
patch:
--- test.ref 2016-08-22 22:12:43.380000000 +0100
+++ test.out3 2016-08-22 22:12:49.990000000 +0100
@@ -499,7 +499,7 @@
2
1 0 1 0
4886718345
-shift: 9 9 9312
+shift: 291 291 291
shiftc: 36 36 2328
shiftc: 0 0 9998683865088
manyarg_test:
More discussion on this thread:
https://lists.nongnu.org/archive/html/tinycc-devel/2016-08/msg00004.html
|
| |
|
|
|
|
|
|
|
|
|
| |
fixes 5c35ba66c5ade4713bbd9c005e66889f6d7db293
Implementation was consistent within tcc but incompatible
with the ABI (for example library functions vprintf etc)
Also:
- tccpp.c/get_tok_str() : avoid "unknown format "%llu" warning
- x86_64_gen.c/gen_vla_alloc() : fix vstack leak
|
| |
|
|
|
| |
This fixes and activates the asm test that's part of tcctest.c
also on x86-64, requiring a small fix for the 'm' constraint.
|
| |
|
|
|
|
|
| |
Catch top level redeclarations too.
Also fix mistakes in tcctest.c and the tcc sources (win32)
showing up now.
|
| |
|
|
|
|
|
|
|
| |
Code like this was broken:
char volatile vi = i;
See testcase, happens in ideosyncratic legacy code sprinkling
volatile all over.
|
| |
|
|
|
| |
We really need to use PEEKC during tokenization so as to
skip line continuations automatically.
|
| | |
|
| | |
|