From ff38f560402aa61ce8e4ae38b4fa0ff2ddbaede6 Mon Sep 17 00:00:00 2001 From: vole-dev Date: Sat, 30 Oct 2021 10:30:28 -0500 Subject: default mabi based on RISC-V extensions and -mabi build option The target abi can also be set in build.zig via LibExeObjStep.target_abi The value passed in is checked that it is a valid value in std.Target.TargetAbi The target abi is also validated against the target cpu --- lib/std/build.zig | 4 +++ lib/std/target.zig | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'lib') diff --git a/lib/std/build.zig b/lib/std/build.zig index 30296081b7..cd551924a9 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1474,6 +1474,7 @@ pub const LibExeObjStep = struct { name_prefix: []const u8, filter: ?[]const u8, test_evented_io: bool = false, + target_abi: ?std.Target.TargetAbi = null, code_model: std.builtin.CodeModel = .default, wasi_exec_model: ?std.builtin.WasiExecModel = null, @@ -2458,6 +2459,9 @@ pub const LibExeObjStep = struct { try zig_args.append(builder.fmt("--global-base={d}", .{global_base})); } + if (self.target_abi) |target_abi| { + try zig_args.append(builder.fmt("-mabi={s}", .{@tagName(target_abi)})); + } if (self.code_model != .default) { try zig_args.append("-mcmodel"); try zig_args.append(@tagName(self.code_model)); diff --git a/lib/std/target.zig b/lib/std/target.zig index c6ee53157d..43cd80bb3b 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -560,6 +560,84 @@ pub const Target = struct { } }; + /// processor specific ABI + pub const TargetAbi = enum { + //TODO add ARM, Mips, and PowerPC + ilp32, + ilp32d, + ilp32e, + ilp32f, + lp64, + lp64d, + lp64f, + + const Riscv32ABI = struct { + fn default(features: Cpu.Feature.Set) TargetAbi { + if (riscv.featureSetHas(features, .d)) { + return .ilp32d; + } else if (riscv.featureSetHas(features, .e)) { + return .ilp32e; + } else { + return .ilp32; + } + } + fn validate(target_abi: TargetAbi, features: Cpu.Feature.Set) ParseError!void { + const has_e = riscv.featureSetHas(features, .e); + const has_f = riscv.featureSetHas(features, .f); + const has_d = riscv.featureSetHas(features, .d); + return switch (target_abi) { + .ilp32e => if (has_e) {} else error.FeatureAbiMismatch, + .ilp32 => if (!has_e) {} else error.FeatureAbiMismatch, + .ilp32f => if (!has_e and has_f) {} else error.FeatureAbiMismatch, + .ilp32d => if (!has_e and has_d) {} else error.FeatureAbiMismatch, + else => error.ArchAbiMismatch, + }; + } + }; + const Riscv64ABI = struct { + fn default(features: Cpu.Feature.Set) TargetAbi { + if (riscv.featureSetHas(features, .d)) { + return .lp64d; + } else { + return .lp64; + } + } + fn validate(target_abi: TargetAbi, features: Cpu.Feature.Set) ParseError!void { + const has_f = riscv.featureSetHas(features, .f); + const has_d = riscv.featureSetHas(features, .d); + return switch (target_abi) { + .lp64 => {}, + .lp64f => if (has_f) {} else error.FeatureAbiMismatch, + .lp64d => if (has_d) {} else error.FeatureAbiMismatch, + else => error.ArchAbiMismatch, + }; + } + }; + pub fn default(arch: Cpu.Arch, features: Cpu.Feature.Set) ?TargetAbi { + return switch (arch) { + .riscv32 => Riscv32ABI.default(features), + .riscv64 => Riscv64ABI.default(features), + else => null, + }; + } + + pub const ParseError = error{ + InvalidAbi, + ArchAbiMismatch, + FeatureAbiMismatch, + }; + pub fn parse(cpu: Cpu, abi_string: []const u8) ParseError!TargetAbi { + const target_abi = std.meta.stringToEnum(TargetAbi, abi_string) orelse return error.InvalidAbi; + + switch (cpu.arch) { + .riscv32 => try Riscv32ABI.validate(target_abi, cpu.features), + .riscv64 => try Riscv64ABI.validate(target_abi, cpu.features), + else => return error.ArchAbiMismatch, + } + return target_abi; + } + }; + pub const ObjectFormat = enum { /// Common Object File Format (Windows) coff, -- cgit v1.2.3