aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-09-11 17:41:55 -0700
committerGitHub <noreply@github.com>2024-09-11 17:41:55 -0700
commit4fba7336a9038b4abf647caf822f89df717d3cc0 (patch)
treed2a5e61671fefce3ba53454b46311ba77dc31b7a /src/codegen
parent218cf059dd215282aa96d6b4715e68d533a4238e (diff)
parentf1645772c1881a233ffcfc5072710040c4881deb (diff)
downloadzig-4fba7336a9038b4abf647caf822f89df717d3cc0.tar.gz
zig-4fba7336a9038b4abf647caf822f89df717d3cc0.zip
Merge pull request #21269 from alexrp/soft-float
Fix soft float support, split musl triples by float ABI, and enable CI
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index c8eb37b30a..956ed7de08 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1285,8 +1285,7 @@ pub const Object = struct {
.large => .Large,
};
- // TODO handle float ABI better- it should depend on the ABI portion of std.Target
- const float_abi: llvm.ABIType = .Default;
+ const float_abi: llvm.ABIType = if (comp.root_mod.resolved_target.result.floatAbi() == .hard) .Hard else .Soft;
var target_machine = llvm.TargetMachine.create(
target,
@@ -3110,6 +3109,30 @@ pub const Object = struct {
.value = .empty,
} }, &o.builder);
}
+ if (target.floatAbi() == .soft) {
+ // `use-soft-float` means "use software routines for floating point computations". In
+ // other words, it configures how LLVM lowers basic float instructions like `fcmp`,
+ // `fadd`, etc. The float calling convention is configured on `TargetMachine` and is
+ // mostly an orthogonal concept, although obviously we do need hardware float operations
+ // to actually be able to pass float values in float registers.
+ //
+ // Ideally, we would support something akin to the `-mfloat-abi=softfp` option that GCC
+ // and Clang support for Arm32 and CSKY. We don't currently expose such an option in
+ // Zig, and using CPU features as the source of truth for this makes for a miserable
+ // user experience since people expect e.g. `arm-linux-gnueabi` to mean full soft float
+ // unless the compiler has explicitly been told otherwise. (And note that our baseline
+ // CPU models almost all include FPU features!)
+ //
+ // Revisit this at some point.
+ try attributes.addFnAttr(.{ .string = .{
+ .kind = try o.builder.string("use-soft-float"),
+ .value = try o.builder.string("true"),
+ } }, &o.builder);
+
+ // This prevents LLVM from using FPU/SIMD code for things like `memcpy`. As for the
+ // above, this should be revisited if `softfp` support is added.
+ try attributes.addFnAttr(.noimplicitfloat, &o.builder);
+ }
}
fn resolveGlobalUav(
@@ -12423,6 +12446,11 @@ fn backendSupportsF16(target: std.Target) bool {
.riscv32,
.s390x,
=> false,
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ => target.floatAbi() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
.aarch64,
.aarch64_be,
=> std.Target.aarch64.featureSetHas(target.cpu.features, .fp_armv8),
@@ -12445,6 +12473,11 @@ fn backendSupportsF128(target: std.Target) bool {
.powerpc64,
.powerpc64le,
=> target.os.tag != .aix,
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ => target.floatAbi() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
.aarch64,
.aarch64_be,
=> std.Target.aarch64.featureSetHas(target.cpu.features, .fp_armv8),