aboutsummaryrefslogtreecommitdiff
path: root/src/arch
AgeCommit message (Collapse)Author
2024-05-11riscv: implement a basic `@intCast`David Rubin
the truncation panic logic is generated in Sema, so I don't need to roll anything of my own. I add all of the boilerplate for that detecting the truncation and it works in basic test cases!
2024-05-11riscv: fix overflow checks in addition.David Rubin
2024-05-11riscv: change `load_symbol` psuedo instruction size to 8David Rubin
2024-05-11riscv: fix how we calculate stack offsets. allows for pass by reference ↵David Rubin
arguments.
2024-05-11riscv: correctly index struct field accessDavid Rubin
when the struct is in stack memory, we access it using a byte-offset, because that's how the stack works. on the other hand when the struct is in a register, we are working with bits and the field offset should be a bit offset.
2024-05-11riscv: add `allocReg` helper, and clean up some comparing logicDavid Rubin
- Added the basic framework for panicing with an overflow in `airAddWithOverflow`, but there is no check done yet. - added the `cmp_lt`, `cmp_gte`, and `cmp_imm_eq` MIR instructions, and their respective functionality.
2024-05-11riscv: correct the order of the return epilogueDavid Rubin
2024-05-11riscv: pointer workDavid Rubin
lots of thinking later, ive begun to grasp my head around how the pointers should work. this commit allows basic pointer loading and storing to happen.
2024-05-11riscv: change up how we do argsDavid Rubin
- before we were storing each arg in it's own function arg register. with this commit now we store the args in the fa register before calling as per the RISC-V calling convention, however as soon as we enter the callee, aka in airArg, we spill the argument to the stack. this allows us to spend less effort worrying about whether we're going to clobber the function arguments when another function is called inside of the callee. - we were actually clobbering the fa regs inside of resolveCallingConvetion, because of the null argument to allocReg. now each lock is stored in an array which is then iterated over and unlocked, which actually aids in the first point of this commit.
2024-05-11riscv: reorganize `binOp` and implement `cmp_imm_gte` MIRDavid Rubin
this was an annoying one to do, as there is no (to my knowledge) myriad sequence that will allow us to do `gte` compares with an immediate without allocating a register. RISC-V provides a single instruction to do compares, that being `lt`, and so you need to use more than one for other variants, but in this case, i believe you need to allocate a register.
2024-05-11riscv: update builtin namesDavid Rubin
2024-05-11riscv: progress toward arraysDavid Rubin
- implement `airArrayElemVal` for arrays on the stack. This is really easy as we can just move the offset by the bytes into the array. This only works when the index access is comptime-known though, this won't work for runtime access.
2024-05-11riscv: implement 64 bit immediate into register loadingDavid Rubin
LLVM has a better myriad sequence for this, where they don't allocate a temporary register, but for now this will do.
2024-05-11riscv: 16 bit `@byteSwap`David Rubin
2024-05-11riscv: implement basic logical shiftingDavid Rubin
2024-05-11riscv: add `cmp_eq` MIR instructionDavid Rubin
this opens up the door for addition!
2024-05-11riscv: basic struct field accessDavid Rubin
the current implementation only works when the struct is in a register. we use some shifting magic to get the field into the LSB, and from there, given the type provenance, the generated code should never reach into the bits beyond the bit size of the type and interact with the rest of the struct.
2024-05-11riscv: implement basic branchingDavid Rubin
we use a code offset map in Emit.zig to pre-compute what byte offset each MIR instruction is at. this is important because they can be of different size
2024-05-11riscv: implement `@abs`David Rubin
- add the `abs` MIR instruction - implement `@abs` by shifting to the right by `bits - 1`, and xoring.
2024-05-11riscv: update `start.zig` and restore ra from the proper stack offsetDavid Rubin
2024-05-11riscv: basic function argumentsDavid Rubin
- rename setRegOrMem -> setValue - a naive method of passing arguments by register - gather the prologue and epilogue and generate them in Emit.zig. this is cleaner because we have the final stack size in the emit step. - define the "fa" register set, which contains the RISC-V calling convention defined function argument registers
2024-05-11riscv: initial cleanup and workDavid Rubin
2024-05-08x86_64: fix C abi of incomplete sse registerJacob Young
2024-05-08x86_64 sysv C ABI: fix f128 param and return typesAndrew Kelley
Clang 17 passed struct{f128} parameters using rdi and rax, while Clang 18 matches GCC 13.2 behavior, passing them using xmm0. This commit makes Zig's LLVM backend match Clang 18 and GCC 13.2. The commit deletes a hack in x86_64/abi.zig which miscategorized f128 as "memory" which obviously disagreed with the spec.
2024-04-22x86_64: fix C abi for unionsJacob Young
Closes #19721
2024-04-17compiler: rework comptime pointer representation and accessmlugg
We've got a big one here! This commit reworks how we represent pointers in the InternPool, and rewrites the logic for loading and storing from them at comptime. Firstly, the pointer representation. Previously, pointers were represented in a highly structured manner: pointers to fields, array elements, etc, were explicitly represented. This works well for simple cases, but is quite difficult to handle in the cases of unusual reinterpretations, pointer casts, offsets, etc. Therefore, pointers are now represented in a more "flat" manner. For types without well-defined layouts -- such as comptime-only types, automatic-layout aggregates, and so on -- we still use this "hierarchical" structure. However, for types with well-defined layouts, we use a byte offset associated with the pointer. This allows the comptime pointer access logic to deal with reinterpreted pointers far more gracefully, because the "base address" of a pointer -- for instance a `field` -- is a single value which pointer accesses cannot exceed since the parent has undefined layout. This strategy is also more useful to most backends -- see the updated logic in `codegen.zig` and `codegen/llvm.zig`. For backends which do prefer a chain of field and elements accesses for lowering pointer values, such as SPIR-V, there is a helpful function in `Value` which creates a strategy to derive a pointer value using ideally only field and element accesses. This is actually more correct than the previous logic, since it correctly handles pointer casts which, after the dust has settled, end up referring exactly to an aggregate field or array element. In terms of the pointer access code, it has been rewritten from the ground up. The old logic had become rather a mess of special cases being added whenever bugs were hit, and was still riddled with bugs. The new logic was written to handle the "difficult" cases correctly, the most notable of which is restructuring of a comptime-only array (for instance, converting a `[3][2]comptime_int` to a `[2][3]comptime_int`. Currently, the logic for loading and storing work somewhat differently, but a future change will likely improve the loading logic to bring it more in line with the store strategy. As far as I can tell, the rewrite has fixed all bugs exposed by #19414. As a part of this, the comptime bitcast logic has also been rewritten. Previously, bitcasts simply worked by serializing the entire value into an in-memory buffer, then deserializing it. This strategy has two key weaknesses: pointers, and undefined values. Representations of these values at comptime cannot be easily serialized/deserialized whilst preserving data, which means many bitcasts would become runtime-known if pointers were involved, or would turn `undefined` values into `0xAA`. The new logic works by "flattening" the datastructure to be cast into a sequence of bit-packed atomic values, and then "unflattening" it; using serialization when necessary, but with special handling for `undefined` values and for pointers which align in virtual memory. The resulting code is definitely slower -- more on this later -- but it is correct. The pointer access and bitcast logic required some helper functions and types which are not generally useful elsewhere, so I opted to split them into separate files `Sema/comptime_ptr_access.zig` and `Sema/bitcast.zig`, with simple re-exports in `Sema.zig` for their small public APIs. Whilst working on this branch, I caught various unrelated bugs with transitive Sema errors, and with the handling of `undefined` values. These bugs have been fixed, and corresponding behavior test added. In terms of performance, I do anticipate that this commit will regress performance somewhat, because the new pointer access and bitcast logic is necessarily more complex. I have not yet taken performance measurements, but will do shortly, and post the results in this PR. If the performance regression is severe, I will do work to to optimize the new logic before merge. Resolves: #19452 Resolves: #19460
2024-04-16x86_64: fix miscompilation regression in package fetching codeJacob Young
2024-04-08InternPool: remove slice from byte aggregate keysJacob Young
This deletes a ton of lookups and avoids many UAF bugs. Closes #19485
2024-04-06x86_64: fix abi of nested structsJacob Young
2024-03-30x86_64: cleanup comptime mutable memory changeJacob Young
2024-03-30Sema: rework `@fieldParentPtr` to accept a pointer typeJacob Young
There is no way to know the expected parent pointer attributes (most notably alignment) from the type of the field pointer, so provide them in the first argument.
2024-03-30cbe: rewrite `CType`Jacob Young
Closes #14904
2024-03-26compiler: eliminate TypedValuemlugg
The only logic which remained in this file was the Value printing logic. This has been moved into a new `print_value.zig`.
2024-03-26compiler: eliminate most usages of TypedValuemlugg
2024-03-26Zcu: eliminate `Decl.alive` fieldmlugg
Legacy anon decls now have three uses: * Type owner decls * Function owner decls * `@export` and `@extern` Therefore, there are no longer any cases where we wish to explicitly omit legacy anon decls from the binary. This means we can remove the concept of an "alive" vs "dead" `Decl`, which also allows us to remove the separate `anon_work_queue` in `Compilation`.
2024-03-26compiler: eliminate legacy Value representationmlugg
Good riddance! Most of these changes are trivial. There's a fix for a minor bug this exposed in `Value.readFromPackedMemory`, but aside from that, it's all just things like changing `intern` calls to `toIntern`.
2024-03-26Zcu.Decl: remove `ty` fieldmlugg
`Decl` can no longer store un-interned values, so this field is now unnecessary. The type can instead be fetched with the new `typeOf` helper method, which just gets the type of the Decl's `Value`.
2024-03-25compiler: implement analysis-local comptime-mutable memorymlugg
This commit changes how we represent comptime-mutable memory (`comptime var`) in the compiler in order to implement the intended behavior that references to such memory can only exist at comptime. It does *not* clean up the representation of mutable values, improve the representation of comptime-known pointers, or fix the many bugs in the comptime pointer access code. These will be future enhancements. Comptime memory lives for the duration of a single Sema, and is not permitted to escape that one analysis, either by becoming runtime-known or by becoming comptime-known to other analyses. These restrictions mean that we can represent comptime allocations not via Decl, but with state local to Sema - specifically, the new `Sema.comptime_allocs` field. All comptime-mutable allocations, as well as any comptime-known const allocs containing references to such memory, live in here. This allows for relatively fast checking of whether a value references any comptime-mtuable memory, since we need only traverse values up to pointers: pointers to Decls can never reference comptime-mutable memory, and pointers into `Sema.comptime_allocs` always do. This change exposed some faulty pointer access logic in `Value.zig`. I've fixed the important cases, but there are some TODOs I've put in which are definitely possible to hit with sufficiently esoteric code. I plan to resolve these by auditing all direct accesses to pointers (most of them ought to use Sema to perform the pointer access!), but for now this is sufficient for all realistic code and to get tests passing. This change eliminates `Zcu.tmp_hack_arena`, instead using the Sema arena for comptime memory mutations, which is possible since comptime memory is now local to the current Sema. This change should allow `Decl` to store only an `InternPool.Index` rather than a full-blown `ty: Type, val: Value`. This commit does not perform this refactor.
2024-03-18Add 64bit byteswap case, use fewer localsSuperAuguste
2024-03-15bsd: debitrot AtomicOrder renamesMichael Dusan
- complete std.builtin.AtomicOrder renames that were missed from 6067d39522f
2024-03-11Merge pull request #19229 from tiehuis/ryu-128Andrew Kelley
std.fmt: add ryu floating-point formatting implementation
2024-03-11std.builtin: make atomic order fields lowercaseTristan Ross
2024-03-11std.builtin: make link mode fields lowercaseTristan Ross
2024-03-11std.builtin: make container layout fields lowercaseTristan Ross
2024-03-10wasm/codegen: add "and" + "or" impl for big intsMarc Tiehuis
2024-03-06InternPool: create specialized functions for loading namespace typesmlugg
Namespace types (`struct`, `enum`, `union`, `opaque`) do not use structural equality - equivalence is based on their Decl index (and soon will change to AST node + captures). However, we previously stored all other information in the corresponding `InternPool.Key` anyway. For logical consistency, it makes sense to have the key only be the true key (that is, the Decl index) and to load all other data through another function. This introduces those functions, by the name of `loadStructType` etc. It's a big diff, but most of it is no-brainer changes. In future, it might be nice to eliminate a bunch of the loaded state in favour of accessor functions on the `LoadedXyzType` types (like how we have `LoadedUnionType.size()`), but that can be explored at a later date.
2024-03-02Air: replace `.dbg_inline_*` with `.dbg_inline_block`Jacob Young
This prevents the possibility of not emitting a `.dbg_inline_end` instruction and reduces the allocation requirements of the backends. Closes #19093
2024-03-01compiler: audit debug mode checksJacob Young
* Introduce `-Ddebug-extensions` for enabling compiler debug helpers * Replace safety mode checks with `std.debug.runtime_safety` * Replace debugger helper checks with `!builtin.strip_debug_info` Sometimes, you just have to debug optimized compilers...
2024-02-29wasm: make symbol indexes a non-exhaustive enumLuuk de Gram
This introduces some type safety so we cannot accidently give an atom index as a symbol index. This also means we do not have to store any optionals and therefore allow for memory optimizations. Lastly, we can now always simply access the symbol index of an atom, rather than having to call `getSymbolIndex` as it is easy to forget.
2024-02-29wasm: correctly generate relocations for type indexLuuk de Gram
Previously we could directly write the type index because we used the index that was known in the final binary. However, as we now process the Zig module as its own relocatable object file, we must ensure to generate a relocation for type indexes. This also ensures that we can later link the relocatable object file as a standalone also. This also fixes generating indirect function table entries for ZigObject as it now correctly points to the relocation symbol index rather than the symbol index that owns the relocation.