Merge pull request #22589 from alexrp/target-changes

Some miscellaneous target and calling convention changes
This commit is contained in:
Alex Rønne Petersen 2025-02-18 00:51:59 +01:00 committed by GitHub
commit b732070fd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
68 changed files with 768 additions and 751 deletions

View File

@ -742,7 +742,7 @@ fn addCmakeCfgOptionsToExe(
const mod = exe.root_module;
const target = mod.resolved_target.?.result;
if (target.isDarwin()) {
if (target.os.tag.isDarwin()) {
// useful for package maintainers
exe.headerpad_max_install_names = true;
}

View File

@ -308,7 +308,7 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
),
else => {},
}
if (comp.target.isAndroid()) {
if (comp.target.abi.isAndroid()) {
try w.writeAll("#define __ANDROID__ 1\n");
}
@ -734,7 +734,7 @@ pub fn float80Type(comp: *const Compilation) ?Type {
/// Smallest integer type with at least N bits
pub fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type {
if (bits == 64 and (comp.target.isDarwin() or comp.target.isWasm())) {
if (bits == 64 and (comp.target.os.tag.isDarwin() or comp.target.cpu.arch.isWasm())) {
// WebAssembly and Darwin use `long long` for `int_least64_t` and `int_fast64_t`.
return .{ .specifier = if (signedness == .signed) .long_long else .ulong_long };
}

View File

@ -183,7 +183,7 @@ fn collectLibDirsAndTriples(
// TODO
return;
}
if (target.isAndroid()) {
if (target.abi.isAndroid()) {
const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"};
const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"};
const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"};

View File

@ -161,7 +161,7 @@ pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
} else {
var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
defer linker_name.deinit();
if (tc.getTarget().isDarwin()) {
if (tc.getTarget().os.tag.isDarwin()) {
linker_name.appendSliceAssumeCapacity("ld64.");
} else {
linker_name.appendSliceAssumeCapacity("ld.");
@ -343,7 +343,7 @@ pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void {
}
fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
if (tc.getTarget().isAndroid()) {
if (tc.getTarget().abi.isAndroid()) {
return .compiler_rt;
}
return .libgcc;
@ -369,7 +369,7 @@ pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: Fil
fn getLibGCCKind(tc: *const Toolchain) LibGCCKind {
const target = tc.getTarget();
if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.isAndroid()) {
if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.abi.isAndroid()) {
return .static;
}
if (tc.driver.shared_libgcc) {
@ -384,7 +384,7 @@ fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
switch (tc.getRuntimeLibKind()) {
.compiler_rt => {
const target = tc.getTarget();
if (target.isAndroid() or target.os.tag == .aix) {
if (target.abi.isAndroid() or target.os.tag == .aix) {
return .compiler_rt;
} else {
return .none;
@ -417,14 +417,14 @@ fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
const unw = try tc.getUnwindLibKind();
const target = tc.getTarget();
if ((target.isAndroid() and unw == .libgcc) or
if ((target.abi.isAndroid() and unw == .libgcc) or
target.os.tag == .elfiamcu or
target.ofmt == .wasm or
target_util.isWindowsMSVCEnvironment(target) or
unw == .none) return;
const lgk = tc.getLibGCCKind();
const as_needed = lgk == .unspecified and !target.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
if (as_needed) {
try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
}
@ -483,7 +483,7 @@ pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !v
},
}
if (target.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
if (target.abi.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
try argv.append("-ldl");
}
}

View File

@ -1102,7 +1102,7 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
.double => comp.target.cTypeAlignment(.double),
.long_double => comp.target.cTypeAlignment(.longdouble),
.int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.isGnu()) 8 else 16,
.int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.abi.isGnu()) 8 else 16,
.fp16, .float16 => 2,
.float128 => 16,

View File

@ -117,8 +117,8 @@ pub fn int64Type(target: std.Target) Type {
.sparc64 => return intMaxType(target),
.x86, .x86_64 => if (!target.isDarwin()) return intMaxType(target),
.aarch64, .aarch64_be => if (!target.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
.x86, .x86_64 => if (!target.os.tag.isDarwin()) return intMaxType(target),
.aarch64, .aarch64_be => if (!target.os.tag.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
else => {},
}
return .{ .specifier = .long_long };
@ -144,7 +144,7 @@ pub fn defaultFunctionAlignment(target: std.Target) u8 {
}
pub fn isTlsSupported(target: std.Target) bool {
if (target.isDarwin()) {
if (target.os.tag.isDarwin()) {
var supported = false;
switch (target.os.tag) {
.macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false),
@ -199,7 +199,7 @@ pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
switch (target.cpu.arch) {
.aarch64 => {
if (target.isDarwin() or target.os.tag == .windows) return false;
if (target.os.tag.isDarwin() or target.os.tag == .windows) return false;
return true;
},
.armeb => {
@ -229,7 +229,7 @@ pub fn packAllEnums(target: std.Target) bool {
pub fn defaultAlignment(target: std.Target) u29 {
switch (target.cpu.arch) {
.avr => return 1,
.arm => if (target.isAndroid() or target.os.tag == .ios) return 16 else return 8,
.arm => if (target.abi.isAndroid() or target.os.tag == .ios) return 16 else return 8,
.sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
.mips, .mipsel => switch (target.abi) {
.none, .gnuabi64 => return 16,
@ -242,9 +242,8 @@ pub fn defaultAlignment(target: std.Target) u29 {
pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
// Android is linux but not gcc, so these checks go first
// the rest for documentation as fn returns .clang
if (target.isDarwin() or
target.isAndroid() or
target.isBSD() or
if (target.abi.isAndroid() or
target.os.tag.isBSD() or
target.os.tag == .fuchsia or
target.os.tag == .solaris or
target.os.tag == .haiku or
@ -268,7 +267,7 @@ pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
pub fn hasFloat128(target: std.Target) bool {
if (target.cpu.arch.isWasm()) return true;
if (target.isDarwin()) return false;
if (target.os.tag.isDarwin()) return false;
if (target.cpu.arch.isPowerPC()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128);
return switch (target.os.tag) {
.dragonfly,
@ -461,7 +460,6 @@ pub fn get32BitArchVariant(target: std.Target) ?std.Target {
.amdgcn,
.avr,
.msp430,
.spu_2,
.ve,
.bpfel,
.bpfeb,
@ -522,7 +520,6 @@ pub fn get64BitArchVariant(target: std.Target) ?std.Target {
.lanai,
.m68k,
.msp430,
.spu_2,
.xcore,
.xtensa,
=> return null,
@ -620,8 +617,6 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
.wasm32 => "wasm32",
.wasm64 => "wasm64",
.ve => "ve",
// Note: spu_2 is not supported in LLVM; this is the Zig arch name
.spu_2 => "spu_2",
};
writer.writeAll(llvm_arch) catch unreachable;
writer.writeByte('-') catch unreachable;

View File

@ -27,7 +27,7 @@ pub fn discover(self: *Linux, tc: *Toolchain) !void {
fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void {
const gpa = tc.driver.comp.gpa;
const target = tc.getTarget();
const is_android = target.isAndroid();
const is_android = target.abi.isAndroid();
if (self.distro.isAlpine() or is_android) {
try self.extra_opts.ensureUnusedCapacity(gpa, 2);
self.extra_opts.appendAssumeCapacity("-z");
@ -113,7 +113,7 @@ fn findPaths(self: *Linux, tc: *Toolchain) !void {
try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file);
try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file);
if (target.isAndroid()) {
if (target.abi.isAndroid()) {
// TODO
}
try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file);
@ -156,7 +156,7 @@ fn getStatic(self: *const Linux, d: *const Driver) bool {
pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 {
_ = self;
if (target.isAndroid()) {
if (target.abi.isAndroid()) {
return "ld.lld";
}
return "ld";
@ -169,7 +169,7 @@ pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.Arra
const is_pie = self.getPIE(d);
const is_static_pie = try self.getStaticPIE(d);
const is_static = self.getStatic(d);
const is_android = target.isAndroid();
const is_android = target.abi.isAndroid();
const is_iamcu = target.os.tag == .elfiamcu;
const is_ve = target.cpu.arch == .ve;
const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor
@ -326,7 +326,7 @@ pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.Arra
}
fn getMultiarchTriple(target: std.Target) ?[]const u8 {
const is_android = target.isAndroid();
const is_android = target.abi.isAndroid();
const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
return switch (target.cpu.arch) {
.arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
@ -380,7 +380,7 @@ pub fn defineSystemIncludes(self: *const Linux, tc: *const Toolchain) !void {
// musl prefers /usr/include before builtin includes, so musl targets will add builtins
// at the end of this function (unless disabled with nostdlibinc)
if (!tc.driver.nobuiltininc and (!target.isMusl() or tc.driver.nostdlibinc)) {
if (!tc.driver.nobuiltininc and (!target.abi.isMusl() or tc.driver.nostdlibinc)) {
try comp.addBuiltinIncludeDir(tc.driver.aro_name);
}
@ -411,7 +411,7 @@ pub fn defineSystemIncludes(self: *const Linux, tc: *const Toolchain) !void {
try comp.addSystemIncludeDir("/usr/include");
std.debug.assert(!tc.driver.nostdlibinc);
if (!tc.driver.nobuiltininc and target.isMusl()) {
if (!tc.driver.nobuiltininc and target.abi.isMusl()) {
try comp.addBuiltinIncludeDir(tc.driver.aro_name);
}
}

View File

@ -14,7 +14,7 @@ else
/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
/// export it to the host runtime.
pub const visibility: std.builtin.SymbolVisibility =
if (builtin.target.isWasm() and linkage != .internal) .hidden else .default;
if (builtin.target.cpu.arch.isWasm() and linkage != .internal) .hidden else .default;
pub const want_aeabi = switch (builtin.abi) {
.eabi,
@ -92,7 +92,7 @@ pub const panic = if (builtin.is_test) std.debug.FullPanic(std.debug.defaultPani
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()) {
switch (builtin.abi.float()) {
.soft => u16,
.hard => f16,
}
@ -100,7 +100,7 @@ pub fn F16T(comptime OtherType: type) type {
u16,
.aarch64, .aarch64_be => f16,
.riscv32, .riscv64 => f16,
.x86, .x86_64 => if (builtin.target.isDarwin()) switch (OtherType) {
.x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) {
// Starting with LLVM 16, Darwin uses different abi for f16
// depending on the type of the other return/argument..???
f32, f64 => u16,

View File

@ -465,7 +465,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
if (compile.linkage != null and compile.linkage.? == .static) {
compile.out_lib_filename = compile.out_filename;
} else if (compile.version) |version| {
if (target.isDarwin()) {
if (target.os.tag.isDarwin()) {
compile.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
compile.name,
version.major,
@ -480,7 +480,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
compile.out_lib_filename = compile.out_filename;
}
} else {
if (target.isDarwin()) {
if (target.os.tag.isDarwin()) {
compile.out_lib_filename = compile.out_filename;
} else if (target.os.tag == .windows) {
compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
@ -1524,7 +1524,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
try zig_args.append(b.fmt("{}", .{version}));
}
if (compile.rootModuleTarget().isDarwin()) {
if (compile.rootModuleTarget().os.tag.isDarwin()) {
const install_name = compile.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{
compile.rootModuleTarget().libPrefix(),
compile.name,

View File

@ -144,10 +144,6 @@ pub const Os = struct {
};
}
pub inline fn isGnuLibC(tag: Os.Tag, abi: Abi) bool {
return (tag == .hurd or tag == .linux) and abi.isGnu();
}
pub fn defaultVersionRange(tag: Tag, arch: Cpu.Arch, abi: Abi) Os {
return .{
.tag = tag,
@ -218,23 +214,6 @@ pub const Os = struct {
.windows => .windows,
};
}
pub fn archName(tag: Tag, arch: Cpu.Arch) [:0]const u8 {
return switch (tag) {
.linux => switch (arch) {
.arm, .armeb, .thumb, .thumbeb => "arm",
.aarch64, .aarch64_be => "aarch64",
.loongarch32, .loongarch64 => "loongarch",
.mips, .mipsel, .mips64, .mips64el => "mips",
.powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
.riscv32, .riscv64 => "riscv",
.sparc, .sparc64 => "sparc",
.x86, .x86_64 => "x86",
else => @tagName(arch),
},
else => @tagName(arch),
};
}
};
/// Based on NTDDI version constants from
@ -763,6 +742,7 @@ pub const mips = @import("Target/mips.zig");
pub const msp430 = @import("Target/msp430.zig");
pub const nvptx = @import("Target/nvptx.zig");
pub const powerpc = @import("Target/powerpc.zig");
pub const propeller = @import("Target/propeller.zig");
pub const riscv = @import("Target/riscv.zig");
pub const sparc = @import("Target/sparc.zig");
pub const spirv = @import("Target/spirv.zig");
@ -772,7 +752,6 @@ pub const wasm = @import("Target/wasm.zig");
pub const x86 = @import("Target/x86.zig");
pub const xcore = @import("Target/xcore.zig");
pub const xtensa = @import("Target/xtensa.zig");
pub const propeller = @import("Target/propeller.zig");
pub const Abi = enum {
none,
@ -990,7 +969,12 @@ pub const Abi = enum {
};
}
pub inline fn floatAbi(abi: Abi) FloatAbi {
pub const Float = enum {
hard,
soft,
};
pub inline fn float(abi: Abi) Float {
return switch (abi) {
.androideabi,
.eabi,
@ -1081,20 +1065,17 @@ pub fn toElfMachine(target: Target) std.elf.EM {
.msp430 => .MSP430,
.powerpc, .powerpcle => .PPC,
.powerpc64, .powerpc64le => .PPC64,
.propeller => .PROPELLER,
.riscv32, .riscv64 => .RISCV,
.s390x => .S390,
.sparc => if (Target.sparc.featureSetHas(target.cpu.features, .v9)) .SPARC32PLUS else .SPARC,
.sparc64 => .SPARCV9,
.spu_2 => .SPU_2,
.ve => .VE,
.x86 => if (target.os.tag == .elfiamcu) .IAMCU else .@"386",
.x86_64 => .X86_64,
.xcore => .XCORE,
.xtensa => .XTENSA,
.propeller1 => .PROPELLER,
.propeller2 => .PROPELLER2,
.nvptx,
.nvptx64,
.spirv,
@ -1148,14 +1129,12 @@ pub fn toCoffMachine(target: Target) std.coff.MachineType {
.spirv,
.spirv32,
.spirv64,
.spu_2,
.ve,
.wasm32,
.wasm64,
.xcore,
.xtensa,
.propeller1,
.propeller2,
.propeller,
=> .UNKNOWN,
};
}
@ -1368,8 +1347,7 @@ pub const Cpu = struct {
powerpcle,
powerpc64,
powerpc64le,
propeller1,
propeller2,
propeller,
riscv32,
riscv64,
s390x,
@ -1378,7 +1356,6 @@ pub const Cpu = struct {
spirv,
spirv32,
spirv64,
spu_2,
ve,
wasm32,
wasm64,
@ -1520,14 +1497,6 @@ pub const Cpu = struct {
};
}
/// Returns if the architecture is a Parallax propeller architecture.
pub inline fn isPropeller(arch: Arch) bool {
return switch (arch) {
.propeller1, .propeller2 => true,
else => false,
};
}
pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
for (arch.allCpuModels()) |cpu| {
if (std.mem.eql(u8, cpu_name, cpu.name)) {
@ -1564,7 +1533,6 @@ pub const Cpu = struct {
.xcore,
.thumb,
.ve,
.spu_2,
// GPU bitness is opaque. For now, assume little endian.
.spirv,
.spirv32,
@ -1572,8 +1540,7 @@ pub const Cpu = struct {
.loongarch32,
.loongarch64,
.arc,
.propeller1,
.propeller2,
.propeller,
=> .little,
.armeb,
@ -1593,26 +1560,6 @@ pub const Cpu = struct {
};
}
/// Returns whether this architecture supports the address space
pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
const is_nvptx = arch.isNvptx();
const is_spirv = arch.isSpirV();
const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
return switch (address_space) {
.generic => true,
.fs, .gs, .ss => arch == .x86_64 or arch == .x86,
.global, .constant, .local, .shared => is_gpu,
.param => is_nvptx,
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
// TODO this should also check how many flash banks the cpu has
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
// Propeller address spaces:
.cog, .hub => arch.isPropeller(),
.lut => (arch == .propeller2),
};
}
/// Returns a name that matches the lib/std/target/* source file name.
pub fn genericName(arch: Arch) [:0]const u8 {
return switch (arch) {
@ -1622,6 +1569,7 @@ pub const Cpu = struct {
.loongarch32, .loongarch64 => "loongarch",
.mips, .mipsel, .mips64, .mips64el => "mips",
.powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
.propeller => "propeller",
.riscv32, .riscv64 => "riscv",
.sparc, .sparc64 => "sparc",
.s390x => "s390x",
@ -1629,7 +1577,6 @@ pub const Cpu = struct {
.nvptx, .nvptx64 => "nvptx",
.wasm32, .wasm64 => "wasm",
.spirv, .spirv32, .spirv64 => "spirv",
.propeller1, .propeller2 => "propeller",
else => @tagName(arch),
};
}
@ -1770,10 +1717,8 @@ pub const Cpu = struct {
.aarch64_vfabi_sve,
=> &.{ .aarch64, .aarch64_be },
.arm_apcs,
.arm_aapcs,
.arm_aapcs_vfp,
.arm_aapcs16_vfp,
.arm_interrupt,
=> &.{ .arm, .armeb, .thumb, .thumbeb },
@ -1813,7 +1758,7 @@ pub const Cpu = struct {
.powerpc_aix_altivec,
=> &.{ .powerpc, .powerpcle },
.wasm_watc,
.wasm_mvp,
=> &.{ .wasm64, .wasm32 },
.arc_sysv,
@ -1854,11 +1799,8 @@ pub const Cpu = struct {
.msp430_eabi,
=> &.{.msp430},
.propeller1_sysv,
=> &.{.propeller1},
.propeller2_sysv,
=> &.{.propeller2},
.propeller_sysv,
=> &.{.propeller},
.s390x_sysv,
.s390x_sysv_vx,
@ -1937,8 +1879,7 @@ pub const Cpu = struct {
.msp430 => &msp430.cpu.generic,
.powerpc, .powerpcle => &powerpc.cpu.ppc,
.powerpc64, .powerpc64le => &powerpc.cpu.ppc64,
.propeller1 => &propeller.cpu.generic,
.propeller2 => &propeller.cpu.generic,
.propeller => &propeller.cpu.p1,
.riscv32 => &riscv.cpu.generic_rv32,
.riscv64 => &riscv.cpu.generic_rv64,
.spirv, .spirv32, .spirv64 => &spirv.cpu.generic,
@ -1954,7 +1895,6 @@ pub const Cpu = struct {
.xtensa => &xtensa.cpu.generic,
.kalimba,
.spu_2,
=> &S.generic_model,
};
}
@ -2015,6 +1955,35 @@ pub const Cpu = struct {
pub fn baseline(arch: Arch, os: Os) Cpu {
return Model.baseline(arch, os).toCpu(arch);
}
/// Returns whether this architecture supports `address_space`. If `context` is `null`, this
/// function simply answers the general question of whether the architecture has any concept
/// of `address_space`; if non-`null`, the function additionally checks whether
/// `address_space` is valid in that context.
pub fn supportsAddressSpace(
cpu: Cpu,
address_space: std.builtin.AddressSpace,
context: ?std.builtin.AddressSpace.Context,
) bool {
const arch = cpu.arch;
const is_nvptx = arch.isNvptx();
const is_spirv = arch.isSpirV();
const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
return switch (address_space) {
.generic => true,
.fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, // TODO this should also check how many flash banks the cpu has
.cog, .hub => arch == .propeller,
.lut => arch == .propeller and std.Target.propeller.featureSetHas(cpu.features, .p2),
.global, .local, .shared => is_gpu,
.constant => is_gpu and (context == null or context == .constant),
.param => is_nvptx,
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
};
}
};
pub fn zigTriple(target: Target, allocator: Allocator) Allocator.Error![]u8 {
@ -2054,48 +2023,29 @@ pub fn libPrefix(target: Target) [:0]const u8 {
}
pub inline fn isMinGW(target: Target) bool {
return target.os.tag == .windows and target.isGnu();
}
pub inline fn isGnu(target: Target) bool {
return target.abi.isGnu();
}
pub inline fn isMusl(target: Target) bool {
return target.abi.isMusl();
}
pub inline fn isAndroid(target: Target) bool {
return target.abi.isAndroid();
}
pub inline fn isWasm(target: Target) bool {
return target.cpu.arch.isWasm();
}
pub inline fn isDarwin(target: Target) bool {
return target.os.tag.isDarwin();
}
pub inline fn isBSD(target: Target) bool {
return target.os.tag.isBSD();
return target.os.tag == .windows and target.abi.isGnu();
}
pub inline fn isGnuLibC(target: Target) bool {
return target.os.tag.isGnuLibC(target.abi);
return switch (target.os.tag) {
.hurd, .linux => target.abi.isGnu(),
else => false,
};
}
pub inline fn isSpirV(target: Target) bool {
return target.cpu.arch.isSpirV();
pub inline fn isMuslLibC(target: Target) bool {
return target.os.tag == .linux and target.abi.isMusl();
}
pub const FloatAbi = enum {
hard,
soft,
};
pub inline fn isDarwinLibC(target: Target) bool {
return switch (target.abi) {
.none, .macabi, .simulator => target.os.tag.isDarwin(),
else => false,
};
}
pub inline fn floatAbi(target: Target) FloatAbi {
return target.abi.floatAbi();
pub inline fn isWasiLibC(target: Target) bool {
return target.os.tag == .wasi and target.abi.isMusl();
}
pub const DynamicLinker = struct {
@ -2627,7 +2577,6 @@ pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 {
return switch (cpu.arch) {
.avr,
.msp430,
.spu_2,
=> 16,
.arc,
@ -2653,8 +2602,7 @@ pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 {
.spirv32,
.loongarch32,
.xtensa,
.propeller1,
.propeller2,
.propeller,
=> 32,
.aarch64,
@ -2733,7 +2681,7 @@ pub fn stackAlignment(target: Target) u16 {
/// Note that char signedness is implementation-defined and many compilers provide
/// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char
pub fn charSignedness(target: Target) std.builtin.Signedness {
if (target.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed;
if (target.os.tag.isDarwin() or target.os.tag == .windows or target.os.tag == .uefi) return .signed;
return switch (target.cpu.arch) {
.arm,
@ -3164,10 +3112,8 @@ pub fn cTypeAlignment(target: Target, c_type: CType) u16 {
.x86,
.xcore,
.kalimba,
.spu_2,
.xtensa,
.propeller1,
.propeller2,
.propeller,
=> 4,
.arm,
@ -3260,10 +3206,8 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 {
.csky,
.xcore,
.kalimba,
.spu_2,
.xtensa,
.propeller1,
.propeller2,
.propeller,
=> 4,
.arc,
@ -3330,7 +3274,7 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
.windows => .{ .aarch64_aapcs_win = .{} },
else => .{ .aarch64_aapcs = .{} },
},
.arm, .armeb, .thumb, .thumbeb => switch (target.abi.floatAbi()) {
.arm, .armeb, .thumb, .thumbeb => switch (target.abi.float()) {
.soft => .{ .arm_aapcs = .{} },
.hard => .{ .arm_aapcs_vfp = .{} },
},
@ -3343,7 +3287,7 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
.riscv32 => .{ .riscv32_ilp32 = .{} },
.sparc64 => .{ .sparc64_sysv = .{} },
.sparc => .{ .sparc_sysv = .{} },
.powerpc64 => if (target.isMusl())
.powerpc64 => if (target.abi.isMusl())
.{ .powerpc64_elf_v2 = .{} }
else
.{ .powerpc64_elf = .{} },
@ -3352,8 +3296,7 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
.aix => .{ .powerpc_aix = .{} },
else => .{ .powerpc_sysv = .{} },
},
.wasm32 => .{ .wasm_watc = .{} },
.wasm64 => .{ .wasm_watc = .{} },
.wasm32, .wasm64 => .{ .wasm_mvp = .{} },
.arc => .{ .arc_sysv = .{} },
.avr => .avr_gnu,
.bpfel, .bpfeb => .{ .bpf_std = .{} },
@ -3368,10 +3311,8 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
else
.{ .m68k_sysv = .{} },
.msp430 => .{ .msp430_eabi = .{} },
.propeller1 => .{ .propeller1_sysv = .{} },
.propeller2 => .{ .propeller2_sysv = .{} },
.propeller => .{ .propeller_sysv = .{} },
.s390x => .{ .s390x_sysv = .{} },
.spu_2 => null,
.ve => .{ .ve_sysv = .{} },
.xcore => .{ .xcore_xs1 = .{} },
.xtensa => .{ .xtensa_call0 = .{} },
@ -3381,10 +3322,6 @@ pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
};
}
pub fn osArchName(target: std.Target) [:0]const u8 {
return target.os.tag.archName(target.cpu.arch);
}
const Target = @This();
const std = @import("std.zig");
const builtin = @import("builtin");

View File

@ -26,7 +26,7 @@ os_version_min: ?OsVersion = null,
os_version_max: ?OsVersion = null,
/// `null` means default when cross compiling, or native when `os_tag` is native.
/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
/// If `isGnu()` is `false`, this must be `null` and is ignored.
glibc_version: ?SemanticVersion = null,
/// `null` means default when cross compiling, or native when `os_tag` is native.
@ -235,8 +235,7 @@ pub fn parse(args: ParseOptions) !Query {
const abi_ver_text = abi_it.rest();
if (abi_it.next() != null) {
const tag = result.os_tag orelse builtin.os.tag;
if (tag.isGnuLibC(abi)) {
if (abi.isGnu()) {
result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
error.Overflow => return error.InvalidAbiVersion,
error.InvalidVersion => return error.InvalidAbiVersion,

View File

@ -1,20 +1,46 @@
//! This file is auto-generated by tools/update_cpu_features.zig.
const std = @import("../std.zig");
const CpuFeature = std.Target.Cpu.Feature;
const CpuModel = std.Target.Cpu.Model;
pub const Feature = enum {};
pub const Feature = enum {
p2,
};
pub const featureSet = CpuFeature.FeatureSetFns(Feature).featureSet;
pub const featureSetHas = CpuFeature.FeatureSetFns(Feature).featureSetHas;
pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny;
pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll;
pub const all_features: [0]CpuFeature = .{};
pub const all_features = blk: {
const len = @typeInfo(Feature).@"enum".fields.len;
std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
var result: [len]CpuFeature = undefined;
result[@intFromEnum(Feature.p2)] = .{
.llvm_name = null,
.description = "Enable Propeller 2",
.dependencies = featureSet(&[_]Feature{}),
};
const ti = @typeInfo(Feature);
for (&result, 0..) |*elem, i| {
elem.index = i;
elem.name = ti.@"enum".fields[i].name;
}
break :blk result;
};
pub const cpu = struct {
pub const generic = CpuModel{
.name = "generic",
pub const p1: CpuModel = .{
.name = "p1",
.llvm_name = null,
.features = featureSet(&[_]Feature{}),
};
pub const p2: CpuModel = .{
.name = "p2",
.llvm_name = null,
.features = featureSet(&[_]Feature{
.p2,
}),
};
};

View File

@ -734,7 +734,7 @@ const PosixThreadImpl = struct {
else => {
var count: c_int = undefined;
var count_len: usize = @sizeOf(c_int);
const name = if (comptime target.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
const name = if (comptime target.os.tag.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
posix.sysctlbynameZ(name, &count, &count_len, null, 0) catch |err| switch (err) {
error.NameTooLong, error.UnknownName => unreachable,
else => |e| return e,

View File

@ -80,7 +80,7 @@ else if (builtin.os.tag == .openbsd)
OpenbsdImpl
else if (builtin.os.tag == .dragonfly)
DragonflyImpl
else if (builtin.target.isWasm())
else if (builtin.target.cpu.arch.isWasm())
WasmImpl
else if (std.Thread.use_pthreads)
PosixImpl

View File

@ -220,8 +220,6 @@ pub const CallingConvention = union(enum(u8)) {
};
/// Deprecated; use `.x86_thiscall`.
pub const Thiscall: CallingConvention = .{ .x86_thiscall = .{} };
/// Deprecated; do not use.
pub const APCS: CallingConvention = .{ .arm_apcs = .{} };
/// Deprecated; use `.arm_aapcs`.
pub const AAPCS: CallingConvention = .{ .arm_aapcs = .{} };
/// Deprecated; use `.arm_aapcs_vfp`.
@ -284,14 +282,10 @@ pub const CallingConvention = union(enum(u8)) {
aarch64_vfabi_sve: CommonOptions,
// Calling convetions for the `arm`, `armeb`, `thumb`, and `thumbeb` architectures.
/// Deprecated; do not use.
arm_apcs: CommonOptions, // Removal of `arm_apcs` is blocked by #21842.
/// ARM Architecture Procedure Call Standard
arm_aapcs: CommonOptions,
/// ARM Architecture Procedure Call Standard Vector Floating-Point
arm_aapcs_vfp: CommonOptions,
/// Deprecated; do not use.
arm_aapcs16_vfp: CommonOptions, // Removal of `arm_aapcs16_vfp` is blocked by #21842.
arm_interrupt: ArmInterruptOptions,
// Calling conventions for the `mips64` and `mips64el` architectures.
@ -331,7 +325,7 @@ pub const CallingConvention = union(enum(u8)) {
powerpc_aix_altivec: CommonOptions,
/// The standard `wasm32` and `wasm64` calling convention, as specified in the WebAssembly Tool Conventions.
wasm_watc: CommonOptions,
wasm_mvp: CommonOptions,
/// The standard `arc` calling convention.
arc_sysv: CommonOptions,
@ -371,11 +365,8 @@ pub const CallingConvention = union(enum(u8)) {
/// The standard `msp430` calling convention.
msp430_eabi: CommonOptions,
/// The standard `propeller1` calling convention.
propeller1_sysv: CommonOptions,
/// The standard `propeller2` calling convention.
propeller2_sysv: CommonOptions,
/// The standard `propeller` calling convention.
propeller_sysv: CommonOptions,
// Calling conventions for the `s390x` architecture.
s390x_sysv: CommonOptions,
@ -500,6 +491,21 @@ pub const CallingConvention = union(enum(u8)) {
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const AddressSpace = enum(u5) {
/// The places where a user can specify an address space attribute
pub const Context = enum {
/// A function is specified to be placed in a certain address space.
function,
/// A (global) variable is specified to be placed in a certain address space.
/// In contrast to .constant, these values (and thus the address space they will be
/// placed in) are required to be mutable.
variable,
/// A (global) constant value is specified to be placed in a certain address space.
/// In contrast to .variable, values placed in this address space are not required to be mutable.
constant,
/// A pointer is ascripted to point into a certain address space.
pointer,
};
// CPU address spaces.
generic,
gs,
@ -951,7 +957,7 @@ pub const VaList = switch (builtin.cpu.arch) {
.amdgcn => *u8,
.avr => *anyopaque,
.bpfel, .bpfeb => *anyopaque,
.hexagon => if (builtin.target.isMusl()) VaListHexagon else *u8,
.hexagon => if (builtin.target.abi.isMusl()) VaListHexagon else *u8,
.loongarch32, .loongarch64 => *anyopaque,
.mips, .mipsel, .mips64, .mips64el => *anyopaque,
.riscv32, .riscv64 => *anyopaque,

View File

@ -2808,7 +2808,7 @@ pub const Sigaction = switch (native_os) {
.mipsel,
.mips64,
.mips64el,
=> if (builtin.target.isMusl())
=> if (builtin.target.abi.isMusl())
linux.Sigaction
else if (builtin.target.ptrBitWidth() == 64) extern struct {
pub const handler_fn = *align(1) const fn (i32) callconv(.c) void;
@ -6701,7 +6701,7 @@ pub const Stat = switch (native_os) {
return self.ctim;
}
},
.mips, .mipsel => if (builtin.target.isMusl()) extern struct {
.mips, .mipsel => if (builtin.target.abi.isMusl()) extern struct {
dev: dev_t,
__pad0: [2]i32,
ino: ino_t,
@ -6762,7 +6762,7 @@ pub const Stat = switch (native_os) {
return self.ctim;
}
},
.mips64, .mips64el => if (builtin.target.isMusl()) extern struct {
.mips64, .mips64el => if (builtin.target.abi.isMusl()) extern struct {
dev: dev_t,
__pad0: [3]i32,
ino: ino_t,
@ -9863,16 +9863,16 @@ pub const LC = enum(c_int) {
pub extern "c" fn setlocale(category: LC, locale: ?[*:0]const u8) ?[*:0]const u8;
pub const getcontext = if (builtin.target.isAndroid() or builtin.target.os.tag == .openbsd)
pub const getcontext = if (builtin.target.abi.isAndroid() or builtin.target.os.tag == .openbsd)
{} // android bionic and openbsd libc does not implement getcontext
else if (native_os == .linux and builtin.target.isMusl())
else if (native_os == .linux and builtin.target.abi.isMusl())
linux.getcontext
else
private.getcontext;
pub const max_align_t = if (native_abi == .msvc or native_abi == .itanium)
f64
else if (builtin.target.isDarwin())
else if (native_os.isDarwin())
c_longdouble
else
extern struct {

View File

@ -979,7 +979,7 @@ pub const kevent64_s = extern struct {
// to make sure the struct is laid out the same. These values were
// produced from C code using the offsetof macro.
comptime {
if (builtin.target.isDarwin()) {
if (builtin.target.os.tag.isDarwin()) {
assert(@offsetOf(kevent64_s, "ident") == 0);
assert(@offsetOf(kevent64_s, "filter") == 8);
assert(@offsetOf(kevent64_s, "flags") == 10);

View File

@ -292,7 +292,7 @@ pub fn dumpHexFallible(bytes: []const u8) !void {
/// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
nosuspend {
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
@ -380,7 +380,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
/// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
nosuspend {
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
@ -478,7 +478,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT
/// TODO multithreaded awareness
pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
nosuspend {
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
@ -759,7 +759,7 @@ pub const StackIterator = struct {
pub fn initWithContext(first_address: ?usize, debug_info: *SelfInfo, context: *posix.ucontext_t) !StackIterator {
// The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that
// the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder.
if (builtin.target.isDarwin() and native_arch == .aarch64)
if (builtin.target.os.tag.isDarwin() and native_arch == .aarch64)
return init(first_address, @truncate(context.mcontext.ss.fp));
if (SelfInfo.supports_unwinding) {

View File

@ -17,7 +17,6 @@ pub fn supportsUnwinding(target: std.Target) bool {
.spirv,
.spirv32,
.spirv64,
.spu_2,
=> false,
// Enabling this causes relocation errors such as:

View File

@ -121,13 +121,13 @@ pub fn deinit(self: *SelfInfo) void {
}
pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module {
if (builtin.target.isDarwin()) {
if (builtin.target.os.tag.isDarwin()) {
return self.lookupModuleDyld(address);
} else if (native_os == .windows) {
return self.lookupModuleWin32(address);
} else if (native_os == .haiku) {
return self.lookupModuleHaiku(address);
} else if (builtin.target.isWasm()) {
} else if (builtin.target.cpu.arch.isWasm()) {
return self.lookupModuleWasm(address);
} else {
return self.lookupModuleDl(address);
@ -138,13 +138,13 @@ pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module {
// This can be called when getModuleForAddress fails, so implementations should provide
// a path that doesn't rely on any side-effects of a prior successful module lookup.
pub fn getModuleNameForAddress(self: *SelfInfo, address: usize) ?[]const u8 {
if (builtin.target.isDarwin()) {
if (builtin.target.os.tag.isDarwin()) {
return self.lookupModuleNameDyld(address);
} else if (native_os == .windows) {
return self.lookupModuleNameWin32(address);
} else if (native_os == .haiku) {
return null;
} else if (builtin.target.isWasm()) {
} else if (builtin.target.cpu.arch.isWasm()) {
return null;
} else {
return self.lookupModuleNameDl(address);

View File

@ -1178,8 +1178,6 @@ pub const EM = enum(u16) {
MIPS_RS3_LE = 10,
/// Old version of Sparc v9, from before the ABI (deprecated)
OLD_SPARCV9 = 11,
/// SPU Mark II
SPU_2 = 13,
/// HPPA
PARISC = 15,
/// Fujitsu VPP500 (also old version of PowerPC; deprecated)

View File

@ -2587,7 +2587,7 @@ const CopyFileRawError = error{SystemResources} || posix.CopyFileRangeError || p
// The copy starts at offset 0, the initial offsets are preserved.
// No metadata is transferred over.
fn copy_file(fd_in: posix.fd_t, fd_out: posix.fd_t, maybe_size: ?u64) CopyFileRawError!void {
if (builtin.target.isDarwin()) {
if (builtin.target.os.tag.isDarwin()) {
const rc = posix.system.fcopyfile(fd_in, fd_out, null, .{ .DATA = true });
switch (posix.errno(rc)) {
.SUCCESS => return,

View File

@ -348,7 +348,7 @@ pub const page_allocator: Allocator = if (@hasDecl(root, "os") and
@hasDecl(root.os, "heap") and
@hasDecl(root.os.heap, "page_allocator"))
root.os.heap.page_allocator
else if (builtin.target.isWasm()) .{
else if (builtin.target.cpu.arch.isWasm()) .{
.ptr = undefined,
.vtable = &WasmAllocator.vtable,
} else if (builtin.target.os.tag == .plan9) .{
@ -508,7 +508,7 @@ test PageAllocator {
const allocator = page_allocator;
try testAllocator(allocator);
try testAllocatorAligned(allocator);
if (!builtin.target.isWasm()) {
if (!builtin.target.cpu.arch.isWasm()) {
try testAllocatorLargeAlignment(allocator);
try testAllocatorAlignedShrink(allocator);
}
@ -990,7 +990,7 @@ test {
_ = FixedBufferAllocator;
_ = ThreadSafeAllocator;
_ = SbrkAllocator;
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
_ = WasmAllocator;
}
if (!builtin.single_threaded) _ = smp_allocator;

View File

@ -7,7 +7,7 @@ const wasm = std.wasm;
const math = std.math;
comptime {
if (!builtin.target.isWasm()) {
if (!builtin.target.cpu.arch.isWasm()) {
@compileError("only available for wasm32 arch");
}
if (!builtin.single_threaded) {

View File

@ -1140,7 +1140,7 @@ test "shrink" {
}
test "large object - grow" {
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
// Not expected to pass on targets that do not have memory mapping.
return error.SkipZigTest;
}
@ -1319,7 +1319,7 @@ test "realloc large object to larger alignment" {
}
test "large object rejects shrinking to small" {
if (builtin.target.isWasm()) {
if (builtin.target.cpu.arch.isWasm()) {
// Not expected to pass on targets that do not have memory mapping.
return error.SkipZigTest;
}

View File

@ -2262,7 +2262,7 @@ test "bitNotWrap more than two limbs" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
// LLVM: unexpected runtime library name: __umodei4
if (builtin.zig_backend == .stage2_llvm and comptime builtin.target.isWasm()) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm and comptime builtin.target.cpu.arch.isWasm()) return error.SkipZigTest; // TODO
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
defer a.deinit();

View File

@ -263,7 +263,7 @@ test gamma {
}
test "gamma.special" {
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
inline for (&.{ f32, f64 }) |T| {
try expect(std.math.isNan(gamma(T, -std.math.nan(T))));

View File

@ -135,7 +135,7 @@ test log10_int {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm and comptime builtin.target.isWasm()) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm and comptime builtin.target.cpu.arch.isWasm()) return error.SkipZigTest; // TODO
inline for (
.{ u8, u16, u32, u64, u128, u256, u512 },

View File

@ -3583,7 +3583,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
return rc;
}
const have_sock_flags = !builtin.target.isDarwin() and native_os != .haiku;
const have_sock_flags = !builtin.target.os.tag.isDarwin() and native_os != .haiku;
const filtered_sock_type = if (!have_sock_flags)
socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
else
@ -3879,7 +3879,7 @@ pub fn accept(
/// description of the `CLOEXEC` flag in `open` for reasons why this may be useful.
flags: u32,
) AcceptError!socket_t {
const have_accept4 = !(builtin.target.isDarwin() or native_os == .windows or native_os == .haiku);
const have_accept4 = !(builtin.target.os.tag.isDarwin() or native_os == .windows or native_os == .haiku);
assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)
const accepted_sock: socket_t = while (true) {

View File

@ -127,7 +127,7 @@ fn detectFromInstallation(arena: Allocator, target: std.Target, lci: *const LibC
var sysroot: ?[]const u8 = null;
if (target.isDarwin()) d: {
if (target.os.tag.isDarwin()) d: {
const down1 = std.fs.path.dirname(lci.sys_include_dir.?) orelse break :d;
const down2 = std.fs.path.dirname(down1) orelse break :d;
try framework_list.append(try std.fs.path.join(arena, &.{ down2, "System", "Library", "Frameworks" }));
@ -150,7 +150,7 @@ pub fn detectFromBuilding(
) !LibCDirs {
const s = std.fs.path.sep_str;
if (target.isDarwin()) {
if (target.os.tag.isDarwin()) {
const list = try arena.alloc([]const u8, 1);
list[0] = try std.fmt.allocPrint(
arena,
@ -187,7 +187,7 @@ pub fn detectFromBuilding(
"{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}",
.{ zig_lib_dir, generic_name },
);
const generic_arch_name = target.osArchName();
const generic_arch_name = std.zig.target.osArchName(target);
const arch_os_include_dir = try std.fmt.allocPrint(
arena,
"{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any",

View File

@ -81,7 +81,7 @@ pub fn parse(
}
const os_tag = target.os.tag;
if (self.crt_dir == null and !target.isDarwin()) {
if (self.crt_dir == null and !target.os.tag.isDarwin()) {
log.err("crt_dir may not be empty for {s}", .{@tagName(os_tag)});
return error.ParseError;
}
@ -167,7 +167,7 @@ pub const FindNativeOptions = struct {
pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
var self: LibCInstallation = .{};
if (is_darwin and args.target.isDarwin()) {
if (is_darwin and args.target.os.tag.isDarwin()) {
if (!std.zig.system.darwin.isSdkInstalled(args.allocator))
return error.DarwinSdkNotFound;
const sdk = std.zig.system.darwin.getSdk(args.allocator, args.target) orelse
@ -444,7 +444,7 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindE
self.crt_dir = try ccPrintFileName(.{
.allocator = args.allocator,
.search_basename = switch (args.target.os.tag) {
.linux => if (args.target.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
.linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
else => "crt1.o",
},
.want_dirname = .only_dir,
@ -734,7 +734,7 @@ pub const CrtBasenames = struct {
const target = args.target;
if (target.isAndroid()) return switch (mode) {
if (target.abi.isAndroid()) return switch (mode) {
.dynamic_lib => .{
.crtbegin = "crtbegin_so.o",
.crtend = "crtend_so.o",
@ -1025,7 +1025,7 @@ const fs = std.fs;
const Allocator = std.mem.Allocator;
const Path = std.Build.Cache.Path;
const is_darwin = builtin.target.isDarwin();
const is_darwin = builtin.target.os.tag.isDarwin();
const is_windows = builtin.target.os.tag == .windows;
const is_haiku = builtin.target.os.tag == .haiku;

View File

@ -415,7 +415,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
}
// https://github.com/llvm/llvm-project/issues/105978
if (result.cpu.arch.isArm() and result.abi.floatAbi() == .soft) {
if (result.cpu.arch.isArm() and result.abi.float() == .soft) {
result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
}
}

View File

@ -83,7 +83,7 @@ pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths {
// TODO: consider also adding homebrew paths
// TODO: consider also adding macports paths
if (builtin.target.isDarwin()) {
if (builtin.target.os.tag.isDarwin()) {
if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: {
const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk;
try self.addLibDir(try std.fs.path.join(arena, &.{ sdk, "usr/lib" }));

View File

@ -129,6 +129,23 @@ pub fn glibcRuntimeTriple(
};
}
pub fn osArchName(target: std.Target) [:0]const u8 {
return switch (target.os.tag) {
.linux => switch (target.cpu.arch) {
.arm, .armeb, .thumb, .thumbeb => "arm",
.aarch64, .aarch64_be => "aarch64",
.loongarch32, .loongarch64 => "loongarch",
.mips, .mipsel, .mips64, .mips64el => "mips",
.powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
.riscv32, .riscv64 => "riscv",
.sparc, .sparc64 => "sparc",
.x86, .x86_64 => "x86",
else => @tagName(target.cpu.arch),
},
else => @tagName(target.cpu.arch),
};
}
pub fn muslArchName(arch: std.Target.Cpu.Arch, abi: std.Target.Abi) [:0]const u8 {
return switch (abi) {
.muslabin32 => "mipsn32",

View File

@ -1766,11 +1766,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
if (comp.config.link_libc and is_exe_or_dyn_lib) {
// If the "is darwin" check is moved below the libc_installation check below,
// error.LibCInstallationMissingCrtDir is returned from lci.resolveCrtPaths().
if (target.isDarwin()) {
switch (target.abi) {
.none, .simulator, .macabi => {},
else => return error.LibCUnavailable,
}
if (target.isDarwinLibC()) {
// TODO delete logic from MachO flush() and queue up tasks here instead.
} else if (comp.libc_installation) |lci| {
const basenames = LibCInstallation.CrtBasenames.get(.{
@ -1793,7 +1789,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
// Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.
comp.link_task_queue.shared.appendAssumeCapacity(.load_host_libc);
comp.remaining_prelink_tasks += 1;
} else if (target.isMusl() and !target.isWasm()) {
} else if (target.isMuslLibC()) {
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| {
@ -1817,7 +1813,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;
comp.remaining_prelink_tasks += 1;
} else if (target.isWasm() and target.os.tag == .wasi) {
} else if (target.isWasiLibC()) {
if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
for (comp.wasi_emulated_libs) |crt_file| {
@ -1839,11 +1835,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
// When linking mingw-w64 there are some import libs we always need.
try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
} else if (target.isDarwin()) {
switch (target.abi) {
.none, .simulator, .macabi => {},
else => return error.LibCUnavailable,
}
} else if (target.os.tag == .freestanding and capable_of_building_zig_libc) {
comp.queued_jobs.zig_libc = true;
comp.remaining_prelink_tasks += 1;
@ -5545,7 +5536,7 @@ pub fn addCCArgs(
// We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future.
if (target_util.clangSupportsFloatAbiArg(target)) {
const fabi = @tagName(target.floatAbi());
const fabi = @tagName(target.abi.float());
try argv.append(switch (target.cpu.arch) {
// For whatever reason, Clang doesn't support `-mfloat-abi` for s390x.
@ -5598,7 +5589,7 @@ pub fn addCCArgs(
if (ext != .assembly) {
try argv.append(if (target.os.tag == .freestanding) "-ffreestanding" else "-fhosted");
if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) {
if (target_util.clangSupportsNoImplicitFloatArg(target) and target.abi.float() == .soft) {
try argv.append("-mno-implicit-float");
}
@ -5646,7 +5637,7 @@ pub fn addCCArgs(
// LLVM IR files don't support these flags.
if (ext != .ll and ext != .bc) {
// https://github.com/llvm/llvm-project/issues/105972
if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) {
if (target.cpu.arch.isPowerPC() and target.abi.float() == .soft) {
try argv.append("-D__NO_FPRS__");
try argv.append("-D_SOFT_FLOAT");
try argv.append("-D_SOFT_DOUBLE");

View File

@ -9378,7 +9378,7 @@ pub fn handleExternLibName(
);
break :blk;
}
if (!target.isWasm() and !block.ownerModule().pic) {
if (!target.cpu.arch.isWasm() and !block.ownerModule().pic) {
return sema.fail(
block,
src_loc,
@ -9407,10 +9407,8 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
.aarch64_aapcs_win,
.aarch64_vfabi,
.aarch64_vfabi_sve,
.arm_apcs,
.arm_aapcs,
.arm_aapcs_vfp,
.arm_aapcs16_vfp,
.mips64_n64,
.mips64_n32,
.mips_o32,
@ -9427,7 +9425,7 @@ const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention
.powerpc_sysv_altivec,
.powerpc_aix,
.powerpc_aix_altivec,
.wasm_watc,
.wasm_mvp,
.arc_sysv,
.avr_gnu,
.bpf_std,
@ -26513,7 +26511,7 @@ fn zirWasmMemorySize(
const index_src = block.builtinCallArgSrc(extra.node, 0);
const builtin_src = block.nodeOffset(extra.node);
const target = sema.pt.zcu.getTarget();
if (!target.isWasm()) {
if (!target.cpu.arch.isWasm()) {
return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
}
@ -26538,7 +26536,7 @@ fn zirWasmMemoryGrow(
const index_src = block.builtinCallArgSrc(extra.node, 0);
const delta_src = block.builtinCallArgSrc(extra.node, 1);
const target = sema.pt.zcu.getTarget();
if (!target.isWasm()) {
if (!target.cpu.arch.isWasm()) {
return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
}
@ -37222,30 +37220,12 @@ fn analyzeComptimeAlloc(
} })));
}
/// The places where a user can specify an address space attribute
pub const AddressSpaceContext = enum {
/// A function is specified to be placed in a certain address space.
function,
/// A (global) variable is specified to be placed in a certain address space.
/// In contrast to .constant, these values (and thus the address space they will be
/// placed in) are required to be mutable.
variable,
/// A (global) constant value is specified to be placed in a certain address space.
/// In contrast to .variable, values placed in this address space are not required to be mutable.
constant,
/// A pointer is ascripted to point into a certain address space.
pointer,
};
fn resolveAddressSpace(
sema: *Sema,
block: *Block,
src: LazySrcLoc,
zir_ref: Zir.Inst.Ref,
ctx: AddressSpaceContext,
ctx: std.builtin.AddressSpace.Context,
) !std.builtin.AddressSpace {
const air_ref = try sema.resolveInst(zir_ref);
return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
@ -37256,7 +37236,7 @@ pub fn analyzeAsAddressSpace(
block: *Block,
src: LazySrcLoc,
air_ref: Air.Inst.Ref,
ctx: AddressSpaceContext,
ctx: std.builtin.AddressSpace.Context,
) !std.builtin.AddressSpace {
const pt = sema.pt;
const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
@ -37264,30 +37244,8 @@ pub fn analyzeAsAddressSpace(
const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
const address_space = try sema.interpretBuiltinType(block, src, addrspace_val, std.builtin.AddressSpace);
const target = pt.zcu.getTarget();
const arch = target.cpu.arch;
const is_nv = arch.isNvptx();
const is_amd = arch == .amdgcn;
const is_spirv = arch.isSpirV();
const is_gpu = is_nv or is_amd or is_spirv;
const supported = switch (address_space) {
// TODO: on spir-v only when os is opencl.
.generic => true,
.gs, .fs, .ss => (arch == .x86 or arch == .x86_64) and ctx == .pointer,
// TODO: check that .shared and .local are left uninitialized
.param => is_nv,
.input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
.global, .shared, .local => is_gpu,
.constant => is_gpu and (ctx == .constant),
// TODO this should also check how many flash banks the cpu has
.flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
.cog, .hub => arch.isPropeller(),
.lut => (arch == .propeller2),
};
if (!supported) {
if (!target.cpu.supportsAddressSpace(address_space, ctx)) {
// TODO error messages could be made more elaborate here
const entity = switch (ctx) {
.function => "functions",
@ -37299,7 +37257,7 @@ pub fn analyzeAsAddressSpace(
block,
src,
"{s} with address space '{s}' are not supported on {s}",
.{ entity, @tagName(address_space), arch.genericName() },
.{ entity, @tagName(address_space), target.cpu.arch.genericName() },
);
}
@ -38729,7 +38687,7 @@ pub fn resolveNavPtrModifiers(
};
const @"addrspace": std.builtin.AddressSpace = as: {
const addrspace_ctx: Sema.AddressSpaceContext = switch (zir_decl.kind) {
const addrspace_ctx: std.builtin.AddressSpace.Context = switch (zir_decl.kind) {
.@"var" => .variable,
else => switch (nav_ty.zigTypeTag(zcu)) {
.@"fn" => .function,

View File

@ -1647,7 +1647,7 @@ pub fn maxIntAlignment(target: std.Target) u16 {
.avr => 1,
.msp430 => 2,
.xcore => 4,
.propeller1, .propeller2 => 4,
.propeller => 4,
.arm,
.armeb,
@ -1698,7 +1698,6 @@ pub fn maxIntAlignment(target: std.Target) u16 {
// Below this comment are unverified but based on the fact that C requires
// int128_t to be 16 bytes aligned, it's a safe default.
.spu_2,
.csky,
.arc,
.m68k,

View File

@ -3594,7 +3594,6 @@ pub fn atomicPtrAlignment(
const max_atomic_bits: u16 = switch (target.cpu.arch) {
.avr,
.msp430,
.spu_2,
=> 16,
.arc,
@ -3620,8 +3619,7 @@ pub fn atomicPtrAlignment(
.spirv32,
.loongarch32,
.xtensa,
.propeller1,
.propeller2,
.propeller,
=> 32,
.amdgcn,
@ -4211,9 +4209,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
=> |opts| opts.incoming_stack_alignment == null,
.arm_aapcs_vfp,
=> |opts| opts.incoming_stack_alignment == null and target.os.tag != .watchos,
.arm_aapcs16_vfp,
=> |opts| opts.incoming_stack_alignment == null and target.os.tag == .watchos,
=> |opts| opts.incoming_stack_alignment == null,
.arm_interrupt,
=> |opts| opts.incoming_stack_alignment == null,
@ -4241,7 +4237,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
};
},
.stage2_wasm => switch (cc) {
.wasm_watc => |opts| opts.incoming_stack_alignment == null,
.wasm_mvp => |opts| opts.incoming_stack_alignment == null,
else => false,
},
.stage2_arm => switch (cc) {

View File

@ -1396,7 +1396,7 @@ fn resolveCallingConventionValues(
result.local_index += 1;
}
},
.wasm_watc => {
.wasm_mvp => {
for (fn_info.param_types.get(ip)) |ty| {
const ty_classes = abi.classifyType(Type.fromInterned(ty), zcu);
for (ty_classes) |class| {
@ -1421,7 +1421,7 @@ pub fn firstParamSRet(
switch (cc) {
.@"inline" => unreachable,
.auto => return isByRef(return_type, zcu, target),
.wasm_watc => {
.wasm_mvp => {
const ty_classes = abi.classifyType(return_type, zcu);
if (ty_classes[0] == .indirect) return true;
if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;
@ -1434,7 +1434,7 @@ pub fn firstParamSRet(
/// Lowers a Zig type and its value based on a given calling convention to ensure
/// it matches the ABI.
fn lowerArg(cg: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void {
if (cc != .wasm_watc) {
if (cc != .wasm_mvp) {
return cg.lowerToStack(value);
}
@ -2124,7 +2124,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
// to the stack instead
if (cg.return_value != .none) {
try cg.store(cg.return_value, operand, ret_ty, 0);
} else if (fn_info.cc == .wasm_watc and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
} else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
switch (ret_ty.zigTypeTag(zcu)) {
// Aggregate types can be lowered as a singular value
.@"struct", .@"union" => {
@ -2268,7 +2268,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
} else if (first_param_sret) {
break :result_value sret;
// TODO: Make this less fragile and optimize
} else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_watc and ret_ty.zigTypeTag(zcu) == .@"struct" or ret_ty.zigTypeTag(zcu) == .@"union") {
} else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_mvp and ret_ty.zigTypeTag(zcu) == .@"struct" or ret_ty.zigTypeTag(zcu) == .@"union") {
const result_local = try cg.allocLocal(ret_ty);
try cg.addLocal(.local_set, result_local.local.value);
const scalar_type = abi.scalarType(ret_ty, zcu);
@ -2546,7 +2546,7 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const arg = cg.args[arg_index];
const cc = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?.cc;
const arg_ty = cg.typeOfIndex(inst);
if (cc == .wasm_watc) {
if (cc == .wasm_mvp) {
const arg_classes = abi.classifyType(arg_ty, zcu);
for (arg_classes) |class| {
if (class != .none) {
@ -7047,7 +7047,7 @@ fn callIntrinsic(
// Always pass over C-ABI
const want_sret_param = firstParamSRet(.{ .wasm_watc = .{} }, return_type, zcu, cg.target);
const want_sret_param = firstParamSRet(.{ .wasm_mvp = .{} }, return_type, zcu, cg.target);
// if we want return as first param, we allocate a pointer to stack,
// and emit it as our first argument
const sret = if (want_sret_param) blk: {
@ -7060,7 +7060,7 @@ fn callIntrinsic(
for (args, 0..) |arg, arg_i| {
assert(!(want_sret_param and arg == .stack));
assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu));
try cg.lowerArg(.{ .wasm_watc = .{} }, Type.fromInterned(param_types[arg_i]), arg);
try cg.lowerArg(.{ .wasm_mvp = .{} }, Type.fromInterned(param_types[arg_i]), arg);
}
try cg.addInst(.{ .tag = .call_intrinsic, .data = .{ .intrinsic = intrinsic } });

View File

@ -90078,7 +90078,7 @@ fn floatCompilerRtAbiName(float_bits: u32) u8 {
fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type {
if (ty.toIntern() == .f16_type and
(other_ty.toIntern() == .f32_type or other_ty.toIntern() == .f64_type) and
self.target.isDarwin()) return .u16;
self.target.os.tag.isDarwin()) return .u16;
return ty;
}

View File

@ -7725,7 +7725,7 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
.aarch64_vfabi_sve => "aarch64_sve_pcs",
.arm_aapcs => "pcs(\"aapcs\")",
.arm_aapcs_vfp, .arm_aapcs16_vfp => "pcs(\"aapcs-vfp\")",
.arm_aapcs_vfp => "pcs(\"aapcs-vfp\")",
.arm_interrupt => |opts| switch (opts.type) {
.generic => "interrupt",

View File

@ -98,9 +98,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
.ve => "ve",
.kalimba,
.spu_2,
.propeller1,
.propeller2,
.propeller,
=> unreachable, // Gated by hasLlvmSupport().
};
@ -1303,7 +1301,7 @@ pub const Object = struct {
.large => .Large,
};
const float_abi: llvm.TargetMachine.FloatABI = if (comp.root_mod.resolved_target.result.floatAbi() == .hard)
const float_abi: llvm.TargetMachine.FloatABI = if (comp.root_mod.resolved_target.result.abi.float() == .hard)
.Hard
else
.Soft;
@ -2941,7 +2939,7 @@ pub const Object = struct {
function_index.setLinkage(.internal, &o.builder);
function_index.setUnnamedAddr(.unnamed_addr, &o.builder);
} else {
if (target.isWasm()) {
if (target.cpu.arch.isWasm()) {
try attributes.addFnAttr(.{ .string = .{
.kind = try o.builder.string("wasm-import-name"),
.value = try o.builder.string(nav.name.toSlice(ip)),
@ -3158,7 +3156,7 @@ pub const Object = struct {
.value = try o.builder.string(std.mem.span(s)),
} }, &o.builder);
}
if (target.floatAbi() == .soft) {
if (target.abi.float() == .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
@ -4832,7 +4830,7 @@ pub const NavGen = struct {
const global_index = o.nav_map.get(nav_index).?;
const decl_name = decl_name: {
if (zcu.getTarget().isWasm() and ty.zigTypeTag(zcu) == .@"fn") {
if (zcu.getTarget().cpu.arch.isWasm() and ty.zigTypeTag(zcu) == .@"fn") {
if (lib_name.toSlice(ip)) |lib_name_slice| {
if (!std.mem.eql(u8, lib_name_slice, "c")) {
break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ nav.name.fmt(ip), lib_name_slice });
@ -6569,7 +6567,7 @@ pub const FuncGen = struct {
// Workaround for:
// * https://github.com/llvm/llvm-project/blob/56905dab7da50bccfcceaeb496b206ff476127e1/llvm/lib/MC/WasmObjectWriter.cpp#L560
// * https://github.com/llvm/llvm-project/blob/56905dab7da50bccfcceaeb496b206ff476127e1/llvm/test/MC/WebAssembly/blockaddress.ll
if (zcu.comp.getTarget().isWasm()) break :jmp_table null;
if (zcu.comp.getTarget().cpu.arch.isWasm()) break :jmp_table null;
// On a 64-bit target, 1024 pointers in our jump table is about 8K of pointers. This seems just
// about acceptable - it won't fill L1d cache on most CPUs.
@ -10026,7 +10024,7 @@ pub const FuncGen = struct {
// of the length. This means we need to emit a check where we skip the memset when the length
// is 0 as we allow for undefined pointers in 0-sized slices.
// This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done.
const intrinsic_len0_traps = o.target.isWasm() and
const intrinsic_len0_traps = o.target.cpu.arch.isWasm() and
ptr_ty.isSlice(zcu) and
std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory);
@ -10183,7 +10181,7 @@ pub const FuncGen = struct {
// For this reason we must add a check for 0-sized slices as its pointer field can be undefined.
// We only have to do this for slices as arrays will have a valid pointer.
// This logic can be removed once https://github.com/ziglang/zig/issues/16360 is done.
if (o.target.isWasm() and
if (o.target.cpu.arch.isWasm() and
std.Target.wasm.featureSetHas(o.target.cpu.features, .bulk_memory) and
dest_ptr_ty.isSlice(zcu))
{
@ -11768,16 +11766,8 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
.x86_interrupt => .x86_intrcc,
.aarch64_vfabi => .aarch64_vector_pcs,
.aarch64_vfabi_sve => .aarch64_sve_vector_pcs,
.arm_apcs => .arm_apcscc,
.arm_aapcs => .arm_aapcscc,
.arm_aapcs_vfp => if (target.os.tag != .watchos)
.arm_aapcs_vfpcc
else
null,
.arm_aapcs16_vfp => if (target.os.tag == .watchos)
.arm_aapcs_vfpcc
else
null,
.arm_aapcs_vfp => .arm_aapcs_vfpcc,
.riscv64_lp64_v => .riscv_vectorcallcc,
.riscv32_ilp32_v => .riscv_vectorcallcc,
.avr_builtin => .avr_builtincc,
@ -11821,7 +11811,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
.powerpc_sysv_altivec,
.powerpc_aix,
.powerpc_aix_altivec,
.wasm_watc,
.wasm_mvp,
.arc_sysv,
.avr_gnu,
.bpf_std,
@ -11834,8 +11824,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
.m68k_sysv,
.m68k_gnu,
.msp430_eabi,
.propeller1_sysv,
.propeller2_sysv,
.propeller_sysv,
.s390x_sysv,
.s390x_sysv_vx,
.ve_sysv,
@ -11999,12 +11988,12 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Targe
.x86_64_win => x86_64_abi.classifyWindows(return_type, zcu) == .memory,
.x86_sysv, .x86_win => isByRef(return_type, zcu),
.x86_stdcall => !isScalar(zcu, return_type),
.wasm_watc => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect,
.wasm_mvp => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect,
.aarch64_aapcs,
.aarch64_aapcs_darwin,
.aarch64_aapcs_win,
=> aarch64_c_abi.classifyType(return_type, zcu) == .memory,
.arm_aapcs, .arm_aapcs_vfp, .arm_aapcs16_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {
.arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {
.memory, .i64_array => true,
.i32_array => |size| size != 1,
.byval => false,
@ -12054,7 +12043,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
.integer => return o.builder.intType(@intCast(return_type.bitSize(zcu))),
.double_integer => return o.builder.arrayType(2, .i64),
},
.arm_aapcs, .arm_aapcs_vfp, .arm_aapcs16_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {
.arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) {
.memory, .i64_array => return .void,
.i32_array => |len| return if (len == 1) .i32 else .void,
.byval => return o.lowerType(return_type),
@ -12084,7 +12073,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
return o.builder.structType(.normal, types[0..types_len]);
},
},
.wasm_watc => {
.wasm_mvp => {
if (isScalar(zcu, return_type)) {
return o.lowerType(return_type);
}
@ -12303,7 +12292,7 @@ const ParamTypeIterator = struct {
.double_integer => return Lowering{ .i64_array = 2 },
}
},
.arm_aapcs, .arm_aapcs_vfp, .arm_aapcs16_vfp => {
.arm_aapcs, .arm_aapcs_vfp => {
it.zig_index += 1;
it.llvm_index += 1;
switch (arm_c_abi.classifyType(ty, zcu, .arg)) {
@ -12349,7 +12338,7 @@ const ParamTypeIterator = struct {
},
}
},
.wasm_watc => {
.wasm_mvp => {
it.zig_index += 1;
it.llvm_index += 1;
if (isScalar(zcu, ty)) {
@ -12707,7 +12696,7 @@ fn backendSupportsF16(target: std.Target) bool {
.armeb,
.thumb,
.thumbeb,
=> target.floatAbi() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
=> target.abi.float() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
.aarch64,
.aarch64_be,
=> std.Target.aarch64.featureSetHas(target.cpu.features, .fp_armv8),
@ -12734,7 +12723,7 @@ fn backendSupportsF128(target: std.Target) bool {
.armeb,
.thumb,
.thumbeb,
=> target.floatAbi() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
=> target.abi.float() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
.aarch64,
.aarch64_be,
=> std.Target.aarch64.featureSetHas(target.cpu.features, .fp_armv8),
@ -13024,9 +13013,7 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
// LLVM does does not have a backend for these.
.kalimba,
.spu_2,
.propeller1,
.propeller2,
.propeller,
=> unreachable,
}
}

View File

@ -469,7 +469,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([
try args.append("-I");
try args.append(try lib_path(comp, arena, lib_libc ++ "include" ++ s ++ "generic-glibc"));
const arch_name = target.osArchName();
const arch_name = std.zig.target.osArchName(target);
try args.append("-I");
try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{
comp.zig_lib_directory.path.?, arch_name,

View File

@ -36,7 +36,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.watchos => if (target.abi == .simulator) "clang_rt.tsan_watchossim_dynamic" else "clang_rt.tsan_watchos_dynamic",
else => "tsan",
};
const link_mode: std.builtin.LinkMode = if (target.isDarwin()) .dynamic else .static;
const link_mode: std.builtin.LinkMode = if (target.os.tag.isDarwin()) .dynamic else .static;
const output_mode = .Lib;
const basename = try std.zig.binNameAlloc(arena, .{
.root_name = root_name,
@ -52,9 +52,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
const link_libcpp = target.isDarwin();
const unwind_tables: std.builtin.UnwindTables =
if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async";
const link_libcpp = target.os.tag.isDarwin();
const config = Compilation.Config.resolve(.{
.output_mode = output_mode,
@ -276,14 +276,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
});
}
const skip_linker_dependencies = !target.isDarwin();
const linker_allow_shlib_undefined = target.isDarwin();
const install_name = if (target.isDarwin())
const skip_linker_dependencies = !target.os.tag.isDarwin();
const linker_allow_shlib_undefined = target.os.tag.isDarwin();
const install_name = if (target.os.tag.isDarwin())
try std.fmt.allocPrintZ(arena, "@rpath/{s}", .{basename})
else
null;
// Workaround for https://github.com/llvm/llvm-project/issues/97627
const headerpad_size: ?u32 = if (target.isDarwin()) 32 else null;
const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null;
const sub_compilation = Compilation.create(comp.gpa, arena, .{
.local_cache_directory = comp.global_cache_directory,
.global_cache_directory = comp.global_cache_directory,

View File

@ -136,7 +136,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.abi.float() == .hard) {
try cflags.append("-DCOMPILER_RT_ARMHF_TARGET");
}
try cflags.append("-Wno-bitwise-conditional-parentheses");

View File

@ -2067,7 +2067,7 @@ fn resolveLibInput(
const lib_name = name_query.name;
if (target.isDarwin() and link_mode == .dynamic) tbd: {
if (target.os.tag.isDarwin() and link_mode == .dynamic) tbd: {
// Prefer .tbd over .dylib.
const test_path: Path = .{
.root_dir = lib_directory,
@ -2104,7 +2104,7 @@ fn resolveLibInput(
// In the case of Darwin, the main check will be .dylib, so here we
// additionally check for .so files.
if (target.isDarwin() and link_mode == .dynamic) so: {
if (target.os.tag.isDarwin() and link_mode == .dynamic) so: {
const test_path: Path = .{
.root_dir = lib_directory,
.sub_path = try std.fmt.allocPrint(arena, "lib{s}.so", .{lib_name}),

View File

@ -1881,7 +1881,7 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
try argv.append(try allocPrint(arena, "-MLLVM:-target-abi={s}", .{mabi}));
}
try argv.append(try allocPrint(arena, "-MLLVM:-float-abi={s}", .{if (target.abi.floatAbi() == .hard) "hard" else "soft"}));
try argv.append(try allocPrint(arena, "-MLLVM:-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}));
if (comp.config.lto != .none) {
switch (optimize_mode) {

View File

@ -3538,11 +3538,8 @@ fn updateLazyType(
.aarch64_vfabi => .LLVM_AAPCS,
.aarch64_vfabi_sve => .LLVM_AAPCS,
.arm_apcs => .normal,
.arm_aapcs => .LLVM_AAPCS,
.arm_aapcs_vfp,
.arm_aapcs16_vfp,
=> .LLVM_AAPCS_VFP,
.arm_aapcs_vfp => .LLVM_AAPCS_VFP,
.riscv64_lp64_v,
.riscv32_ilp32_v,

View File

@ -1709,7 +1709,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
try argv.appendSlice(&.{
"-mllvm",
try std.fmt.allocPrint(arena, "-float-abi={s}", .{if (target.abi.floatAbi() == .hard) "hard" else "soft"}),
try std.fmt.allocPrint(arena, "-float-abi={s}", .{if (target.abi.float() == .hard) "hard" else "soft"}),
});
if (comp.config.lto != .none) {
@ -2053,7 +2053,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
try argv.append(lib_path);
}
try argv.append(try comp.crtFileAsString(arena, "libc_nonshared.a"));
} else if (target.isMusl()) {
} else if (target.abi.isMusl()) {
try argv.append(try comp.crtFileAsString(arena, switch (link_mode) {
.static => "libc.a",
.dynamic => "libc.so",

View File

@ -3548,7 +3548,7 @@ pub fn getTarget(self: MachO) std.Target {
pub fn invalidateKernelCache(dir: fs.Dir, sub_path: []const u8) !void {
const tracy = trace(@src());
defer tracy.end();
if (builtin.target.isDarwin() and builtin.target.cpu.arch == .aarch64) {
if (builtin.target.os.tag.isDarwin() and builtin.target.cpu.arch == .aarch64) {
try dir.copyFile(sub_path, dir, sub_path, .{});
}
}

View File

@ -4600,7 +4600,7 @@ fn convertZcuFnType(
if (CodeGen.firstParamSRet(cc, return_type, zcu, target)) {
try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle
} else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
if (cc == .wasm_watc) {
if (cc == .wasm_mvp) {
const res_classes = abi.classifyType(return_type, zcu);
assert(res_classes[0] == .direct and res_classes[1] == .none);
const scalar_type = abi.scalarType(return_type, zcu);
@ -4618,7 +4618,7 @@ fn convertZcuFnType(
if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue;
switch (cc) {
.wasm_watc => {
.wasm_mvp => {
const param_classes = abi.classifyType(param_type, zcu);
if (param_classes[1] == .none) {
if (param_classes[0] == .direct) {

View File

@ -3983,7 +3983,7 @@ fn createModule(
}
create_module.lib_dir_args = undefined; // From here we use lib_directories instead.
if (resolved_target.is_native_os and target.isDarwin()) {
if (resolved_target.is_native_os and target.os.tag.isDarwin()) {
// If we want to link against frameworks, we need system headers.
if (create_module.frameworks.count() > 0)
create_module.want_native_include_dirs = true;

View File

@ -12,7 +12,7 @@ pub const default_stack_protector_buffer_size = 4;
pub fn cannotDynamicLink(target: std.Target) bool {
return switch (target.os.tag) {
.freestanding => true,
else => target.isSpirV(),
else => target.cpu.arch.isSpirV(),
};
}
@ -40,12 +40,12 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
}
pub fn requiresPIE(target: std.Target) bool {
return target.isAndroid() or target.isDarwin() or target.os.tag == .openbsd;
return target.abi.isAndroid() or target.os.tag.isDarwin() or target.os.tag == .openbsd;
}
/// This function returns whether non-pic code is completely invalid on the given target.
pub fn requiresPIC(target: std.Target, linking_libc: bool) bool {
return target.isAndroid() or
return target.abi.isAndroid() or
target.os.tag == .windows or target.os.tag == .uefi or
osRequiresLibC(target) or
(linking_libc and target.isGnuLibC());
@ -195,9 +195,7 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
// No LLVM backend exists.
.kalimba,
.spu_2,
.propeller1,
.propeller2,
.propeller,
=> false,
};
}
@ -247,7 +245,7 @@ pub fn clangSupportsStackProtector(target: std.Target) bool {
}
pub fn libcProvidesStackProtector(target: std.Target) bool {
return !target.isMinGW() and target.os.tag != .wasi and !target.isSpirV();
return !target.isMinGW() and target.os.tag != .wasi and !target.cpu.arch.isSpirV();
}
pub fn supportsReturnAddress(target: std.Target) bool {
@ -444,12 +442,11 @@ pub fn addrSpaceCastIsValid(
from: AddressSpace,
to: AddressSpace,
) bool {
const arch = target.cpu.arch;
switch (arch) {
.x86_64, .x86 => return arch.supportsAddressSpace(from) and arch.supportsAddressSpace(to),
switch (target.cpu.arch) {
.x86_64, .x86 => return target.cpu.supportsAddressSpace(from, null) and target.cpu.supportsAddressSpace(to, null),
.nvptx64, .nvptx, .amdgcn => {
const to_generic = arch.supportsAddressSpace(from) and to == .generic;
const from_generic = arch.supportsAddressSpace(to) and from == .generic;
const to_generic = target.cpu.supportsAddressSpace(from, null) and to == .generic;
const from_generic = target.cpu.supportsAddressSpace(to, null) and from == .generic;
return to_generic or from_generic;
},
else => return from == .generic and to == .generic,

View File

@ -9,6 +9,7 @@
#define zig_clang
#define zig_gnuc
#elif defined(__GNUC__)
#define zig_gcc
#define zig_gnuc
#elif defined(__IBMC__)
#define zig_xlc
@ -171,7 +172,7 @@
#define zig_callconv(c) __attribute__((c))
#endif
#if zig_has_attribute(naked) || defined(zig_gnuc)
#if zig_has_attribute(naked) || defined(zig_gcc)
#define zig_naked_decl __attribute__((naked))
#define zig_naked __attribute__((naked))
#elif defined(zig_msvc)
@ -265,7 +266,7 @@
#define zig_linksection_fn zig_linksection
#endif
#if zig_has_builtin(unreachable) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(unreachable) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_unreachable() __builtin_unreachable()
#elif defined(zig_msvc)
#define zig_unreachable() __assume(0)
@ -293,11 +294,11 @@
#endif /* zig_macho */
#endif /* zig_msvc */
#if (zig_has_attribute(alias) || defined(zig_tinyc)) && !defined(zig_macho)
#define zig_export(symbol, name) __attribute__((alias(symbol)))
#elif defined(zig_msvc)
#if defined(zig_msvc)
#define zig_export(symbol, name) ; \
__pragma(comment(linker, "/alternatename:" zig_mangle_c(name) "=" zig_mangle_c(symbol)))
#elif (zig_has_attribute(alias) || defined(zig_tinyc)) && !defined(zig_macho)
#define zig_export(symbol, name) __attribute__((alias(symbol)))
#else
#define zig_export(symbol, name) ; \
__asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))
@ -321,7 +322,7 @@
#if defined(zig_msvc)
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args;\
__pragma(comment(linker, "/alternatename:" zig_mangle_c(#fn_name) "=" zig_mangle_c(#libc_name)));
#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, sig_args, call_args)
#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
#else /* zig_msvc */
#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args __asm(zig_mangle_c(#libc_name));
#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type libc_name sig_args; \
@ -331,7 +332,7 @@
#define zig_expand_import_0(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
#define zig_expand_import_1(Type, fn_name, libc_name, sig_args, call_args) zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args)
#if zig_has_attribute(weak) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_attribute(weak) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_weak_linkage __attribute__((weak))
#define zig_weak_linkage_fn __attribute__((weak))
#elif defined(zig_msvc)
@ -418,7 +419,7 @@
#define zig_breakpoint() zig_breakpoint_unavailable
#endif
#if zig_has_builtin(return_address) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(return_address) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
#elif defined(zig_msvc)
#define zig_return_address() _ReturnAddress()
@ -426,7 +427,7 @@
#define zig_return_address() 0
#endif
#if zig_has_builtin(frame_address) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(frame_address) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_frame_address() __builtin_frame_address(0)
#elif defined(zig_msvc)
#define zig_frame_address() _AddressOfReturnAddress()
@ -434,7 +435,7 @@
#define zig_frame_address() 0
#endif
#if zig_has_builtin(prefetch) || defined(zig_gnuc)
#if zig_has_builtin(prefetch) || defined(zig_gcc)
#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
#else
#define zig_prefetch(addr, rw, locality)
@ -452,7 +453,7 @@
#define zig_noreturn [[noreturn]]
#elif __STDC_VERSION__ >= 201112L
#define zig_noreturn _Noreturn
#elif zig_has_attribute(noreturn) || defined(zig_gnuc) || defined(zig_tinyc)
#elif zig_has_attribute(noreturn) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_noreturn __attribute__((noreturn))
#elif defined(zig_msvc)
#define zig_noreturn __declspec(noreturn)
@ -650,7 +651,7 @@ typedef ptrdiff_t intptr_t;
zig_operator(Type, Type, operation, operator)
#define zig_shift_operator(Type, operation, operator) \
zig_operator(Type, uint8_t, operation, operator)
#define zig_int_helpers(w) \
#define zig_int_helpers(w, PromotedUnsigned) \
zig_basic_operator(uint##w##_t, and_u##w, &) \
zig_basic_operator( int##w##_t, and_i##w, &) \
zig_basic_operator(uint##w##_t, or_u##w, |) \
@ -726,19 +727,51 @@ typedef ptrdiff_t intptr_t;
} \
\
static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
return zig_wrap_u##w(lhs * rhs, bits); \
return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \
} \
\
static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \
}
zig_int_helpers(8)
zig_int_helpers(16)
zig_int_helpers(32)
zig_int_helpers(64)
#if UINT8_MAX <= UINT_MAX
zig_int_helpers(8, unsigned int)
#elif UINT8_MAX <= ULONG_MAX
zig_int_helpers(8, unsigned long)
#elif UINT8_MAX <= ULLONG_MAX
zig_int_helpers(8, unsigned long long)
#else
zig_int_helpers(8, uint8_t)
#endif
#if UINT16_MAX <= UINT_MAX
zig_int_helpers(16, unsigned int)
#elif UINT16_MAX <= ULONG_MAX
zig_int_helpers(16, unsigned long)
#elif UINT16_MAX <= ULLONG_MAX
zig_int_helpers(16, unsigned long long)
#else
zig_int_helpers(16, uint16_t)
#endif
#if UINT32_MAX <= UINT_MAX
zig_int_helpers(32, unsigned int)
#elif UINT32_MAX <= ULONG_MAX
zig_int_helpers(32, unsigned long)
#elif UINT32_MAX <= ULLONG_MAX
zig_int_helpers(32, unsigned long long)
#else
zig_int_helpers(32, uint32_t)
#endif
#if UINT64_MAX <= UINT_MAX
zig_int_helpers(64, unsigned int)
#elif UINT64_MAX <= ULONG_MAX
zig_int_helpers(64, unsigned long)
#elif UINT64_MAX <= ULLONG_MAX
zig_int_helpers(64, unsigned long long)
#else
zig_int_helpers(64, uint64_t)
#endif
static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint32_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u32(full_res, bits);
@ -751,7 +784,7 @@ static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
zig_extern int32_t __addosi4(int32_t lhs, int32_t rhs, int *overflow);
static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int32_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
#else
@ -764,7 +797,7 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
}
static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint64_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u64(full_res, bits);
@ -777,7 +810,7 @@ static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
zig_extern int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow);
static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int64_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
#else
@ -790,7 +823,7 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
}
static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint8_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u8(full_res, bits);
@ -804,7 +837,7 @@ static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
}
static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int8_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i8(full_res, bits);
@ -818,7 +851,7 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
}
static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint16_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u16(full_res, bits);
@ -832,7 +865,7 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
}
static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gnuc)
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int16_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i16(full_res, bits);
@ -846,7 +879,7 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
}
static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint32_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u32(full_res, bits);
@ -859,7 +892,7 @@ static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
zig_extern int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow);
static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int32_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
#else
@ -872,7 +905,7 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
}
static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint64_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u64(full_res, bits);
@ -885,7 +918,7 @@ static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
zig_extern int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow);
static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int64_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
#else
@ -898,7 +931,7 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
}
static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint8_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u8(full_res, bits);
@ -912,7 +945,7 @@ static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
}
static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int8_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i8(full_res, bits);
@ -926,7 +959,7 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
}
static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint16_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u16(full_res, bits);
@ -940,7 +973,7 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
}
static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gnuc)
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int16_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i16(full_res, bits);
@ -954,7 +987,7 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
}
static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint32_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u32(full_res, bits);
@ -967,7 +1000,7 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int32_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
#else
@ -980,7 +1013,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
}
static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint64_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u64(full_res, bits);
@ -993,7 +1026,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int64_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
#else
@ -1006,7 +1039,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
}
static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint8_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u8(full_res, bits);
@ -1020,7 +1053,7 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
}
static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int8_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i8(full_res, bits);
@ -1034,7 +1067,7 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
}
static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint16_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u16(full_res, bits);
@ -1048,7 +1081,7 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
}
static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gnuc)
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int16_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i16(full_res, bits);
@ -1157,7 +1190,7 @@ static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) {
static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) {
uint16_t full_res;
#if zig_has_builtin(bswap16) || defined(zig_gnuc)
#if zig_has_builtin(bswap16) || defined(zig_gcc)
full_res = __builtin_bswap16(val);
#else
full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 |
@ -1172,7 +1205,7 @@ static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {
static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {
uint32_t full_res;
#if zig_has_builtin(bswap32) || defined(zig_gnuc)
#if zig_has_builtin(bswap32) || defined(zig_gcc)
full_res = __builtin_bswap32(val);
#else
full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 |
@ -1187,7 +1220,7 @@ static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) {
static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {
uint64_t full_res;
#if zig_has_builtin(bswap64) || defined(zig_gnuc)
#if zig_has_builtin(bswap64) || defined(zig_gcc)
full_res = __builtin_bswap64(val);
#else
full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 |
@ -1267,7 +1300,7 @@ static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {
static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \
return zig_popcount_u##w((uint##w##_t)val, bits); \
}
#if zig_has_builtin(popcount) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_builtin_popcount(w) \
static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \
(void)bits; \
@ -1296,7 +1329,7 @@ zig_builtin_popcount(64)
static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \
return zig_ctz_u##w((uint##w##_t)val, bits); \
}
#if zig_has_builtin(ctz) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_builtin_ctz(w) \
static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \
if (val == 0) return bits; \
@ -1321,7 +1354,7 @@ zig_builtin_ctz(64)
static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \
return zig_clz_u##w((uint##w##_t)val, bits); \
}
#if zig_has_builtin(clz) || defined(zig_gnuc) || defined(zig_tinyc)
#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)
#define zig_builtin_clz(w) \
static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \
if (val == 0) return bits; \
@ -3176,7 +3209,7 @@ long double __cdecl nanl(char const* input);
#define __builtin_infl() zig_msvc_flt_infl
#endif
#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gnuc)
#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gcc)
#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16 (__builtin_##name, )(arg)
#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32 (__builtin_##name, )(arg)
#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64 (__builtin_##name, )(arg)
@ -3202,7 +3235,7 @@ typedef double zig_f16;
#elif LDBL_MANT_DIG == 11
typedef long double zig_f16;
#define zig_make_f16(fp, repr) fp##l
#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
typedef _Float16 zig_f16;
#define zig_make_f16(fp, repr) fp##f16
#elif defined(__SIZEOF_FP16__)
@ -3324,7 +3357,7 @@ typedef zig_u128 zig_f80;
#define zig_init_special_f80(sign, name, arg, repr) repr
#endif
#if !defined(zig_clang) && defined(zig_gnuc) && defined(zig_x86)
#if defined(zig_gcc) && defined(zig_x86)
#define zig_f128_has_miscompilations 1
#else
#define zig_f128_has_miscompilations 0
@ -3729,7 +3762,11 @@ zig_float_builtins(64)
res = zig_atomicrmw_expected; \
} while (0)
#if (__STDC_VERSION__ >= 201112L || (zig_has_include(<stdatomic.h>) && !defined(zig_msvc))) && !defined(__STDC_NO_ATOMICS__)
#if (__STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)) || (zig_has_include(<stdatomic.h>) && !defined(zig_msvc))
#define zig_c11_atomics
#endif
#if defined(zig_c11_atomics)
#include <stdatomic.h>
typedef enum memory_order zig_memory_order;
#define zig_memory_order_relaxed memory_order_relaxed
@ -3765,9 +3802,9 @@ typedef int zig_memory_order;
#define zig_memory_order_acq_rel __ATOMIC_ACQ_REL
#define zig_memory_order_seq_cst __ATOMIC_SEQ_CST
#define zig_atomic(Type) Type
#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)
#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, &(arg), &(res), order)
#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), false, succ, fail)
#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), true, succ, fail)
#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, (ReprType *)&(arg), &(res), order)
#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order)
#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order)
#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order)
@ -3776,7 +3813,7 @@ typedef int zig_memory_order;
#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, &(arg), order)
#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, (ReprType *)&(arg), order)
#define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order)
#undef zig_atomicrmw_xchg_float
#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
@ -3823,7 +3860,7 @@ typedef int zig_memory_order;
#define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable
#endif
#if defined(zig_msvc) && defined(zig_x86)
#if !defined(zig_c11_atomics) && defined(zig_msvc) && defined(zig_x86)
/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
@ -4069,7 +4106,7 @@ static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 a
#endif /* zig_x86_32 */
#endif /* zig_msvc && zig_x86 */
#endif /* !zig_c11_atomics && zig_msvc && zig_x86 */
/* ======================== Special Case Intrinsics ========================= */

Binary file not shown.

View File

@ -126,7 +126,7 @@ test "cmp f16" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
try testCmp(f16);
try comptime testCmp(f16);
@ -135,7 +135,7 @@ test "cmp f16" {
test "cmp f32/f64" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
try testCmp(f32);
try comptime testCmp(f32);

View File

@ -1639,7 +1639,7 @@ test "NaN comparison" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
try testNanEqNan(f16);
try testNanEqNan(f32);
@ -1795,7 +1795,7 @@ test "runtime comparison to NaN is comptime-known" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
const S = struct {
fn doTheTest(comptime F: type, x: F) void {
@ -1826,7 +1826,7 @@ test "runtime int comparison to inf is comptime-known" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
const S = struct {
fn doTheTest(comptime F: type, x: u32) void {

View File

@ -135,7 +135,7 @@ export fn zig_f64(x: f64) void {
expect(x == 56.78) catch @panic("test failure: zig_f64");
}
export fn zig_longdouble(x: c_longdouble) void {
if (!builtin.target.isWasm()) return; // waiting for #1481
if (!builtin.target.cpu.arch.isWasm()) return; // waiting for #1481
expect(x == 12.34) catch @panic("test failure: zig_longdouble");
}
@ -1661,7 +1661,7 @@ test "bool simd vector" {
}
{
if (!builtin.target.isWasm()) c_vector_256_bool(.{
if (!builtin.target.cpu.arch.isWasm()) c_vector_256_bool(.{
false,
true,
true,
@ -2179,7 +2179,7 @@ test "bool simd vector" {
try expect(vec[255] == false);
}
{
if (!builtin.target.isWasm()) c_vector_512_bool(.{
if (!builtin.target.cpu.arch.isWasm()) c_vector_512_bool(.{
true,
true,
true,
@ -5593,7 +5593,7 @@ test "f80 extra struct" {
comptime {
skip: {
if (builtin.target.isWasm()) break :skip;
if (builtin.target.cpu.arch.isWasm()) break :skip;
_ = struct {
export fn zig_f128(x: f128) f128 {

View File

@ -117,9 +117,9 @@ export fn testMutablePointer() void {
// tmp.zig:37:38: note: imported here
// neg_inf.zon:1:1: error: expected type '?u8'
// tmp.zig:57:28: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testNonExhaustiveEnum__enum_490'
// neg_inf.zon:1:1: error: expected type 'tmp.testNonExhaustiveEnum__enum_487'
// tmp.zig:62:39: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testUntaggedUnion__union_492'
// neg_inf.zon:1:1: error: expected type 'tmp.testUntaggedUnion__union_489'
// tmp.zig:67:44: note: imported here
// neg_inf.zon:1:1: error: expected type 'tmp.testTaggedUnionVoid__union_495'
// neg_inf.zon:1:1: error: expected type 'tmp.testTaggedUnionVoid__union_492'
// tmp.zig:72:50: note: imported here

View File

@ -15,6 +15,6 @@ pub export fn entry() void {
// error
//
// :7:25: error: unable to resolve comptime value
// :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_464.C' must be comptime-known
// :7:25: note: initializer of comptime-only struct 'tmp.S.foo__anon_461.C' must be comptime-known
// :4:16: note: struct requires comptime because of this field
// :4:16: note: types are not available at runtime

View File

@ -16,5 +16,5 @@ pub export fn entry2() void {
//
// :3:6: error: no field or member function named 'copy' in '[]const u8'
// :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})'
// :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_468'
// :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_465'
// :12:6: note: struct declared here

View File

@ -1,10 +1,8 @@
export fn entry1() callconv(.APCS) void {}
export fn entry2() callconv(.AAPCS) void {}
export fn entry3() callconv(.AAPCSVFP) void {}
// error
// target=x86_64-linux-none
//
// :1:30: error: calling convention 'arm_apcs' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb'
// :2:30: error: calling convention 'arm_aapcs' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb'
// :3:30: error: calling convention 'arm_aapcs_vfp' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb'
// :1:30: error: calling convention 'arm_aapcs' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb'
// :2:30: error: calling convention 'arm_aapcs_vfp' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb'

View File

@ -6,6 +6,6 @@ export fn foo() void {
// error
//
// :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_457'
// :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_454'
// :3:16: note: struct declared here
// :1:11: note: struct declared here

View File

@ -44,9 +44,9 @@ comptime {
//
// :5:23: error: expected error union type, found 'comptime_int'
// :10:23: error: expected error union type, found '@TypeOf(.{})'
// :15:23: error: expected error union type, found 'tmp.test2__struct_494'
// :15:23: error: expected error union type, found 'tmp.test2__struct_491'
// :15:23: note: struct declared here
// :20:27: error: expected error union type, found 'tmp.test3__struct_496'
// :20:27: error: expected error union type, found 'tmp.test3__struct_493'
// :20:27: note: struct declared here
// :25:23: error: expected error union type, found 'struct { comptime *const [5:0]u8 = "hello" }'
// :31:13: error: expected error union type, found 'u32'

View File

@ -24,7 +24,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("unwind.zig"),
.target = target,
.optimize = optimize,
.unwind_tables = if (target.result.isDarwin()) .@"async" else null,
.unwind_tables = if (target.result.os.tag.isDarwin()) .@"async" else null,
.omit_frame_pointer = false,
}),
});
@ -94,7 +94,7 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("shared_lib_unwind.zig"),
.target = target,
.optimize = optimize,
.unwind_tables = if (target.result.isDarwin()) .@"async" else null,
.unwind_tables = if (target.result.os.tag.isDarwin()) .@"async" else null,
.omit_frame_pointer = true,
}),
});

View File

@ -36,8 +36,8 @@ extern fn frame0(
pub fn main() !void {
// Disabled until the DWARF unwinder bugs on .aarch64 are solved
if (builtin.omit_frame_pointer and comptime builtin.target.isDarwin() and builtin.cpu.arch == .aarch64) return;
if (builtin.target.isDarwin() and builtin.cpu.arch == .x86_64) return; // https://github.com/ziglang/zig/issues/21337
if (builtin.omit_frame_pointer and comptime builtin.target.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) return;
if (builtin.target.os.tag.isDarwin() and builtin.cpu.arch == .x86_64) return; // https://github.com/ziglang/zig/issues/21337
if (!std.debug.have_ucontext or !std.debug.have_getcontext) return;

View File

@ -88,7 +88,7 @@ noinline fn frame0(expected: *[4]usize, unwound: *[4]usize) void {
pub fn main() !void {
// Disabled until the DWARF unwinder bugs on .aarch64 are solved
if (builtin.omit_frame_pointer and comptime builtin.target.isDarwin() and builtin.cpu.arch == .aarch64) return;
if (builtin.omit_frame_pointer and comptime builtin.target.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) return;
if (!std.debug.have_ucontext or !std.debug.have_getcontext) return;

View File

@ -34,10 +34,12 @@ const Feature = struct {
flatten: bool = false,
};
const LlvmTarget = struct {
const ArchTarget = struct {
zig_name: []const u8,
llvm_name: []const u8,
td_name: []const u8,
llvm: ?struct {
name: []const u8,
td_name: []const u8,
},
feature_overrides: []const FeatureOverride = &.{},
extra_cpus: []const Cpu = &.{},
extra_features: []const Feature = &.{},
@ -45,11 +47,13 @@ const LlvmTarget = struct {
branch_quota: ?usize = null,
};
const llvm_targets = [_]LlvmTarget{
const targets = [_]ArchTarget{
.{
.zig_name = "aarch64",
.llvm_name = "AArch64",
.td_name = "AArch64.td",
.llvm = .{
.name = "AArch64",
.td_name = "AArch64",
},
.branch_quota = 2000,
.feature_overrides = &.{
.{
@ -391,8 +395,10 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "amdgcn",
.llvm_name = "AMDGPU",
.td_name = "AMDGPU.td",
.llvm = .{
.name = "AMDGPU",
.td_name = "AMDGPU",
},
.feature_overrides = &.{
.{
.llvm_name = "DumpCode",
@ -418,13 +424,17 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "arc",
.llvm_name = "ARC",
.td_name = "ARC.td",
.llvm = .{
.name = "ARC",
.td_name = "ARC",
},
},
.{
.zig_name = "arm",
.llvm_name = "ARM",
.td_name = "ARM.td",
.llvm = .{
.name = "ARM",
.td_name = "ARM",
},
.branch_quota = 10000,
.feature_overrides = &.{
.{
@ -928,66 +938,113 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "avr",
.llvm_name = "AVR",
.td_name = "AVR.td",
.llvm = .{
.name = "AVR",
.td_name = "AVR",
},
},
.{
.zig_name = "bpf",
.llvm_name = "BPF",
.td_name = "BPF.td",
.llvm = .{
.name = "BPF",
.td_name = "BPF",
},
},
.{
.zig_name = "csky",
.llvm_name = "CSKY",
.td_name = "CSKY.td",
.llvm = .{
.name = "CSKY",
.td_name = "CSKY",
},
},
.{
.zig_name = "hexagon",
.llvm_name = "Hexagon",
.td_name = "Hexagon.td",
.llvm = .{
.name = "Hexagon",
.td_name = "Hexagon",
},
},
.{
.zig_name = "lanai",
.llvm_name = "Lanai",
.td_name = "Lanai.td",
.llvm = .{
.name = "Lanai",
.td_name = "Lanai",
},
},
.{
.zig_name = "loongarch",
.llvm_name = "LoongArch",
.td_name = "LoongArch.td",
.llvm = .{
.name = "LoongArch",
.td_name = "LoongArch",
},
},
.{
.zig_name = "m68k",
.llvm_name = "M68k",
.td_name = "M68k.td",
.llvm = .{
.name = "M68k",
.td_name = "M68k",
},
},
.{
.zig_name = "msp430",
.llvm_name = "MSP430",
.td_name = "MSP430.td",
.llvm = .{
.name = "MSP430",
.td_name = "MSP430",
},
},
.{
.zig_name = "mips",
.llvm_name = "Mips",
.td_name = "Mips.td",
.llvm = .{
.name = "Mips",
.td_name = "Mips",
},
},
.{
.zig_name = "nvptx",
.llvm_name = "NVPTX",
.td_name = "NVPTX.td",
.llvm = .{
.name = "NVPTX",
.td_name = "NVPTX",
},
},
.{
.zig_name = "powerpc",
.llvm_name = "PowerPC",
.td_name = "PPC.td",
.llvm = .{
.name = "PowerPC",
.td_name = "PPC",
},
.omit_cpus = &.{
"ppc32",
},
},
.{
.zig_name = "propeller",
.llvm = null,
.extra_features = &.{
.{
.zig_name = "p2",
.desc = "Enable Propeller 2",
.deps = &.{},
},
},
.extra_cpus = &.{
.{
.llvm_name = null,
.zig_name = "p1",
.features = &.{},
},
.{
.llvm_name = null,
.zig_name = "p2",
.features = &.{"p2"},
},
},
},
.{
.zig_name = "riscv",
.llvm_name = "RISCV",
.td_name = "RISCV.td",
.llvm = .{
.name = "RISCV",
.td_name = "RISCV",
},
.branch_quota = 2000,
.feature_overrides = &.{
.{
@ -1010,29 +1067,38 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "sparc",
.llvm_name = "Sparc",
.td_name = "Sparc.td",
.llvm = .{
.name = "Sparc",
.td_name = "Sparc",
},
},
// TODO: merge tools/update_spirv_features.zig into this script
//.{
// .zig_name = "spirv",
// .llvm_name = "SPIRV",
// .td_name = "SPIRV.td",
// .llvm = .{
// .name = "SPIRV",
// },
//},
.{
.zig_name = "s390x",
.llvm_name = "SystemZ",
.td_name = "SystemZ.td",
.llvm = .{
.name = "SystemZ",
.td_name = "SystemZ",
},
},
.{
.zig_name = "ve",
.llvm_name = "VE",
.td_name = "VE.td",
.llvm = .{
.name = "VE",
.td_name = "VE",
},
},
.{
.zig_name = "wasm",
.llvm_name = "WebAssembly",
.td_name = "WebAssembly.td",
.llvm = .{
.name = "WebAssembly",
.td_name = "WebAssembly",
},
.extra_features = &.{
.{
.zig_name = "nontrapping_bulk_memory_len0",
@ -1057,8 +1123,10 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "x86",
.llvm_name = "X86",
.td_name = "X86.td",
.llvm = .{
.name = "X86",
.td_name = "X86",
},
.feature_overrides = &.{
.{
.llvm_name = "64bit-mode",
@ -1362,13 +1430,17 @@ const llvm_targets = [_]LlvmTarget{
},
.{
.zig_name = "xcore",
.llvm_name = "XCore",
.td_name = "XCore.td",
.llvm = .{
.name = "XCore",
.td_name = "XCore",
},
},
.{
.zig_name = "xtensa",
.llvm_name = "Xtensa",
.td_name = "Xtensa.td",
.llvm = .{
.name = "Xtensa",
.td_name = "Xtensa",
},
},
};
@ -1413,33 +1485,33 @@ pub fn main() anyerror!void {
var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});
defer zig_src_dir.close();
const root_progress = std.Progress.start(.{ .estimated_total_items = llvm_targets.len });
const root_progress = std.Progress.start(.{ .estimated_total_items = targets.len });
defer root_progress.end();
if (builtin.single_threaded) {
for (llvm_targets) |llvm_target| {
if (filter) |zig_name| if (!std.mem.eql(u8, llvm_target.zig_name, zig_name)) continue;
for (targets) |target| {
if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
try processOneTarget(.{
.llvm_tblgen_exe = llvm_tblgen_exe,
.llvm_src_root = llvm_src_root,
.zig_src_dir = zig_src_dir,
.root_progress = root_progress,
.llvm_target = llvm_target,
.target = target,
});
}
} else {
var pool: std.Thread.Pool = undefined;
try pool.init(.{ .allocator = arena, .n_jobs = llvm_targets.len });
try pool.init(.{ .allocator = arena, .n_jobs = targets.len });
defer pool.deinit();
for (llvm_targets) |llvm_target| {
if (filter) |zig_name| if (!std.mem.eql(u8, llvm_target.zig_name, zig_name)) continue;
for (targets) |target| {
if (filter) |zig_name| if (!std.mem.eql(u8, target.zig_name, zig_name)) continue;
const job = Job{
.llvm_tblgen_exe = llvm_tblgen_exe,
.llvm_src_root = llvm_src_root,
.zig_src_dir = zig_src_dir,
.root_progress = root_progress,
.llvm_target = llvm_target,
.target = target,
};
try pool.spawn(processOneTarget, .{job});
}
@ -1451,162 +1523,147 @@ const Job = struct {
llvm_src_root: []const u8,
zig_src_dir: std.fs.Dir,
root_progress: std.Progress.Node,
llvm_target: LlvmTarget,
target: ArchTarget,
};
fn processOneTarget(job: Job) void {
errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)});
const llvm_target = job.llvm_target;
const target = job.target;
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_state.deinit();
const arena = arena_state.allocator();
const progress_node = job.root_progress.start(llvm_target.zig_name, 3);
const progress_node = job.root_progress.start(target.zig_name, 3);
defer progress_node.end();
const tblgen_progress = progress_node.start("running llvm-tblgen", 0);
const child_args = [_][]const u8{
job.llvm_tblgen_exe,
"--dump-json",
try std.fmt.allocPrint(arena, "{s}/llvm/lib/Target/{s}/{s}", .{
job.llvm_src_root,
llvm_target.llvm_name,
llvm_target.td_name,
}),
try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{job.llvm_src_root}),
try std.fmt.allocPrint(arena, "-I={s}/llvm/lib/Target/{s}", .{
job.llvm_src_root, llvm_target.llvm_name,
}),
};
const child_result = try std.process.Child.run(.{
.allocator = arena,
.argv = &child_args,
.max_output_bytes = 500 * 1024 * 1024,
});
tblgen_progress.end();
if (child_result.stderr.len != 0) {
std.debug.print("{s}\n", .{child_result.stderr});
}
const json_text = switch (child_result.term) {
.Exited => |code| if (code == 0) child_result.stdout else {
std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
std.process.exit(1);
},
else => {
std.debug.print("llvm-tblgen crashed\n", .{});
std.process.exit(1);
},
};
const json_parse_progress = progress_node.start("parsing JSON", 0);
const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
defer parsed.deinit();
const root_map = &parsed.value.object;
json_parse_progress.end();
const render_progress = progress_node.start("rendering Zig code", 0);
// So far, LLVM only has a few aliases for the same CPU.
var cpu_aliases = std.StringHashMap(std.SegmentedList(struct {
llvm: []const u8,
zig: []const u8,
}, 4)).init(arena);
{
var it = root_map.iterator();
while (it.next()) |kv| {
if (kv.key_ptr.len == 0) continue;
if (kv.key_ptr.*[0] == '!') continue;
if (kv.value_ptr.* != .object) continue;
if (hasSuperclass(&kv.value_ptr.object, "ProcessorAlias")) {
// Note that `Name` is actually the alias, while `Alias` is the name that will have
// a full `Processor` object defined.
const llvm_alias = kv.value_ptr.object.get("Name").?.string;
const llvm_name = kv.value_ptr.object.get("Alias").?.string;
const gop = try cpu_aliases.getOrPut(try llvmNameToZigName(arena, llvm_name));
if (!gop.found_existing) gop.value_ptr.* = .{};
try gop.value_ptr.append(arena, .{
.llvm = llvm_alias,
.zig = try llvmNameToZigName(arena, llvm_alias),
});
}
}
}
var features_table = std.StringHashMap(Feature).init(arena);
var all_features = std.ArrayList(Feature).init(arena);
var all_cpus = std.ArrayList(Cpu).init(arena);
{
var it = root_map.iterator();
while (it.next()) |kv| {
if (kv.key_ptr.len == 0) continue;
if (kv.key_ptr.*[0] == '!') continue;
if (kv.value_ptr.* != .object) continue;
if (hasSuperclass(&kv.value_ptr.object, "SubtargetFeature")) {
const llvm_name = kv.value_ptr.object.get("Name").?.string;
if (llvm_name.len == 0) continue;
var zig_name = try llvmNameToZigName(arena, llvm_name);
var desc = kv.value_ptr.object.get("Desc").?.string;
var deps = std.ArrayList([]const u8).init(arena);
var omit = false;
var flatten = false;
var omit_deps: []const []const u8 = &.{};
var extra_deps: []const []const u8 = &.{};
for (llvm_target.feature_overrides) |feature_override| {
if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
if (feature_override.omit) {
// Still put the feature into the table so that we can
// expand dependencies for the feature overrides marked `flatten`.
omit = true;
}
if (feature_override.flatten) {
flatten = true;
}
if (feature_override.zig_name) |override_name| {
zig_name = override_name;
}
if (feature_override.desc) |override_desc| {
desc = override_desc;
}
omit_deps = feature_override.omit_deps;
extra_deps = feature_override.extra_deps;
break;
}
if (target.llvm) |llvm| {
const tblgen_progress = progress_node.start("running llvm-tblgen", 0);
const child_args = [_][]const u8{
job.llvm_tblgen_exe,
"--dump-json",
try std.fmt.allocPrint(arena, "{s}/llvm/lib/Target/{s}/{s}.td", .{
job.llvm_src_root,
llvm.name,
llvm.td_name,
}),
try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{job.llvm_src_root}),
try std.fmt.allocPrint(arena, "-I={s}/llvm/lib/Target/{s}", .{
job.llvm_src_root, llvm.name,
}),
};
const child_result = try std.process.Child.run(.{
.allocator = arena,
.argv = &child_args,
.max_output_bytes = 500 * 1024 * 1024,
});
tblgen_progress.end();
if (child_result.stderr.len != 0) {
std.debug.print("{s}\n", .{child_result.stderr});
}
const json_text = switch (child_result.term) {
.Exited => |code| if (code == 0) child_result.stdout else {
std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
std.process.exit(1);
},
else => {
std.debug.print("llvm-tblgen crashed\n", .{});
std.process.exit(1);
},
};
const json_parse_progress = progress_node.start("parsing JSON", 0);
const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
defer parsed.deinit();
const root_map = &parsed.value.object;
json_parse_progress.end();
const collate_progress = progress_node.start("collating LLVM data", 0);
// So far, LLVM only has a few aliases for the same CPU.
var cpu_aliases = std.StringHashMap(std.SegmentedList(struct {
llvm: []const u8,
zig: []const u8,
}, 4)).init(arena);
{
var it = root_map.iterator();
while (it.next()) |kv| {
if (kv.key_ptr.len == 0) continue;
if (kv.key_ptr.*[0] == '!') continue;
if (kv.value_ptr.* != .object) continue;
if (hasSuperclass(&kv.value_ptr.object, "ProcessorAlias")) {
// Note that `Name` is actually the alias, while `Alias` is the name that will have
// a full `Processor` object defined.
const llvm_alias = kv.value_ptr.object.get("Name").?.string;
const llvm_name = kv.value_ptr.object.get("Alias").?.string;
const gop = try cpu_aliases.getOrPut(try llvmNameToZigName(arena, llvm_name));
if (!gop.found_existing) gop.value_ptr.* = .{};
try gop.value_ptr.append(arena, .{
.llvm = llvm_alias,
.zig = try llvmNameToZigName(arena, llvm_alias),
});
}
const implies = kv.value_ptr.object.get("Implies").?.array;
for (implies.items) |imply| {
const other_key = imply.object.get("def").?.string;
const other_obj = root_map.get(other_key).?.object;
const other_llvm_name = other_obj.get("Name").?.string;
const other_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
llvm_target,
other_llvm_name,
)) orelse continue;
for (omit_deps) |omit_dep| {
if (mem.eql(u8, other_zig_name, omit_dep)) break;
} else {
try deps.append(other_zig_name);
}
}
{
var it = root_map.iterator();
while (it.next()) |kv| {
if (kv.key_ptr.len == 0) continue;
if (kv.key_ptr.*[0] == '!') continue;
if (kv.value_ptr.* != .object) continue;
if (hasSuperclass(&kv.value_ptr.object, "SubtargetFeature")) {
const llvm_name = kv.value_ptr.object.get("Name").?.string;
if (llvm_name.len == 0) continue;
var zig_name = try llvmNameToZigName(arena, llvm_name);
var desc = kv.value_ptr.object.get("Desc").?.string;
var deps = std.ArrayList([]const u8).init(arena);
var omit = false;
var flatten = false;
var omit_deps: []const []const u8 = &.{};
var extra_deps: []const []const u8 = &.{};
for (target.feature_overrides) |feature_override| {
if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
if (feature_override.omit) {
// Still put the feature into the table so that we can
// expand dependencies for the feature overrides marked `flatten`.
omit = true;
}
if (feature_override.flatten) {
flatten = true;
}
if (feature_override.zig_name) |override_name| {
zig_name = override_name;
}
if (feature_override.desc) |override_desc| {
desc = override_desc;
}
omit_deps = feature_override.omit_deps;
extra_deps = feature_override.extra_deps;
break;
}
}
}
// This is used by AArch64.
if (kv.value_ptr.object.get("DefaultExts")) |exts_val| {
for (exts_val.array.items) |ext| {
const other_key = ext.object.get("def").?.string;
const implies = kv.value_ptr.object.get("Implies").?.array;
for (implies.items) |imply| {
const other_key = imply.object.get("def").?.string;
const other_obj = root_map.get(other_key).?.object;
const other_llvm_name = other_obj.get("Name").?.string;
const other_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
llvm_target,
target,
other_llvm_name,
)) orelse continue;
for (omit_deps) |omit_dep| {
@ -1615,118 +1672,141 @@ fn processOneTarget(job: Job) void {
try deps.append(other_zig_name);
}
}
}
for (extra_deps) |extra_dep| {
try deps.append(extra_dep);
}
const feature: Feature = .{
.llvm_name = llvm_name,
.zig_name = zig_name,
.desc = desc,
.deps = deps.items,
.flatten = flatten,
};
try features_table.put(zig_name, feature);
if (!omit and !flatten) {
try all_features.append(feature);
}
}
if (hasSuperclass(&kv.value_ptr.object, "Processor")) {
const llvm_name = kv.value_ptr.object.get("Name").?.string;
if (llvm_name.len == 0) continue;
const omitted = for (llvm_target.omit_cpus) |omit_cpu_name| {
if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;
} else false;
if (omitted) continue;
var zig_name = try llvmNameToZigName(arena, llvm_name);
var deps = std.ArrayList([]const u8).init(arena);
var omit_deps: []const []const u8 = &.{};
var extra_deps: []const []const u8 = &.{};
for (llvm_target.feature_overrides) |feature_override| {
if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
if (feature_override.omit) {
continue;
// This is used by AArch64.
if (kv.value_ptr.object.get("DefaultExts")) |exts_val| {
for (exts_val.array.items) |ext| {
const other_key = ext.object.get("def").?.string;
const other_obj = root_map.get(other_key).?.object;
const other_llvm_name = other_obj.get("Name").?.string;
const other_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
target,
other_llvm_name,
)) orelse continue;
for (omit_deps) |omit_dep| {
if (mem.eql(u8, other_zig_name, omit_dep)) break;
} else {
try deps.append(other_zig_name);
}
}
if (feature_override.zig_name) |override_name| {
zig_name = override_name;
}
omit_deps = feature_override.omit_deps;
extra_deps = feature_override.extra_deps;
break;
}
for (extra_deps) |extra_dep| {
try deps.append(extra_dep);
}
const feature: Feature = .{
.llvm_name = llvm_name,
.zig_name = zig_name,
.desc = desc,
.deps = deps.items,
.flatten = flatten,
};
try features_table.put(zig_name, feature);
if (!omit and !flatten) {
try all_features.append(feature);
}
}
const features = kv.value_ptr.object.get("Features").?.array;
for (features.items) |feature| {
const feature_key = feature.object.get("def").?.string;
const feature_obj = root_map.get(feature_key).?.object;
const feature_llvm_name = feature_obj.get("Name").?.string;
if (feature_llvm_name.len == 0) continue;
const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
llvm_target,
feature_llvm_name,
)) orelse continue;
for (omit_deps) |omit_dep| {
if (mem.eql(u8, feature_zig_name, omit_dep)) break;
} else {
if (hasSuperclass(&kv.value_ptr.object, "Processor")) {
const llvm_name = kv.value_ptr.object.get("Name").?.string;
if (llvm_name.len == 0) continue;
const omitted = for (target.omit_cpus) |omit_cpu_name| {
if (mem.eql(u8, omit_cpu_name, llvm_name)) break true;
} else false;
if (omitted) continue;
var zig_name = try llvmNameToZigName(arena, llvm_name);
var deps = std.ArrayList([]const u8).init(arena);
var omit_deps: []const []const u8 = &.{};
var extra_deps: []const []const u8 = &.{};
for (target.feature_overrides) |feature_override| {
if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
if (feature_override.omit) {
continue;
}
if (feature_override.zig_name) |override_name| {
zig_name = override_name;
}
omit_deps = feature_override.omit_deps;
extra_deps = feature_override.extra_deps;
break;
}
}
const features = kv.value_ptr.object.get("Features").?.array;
for (features.items) |feature| {
const feature_key = feature.object.get("def").?.string;
const feature_obj = root_map.get(feature_key).?.object;
const feature_llvm_name = feature_obj.get("Name").?.string;
if (feature_llvm_name.len == 0) continue;
const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
target,
feature_llvm_name,
)) orelse continue;
for (omit_deps) |omit_dep| {
if (mem.eql(u8, feature_zig_name, omit_dep)) break;
} else {
try deps.append(feature_zig_name);
}
}
for (extra_deps) |extra_dep| {
try deps.append(extra_dep);
}
const tune_features = kv.value_ptr.object.get("TuneFeatures").?.array;
for (tune_features.items) |feature| {
const feature_key = feature.object.get("def").?.string;
const feature_obj = root_map.get(feature_key).?.object;
const feature_llvm_name = feature_obj.get("Name").?.string;
if (feature_llvm_name.len == 0) continue;
const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
target,
feature_llvm_name,
)) orelse continue;
try deps.append(feature_zig_name);
}
}
for (extra_deps) |extra_dep| {
try deps.append(extra_dep);
}
const tune_features = kv.value_ptr.object.get("TuneFeatures").?.array;
for (tune_features.items) |feature| {
const feature_key = feature.object.get("def").?.string;
const feature_obj = root_map.get(feature_key).?.object;
const feature_llvm_name = feature_obj.get("Name").?.string;
if (feature_llvm_name.len == 0) continue;
const feature_zig_name = (try llvmFeatureNameToZigNameOmit(
arena,
llvm_target,
feature_llvm_name,
)) orelse continue;
try deps.append(feature_zig_name);
}
try all_cpus.append(.{
.llvm_name = llvm_name,
.zig_name = zig_name,
.features = deps.items,
});
try all_cpus.append(.{
.llvm_name = llvm_name,
.zig_name = zig_name,
.features = deps.items,
});
if (cpu_aliases.get(zig_name)) |aliases| {
var alias_it = aliases.constIterator(0);
if (cpu_aliases.get(zig_name)) |aliases| {
var alias_it = aliases.constIterator(0);
alias_it: while (alias_it.next()) |alias| {
for (llvm_target.omit_cpus) |omit_cpu_name| {
if (mem.eql(u8, omit_cpu_name, alias.llvm)) continue :alias_it;
alias_it: while (alias_it.next()) |alias| {
for (target.omit_cpus) |omit_cpu_name| {
if (mem.eql(u8, omit_cpu_name, alias.llvm)) continue :alias_it;
}
try all_cpus.append(.{
.llvm_name = alias.llvm,
.zig_name = alias.zig,
.features = deps.items,
});
}
try all_cpus.append(.{
.llvm_name = alias.llvm,
.zig_name = alias.zig,
.features = deps.items,
});
}
}
}
}
collate_progress.end();
}
for (llvm_target.extra_features) |extra_feature| {
for (target.extra_features) |extra_feature| {
try features_table.put(extra_feature.zig_name, extra_feature);
try all_features.append(extra_feature);
}
for (llvm_target.extra_cpus) |extra_cpu| {
for (target.extra_cpus) |extra_cpu| {
try all_cpus.append(extra_cpu);
}
mem.sort(Feature, all_features.items, {}, featureLessThan);
mem.sort(Cpu, all_cpus.items, {}, cpuLessThan);
const render_progress = progress_node.start("rendering Zig code", 0);
var target_dir = try job.zig_src_dir.openDir("lib/std/Target", .{});
defer target_dir.close();
const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{llvm_target.zig_name});
const zig_code_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{target.zig_name});
var zig_code_file = try target_dir.createFile(zig_code_basename, .{});
defer zig_code_file.close();
@ -1760,7 +1840,7 @@ fn processOneTarget(job: Job) void {
\\pub const all_features = blk: {
\\
);
if (llvm_target.branch_quota) |branch_quota| {
if (target.branch_quota) |branch_quota| {
try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota});
}
try w.writeAll(
@ -1941,10 +2021,10 @@ fn llvmNameToZigName(arena: mem.Allocator, llvm_name: []const u8) ![]const u8 {
fn llvmFeatureNameToZigNameOmit(
arena: mem.Allocator,
llvm_target: LlvmTarget,
target: ArchTarget,
llvm_name: []const u8,
) !?[]const u8 {
for (llvm_target.feature_overrides) |feature_override| {
for (target.feature_overrides) |feature_override| {
if (mem.eql(u8, feature_override.llvm_name, llvm_name)) {
if (feature_override.omit) return null;
return feature_override.zig_name orelse break;