diff --git a/build.zig b/build.zig index 4d3cf492bd..e9f0b69400 100644 --- a/build.zig +++ b/build.zig @@ -445,6 +445,9 @@ pub fn build(b: *Builder) !void { false, // skip_single_threaded skip_non_native, skip_libc, + skip_stage1, + omit_stage2, + is_stage1, )); toolchain_step.dependOn(tests.addPkgTests( @@ -457,6 +460,9 @@ pub fn build(b: *Builder) !void { true, // skip_single_threaded skip_non_native, true, // skip_libc + skip_stage1, + omit_stage2 or true, // TODO get these all passing + is_stage1, )); toolchain_step.dependOn(tests.addPkgTests( @@ -469,6 +475,9 @@ pub fn build(b: *Builder) !void { true, // skip_single_threaded skip_non_native, true, // skip_libc + skip_stage1, + omit_stage2 or true, // TODO get these all passing + is_stage1, )); toolchain_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes)); @@ -494,6 +503,9 @@ pub fn build(b: *Builder) !void { false, skip_non_native, skip_libc, + skip_stage1, + omit_stage2 or true, // TODO get these all passing + is_stage1, ); const test_step = b.step("test", "Run all the tests"); diff --git a/ci/azure/macos_script b/ci/azure/macos_script index b163afe3b3..e8c7c69a33 100755 --- a/ci/azure/macos_script +++ b/ci/azure/macos_script @@ -58,12 +58,25 @@ make $JOBS install # Build stage2 standalone so that we can test stage2 against stage2 compiler-rt. release/bin/zig build -p stage2 -Denable-llvm -stage2/bin/zig test ../test/behavior.zig -I../test -fLLVM -stage2/bin/zig test ../test/behavior.zig -I../test -fno-LLVM +stage2/bin/zig build test-behavior -release/bin/zig build test-toolchain -Denable-macos-sdk -release/bin/zig build test-std -release/bin/zig build docs +# TODO: upgrade these to test stage2 instead of stage1 +# TODO: upgrade these to test stage3 instead of stage2 +release/bin/zig build test-behavior -Denable-macos-sdk -Domit-stage2 +release/bin/zig build test-compiler-rt -Denable-macos-sdk +release/bin/zig build test-std -Denable-macos-sdk +release/bin/zig build test-minilibc -Denable-macos-sdk +release/bin/zig build test-compare-output -Denable-macos-sdk +release/bin/zig build test-standalone -Denable-macos-sdk +release/bin/zig build test-stack-traces -Denable-macos-sdk +release/bin/zig build test-cli -Denable-macos-sdk +release/bin/zig build test-asm-link -Denable-macos-sdk +release/bin/zig build test-runtime-safety -Denable-macos-sdk +release/bin/zig build test-translate-c -Denable-macos-sdk +release/bin/zig build test-run-translated-c -Denable-macos-sdk +release/bin/zig build docs -Denable-macos-sdk +release/bin/zig build test-fmt -Denable-macos-sdk +release/bin/zig build test-stage2 -Denable-macos-sdk if [ "${BUILD_REASON}" != "PullRequest" ]; then mv ../LICENSE release/ diff --git a/ci/zinc/linux_test.sh b/ci/zinc/linux_test.sh index 180589cc8e..01aee9a502 100755 --- a/ci/zinc/linux_test.sh +++ b/ci/zinc/linux_test.sh @@ -48,25 +48,19 @@ cd $WORKSPACE $ZIG fmt --check . --exclude test/cases/ # Build stage2 standalone so that we can test stage2 against stage2 compiler-rt. -$ZIG build -p stage2 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL" +$ZIG build -p stage2 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL" # Ensure that stage2 can build itself. -./stage2/bin/zig build -p stage3 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL" +stage2/bin/zig build -p stage3 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL" +stage2/bin/zig build # test building self-hosted without LLVM +stage2/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm -stage2/bin/zig test test/behavior.zig -I test -fLLVM -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -stage2/bin/zig test test/behavior.zig -I test -fLLVM -target aarch64-linux --test-cmd qemu-aarch64 --test-cmd-bin -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -target aarch64-linux --test-cmd qemu-aarch64 --test-cmd-bin -stage2/bin/zig test test/behavior.zig -I test -ofmt=c -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -target wasm32-wasi --test-cmd wasmtime --test-cmd-bin -stage2/bin/zig test test/behavior.zig -I test -fLLVM -target wasm32-wasi --test-cmd wasmtime --test-cmd-bin -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -target arm-linux --test-cmd qemu-arm --test-cmd-bin -stage2/bin/zig test test/behavior.zig -I test -fLLVM -target aarch64-macos --test-no-exec -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -target aarch64-macos --test-no-exec -stage2/bin/zig test test/behavior.zig -I test -fLLVM -target x86_64-macos --test-no-exec -stage2/bin/zig test test/behavior.zig -I test -fno-LLVM -target x86_64-macos --test-no-exec +# Here we use stage2 instead of stage3 because of two bugs remaining: +# * https://github.com/ziglang/zig/issues/11367 (and corresponding workaround in compiler source) +# * https://github.com/ziglang/zig/pull/11492#issuecomment-1112871321 +stage2/bin/zig build test-behavior -fqemu -fwasmtime -$ZIG build test-behavior -fqemu -fwasmtime +$ZIG build test-behavior -fqemu -fwasmtime -Domit-stage2 $ZIG build test-compiler-rt -fqemu -fwasmtime $ZIG build test-std -fqemu -fwasmtime $ZIG build test-minilibc -fqemu -fwasmtime @@ -79,8 +73,6 @@ $ZIG build test-runtime-safety -fqemu -fwasmtime $ZIG build test-translate-c -fqemu -fwasmtime $ZIG build test-run-translated-c -fqemu -fwasmtime $ZIG build docs -fqemu -fwasmtime -$ZIG build # test building self-hosted without LLVM -$ZIG build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm $ZIG build test-fmt -fqemu -fwasmtime $ZIG build test-stage2 -fqemu -fwasmtime diff --git a/lib/std/build.zig b/lib/std/build.zig index 38744cea1e..b50678a0e5 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1590,6 +1590,8 @@ pub const LibExeObjStep = struct { want_lto: ?bool = null, use_stage1: ?bool = null, + use_llvm: ?bool = null, + ofmt: ?std.Target.ObjectFormat = null, output_path_source: GeneratedFile, output_lib_path_source: GeneratedFile, @@ -2351,6 +2353,18 @@ pub const LibExeObjStep = struct { } } + if (self.use_llvm) |use_llvm| { + if (use_llvm) { + try zig_args.append("-fLLVM"); + } else { + try zig_args.append("-fno-LLVM"); + } + } + + if (self.ofmt) |ofmt| { + try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-ofmt={s}", .{@tagName(ofmt)})); + } + if (self.entry_symbol_name) |entry| { try zig_args.append("--entry"); try zig_args.append(entry); diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig index 613957fa25..7f4a7385f2 100644 --- a/lib/std/os/linux/arm-eabi.zig +++ b/lib/std/os/linux/arm-eabi.zig @@ -99,7 +99,10 @@ pub fn syscall6( /// This matches the libc clone function. pub extern fn clone( - func: fn (arg: usize) callconv(.C) u8, + func: switch (@import("builtin").zig_backend) { + .stage1 => fn (arg: usize) callconv(.C) u8, + else => *const fn (arg: usize) callconv(.C) u8, + }, stack: usize, flags: u32, arg: usize, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 426ef7c378..800786891e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4234,36 +4234,103 @@ pub const FuncGen = struct { return null; const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand = try self.resolveInst(ty_op.operand); const operand_ty = self.air.typeOf(ty_op.operand); const operand_scalar_ty = operand_ty.scalarType(); - const dest_ty = self.air.typeOfIndex(inst); - const dest_llvm_ty = try self.dg.llvmType(dest_ty); - if (operand_scalar_ty.isSignedInt()) { - return self.builder.buildSIToFP(operand, dest_llvm_ty, ""); - } else { - return self.builder.buildUIToFP(operand, dest_llvm_ty, ""); + const dest_ty = self.air.typeOfIndex(inst); + const dest_scalar_ty = dest_ty.scalarType(); + const dest_llvm_ty = try self.dg.llvmType(dest_ty); + const target = self.dg.module.getTarget(); + + if (intrinsicsAllowed(dest_scalar_ty, target)) { + if (operand_scalar_ty.isSignedInt()) { + return self.builder.buildSIToFP(operand, dest_llvm_ty, ""); + } else { + return self.builder.buildUIToFP(operand, dest_llvm_ty, ""); + } } + + const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target)); + const rt_int_bits = compilerRtIntBits(operand_bits); + const rt_int_ty = self.context.intType(rt_int_bits); + const extended = e: { + if (operand_scalar_ty.isSignedInt()) { + break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, ""); + } else { + break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, ""); + } + }; + const dest_bits = dest_scalar_ty.floatBits(target); + const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); + const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); + const sign_prefix = if (operand_scalar_ty.isSignedInt()) "" else "un"; + var fn_name_buf: [64]u8 = undefined; + const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{ + sign_prefix, + compiler_rt_operand_abbrev, + compiler_rt_dest_abbrev, + }) catch unreachable; + const param_types = [1]*const llvm.Type{rt_int_ty}; + const libc_fn = self.getLibcFunction(fn_name, ¶m_types, dest_llvm_ty); + const params = [1]*const llvm.Value{extended}; + + return self.builder.buildCall(libc_fn, ¶ms, params.len, .C, .Auto, ""); } fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { if (self.liveness.isUnused(inst)) return null; + const target = self.dg.module.getTarget(); const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand = try self.resolveInst(ty_op.operand); + const operand_ty = self.air.typeOf(ty_op.operand); + const operand_scalar_ty = operand_ty.scalarType(); + const dest_ty = self.air.typeOfIndex(inst); const dest_scalar_ty = dest_ty.scalarType(); const dest_llvm_ty = try self.dg.llvmType(dest_ty); - // TODO set fast math flag - - if (dest_scalar_ty.isSignedInt()) { - return self.builder.buildFPToSI(operand, dest_llvm_ty, ""); - } else { - return self.builder.buildFPToUI(operand, dest_llvm_ty, ""); + if (intrinsicsAllowed(operand_scalar_ty, target)) { + // TODO set fast math flag + if (dest_scalar_ty.isSignedInt()) { + return self.builder.buildFPToSI(operand, dest_llvm_ty, ""); + } else { + return self.builder.buildFPToUI(operand, dest_llvm_ty, ""); + } } + + const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(target))); + const libc_ret_ty = self.context.intType(rt_int_bits); + + const operand_bits = operand_scalar_ty.floatBits(target); + const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); + + const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); + const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "un"; + + var fn_name_buf: [64]u8 = undefined; + const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{ + sign_prefix, + compiler_rt_operand_abbrev, + compiler_rt_dest_abbrev, + }) catch unreachable; + + const operand_llvm_ty = try self.dg.llvmType(operand_ty); + const param_types = [1]*const llvm.Type{operand_llvm_ty}; + const libc_fn = self.getLibcFunction(fn_name, ¶m_types, libc_ret_ty); + const params = [1]*const llvm.Value{operand}; + + const result = self.builder.buildCall(libc_fn, ¶ms, params.len, .C, .Auto, ""); + + if (libc_ret_ty == dest_llvm_ty) { + return result; + } + + return self.builder.buildTrunc(result, dest_llvm_ty, ""); } fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { @@ -5615,6 +5682,16 @@ pub const FuncGen = struct { }; } + fn compilerRtIntAbbrev(bits: u16) []const u8 { + return switch (bits) { + 16 => "h", + 32 => "s", + 64 => "d", + 128 => "t", + else => "o", // Non-standard + }; + } + /// Creates a floating point comparison by lowering to the appropriate /// hardware instruction or softfloat routine for the target fn buildFloatCmp( @@ -8313,3 +8390,12 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool { } return false; } + +fn compilerRtIntBits(bits: u16) u16 { + inline for (.{ 8, 16, 32, 64, 128 }) |b| { + if (bits <= b) { + return b; + } + } + return bits; +} diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 4732e0dd49..c70a7d1553 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -476,6 +476,14 @@ pub const Builder = opaque { Name: [*:0]const u8, ) *const Value; + pub const buildSExtOrBitCast = LLVMBuildSExtOrBitCast; + extern fn LLVMBuildSExtOrBitCast( + *const Builder, + Val: *const Value, + DestTy: *const Type, + Name: [*:0]const u8, + ) *const Value; + pub const buildCall = ZigLLVMBuildCall; extern fn ZigLLVMBuildCall( *const Builder, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7caccb1fb8..fa110f28cc 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -392,8 +392,9 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator // ABI such as aarch64-ios-simulator, etc. const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator); + const use_llvm = build_options.have_llvm and options.use_llvm; const use_stage1 = build_options.is_stage1 and options.use_stage1; - const needs_prealloc = !(use_stage1 or options.cache_mode == .whole); + const needs_prealloc = !(use_stage1 or use_llvm or options.cache_mode == .whole); const self = try gpa.create(MachO); errdefer gpa.destroy(self); @@ -410,7 +411,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { .needs_prealloc = needs_prealloc, }; - const use_llvm = build_options.have_llvm and options.use_llvm; if (use_llvm and !use_stage1) { self.llvm_object = try LlvmObject.create(gpa, options); } @@ -519,7 +519,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No var needs_full_relink = true; cache: { - if (use_stage1 and self.base.options.disable_lld_caching) break :cache; + if ((use_stage1 and self.base.options.disable_lld_caching) or self.base.options.cache_mode == .whole) + break :cache; man = comp.cache_parent.obtain(); @@ -571,7 +572,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No if (mem.eql(u8, prev_digest, &digest)) { // Hot diggity dog! The output binary is already there. - if (use_stage1) { + const use_llvm = build_options.have_llvm and self.base.options.use_llvm; + if (use_llvm or use_stage1) { log.debug("MachO Zld digest={s} match - skipping invocation", .{std.fmt.fmtSliceHexLower(&digest)}); self.base.lock = man.toOwnedLock(); return; @@ -1025,7 +1027,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.createTentativeDefAtoms(); try self.parseObjectsIntoAtoms(); - if (use_stage1) { + const use_llvm = build_options.have_llvm and self.base.options.use_llvm; + if (use_llvm or use_stage1) { try self.sortSections(); try self.allocateTextSegment(); try self.allocateDataConstSegment(); @@ -1041,7 +1044,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No self.logSectionOrdinals(); } - if (use_stage1) { + if (use_llvm or use_stage1) { try self.writeAllAtoms(); } else { try self.writeAtoms(); @@ -1097,7 +1100,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No } cache: { - if (use_stage1 and self.base.options.disable_lld_caching) break :cache; + if ((use_stage1 and self.base.options.disable_lld_caching) or self.base.options.cache_mode == .whole) + break :cache; // Update the file with the digest. If it fails we can continue; it only // means that the next invocation will have an unnecessary cache miss. Cache.writeSmallFile(cache_dir_handle, id_symlink_basename, &digest) catch |err| { @@ -4930,12 +4934,13 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { var start: u64 = offset; for (seg.sections.items) |*sect, sect_id| { const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL; + const use_llvm = build_options.have_llvm and self.base.options.use_llvm; const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; const alignment = try math.powi(u32, 2, sect.@"align"); const start_aligned = mem.alignForwardGeneric(u64, start, alignment); // TODO handle zerofill sections in stage2 - sect.offset = if (is_zerofill and use_stage1) 0 else @intCast(u32, seg.inner.fileoff + start_aligned); + sect.offset = if (is_zerofill and (use_stage1 or use_llvm)) 0 else @intCast(u32, seg.inner.fileoff + start_aligned); sect.addr = seg.inner.vmaddr + start_aligned; // Recalculate section size given the allocated start address @@ -4963,7 +4968,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { start = start_aligned + sect.size; - if (!(is_zerofill and use_stage1)) { + if (!(is_zerofill and (use_stage1 or use_llvm))) { seg.inner.filesize = start; } seg.inner.vmsize = start; @@ -5012,10 +5017,11 @@ fn initSection( sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff; const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL; + const use_llvm = build_options.have_llvm and self.base.options.use_llvm; const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; // TODO handle zerofill in stage2 - if (!(is_zerofill and use_stage1)) { + if (!(is_zerofill and (use_stage1 or use_llvm))) { sect.offset = @intCast(u32, off); } } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index a1bd41e7b0..416c7914e7 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -112,6 +112,42 @@ test "@intToFloat" { comptime try S.doTheTest(); } +test "@intToFloat(f80)" { + if (builtin.zig_backend == .stage1) return error.SkipZigTest; + + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest(comptime Int: type) !void { + try testIntToFloat(Int, -2); + } + + fn testIntToFloat(comptime Int: type, k: Int) !void { + const f = @intToFloat(f80, k); + const i = @floatToInt(Int, f); + try expect(i == k); + } + }; + try S.doTheTest(i31); + try S.doTheTest(i32); + try S.doTheTest(i45); + try S.doTheTest(i64); + try S.doTheTest(i80); + try S.doTheTest(i128); + // try S.doTheTest(i256); // TODO missing compiler_rt symbols + comptime try S.doTheTest(i31); + comptime try S.doTheTest(i32); + comptime try S.doTheTest(i45); + comptime try S.doTheTest(i64); + comptime try S.doTheTest(i80); + comptime try S.doTheTest(i128); + comptime try S.doTheTest(i256); +} + test "@floatToInt" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/tests.zig b/test/tests.zig index ee4b922021..62c437e7f7 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -34,6 +34,7 @@ const TestTarget = struct { link_libc: bool = false, single_threaded: bool = false, disable_native: bool = false, + backend: ?std.builtin.CompilerBackend = null, }; const test_targets = blk: { @@ -42,15 +43,73 @@ const test_targets = blk: { // lot of branches) @setEvalBranchQuota(50000); break :blk [_]TestTarget{ - TestTarget{}, - TestTarget{ + .{}, + .{ .link_libc = true, }, - TestTarget{ + .{ .single_threaded = true, }, - TestTarget{ + .{ + .link_libc = true, + .backend = .stage2_c, + }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .linux, + .abi = .none, + }, + .backend = .stage2_x86_64, + }, + .{ + .target = .{ + .cpu_arch = .aarch64, + .os_tag = .linux, + }, + .backend = .stage2_aarch64, + }, + .{ + .target = .{ + .cpu_arch = .wasm32, + .os_tag = .wasi, + }, + .single_threaded = true, + .backend = .stage2_wasm, + }, + .{ + .target = .{ + .cpu_arch = .arm, + .os_tag = .linux, + }, + .backend = .stage2_wasm, + }, + .{ + .target = CrossTarget.parse(.{ + .arch_os_abi = "arm-linux-none", + .cpu_features = "generic+v8a", + }) catch unreachable, + .backend = .stage2_arm, + }, + .{ + .target = .{ + .cpu_arch = .aarch64, + .os_tag = .macos, + .abi = .gnu, + }, + .backend = .stage2_aarch64, + }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .macos, + .abi = .gnu, + }, + .backend = .stage2_x86_64, + }, + + .{ .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi, @@ -58,7 +117,7 @@ const test_targets = blk: { .link_libc = false, .single_threaded = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi, @@ -67,14 +126,14 @@ const test_targets = blk: { .single_threaded = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .none, }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .linux, @@ -82,7 +141,7 @@ const test_targets = blk: { }, .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .linux, @@ -91,14 +150,14 @@ const test_targets = blk: { .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .i386, .os_tag = .linux, .abi = .none, }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .i386, .os_tag = .linux, @@ -106,7 +165,7 @@ const test_targets = blk: { }, .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .i386, .os_tag = .linux, @@ -115,14 +174,14 @@ const test_targets = blk: { .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .none, }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .aarch64, .os_tag = .linux, @@ -130,7 +189,7 @@ const test_targets = blk: { }, .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .aarch64, .os_tag = .linux, @@ -138,7 +197,7 @@ const test_targets = blk: { }, .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .aarch64, .os_tag = .windows, @@ -147,13 +206,13 @@ const test_targets = blk: { .link_libc = true, }, - TestTarget{ + .{ .target = CrossTarget.parse(.{ .arch_os_abi = "arm-linux-none", .cpu_features = "generic+v8a", }) catch unreachable, }, - TestTarget{ + .{ .target = CrossTarget.parse(.{ .arch_os_abi = "arm-linux-musleabihf", .cpu_features = "generic+v8a", @@ -161,7 +220,7 @@ const test_targets = blk: { .link_libc = true, }, // https://github.com/ziglang/zig/issues/3287 - //TestTarget{ + //.{ // .target = CrossTarget.parse(.{ // .arch_os_abi = "arm-linux-gnueabihf", // .cpu_features = "generic+v8a", @@ -169,7 +228,7 @@ const test_targets = blk: { // .link_libc = true, //}, - TestTarget{ + .{ .target = .{ .cpu_arch = .mips, .os_tag = .linux, @@ -177,7 +236,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .mips, .os_tag = .linux, @@ -187,7 +246,7 @@ const test_targets = blk: { }, // https://github.com/ziglang/zig/issues/4927 - //TestTarget{ + //.{ // .target = .{ // .cpu_arch = .mips, // .os_tag = .linux, @@ -196,7 +255,7 @@ const test_targets = blk: { // .link_libc = true, //}, - TestTarget{ + .{ .target = .{ .cpu_arch = .mipsel, .os_tag = .linux, @@ -204,7 +263,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .mipsel, .os_tag = .linux, @@ -214,7 +273,7 @@ const test_targets = blk: { }, // https://github.com/ziglang/zig/issues/4927 - //TestTarget{ + //.{ // .target = .{ // .cpu_arch = .mipsel, // .os_tag = .linux, @@ -223,14 +282,14 @@ const test_targets = blk: { // .link_libc = true, //}, - TestTarget{ + .{ .target = .{ .cpu_arch = .powerpc, .os_tag = .linux, .abi = .none, }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .powerpc, .os_tag = .linux, @@ -239,7 +298,7 @@ const test_targets = blk: { .link_libc = true, }, // https://github.com/ziglang/zig/issues/2256 - //TestTarget{ + //.{ // .target = .{ // .cpu_arch = .powerpc, // .os_tag = .linux, @@ -248,7 +307,7 @@ const test_targets = blk: { // .link_libc = true, //}, - TestTarget{ + .{ .target = .{ .cpu_arch = .riscv64, .os_tag = .linux, @@ -256,7 +315,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .riscv64, .os_tag = .linux, @@ -266,7 +325,7 @@ const test_targets = blk: { }, // https://github.com/ziglang/zig/issues/3340 - //TestTarget{ + //.{ // .target = .{ // .cpu_arch = .riscv64, // .os = .linux, @@ -275,7 +334,7 @@ const test_targets = blk: { // .link_libc = true, //}, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .macos, @@ -283,7 +342,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .aarch64, .os_tag = .macos, @@ -291,7 +350,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .i386, .os_tag = .windows, @@ -299,7 +358,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .windows, @@ -307,7 +366,7 @@ const test_targets = blk: { }, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .i386, .os_tag = .windows, @@ -316,7 +375,7 @@ const test_targets = blk: { .link_libc = true, }, - TestTarget{ + .{ .target = .{ .cpu_arch = .x86_64, .os_tag = .windows, @@ -326,38 +385,38 @@ const test_targets = blk: { }, // Do the release tests last because they take a long time - TestTarget{ + .{ .mode = .ReleaseFast, }, - TestTarget{ + .{ .link_libc = true, .mode = .ReleaseFast, }, - TestTarget{ + .{ .mode = .ReleaseFast, .single_threaded = true, }, - TestTarget{ + .{ .mode = .ReleaseSafe, }, - TestTarget{ + .{ .link_libc = true, .mode = .ReleaseSafe, }, - TestTarget{ + .{ .mode = .ReleaseSafe, .single_threaded = true, }, - TestTarget{ + .{ .mode = .ReleaseSmall, }, - TestTarget{ + .{ .link_libc = true, .mode = .ReleaseSmall, }, - TestTarget{ + .{ .mode = .ReleaseSmall, .single_threaded = true, }, @@ -524,6 +583,9 @@ pub fn addPkgTests( skip_single_threaded: bool, skip_non_native: bool, skip_libc: bool, + skip_stage1: bool, + skip_stage2: bool, + is_stage1: bool, ) *build.Step { const step = b.step(b.fmt("test-{s}", .{name}), desc); @@ -549,6 +611,11 @@ pub fn addPkgTests( continue; } + if (test_target.backend) |backend| switch (backend) { + .stage1 => if (skip_stage1) continue, + else => if (skip_stage2) continue, + } else if (is_stage1 and skip_stage1) continue; + const want_this_mode = for (modes) |m| { if (m == test_target.mode) break true; } else false; @@ -565,12 +632,14 @@ pub fn addPkgTests( const these_tests = b.addTest(root_src); const single_threaded_txt = if (test_target.single_threaded) "single" else "multi"; - these_tests.setNamePrefix(b.fmt("{s}-{s}-{s}-{s}-{s} ", .{ + const backend_txt = if (test_target.backend) |backend| @tagName(backend) else "default"; + these_tests.setNamePrefix(b.fmt("{s}-{s}-{s}-{s}-{s}-{s} ", .{ name, triple_prefix, @tagName(test_target.mode), libc_prefix, single_threaded_txt, + backend_txt, })); these_tests.single_threaded = test_target.single_threaded; these_tests.setFilter(test_filter); @@ -581,6 +650,24 @@ pub fn addPkgTests( } these_tests.overrideZigLibDir("lib"); these_tests.addIncludePath("test"); + if (test_target.backend) |backend| switch (backend) { + .stage1 => { + these_tests.use_stage1 = true; + }, + .stage2_llvm => { + these_tests.use_stage1 = false; + these_tests.use_llvm = true; + }, + .stage2_c => { + these_tests.use_stage1 = false; + these_tests.use_llvm = false; + these_tests.ofmt = .c; + }, + else => { + these_tests.use_stage1 = false; + these_tests.use_llvm = false; + }, + }; step.dependOn(&these_tests.step); }