aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
AgeCommit message (Collapse)Author
2021-04-16stage2 x86_64: try to fix RIP-relative offset to GOT for machogracefu
2021-04-16stage2 x86_64: simplify inst encoder to a set of dumb helper fnsgracefu
2021-04-16stage2 x86_64: implement integer mulgracefu
This was also an experiment to see if it were easier to implement a new feature when using the instruction encoder. Verdict: It's not that much easier, but I think it's certainly much more readable, because the description of the Instruction annotates what each field means. Right now, precise knowledge of x86_64 instructions is still required because things like when to set the 64-bit flag, how to read x86_64 instruction references, etc. are still not automatically done for you. In the future, this interface might make it sligtly easier to write an assembler for x86_64, by abstracting the bit-fiddling aspects of instruction encoding.
2021-04-16stage2 x86_64: use abi size to determine 64-bit operationgracefu
From my very cursory reading, it seems that the register manager doesn't distinguish between registers that are physically the same but have different sizes. In that case, this means that during codegen, we can't rely on `reg.size()` when determining the width of the operations we have to perform. Instead, we must use some form of `ty.abiSize(self.target.*)` to determine the size of the type we're operating with. If this size is 64 bits, then we should enable 64-bit operation. This fixed a bug in the codegen for spilling instructions, which was overwriting the previous stack entry with zeroes. See the modified test case in this commit.
2021-04-16stage2 x86_64: refactor codegen to use inst encodergracefu
There are parts of it that I didn't modify because the byte representation was important (e.g. we need to know what the exact byte position where we store the address into the offset table is)
2021-04-15stage2: entry point via std lib and proper updated file detectionAndrew Kelley
Instead of Module setting up the root_scope with the root source file, instead, Module relies on the package table graph being set up properly, and inside `update()`, it does the equivalent of `_ = @import("std");`. This, in term, imports start.zig, which has the logic to call main (or not). `Module` no longer has `root_scope` - the root source file is no longer special, it's just in the package table mapped to "root". I also went ahead and implemented proper detection of updated files. mtime, inode, size, and source hash are kept in `Scope.File`. During an update, iterate over `import_table` and stat each file to find out which ones are updated. The source hash is redundant with the source hash used by the struct decl that corresponds to the file, so it should be removed in a future commit before merging the branch. * AstGen: add "previously declared here" notes for variables shadowing decls. * Parse imports as structs. Module now calls `AstGen.structDeclInner`, which is called by `AstGen.containerDecl`. - `importFile` is a bit kludgy with how it handles the top level Decl that kinda gets merged into the struct decl at the end of the function. Be on the look out for bugs related to that as well as possibly cleaner ways to implement this. * Module: factor out lookupDeclName into lookupIdentifier and lookupNa * Rename `Scope.Container` to `Scope.Namespace`. * Delete some dead code. This branch won't work until `usingnamespace` is implemented because it relies on `@import("builtin").OutputMode` and `OutputMode` comes from a `usingnamespace`.
2021-04-11stage2 ARM: Add fibonacci testjoachimschmidt557
2021-04-11stage2 codegen: Set MCValue of register arguments to their stack copyjoachimschmidt557
2021-04-09Merge pull request #8470 from ziglang/stage2-startAndrew Kelley
stage2: blaze the trail for std lib integration
2021-04-08stage2: simplify Decl src_node fieldAndrew Kelley
Also fix "previous definition here" error notes to be correct.
2021-04-08Merge pull request #8464 from gracefuu/grace/wasm-opsAndrew Kelley
stage2 wasm: Add division and bitwise/boolean ops &, |, ^, and, or
2021-04-08stage2: Add .div to ir.ziggracefu
2021-04-07stage2 regalloc: Add unit test for getRegjoachimschmidt557
2021-04-06stage2 regalloc: Add getReg and getRegWithoutTrackingjoachimschmidt557
2021-04-02stage2 AArch64: Add ldrh and ldrb instructionsjoachimschmidt557
2021-04-02stage2 register_manager: Add unit tests for tryAllocReg and allocRegjoachimschmidt557
2021-04-02stage2 codegen: Extract register management code into separate filejoachimschmidt557
2021-04-01stage2: implement structs in the frontendAndrew Kelley
New ZIR instructions: * struct_decl_packed * struct_decl_extern New TZIR instruction: struct_field_ptr Introduce `Module.Struct`. It uses `Value` to store default values and abi alignments. Implemented Sema.analyzeStructFieldPtr and zirStructDecl. Some stuff I changed from `@panic("TODO")` to `log.warn("TODO")`. It's becoming more clear that we need the lazy value mechanism soon; Type is becoming unruly, and some of these functions have too much logic given that they don't have any context for memory management or error reporting.
2021-03-31Merge pull request #8266 from ziglang/zir-memory-layoutAndrew Kelley
rework ZIR memory layout; overhaul source locations
2021-03-31Sema: implement switch validation for rangesAndrew Kelley
2021-03-31stage2 codegen: Make sure function return value is in a calleejoachimschmidt557
preserved register
2021-03-31stage2 AArch64: implement strb and strhjoachimschmidt557
2021-03-28stage2: implement sema for @errorToInt and @intToErrorjacob gw
2021-03-18stage2: codegen: update asm IR to new namesAndrew Kelley
2021-03-18stage2: the code is compiling againAndrew Kelley
(with a lot of things commented out)
2021-03-18stage2: get Module and Sema compiling againAndrew Kelley
There are some `@panic("TODO")` in there but I'm trying to get the branch to the point where collaborators can jump in. Next is to repair the seam between LazySrcLoc and codegen's expected absolute file offsets.
2021-03-18Merge remote-tracking branch 'origin/master' into zir-memory-layoutAndrew Kelley
I need the enum arrays that were just merged into master.
2021-03-17stage2: Module and Sema are compiling againAndrew Kelley
Next up is reworking the seam between the LazySrcLoc emitted by Sema and the byte offsets currently expected by codegen. And then the big one: updating astgen.zig to use the new memory layout.
2021-03-17macho: offset table part of GOTJakub Konka
2021-03-17macho: apply some renames to bring closer to zldJakub Konka
2021-03-11Merge pull request #7934 from Vexu/stage2-cbeAndrew Kelley
Stage2 cbe: optionals and errors
2021-03-11stage2 tzir: Add wrapping integer arithmetic instructionsjoachimschmidt557
2021-03-08cbe: add error comparison supportjacob gw
2021-03-02stage2 ARM: Implement basic integer multiplicationjoachimschmidt557
2021-02-25improve stage2 to allow catch at comptime:g-w1
* add error_union value tag. * add analyzeIsErr * add Value.isError * add TZIR wrap_errunion_payload and wrap_errunion_err for wrapping from T -> E!T and E -> E!T * add anlyzeInstUnwrapErrCode and analyzeInstUnwrapErr * add analyzeInstEnsureErrPayloadVoid: * add wrapErrorUnion * add comptime error comparison for tests * tests!
2021-02-25stage2 ARM: Save callee-saved registersjoachimschmidt557
Add a new allocated_registers bitmap to keep track of all callee-saved registers allocated during generation of this function. Function(.arm).gen uses this data to generate instructions in the function prologue and epilogue to push and pop these registers respectively.
2021-02-24zig fmt src/Andrew Kelley
2021-02-24Merge remote-tracking branch 'origin/master' into ast-memory-layoutAndrew Kelley
2021-02-21stage2 codegen: Add Type argument to genSetRegjoachimschmidt557
2021-02-12stage2: more progress towards Module/astgen building with new mem layoutAndrew Kelley
2021-02-12stage2: fix zero-sized function parameters (#7998)Tadeo Kondrak
2021-02-09require specifier for arrayish typesJonathan Marler
2021-02-09stage2 ARM: fix register allocation in genArmBinOpjoachimschmidt557
Previously, this would reuse an operand even if reuseOperand returned false for both operands. genArmBinOpCode was also changed to be more Three-address code oriented in the process.
2021-02-01stage2 ARM: save function arguments to stack for debuggingjoachimschmidt557
This changes genArg to copy registers to the stack for better debugging. Thus, it requires genSetStack to be implemented in order for genArg to work.
2021-01-31astgen: rework labeled blocksAndrew Kelley
2021-01-31sema: after block gets peer type resolved, insert type coercionsAndrew Kelley
on the break instruction operands. This involves a new TZIR instruction, br_block_flat, which represents a break instruction where the operand is the result of a flat block. See the doc comments on the instructions for more details. How it works: when adding break instructions in semantic analysis, the underlying allocation is slightly padded so that it is the size of a br_block_flat instruction, which allows the break instruction to later be converted without removing instructions inside the parent body. The extra type coercion instructions go into the body of the br_block_flat, and backends are responsible for dispatching the instruction correctly (it should map to the same function calls for related instructions).
2021-01-31stage2: rework astgen result locationsAndrew Kelley
Motivating test case: ```zig export fn _start() noreturn { var x: u64 = 1; var y: u32 = 2; var thing: u32 = 1; const result = if (thing == 1) x else y; exit(); } ``` The main idea here is for astgen to output ideal ZIR depending on whether or not the sub-expressions of a block consume the result location. Here, neither `x` nor `y` consume the result location of the conditional expression block, and so the ZIR should communicate the result of the condbr using break instructions, not with the result location pointer. With this commit, this is accomplished: ``` %22 = alloc_inferred() %23 = block({ %24 = const(TypedValue{ .ty = type, .val = bool}) %25 = deref(%18) %26 = const(TypedValue{ .ty = comptime_int, .val = 1}) %27 = cmp_eq(%25, %26) %28 = as(%24, %27) %29 = condbr(%28, { %30 = deref(%4) < there is no longer a store instruction here > %31 = break("label_23", %30) }, { %32 = deref(%11) < there is no longer a store instruction here > %33 = break("label_23", %32) }) }) %34 = store_to_inferred_ptr(%22, %23) <-- the store is only here %35 = resolve_inferred_alloc(%22) ``` However if the result location gets consumed, the break instructions change to break_void, and the result value is communicated only by the stores, not by the break instructions. Implementation: * The GenZIR scope that conditional branches uses now has an optional result location pointer field and a count of how many times the result location ended up being an rvalue (not consumed). * When rvalue() is called on a result location for a block, it increments this counter. After generating the branches of a block, astgen for the conditional branch checks this count and if it is 2 then the store_to_block_ptr instructions are elided and it calls rvalue() using the block result (which will account for peer type resolution on the break operands). astgen has many functions disabled until they can be reworked with these new semantics. That will be done before merging the branch. There are some new rules for astgen to follow regarding result locations and what you are allowed/required to do depending on which one is passed to expr(). See the updated doc comments of ResultLoc for details. I also changed naming conventions of stuff in this commit, sorry about that.
2021-01-18stage2: rework ZIR/TZIR for optionals and error unionsAndrew Kelley
* fix wrong pointer const-ness when unwrapping optionals * allow grouped expressions and orelse as lvalues * ZIR for unwrapping optionals: no redundant deref - add notes to please don't use rlWrapPtr, this function should be deleted * catch and orelse: better ZIR for non-lvalue: no redundant deref; operate entirely on values. lvalue case still works properly. - properly propagate the result location into the target expression * Test harness: better output when tests fail due to compile errors. * TZIR: add instruction variants. These allow fewer TZIR instructions to be emitted from zir_sema. See the commit diff for per-instruction documentation. - is_null - is_non_null - is_null_ptr - is_non_null_ptr - is_err - is_err_ptr - optional_payload - optional_payload_ptr * TZIR: removed old naming convention instructions: - isnonnull - isnull - iserr - unwrap_optional * ZIR: add instruction variants. These allow fewer ZIR instructions to be emitted from astgen. See the commit diff for per-instruction documentation. - is_non_null - is_null - is_non_null_ptr - is_null_ptr - is_err - is_err_ptr - optional_payload_safe - optional_payload_unsafe - optional_payload_safe_ptr - optional_payload_unsafe_ptr - err_union_payload_safe - err_union_payload_unsafe - err_union_payload_safe_ptr - err_union_payload_unsafe_ptr - err_union_code - err_union_code_ptr * ZIR: removed old naming convention instructions: - isnonnull - isnull - iserr - unwrap_optional_safe - unwrap_optional_unsafe - unwrap_err_safe - unwrap_err_unsafe - unwrap_err_code
2021-01-18stage2 AArch64: implement jumpjoachimschmidt557
2021-01-18Merge pull request #7808 from joachimschmidt557/stage2-aarch64Jakub Konka
Stage2 AArch64: Fix genSetStack