Skip to content

Commit

Permalink
std.Target: Add FloatAbi.hard32 and isSoft()/isHard() functions.
Browse files Browse the repository at this point in the history
We need the extra ABI to represent the 3 float ABIs on RISC-V and LoongArch:

* ilp32/lp64 (soft float)
* ilp32f/lp64f (hard float for f32)
* ilp32d/lp64d (hard float for f32 and f64)
  • Loading branch information
alexrp committed Jun 23, 2024
1 parent 2876513 commit 48a34d5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
12 changes: 5 additions & 7 deletions lib/compiler_rt/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,11 @@ pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?
/// here in compiler-rt.
pub fn F16T(comptime OtherType: type) type {
return switch (builtin.cpu.arch) {
.arm, .armeb, .thumb, .thumbeb => if (std.Target.arm.featureSetHas(builtin.cpu.features, .has_v8))
switch (builtin.abi.floatAbi()) {
.soft => u16,
.hard => f16,
}
else
u16,
.arm,
.armeb,
.thumb,
.thumbeb,
=> if (std.Target.arm.featureSetHas(builtin.cpu.features, .has_v8) and builtin.abi.isHardFloat()) f16 else u16,
.aarch64, .aarch64_be, .aarch64_32 => f16,
.riscv64 => if (builtin.zig_backend == .stage1) u16 else f16,
.x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) {
Expand Down
45 changes: 38 additions & 7 deletions lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,14 @@ pub const Abi = enum {
else => .soft,
};
}

pub inline fn isSoftFloat(abi: Abi) bool {
return abi.floatAbi().isSoft();
}

pub inline fn isHardFloat(abi: Abi) bool {
return abi.floatAbi().isHard();
}
};

pub const ObjectFormat = enum {
Expand Down Expand Up @@ -1645,15 +1653,41 @@ pub inline fn isSpirV(target: Target) bool {
return target.cpu.arch.isSpirV();
}

/// Most architectures only make the distinction between soft float and hard float, and assume that
/// hard float implies that both `f32` and `f64` have hardware support, while soft float implies
/// that both are emulated. We use `.soft` and `.hard` for these cases.
///
/// Some architectures, however, have three floating point ABIs: Soft float, hard float for just
/// `f32`, and hard float for both `f32` and `f64`. Here, hard float for both is usually the norm,
/// with hard float for just `f32` being more common in embedded scenarios. This is the case for
/// RISC-V and LoongArch, for example. We use `.hard32` to refer to the case where only `f32` has
/// hardware support.
pub const FloatAbi = enum {
hard,
soft,
hard,
hard32,

pub inline fn isSoft(abi: FloatAbi) bool {
return abi == .soft;
}

pub inline fn isHard(abi: FloatAbi) bool {
return !abi.isSoft();
}
};

pub inline fn getFloatAbi(target: Target) FloatAbi {
pub inline fn floatAbi(target: Target) FloatAbi {
return target.abi.floatAbi();
}

pub inline fn isSoftFloat(target: Target) bool {
return target.floatAbi().isSoft();
}

pub inline fn isHardFloat(target: Target) bool {
return target.floatAbi().isHard();
}

pub inline fn hasDynamicLinker(target: Target) bool {
if (target.cpu.arch.isWasm()) {
return false;
Expand Down Expand Up @@ -1733,7 +1767,7 @@ pub const DynamicLinker = struct {
.thumbeb => .armeb,
else => cpu.arch,
}),
if (cpu.arch.isArmOrThumb() and abi.floatAbi() == .hard) "hf" else "",
if (cpu.arch.isArmOrThumb() and abi.isHardFloat()) "hf" else "",
}) catch unreachable else switch (os_tag) {
.freebsd => init("/libexec/ld-elf.so.1"),
.netbsd => init("/libexec/ld.elf_so"),
Expand All @@ -1754,10 +1788,7 @@ pub const DynamicLinker = struct {
.armeb,
.thumb,
.thumbeb,
=> initFmt("/lib/ld-linux{s}.so.3", .{switch (abi.floatAbi()) {
.hard => "-armhf",
else => "",
}}) catch unreachable,
=> initFmt("/lib/ld-linux{s}.so.3", .{if (abi.isHardFloat()) "-armhf" else ""}) catch unreachable,

.mips,
.mipsel,
Expand Down
2 changes: 1 addition & 1 deletion src/libunwind.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
if (!comp.config.any_non_single_threaded) {
try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS");
}
if (target.cpu.arch.isARM() and target.abi.floatAbi() == .hard) {
if (target.cpu.arch.isARM() and target.isHardFloat()) {
try cflags.append("-DCOMPILER_RT_ARMHF_TARGET");
}
try cflags.append("-Wno-bitwise-conditional-parentheses");
Expand Down

0 comments on commit 48a34d5

Please sign in to comment.