From 4e843b4e2b8c7cd48ecbd80a59036f1f72a997ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 4 Oct 2024 23:03:07 +0200 Subject: [PATCH 1/7] llvm: Remove extraneous commas for branch hint metadata in textual IR output. --- src/codegen/llvm/Builder.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index ce4040c127..19c4eebff3 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -9817,9 +9817,9 @@ pub fn printUnbuffered( }); switch (extra.weights) { .none => {}, - .unpredictable => try writer.writeAll(", !unpredictable !{}"), + .unpredictable => try writer.writeAll("!unpredictable !{}"), _ => try writer.print("{}", .{ - try metadata_formatter.fmt(", !prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))), + try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))), }), } }, @@ -10098,9 +10098,9 @@ pub fn printUnbuffered( try writer.writeAll(" ]"); switch (extra.data.weights) { .none => {}, - .unpredictable => try writer.writeAll(", !unpredictable !{}"), + .unpredictable => try writer.writeAll("!unpredictable !{}"), _ => try writer.print("{}", .{ - try metadata_formatter.fmt(", !prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))), + try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))), }), } }, From c9e67e71c146d9a9c217d3f47e75258a1ffeedd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 3 Oct 2024 08:34:19 +0200 Subject: [PATCH 2/7] std.Target: Replace isARM() with isArmOrThumb() and rename it to isArm(). The old isARM() function was a portability trap. With the name it had, it seemed like the obviously correct function to use, but it didn't include Thumb. In the vast majority of cases where someone wants to ask "is the target Arm?", Thumb *should* be included. There are exactly 3 cases in the codebase where we do actually need to exclude Thumb, although one of those is in Aro and mirrors a check in Clang that is itself likely a bug. These rare cases can just add an extra isThumb() check. --- lib/compiler/aro/aro/toolchains/Linux.zig | 2 +- lib/compiler_rt/arm.zig | 8 +++----- lib/compiler_rt/clzsi2_test.zig | 2 +- lib/compiler_rt/common.zig | 2 +- lib/std/Target.zig | 19 ++++++++----------- lib/std/math/gamma.zig | 2 +- lib/std/math/isnan.zig | 2 +- lib/std/os/linux.zig | 4 ++-- lib/std/simd.zig | 2 +- lib/std/start.zig | 2 +- lib/std/zig/system.zig | 2 +- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 6 +++--- src/glibc.zig | 4 ++-- src/libunwind.zig | 2 +- src/link/Coff.zig | 10 ++++------ src/link/Elf.zig | 2 +- test/behavior/cast.zig | 4 ++-- test/behavior/eval.zig | 2 +- test/behavior/floatop.zig | 14 +++++++------- test/behavior/math.zig | 14 +++++++------- test/behavior/maximum_minimum.zig | 2 +- test/behavior/muladd.zig | 8 ++++---- test/behavior/saturating_arithmetic.zig | 4 ++-- test/behavior/struct.zig | 6 +++--- test/behavior/vector.zig | 4 ++-- test/c_abi/main.zig | 6 +++--- 27 files changed, 65 insertions(+), 72 deletions(-) diff --git a/lib/compiler/aro/aro/toolchains/Linux.zig b/lib/compiler/aro/aro/toolchains/Linux.zig index 9666c8e3b0..763222cc98 100644 --- a/lib/compiler/aro/aro/toolchains/Linux.zig +++ b/lib/compiler/aro/aro/toolchains/Linux.zig @@ -40,7 +40,7 @@ fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void { self.extra_opts.appendAssumeCapacity("relro"); } - if (target.cpu.arch.isARM() or target.cpu.arch.isAARCH64() or is_android) { + if ((target.cpu.arch.isArm() and !target.cpu.arch.isThumb()) or target.cpu.arch.isAARCH64() or is_android) { try self.extra_opts.ensureUnusedCapacity(gpa, 2); self.extra_opts.appendAssumeCapacity("-z"); self.extra_opts.appendAssumeCapacity("max-page-size=4096"); diff --git a/lib/compiler_rt/arm.zig b/lib/compiler_rt/arm.zig index e42694b2bf..5a95e9da49 100644 --- a/lib/compiler_rt/arm.zig +++ b/lib/compiler_rt/arm.zig @@ -10,7 +10,7 @@ pub const panic = common.panic; comptime { if (!builtin.is_test) { - if (arch.isArmOrThumb()) { + if (arch.isArm()) { @export(&__aeabi_unwind_cpp_pr0, .{ .name = "__aeabi_unwind_cpp_pr0", .linkage = common.linkage, .visibility = common.visibility }); @export(&__aeabi_unwind_cpp_pr1, .{ .name = "__aeabi_unwind_cpp_pr1", .linkage = common.linkage, .visibility = common.visibility }); @export(&__aeabi_unwind_cpp_pr2, .{ .name = "__aeabi_unwind_cpp_pr2", .linkage = common.linkage, .visibility = common.visibility }); @@ -206,7 +206,7 @@ fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 { } test "__aeabi_frsub" { - if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; + if (!builtin.cpu.arch.isArm() or builtin.cpu.arch.isThumb()) return error.SkipZigTest; const inf32 = std.math.inf(f32); const maxf32 = std.math.floatMax(f32); const frsub_data = [_][3]f32{ @@ -226,14 +226,13 @@ test "__aeabi_frsub" { [_]f32{ maxf32, -maxf32, -inf32 }, [_]f32{ -maxf32, maxf32, inf32 }, }; - if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; for (frsub_data) |data| { try std.testing.expectApproxEqAbs(data[2], __aeabi_frsub(data[0], data[1]), 0.001); } } test "__aeabi_drsub" { - if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; + if (!builtin.cpu.arch.isArm() or builtin.cpu.arch.isThumb()) return error.SkipZigTest; const inf64 = std.math.inf(f64); const maxf64 = std.math.floatMax(f64); const frsub_data = [_][3]f64{ @@ -253,7 +252,6 @@ test "__aeabi_drsub" { [_]f64{ maxf64, -maxf64, -inf64 }, [_]f64{ -maxf64, maxf64, inf64 }, }; - if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; for (frsub_data) |data| { try std.testing.expectApproxEqAbs(data[2], __aeabi_drsub(data[0], data[1]), 0.000001); } diff --git a/lib/compiler_rt/clzsi2_test.zig b/lib/compiler_rt/clzsi2_test.zig index 4fd85edca5..188290e90b 100644 --- a/lib/compiler_rt/clzsi2_test.zig +++ b/lib/compiler_rt/clzsi2_test.zig @@ -268,7 +268,7 @@ test "clzsi2" { try test__clzsi2(0xFE000000, 0); try test__clzsi2(0xFF000000, 0); // arm and thumb1 assume input a != 0 - if (!builtin.cpu.arch.isArmOrThumb()) + if (!builtin.cpu.arch.isArm()) try test__clzsi2(0x00000000, 32); try test__clzsi2(0x00000001, 31); try test__clzsi2(0x00000002, 30); diff --git a/lib/compiler_rt/common.zig b/lib/compiler_rt/common.zig index 3b1f93f1c2..afc3a2e6d9 100644 --- a/lib/compiler_rt/common.zig +++ b/lib/compiler_rt/common.zig @@ -29,7 +29,7 @@ pub const want_aeabi = switch (builtin.abi) { }, else => false, }; -pub const want_mingw_arm_abi = builtin.cpu.arch.isArmOrThumb() and builtin.target.isMinGW(); +pub const want_mingw_arm_abi = builtin.cpu.arch.isArm() and builtin.target.isMinGW(); pub const want_ppc_abi = builtin.cpu.arch.isPowerPC(); diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 4610d11c01..2adbe8e185 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1379,17 +1379,11 @@ pub const Cpu = struct { }; } - pub inline fn isARM(arch: Arch) bool { + /// Note that this includes Thumb. + pub inline fn isArm(arch: Arch) bool { return switch (arch) { .arm, .armeb => true, - else => false, - }; - } - - pub inline fn isAARCH64(arch: Arch) bool { - return switch (arch) { - .aarch64, .aarch64_be => true, - else => false, + else => arch.isThumb(), }; } @@ -1400,8 +1394,11 @@ pub const Cpu = struct { }; } - pub inline fn isArmOrThumb(arch: Arch) bool { - return arch.isARM() or arch.isThumb(); + pub inline fn isAARCH64(arch: Arch) bool { + return switch (arch) { + .aarch64, .aarch64_be => true, + else => false, + }; } pub inline fn isWasm(arch: Arch) bool { diff --git a/lib/std/math/gamma.zig b/lib/std/math/gamma.zig index 5ac041e195..aad2a104cc 100644 --- a/lib/std/math/gamma.zig +++ b/lib/std/math/gamma.zig @@ -263,7 +263,7 @@ test gamma { } test "gamma.special" { - if (builtin.cpu.arch.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .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)))); diff --git a/lib/std/math/isnan.zig b/lib/std/math/isnan.zig index a85100ba90..e05ce452dd 100644 --- a/lib/std/math/isnan.zig +++ b/lib/std/math/isnan.zig @@ -32,7 +32,7 @@ test isSignalNan { // TODO: Signalling NaN values get converted to quiet NaN values in // some cases where they shouldn't such that this can fail. // See https://github.com/ziglang/zig/issues/14366 - if (!builtin.cpu.arch.isArmOrThumb() and + if (!builtin.cpu.arch.isArm() and !builtin.cpu.arch.isAARCH64() and !builtin.cpu.arch.isPowerPC() and builtin.zig_backend != .stage2_c) diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index bccbba5aed..289027aea6 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -506,7 +506,7 @@ fn getauxvalImpl(index: usize) callconv(.C) usize { const require_aligned_register_pair = builtin.cpu.arch.isPowerPC32() or builtin.cpu.arch.isMIPS32() or - builtin.cpu.arch.isArmOrThumb(); + builtin.cpu.arch.isArm(); // Split a 64bit value into a {LSB,MSB} pair. // The LE/BE variants specify the endianness to assume. @@ -2331,7 +2331,7 @@ pub fn process_vm_writev(pid: pid_t, local: []const iovec_const, remote: []const } pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize { - if (comptime native_arch.isArmOrThumb() or native_arch.isPowerPC32()) { + if (comptime native_arch.isArm() or native_arch.isPowerPC32()) { // These architectures reorder the arguments so that a register is not skipped to align the // register number that `offset` is passed in. diff --git a/lib/std/simd.zig b/lib/std/simd.zig index c570c36615..dc2686f460 100644 --- a/lib/std/simd.zig +++ b/lib/std/simd.zig @@ -18,7 +18,7 @@ pub fn suggestVectorLengthForCpu(comptime T: type, comptime cpu: std.Target.Cpu) if (std.Target.x86.featureSetHasAny(cpu.features, .{ .prefer_256_bit, .avx2 }) and !std.Target.x86.featureSetHas(cpu.features, .prefer_128_bit)) break :blk 256; if (std.Target.x86.featureSetHas(cpu.features, .sse)) break :blk 128; if (std.Target.x86.featureSetHasAny(cpu.features, .{ .mmx, .@"3dnow" })) break :blk 64; - } else if (cpu.arch.isArmOrThumb()) { + } else if (cpu.arch.isArm()) { if (std.Target.arm.featureSetHas(cpu.features, .neon)) break :blk 128; } else if (cpu.arch.isAARCH64()) { // SVE allows up to 2048 bits in the specification, as of 2022 the most powerful machine has implemented 512-bit diff --git a/lib/std/start.zig b/lib/std/start.zig index c5664cbf0f..1d1e38654b 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -495,7 +495,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { // ARMv6 targets (and earlier) have no support for TLS in hardware. // FIXME: Elide the check for targets >= ARMv7 when the target feature API // becomes less verbose (and more usable). - if (comptime native_arch.isArmOrThumb()) { + if (comptime native_arch.isArm()) { if (at_hwcap & std.os.linux.HWCAP.TLS == 0) { // FIXME: Make __aeabi_read_tp call the kernel helper kuser_get_tls // For the time being use a simple trap instead of a @panic call to diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 15392d34f1..10b00c0e97 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -401,7 +401,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { } // https://github.com/llvm/llvm-project/issues/105978 - if (result.cpu.arch.isArmOrThumb() and result.floatAbi() == .soft) { + if (result.cpu.arch.isArm() and result.floatAbi() == .soft) { result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2)); } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 4d55637f27..41ec422959 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -5190,7 +5190,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool return switch (constraint[0]) { '{' => true, 'i', 'r' => false, - 'I' => !target.cpu.arch.isArmOrThumb(), + 'I' => !target.cpu.arch.isArm(), else => switch (value) { .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) { .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index fc7d26a815..85a4062ed3 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -494,7 +494,7 @@ const DataLayoutBuilder = struct { if (idx != size) try writer.print(":{d}", .{idx}); } } - if (self.target.cpu.arch.isArmOrThumb()) + if (self.target.cpu.arch.isArm()) try writer.writeAll("-Fi8") // for thumb interwork else if (self.target.cpu.arch == .powerpc64 and self.target.os.tag != .freebsd and @@ -761,7 +761,7 @@ const DataLayoutBuilder = struct { else => {}, } }, - .vector => if (self.target.cpu.arch.isArmOrThumb()) { + .vector => if (self.target.cpu.arch.isArm()) { switch (size) { 128 => abi = 64, else => {}, @@ -827,7 +827,7 @@ const DataLayoutBuilder = struct { else => {}, }, .aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or - self.target.cpu.arch.isArmOrThumb()) + self.target.cpu.arch.isArm()) { pref = @min(pref, self.target.ptrBitWidth()); } else switch (self.target.cpu.arch) { diff --git a/src/glibc.zig b/src/glibc.zig index a7736a9827..9876308aee 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -440,7 +440,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ try result.appendSlice("sparc" ++ s ++ "sparc32"); } } - } else if (arch.isARM()) { + } else if (arch.isArm()) { try result.appendSlice("arm"); } else if (arch.isMIPS()) { if (!mem.eql(u8, basename, "crti.S") and !mem.eql(u8, basename, "crtn.S")) { @@ -604,7 +604,7 @@ fn add_include_dirs_arch( try args.append("-I"); try args.append(try path.join(arena, &[_][]const u8{ dir, "x86" })); } - } else if (arch.isARM()) { + } else if (arch.isArm()) { if (opt_nptl) |nptl| { try args.append("-I"); try args.append(try path.join(arena, &[_][]const u8{ dir, "arm", nptl })); diff --git a/src/libunwind.zig b/src/libunwind.zig index fba604e725..d7b22e2067 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -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.isArmOrThumb() and target.abi.floatAbi() == .hard) { + if (target.cpu.arch.isArm() and target.abi.floatAbi() == .hard) { try cflags.append("-DCOMPILER_RT_ARMHF_TARGET"); } try cflags.append("-Wno-bitwise-conditional-parentheses"); diff --git a/src/link/Coff.zig b/src/link/Coff.zig index bc88f5fc4c..a52892409a 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1865,12 +1865,10 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: try argv.append("-MACHINE:X86"); } else if (target.cpu.arch == .x86_64) { try argv.append("-MACHINE:X64"); - } else if (target.cpu.arch.isARM()) { - if (target.ptrBitWidth() == 32) { - try argv.append("-MACHINE:ARM"); - } else { - try argv.append("-MACHINE:ARM64"); - } + } else if (target.cpu.arch == .thumb) { + try argv.append("-MACHINE:ARM"); + } else if (target.cpu.arch == .aarch64) { + try argv.append("-MACHINE:ARM64"); } for (comp.force_undefined_symbols.keys()) |symbol| { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ccc9e24bf6..1f560d74db 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1823,7 +1823,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s } if (link_mode == .static) { - if (target.cpu.arch.isArmOrThumb()) { + if (target.cpu.arch.isArm()) { try argv.append("-Bstatic"); } else { try argv.append("-static"); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index efc7d4237f..3a9b5157a4 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -124,7 +124,7 @@ test "@floatFromInt(f80)" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; @@ -1362,7 +1362,7 @@ test "cast f16 to wider types" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 4085e4c47d..da39b06d92 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -522,7 +522,7 @@ test "runtime 128 bit integer division" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 69dacb66fd..72b773b76c 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -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.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .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.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 try testCmp(f32); try comptime testCmp(f32); @@ -146,7 +146,7 @@ test "cmp f32/f64" { test "cmp f128" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; 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; @@ -1009,7 +1009,7 @@ test "@abs f32/f64" { test "@abs f80/f128/c_longdouble" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; 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.zig_backend == .stage2_spirv64) return error.SkipZigTest; @@ -1134,7 +1134,7 @@ test "@floor f32/f64" { test "@floor f80/f128/c_longdouble" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; 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.zig_backend == .stage2_spirv64) return error.SkipZigTest; @@ -1232,7 +1232,7 @@ test "@ceil f32/f64" { test "@ceil f80/f128/c_longdouble" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; 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.zig_backend == .stage2_spirv64) return error.SkipZigTest; @@ -1330,7 +1330,7 @@ test "@trunc f32/f64" { test "@trunc f80/f128/c_longdouble" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest; 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.zig_backend == .stage2_spirv64) return error.SkipZigTest; diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 07dd133fe4..21f09a877f 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -780,7 +780,7 @@ test "128-bit multiplication" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 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_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; { @@ -1369,7 +1369,7 @@ test "remainder division" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 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_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { @@ -1522,7 +1522,7 @@ test "@round f80" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; @@ -1535,7 +1535,7 @@ test "@round f128" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; @@ -1579,7 +1579,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.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 try testNanEqNan(f16); try testNanEqNan(f32); @@ -1735,7 +1735,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.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 const S = struct { fn doTheTest(comptime F: type, x: F) void { @@ -1766,7 +1766,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.isArmOrThumb() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 + if (builtin.cpu.arch.isArm() and builtin.target.floatAbi() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234 const S = struct { fn doTheTest(comptime F: type, x: u32) void { diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig index 8994d9d182..d7d494a9ad 100644 --- a/test/behavior/maximum_minimum.zig +++ b/test/behavior/maximum_minimum.zig @@ -122,7 +122,7 @@ test "@min/max for floats" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; diff --git a/test/behavior/muladd.zig b/test/behavior/muladd.zig index 7b45cc9b72..ec07f203ec 100644 --- a/test/behavior/muladd.zig +++ b/test/behavior/muladd.zig @@ -58,7 +58,7 @@ test "@mulAdd f80" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; @@ -79,7 +79,7 @@ test "@mulAdd f128" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) 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; @@ -189,7 +189,7 @@ test "vector f80" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try comptime vector80(); @@ -216,7 +216,7 @@ test "vector f128" { 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_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; try comptime vector128(); diff --git a/test/behavior/saturating_arithmetic.zig b/test/behavior/saturating_arithmetic.zig index 3e41e2fa3f..ea3d51f3e6 100644 --- a/test/behavior/saturating_arithmetic.zig +++ b/test/behavior/saturating_arithmetic.zig @@ -164,7 +164,7 @@ test "saturating multiplication <= 32 bits" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { @@ -264,7 +264,7 @@ test "saturating multiplication" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) { diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 283c8dbc4a..b45fa171cb 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -419,7 +419,7 @@ test "packed struct 24bits" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO - if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO + if (comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; @@ -818,7 +818,7 @@ test "non-packed struct with u128 entry in union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; const U = union(enum) { @@ -941,7 +941,7 @@ test "tuple assigned to variable" { test "comptime struct field" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO + if (comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; // TODO const T = struct { a: i32, diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index 666c45b741..a2826617f8 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -101,7 +101,7 @@ test "vector float operators" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) { @@ -753,7 +753,7 @@ test "vector reduce operation" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArm()) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21091 diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index 09b5011665..f18fa4b3d5 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -10,7 +10,7 @@ const builtin = @import("builtin"); const print = std.debug.print; const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; -const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isARM() and +const have_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPowerPC32(); const have_f128 = builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin(); @@ -181,7 +181,7 @@ extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat; extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isMIPS() and - !builtin.cpu.arch.isARM() and !builtin.cpu.arch.isPowerPC32() and !builtin.cpu.arch.isRISCV(); + !builtin.cpu.arch.isArm() and !builtin.cpu.arch.isPowerPC32() and !builtin.cpu.arch.isRISCV(); test "C ABI complex float" { if (!complex_abi_compatible) return error.SkipZigTest; @@ -5553,7 +5553,7 @@ extern fn c_f16_struct(f16_struct) f16_struct; test "f16 struct" { if (builtin.target.cpu.arch.isMIPS64()) return error.SkipZigTest; if (builtin.target.cpu.arch.isPowerPC32()) return error.SkipZigTest; - if (builtin.cpu.arch.isARM() and builtin.mode != .Debug) return error.SkipZigTest; + if (builtin.cpu.arch.isArm() and builtin.mode != .Debug) return error.SkipZigTest; const a = c_f16_struct(.{ .a = 12 }); try expect(a.a == 34); From 39abcc303c471c0180cdb0f5dce4303bbbe45362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 4 Oct 2024 20:25:13 +0200 Subject: [PATCH 3/7] Compilation: Pass -fno-PIC to clang if PIC is disabled. Let's not implicitly rely on whatever Clang's default is. --- src/Compilation.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 7777aa1371..7c08b74b04 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5628,8 +5628,8 @@ pub fn addCCArgs( try argv.append("-mthumb"); } - if (target_util.supports_fpic(target) and mod.pic) { - try argv.append("-fPIC"); + if (target_util.supports_fpic(target)) { + try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC"); } try argv.ensureUnusedCapacity(2); From 4c70aea460d0cf4a5c1f77ec662837680e272220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 2 Nov 2024 11:18:52 +0100 Subject: [PATCH 4/7] Compilation: Use the regular module mechanism for setting PIC on CRT objects. addCCArgs() will then pass the appropriate flag to Clang. --- src/Compilation.zig | 4 +++- src/glibc.zig | 8 ++++---- src/mingw.zig | 6 +++--- src/musl.zig | 14 ++++++-------- src/wasi_libc.zig | 14 +++++++------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 7c08b74b04..6d7097e5fa 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -6266,6 +6266,7 @@ pub fn build_crt_file( comp: *Compilation, root_name: []const u8, output_mode: std.builtin.OutputMode, + pic: ?bool, misc_task_tag: MiscTask, prog_node: std.Progress.Node, /// These elements have to get mutated to add the owner module after it is @@ -6318,7 +6319,8 @@ pub fn build_crt_file( .omit_frame_pointer = comp.root_mod.omit_frame_pointer, .valgrind = false, .unwind_tables = false, - .pic = comp.root_mod.pic, + // Some CRT objects (rcrt1.o, Scrt1.o) are opinionated about PIC. + .pic = pic orelse comp.root_mod.pic, .optimize_mode = comp.compilerRtOptMode(), .structured_cfg = comp.root_mod.structured_cfg, }, diff --git a/src/glibc.zig b/src/glibc.zig index 9876308aee..588c3af004 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -221,7 +221,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = comp.root_mod, }, }; - return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &files); + return comp.build_crt_file("crti", .Obj, null, .@"glibc crti.o", prog_node, &files); }, .crtn_o => { var args = std.ArrayList([]const u8).init(arena); @@ -242,7 +242,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }, }; - return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &files); + return comp.build_crt_file("crtn", .Obj, null, .@"glibc crtn.o", prog_node, &files); }, .scrt1_o => { const start_o: Compilation.CSourceFile = blk: { @@ -295,7 +295,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre }; var files = [_]Compilation.CSourceFile{ start_o, abi_note_o, init_o }; const basename = if (comp.config.output_mode == .Exe and !comp.config.pie) "crt1" else "Scrt1"; - return comp.build_crt_file(basename, .Obj, .@"glibc Scrt1.o", prog_node, &files); + return comp.build_crt_file(basename, .Obj, null, .@"glibc Scrt1.o", prog_node, &files); }, .libc_nonshared_a => { const s = path.sep_str; @@ -413,7 +413,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre files_index += 1; } const files = files_buf[0..files_index]; - return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files); + return comp.build_crt_file("c_nonshared", .Lib, null, .@"glibc libc_nonshared.a", prog_node, files); }, } } diff --git a/src/mingw.zig b/src/mingw.zig index 154a3cb375..d4ef1ac5a7 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -41,7 +41,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }, }; - return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files); + return comp.build_crt_file("crt2", .Obj, null, .@"mingw-w64 crt2.o", prog_node, &files); }, .dllcrt2_o => { @@ -56,7 +56,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }, }; - return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files); + return comp.build_crt_file("dllcrt2", .Obj, null, .@"mingw-w64 dllcrt2.o", prog_node, &files); }, .mingw32_lib => { @@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre } else { @panic("unsupported arch"); } - return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items); + return comp.build_crt_file("mingw32", .Lib, null, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items); }, } } diff --git a/src/musl.zig b/src/musl.zig index 975929a59d..b07fdf1ee6 100644 --- a/src/musl.zig +++ b/src/musl.zig @@ -39,7 +39,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }, }; - return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &files); + return comp.build_crt_file("crti", .Obj, null, .@"musl crti.o", prog_node, &files); }, .crtn_o => { var args = std.ArrayList([]const u8).init(arena); @@ -51,7 +51,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }, }; - return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &files); + return comp.build_crt_file("crtn", .Obj, null, .@"musl crtn.o", prog_node, &files); }, .crt1_o => { var args = std.ArrayList([]const u8).init(arena); @@ -69,13 +69,12 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }, }; - return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &files); + return comp.build_crt_file("crt1", .Obj, null, .@"musl crt1.o", prog_node, &files); }, .rcrt1_o => { var args = std.ArrayList([]const u8).init(arena); try addCcArgs(comp, arena, &args, false); try args.appendSlice(&[_][]const u8{ - "-fPIC", "-fno-stack-protector", "-DCRT", }); @@ -88,13 +87,12 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }, }; - return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &files); + return comp.build_crt_file("rcrt1", .Obj, true, .@"musl rcrt1.o", prog_node, &files); }, .scrt1_o => { var args = std.ArrayList([]const u8).init(arena); try addCcArgs(comp, arena, &args, false); try args.appendSlice(&[_][]const u8{ - "-fPIC", "-fno-stack-protector", "-DCRT", }); @@ -107,7 +105,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }, }; - return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &files); + return comp.build_crt_file("Scrt1", .Obj, true, .@"musl Scrt1.o", prog_node, &files); }, .libc_a => { // When there is a src//foo.* then it should substitute for src/foo.* @@ -190,7 +188,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro .owner = undefined, }; } - return comp.build_crt_file("c", .Lib, .@"musl libc.a", prog_node, c_source_files.items); + return comp.build_crt_file("c", .Lib, null, .@"musl libc.a", prog_node, c_source_files.items); }, .libc_so => { const optimize_mode = comp.compilerRtOptMode(); diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index ce94110b69..3b9d9c5446 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }, }; - return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files); + return comp.build_crt_file("crt1-reactor", .Obj, null, .@"wasi crt1-reactor.o", prog_node, &files); }, .crt1_command_o => { var args = std.ArrayList([]const u8).init(arena); @@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }, }; - return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files); + return comp.build_crt_file("crt1-command", .Obj, null, .@"wasi crt1-command.o", prog_node, &files); }, .libc_a => { var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena); @@ -150,7 +150,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre } } - try comp.build_crt_file("c", .Lib, .@"wasi libc.a", prog_node, libc_sources.items); + try comp.build_crt_file("c", .Lib, null, .@"wasi libc.a", prog_node, libc_sources.items); }, .libwasi_emulated_process_clocks_a => { var args = std.ArrayList([]const u8).init(arena); @@ -167,7 +167,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }); } - try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items); + try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, null, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items); }, .libwasi_emulated_getpid_a => { var args = std.ArrayList([]const u8).init(arena); @@ -184,7 +184,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }); } - try comp.build_crt_file("wasi-emulated-getpid", .Lib, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items); + try comp.build_crt_file("wasi-emulated-getpid", .Lib, null, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items); }, .libwasi_emulated_mman_a => { var args = std.ArrayList([]const u8).init(arena); @@ -201,7 +201,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre .owner = undefined, }); } - try comp.build_crt_file("wasi-emulated-mman", .Lib, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items); + try comp.build_crt_file("wasi-emulated-mman", .Lib, null, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items); }, .libwasi_emulated_signal_a => { var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena); @@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre } } - try comp.build_crt_file("wasi-emulated-signal", .Lib, .@"libwasi-emulated-signal.a", prog_node, emu_signal_sources.items); + try comp.build_crt_file("wasi-emulated-signal", .Lib, null, .@"libwasi-emulated-signal.a", prog_node, emu_signal_sources.items); }, } } From 3a2647b7d3b68fe32bab488f1fa8eaa1ec57f31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 2 Nov 2024 11:58:23 +0100 Subject: [PATCH 5/7] glibc: Don't build CRT objects that won't be used. --- src/Compilation.zig | 4 ++-- src/glibc.zig | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 6d7097e5fa..51877d7973 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1795,8 +1795,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil .{ .glibc_crt_file = .crtn_o }, }); } - if (!is_dyn_lib) { - try comp.queueJob(.{ .glibc_crt_file = .scrt1_o }); + if (glibc.needsCrt0(comp.config.output_mode)) |f| { + try comp.queueJobs(&.{.{ .glibc_crt_file = f }}); } try comp.queueJobs(&[_]Job{ .{ .glibc_shared_objects = {} }, diff --git a/src/glibc.zig b/src/glibc.zig index 588c3af004..df37deed64 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -1357,3 +1357,10 @@ pub fn needsCrtiCrtn(target: std.Target) bool { else => true, }; } + +pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile { + return switch (output_mode) { + .Obj, .Lib => null, + .Exe => .scrt1_o, + }; +} From d89cf3e7d86e21cd418795d1c0f0057f6d6eb60b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 5 Oct 2024 02:25:13 +0200 Subject: [PATCH 6/7] test: Add the ability to skip specific modules for a target. --- test/tests.zig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/tests.zig b/test/tests.zig index a9035560b3..32e618d939 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -28,6 +28,7 @@ const TestTarget = struct { use_lld: ?bool = null, pic: ?bool = null, strip: ?bool = null, + skip_modules: []const []const u8 = &.{}, // This is intended for targets that are known to be slow to compile. These are acceptable to // run in CI, but should not be run on developer machines by default. As an example, at the time @@ -1225,7 +1226,13 @@ const ModuleTestOptions = struct { pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { const step = b.step(b.fmt("test-{s}", .{options.name}), options.desc); - for (test_targets) |test_target| { + for_targets: for (test_targets) |test_target| { + if (test_target.skip_modules.len > 0) { + for (test_target.skip_modules) |skip_mod| { + if (std.mem.eql(u8, options.name, skip_mod)) continue :for_targets; + } + } + if (!options.test_slow_targets and test_target.slow_backend) continue; if (options.skip_non_native and !test_target.target.isNative()) From 621487d5abcf9006b3e38f96c49a533c1835e7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 5 Oct 2024 02:25:59 +0200 Subject: [PATCH 7/7] test: Add thumb-linux-(musl)eabi(hf) target triples for module tests. --- test/tests.zig | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test/tests.zig b/test/tests.zig index 32e618d939..49a196744d 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -338,6 +338,70 @@ const test_targets = blk: { .link_libc = true, }, + .{ + .target = .{ + .cpu_arch = .thumb, + .os_tag = .linux, + .abi = .eabi, + }, + }, + .{ + .target = .{ + .cpu_arch = .thumb, + .os_tag = .linux, + .abi = .eabihf, + }, + }, + .{ + .target = .{ + .cpu_arch = .thumb, + .os_tag = .linux, + .abi = .musleabi, + }, + .link_libc = true, + .skip_modules = &.{"std"}, + }, + .{ + .target = .{ + .cpu_arch = .thumb, + .os_tag = .linux, + .abi = .musleabihf, + }, + .link_libc = true, + .skip_modules = &.{"std"}, + }, + // Calls are normally lowered to branch instructions that only support +/- 16 MB range when + // targeting Thumb. This is not sufficient for the std test binary linked statically with + // musl, so use long calls to avoid out-of-range relocations. + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "thumb-linux-musleabi", + .cpu_features = "baseline+long_calls", + }) catch @panic("OOM"), + .link_libc = true, + .pic = false, // Long calls don't work with PIC. + .skip_modules = &.{ + "behavior", + "c-import", + "compiler-rt", + "universal-libc", + }, + }, + .{ + .target = std.Target.Query.parse(.{ + .arch_os_abi = "thumb-linux-musleabihf", + .cpu_features = "baseline+long_calls", + }) catch @panic("OOM"), + .link_libc = true, + .pic = false, // Long calls don't work with PIC. + .skip_modules = &.{ + "behavior", + "c-import", + "compiler-rt", + "universal-libc", + }, + }, + .{ .target = .{ .cpu_arch = .mips,