diff --git a/lib/std/crypto/ecdsa.zig b/lib/std/crypto/ecdsa.zig index 1a5335b07e..acb054d8cd 100644 --- a/lib/std/crypto/ecdsa.zig +++ b/lib/std/crypto/ecdsa.zig @@ -372,7 +372,10 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { } test "ECDSA - Basic operations over EcdsaP384Sha384" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const Scheme = EcdsaP384Sha384; const kp = try Scheme.KeyPair.create(null); @@ -388,7 +391,10 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" { } test "ECDSA - Basic operations over Secp256k1" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const Scheme = EcdsaSecp256k1Sha256oSha256; const kp = try Scheme.KeyPair.create(null); @@ -404,7 +410,10 @@ test "ECDSA - Basic operations over Secp256k1" { } test "ECDSA - Basic operations over EcdsaP384Sha256" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); const kp = try Scheme.KeyPair.create(null); @@ -420,7 +429,10 @@ test "ECDSA - Basic operations over EcdsaP384Sha256" { } test "ECDSA - Verifying a existing signature with EcdsaP384Sha256" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256); // zig fmt: off @@ -464,7 +476,10 @@ const TestVector = struct { }; test "ECDSA - Test vectors from Project Wycheproof" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const vectors = [_]TestVector{ .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", .result = .valid }, @@ -878,7 +893,10 @@ fn tvTry(vector: TestVector) !void { } test "ECDSA - Sec1 encoding/decoding" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + switch (builtin.zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const Scheme = EcdsaP384Sha384; const kp = try Scheme.KeyPair.create(null); diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig index 287d37544f..037feae5ed 100644 --- a/lib/std/crypto/ff.zig +++ b/lib/std/crypto/ff.zig @@ -912,7 +912,10 @@ const ct_unprotected = struct { }; test { - if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; + switch (@import("builtin").zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } const M = Modulus(256); const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233); diff --git a/lib/std/crypto/pcurves/p384.zig b/lib/std/crypto/pcurves/p384.zig index d5afd6eb4d..44dd4e50b7 100644 --- a/lib/std/crypto/pcurves/p384.zig +++ b/lib/std/crypto/pcurves/p384.zig @@ -478,7 +478,10 @@ pub const AffineCoordinates = struct { }; test { - if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; + switch (@import("builtin").zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } _ = @import("tests/p384.zig"); } diff --git a/lib/std/crypto/pcurves/secp256k1.zig b/lib/std/crypto/pcurves/secp256k1.zig index cd7f1faf75..6286b96249 100644 --- a/lib/std/crypto/pcurves/secp256k1.zig +++ b/lib/std/crypto/pcurves/secp256k1.zig @@ -556,7 +556,10 @@ pub const AffineCoordinates = struct { }; test { - if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; + switch (@import("builtin").zig_backend) { + .stage2_c, .stage2_x86_64 => return error.SkipZigTest, + else => {}, + } _ = @import("tests/secp256k1.zig"); } diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index 668f07b32d..40a4dc9ffc 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -3031,6 +3031,8 @@ fn byteSwapTest(comptime T: type, comptime input: comptime_int, comptime expecte } test "big int byte swap" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + var a = try Managed.initSet(testing.allocator, 0x01_ffffffff_ffffffff_ffffffff); defer a.deinit(); diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig index 785f11771c..7544c0f9cc 100644 --- a/lib/std/math/log10.zig +++ b/lib/std/math/log10.zig @@ -170,11 +170,11 @@ test "log10_int vs old implementation" { test "log10_int close to powers of 10" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_llvm and comptime builtin.target.isWasm()) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const int_types = .{ u8, u16, u32, u64, u128, u256, u512 }; const max_log_values: [7]usize = .{ 2, 4, 9, 19, 38, 77, 154 }; diff --git a/lib/std/math/nextafter.zig b/lib/std/math/nextafter.zig index 3a0b2d88a5..56117b36d9 100644 --- a/lib/std/math/nextafter.zig +++ b/lib/std/math/nextafter.zig @@ -103,6 +103,8 @@ fn nextAfterFloat(comptime T: type, x: T, y: T) T { } test "math.nextAfter.int" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + try expect(nextAfter(i0, 0, 0) == 0); try expect(nextAfter(u0, 0, 0) == 0); try expect(nextAfter(i1, 0, 0) == 0); diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index a00d562924..624f22d4a6 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2895,13 +2895,16 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { }.signedness; const src_mcv = try self.resolveInst(ty_op.operand); - const src_storage_bits = switch (src_mcv) { + const src_storage_bits: u16 = switch (src_mcv) { .register, .register_offset => 64, - .load_frame => |frame_addr| self.getFrameAddrSize(frame_addr) * 8, + .register_pair => 128, + .load_frame => |frame_addr| @intCast(self.getFrameAddrSize(frame_addr) * 8), else => src_int_info.bits, }; const dst_mcv = if (dst_int_info.bits <= src_storage_bits and + std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable == + std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { const dst_mcv = try self.allocRegOrMem(inst, true); try self.genCopy(min_ty, dst_mcv, src_mcv); @@ -3646,7 +3649,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { }, else => { // For now, this is the only supported multiply that doesn't fit in a register. - assert(dst_info.bits <= 128 and src_bits == 64); + if (dst_info.bits > 128 or src_bits != 64) + return self.fail("TODO implement airWithOverflow from {} to {}", .{ + src_ty.fmt(mod), dst_ty.fmt(mod), + }); const frame_index = try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod)); @@ -4424,42 +4430,46 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { // this is identical to the `airPtrElemPtr` codegen expect here an // additional `mov` is needed at the end to get the actual value - const elem_ty = ptr_ty.elemType2(mod); - const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); - const index_ty = self.typeOf(bin_op.rhs); - const index_mcv = try self.resolveInst(bin_op.rhs); - const index_lock = switch (index_mcv) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, + const result = result: { + const elem_ty = ptr_ty.elemType2(mod); + if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none; + + const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); + const index_ty = self.typeOf(bin_op.rhs); + const index_mcv = try self.resolveInst(bin_op.rhs); + const index_lock = switch (index_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (index_lock) |lock| self.register_manager.unlockReg(lock); + + const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); + const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg); + defer self.register_manager.unlockReg(offset_lock); + + const ptr_mcv = try self.resolveInst(bin_op.lhs); + const elem_ptr_reg = if (ptr_mcv.isRegister() and self.liveness.operandDies(inst, 0)) + ptr_mcv.register + else + try self.copyToTmpRegister(ptr_ty, ptr_mcv); + const elem_ptr_lock = self.register_manager.lockRegAssumeUnused(elem_ptr_reg); + defer self.register_manager.unlockReg(elem_ptr_lock); + try self.asmRegisterRegister( + .{ ._, .add }, + elem_ptr_reg, + offset_reg, + ); + + const dst_mcv = try self.allocRegOrMem(inst, true); + const dst_lock = switch (dst_mcv) { + .register => |reg| self.register_manager.lockRegAssumeUnused(reg), + else => null, + }; + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + try self.load(dst_mcv, ptr_ty, .{ .register = elem_ptr_reg }); + break :result dst_mcv; }; - defer if (index_lock) |lock| self.register_manager.unlockReg(lock); - - const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_abi_size); - const offset_lock = self.register_manager.lockRegAssumeUnused(offset_reg); - defer self.register_manager.unlockReg(offset_lock); - - const ptr_mcv = try self.resolveInst(bin_op.lhs); - const elem_ptr_reg = if (ptr_mcv.isRegister() and self.liveness.operandDies(inst, 0)) - ptr_mcv.register - else - try self.copyToTmpRegister(ptr_ty, ptr_mcv); - const elem_ptr_lock = self.register_manager.lockRegAssumeUnused(elem_ptr_reg); - defer self.register_manager.unlockReg(elem_ptr_lock); - try self.asmRegisterRegister( - .{ ._, .add }, - elem_ptr_reg, - offset_reg, - ); - - const dst_mcv = try self.allocRegOrMem(inst, true); - const dst_lock = switch (dst_mcv) { - .register => |reg| self.register_manager.lockRegAssumeUnused(reg), - else => null, - }; - defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); - try self.load(dst_mcv, ptr_ty, .{ .register = elem_ptr_reg }); - - return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); + return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { @@ -5790,15 +5800,17 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn const ptr_info = ptr_ty.ptrInfo(mod); const val_ty = ptr_info.child.toType(); + if (!val_ty.hasRuntimeBitsIgnoreComptime(mod)) return; const val_abi_size: u32 = @intCast(val_ty.abiSize(mod)); + + if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(mod)}); + const limb_abi_size: u32 = @min(val_abi_size, 8); const limb_abi_bits = limb_abi_size * 8; const val_byte_off: i32 = @intCast(ptr_info.packed_offset.bit_offset / limb_abi_bits * limb_abi_size); const val_bit_off = ptr_info.packed_offset.bit_offset % limb_abi_bits; const val_extra_bits = self.regExtraBits(val_ty); - if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(mod)}); - const ptr_reg = try self.copyToTmpRegister(ptr_ty, ptr_mcv); const ptr_lock = self.register_manager.lockRegAssumeUnused(ptr_reg); defer self.register_manager.unlockReg(ptr_lock); @@ -5861,6 +5873,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { const mod = self.bin_file.options.module.?; const dst_ty = ptr_ty.childType(mod); + if (!dst_ty.hasRuntimeBitsIgnoreComptime(mod)) return; switch (ptr_mcv) { .none, .unreach, @@ -5937,6 +5950,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In const mod = self.bin_file.options.module.?; const ptr_info = ptr_ty.ptrInfo(mod); const src_ty = ptr_ty.childType(mod); + if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; const limb_abi_size: u16 = @min(ptr_info.packed_offset.host_size, 8); const limb_abi_bits = limb_abi_size * 8; @@ -6008,6 +6022,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { const mod = self.bin_file.options.module.?; const src_ty = ptr_ty.childType(mod); + if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; switch (ptr_mcv) { .none, .unreach, @@ -11286,7 +11301,6 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr .none, .unreach, .dead, - .register_pair, .register_overflow, .reserved_frame, => unreachable, @@ -11390,6 +11404,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr }, .x87, .mmx => unreachable, }, + .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }), .register_offset, .indirect, .load_frame, diff --git a/src/codegen.zig b/src/codegen.zig index 24269f38ba..88895aa65c 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -545,7 +545,7 @@ pub fn generateSymbol( if (layout.payload_size == 0) { return generateSymbol(bin_file, src_loc, .{ - .ty = typed_value.ty.unionTagType(mod).?, + .ty = typed_value.ty.unionTagTypeSafety(mod).?, .val = un.tag.toValue(), }, code, debug_output, reloc_info); } @@ -553,7 +553,7 @@ pub fn generateSymbol( // Check if we should store the tag first. if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { switch (try generateSymbol(bin_file, src_loc, .{ - .ty = typed_value.ty.unionTagType(mod).?, + .ty = typed_value.ty.unionTagTypeSafety(mod).?, .val = un.tag.toValue(), }, code, debug_output, reloc_info)) { .ok => {},