Prior to this change we would assume the ABI for Apple targets to
be GNU which could result in subtle errors in LLVM emitting calls
to non-existent system libc provided functions such as `_sincosf`
which is a GNU extension and as such is not provided by macOS for example.
This would result in linker errors where the linker would not be
able to find the said symbol in `libSystem.tbd`.
With this change, we now correctly identify macOS (and other Apple
platforms) as having ABI `unknown` which translates to unspecified
in LLVM under-the-hood:
```
// main.ll
target triple = "aarch64-unknown-macos-unknown"
```
Note however that we never suffix the target OS with target version
such as `macos11` or `macos12` which means we fail to instruct LLVM
of potential optimisations provided by the OS such as the availability
of function `___sincosf_stret`. I suggest we investigate that in a
follow-up commit.
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)
stage2: change logic for detecting whether the main package is inside
the std package. Previously it relied on realpath() which is not portable.
This uses resolve() which is how imports already work.
* stage2: fix cleanup bug when creating Module
* flatten lib/std/special/* to lib/*
- this was motivated by making main_pkg_is_inside_std false for
compiler_rt & friends.
* rename "mini libc" to "universal libc"
Before this change, struct {f80, f80} targeting i386-windows-msvc lowers
to
```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [6 x i8], x86_fp80, [6 x i8] }
```
which has an incorrect ABI size of 40. After this change, the struct
lowers to
```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [4 x i8], x86_fp80, [4 x i8] }
```
which has the correct ABI size of 32, and properly aligns the second
field to 16 bytes.
The other place that calculates field padding (lowering of constant
values in codegen.cpp) already correctly calls LLVMABISizeOfType
rather than LLVMStoreSizeOfType.
This fixes the compiler-rt tests for i386-windows in this branch.
These are only as accurate as f64 even for f128 comptime functions. This
is OK for now; improvements will come with the launch of self-hosted
(#89) and enhancements to compiler-rt implementations.
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.
According to Apple docs, the long double type is a double precision
IEEE754 binary floating-point type, which makes it identical to the
double type. This behavior contrasts to the standard specification,
in which a long double is a quad-precision, IEEE754 binary,
floating-point type.
Thus, we need to take this into account when using the compiler
intrinsics so that we select the correct function version for
FloatMulAdd.
* 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.
* goals
- zig as linker for object files generated by other compilers
- zig-specific runtime features for eventual standardisation
* changes
- missing routines are marked with `missing`
- structure inspired by libgcc docs, but improved order and wording
- rename misspelled functions
- reorder and rephrase compiler_rt.zig to reflect documentation
- potential decimal float or fixed-point arithmetic support:
* 'Decimal float library routines' ca. 120 functions
* 'Fixed-point fractional library routines' ca. 300 functions
thanks to @Vexu for multiple reviews and @scheibo for review
Non-Arm CPUs use u16 as the parameter to __extendhfxf2 and the return value of
__truncxfhf2, so insert appropriate bitcasts in gen_soft_f80_widen_or_shorten.
Otherwise, LLVM might crash because the functions are called in a different way
than its compiler-rt definition.
This fixes stage1 build on SPARCv9, and possibly other non-x86, non-Arm CPUs.
Comment reproduced here:
Note the following u64 alignments:
x86-linux: 4
x86-windows: 8
LLVM makes x86_fp80 have the following alignment and sizes regardless
of operating system:
x86_64: size=16, align=16
x86: size=12, align=4
However in Zig we override x86-windows to have size=16, align=16
in order for the property to hold that u80 and f80 have the same ABI size.
Fixes "error: destination type 'f80' has size 12 but source type 'u80'
has size 16" when trying to bitcast between f80 and u80 on i386-windows.
Get rid of `std.math.F80Repr`. Instead of trying to match the memory
layout of f80, we treat it as a value, same as the other floating point
types. The functions `make_f80` and `break_f80` are introduced to
compose an f80 value out of its parts, and the inverse operation.
stage2 LLVM backend: fix pointer to zero length array tripping LLVM
assertion. It now checks for when the element type is a zero-bit type
and lowers such thing the same way that pointers to other zero-bit types
are lowered.
Both stage1 and stage2 LLVM backends are adjusted so that f80 is lowered
as x86_fp80 on x86_64 and i386 architectures, and identical to a u80 on
others. LLVM constants are lowered in a less hacky way now that #10860
is fixed, by using the expression `(exp << 64) | fraction` using llvm
constants.
Sema is improved to handle c_longdouble by recursively handling it
correctly for whatever the float bit width is. In both stage1 and
stage2.
* F80Repr extern struct needs no explicit padding; let's match the
target padding.
* stage2: fix lowering of f80 constants.
* stage1: decide ABI size and alignment of f80 based on alignment of
u64. x86 has alignof u64 equal to 4 but arm has it as 8.
* stage2: fix Value.floatReadFromMemory to use F80Repr
* pass air_tag instead of zir_tag
* also pass eval function so that the branch only happens once and the
body of zirUnaryMath is simplified
* Value.sqrt: update to handle f80 and f128 in the normalized way that
includes handling c_longdouble.
Semi-related change: fix incorrect sqrt builtin name for f80 in stage1.
Currently Zig lowers `@intToFloat` for f80 incorrectly on non-x86
targets:
```
broken LLVM module found:
UIToFP result must be FP or FP vector
%62 = uitofp i64 %61 to i128
SIToFP result must be FP or FP vector
%66 = sitofp i64 %65 to i128
```
This happens because on such targets, we use i128 instead of x86_fp80 in
order to avoid "LLVM ERROR: Cannot select". `@intToFloat` must be
lowered differently to account for this difference as well.
These options were removed in 5e63baae8 (CLI: remove --verbose-ast and
--verbose-tokenize, 2021-06-09) but some remainders were left in.
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>