Rename all references of sparcv9 to sparc64, to make Zig align more with
other projects. Also, added new function to convert glibc arch name to Zig
arch name, since it refers to the architecture as sparcv9.
This is based on the suggestion by @kubkon in PR 11847.
(https://github.com/ziglang/zig/pull/11487#pullrequestreview-963761757)
If the hw doesn't have support for exotic floating-point types such
as `f80`, we lower the call to a compiler-rt function call instead.
I've added a behavior test specifically targeting this use case which
now passes on `aarch64-macos`.
Additionally, this commit makes it possible to successfully build
stage3 on `aarch64-macos`. We can print the compiler's help message,
however, building with it needs a little bit more love still.
* sret logic needed a check for hasRuntimeBits()
* lower f128 on windows targets with the "sse" class rather than
"memory". For reference, clang emits a compile error when __float128
is used with the MSVC ABI, saying that this type is not supported.
The docs for the x64 calling convention have both of these sentences:
- "Any argument that doesn't fit in 8 bytes, or isn't 1, 2, 4, or 8 bytes,
must be passed by reference."
- "All floating point operations are done using the 16 XMM registers."
* For i128, however, it is clear that the Windows calling convention
wants such an object to be passed by reference. I fixed the LLVM
lowering for function parameters to make this work.
So far it's supported by the LLVM backend only. I recommend for the
other backends to wait for the resolution of #10761 before adding
support for this feature.
Prior to this commit, the logic for ABI size and ABI alignment for
integers was naive and incorrect. This results in wasted hardware as
well as undefined behavior in the LLVM backend when we memset an
incorrect number of bytes to 0xaa due to disagreeing with LLVM about the
ABI size of integers.
This commit introduces a "max int align" value which is different per
Target. This value is used to derive the ABI size and alignment of all
integers.
This commit makes an interesting change from stage1, which treats
128-bit integers as 16-bytes aligned for x86_64-linux. stage1 is
incorrect. The maximum integer alignment on this system is only 8 bytes.
This change breaks the behavior test called "128-bit cmpxchg" because on
that target, 128-bit cmpxchg does require a 16-bytes aligned pointer to
a 128 bit integer. However, this alignment property does not belong on
*all* 128 bit integers - only on the pointer type in the `@cmpxchg`
builtin function prototype. The user can then use an alignment override
annotation on a 128-bit integer variable or struct field to obtain such
a pointer.
* outputs can have names and be referenced with template replacements
the same as inputs.
* fix print_air.zig not decoding correctly.
* LLVM backend: use a table for template names for simplicity
Just like for Struct in 8238d4b33585a715c58ab559cd001dd3ea1db55b, in the
case of ErrorUnion struct we need to return a compound literal "(T){...}"
instead of just "{}", which is invalid code when used in e.g. a "return"
expression.
The reason for having `@tan` is that we already have `@sin` and `@cos`
because some targets have machine code instructions for them, but in the
case that the implementation needs to go into compiler-rt, sin, cos, and
tan all share a common dependency which includes a table of data. To
avoid duplicating this table of data, we promote tan to become a builtin
alongside sin and cos.
ZIR: The tag enum is at capacity so this commit moves
`field_call_bind_named` to be `extended`. I measured this as one of
the least used tags in the zig codebase.
Fix libc math suffix for `f32` being wrong in both stage1 and stage2.
stage1: add missing libc prefix for float functions.
* std.math.snan: fix compilation error. Also make it and nan inline.
* LLVM: use a proper enum type for float op instead of enum literal.
Also various cleanups.
* LLVM: use LLVMBuildVectorSplat for vector splat AIR instruction.
- also the bindings had parameter order wrong
* LLVM: additionally handle f16 lowering. For now all targets report OK
but I think we will need to add some exceptions to this list.
Updates stage2 to manually lower softfloat operations for all unary
floating point operations and arithmetic.
Softfloat support still needs to be added for conversion operators
(float<->float and int<->float)
For parameters and return types of functions with the C calling
convention, the LLVM backend now has a special lowering for the function
type that makes the function adhere to the C ABI. The AIR instruction
lowerings for call, ret, and ret_load are adjusted to bitcast the real
type to the ABI type if necessary.
More work on this will need to be done, however, this improvement is
enough that stage3 now passes all the same behavior tests that stage2
passes - notably, translate-c no longer has a segfault due to C ABI
issues with Zig's Clang C API wrapper.
Rather than allocating Decl objects with an Allocator, we instead allocate
them with a SegmentedList. This provides four advantages:
* Stable memory so that one thread can access a Decl object while another
thread allocates additional Decl objects from this list.
* It allows us to use u32 indexes to reference Decl objects rather than
pointers, saving memory in Type, Value, and dependency sets.
* Using integers to reference Decl objects rather than pointers makes
serialization trivial.
* It provides a unique integer to be used for anonymous symbol names,
avoiding multi-threaded contention on an atomic counter.
* The `@bitCast` workaround is removed in favor of `@ptrCast` properly
doing element casting for slice element types. This required an
enhancement both to stage1 and stage2.
* stage1 incorrectly accepts `.{}` instead of `{}`. stage2 code that
abused this is fixed.
* Make some parameters comptime to support functions in switch
expressions (as opposed to making them function pointers).
* Avoid relying on local temporaries being mutable.
* Workarounds for when stage1 and stage2 disagree on function pointer
types.
* Workaround recursive formatting bug with a `@panic("TODO")`.
* Remove unreachable `else` prongs for some inferred error sets.
All in effort towards #89.
Prior to this, Liveness encoded `asm`, `call`, and `aggregate_init` with
a single 32-bit integer, allowing up to 35 operands (3 are provided by
the regular tomb_bits). However, the Zig language allows function calls
with more than 35 arguments, inline assembly with more than 35 inputs,
and anonymous tuples with more than 35 elements.
The new encoding stores an index to the extra array instead of the bits
directly, and then as many extra elements as needed to encode all the
operands. The MSB is used as a flag to tell which element is the last
one, allowing for 31 bits per element.
Prior to this, print_air did not bother correctly printing tombstones
for these instructions; now it does.
In addition to updating the BigTomb iteration logic in the machine code
backends, this commit extracts the common logic into the Liveness namespace.
This is not complete support for asm expressions, but allows a few more
test cases from test/behavior/asm.zig to pass. Since the non-register
inputs are named `input_${n}` they can cause name collisions: I'm
wrapping the asm expressions in their own block to prevent that.
Contextually, this change also makes test/behavior/asm.zig run for
stage2, but skips individual tests for most backends (I only verified
the C and LLVM backends successfully run one new test case) and the
entire test file for aarch64, where it's running into preexisting
shortcomings.
This commit introduces a new AIR instruction `cmp_lt_errors_len`. It's
specific to this use case for two reasons:
* The total number of errors is not stable during semantic analysis; it
can only be reliably checked when flush() is called. So the backend
that is lowering the instruction must emit a relocation of some kind
and then populate it during flush().
* The fewer AIR instructions in memory, the better for compiler
performance, so we squish complex meanings into AIR tags without
hesitation.
The instruction is implemented only in the LLVM backend so far. It does
this by creating a simple function which is gutted and re-populated
with each flush().
AstGen now uses ResultLoc.coerced_ty for `@intToError` and Sema does the
coercion.
Commit 052079c99455d01312d377d72fa1b8b5c0b22aad surfaced two issues with
the generated C code:
- renderInt128() contained a seemingly unnecessary assertion to verify
that the high 64 bits of the number were nonzero, dating back to
9bf1681990fe87a6b2e5fc644a89f1aece304579. I removed it.
- renderValue() didn't have any special handling for undefined structs,
falling back to printing "{}" which generated invalid expressions
such as "return {}" for functions returning structs, whereas
"return (S){}" is the correct form. I changed it accordingly.
At the same time I'm reenabling the relevant tests.
Sema:
* queue full resolution of std.builtin.Type.Error when doing `@typeInfo`
for error sets.
LLVM backend:
* change a TODO comment to a proper explanation of why debug info
for structs is left as a fwd decl sometimes.
* remove handling of packed unions which does not match the type
information or constant generation code.
* remove copy+pasted code
* fix union debug info not matching the memory layout
* remove unnecessary error checks and type casting
This includes various fixes/improvements to the C backend to improve
error/union support. It also fixes up our handling of decls, where some
decls were not correctly marked alive.
The existing `cmp_*` instructions get their result type from `lhs`, but
vector comparison will always return a vector of bools with only the
length derived from its operands. This necessitates the creation of a
new AIR instruction.