Commit graph

84 commits

Author SHA1 Message Date
Erica Z
c8220b638b replace asm keyword
when applying a custom set of CFLAGS under clang that does not include
-std=c99, asm is treated as a keyword and as such can not be used as an
identifier. this prevents the issue by renaming the offending variables.
2024-05-28 10:39:41 +02:00
Quentin Carbonneaux
b24af7d3f7 revert 1b7770e271
Quotes are used on Apple target
variants to flag that we must
not add the _ symbol prefix.
2024-04-22 14:01:50 +02:00
Quentin Carbonneaux
4a809d69b5 fold scaled offsets in addresses 2024-04-11 14:14:53 +02:00
Quentin Carbonneaux
8e8f706436 drop over-zealous offset accumulation 2024-04-11 10:22:46 +02:00
Quentin Carbonneaux
2d046a0ac6 use mgen in amd64/isel.c 2024-04-09 21:47:16 +02:00
Michael Forney
1b7770e271 Drop quotes around floating point constant labels
This is incompatible with binutils gas older than 2.26.
2024-03-26 09:22:06 +01:00
Drew DeVault
85287081c4 dbgloc: add column argument
dbgloc line [col]

This is implemented in a backwards-compatible manner.
2024-01-02 12:12:05 +01:00
Quentin Carbonneaux
4bc4c9584a revert 5af33410
Causes errors with stock toolchain
on OpenBSD.
2024-01-02 11:16:08 +01:00
Tobias Heider
5af33410f6 Fix IBT/BTI by instrumenting function calls 2023-12-30 15:59:25 +01:00
Quentin Carbonneaux
c5aca682a2 comments in amd64 isel 2023-08-28 22:45:41 +02:00
Michael Forney
d6c9669c3c Fix conversion from float/double to unsigned int
signed int can't represent all the values of unsigned int, so we
need to do the conversion to signed long, and use the lower 32 bits
as the result.
2023-08-26 15:16:45 +02:00
Quentin Carbonneaux
36946a5142 file,loc become dbgfile,dbgloc 2023-08-18 15:12:56 +02:00
Thomas Bracht Laumann Jespersen
0d929287d7 implement line number info tracking
Support "file" and "loc" directives. "file" takes a string (a file name)
assigns it a number, sets the current file to that number and records
the string for later. "loc" takes a single number and outputs location
information with a reference to the current file.
2023-06-06 18:44:51 +02:00
Quentin Carbonneaux
a3dfbb9c04 amd64_apple: one more thread-local symbols fix
We now treat thread-local
symbols in Mems properly.
2023-04-02 19:21:16 +02:00
Quentin Carbonneaux
1ec70daee6 amd64_apple: support thread-local addresses
Non-store/load instructions were
not lowered correctly for thread-
local symbols. This is an attempt
at a fix (cannot test for now).
2023-04-02 16:51:49 +02:00
Quentin Carbonneaux
56f4b5be4c amd64_sysv: fix offsets in thread-local Oaddr 2023-04-02 15:48:48 +02:00
Quentin Carbonneaux
a9d3e06a57 amd64_sysv: thread-local support in Oaddr
Thanks to Lassi Pulkkinen for
flagging the issue and pointing
me to Ulrich Drepper's extensive
doc [1].

[1] https://people.redhat.com/drepper/tls.pdf
2023-04-02 14:48:52 +02:00
Quentin Carbonneaux
5fee3da6ac rename blknew() to newblk()
This is consistent with newtmp()
and newcon().
2023-03-22 11:43:46 +01:00
Quentin Carbonneaux
eb9fcece9e naming nit 2023-03-19 07:38:24 +01:00
Quentin Carbonneaux
011dfc839d silence format warning more reliably 2023-03-16 16:22:11 +01:00
Quentin Carbonneaux
6f45894c7f silence some warnings 2023-03-15 22:07:18 +01:00
Quentin Carbonneaux
5e9726946d new UNDEF Ref
Crashing loads of uninitialized memory
proved to be a problem when implementing
unions using qbe.  This patch introduces
a new UNDEF Ref to represent data that is
known to be uninitialized.  Optimization
passes can make use of it to eliminate
some code.  In the last compilation stages,
UNDEF is treated as the constant 0xdeaddead.
2022-12-25 16:37:33 +01:00
Quentin Carbonneaux
26c1c30b7d new blit instruction 2022-12-14 23:18:26 +01:00
Quentin Carbonneaux
c0f25aeae3 new rsval() helper for signed Refs
The .val field is signed in RSlot.
Add a new dedicated function to
fetch it as a signed int.
2022-12-12 22:16:33 +01:00
Quentin Carbonneaux
9126afa2da new hlt block terminator
It is handy to express when
the end of a block cannot be
reached. If a hlt terminator
is executed, it traps the
program.

We don't go the llvm way and
specify execution semantics as
undefined behavior.
2022-11-27 21:48:21 +01:00
Quentin Carbonneaux
cbee74bdb4 use a new struct for symbols
Symbols are a useful abstraction
that occurs in both Con and Alias.
In this patch they get their own
struct. This new struct packages
a symbol name and a type; the type
tells us where the symbol name
must be interpreted (currently, in
gobal memory or in thread-local
storage).

The refactor fixed a bug in
addcon(), proving the value of
packaging symbol names with their
type.
2022-11-22 21:56:21 +01:00
Quentin Carbonneaux
8ecae92299 thread-local storage for amd64_apple
It is quite similar to arm64_apple.
Probably, the call that needs to be
generated also provides extra
invariants on top of the regular
abi, but I have not checked that.

Clang generates code that is a bit
neater than qbe's because, on x86,
a load can be fused in a call
instruction! We do not bother with
supporting these since we expect
only sporadic use of the feature.

For reference, here is what clang
might output for a store to the
second entry of a thread-local
array of ints:

        movq    _x@TLVP(%rip), %rdi
        callq   *(%rdi)
        movl    %ecx, 4(%rax)
2022-10-12 21:12:08 +02:00
Quentin Carbonneaux
b03a8970d7 mark apple targets with a boolean
It is more natural to branch on a
flag than have different function
pointers for high-level passes.
2022-10-08 21:48:47 +02:00
Quentin Carbonneaux
4e90b4210e "rel" fields become "reloc" 2022-10-08 21:48:47 +02:00
Quentin Carbonneaux
00a30954ac add support for thread-local storage
The apple targets are not done yet.
2022-10-08 21:48:42 +02:00
Quentin Carbonneaux
70f297bab7 fix case of Pool constants 2022-10-03 10:41:30 +02:00
Quentin Carbonneaux
a9a70e30a8 add new target-specific abi0 pass
The general idea is to give abis a
chance to talk before we've done all
the optimizations. Currently, all
targets eliminate {par,arg,ret}{sb,ub,...}
during this pass. The forthcoming
arm64_apple will, however, insert
proper extensions during abi0.

Moving forward abis can, for example,
lower small-aggregates passing there
so that memory optimizations can
interact better with function calls.
2022-10-03 10:41:03 +02:00
Quentin Carbonneaux
8dddb971d9 drop -G flag and add target amd64_apple
apple support is more than assembly syntax
in case of arm64 machines, and apple syntax
is currently useless in all cases but amd64;
rather than having a -G option that only
makes sense with amd64, we add a new target
amd64_apple
2022-08-31 21:42:49 +02:00
Quentin Carbonneaux
740bf867b3 do not fold cnst+cnst in amd64's isel
This may cause invalid assembly to be generated
and is not all that useful anyway after constant
folding has run.
2022-06-14 13:49:50 +02:00
Michael Forney
c6b41eb8c8 amd64: restore previous name of amd64_sysv target 2022-03-17 13:24:52 +01:00
Quentin Carbonneaux
2416d29141 new -t? flag to print default target 2022-03-15 22:30:34 +01:00
Quentin Carbonneaux
c5769f62b4 dynamic stack allocs for arm64
I also moved some isel logic
that would have been repeated
a third time in util.c.
2022-03-14 23:14:48 +01:00
Quentin Carbonneaux
9060981c10 flag types defined as unions
The risc-v abi needs to know if a
type is defined as a union or not.

We cannot use nunion to obtain this
information because the risc-v abi
made the unfortunate decision of
treating

	union { int i; }

differently from

	int i;

So, instead, I introduce a single
bit flag 'isunion'.
2022-03-08 15:57:06 +01:00
Quentin Carbonneaux
349794f3e4 cosmetics 2022-03-08 15:36:26 +01:00
Quentin Carbonneaux
2ca6fb25a2 shared linkage logic for func/data 2022-02-02 21:09:37 +01:00
Quentin Carbonneaux
f913cb0fb7 amd64/isel: nits 2022-01-28 11:10:34 +01:00
Bor Grošelj Simić
3964574a83 implement float -> unsigned casts
amd64 lacks instruction for this so it has to be implemented with
float -> signed casts. The approach is borrowed from llvm.
2022-01-28 09:24:15 +01:00
Bor Grošelj Simić
74d022f975 implement unsigned -> float casts
amd64 lacks an instruction for this so it has to be implemented with
signed -> float casts:
 - Word casting is done by zero-extending the word to a long and then doing
   a regular signed cast.
 - Long casting is done by dividing by two with correct rounding if the
   highest bit is set and casting that to float, then adding
   1 to mantissa with integer addition
2022-01-28 09:24:15 +01:00
Eyal Sawady
e91d121581 Add a negation instruction
Necessary for floating-point negation, because
`%result = sub 0, %operand` doesn't give the correct sign for 0/-0.
2022-01-23 11:43:59 +01:00
Michael Forney
bf153b359e reuse previous address constants in fold()
parseref() has code to reuse address constants, but this is not
done in other passes such as fold or isel. Introduce a new function
newcon() which takes a Con and returns a Ref for that constant, and
use this whenever creating address constants.

This is necessary to fix folding of address constants when one
operand is already folded. For example, in

	%a =l add $x, 1
	%b =l add %a, 2
	%c =w loadw %b

%a and %b were folded to $x+1 and $x+3 respectively, but then the
second add is visited again since it uses %a. This gets folded to
$x+3 as well, but as a new distinct constant. This results in %b
getting labeled as bottom instead of either constant, disabling the
replacement of %b by a constant in subsequent instructions (such
as the loadw).
2021-11-22 18:07:50 +01:00
Michael Forney
ae8803cbe6 amd64: avoid reading past end of passed struct
If the size of the struct is not a multiple of 8, the actual struct
size may be different from the size reserved on the stack.

This fixes the case where the struct is passed in memory, but we
still may over-read a struct passed in registers. A TODO is added
for now.
2021-11-08 14:11:10 +01:00
Quentin Carbonneaux
fcdef10dae make variadic args explicit
Some abis, like the riscv one, treat
arguments differently depending on
whether they are variadic or not.
To prepare for the upcomming riscv
target, we change the variadic call
syntax and give meaning to the
location of the '...' marker.

  # new syntax
  %ret =w call $f(w %regular, ..., w %variadic)

By nature of their abis, the change
is backwards compatible for existing
targets.
2021-10-22 23:53:25 +02:00
Quentin Carbonneaux
503c672d47 amd64/sysv: unbreak env calls
Env calls were disfunctional from the
start. This fixes them on amd64, but
they remain to do on arm64. A new
test shows how to use them.
2021-10-17 21:03:03 +02:00
Andrew Chambers
462e49fd5c add size suffix to frame setup. 2021-10-13 13:16:33 +02:00
Michael Forney
7ac88f5d48 amd64/isel: fix floating point == and != result with NaN
On x86_64, ucomis[sd] sets ZF=1, PF=0, CF=0 for equal arguments.
However, if the arguments are unordered it sets ZF=1, PF=1, CF=1,
and there is no jump/flag instruction for ZF=1 & PF=0 or ZF=1 & CF=0.

So, in order to correctly implement ceq[sd] on x86_64, we need to
be a bit more creative. There are several options available, depending
on whether the result of ceq[sd] is used with jnz, or with other
instructions, or both.

If the result is used for a conditional jump, both gcc and clang
use a combination of jp and jnz:

	ucomisd %xmm1, %xmm0
	jp .Lfalse
	jnz .Lfalse
	...
	.Lfalse:

If the result is used in other instructions or return, gcc does the
following for x == y:

	ucomisd %xmm1, %xmm0
	setnp %al
	movzbl %al, %eax
	movl $0, %edx
	cmovne %edx, %eax

This sets EAX to PF=0, then uses cmovne to clear it if ZF=0. It
also takes care to avoid clobbering the flags register in case the
result is also used for a conditional jump. Implementing this
approach in QBE would require adding an architecture-specific
instruction for cmovne.

In contrast, clang does an additional compare, this time using
cmpeqsd instead of ucomisd:

	cmpeqsd %xmm1, %xmm0
	movq %xmm0, %rax
	andl $1, %rax

The cmpeqsd instruction doas a floating point equality test, setting
XMM0 to all 1s if they are equal and all 0s if they are not. However,
we need the result in a non-XMM register, so it moves the result
back then masks off all but the first bit.

Both of these approaches are a bit awkward to implement in QBE, so
instead, this commit does the following:

	ucomisd %xmm1, %xmm0
	setz %al
	movzbl %al, %eax
	setnp %cl
	movzbl %cl, %ecx
	andl %ecx, %eax

This sets the result by anding the two flags, but has a side effect
of clobbering the flags register. This was a problem in one of my
earlier patches to fix this issue[0], in addition to being more
complex than I'd hoped.

Instead, this commit always leaves the ceq[sd] instruction in the
block, even if the result is only used to control a jump, so that
the above instruction sequence is always used. Then, since we now
have ZF=!(ZF=1 & PF=0) for x == y, or ZF=!(ZF=0 | PF=1) for x != y,
we can use jnz for the jump instruction.

[0] 64833841b1
2021-08-29 22:33:04 +02:00