aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
AgeCommit message (Collapse)Author
2022-03-19wasm: All union/tuple/array tests passingLuuk de Gram
This implements improvements/fixes to get all the union, tuple, and array behavior tests passing. Previously, we lowered parent pointers for field_ptr and element_ptr incompletely. This has now been improved to recursively lower such pointer. Also a fix was done to `generateSymbol` when checking a container's layout. Previously it was assumed to always be a struct. However, the type can also be a tuple, and therefore panicking. Updating to ask a type's container layout instead allows us to keep a singular branch for both cases.
2022-03-14stage2: apply fix for #11165 to codegen.zig for native backendsMitchell Hashimoto
Co-authored-by: Cody Tapscott <topolarity@tapscott.me>
2022-03-14stage2: rework Value storage of structs and arraysAndrew Kelley
Now they both use `Value.Tag.aggregate`. Additionally the LLVM backend now has implemented lowering of tuple values.
2022-03-10stage2: implement integer pointer constantsAndrew Kelley
2022-03-06wasm: Unify function generationLuuk de Gram
Like decl code generation, also unify the wasm backend and the wasm linker to call into the general purpose `codegen.zig` to generate the code for a function.
2022-03-06stage2: Fix codegen for unions and error unionsLuuk de Gram
When an union had a zero-sized payload type, we would lower the tag twice. This is fixed by exiting early when `payload_size` is 0. With regards to error unions, we were only accounting for padding for the payload field. However, the errorset value can have a smaller alignment than the payload as well, i.e. error!usize. We fix this by also accounting for padding/alignment of the error set tag of an error union.
2022-03-05elf: add debug info for non-ptr optionalsJakub Konka
2022-03-02codegen: handle elem_ptr when lowering to memoryJakub Konka
* x64: handle storing from-to non-stack memory
2022-03-02codegen: leave f80 explicitly unhandled for nowJakub Konka
2022-03-02codegen: lower optionals and floats across linking backendsJakub Konka
2022-03-01codegen: ensure we descend on nested field_ptrs when loweringJakub Konka
2022-03-01codegen: lower field_ptr to memory across linking backendsJakub Konka
This requires generating an addend for the target relocation as the field pointer might point at a field inner to the container.
2022-03-01Merge pull request #11016 from ziglang/x64-more-codegenJakub Konka
2022-02-28Sema: fix pointer type hash and equality functionsAndrew Kelley
Several issues with pointer types are fixed: Prior to this commit, Zig would not canonicalize a pointer type with an explicit alignment to alignment=0 if it matched the pointee ABI alignment. In order to fix this, `Type.ptr` now takes a Target parameter. I also moved the host_size canonicalization to `Type.ptr` since target is now available. Similarly, is_allowzero in the case of C pointers is now treated as a canonicalization done by the function rather than a precondition. in-memory coercion for pointers now properly checks ABI alignment of pointee types instead of incorrectly treating the 0 value as an alignment. Type equality is completely reworked based on the tag() rather than the zigTypeTag(). It's still semantically based on zigTypeTag() but that knowledge is implied rather than dictating the control flow of the logic. Importantly, this fixes cases for opaques, structs, tuples, enums, and unions, where type equality was incorrectly returning based on whether the tag() values were equal. Additionally, pointer type equality now takes into account alignment. Because we canonicalize non-zero alignment which equals pointee type ABI alignment to alignment=0, this now can be a simple integer comparison. Type hashing is implemented for pointers and floats. Array types now additionally hash their sentinels. This regressed some behavior tests that were passing but only because of bugs regarding type equality. The C backend has a noticeable problem with lowering differently-aligned pointers (particularly slices) as the same type, causing C compilation errors due to duplicate declarations.
2022-02-28codegen: fix padding calculation for error unions when loweringJakub Konka
* do not track `rdi` register before `call` inst, but instead freeze it from further use, until `call` has been realised * pass more error union tests
2022-02-28codegen: impl lowering of union type to memoryJakub Konka
2022-02-22x64: fix lowering of error unions (we didn't pad to alignment)Jakub Konka
* fix returning large values on stack from procedure calls - we need to explicitly specify source and dest base registers for `genSetStack` as well
2022-02-22codegen: lower repeated and empty_with_sentinel array typeJakub Konka
2022-02-22codegen: lower error_set and error_unionJakub Konka
2022-02-11elf: store pointer relocations indexed by containing atomJakub Konka
In `getDeclVAddr`, it may happen that the target `Decl` has not been allocated space in virtual memory. In this case, we store a relocation in the linker-global table which we will iterate over when flushing the module, and fill in any missing address in the final binary. Note that for optimisation, if the address was resolved at the time of a call to `getDeclVAddr`, we skip relocating this atom. This commit also adds the glue code for lowering const slices in the ARM backend.
2022-02-11codegen: handle lowering of const slice pointersJakub Konka
2022-02-09stage2: handle decl ref to void typesJakub Konka
Fixes behavior test 1914
2022-02-08stage2: tiny improvements all over the placeJakub Konka
* pass more x64 behavior tests * return with a TODO error when lowering a decl with no runtime bits * insert some debug logs for tracing recursive descent down the type-value tree when lowering types * print `Decl`'s name when print debugging `decl_ref` value
2022-02-07stage2,x64: impl lowering of shift ops in EmitJakub Konka
2022-02-02stage2: pad out (non-packed) struct fields when lowering to bytesJakub Konka
* pad out (non-packed) struct fields when lowering to bytes to be saved in the binary - prior to this change, fields would be saved at non-aligned addresses leading to wrong accesses * add a matching test case to `behavior/struct.zig` tests * fix offset to field calculation in `struct_field_ptr` on `x86_64`
2022-01-24stage2: rework a lot of stuffAndrew Kelley
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
2022-01-15stage2: fix Decl garbage collection not marking enoughAndrew Kelley
It is the job of codegen backends to mark Decls that are referenced as alive so that the frontend does not sweep them with the garbage. This commit unifies the code between the backends with an added method on Decl. The implementation is more complete than before, switching on the Decl val tag and recursing into sub-values. As a result, two more array tests are passing.
2022-01-10stage2: enable zig test on x86_64-macos (#10551)Jakub Konka
* stage2: put decls in different MachO sections Use `getDeclVAddrWithReloc` when targeting MachO backend rather than `getDeclVAddr` - this fn returns a zero vaddr and instead creates a relocation on the linker side which will get automatically updated whenever the target decl is moved in memory. This fn also records a rebase of the target pointer so that its value is correctly slid in presence of ASLR. This commit enables `zig test` on x86_64-macos. * stage2: fix output section selection for type,val pairs
2022-01-06Sema: const inferred alloc infers comptime-nessAndrew Kelley
const locals now detect if the value ends up being comptime known. In such case, it replaces the runtime AIR instructions with a decl_ref const. In the backends, some more sophisticated logic for marking decls as alive was needed to prevent Decls incorrectly being garbage collected that were indirectly referenced in such manner.
2022-01-01stage2 codegen: Add generateSymbol for optional stubjoachimschmidt557
2021-12-30stage2 ARM: implement struct_field_ptr and struct_field_valjoachimschmidt557
2021-12-28stage2 ARM: implement slice_elem_val for types with size <= 4joachimschmidt557
2021-12-26stage2 codegen: Implement generateSymbol for undefined valuesjoachimschmidt557
2021-11-24stage2: fix unwrap function call with optional pointer return valueAndrew Kelley
2021-11-21stage2: fix the build for 32-bit architecturesAndrew Kelley
* Introduce a mechanism into Sema for emitting a compile error when an integer is too big and we need it to fit into a usize. * Add `@intCast` where necessary * link/MachO: fix an unnecessary allocation when all that was happening was appending zeroes to an ArrayList. * Add `error.Overflow` as a possible error to some codepaths, allowing usage of `math.intCast`. closes #9710
2021-11-08stage2 x86_64: add MIR->Isel lowering step for x86_64Jakub Konka
* incorporate Andrew's MIR draft as Mir.zig * add skeleton for Emit.zig module - Emit will lower MIR into machine code or textual ASM. * implement push * implement ret * implement mov r/m, r * implement sub r/m imm and sub r/m, r * put encoding common ops together - some ops share impl such as MOV and cmp so put them together and vary the actual opcode with modRM ext only. * implement pop * implement movabs - movabs being a special-case of mov not handled by general mov MIR instruction due to requirement to handle 64bit immediates. * store imm64 as a struct `Imm64{ msb: u32, lsb: u32 }` in extra data for use with for instance movabs inst * implement more mov variations * implement adc * implement add * implement sub * implement xor * implement and * implement or * implement sbb * implement cmp * implement lea - lea doesn't follow the scheme as other inst above. Similarly, I think bit shifts and rotates should be put in a separate basket too. * implement adc_scale_src * implement add_scale_src * implement sub_scale_src * implement xor_scale_src * implement and_scale_src * implement or_scale_src * implement sbb_scale_src * implement cmp_scale_src * implement adc_scale_dst * implement add_scale_dst * implement sub_scale_dst * implement xor_scale_dst * implement and_scale_dst * implement or_scale_dst * implement sbb_scale_dst * implement cmp_scale_dst * implement mov_scale_src * implement mov_scale_dst * implement adc_scale_imm * implement add_scale_imm * implement sub_scale_imm * implement xor_scale_imm * implement and_scale_imm * implement or_scale_imm * implement sbb_scale_imm * implement cmp_scale_imm * port bin math to MIR * backpatch stack size into prev MIR inst * implement Function.gen() (minus dbg info) * implement jmp/call [imm] - we can now call functions using indirect absolute addressing, or via registers. * port airRet to use MIR * port airLoop to use MIR * patch up performReloc to use inst indices * implement conditional jumps (without relocs) * implement set byte on condition * implement basic lea r64, [rip + imm] * implement calling externs * implement callq in PIE * implement lea RIP in PIE context * remove all refs to Encoder from CodeGen * implement basic imul ops * pass all Linux tests! * enable most of dbg info gen * generate arg dbg info in Emit
2021-11-07stage2 ARM: move codegen to separate filejoachimschmidt557
This also removes i386 codegen code, which was unused and untested
2021-11-02stage2 RISCV64: move codegen to separate filejoachimschmidt557
2021-10-31stage2: move x86_64 codegen to arch/x86_64/CodeGen.zigJakub Konka
This mimics steps taken for aarch64 and preps stage2 x86_64 for a rewrite introducing MIR for this arch.
2021-10-31stage2 AArch64: begin transition to MIRjoachimschmidt557
This commit includes the transitions for the following instructions: - add_immediate - b - bl - blr - brk - ldp - ldr - ldrb - ldrh - mov_to_from_sp - mov_register - movk - movz - nop - ret - stp - str - strb - strh - sub_immediate - svc
2021-10-29stage2: implement `@popCount` for non-vectorsAndrew Kelley
2021-10-26stage2: implement runtime pointer access to global constantsAndrew Kelley
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-22stage2: slice and alignment fixesAndrew Kelley
* Fix backend using wrong union field of the slice instruction. * LLVM backend properly sets alignment on global variables. * Sema: add coercion for *T to *[1]T * Sema: pointers to Decls with explicit alignment now have alignment metadata in them.
2021-10-21stage2: more division supportAndrew Kelley
AIR: * div is renamed to div_trunc. * Add div_float, div_floor, div_exact. - Implemented in Sema and LLVM codegen. C backend has a stub. Improvements to std.math.big.Int: * Add `eqZero` function to `Mutable`. * Fix incorrect results for `divFloor`. Compiler-rt: * Add muloti4 to the stage2 section.
2021-10-21stage2: elemPtr for slicesRobin Voetter
* Restructure elemPtr a bit * New AIR instruction: slice_elem_ptr, which returns a pointer to an element of a slice * Value: adapt elemPtr to work on slices
2021-10-21stage2: remove ptr_ptr_elem_val and ptr_slice_elem_valRobin Voetter
2021-10-20stage2: implement slicingAndrew Kelley
* New AIR instruction: slice, which constructs a slice out of a pointer and a length. * AstGen: use `coerced_ty` for start and end expressions, use `none` for the sentinel, and don't try to load the result of the slice operation because it returns a by-value result. * Sema: pointer arithmetic is extracted into analyzePointerArithmetic and it is used by the implementation of slice. - Also I implemented comptime pointer addition. * Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them inside the slice semantic analysis. - The approach in stage2 is much cleaner than stage1 because it uses more granular analysis calls for obtaining the slice pointer, doing arithmetic on it, and checking if the length is comptime-known. * Sema: use the slice Value Tag for slices when doing coercion from pointer-to-array. * LLVM backend: detect when emitting a GEP instruction into a pointer-to-array and add the extra index that is required. * Type: ptrAlignment for c_void returns 0. * Implement Value.hash and Value.eql for slices. * Remove accidentally duplicated behavior test.
2021-10-20stage2: air ptr_slice_len_ptr and ptr_slice_ptr_ptrRobin Voetter
2021-10-15stage2 AArch64: move codegen to separate filejoachimschmidt557
2021-10-14stage2: implement `@minimum` and `@maximum`, including vectorsAndrew Kelley
* std.os: take advantage of `@minimum`. It's probably time to deprecate `std.min` and `std.max`. * New AIR instructions: min and max * Introduce SIMD vector support to stage2 * Add `@Type` support for vectors * Sema: add `checkSimdBinOp` which can be re-used for other arithmatic operators that want to support vectors. * Implement coercion from vectors to arrays. - In backends this is handled with bitcast for vector to array, however maybe we want to reduce the amount of branching by introducing an explicit AIR instruction for it in the future. * LLVM backend: implement lowering vector types * Sema: Implement `slice.ptr` at comptime * Value: improve `numberMin` and `numberMax` to support floats in addition to integers, and make them behave properly in the presence of NaN.