Commit graph

583 commits

Author SHA1 Message Date
Andrew Kelley
9d422bff18 stage2: move all integer types to InternPool 2023-06-10 20:40:04 -07:00
Andrew Kelley
85c69c5194 Type.isSlice: make it InternPool aware 2023-06-10 20:40:04 -07:00
Andrew Kelley
836d8a1f64 stage2: move most simple types to InternPool 2023-06-10 20:40:04 -07:00
Andrew Kelley
4cd8a40b3b stage2: move float types to InternPool 2023-06-10 20:40:03 -07:00
Andrew Kelley
00f82f1c46 stage2: add interned AIR tag
This required additionally passing the `InternPool` into some AIR
methods.

Also, implement `Type.isNoReturn` for interned types.
2023-06-10 20:40:03 -07:00
Andrew Kelley
9aec2758cc stage2: start the InternPool transition
Instead of doing everything at once which is a hopelessly large task,
this introduces a piecemeal transition that can be done in small
increments at a time.

This is a minimal changeset that keeps the compiler compiling. It only
uses the InternPool for a small set of types.

Behavior tests are not passing.

Air.Inst.Ref and Zir.Inst.Ref are separated into different enums but
compile-time verified to have the same fields in the same order.

The large set of changes is mainly to deal with the fact that most Type
and Value methods now require a Module to be passed in, so that the
InternPool object can be accessed.
2023-06-10 20:40:03 -07:00
Luuk de Gram
ebfd3450d9
codegen: Write padding bytes for unions
Previously we did not write any missing padding bytes after the smallest
field (either tag or payload, depending on alignment). This resulted in
writing too few bytes and not matching the full abisize of the union.
2023-05-31 18:04:33 +02:00
Luuk de Gram
7e10cf4fbe
wasm: shl_with_overflow ensure rhs is coerced
Both operands must have the same Wasm type before we are allowed
to perform any binary operation on the values.
2023-05-31 18:04:33 +02:00
Luuk de Gram
e36cc0ce8f
wasm: union_init support packed unions 2023-05-31 18:04:33 +02:00
Luuk de Gram
128814f9bf
wasm: aggregate_init store sentinel for arrays 2023-05-31 18:04:32 +02:00
Luuk de Gram
969f921162
wasm: ptr_elem_val use pointer type for local
When storing the address after calculating the element's address,
ensure it's stored in a local with the correct type. Previously it
would incorrectly use the element's type, which could be a float for
example and therefore generate invalid WebAssembly code.

This change also introduces a more robust `store` function.
2023-05-31 18:04:32 +02:00
Luuk de Gram
ffa89d3b83
wasm: UnwrapErrUnionPayloadPtr ensure ptr ret
When the paylaod is zero-sized we must ensure a valid pointer
is still returned for the ptr variation of the instruction. This,
because it's valid to have a pointer to a zero-sized value.
In such a case, we simply return the operand.
2023-05-31 18:04:32 +02:00
Luuk de Gram
3c72b4d25e
wasm: support and optimize for all packed unions
For packed unions where its abi size is less than or equal to 8 bytes
we store it directly and don't pass it by reference. This means that
when retrieving the field, we will perform shifts and bitcasts to ensure
the correct type is returned. For larger packed unions, we either allocate
a new stack value based on the field type when the field type is also passed
by reference, or load it directly into a local if it's not.
2023-05-31 18:04:32 +02:00
Luuk de Gram
7cfc44d86f
wasm: implement struct_field_val for packed unions
We currently have `isRef` return true for any type of union, including
packed unions. This means we can simply load it from the data section
to the exact type we want. In the future we can optimize it so it works
similarly to packed structs below 64 bits which do not get stored in
the data section and are not passed by ref.
2023-05-31 18:04:32 +02:00
Luuk de Gram
49fddbf4c1
wasm: union_init correctly store the tag
Previously we would only store the payload, but not the actual tag
that was set. This meant miscompilations where it would incorrectly
return the tag value.

This also adds a tiny optimization for payloads which are not `byRef`
by directly storing them based on offset, rather than first calculating
a pointer to an offset.
2023-05-31 18:04:32 +02:00
Luuk de Gram
00dedabc41
wasm: memcpy support elem abi-size > 1
Previously it was incorrectly assumed that all memcopy's generated by
the `memcpy` AIR instruction had an element size of 1 byte. However,
this would result in miscompilations for pointer's to arrays where
the element size of the array was larger than 1 byte. We now corectly
calculate this size.
2023-05-31 18:04:31 +02:00
Veikka Tuominen
ca16f1e8a7 std.Target adjustments
* move `ptrBitWidth` from Arch to Target since it needs to know about the abi
* double isn't always 8 bits
* AVR uses 1-byte alignment for everything in GCC
2023-05-26 21:42:19 -07:00
Andrew Kelley
dbd44658ff wasm backend: emit a TODO error rather than miscompile 2023-05-26 21:10:54 -07:00
Luuk de Gram
832330094c
wasm: aggregate_init - ensure zeroed result local
When initializing a packed struct, we must ensure the result local
is zero'd. Previously we would do this by ensuring a new local is
allocated. Although a local is always zero by default, it meant that
if such an initialization was being done inside a loop, it would re-
use that very same local that could potentially still hold a different
value. Because this value is `or`'d with the value, it would result
in a miscompilation. By manually setting this result to 0, we guarantee
the correct behavior.
2023-05-19 20:22:48 +02:00
Luuk de Gram
ca870aa005
wasm: fix div_trunc for floats
For floats we would previously only do the division, but not
the truncation for floats. This would result in incorrect values
being returned.
2023-05-19 20:22:47 +02:00
Luuk de Gram
4a33aa922e
wasm: support memset for elem abi size > 1
Previously we incorrectly assumed all memset's to have its element
abi-size be 1 byte. This would set the region of memory incorrectly.
We now have a more efficient loop, as well as support any element
type by re-using the `store` function for each element and moving
the pointer by 1 element.
2023-05-19 20:22:45 +02:00
Luuk de Gram
55a260c968
wasm: implement shl for big integers 2023-05-19 20:20:29 +02:00
Luuk de Gram
b93fa9833e
wasm: memset - correctly load the ptr for slices
Previously we would use the address of the slice itself, which would
result in miscompilations and accidently setting the memory region
of the slice itself, rather than based on the `ptr` field.
2023-05-19 20:20:29 +02:00
Luuk de Gram
061d99285d
wasm: correctly use elem type when lowering
Previously when lowering a value of `elem_ptr` we would multiply the
abisize of the parent type by the index, rather than the element type.
This would result in an invalid pointer way beyond the correct pointer.

We now also pass the current offset to each recursive call to ensure
we do not miss inner offsets.
2023-05-19 20:20:26 +02:00
Luuk de Gram
6c06944b59
wasm: fix return ret_load with zero-size type
When we have a `ret_load` instruction with a zero-sized type which was
not an error, we would not emit any instruction. This resulted in
no `return` instruction and also not correctly resetting the global
stack_pointer.

This commit also enables the regular test runner for the WebAssembly
backend.
2023-05-19 20:19:00 +02:00
Luuk de Gram
43e89026ac
wasm: fix double free of locals
A copy was being made of a WValue variable, which meant the call
to `free` would insert the local that was being held by said WValue
was appended to the free list twice. This led to the same local being
reused even though it wasn't free and would lead to it being over-
written by a new value.
2023-05-19 20:19:00 +02:00
Luuk de Gram
8be69f4132
wasm: simplify merging of branches
Rather than adding all values that were generated in the child branch,
we simply discard them as outer branches cannot refer to values
produced from an inner branch.
2023-05-19 20:19:00 +02:00
Luuk de Gram
99422cb528
wasm: add dead tag to WValue
This new tag is used for freed locals that are not allowed to have any
remaining references pointing to it. This new tag allows us to easily
identify liveness bugs. Previously we would set the entire region to
`undefined` which would incorrectly set the tag to `function_index`,
making codegen think it was a valid `WValue` while it wasn't.
2023-05-19 20:19:00 +02:00
Luuk de Gram
f2860bb4f4
wasm: more liveness fixes 2023-05-19 20:18:59 +02:00
Luuk de Gram
67d27dbe63
wasm: fix liveness bugs
Make sure to increase the reference count for `intcast` when the
operand doesn't require any casting of the respective WebAssembly type.

Function arguments have a reserved slot, and therefore cannot be
re-used arbitrarily
2023-05-19 20:18:59 +02:00
Luuk de Gram
e20976b7f2
wasm: fix miscompilation for shifting
This fix ensures that when we are shifting left or right,
both operands have the same WebAssembly type. e.g. it's not possible
to shift a 64 bit integer and 32 bit integer together and will fail
WebAssembly's validator. By first coercing the values to the same
type, we ensure we satisfy the validator.
2023-05-19 20:18:59 +02:00
Luuk de Gram
d353d208e2
wasm: implement @mulWithOverflow for big ints
Currently we only support exact 128 bit *unsigned* integers
2023-05-19 20:18:59 +02:00
Luuk de Gram
992de8e617
wasm: implement @addWithOverflow for 64bit ints 2023-05-19 20:18:59 +02:00
Luuk de Gram
8236a26c60
wasm: implement mul, shl and xor for big ints
Uses compiler-rt for multiplication and shifting left, while lowers
it down using regular instructions for xor.
2023-05-19 20:18:59 +02:00
Luuk de Gram
eb77e3381f
wasm: implement @frameAddress 2023-05-19 20:18:58 +02:00
Andrew Kelley
aa3405aabc
Merge pull request #15474 from Luukdegram/wasm-atomics
wasm: implement atomic instructions
2023-04-27 08:26:35 -07:00
Luuk de Gram
b26a46d05b
wasm: support pointers in cmpxchg 2023-04-26 16:28:41 +02:00
Luuk de Gram
7c09e09457
wasm: implement atomic stores 2023-04-26 16:28:41 +02:00
Luuk de Gram
0e3303ccd9
wasm: implement @fence
Uses the `atomic.fence` instruction for multi-thread-enabled builds
where the `atomics` feature is enabled for the wasm32 target.
In all other cases, this lowers to a nop.
2023-04-26 16:28:41 +02:00
Luuk de Gram
b19c258f04
wasm: implement @atomicRmw
Implements the lowering of the `@atomicRmw` builtin. Uses the atomic
opcodes when the cpu feature `atomics` is enabled. Otherwise lowers
it to regular instructions. For the operations that do not lower to
a direct atomic opcode, we use a loop in combiantion with a cmpxchg
to ensure the swapping of values is doing atomically.
2023-04-26 16:28:40 +02:00
Luuk de Gram
fd47eddc86
wasm: implement @atomicLoad
Uses the atomic instructions when cpu feature is enabled, otherwise
lowers it down to a regular load.
2023-04-26 16:28:40 +02:00
Luuk de Gram
650976b226
wasm: use atomic feature for @cmpxchg when enabled
When the user passes the cpu feature `atomics` to the target triple,
the backend will lower the AIR instruction using opcodes from the
atomics feature instead of manually lowering it.
2023-04-26 16:28:40 +02:00
Luuk de Gram
5bbd482286
wasm: implement cmpxchg{weak/strong} 2023-04-26 16:28:37 +02:00
Andrew Kelley
5378fdffdc stage2: introduce store_safe AIR instruction
store:
The value to store may be undefined, in which case the destination
memory region has undefined bytes after this instruction is
evaluated. In such case ignoring this instruction is legal
lowering.

store_safe:
Same as `store`, except if the value to store is undefined, the
memory region should be filled with 0xaa bytes, and any other
safety metadata such as Valgrind integrations should be notified of
this memory region being undefined.
2023-04-25 11:23:41 -07:00
Andrew Kelley
747f58366a wasm backend: fix airMemset with slices 2023-04-25 11:23:41 -07:00
Andrew Kelley
057c950093 LLVM backend: support non-byte-sized memset
Also introduce memset_safe AIR tag and support it in C backend and LLVM
backend.
2023-04-25 11:23:41 -07:00
Andrew Kelley
76e340cbfa wasm backend: implement new memcpy/memset and ptrtoint semantics 2023-04-25 11:23:40 -07:00
Luuk de Gram
6c1ab376dd
wasm: store __zig_lt_errors_len in linear data
Rather than using a function call to verify if an error fits within
the global error set's length, we now store the error set' size in
the .rodata segment of the linear memory and load that value onto
the stack to check with the integer value.
2023-04-22 21:57:38 +02:00
Luuk de Gram
d4ceb12ae9
wasm: implement error_set_has_value
This implements the safety check for error casts. The instruction
generates a jump table with 2 possibilities. The operand is used
as an index into the jump table. For cases where the value does
not exist within the error set, it will generate a jump to the
'false' block. For cases where it does exist, it will generate
a jump to the 'true' block. By calculating the highest and lowest
value we can keep the jump table smaller, as it doesn't need to
contain an index into the entire error set.
2023-04-22 21:16:23 +02:00
Luuk de Gram
c4b295bb6e
wasm: implement cmp_lt_errors_len instruction
Creates a global undefined symbol when this instruction is called.
The linker will then resolve it as a lazy symbol, ensuring it is
only generated when the symbol was created. In `flush` it will then
generate the function as only then, all errors are known and we can
generate the function body. This logic allows us to re-use the same
functionality of linker-synthetic-functions.
2023-04-22 21:16:23 +02:00