| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
When copying the content of compound literals we must
include relocations as well.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
| |
This disables generation of any SSE instructions (in particular
in stdarg function prologues). Necessary for kernel compiles.
|
| |
|
|
|
|
|
|
| |
Some routines were using the wrong type (int) in passing addends,
truncating it. This matters when bit 31 isn't set and the high
32 bits are set: the truncation would make it unsigned where in
reality it's signed (happen e.g. on the x86-64 with it's load
address at top-2GB).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This target has _32 and _32S relocs (the latter being for signed
32 bit entities). All instruction displacements have to use
the 32S variants. Normal references like
.long s
normally would use the _32 variant. For normal executables this
doesn't matter. For shared libraries neither (which use PC-relative
relocs). But it matters for things like the kernel that are linked
to high addresses (signed ones). There the GNU linker would error
out on overflow for the _32 variant.
To keep life simple we simply switch from _32 to _32S altogether.
Strictly speaking it's still wrong, but in practice using _32 is
more often wrong than using _32S ;)
|
| |
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Not fully thought out. You can't jump inside stmt exprs,
but you can jump out of them. So there's a difference
between undefined but declared labels at the end of stmt
exprs and those defined inside. Additionally it should
also be checked if a label defined inside a stmt expr
was tentatively created as declared from outside.
I'm not prepared doing that right now, so simply revert.
This reverts commit 9160e4cab9147d77840cc44a285031fdb4640cf9.
|
| |
|
|
| |
Creating condition_3way for this.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
One can't jump into statement expressions from outside
them, like the following:
int i = ({ label: foo(); 42; });
goto label;
We reject this by making the labels simply not available
outside (GCC has a nicer error message about jumping into
a statement expression).
|
| |
|
|
|
|
|
| |
In statement expression we really mustn't emit backward jumps
under nocode_wanted (they will form infinte loops as no expressions
are evaluated). Do-while and explicit loop with gotos weren't
handled.
|
| |
|
|
| |
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.
|
| |
|
|
|
|
|
| |
Our preprocessor throws away # line-comments in asm mode.
It did so also inside preprocessor directives, thereby
removing stringification. Parse defines in non-asm mode (but
retain '.' as identifier character inside macro definitions).
|
| |
|
|
|
| |
In particular don't care if they're signed or unsigned, they're all
acceptable as immediates.
|
| |
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
That, as well as "sym = expr", if expr contains symbols.
Slightly tricky because a definition from .set is overridable,
whereas proper definitions aren't.
This doesn't yet allow using this for override tricks from C
and global asm blocks because the symbol tables from C and asm
are separate.
|
| |
|
|
|
|
|
| |
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).
|
| | |
|
| |
|
|
|
| |
str accepts rm16/r32/r64, and push/pop defaults to 64 when given
memory operands (to 32 on i386).
|
| | |
|
| |
|
|
| |
Implement missing support for range init for local variables.
|
| |
|
|
|
|
|
| |
This requires correctly handling the REX prefix.
As bonus we now also support the four 8bit registers
spl,bpl,sil,dil, which are decoded as ah,ch,dh,bh in non-long-mode
(and require a REX prefix as well).
|
| | |
|
| |
|
|
| |
See testcase.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
For
union U { struct {int a,b}; int c; };
union U u = {{ 1, 2, }};
The unnamed first member of union U needs to actually exist in the
structure so initializer parsing isn't confused about the double braces.
That means also the a and b members must be part of _that_, not of
union U directly. Which in turn means we need to do a bit more work
for field lookup.
See the testcase extension for more things that need to work.
|
| |
|
|
|
| |
Some parameters aren't actually necessary. Also join the
two parsing loops for the initializer list of arrays and structs.
|
| |
|
|
|
|
|
| |
Remove dead code and variables. Properly check for unions when
skipping fields in initializers. Make tests2/*.expect depend
on the .c files so they are automatically rebuilt when the latter
change.
|
| |
|
|
|
|
| |
E.g. "struct { struct S s; int a;} = { others, 42 };"
if 'others' is also a 'struct S'. Also when the value is a
compound literal. See added testcases.
|
| |
|
|
|
|
| |
Start reimplementing the whole initializer handling to be
conforming to ISO C. This patch just reimplements current
functionality to prepare for further changes, all tests pass.
|
| |
|
|
| |
"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.
|