diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 187e2d7ec1..6cda6716b7 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -3248,9 +3248,7 @@ test { _ = &makeDirAbsolute; _ = &makeDirAbsoluteZ; _ = ©FileAbsolute; - if (builtin.zig_backend != .stage2_x86_64) { - _ = &updateFileAbsolute; - } + _ = &updateFileAbsolute; } _ = &Dir.copyFile; _ = @import("fs/test.zig"); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 782d9e9265..9a11c7cb29 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1460,8 +1460,6 @@ test "walker without fully iterating" { test ". and .. in fs.Dir functions" { if (builtin.os.tag == .wasi and builtin.link_libc) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) { // https://github.com/ziglang/zig/issues/17134 return error.SkipZigTest; @@ -1502,8 +1500,6 @@ test ". and .. in fs.Dir functions" { test ". and .. in absolute functions" { if (builtin.os.tag == .wasi) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index 46c40512e2..5774b74b61 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -161,8 +161,6 @@ test "setEndPos" { } test "updateTimes" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var tmp = tmpDir(.{}); defer tmp.cleanup(); diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index b5ad916c20..66060d6b4b 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -1182,8 +1182,6 @@ test "big.int div single-single with rem" { } test "big.int div multi-single no rem" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var op1: u128 = 0xffffeeeeddddcccc; var op2: u128 = 34; @@ -1203,8 +1201,6 @@ test "big.int div multi-single no rem" { } test "big.int div multi-single with rem" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var op1: u128 = 0xffffeeeeddddcccf; var op2: u128 = 34; @@ -1224,8 +1220,6 @@ test "big.int div multi-single with rem" { } test "big.int div multi>2-single" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var op1: u128 = 0xfefefefefefefefefefefefefefefefe; var op2: u128 = 0xefab8; @@ -1405,8 +1399,6 @@ test "big.int div trunc single-single -/-" { } test "big.int divTrunc #15535" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var one = try Managed.initSet(testing.allocator, 1); defer one.deinit(); var x = try Managed.initSet(testing.allocator, std.math.pow(u128, 2, 64)); @@ -1949,8 +1941,6 @@ test "big.int truncate multi to multi signed" { } test "big.int truncate negative multi to single" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Managed.initSet(testing.allocator, -@as(SignedDoubleLimb, maxInt(Limb) + 1)); defer a.deinit(); @@ -2362,8 +2352,6 @@ test "big.int bitwise xor simple" { } test "big.int bitwise xor multi-limb" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var x: DoubleLimb = maxInt(Limb) + 1; var y: DoubleLimb = maxInt(Limb); var a = try Managed.initSet(testing.allocator, x); @@ -2538,8 +2526,6 @@ test "big.int var args" { } test "big.int gcd non-one small" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Managed.initSet(testing.allocator, 17); defer a.deinit(); var b = try Managed.initSet(testing.allocator, 97); @@ -2553,8 +2539,6 @@ test "big.int gcd non-one small" { } test "big.int gcd non-one medium" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Managed.initSet(testing.allocator, 4864); defer a.deinit(); var b = try Managed.initSet(testing.allocator, 3458); @@ -2568,8 +2552,6 @@ test "big.int gcd non-one medium" { } test "big.int gcd non-one large" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Managed.initSet(testing.allocator, 0xffffffffffffffff); defer a.deinit(); var b = try Managed.initSet(testing.allocator, 0xffffffffffffffff7777); @@ -2602,8 +2584,6 @@ test "big.int gcd large multi-limb result" { } test "big.int gcd one large" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Managed.initSet(testing.allocator, 1897056385327307); defer a.deinit(); var b = try Managed.initSet(testing.allocator, 2251799813685248); diff --git a/lib/std/math/big/rational.zig b/lib/std/math/big/rational.zig index f3812fe35d..2558aff38f 100644 --- a/lib/std/math/big/rational.zig +++ b/lib/std/math/big/rational.zig @@ -514,8 +514,6 @@ test "big.rational extractLowBits" { } test "big.rational set" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); @@ -615,8 +613,6 @@ test "big.rational set/to Float round-trip" { } test "big.rational copy" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); @@ -681,8 +677,6 @@ test "big.rational abs" { } test "big.rational swap" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -707,8 +701,6 @@ test "big.rational swap" { } test "big.rational order" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -724,8 +716,6 @@ test "big.rational order" { } test "big.rational order/orderAbs with negative" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -738,8 +728,6 @@ test "big.rational order/orderAbs with negative" { } test "big.rational add single-limb" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -755,8 +743,6 @@ test "big.rational add single-limb" { } test "big.rational add" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -773,8 +759,6 @@ test "big.rational add" { } test "big.rational sub" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -791,8 +775,6 @@ test "big.rational sub" { } test "big.rational mul" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var a = try Rational.init(testing.allocator); defer a.deinit(); var b = try Rational.init(testing.allocator); @@ -809,8 +791,6 @@ test "big.rational mul" { } test "big.rational div" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - { var a = try Rational.init(testing.allocator); defer a.deinit(); diff --git a/lib/std/os/linux/io_uring.zig b/lib/std/os/linux/io_uring.zig index 915036d962..0f7fa22d80 100644 --- a/lib/std/os/linux/io_uring.zig +++ b/lib/std/os/linux/io_uring.zig @@ -2204,8 +2204,6 @@ test "sendmsg/recvmsg" { test "timeout (after a relative time)" { if (builtin.os.tag != .linux) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - var ring = IO_Uring.init(1, 0) catch |err| switch (err) { error.SystemOutdated => return error.SkipZigTest, error.PermissionDenied => return error.SkipZigTest, diff --git a/lib/std/time.zig b/lib/std/time.zig index 010c1af291..c078e97793 100644 --- a/lib/std/time.zig +++ b/lib/std/time.zig @@ -122,8 +122,6 @@ pub fn nanoTimestamp() i128 { } test "timestamp" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - const margin = ns_per_ms * 50; const time_0 = milliTimestamp(); diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 721216032c..0752f1b8f1 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3221,6 +3221,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), else => {}, } + const dst_abi_size: u32 = @intCast(dst_ty.abiSize(mod)); const dst_info = dst_ty.intInfo(mod); const src_ty = try mod.intType(dst_info.signedness, switch (tag) { @@ -3232,12 +3233,153 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { ), .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits, }); + const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); + + if (dst_abi_size == 16 and src_abi_size == 16) switch (tag) { + else => unreachable, + .mul, .mul_wrap => {}, + .div_trunc, .div_floor, .div_exact, .rem, .mod => { + const signed = dst_ty.isSignedInt(mod); + var callee_buf: ["__udiv?i3".len]u8 = undefined; + const signed_div_floor_state: struct { + frame_index: FrameIndex, + reloc: Mir.Inst.Index, + } = if (signed and tag == .div_floor) state: { + const frame_index = try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod)); + try self.asmMemoryImmediate( + .{ ._, .mov }, + Memory.sib(.qword, .{ .base = .{ .frame = frame_index } }), + Immediate.u(0), + ); + + const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); + + const lhs_mcv = try self.resolveInst(bin_op.lhs); + if (lhs_mcv.isMemory()) try self.asmRegisterMemory( + .{ ._, .mov }, + tmp_reg, + lhs_mcv.address().offset(8).deref().mem(.qword), + ) else try self.asmRegisterRegister( + .{ ._, .mov }, + tmp_reg, + lhs_mcv.register_pair[1], + ); + + const rhs_mcv = try self.resolveInst(bin_op.rhs); + if (rhs_mcv.isMemory()) try self.asmRegisterMemory( + .{ ._, .xor }, + tmp_reg, + rhs_mcv.address().offset(8).deref().mem(.qword), + ) else try self.asmRegisterRegister( + .{ ._, .xor }, + tmp_reg, + rhs_mcv.register_pair[1], + ); + const reloc = try self.asmJccReloc(.ns, undefined); + + break :state .{ .frame_index = frame_index, .reloc = reloc }; + } else undefined; + const call_mcv = try self.genCall( + .{ .lib = .{ + .return_type = dst_ty.toIntern(), + .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, + .callee = std.fmt.bufPrint(&callee_buf, "__{s}{s}{c}i3", .{ + if (signed) "" else "u", + switch (tag) { + .div_trunc, .div_exact => "div", + .div_floor => if (signed) "mod" else "div", + .rem, .mod => "mod", + else => unreachable, + }, + intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), + }) catch unreachable, + } }, + &.{ src_ty, src_ty }, + &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, + ); + break :result if (signed) switch (tag) { + .div_floor => { + try self.asmRegisterRegister( + .{ ._, .@"or" }, + call_mcv.register_pair[0], + call_mcv.register_pair[1], + ); + try self.asmSetccMemory(.nz, Memory.sib(.byte, .{ + .base = .{ .frame = signed_div_floor_state.frame_index }, + })); + try self.performReloc(signed_div_floor_state.reloc); + const dst_mcv = try self.genCall( + .{ .lib = .{ + .return_type = dst_ty.toIntern(), + .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, + .callee = std.fmt.bufPrint(&callee_buf, "__div{c}i3", .{ + intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), + }) catch unreachable, + } }, + &.{ src_ty, src_ty }, + &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, + ); + try self.asmRegisterMemory( + .{ ._, .sub }, + dst_mcv.register_pair[0], + Memory.sib(.qword, .{ + .base = .{ .frame = signed_div_floor_state.frame_index }, + }), + ); + try self.asmRegisterImmediate( + .{ ._, .sbb }, + dst_mcv.register_pair[1], + Immediate.u(0), + ); + try self.freeValue( + .{ .load_frame = .{ .index = signed_div_floor_state.frame_index } }, + ); + break :result dst_mcv; + }, + .mod => { + const dst_regs = call_mcv.register_pair; + const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); + defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); + + const tmp_regs = + try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); + const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); + defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); + + const rhs_mcv = try self.resolveInst(bin_op.rhs); + + for (tmp_regs, dst_regs) |tmp_reg, dst_reg| + try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg); + if (rhs_mcv.isMemory()) { + try self.asmRegisterMemory(.{ ._, .add }, tmp_regs[0], rhs_mcv.mem(.qword)); + try self.asmRegisterMemory( + .{ ._, .adc }, + tmp_regs[1], + rhs_mcv.address().offset(8).deref().mem(.qword), + ); + } else for ( + [_]Mir.Inst.Tag{ .add, .adc }, + tmp_regs, + rhs_mcv.register_pair, + ) |op, tmp_reg, rhs_reg| + try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg); + try self.asmRegisterRegister(.{ ._, .@"test" }, dst_regs[1], dst_regs[1]); + for (dst_regs, tmp_regs) |dst_reg, tmp_reg| + try self.asmCmovccRegisterRegister(.s, dst_reg, tmp_reg); + break :result call_mcv; + }, + else => call_mcv, + } else call_mcv; + }, + }; try self.spillEflagsIfOccupied(); try self.spillRegisters(&.{ .rax, .rdx }); - const lhs = try self.resolveInst(bin_op.lhs); - const rhs = try self.resolveInst(bin_op.rhs); - break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs, rhs); + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const rhs_mcv = try self.resolveInst(bin_op.rhs); + break :result try self.genMulDivBinOp(tag, inst, dst_ty, src_ty, lhs_mcv, rhs_mcv); }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -7201,37 +7343,7 @@ fn genMulDivBinOp( assert(self.eflags_inst == null); if (dst_abi_size == 16 and src_abi_size == 16) { - switch (tag) { - else => unreachable, - .mul, .mul_wrap => {}, - .div_trunc, .div_floor, .div_exact, .rem, .mod => { - const signed = dst_ty.isSignedInt(mod); - if (signed) switch (tag) { - .div_floor, .mod => return self.fail( - "TODO implement genMulDivBinOp for {s} from {} to {}", - .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, - ), - else => {}, - }; - var callee_buf: ["__udiv?i3".len]u8 = undefined; - return try self.genCall(.{ .lib = .{ - .return_type = dst_ty.toIntern(), - .param_types = &.{ src_ty.toIntern(), src_ty.toIntern() }, - .callee = std.fmt.bufPrint(&callee_buf, "__{s}{s}{c}i3", .{ - if (signed) "" else "u", - switch (tag) { - .div_trunc, .div_exact => "div", - .div_floor => if (signed) unreachable else "div", - .rem => "mod", - .mod => if (signed) unreachable else "mod", - else => unreachable, - }, - intCompilerRtAbiName(@intCast(dst_ty.bitSize(mod))), - }) catch unreachable, - } }, &.{ src_ty, src_ty }, &.{ lhs_mcv, rhs_mcv }); - }, - } - + assert(tag == .mul or tag == .mul_wrap); const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }); defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);