162 Commits

Author SHA1 Message Date
Andrew Kelley
4dd65316b7 AstGen: coerce break operands of labeled blocks
Similar code was already in place for conditional branches. This updates
AstGen to do the same for labeled blocks. It takes advantage of the
`store_to_block_ptr` instructions by mutating them in place to become
`as` instructions, coercing the break operands before they are returned
from the block.
2022-03-28 18:28:08 -07:00
Veikka Tuominen
a415fe0bc0 AstGen: clear rl_ty_inst in setBreakResultLoc if one is not provided 2022-03-28 13:05:08 -07:00
Luuk de Gram
16e88b75ba wasm: Enable passing tests 2022-03-26 21:20:29 +01:00
mparadinha
79e2d4b3f6 stage2: x86_64: update passing tests after implementing ptr_elem_val
the 3 tests that called `testArray2DConstDoublePtr` started passing
after implementing `ptr_elem_val`. the rest of these I think were
already passing before.
2022-03-21 20:13:27 +00:00
Veikka Tuominen
2757237332 Sema: add error for runtime block peer type being comptime only 2022-03-19 13:36:16 +02:00
joachimschmidt557
3ecba7d7a2
stage2 ARM: implement slice_elem_ptr, ptr_elem_ptr 2022-03-18 12:12:14 +01:00
Andrew Kelley
f3f5a5d05b stage2: improve @typeName
* make it always return a fully qualified name. stage1 is inconsistent
   about this.
 * AstGen: fix anon_name_strategy to correctly be `func` when anon type
   creation happens in the operand of the return expression.
 * Sema: implement type names for the "function" naming strategy.
 * Put "enum", "union", "opaque", or "struct" in place of "anon" when
   creating respective anonymous Decl names.
 * std.testing: add `expectStringStartsWith`. Didn't end up using it
   after all.

Also this enables the real test runner for stage2 LLVM backend (sans
wasm32) since it works now.
2022-03-18 00:12:22 -07:00
Luuk de Gram
eafdc5562f
wasm: Implement 'memcpy' instruction
This implements the `memcpy` instruction and also updates the inline memcpy calls
to make use of the same implementation. We use the fast-loop when the length is comptime known,
and use a runtime loop when the length is runtime known.
We also perform feature-dection to emit a simply wasm memory.copy instruction when the feature
'bulk-memory' is enabled. (off by default).
2022-03-17 20:41:23 +01:00
Andrew Kelley
078037ab9b stage2: passing threadlocal tests for x86_64-linux
* use the real start code for LLVM backend with x86_64-linux
   - there is still a check for zig_backend after initializing the TLS
     area to skip some stuff.
 * introduce new AIR instructions and implement them for the LLVM
   backend. They are the same as `call` except with a modifier.
   - call_always_tail
   - call_never_tail
   - call_never_inline
 * LLVM backend calls hasRuntimeBitsIgnoringComptime in more places to
   avoid unnecessarily depending on comptimeOnly being resolved for some
   types.
 * LLVM backend: remove duplicate code for setting linkage and value
   name. The canonical place for this is in `updateDeclExports`.
 * LLVM backend: do some assembly template massaging to make `%%`
   rendered as `%`. More hacks will be needed to make inline assembly
   catch up with stage1.
2022-03-11 00:04:42 -07:00
Andrew Kelley
b642fa24a6 stage2: implement integer pointer constants 2022-03-10 17:52:18 -07:00
Andrew Kelley
f736cde397 Sema: implement pointer to tuple to pointer to array coercion
This involved an LLVM backend fix for the aggregate_init instruction.
2022-03-09 18:49:37 -07:00
Veikka Tuominen
01b454f851 AstGen: ensure lableld block implicitly ends in a break 2022-03-09 17:12:40 +02:00
joachimschmidt557
95fc41b2b4 stage2 ARM: implement ret_load 2022-03-08 21:10:04 +01:00
Veikka Tuominen
aa7cbca7d3 stage2: make analyzePtrArithmetic no-op with offset=0 2022-03-03 22:42:34 +02:00
Cody Tapscott
5c8a507e7a stage2 parser: UTF-8 encode \u{NNNNNN} escape sequences
The core of this change is to re-use the escape sequence parsing logic
for parsing both string and character literals.

The actual fix is that UTF-8 encoding was missing for string literals
with \u{...} escape sequences.
2022-03-02 14:45:19 -05:00
Jakub Konka
d35cae551e x64: rectify and add missing optionals bits
Includes changes/additions to:
* `wrap_optional`
* `optional_payload`
* `isNull` helper
2022-03-02 14:05:29 +01:00
Andrew Kelley
6f303c01f3 LLVM: add extra padding to structs and tuples sometimes
* Sema: resolve type fully when emitting an alloc AIR instruction to
   avoid tripping assertion for checking struct field alignment.
 * LLVM backend: keep a reference to the LLVM target data alive during
   lowering so that we can ask LLVM what it thinks the ABI alignment
   and size of LLVM types are. We need this in order to lower tuples and
   structs so that we can put in extra padding bytes when Zig disagrees
   with LLVM about the size or alignment of something.
 * LLVM backend: make the LLVM struct type packed that contains the most
   aligned union field and the padding. This prevents the struct from
   being too big according to LLVM. In the future, we may want to
   consider instead emitting unions in a "flat" manner; putting the tag,
   most aligned union field, and padding all in the same struct field
   space.
 * LLVM backend: make structs with 2 or fewer fields return isByRef=false.
   This results in more efficient codegen. This required lowering of
   bitcast to sometimes store the struct into an alloca, ptrcast, and
   then load because LLVM does not allow bitcasting structs.
 * enable more passing behavior tests.
2022-03-01 18:24:00 -07:00
Jakub Konka
caa4e30ef4 x64: impl airMemset using inline memset 2022-03-01 15:21:10 +01:00
joachimschmidt557
ca97caab8a stage2 ARM: implement return types with abi size > 4 2022-03-01 09:14:52 +01:00
Jakub Konka
cfbc3537ef x64: pass more behavior tests 2022-02-28 23:20:05 +01:00
joachimschmidt557
91fbcf7093
stage2 ARM: enable more behavior tests 2022-02-27 21:38:56 +01:00
Veikka Tuominen
7a92b89a9d stage2: forward discard result loc to more expressions 2022-02-27 13:32:55 +02:00
joachimschmidt557
f48f4baf67
stage2 ARM: generate correct variants of ldr instruction
When loading an i16 for example, generate ldrsh instead of ldrh
2022-02-26 13:00:01 +01:00
joachimschmidt557
8ef80cfaab
stage2 ARM: implement truncate to ints with bits <= 32 2022-02-26 12:59:57 +01:00
Jakub Konka
e0f5627d4a x64+aarch64: check for pointer to zero-bit type when lowering decl
Unless the pointer is a pointer to a function, if the pointee type
has zero-bits, we need to return `MCValue.none` as the `Decl` has
not been lowered to memory, and therefore, any GOT reference will be
wrong.
2022-02-25 21:59:19 +01:00
Jakub Konka
1b8ed7842c macho: redo selection of segment/section for decls and consts
* fix alignment issues for consts with natural ABI alignment not
  matching that of the `ldr` instruction in `aarch64` - solved by
  preceeding the `ldr` with an additional `add` instruction to form
  the full address before dereferencing the pointer.
* redo selection of segment/section for decls and consts based on
  combined type and value
2022-02-25 21:59:19 +01:00
Andrew Kelley
27eb42c15e Sema: implement tupleFieldVal, fix comptime elem_ptr 2022-02-24 22:28:37 -07:00
joachimschmidt557
f91fe9afb9
stage2 AArch64: more support for MCValue.got_load and direct_load 2022-02-23 21:58:13 +01:00
Jakub Konka
25e4b16e25 Port more behavior tests 2022-02-22 21:57:42 +01:00
joachimschmidt557
25f73224f7
stage2 AArch64: pass a few more behavior tests 2022-02-21 23:05:16 +01:00
joachimschmidt557
2ba1ef165a
stage2 AArch64: implement genSetReg for ptr_stack_offset 2022-02-21 22:54:14 +01:00
joachimschmidt557
a9154a7eaf
stage2 AArch64: implement storing to memory 2022-02-21 22:44:40 +01:00
Cody Tapscott
1639fd4c45 Fix 2D array support for C backend
This updates the C backend to use proper array types.

In order to do that, this commit also:
 - fixes up elem_ptr and field_ptr handling
 - adds `renderTypecast` (renders in C typecast format, e.g. "int* [10]")
 - adds a bit special handling for undefined pointers, which is necessary
   to support slice/elem_ptr to undefined decls
2022-02-16 12:57:11 -07:00
Jakub Konka
9c82f3ae6f stage2: disable failing aarch64-macos behavior tests 2022-02-15 21:04:36 +01:00
joachimschmidt557
22895f5616
stage2 AArch64: Enable behavior testing 2022-02-14 22:33:01 +01:00
joachimschmidt557
2262640e8b stage2 ARM: lower const slices
Follow-up to e1a535360fb9ed08fc48018571b9702ab12a5876 for ARM

This also fixes some stack offset calculation bugs
2022-02-12 00:01:05 +01:00
Jakub Konka
cad3e3e63a x64: enable more behavior tests 2022-02-11 12:49:06 +01:00
Jakub Konka
e139c41fd8 stage2: handle truncate to signed non-pow-two integers 2022-02-10 15:05:12 +01:00
Jakub Konka
c689df1215 stage2: disable some tests on x86_64-macos 2022-02-08 23:59:10 +01:00
Jakub Konka
e42b5e76ba stage2: handle void type in Elf DWARF gen
Enable more behavior tests on both x64 and arm
2022-02-08 23:43:25 +01:00
John Schmidt
fd1284ebd0 stage2: apply type coercion in if expressions
When setting the break value in an if expression we must explicitly
check if a result location type coercion that needs to happen. This was
already done for switch expression, so let's just imitate that check
and fix for if expressions. To make this possible, we now also propagate
`rl_ty_inst` to sub scopes.
2022-02-06 21:26:26 -05:00
Andrew Kelley
2c9a5e791b organize behavior tests
Every test that is moved in this commit has been checked to see if it is
now passing.
2022-01-26 00:36:12 -07:00
Andrew Kelley
b34f994c0b stage2: type system treats fn ptr and body separately
This commit updates stage2 to enforce the property that the syntax
`fn()void` is a function *body* not a *pointer*. To get a pointer, the
syntax `*const fn()void` is required.

ZIR puts function alignment into the func instruction rather than the
decl because this way it makes it into function types. LLVM backend
respects function alignments.

Struct and Union have methods `fieldSrcLoc` to help look up source
locations of their fields. These trigger full loading, tokenization, and
parsing of source files, so should only be called once it is confirmed
that an error message needs to be printed.

There are some nice new error hints for explaining why a type is
required to be comptime, particularly for structs that contain function
body types.

`Type.requiresComptime` is now moved into Sema because it can fail and
might need to trigger field type resolution. Comptime pointer loading
takes into account types that do not have a well-defined memory layout
and does not try to compute a byte offset for them.

`fn()void` syntax no longer secretly makes a pointer. You get a function
body type, which requires comptime. However a pointer to a function body
can be runtime known (obviously).

Compile errors that report "expected pointer, found ..." are factored
out into convenience functions `checkPtrOperand` and `checkPtrType` and
have a note about function pointers.

Implemented `Value.hash` for functions, enum literals, and undefined values.

stage1 is not updated to this (yet?), so some workarounds and disabled
tests are needed to keep everything working. Should we update stage1 to
these new type semantics? Yes probably because I don't want to add too
much conditional compilation logic in the std lib for the different
backends.
2022-01-24 21:47:53 -07:00
Andrew Kelley
4d05f2ae5f remove zig_is_stage2 from @import("builtin")
Instead use the standarized option for communicating the
zig compiler backend at comptime, which is `zig_backend`. This was
introduced in commit 1c24ef0d0b09a12a1fe98056f2fc04de78a82df3.
2022-01-17 21:55:49 -07:00
Thomas Ives
51efd553ae C backend: Improve lowering of Zig types to C types
1. Changed Zig pointers to functions to be typedef'd so then we can
   treat them the same as other types.

2. Distinguished between const slices (zig_L prefix) and mut slices
   (zig_M prefix).

3. Changed lowering of Zig "const pointers" (e.g. *const u8) to to C
   "pointers to const" (e.g. const char *) rather than C "const
   pointers" (e.g.  char * const)

4. Ensured that all typedefs are "linked" even if the decl doesn't
   require any forward declarations

5. Added test that exercises function pointer type rendering

6. Changed .slice_ptr instruction to allocate pointer local rather than
   a uintptr_t local
2021-11-10 12:39:47 -05:00
Emily Bellows
969bcb6a59 C backend: implement signed trunc 2021-10-30 16:09:55 -04:00
Andrew Kelley
bbe4a9fa99 C backend: implement trunc for unsigned non-pow2 ints 2021-10-28 18:33:13 -07:00
Andrew Kelley
98009a2f66 C backend: implement trunc instruction
Note that there is not any test coverage yet for integer
truncation involving non-power-of-two integers.
2021-10-28 17:41:45 -07:00
Andrew Kelley
3af9731600 stage2: implement runtime pointer access to global constants
The main problem that motivated these changes is that global constants
which are referenced by pointer would not be emitted into the binary.
This happened because `semaDecl` did not add `codegen_decl` tasks for
global constants, instead relying on the constant values being copied as
necessary. However when the global constants are referenced by pointer,
they need to be sent to the linker to be emitted.

After making global const arrays, structs, and unions get emitted, this
uncovered a latent issue: the anonymous decls that they referenced would
get garbage collected (via `deleteUnusedDecl`) even though they would
later be referenced by the global const.

In order to solve this problem, I introduced `anon_work_queue` which is
the same as `work_queue` except a lower priority. The `codegen_decl`
task for anon decls goes into the `anon_work_queue` ensuring that the
owner decl gets a chance to mark its anon decls as alive before they are
possibly deleted.

This caused a few regressions, which I made the judgement call to add
workarounds for. Two steps forward, one step back, is still progress.

The regressions were:
 * Two behavior tests having to do with unions. These tests were
   intentionally exercising the LLVM constant value lowering, however,
   due to the bug with garbage collection that was fixed in this commit,
   the LLVM code was not getting exercised, and union types/values were
   not implemented correctly, due to me forgetting that LLVM does not
   allow bitcasting aggregate values.
   - This is worked around by allowing those 2 test cases to regress,
     moving them to the "passing for stage1 only" section.
 * The test-stage2 test cases (in test/cases/*) for non-LLVM backends
   previously did not have any calls to lower struct values, but now
   they do. The code that was there was just `@panic("TODO")`. I
   replaced that code with a stub that generates the wrong value. This
   is an intentional miscompilation that will obviously need to get
   fixed before any struct behavior tests pass. None of the current
   tests we have exercise loading any values from these global const
   structs, so there is not a problem until we try to improve these
   backends.
2021-10-26 22:41:19 -07:00
Andrew Kelley
f0dcdd7931 stage2: fix Decl addrspace being undefined 2021-10-22 15:53:59 -07:00