diff --git a/lib/compiler_rt/udivmodei4.zig b/lib/compiler_rt/udivmodei4.zig index ef248181fd63f1aba2e03965333afe7f34ac0ba6..6bddd78b8157b8b59e2d013090560b501a4a5d25 100644 --- a/lib/compiler_rt/udivmodei4.zig +++ b/lib/compiler_rt/udivmodei4.zig @@ -114,23 +114,22 @@ fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void { pub fn __udivei4(r_q: [*]u32, u_p: [*]const u32, v_p: [*]const u32, bits: usize) callconv(.C) void { @setRuntimeSafety(builtin.is_test); - const u = u_p[0 .. bits / 32]; - const v = v_p[0 .. bits / 32]; - const q = r_q[0 .. bits / 32]; + const u = u_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; + const v = v_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; + const q = r_q[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; @call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable; } pub fn __umodei4(r_p: [*]u32, u_p: [*]const u32, v_p: [*]const u32, bits: usize) callconv(.C) void { @setRuntimeSafety(builtin.is_test); - const u = u_p[0 .. bits / 32]; - const v = v_p[0 .. bits / 32]; - const r = r_p[0 .. bits / 32]; + const u = u_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; + const v = v_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; + const r = r_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable]; @call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable; } test "__udivei4/__umodei4" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const RndGen = std.Random.DefaultPrng; var rnd = RndGen.init(42); diff --git a/lib/std/Random/Xoshiro256.zig b/lib/std/Random/Xoshiro256.zig index bf917885f66655e8c4fa9dd1bfd77230efd96426..75e860b89f921d66563393214c027600d8157d7e 100644 --- a/lib/std/Random/Xoshiro256.zig +++ b/lib/std/Random/Xoshiro256.zig @@ -90,7 +90,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void { test "xoroshiro sequence" { if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; - if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; var r = Xoshiro256.init(0); diff --git a/lib/std/crypto/aes_ocb.zig b/lib/std/crypto/aes_ocb.zig index 879710d8481b2b44dad2c5b1f9bdb20dfde9c303..6cbb2e086720a4aad61f3bb1708ad63273a20054 100644 --- a/lib/std/crypto/aes_ocb.zig +++ b/lib/std/crypto/aes_ocb.zig @@ -262,7 +262,6 @@ const hexToBytes = std.fmt.hexToBytes; test "AesOcb test vector 1" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var k: [Aes128Ocb.key_length]u8 = undefined; var nonce: [Aes128Ocb.nonce_length]u8 = undefined; @@ -282,7 +281,6 @@ test "AesOcb test vector 1" { test "AesOcb test vector 2" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var k: [Aes128Ocb.key_length]u8 = undefined; var nonce: [Aes128Ocb.nonce_length]u8 = undefined; @@ -304,7 +302,6 @@ test "AesOcb test vector 2" { test "AesOcb test vector 3" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var k: [Aes128Ocb.key_length]u8 = undefined; var nonce: [Aes128Ocb.nonce_length]u8 = undefined; @@ -329,7 +326,6 @@ test "AesOcb test vector 3" { test "AesOcb test vector 4" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var k: [Aes128Ocb.key_length]u8 = undefined; var nonce: [Aes128Ocb.nonce_length]u8 = undefined; diff --git a/lib/std/crypto/ecdsa.zig b/lib/std/crypto/ecdsa.zig index 321923525b4955e2556d6c73f02d90e3c1dab408..7c4df6e35d8060d344c4ac621bb39d19c7e769b5 100644 --- a/lib/std/crypto/ecdsa.zig +++ b/lib/std/crypto/ecdsa.zig @@ -389,7 +389,6 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" { test "ECDSA - Basic operations over Secp256k1" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; const Scheme = EcdsaSecp256k1Sha256oSha256; const kp = try Scheme.KeyPair.create(null); diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig index 90b1b9f441f1331dd24a1ed3527030319cfe9049..b917ce7a4308bf9c4baec5f142198f067cc32954 100644 --- a/lib/std/crypto/ff.zig +++ b/lib/std/crypto/ff.zig @@ -907,9 +907,8 @@ const ct_unprotected = struct { } }; -test { +test "finite field arithmetic" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; 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 6585a0adfddb1317226de534a2a44796c83c2bc8..f8c5713209fb01a24b8b3f0c45ed1b18b201e554 100644 --- a/lib/std/crypto/pcurves/p384.zig +++ b/lib/std/crypto/pcurves/p384.zig @@ -479,7 +479,6 @@ pub const AffineCoordinates = struct { test { if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; - if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; _ = @import("tests/p384.zig"); } diff --git a/lib/std/crypto/pcurves/secp256k1.zig b/lib/std/crypto/pcurves/secp256k1.zig index a623e25de40a6920f21ca64abf638f9b0f045ea9..c2d9e37dfe760186822b82d18f8af9e6f38625cf 100644 --- a/lib/std/crypto/pcurves/secp256k1.zig +++ b/lib/std/crypto/pcurves/secp256k1.zig @@ -557,7 +557,6 @@ pub const AffineCoordinates = struct { test { if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; - if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; _ = @import("tests/secp256k1.zig"); } diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index e5bfca02b2b3b0ff4247895816ae319c1cd938be..262d51bcee6c2d68fc874040e1f81ecdee88ea06 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -2790,8 +2790,6 @@ test "positional/alignment/width/precision" { } test "vector" { - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.target.cpu.arch == .riscv64) { // https://github.com/ziglang/zig/issues/4486 return error.SkipZigTest; diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index e1f423e3c15dfd258fa7e012cfd8b489416147a0..558ada33741b43c42f328b3ba792ca0635483c25 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -918,7 +918,6 @@ test "big.int mul multi-single" { test "big.int mul multi-multi" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var op1: u256 = 0x998888efefefefefefefef; var op2: u256 = 0x333000abababababababab; @@ -1042,7 +1041,6 @@ test "big.int mulWrap single-single signed" { test "big.int mulWrap multi-multi unsigned" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var op1: u256 = 0x998888efefefefefefefef; var op2: u256 = 0x333000abababababababab; @@ -1698,7 +1696,6 @@ test "big.int div multi-multi (2 branch)" { test "big.int div multi-multi (3.1/3.3 branch)" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111); defer a.deinit(); @@ -2187,7 +2184,6 @@ test "big.int bitNotWrap more than two limbs" { // This test requires int sizes greater than 128 bits. 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_arm) return error.SkipZigTest; // TODO // LLVM: unexpected runtime library name: __umodei4 @@ -2537,7 +2533,6 @@ test "big.int gcd non-one large" { test "big.int gcd large multi-limb result" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678); defer a.deinit(); diff --git a/lib/std/math/log10.zig b/lib/std/math/log10.zig index 0619fdbc17aed50a55838c0a8e713e2e15e85ac0..5b3ee8a8400a7e07e758dcec1b150c8a589c6a1f 100644 --- a/lib/std/math/log10.zig +++ b/lib/std/math/log10.zig @@ -1,10 +1,6 @@ const std = @import("../std.zig"); const builtin = @import("builtin"); -const math = std.math; const testing = std.testing; -const maxInt = std.math.maxInt; -const assert = std.debug.assert; -const Log2Int = std.math.Log2Int; /// Returns the base-10 logarithm of x. /// @@ -38,13 +34,13 @@ pub fn log10(x: anytype) @TypeOf(x) { /// Return the log base 10 of integer value x, rounding down to the /// nearest integer. -pub fn log10_int(x: anytype) Log2Int(@TypeOf(x)) { +pub fn log10_int(x: anytype) std.math.Log2Int(@TypeOf(x)) { const T = @TypeOf(x); - const OutT = Log2Int(T); + const OutT = std.math.Log2Int(T); if (@typeInfo(T) != .Int or @typeInfo(T).Int.signedness != .unsigned) @compileError("log10_int requires an unsigned integer, found " ++ @typeName(T)); - assert(x != 0); + std.debug.assert(x != 0); const bit_size = @typeInfo(T).Int.bits; @@ -133,18 +129,7 @@ inline fn less_than_5(x: u32) u32 { return (((x + C1) & (x + C2)) ^ ((x + C3) & (x + C4))) >> 17; } -fn oldlog10(x: anytype) u8 { - return @as(u8, @intFromFloat(@log10(@as(f64, @floatFromInt(x))))); -} - -test "oldlog10 doesn't work" { - try testing.expect(14 != oldlog10(pow10(15) - 1)); - - // log10(10**15 -1) should indeed be 14 - try testing.expect(14 == log10_int(@as(u64, pow10(15) - 1))); -} - -test "log10_int vs old implementation" { +test log10_int { 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_aarch64) return error.SkipZigTest; // TODO @@ -152,53 +137,22 @@ test "log10_int vs old implementation" { 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 - const int_types = .{ u8, u16, u32, u64, u128 }; - - inline for (int_types) |T| { - const last = @min(maxInt(T), 100_000); - for (1..last) |i| { - const x = @as(T, @intCast(i)); - try testing.expectEqual(oldlog10(x), log10_int(x)); - } - - const max_int: T = maxInt(T); - try testing.expectEqual(oldlog10(max_int), log10_int(max_int)); - } -} - -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_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 }; - - inline for (int_types, max_log_values) |T, expected_max_ilog| { - const max_val: T = maxInt(T); - - try testing.expectEqual(expected_max_ilog, log10_int(max_val)); - - for (0..(expected_max_ilog + 1)) |idx| { - const i = @as(T, @intCast(idx)); - const p: T = try math.powi(T, 10, i); - - const b = @as(Log2Int(T), @intCast(i)); - - if (p >= 10) { - try testing.expectEqual(b - 1, log10_int(p - 9)); - try testing.expectEqual(b - 1, log10_int(p - 1)); - } - - try testing.expectEqual(b, log10_int(p)); - try testing.expectEqual(b, log10_int(p + 1)); - if (p >= 10) { - try testing.expectEqual(b, log10_int(p + 9)); + inline for ( + .{ u8, u16, u32, u64, u128, u256, u512 }, + .{ 2, 4, 9, 19, 38, 77, 154 }, + ) |T, max_exponent| { + for (0..max_exponent + 1) |exponent_usize| { + const exponent: std.math.Log2Int(T) = @intCast(exponent_usize); + const power_of_ten = try std.math.powi(T, 10, exponent); + + if (exponent > 0) { + try testing.expectEqual(exponent - 1, log10_int(power_of_ten - 9)); + try testing.expectEqual(exponent - 1, log10_int(power_of_ten - 1)); } + try testing.expectEqual(exponent, log10_int(power_of_ten)); + try testing.expectEqual(exponent, log10_int(power_of_ten + 1)); + try testing.expectEqual(exponent, log10_int(power_of_ten + 8)); } + try testing.expectEqual(max_exponent, log10_int(@as(T, std.math.maxInt(T)))); } } diff --git a/lib/std/math/nextafter.zig b/lib/std/math/nextafter.zig index 9008858a627d1bde954863d4df3f0e4514aa79c7..7d2396ed26382593e9b4b0071d365868bec6d152 100644 --- a/lib/std/math/nextafter.zig +++ b/lib/std/math/nextafter.zig @@ -102,8 +102,6 @@ fn nextAfterFloat(comptime T: type, x: T, y: T) T { } test "math.nextAfter.int" { - if (@import("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 46f353f13fed0d4153ce3cb7a87f1f9620a7cb98..e547b797ac6e2a06ce3d039a981c17e1d5d49724 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -221,6 +221,8 @@ pub const MCValue = union(enum) { /// The address of an offset from a frame index /// Payload is a frame address. lea_frame: FrameAddr, + /// Supports integer_per_element abi + elementwise_regs_then_frame: packed struct { regs: u3 = 0, frame_off: i29 = 0, frame_index: FrameIndex }, /// This indicates that we have already allocated a frame index for this instruction, /// but it has not been spilled there yet in the current control flow. /// Payload is a frame index. @@ -300,6 +302,7 @@ pub const MCValue = union(enum) { .lea_got, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // not in memory @@ -332,6 +335,7 @@ pub const MCValue = union(enum) { .load_tlv, .load_frame, .load_symbol, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // not dereferenceable @@ -352,6 +356,7 @@ pub const MCValue = union(enum) { .unreach, .dead, .undef, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // not valid @@ -403,8 +408,8 @@ pub const MCValue = union(enum) { .load_tlv, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, - .air_ref, .lea_symbol, => unreachable, .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| .{ @@ -441,6 +446,7 @@ pub const MCValue = union(enum) { } }, }; }, + .air_ref => |ref| (try function.resolveInst(ref)).mem(function, size), }; } @@ -470,6 +476,7 @@ pub const MCValue = union(enum) { .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}), .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}), .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }), + .elementwise_regs_then_frame => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{ pl.regs, pl.frame_index, pl.frame_off }), .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }), .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}), .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}), @@ -502,6 +509,7 @@ const InstTracking = struct { .lea_symbol, => result, .dead, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -537,7 +545,7 @@ const InstTracking = struct { else => unreachable, } tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long }); - try function.genCopy(function.typeOfIndex(inst), self.long, self.short); + try function.genCopy(function.typeOfIndex(inst), self.long, self.short, .{}); } fn reuseFrame(self: *InstTracking) void { @@ -569,6 +577,7 @@ const InstTracking = struct { .register_offset, .register_overflow, .indirect, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -614,6 +623,7 @@ const InstTracking = struct { .register_offset, .register_overflow, .indirect, + .elementwise_regs_then_frame, .air_ref, => unreachable, } @@ -637,8 +647,8 @@ const InstTracking = struct { ) !void { const ty = function.typeOfIndex(inst); if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame) - try function.genCopy(ty, target.long, self.short); - try function.genCopy(ty, target.short, self.short); + try function.genCopy(ty, target.long, self.short, .{}); + try function.genCopy(ty, target.short, self.short, .{}); } fn trackMaterialize(self: *InstTracking, inst: Air.Inst.Index, target: InstTracking) void { @@ -1717,6 +1727,7 @@ fn gen(self: *Self) InnerError!void { 0, Type.usize, self.ret_mcv.long.address().offset(-self.ret_mcv.short.indirect.off), + .{}, ); self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } }; tracking_log.debug("spill {} to {}", .{ self.ret_mcv.long, frame_index }); @@ -1740,6 +1751,7 @@ fn gen(self: *Self) InnerError!void { @intCast(reg_i * 8), Type.usize, .{ .register = reg }, + .{}, ); try self.asmRegisterImmediate(.{ ._, .cmp }, .al, Immediate.u(info.fp_count)); @@ -1752,9 +1764,10 @@ fn gen(self: *Self) InnerError!void { @intCast(abi.SysV.c_abi_int_param_regs.len * 8 + reg_i * 16), vec_2_f64, .{ .register = reg }, + .{}, ); - try self.performReloc(skip_sse_reloc); + self.performReloc(skip_sse_reloc); }, .Win64 => return self.fail("TODO implement gen var arg function for Win64", .{}), else => unreachable, @@ -2006,8 +2019,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .load => try self.airLoad(inst), .loop => try self.airLoop(inst), .int_from_ptr => try self.airIntFromPtr(inst), - .ret => try self.airRet(inst), - .ret_safe => try self.airRet(inst), // TODO + .ret => try self.airRet(inst, false), + .ret_safe => try self.airRet(inst, true), .ret_load => try self.airRetLoad(inst), .store => try self.airStore(inst, false), .store_safe => try self.airStore(inst, true), @@ -2209,18 +2222,25 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { 0, Type.usize, .{ .register_offset = .{ .reg = data_reg, .off = data_off } }, + .{}, + ); + try self.genSetMem( + .{ .reg = ret_reg }, + 8, + Type.usize, + .{ .immediate = tag_name.len }, + .{}, ); - try self.genSetMem(.{ .reg = ret_reg }, 8, Type.usize, .{ .immediate = tag_name.len }); exitlude_jump_reloc.* = try self.asmJmpReloc(undefined); - try self.performReloc(skip_reloc); + self.performReloc(skip_reloc); data_off += @intCast(tag_name.len + 1); } try self.airTrap(); - for (exitlude_jump_relocs) |reloc| try self.performReloc(reloc); + for (exitlude_jump_relocs) |reloc| self.performReloc(reloc); try self.asmOpOnly(.{ ._, .ret }); }, else => return self.fail( @@ -2651,7 +2671,7 @@ pub fn spillRegisters(self: *Self, comptime registers: []const Register) !void { /// This can have a side effect of spilling instructions to the stack to free up a register. fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register { const reg = try self.register_manager.allocReg(null, self.regClassForType(ty)); - try self.genSetReg(reg, ty, mcv); + try self.genSetReg(reg, ty, mcv, .{}); return reg; } @@ -2666,7 +2686,7 @@ fn copyToRegisterWithInstTracking( mcv: MCValue, ) !MCValue { const reg: Register = try self.register_manager.allocReg(reg_owner, self.regClassForType(ty)); - try self.genSetReg(reg, ty, mcv); + try self.genSetReg(reg, ty, mcv, .{}); return MCValue{ .register = reg }; } @@ -2919,7 +2939,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { 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); + try self.genCopy(min_ty, dst_mcv, src_mcv, .{}); break :dst dst_mcv; }; @@ -2954,7 +2974,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { if (high_bits > 0) { try self.truncateRegister(src_ty, high_reg); const high_ty = if (dst_int_info.bits >= 64) Type.usize else dst_ty; - try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }); + try self.genCopy(high_ty, high_mcv, .{ .register = high_reg }, .{}); } if (dst_limbs_len > src_limbs_len) try self.genInlineMemset( @@ -2966,6 +2986,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sa }, Type.isize, extend_mcv, + Type.u8, .{ .immediate = 63 }, ); break :extend extend_mcv; @@ -2973,6 +2994,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { .unsigned => .{ .immediate = 0 }, }, .{ .immediate = (dst_limbs_len - src_limbs_len) * 8 }, + .{}, ); break :result dst_mcv; @@ -3006,9 +3028,13 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); - try self.genCopy(dst_ty, dst_mcv, src_mcv); + try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); break :dst dst_mcv; - } else return self.fail("TODO implement trunc from {} to {}", .{ src_ty.fmt(mod), dst_ty.fmt(mod) }); + } else dst: { + const dst_mcv = try self.allocRegOrMem(inst, true); + try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); + break :dst dst_mcv; + }; if (dst_ty.zigTypeTag(mod) == .Vector) { assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod)); @@ -3082,11 +3108,15 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { // when truncating a `u16` to `u5`, for example, those top 3 bits in the result // have to be removed. this only happens if the dst if not a power-of-two size. if (dst_abi_size <= 8) { - if (self.regExtraBits(dst_ty) > 0) try self.truncateRegister(dst_ty, dst_mcv.register.to64()); + if (self.regExtraBits(dst_ty) > 0) { + try self.truncateRegister(dst_ty, dst_mcv.register.to64()); + } } else if (dst_abi_size <= 16) { const dst_info = dst_ty.intInfo(mod); const high_ty = try mod.intType(dst_info.signedness, dst_info.bits - 64); - if (self.regExtraBits(high_ty) > 0) try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); + if (self.regExtraBits(high_ty) > 0) { + try self.truncateRegister(high_ty, dst_mcv.register_pair[1].to64()); + } } break :result dst_mcv; @@ -3116,7 +3146,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); const ptr_ty = self.typeOf(bin_op.lhs); - try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }); + try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, .{ .air_ref = bin_op.lhs }, .{}); const len_ty = self.typeOf(bin_op.rhs); try self.genSetMem( @@ -3124,6 +3154,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { @intCast(ptr_ty.abiSize(mod)), len_ty, .{ .air_ref = bin_op.rhs }, + .{}, ); const result = MCValue{ .load_frame = .{ .index = frame_index } }; @@ -3161,9 +3192,9 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { const hi_ty = try mod.intType(.unsigned, @intCast((dst_ty.bitSize(mod) - 1) % 64 + 1)); const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); - try self.genSetReg(tmp_reg, hi_ty, hi_mcv); + try self.genSetReg(tmp_reg, hi_ty, hi_mcv, .{}); try self.truncateRegister(dst_ty, tmp_reg); - try self.genCopy(hi_ty, hi_mcv, .{ .register = tmp_reg }); + try self.genCopy(hi_ty, hi_mcv, .{ .register = tmp_reg }, .{}); } } } @@ -3344,7 +3375,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { .resurrect = true, .close_scope = true, }); - try self.performReloc(signed_div_floor_state.reloc); + self.performReloc(signed_div_floor_state.reloc); const dst_mcv = try self.genCall( .{ .lib = .{ .return_type = dst_ty.toIntern(), @@ -3429,7 +3460,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { }; try self.spillEflagsIfOccupied(); - try self.spillRegisters(&.{ .rax, .rdx }); + try self.spillRegisters(&.{ .rax, .rcx, .rdx }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); + 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); @@ -3471,10 +3505,22 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { const reg_extra_bits = self.regExtraBits(ty); const cc: Condition = if (ty.isSignedInt(mod)) cc: { if (reg_extra_bits > 0) { - try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); + try self.genShiftBinOpMir( + .{ ._l, .sa }, + ty, + dst_mcv, + Type.u8, + .{ .immediate = reg_extra_bits }, + ); } - try self.genSetReg(limit_reg, ty, dst_mcv); - try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genSetReg(limit_reg, ty, dst_mcv, .{}); + try self.genShiftBinOpMir( + .{ ._r, .sa }, + ty, + limit_mcv, + Type.u8, + .{ .immediate = reg_bits - 1 }, + ); try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, }); @@ -3488,6 +3534,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { .{ ._l, .sa }, ty, shifted_rhs_mcv, + Type.u8, .{ .immediate = reg_extra_bits }, ); try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, shifted_rhs_mcv); @@ -3496,7 +3543,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { } else cc: { try self.genSetReg(limit_reg, ty, .{ .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - ty.bitSize(mod)), - }); + }, .{}); try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv); if (reg_extra_bits > 0) { @@ -3513,9 +3560,13 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { registerAlias(limit_reg, cmov_abi_size), ); - if (reg_extra_bits > 0 and ty.isSignedInt(mod)) { - try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); - } + if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( + .{ ._r, .sa }, + ty, + dst_mcv, + Type.u8, + .{ .immediate = reg_extra_bits }, + ); return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3554,10 +3605,22 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { const reg_extra_bits = self.regExtraBits(ty); const cc: Condition = if (ty.isSignedInt(mod)) cc: { if (reg_extra_bits > 0) { - try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); + try self.genShiftBinOpMir( + .{ ._l, .sa }, + ty, + dst_mcv, + Type.u8, + .{ .immediate = reg_extra_bits }, + ); } - try self.genSetReg(limit_reg, ty, dst_mcv); - try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genSetReg(limit_reg, ty, dst_mcv, .{}); + try self.genShiftBinOpMir( + .{ ._r, .sa }, + ty, + limit_mcv, + Type.u8, + .{ .immediate = reg_bits - 1 }, + ); try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, }); @@ -3571,13 +3634,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { .{ ._l, .sa }, ty, shifted_rhs_mcv, + Type.u8, .{ .immediate = reg_extra_bits }, ); try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, shifted_rhs_mcv); } else try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); break :cc .o; } else cc: { - try self.genSetReg(limit_reg, ty, .{ .immediate = 0 }); + try self.genSetReg(limit_reg, ty, .{ .immediate = 0 }, .{}); try self.genBinOpMir(.{ ._, .sub }, ty, dst_mcv, rhs_mcv); break :cc .c; }; @@ -3589,9 +3653,13 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { registerAlias(limit_reg, cmov_abi_size), ); - if (reg_extra_bits > 0 and ty.isSignedInt(mod)) { - try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits }); - } + if (reg_extra_bits > 0 and ty.isSignedInt(mod)) try self.genShiftBinOpMir( + .{ ._r, .sa }, + ty, + dst_mcv, + Type.u8, + .{ .immediate = reg_extra_bits }, + ); return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -3685,9 +3753,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { .{ty.fmt(mod)}, ); - try self.spillRegisters(&.{ .rax, .rdx }); - const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); - defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); + try self.spillRegisters(&.{ .rax, .rcx, .rdx }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); const lhs_mcv = try self.resolveInst(bin_op.lhs); const lhs_lock = switch (lhs_mcv) { @@ -3710,9 +3778,15 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { const reg_bits = self.regBitSize(ty); const cc: Condition = if (ty.isSignedInt(mod)) cc: { - try self.genSetReg(limit_reg, ty, lhs_mcv); + try self.genSetReg(limit_reg, ty, lhs_mcv, .{}); try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv); - try self.genShiftBinOpMir(.{ ._r, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 }); + try self.genShiftBinOpMir( + .{ ._r, .sa }, + ty, + limit_mcv, + Type.u8, + .{ .immediate = reg_bits - 1 }, + ); try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, .{ .immediate = (@as(u64, 1) << @intCast(reg_bits - 1)) - 1, }); @@ -3720,7 +3794,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { } else cc: { try self.genSetReg(limit_reg, ty, .{ .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - reg_bits), - }); + }, .{}); break :cc .c; }; @@ -3747,6 +3821,9 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}), .Int => { try self.spillEflagsIfOccupied(); + try self.spillRegisters(&.{ .rcx, .rdi, .rsi }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rcx, .rdi, .rsi }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); const partial_mcv = try self.genBinOp(null, switch (tag) { .add_with_overflow => .add, @@ -3776,12 +3853,14 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(1, mod)), Type.u1, .{ .eflags = cc }, + .{}, ); try self.genSetMem( .{ .frame = frame_index }, @intCast(tuple_ty.structFieldOffset(0, mod)), ty, partial_mcv, + .{}, ); break :result .{ .load_frame = .{ .index = frame_index } }; } @@ -3808,8 +3887,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}), .Int => { try self.spillEflagsIfOccupied(); + try self.spillRegisters(&.{ .rcx, .rdi, .rsi }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rcx, .rdi, .rsi }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); - try self.register_manager.getReg(.rcx, null); const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -3849,12 +3930,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(1, mod)), tuple_ty.structFieldType(1, mod), .{ .eflags = cc }, + .{}, ); try self.genSetMem( .{ .frame = frame_index }, @intCast(tuple_ty.structFieldOffset(0, mod)), tuple_ty.structFieldType(0, mod), partial_mcv, + .{}, ); break :result .{ .load_frame = .{ .index = frame_index } }; } @@ -3896,7 +3979,7 @@ fn genSetFrameTruncatedOverflowCompare( const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_bits); const temp_regs = - try self.register_manager.allocRegs(3, .{ null, null, null }, abi.RegisterClass.gp); + try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs); defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); @@ -3909,7 +3992,7 @@ fn genSetFrameTruncatedOverflowCompare( src_mcv.address().offset(int_info.bits / 64 * 8).deref() else src_mcv; - try self.genSetReg(scratch_reg, limb_ty, hi_limb_mcv); + try self.genSetReg(scratch_reg, limb_ty, hi_limb_mcv, .{}); try self.truncateRegister(hi_ty, scratch_reg); try self.genBinOpMir(.{ ._, .cmp }, limb_ty, .{ .register = scratch_reg }, hi_limb_mcv); @@ -3925,18 +4008,26 @@ fn genSetFrameTruncatedOverflowCompare( } const payload_off: i32 = @intCast(tuple_ty.structFieldOffset(0, mod)); - if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv); + if (hi_limb_off > 0) try self.genSetMem( + .{ .frame = frame_index }, + payload_off, + rest_ty, + src_mcv, + .{}, + ); try self.genSetMem( .{ .frame = frame_index }, payload_off + hi_limb_off, limb_ty, .{ .register = scratch_reg }, + .{}, ); try self.genSetMem( .{ .frame = frame_index }, @intCast(tuple_ty.structFieldOffset(1, mod)), tuple_ty.structFieldType(1, mod), if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne }, + .{}, ); } @@ -3950,11 +4041,157 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { .Vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(mod)}), .Int => result: { const dst_info = dst_ty.intInfo(mod); + if (dst_info.bits > 128 and dst_info.signedness == .unsigned) { + const slow_inc = self.hasFeature(.slow_incdec); + const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); + const limb_len = std.math.divCeil(u32, abi_size, 8) catch unreachable; + + try self.spillRegisters(&.{ .rax, .rcx, .rdx }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rax, .rcx, .rdx }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.genInlineMemset( + dst_mcv.address(), + .{ .immediate = 0 }, + .{ .immediate = tuple_ty.abiSize(mod) }, + .{}, + ); + const lhs_mcv = try self.resolveInst(bin_op.lhs); + const rhs_mcv = try self.resolveInst(bin_op.rhs); + + const temp_regs = + try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); + const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); + defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); + + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[0].to32(), temp_regs[0].to32()); + + const outer_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[1].to64(), .{ + .base = .{ .frame = rhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = rhs_mcv.load_frame.off, + } }, + }); + try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); + const skip_inner = try self.asmJccReloc(.z, undefined); + + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[2].to32(), temp_regs[2].to32()); + try self.asmRegisterRegister(.{ ._, .mov }, temp_regs[3].to32(), temp_regs[0].to32()); + try self.asmRegisterRegister(.{ ._, .xor }, .ecx, .ecx); + try self.asmRegisterRegister(.{ ._, .xor }, .edx, .edx); + + const inner_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterImmediate(.{ ._r, .sh }, .cl, Immediate.u(1)); + try self.asmMemoryRegister(.{ ._, .adc }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[3].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off + + @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), + } }, + }, .rdx); + try self.asmSetccRegister(.c, .cl); + + try self.asmRegisterMemory(.{ ._, .mov }, .rax, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[2].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }); + try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); + + try self.asmRegisterImmediate(.{ ._r, .sh }, .ch, Immediate.u(1)); + try self.asmMemoryRegister(.{ ._, .adc }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[3].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off + + @as(i32, @intCast(tuple_ty.structFieldOffset(0, mod))), + } }, + }, .rax); + try self.asmSetccRegister(.c, .ch); + + if (slow_inc) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), Immediate.u(1)); + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32()); + try self.asmRegister(.{ ._, .inc }, temp_regs[3].to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[3].to32(), + Immediate.u(limb_len), + ); + _ = try self.asmJccReloc(.b, inner_loop); + + try self.asmRegisterRegister(.{ ._, .@"or" }, .rdx, .rcx); + const overflow = try self.asmJccReloc(.nz, undefined); + const overflow_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[2].to32(), + Immediate.u(limb_len), + ); + const no_overflow = try self.asmJccReloc(.nb, undefined); + if (slow_inc) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32()); + } + try self.asmMemoryImmediate(.{ ._, .cmp }, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[2].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off - 8, + } }, + }, Immediate.u(0)); + _ = try self.asmJccReloc(.z, overflow_loop); + self.performReloc(overflow); + try self.asmMemoryImmediate(.{ ._, .mov }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .byte, + .disp = dst_mcv.load_frame.off + + @as(i32, @intCast(tuple_ty.structFieldOffset(1, mod))), + } }, + }, Immediate.u(1)); + self.performReloc(no_overflow); + + self.performReloc(skip_inner); + if (slow_inc) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[0].to32(), + Immediate.u(limb_len), + ); + _ = try self.asmJccReloc(.b, outer_loop); + + break :result dst_mcv; + } + const lhs_active_bits = self.activeIntBits(bin_op.lhs); const rhs_active_bits = self.activeIntBits(bin_op.rhs); const src_bits = @max(lhs_active_bits, rhs_active_bits, dst_info.bits / 2); const src_ty = try mod.intType(dst_info.signedness, src_bits); - if (src_bits > 64 and src_bits <= 128 and dst_info.bits > 64 and dst_info.bits <= 128) switch (dst_info.signedness) { .signed => { @@ -3976,6 +4213,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(0, mod)), tuple_ty.structFieldType(0, mod), result, + .{}, ); try self.asmMemoryImmediate( .{ ._, .cmp }, @@ -3987,6 +4225,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(1, mod)), tuple_ty.structFieldType(1, mod), .{ .eflags = .ne }, + .{}, ); try self.freeValue(overflow); break :result dst_mcv; @@ -4098,19 +4337,23 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(0, mod)), tuple_ty.structFieldType(0, mod), .{ .register_pair = .{ .rax, .rdx } }, + .{}, ); try self.genSetMem( .{ .frame = dst_mcv.load_frame.index }, @intCast(tuple_ty.structFieldOffset(1, mod)), tuple_ty.structFieldType(1, mod), .{ .register = tmp_regs[1] }, + .{}, ); break :result dst_mcv; }, }; try self.spillEflagsIfOccupied(); - try self.spillRegisters(&.{ .rax, .rdx }); + try self.spillRegisters(&.{ .rax, .rcx, .rdx, .rdi, .rsi }); + const reg_locks = self.register_manager.lockRegsAssumeUnused(5, .{ .rax, .rcx, .rdx, .rdi, .rsi }); + defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); const cc: Condition = switch (dst_info.signedness) { .unsigned => .c, @@ -4149,12 +4392,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { @intCast(tuple_ty.structFieldOffset(0, mod)), tuple_ty.structFieldType(0, mod), partial_mcv, + .{}, ); try self.genSetMem( .{ .frame = frame_index }, @intCast(tuple_ty.structFieldOffset(1, mod)), tuple_ty.structFieldType(1, mod), .{ .immediate = 0 }, // cc being set is impossible + .{}, ); } else try self.genSetFrameTruncatedOverflowCompare( tuple_ty, @@ -4182,7 +4427,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{}); } - try self.genSetReg(.rax, ty, lhs); + try self.genSetReg(.rax, ty, lhs, .{}); switch (tag[1]) { else => unreachable, .mul => {}, @@ -4311,6 +4556,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { tmp_reg, tmp_ty, .{ .load_frame = .{ .index = frame_addr.index, .off = off } }, + .{}, ); try self.truncateRegister(lhs_ty, tmp_reg); try self.genSetMem( @@ -4318,6 +4564,7 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { off, tmp_ty, .{ .register = tmp_reg }, + .{}, ); }, else => {}, @@ -4578,7 +4825,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { try self.genCopy(pl_ty, pl_mcv, switch (opt_mcv) { else => opt_mcv, .register_overflow => |ro| .{ .register = ro.reg }, - }); + }, .{}); break :result pl_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4625,7 +4872,13 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const pl_ty = dst_ty.childType(mod); const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); - try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 }); + try self.genSetMem( + .{ .reg = dst_mcv.getReg().? }, + pl_abi_size, + Type.bool, + .{ .immediate = 1 }, + .{}, + ); break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4660,6 +4913,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sh }, err_union_ty, result, + Type.u8, .{ .immediate = @as(u6, @intCast(err_off * 8)) }, ) else try self.truncateRegister(Type.anyerror, result.register); break :result result; @@ -4817,6 +5071,7 @@ fn genUnwrapErrUnionPayloadMir( .{ ._r, .sh }, err_union_ty, result_mcv, + Type.u8, .{ .immediate = @as(u6, @intCast(payload_off * 8)) }, ) else try self.truncateRegister(payload_ty, result_mcv.register); break :result if (payload_in_gp) @@ -4891,7 +5146,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { defer if (pl_lock) |lock| self.register_manager.unlockReg(lock); const opt_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(pl_ty, opt_mcv, pl_mcv); + try self.genCopy(pl_ty, opt_mcv, pl_mcv, .{}); if (!same_repr) { const pl_abi_size: i32 = @intCast(pl_ty.abiSize(mod)); @@ -4941,8 +5196,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); - try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand); - try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }); + try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand, .{}); + try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 }, .{}); break :result .{ .load_frame = .{ .index = frame_index } }; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4963,9 +5218,9 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(eu_ty, mod)); const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, mod)); const err_off: i32 = @intCast(errUnionErrorOffset(pl_ty, mod)); - try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef); + try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef, .{}); const operand = try self.resolveInst(ty_op.operand); - try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand); + try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand, .{}); break :result .{ .load_frame = .{ .index = frame_index } }; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4979,7 +5234,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { const dst_mcv = try self.allocRegOrMem(inst, true); const dst_ty = self.typeOfIndex(inst); - try self.genCopy(dst_ty, dst_mcv, src_mcv); + try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); break :result dst_mcv; }; return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); @@ -4999,7 +5254,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result len_mcv; const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(Type.usize, dst_mcv, len_mcv); + try self.genCopy(Type.usize, dst_mcv, len_mcv, .{}); break :result dst_mcv; }, else => return self.fail("TODO implement slice_len for {}", .{src_mcv}), @@ -5063,7 +5318,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi // Optimisation: if index MCValue is an immediate, we can multiply in `comptime` // and set the register directly to the scaled offset as an immediate. const reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); - try self.genSetReg(reg, index_ty, .{ .immediate = imm * elem_size }); + try self.genSetReg(reg, index_ty, .{ .immediate = imm * elem_size }, .{}); break :blk reg; }, else => { @@ -5103,7 +5358,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { defer self.register_manager.unlockReg(offset_reg_lock); const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); - try self.genSetReg(addr_reg, Type.usize, slice_mcv); + try self.genSetReg(addr_reg, Type.usize, slice_mcv, .{}); // TODO we could allocate register here, but need to expect addr register and potentially // offset register. try self.genBinOpMir(.{ ._, .add }, slice_ptr_field_type, .{ .register = addr_reg }, .{ @@ -5167,11 +5422,26 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { else => try self.copyToTmpRegister(index_ty, index_mcv), }; switch (array_mcv) { - .register => |array_reg| try self.asmRegisterRegister( - .{ ._, .bt }, - array_reg.to64(), - index_reg.to64(), - ), + .register => |array_reg| switch (array_reg.class()) { + .general_purpose => try self.asmRegisterRegister( + .{ ._, .bt }, + array_reg.to64(), + index_reg.to64(), + ), + .sse => { + const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); + try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); + try self.asmMemoryRegister( + .{ ._, .bt }, + .{ + .base = .{ .frame = frame_index }, + .mod = .{ .rm = .{ .size = .qword } }, + }, + index_reg.to64(), + ); + }, + else => unreachable, + }, .load_frame => try self.asmMemoryRegister( .{ ._, .bt }, try array_mcv.mem(self, .qword), @@ -5205,7 +5475,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { switch (array_mcv) { .register => { const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod)); - try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv); + try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array_mcv, .{}); try self.asmRegisterMemory( .{ ._, .lea }, addr_reg, @@ -5225,7 +5495,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .load_direct, .load_got, .load_tlv, - => try self.genSetReg(addr_reg, Type.usize, array_mcv.address()), + => try self.genSetReg(addr_reg, Type.usize, array_mcv.address(), .{}), .lea_symbol, .lea_direct, .lea_tlv => unreachable, else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{ @tagName(array_mcv), array_ty.fmt(mod), @@ -5245,7 +5515,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .{ .register = addr_reg }, .{ .register = offset_reg }, ); - try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); + try self.genCopy(elem_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); break :result dst_mcv; }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); @@ -5385,7 +5655,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { } else ptr; const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); - try self.store(ptr_tag_ty, adjusted_ptr, tag); + try self.store(ptr_tag_ty, adjusted_ptr, tag, .{}); return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -5424,7 +5694,10 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { }); } - return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand}); + return self.fail( + "TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", + .{operand}, + ); }, .register => { const shift: u6 = if (layout.tag_align.compare(.lt, layout.payload_align)) @@ -5432,7 +5705,13 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { else 0; const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand); - try self.genShiftBinOpMir(.{ ._r, .sh }, Type.usize, result, .{ .immediate = shift }); + try self.genShiftBinOpMir( + .{ ._r, .sh }, + Type.usize, + result, + Type.u8, + .{ .immediate = shift }, + ); break :blk MCValue{ .register = registerAlias(result.register, @intCast(layout.tag_size)), }; @@ -5448,47 +5727,85 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { const mod = self.bin_file.comp.module.?; const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; const result = result: { + try self.spillEflagsIfOccupied(); + const dst_ty = self.typeOfIndex(inst); const src_ty = self.typeOf(ty_op.operand); if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{ src_ty.fmt(mod), }); - const src_bits: u32 = @intCast(src_ty.bitSize(mod)); + const src_mcv = try self.resolveInst(ty_op.operand); + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, + else => src_mcv, + }; + const mat_src_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); + defer self.register_manager.unlockReg(dst_lock); + + const abi_size: u31 = @intCast(src_ty.abiSize(mod)); + const src_bits: u31 = @intCast(src_ty.bitSize(mod)); const has_lzcnt = self.hasFeature(.lzcnt); - if (src_bits > 64 and !has_lzcnt) { - var callee_buf: ["__clz?i2".len]u8 = undefined; - const result = try self.genCall(.{ .lib = .{ - .return_type = .i32_type, - .param_types = &.{src_ty.toIntern()}, - .callee = std.fmt.bufPrint(&callee_buf, "__clz{c}i2", .{ - intCompilerRtAbiName(src_bits), - }) catch unreachable, - } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); - if (src_bits < 128) try self.asmRegisterImmediate( - .{ ._, .sub }, - result.register, - Immediate.u(128 - src_bits), - ); - break :result result; + if (src_bits > @as(u32, if (has_lzcnt) 128 else 64)) { + const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; + const extra_bits = abi_size * 8 - src_bits; + + const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); + const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); + defer self.register_manager.unlockReg(index_lock); + + try self.asmRegisterImmediate(.{ ._, .mov }, index_reg.to32(), Immediate.u(limbs_len)); + switch (extra_bits) { + 1 => try self.asmRegisterRegister(.{ ._, .xor }, dst_reg.to32(), dst_reg.to32()), + else => try self.asmRegisterImmediate( + .{ ._, .mov }, + dst_reg.to32(), + Immediate.s(@as(i32, extra_bits) - 1), + ), + } + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterRegister(.{ ._, .@"test" }, index_reg.to32(), index_reg.to32()); + const zero = try self.asmJccReloc(.z, undefined); + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .sub }, index_reg.to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .dec }, index_reg.to32()); + } + try self.asmMemoryImmediate(.{ ._, .cmp }, .{ + .base = .{ .frame = src_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = index_reg.to64(), + .scale = .@"8", + .disp = src_mcv.load_frame.off, + } }, + }, Immediate.u(0)); + _ = try self.asmJccReloc(.e, loop); + try self.asmRegisterMemory(.{ ._, .bsr }, dst_reg.to64(), .{ + .base = .{ .frame = src_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = index_reg.to64(), + .scale = .@"8", + .disp = src_mcv.load_frame.off, + } }, + }); + self.performReloc(zero); + try self.asmRegisterImmediate(.{ ._l, .sh }, index_reg.to32(), Immediate.u(6)); + try self.asmRegisterRegister(.{ ._, .add }, index_reg.to32(), dst_reg.to32()); + try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to32(), Immediate.u(src_bits - 1)); + try self.asmRegisterRegister(.{ ._, .sub }, dst_reg.to32(), index_reg.to32()); + break :result dst_mcv; } - const src_mcv = try self.resolveInst(ty_op.operand); - const mat_src_mcv = switch (src_mcv) { - .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, - else => src_mcv, - }; - const mat_src_lock = switch (mat_src_mcv) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); - - const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); - const dst_mcv = MCValue{ .register = dst_reg }; - const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); - defer self.register_manager.unlockReg(dst_lock); - if (has_lzcnt) { if (src_bits <= 8) { const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); @@ -5506,7 +5823,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { if (extra_bits > 0) { try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .immediate = extra_bits }); } - } else if (src_bits <= 128) { + } else { + assert(src_bits <= 128); const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); const tmp_mcv = MCValue{ .register = tmp_reg }; const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); @@ -5539,12 +5857,12 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { dst_mcv, .{ .immediate = 128 - src_bits }, ); - } else return self.fail("TODO airClz of {}", .{src_ty.fmt(mod)}); + } break :result dst_mcv; } - if (src_bits > 64) - return self.fail("TODO airClz of {}", .{src_ty.fmt(mod)}); + assert(src_bits <= 64); + const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2); if (math.isPowerOfTwo(src_bits)) { const imm_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits ^ (src_bits - 1), @@ -5561,7 +5879,6 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg }); } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); - const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2); try self.asmCmovccRegisterRegister( .z, registerAlias(dst_reg, cmov_abi_size), @@ -5588,14 +5905,13 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { .{ .register = wide_reg }, ); - const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2); try self.asmCmovccRegisterRegister( .nz, registerAlias(imm_reg, cmov_abi_size), registerAlias(dst_reg, cmov_abi_size), ); - try self.genSetReg(dst_reg, dst_ty, .{ .immediate = src_bits - 1 }); + try self.genSetReg(dst_reg, dst_ty, .{ .immediate = src_bits - 1 }, .{}); try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .register = imm_reg }); } break :result dst_mcv; @@ -5607,50 +5923,93 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { const mod = self.bin_file.comp.module.?; const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; const result = result: { + try self.spillEflagsIfOccupied(); + const dst_ty = self.typeOfIndex(inst); const src_ty = self.typeOf(ty_op.operand); - if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airClz for {}", .{ + if (src_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement airCtz for {}", .{ src_ty.fmt(mod), }); - const src_bits: u32 = @intCast(src_ty.bitSize(mod)); + const src_mcv = try self.resolveInst(ty_op.operand); + const mat_src_mcv = switch (src_mcv) { + .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, + else => src_mcv, + }; + const mat_src_lock = switch (mat_src_mcv) { + .register => |reg| self.register_manager.lockReg(reg), + else => null, + }; + defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); + const dst_mcv = MCValue{ .register = dst_reg }; + const dst_lock = self.register_manager.lockReg(dst_reg); + defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); + + const abi_size: u31 = @intCast(src_ty.abiSize(mod)); + const src_bits: u31 = @intCast(src_ty.bitSize(mod)); const has_bmi = self.hasFeature(.bmi); - if (src_bits > 64 and !has_bmi) { - var callee_buf: ["__ctz?i2".len]u8 = undefined; - break :result try self.genCall(.{ .lib = .{ - .return_type = .i32_type, - .param_types = &.{src_ty.toIntern()}, - .callee = std.fmt.bufPrint(&callee_buf, "__ctz{c}i2", .{ - intCompilerRtAbiName(src_bits), - }) catch unreachable, - } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}); + if (src_bits > @as(u32, if (has_bmi) 128 else 64)) { + const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; + const extra_bits = abi_size * 8 - src_bits; + + const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); + const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); + defer self.register_manager.unlockReg(index_lock); + + try self.asmRegisterImmediate(.{ ._, .mov }, index_reg.to32(), Immediate.s(-1)); + switch (extra_bits) { + 0 => try self.asmRegisterRegister(.{ ._, .xor }, dst_reg.to32(), dst_reg.to32()), + 1 => try self.asmRegisterRegister(.{ ._, .mov }, dst_reg.to32(), dst_reg.to32()), + else => try self.asmRegisterImmediate( + .{ ._, .mov }, + dst_reg.to32(), + Immediate.s(-@as(i32, extra_bits)), + ), + } + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, index_reg.to32()); + } + try self.asmRegisterImmediate(.{ ._, .cmp }, index_reg.to32(), Immediate.u(limbs_len)); + const zero = try self.asmJccReloc(.nb, undefined); + try self.asmMemoryImmediate(.{ ._, .cmp }, .{ + .base = .{ .frame = src_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = index_reg.to64(), + .scale = .@"8", + .disp = src_mcv.load_frame.off, + } }, + }, Immediate.u(0)); + _ = try self.asmJccReloc(.e, loop); + try self.asmRegisterMemory(.{ ._, .bsf }, dst_reg.to64(), .{ + .base = .{ .frame = src_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = index_reg.to64(), + .scale = .@"8", + .disp = src_mcv.load_frame.off, + } }, + }); + self.performReloc(zero); + try self.asmRegisterImmediate(.{ ._l, .sh }, index_reg.to32(), Immediate.u(6)); + try self.asmRegisterRegister(.{ ._, .add }, dst_reg.to32(), index_reg.to32()); + break :result dst_mcv; } - const src_mcv = try self.resolveInst(ty_op.operand); - const mat_src_mcv = switch (src_mcv) { - .immediate => MCValue{ .register = try self.copyToTmpRegister(src_ty, src_mcv) }, - else => src_mcv, - }; - const mat_src_lock = switch (mat_src_mcv) { - .register => |reg| self.register_manager.lockReg(reg), - else => null, - }; - defer if (mat_src_lock) |lock| self.register_manager.unlockReg(lock); - - const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp); - const dst_mcv = MCValue{ .register = dst_reg }; - const dst_lock = self.register_manager.lockReg(dst_reg); - defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); - const wide_ty = if (src_bits <= 8) Type.u16 else src_ty; - if (self.hasFeature(.bmi)) { + if (has_bmi) { if (src_bits <= 64) { const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0); const masked_mcv = if (extra_bits > 0) masked: { const tmp_mcv = tmp: { if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) break :tmp src_mcv; - try self.genSetReg(dst_reg, wide_ty, src_mcv); + try self.genSetReg(dst_reg, wide_ty, src_mcv, .{}); break :tmp dst_mcv; }; try self.genBinOpMir( @@ -5663,7 +6022,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { break :masked tmp_mcv; } else mat_src_mcv; try self.genBinOpMir(.{ ._, .tzcnt }, wide_ty, dst_mcv, masked_mcv); - } else if (src_bits <= 128) { + } else { + assert(src_bits <= 128); const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); const tmp_mcv = MCValue{ .register = tmp_reg }; const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); @@ -5678,7 +6038,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { else .{ .register = mat_src_mcv.register_pair[1] }; const masked_mcv = if (src_bits < 128) masked: { - try self.genCopy(Type.u64, dst_mcv, hi_mat_src_mcv); + try self.genCopy(Type.u64, dst_mcv, hi_mat_src_mcv, .{}); try self.genBinOpMir( .{ ._, .@"or" }, Type.u64, @@ -5691,12 +6051,11 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { try self.genBinOpMir(.{ ._, .add }, dst_ty, dst_mcv, .{ .immediate = 64 }); try self.genBinOpMir(.{ ._, .tzcnt }, Type.u64, tmp_mcv, lo_mat_src_mcv); try self.asmCmovccRegisterRegister(.nc, dst_reg.to32(), tmp_reg.to32()); - } else return self.fail("TODO airCtz of {}", .{src_ty.fmt(mod)}); + } break :result dst_mcv; } - if (src_bits > 64) return self.fail("TODO airCtz of {}", .{src_ty.fmt(mod)}); - + assert(src_bits <= 64); const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); const width_lock = self.register_manager.lockRegAssumeUnused(width_reg); defer self.register_manager.unlockReg(width_lock); @@ -5793,7 +6152,7 @@ fn genPopCount( if (src_abi_size > 1) src_ty else Type.u32, .{ .register = dst_reg }, if (src_abi_size > 1) src_mcv else src: { - if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv); + if (!dst_contains_src) try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); try self.truncateRegister(try src_ty.toUnsigned(mod), dst_reg); break :src .{ .register = dst_reg }; }, @@ -5816,7 +6175,7 @@ fn genPopCount( else undefined; - if (!dst_contains_src) try self.genSetReg(dst, src_ty, src_mcv); + if (!dst_contains_src) try self.genSetReg(dst, src_ty, src_mcv, .{}); // dst = operand try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst); // tmp = operand @@ -5879,23 +6238,22 @@ fn genByteSwap( ) !MCValue { const mod = self.bin_file.comp.module.?; const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; - const have_movbe = self.hasFeature(.movbe); + const has_movbe = self.hasFeature(.movbe); if (src_ty.zigTypeTag(mod) == .Vector) return self.fail( "TODO implement genByteSwap for {}", .{src_ty.fmt(mod)}, ); - const abi_size: u32 = @intCast(src_ty.abiSize(mod)); + const src_lock = switch (src_mcv) { .register => |reg| self.register_manager.lockRegAssumeUnused(reg), else => null, }; defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + const abi_size: u32 = @intCast(src_ty.abiSize(mod)); switch (abi_size) { - else => return self.fail("TODO implement genByteSwap for {}", .{ - src_ty.fmt(mod), - }), + 0 => unreachable, 1 => return if ((mem_ok or src_mcv.isRegister()) and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv @@ -5928,11 +6286,11 @@ fn genByteSwap( for (dst_regs, 0..) |dst_reg, limb_index| { if (src_mcv.isMemory()) { try self.asmRegisterMemory( - .{ ._, if (have_movbe) .movbe else .mov }, + .{ ._, if (has_movbe) .movbe else .mov }, dst_reg.to64(), try src_mcv.address().offset(@intCast(limb_index * 8)).deref().mem(self, .qword), ); - if (!have_movbe) try self.asmRegister(.{ ._, .bswap }, dst_reg.to64()); + if (!has_movbe) try self.asmRegister(.{ ._, .bswap }, dst_reg.to64()); } else { try self.asmRegisterRegister( .{ ._, .mov }, @@ -5944,9 +6302,85 @@ fn genByteSwap( } return .{ .register_pair = .{ dst_regs[1], dst_regs[0] } }; }, + else => { + const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; + + const temp_regs = + try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); + const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); + defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = try self.allocRegOrMem(inst, false); + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[0].to32(), temp_regs[0].to32()); + try self.asmRegisterImmediate( + .{ ._, .mov }, + temp_regs[1].to32(), + Immediate.u(limbs_len - 1), + ); + + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterMemory( + .{ ._, if (has_movbe) .movbe else .mov }, + temp_regs[2].to64(), + .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, + ); + try self.asmRegisterMemory( + .{ ._, if (has_movbe) .movbe else .mov }, + temp_regs[3].to64(), + .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, + ); + if (!has_movbe) { + try self.asmRegister(.{ ._, .bswap }, temp_regs[2].to64()); + try self.asmRegister(.{ ._, .bswap }, temp_regs[3].to64()); + } + try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, temp_regs[3].to64()); + try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, temp_regs[2].to64()); + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), Immediate.u(1)); + try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); + try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); + } + try self.asmRegisterRegister(.{ ._, .cmp }, temp_regs[0].to32(), temp_regs[1].to32()); + _ = try self.asmJccReloc(.be, loop); + return dst_mcv; + }, } - const dst_mcv: MCValue = if (mem_ok and have_movbe and src_mcv.isRegister()) + const dst_mcv: MCValue = if (mem_ok and has_movbe and src_mcv.isRegister()) try self.allocRegOrMem(inst, true) else .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.gp) }; @@ -5954,7 +6388,7 @@ fn genByteSwap( const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register); defer self.register_manager.unlockReg(dst_lock); - try self.genSetReg(dst_reg, src_ty, src_mcv); + try self.genSetReg(dst_reg, src_ty, src_mcv, .{}); switch (abi_size) { else => unreachable, 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }), @@ -5969,20 +6403,20 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; const src_ty = self.typeOf(ty_op.operand); - const abi_size: u32 = @intCast(src_ty.abiSize(mod)); - const bit_size: u32 = @intCast(src_ty.bitSize(mod)); + const src_bits: u32 = @intCast(src_ty.bitSize(mod)); const src_mcv = try self.resolveInst(ty_op.operand); const dst_mcv = try self.genByteSwap(inst, src_ty, src_mcv, true); - - const extra_bits = abi_size * 8 - bit_size; - const signedness: std.builtin.Signedness = - if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned; - if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { - .signed => .{ ._r, .sa }, - .unsigned => .{ ._r, .sh }, - }, src_ty, dst_mcv, .{ .immediate = extra_bits }); - + try self.genShiftBinOpMir( + .{ ._r, switch (if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned) { + .signed => .sa, + .unsigned => .sh, + } }, + src_ty, + dst_mcv, + if (src_bits > 256) Type.u16 else Type.u8, + .{ .immediate = src_ty.abiSize(mod) * 8 - src_bits }, + ); return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); } @@ -6004,8 +6438,8 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock); const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); - const tmp_lock = self.register_manager.lockReg(tmp_reg); - defer if (tmp_lock) |lock| self.register_manager.unlockReg(lock); + const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); + defer self.register_manager.unlockReg(tmp_lock); const limb_abi_size: u32 = @min(abi_size, 8); const tmp = registerAlias(tmp_reg, limb_abi_size); @@ -6103,7 +6537,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { if (extra_bits > 0) try self.genShiftBinOpMir(switch (signedness) { .signed => .{ ._r, .sa }, .unsigned => .{ ._r, .sh }, - }, src_ty, dst_mcv, .{ .immediate = extra_bits }); + }, src_ty, dst_mcv, Type.u8, .{ .immediate = extra_bits }); return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); } @@ -6127,7 +6561,7 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) if (!std.meta.eql(src_mcv, dst_mcv) or !self.reuseOperand(inst, operand, 0, src_mcv)) try self.register_manager.getReg(.st0, inst); - try self.genCopy(ty, dst_mcv, src_mcv); + try self.genCopy(ty, dst_mcv, src_mcv, .{}); switch (tag) { .neg => try self.asmOpOnly(.{ .f_, .chs }), .abs => try self.asmOpOnly(.{ .f_, .abs }), @@ -6344,7 +6778,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro const mod = self.bin_file.comp.module.?; const mir_tag = self.getRoundTag(ty) orelse { const result = try self.genRoundLibcall(ty, src_mcv, mode); - return self.genSetReg(dst_reg, ty, result); + return self.genSetReg(dst_reg, ty, result, .{}); }; const abi_size: u32 = @intCast(ty.abiSize(mod)); const dst_alias = registerAlias(dst_reg, abi_size); @@ -6391,6 +6825,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { else => null, .Int => switch (ty.abiSize(mod)) { + 0 => unreachable, 1...8 => { try self.spillEflagsIfOccupied(); const src_mcv = try self.resolveInst(ty_op.operand); @@ -6435,7 +6870,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); - try self.genCopy(ty, dst_mcv, src_mcv); + try self.genCopy(ty, dst_mcv, src_mcv, .{}); break :dst dst_mcv; }; const dst_regs = dst_mcv.register_pair; @@ -6456,7 +6891,66 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { break :result dst_mcv; }, - else => return self.fail("TODO implement abs for {}", .{ty.fmt(mod)}), + else => { + const abi_size: u31 = @intCast(ty.abiSize(mod)); + const limb_len = std.math.divCeil(u31, abi_size, 8) catch unreachable; + + const tmp_regs = + try self.register_manager.allocRegs(3, .{null} ** 3, abi.RegisterClass.gp); + const tmp_locks = self.register_manager.lockRegsAssumeUnused(3, tmp_regs); + defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); + + try self.spillEflagsIfOccupied(); + const src_mcv = try self.resolveInst(ty_op.operand); + const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) + src_mcv + else + try self.allocRegOrMem(inst, false); + + try self.asmMemoryImmediate( + .{ ._, .cmp }, + try dst_mcv.address().offset((limb_len - 1) * 8).deref().mem(self, .qword), + Immediate.u(0), + ); + const positive = try self.asmJccReloc(.ns, undefined); + + try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[0].to32(), tmp_regs[0].to32()); + try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[1].to8(), tmp_regs[1].to8()); + + const neg_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterRegister(.{ ._, .xor }, tmp_regs[2].to32(), tmp_regs[2].to32()); + try self.asmRegisterImmediate(.{ ._r, .sh }, tmp_regs[1].to8(), Immediate.u(1)); + try self.asmRegisterMemory(.{ ._, .sbb }, tmp_regs[2].to64(), .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = tmp_regs[0].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }); + try self.asmSetccRegister(.c, tmp_regs[1].to8()); + try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = tmp_regs[0].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, tmp_regs[2].to64()); + + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .add }, tmp_regs[0].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, tmp_regs[0].to32()); + } + try self.asmRegisterImmediate(.{ ._, .cmp }, tmp_regs[0].to32(), Immediate.u(limb_len)); + _ = try self.asmJccReloc(.b, neg_loop); + + self.performReloc(positive); + break :result dst_mcv; + }, }, .Float => return self.floatSign(inst, ty_op.operand, ty), .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { @@ -6792,9 +7286,9 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn defer self.register_manager.unlockReg(tmp_lock); const hi_mcv = dst_mcv.address().offset(@intCast(val_bit_size / 64 * 8)).deref(); - try self.genSetReg(tmp_reg, Type.usize, hi_mcv); + try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); try self.truncateRegister(val_ty, tmp_reg); - try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); + try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); } } return; @@ -6802,7 +7296,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn 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_size: u31 = @min(val_abi_size, 8); const limb_abi_bits = limb_abi_size * 8; const val_byte_off: i32 = @intCast(ptr_bit_off / limb_abi_bits * limb_abi_size); const val_bit_off = ptr_bit_off % limb_abi_bits; @@ -6850,7 +7344,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn .base = .{ .reg = ptr_reg }, .mod = .{ .rm = .{ .size = Memory.Size.fromSize(val_abi_size), - .disp = val_byte_off + 1, + .disp = val_byte_off + limb_abi_size, } }, }); try self.spillEflagsIfOccupied(); @@ -6863,7 +7357,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn } if (val_extra_bits > 0) try self.truncateRegister(val_ty, dst_reg); - try self.genCopy(val_ty, dst_mcv, .{ .register = dst_reg }); + try self.genCopy(val_ty, dst_mcv, .{ .register = dst_reg }, .{}); } fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { @@ -6878,6 +7372,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .eflags, .register_pair, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, => unreachable, // not a valid pointer .immediate, @@ -6888,7 +7383,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro .lea_got, .lea_tlv, .lea_frame, - => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()), + => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref(), .{}), .memory, .indirect, .load_symbol, @@ -6901,7 +7396,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_lock); - try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); + try self.genCopy(dst_ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }, .{}); }, .air_ref => |ptr_ref| try self.load(dst_mcv, ptr_ty, try self.resolveInst(ptr_ref)), } @@ -6957,6 +7452,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { if (elem_size <= 8) elem_ty else Type.usize, high_mcv, .{ .register = high_reg }, + .{}, ); } break :result dst_mcv; @@ -7019,18 +7515,20 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); defer self.register_manager.unlockReg(tmp_lock); - try self.genSetReg(tmp_reg, limb_ty, src_mcv); + try self.genSetReg(tmp_reg, limb_ty, src_mcv, .{}); switch (limb_i) { 0 => try self.genShiftBinOpMir( .{ ._l, .sh }, limb_ty, tmp_mcv, + Type.u8, .{ .immediate = src_bit_off }, ), 1 => try self.genShiftBinOpMir( .{ ._r, .sh }, limb_ty, tmp_mcv, + Type.u8, .{ .immediate = limb_abi_bits - src_bit_off }, ), else => unreachable, @@ -7050,7 +7548,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In try self.genSetReg(tmp_reg, limb_ty, switch (limb_i) { 0 => src_mcv, else => src_mcv.address().offset(limb_i * limb_abi_size).deref(), - }); + }, .{}); try self.genBinOpMir(.{ ._, .@"and" }, limb_ty, tmp_mcv, .{ .immediate = part_mask }); try self.asmMemoryRegister( .{ ._, .@"or" }, @@ -7061,7 +7559,13 @@ 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 { +fn store( + self: *Self, + ptr_ty: Type, + ptr_mcv: MCValue, + src_mcv: MCValue, + opts: CopyOptions, +) InnerError!void { const mod = self.bin_file.comp.module.?; const src_ty = ptr_ty.childType(mod); if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; @@ -7073,6 +7577,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .eflags, .register_pair, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, => unreachable, // not a valid pointer .immediate, @@ -7083,7 +7588,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr .lea_got, .lea_tlv, .lea_frame, - => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv), + => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv, opts), .memory, .indirect, .load_symbol, @@ -7096,9 +7601,9 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_lock); - try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv); + try self.genCopy(src_ty, .{ .indirect = .{ .reg = addr_reg } }, src_mcv, opts); }, - .air_ref => |ptr_ref| try self.store(ptr_ty, try self.resolveInst(ptr_ref), src_mcv), + .air_ref => |ptr_ref| try self.store(ptr_ty, try self.resolveInst(ptr_ref), src_mcv, opts), } } @@ -7121,7 +7626,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) { try self.packedStore(ptr_ty, ptr_mcv, src_mcv); } else { - try self.store(ptr_ty, ptr_mcv, src_mcv); + try self.store(ptr_ty, ptr_mcv, src_mcv, .{ .safety = safety }); } } return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); @@ -7212,6 +7717,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sh }, Type.usize, dst_mcv, + Type.u8, .{ .immediate = field_off }, ); } @@ -7237,11 +7743,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { const dst_regs: [2]Register = if (field_rc.supersetOf(container_rc) and self.reuseOperand(inst, operand, 0, src_mcv)) src_regs else dst: { const dst_regs = - try self.register_manager.allocRegs(2, .{ null, null }, field_rc); + try self.register_manager.allocRegs(2, .{null} ** 2, field_rc); const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); - try self.genCopy(container_ty, .{ .register_pair = dst_regs }, src_mcv); + try self.genCopy(container_ty, .{ .register_pair = dst_regs }, src_mcv, .{}); break :dst dst_regs; }; const dst_mcv = MCValue{ .register_pair = dst_regs }; @@ -7255,6 +7761,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sh }, Type.u128, dst_mcv, + Type.u8, .{ .immediate = field_off }, ); } @@ -7291,6 +7798,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sh }, Type.usize, dst_mcv, + Type.u8, .{ .immediate = field_off % 64 }, ); } @@ -7345,7 +7853,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_lock); - try self.genCopy(int_ty, dst_mcv, off_mcv); + try self.genCopy(int_ty, dst_mcv, off_mcv, .{}); if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(int_ty, dst_reg); break :result if (field_is_gp) dst_mcv @@ -7359,7 +7867,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { off_mcv else dst: { const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(field_ty, dst_mcv, off_mcv); + try self.genCopy(field_ty, dst_mcv, off_mcv, .{}); break :dst dst_mcv; }; if (field_abi_size * 8 > field_bit_size and dst_mcv.isMemory()) { @@ -7369,9 +7877,9 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { const hi_mcv = dst_mcv.address().offset(@intCast(field_bit_size / 64 * 8)).deref(); - try self.genSetReg(tmp_reg, Type.usize, hi_mcv); + try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); try self.truncateRegister(field_ty, tmp_reg); - try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); + try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); } break :result dst_mcv; } @@ -7502,7 +8010,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: if (maybe_inst) |inst| if (self.reuseOperand(inst, src_air, 0, src_mcv)) break :dst src_mcv; const dst_mcv = try self.allocRegOrMemAdvanced(src_ty, maybe_inst, true); - try self.genCopy(src_ty, dst_mcv, src_mcv); + try self.genCopy(src_ty, dst_mcv, src_mcv, .{}); break :dst dst_mcv; }; const dst_lock = switch (dst_mcv) { @@ -7549,9 +8057,9 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: defer self.register_manager.unlockReg(tmp_lock); const hi_mcv = dst_mcv.address().offset(@intCast(bit_size / 64 * 8)).deref(); - try self.genSetReg(tmp_reg, Type.usize, hi_mcv); + try self.genSetReg(tmp_reg, Type.usize, hi_mcv, .{}); try self.truncateRegister(src_ty, tmp_reg); - try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }); + try self.genCopy(Type.usize, hi_mcv, .{ .register = tmp_reg }, .{}); } } }, @@ -7573,13 +8081,14 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC .register_offset, .eflags, .register_overflow, + .lea_symbol, .lea_direct, .lea_got, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, - .lea_symbol, => unreachable, // unmodifiable destination .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)), .register_pair => unreachable, // unimplemented @@ -7588,7 +8097,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); - try self.genSetReg(addr_reg, Type.usize, dst_mcv.address()); + try self.genSetReg(addr_reg, Type.usize, dst_mcv.address(), .{}); try self.asmMemory(mir_tag, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ .size = Memory.Size.fromSize(abi_size), } } }); @@ -7604,117 +8113,350 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC fn genShiftBinOpMir( self: *Self, tag: Mir.Inst.FixedTag, - ty: Type, + lhs_ty: Type, lhs_mcv: MCValue, - shift_mcv: MCValue, + rhs_ty: Type, + rhs_mcv: MCValue, ) !void { const mod = self.bin_file.comp.module.?; - const rhs_mcv: MCValue = rhs: { - switch (shift_mcv) { - .immediate => |imm| switch (imm) { + const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); + const shift_abi_size: u32 = @intCast(rhs_ty.abiSize(mod)); + try self.spillEflagsIfOccupied(); + + if (abi_size > 16) { + const limbs_len = math.divCeil(u32, abi_size, 8) catch unreachable; + assert(shift_abi_size >= 1 and shift_abi_size <= 2); + + const rcx_lock: ?RegisterLock = switch (rhs_mcv) { + .immediate => |shift_imm| switch (shift_imm) { 0 => return, - else => break :rhs shift_mcv, + else => null, }, - .register => |shift_reg| if (shift_reg == .rcx) break :rhs shift_mcv, + else => lock: { + if (switch (rhs_mcv) { + .register => |rhs_reg| rhs_reg.id() != Register.rcx.id(), + else => true, + }) { + self.register_manager.getRegAssumeFree(.rcx, null); + try self.genSetReg(.rcx, rhs_ty, rhs_mcv, .{}); + } + break :lock self.register_manager.lockReg(.rcx); + }, + }; + defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); + + const temp_regs = try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); + const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); + defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); + + switch (tag[0]) { + ._l => { + try self.asmRegisterImmediate(.{ ._, .mov }, temp_regs[1].to32(), Immediate.u(limbs_len - 1)); + switch (rhs_mcv) { + .immediate => |shift_imm| try self.asmRegisterImmediate( + .{ ._, .mov }, + temp_regs[0].to32(), + Immediate.u(limbs_len - (shift_imm >> 6) - 1), + ), + else => { + try self.asmRegisterRegister( + .{ ._, .movzx }, + temp_regs[2].to32(), + registerAlias(.rcx, shift_abi_size), + ); + try self.asmRegisterImmediate( + .{ ._, .@"and" }, + .cl, + Immediate.u(std.math.maxInt(u6)), + ); + try self.asmRegisterImmediate( + .{ ._r, .sh }, + temp_regs[2].to32(), + Immediate.u(6), + ); + try self.asmRegisterRegister( + .{ ._, .mov }, + temp_regs[0].to32(), + temp_regs[1].to32(), + ); + try self.asmRegisterRegister( + .{ ._, .sub }, + temp_regs[0].to32(), + temp_regs[2].to32(), + ); + }, + } + }, + ._r => { + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[1].to32(), temp_regs[1].to32()); + switch (rhs_mcv) { + .immediate => |shift_imm| try self.asmRegisterImmediate( + .{ ._, .mov }, + temp_regs[0].to32(), + Immediate.u(shift_imm >> 6), + ), + else => { + try self.asmRegisterRegister( + .{ ._, .movzx }, + temp_regs[0].to32(), + registerAlias(.rcx, shift_abi_size), + ); + try self.asmRegisterImmediate( + .{ ._, .@"and" }, + .cl, + Immediate.u(std.math.maxInt(u6)), + ); + try self.asmRegisterImmediate( + .{ ._r, .sh }, + temp_regs[0].to32(), + Immediate.u(6), + ); + }, + } + }, + else => unreachable, + } + + const slow_inc_dec = self.hasFeature(.slow_incdec); + if (switch (rhs_mcv) { + .immediate => |shift_imm| shift_imm >> 6 < limbs_len - 1, + else => true, + }) { + try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[2].to64(), .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }); + const skip = switch (rhs_mcv) { + .immediate => undefined, + else => switch (tag[0]) { + ._l => try self.asmJccReloc(.z, undefined), + ._r => skip: { + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[0].to32(), + Immediate.u(limbs_len - 1), + ); + break :skip try self.asmJccReloc(.nb, undefined); + }, + else => unreachable, + }, + }; + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[3].to64(), .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = switch (tag[0]) { + ._l => lhs_mcv.load_frame.off - 8, + ._r => lhs_mcv.load_frame.off + 8, + else => unreachable, + }, + } }, + }); + switch (rhs_mcv) { + .immediate => |shift_imm| try self.asmRegisterRegisterImmediate( + .{ switch (tag[0]) { + ._l => ._ld, + ._r => ._rd, + else => unreachable, + }, .sh }, + temp_regs[2].to64(), + temp_regs[3].to64(), + Immediate.u(shift_imm & std.math.maxInt(u6)), + ), + else => try self.asmRegisterRegisterRegister(.{ switch (tag[0]) { + ._l => ._ld, + ._r => ._rd, + else => unreachable, + }, .sh }, temp_regs[2].to64(), temp_regs[3].to64(), .cl), + } + try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }, temp_regs[2].to64()); + try self.asmRegisterRegister(.{ ._, .mov }, temp_regs[2].to64(), temp_regs[3].to64()); + switch (tag[0]) { + ._l => { + if (slow_inc_dec) { + try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), Immediate.u(1)); + try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[0].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); + try self.asmRegister(.{ ._, .dec }, temp_regs[0].to32()); + } + _ = try self.asmJccReloc(.nz, loop); + }, + ._r => { + if (slow_inc_dec) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), Immediate.u(1)); + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32()); + try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[0].to32(), + Immediate.u(limbs_len - 1), + ); + _ = try self.asmJccReloc(.b, loop); + }, + else => unreachable, + } + switch (rhs_mcv) { + .immediate => {}, + else => self.performReloc(skip), + } + } + switch (rhs_mcv) { + .immediate => |shift_imm| try self.asmRegisterImmediate( + tag, + temp_regs[2].to64(), + Immediate.u(shift_imm & std.math.maxInt(u6)), + ), + else => try self.asmRegisterRegister(tag, temp_regs[2].to64(), .cl), + } + try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }, temp_regs[2].to64()); + if (tag[0] == ._r and tag[1] == .sa) try self.asmRegisterImmediate( + tag, + temp_regs[2].to64(), + Immediate.u(63), + ); + if (switch (rhs_mcv) { + .immediate => |shift_imm| shift_imm >> 6 > 0, + else => true, + }) { + const skip = switch (rhs_mcv) { + .immediate => undefined, + else => switch (tag[0]) { + ._l => skip: { + try self.asmRegisterRegister( + .{ ._, .@"test" }, + temp_regs[1].to32(), + temp_regs[1].to32(), + ); + break :skip try self.asmJccReloc(.z, undefined); + }, + ._r => skip: { + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[1].to32(), + Immediate.u(limbs_len - 1), + ); + break :skip try self.asmJccReloc(.nb, undefined); + }, + else => unreachable, + }, + }; + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + switch (tag[0]) { + ._l => if (slow_inc_dec) { + try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); + }, + ._r => if (slow_inc_dec) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32()); + }, + else => unreachable, + } + if (tag[0] == ._r and tag[1] == .sa) try self.asmMemoryRegister(.{ ._, .mov }, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }, temp_regs[2].to64()) else try self.asmMemoryImmediate(.{ ._, .mov }, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[1].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }, Immediate.u(0)); + switch (tag[0]) { + ._l => _ = try self.asmJccReloc(.nz, loop), + ._r => { + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[1].to32(), + Immediate.u(limbs_len - 1), + ); + _ = try self.asmJccReloc(.b, loop); + }, + else => unreachable, + } + switch (rhs_mcv) { + .immediate => {}, + else => self.performReloc(skip), + } + } + return; + } + + assert(shift_abi_size == 1); + const shift_mcv: MCValue = shift: { + switch (rhs_mcv) { + .immediate => |shift_imm| switch (shift_imm) { + 0 => return, + else => break :shift rhs_mcv, + }, + .register => |rhs_reg| if (rhs_reg.id() == Register.rcx.id()) + break :shift rhs_mcv, else => {}, } self.register_manager.getRegAssumeFree(.rcx, null); - try self.genSetReg(.cl, Type.u8, shift_mcv); - break :rhs .{ .register = .rcx }; + try self.genSetReg(.cl, rhs_ty, rhs_mcv, .{}); + break :shift .{ .register = .rcx }; }; - - const abi_size: u32 = @intCast(ty.abiSize(mod)); - if (abi_size <= 8) { - switch (lhs_mcv) { - .register => |lhs_reg| switch (rhs_mcv) { - .immediate => |rhs_imm| try self.asmRegisterImmediate( - tag, - registerAlias(lhs_reg, abi_size), - Immediate.u(rhs_imm), - ), - .register => |rhs_reg| try self.asmRegisterRegister( - tag, - registerAlias(lhs_reg, abi_size), - registerAlias(rhs_reg, 1), - ), - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), - }, - .memory, .indirect, .load_frame => { - const lhs_mem: Memory = switch (lhs_mcv) { - .memory => |addr| .{ - .base = .{ .reg = .ds }, - .mod = .{ .rm = .{ - .size = Memory.Size.fromSize(abi_size), - .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse - return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), - } }, - }, - .indirect => |reg_off| .{ - .base = .{ .reg = reg_off.reg }, - .mod = .{ .rm = .{ - .size = Memory.Size.fromSize(abi_size), - .disp = reg_off.off, - } }, - }, - .load_frame => |frame_addr| .{ - .base = .{ .frame = frame_addr.index }, - .mod = .{ .rm = .{ - .size = Memory.Size.fromSize(abi_size), - .disp = frame_addr.off, - } }, - }, - else => unreachable, - }; - switch (rhs_mcv) { - .immediate => |rhs_imm| try self.asmMemoryImmediate( - tag, - lhs_mem, - Immediate.u(rhs_imm), - ), - .register => |rhs_reg| try self.asmMemoryRegister( - tag, - lhs_mem, - registerAlias(rhs_reg, 1), - ), - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), - } - }, - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), - } - } else if (abi_size <= 16) { + if (abi_size > 8) { const info: struct { indices: [2]u31, double_tag: Mir.Inst.FixedTag } = switch (tag[0]) { ._l => .{ .indices = .{ 0, 1 }, .double_tag = .{ ._ld, .sh } }, ._r => .{ .indices = .{ 1, 0 }, .double_tag = .{ ._rd, .sh } }, else => unreachable, }; switch (lhs_mcv) { - .register_pair => |lhs_regs| switch (rhs_mcv) { - .immediate => |rhs_imm| if (rhs_imm > 0 and rhs_imm < 64) { + .register_pair => |lhs_regs| switch (shift_mcv) { + .immediate => |shift_imm| if (shift_imm > 0 and shift_imm < 64) { try self.asmRegisterRegisterImmediate( info.double_tag, lhs_regs[info.indices[1]], lhs_regs[info.indices[0]], - Immediate.u(rhs_imm), + Immediate.u(shift_imm), ); try self.asmRegisterImmediate( tag, lhs_regs[info.indices[0]], - Immediate.u(rhs_imm), + Immediate.u(shift_imm), ); + return; } else { - assert(rhs_imm < 128); + assert(shift_imm < 128); try self.asmRegisterRegister( .{ ._, .mov }, lhs_regs[info.indices[1]], @@ -7729,13 +8471,14 @@ fn genShiftBinOpMir( lhs_regs[info.indices[0]], lhs_regs[info.indices[0]], ); - if (rhs_imm > 64) try self.asmRegisterImmediate( + if (shift_imm > 64) try self.asmRegisterImmediate( tag, lhs_regs[info.indices[1]], - Immediate.u(rhs_imm - 64), + Immediate.u(shift_imm - 64), ); + return; }, - .register => |rhs_reg| { + .register => |shift_reg| { 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); @@ -7752,16 +8495,16 @@ fn genShiftBinOpMir( info.double_tag, lhs_regs[info.indices[1]], lhs_regs[info.indices[0]], - registerAlias(rhs_reg, 1), + registerAlias(shift_reg, 1), ); try self.asmRegisterRegister( tag, lhs_regs[info.indices[0]], - registerAlias(rhs_reg, 1), + registerAlias(shift_reg, 1), ); try self.asmRegisterImmediate( .{ ._, .cmp }, - registerAlias(rhs_reg, 1), + registerAlias(shift_reg, 1), Immediate.u(64), ); try self.asmCmovccRegisterRegister( @@ -7770,19 +8513,17 @@ fn genShiftBinOpMir( lhs_regs[info.indices[0]], ); try self.asmCmovccRegisterRegister(.ae, lhs_regs[info.indices[0]], tmp_reg); + return; }, - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), + else => {}, }, .load_frame => |dst_frame_addr| { 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); - switch (rhs_mcv) { - .immediate => |rhs_imm| if (rhs_imm > 0 and rhs_imm < 64) { + switch (shift_mcv) { + .immediate => |shift_imm| if (shift_imm > 0 and shift_imm < 64) { try self.asmRegisterMemory( .{ ._, .mov }, tmp_reg, @@ -7804,7 +8545,7 @@ fn genShiftBinOpMir( } }, }, tmp_reg, - Immediate.u(rhs_imm), + Immediate.u(shift_imm), ); try self.asmMemoryImmediate( tag, @@ -7815,10 +8556,11 @@ fn genShiftBinOpMir( .disp = dst_frame_addr.off + info.indices[0] * 8, } }, }, - Immediate.u(rhs_imm), + Immediate.u(shift_imm), ); + return; } else { - assert(rhs_imm < 128); + assert(shift_imm < 128); try self.asmRegisterMemory( .{ ._, .mov }, tmp_reg, @@ -7830,10 +8572,10 @@ fn genShiftBinOpMir( } }, }, ); - if (rhs_imm > 64) try self.asmRegisterImmediate( + if (shift_imm > 64) try self.asmRegisterImmediate( tag, tmp_reg, - Immediate.u(rhs_imm - 64), + Immediate.u(shift_imm - 64), ); try self.asmMemoryRegister( .{ ._, .mov }, @@ -7870,8 +8612,9 @@ fn genShiftBinOpMir( tmp_reg, ); } + return; }, - .register => |rhs_reg| { + .register => |shift_reg| { const first_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); const first_lock = self.register_manager.lockRegAssumeUnused(first_reg); @@ -7916,12 +8659,12 @@ fn genShiftBinOpMir( info.double_tag, second_reg, first_reg, - registerAlias(rhs_reg, 1), + registerAlias(shift_reg, 1), ); - try self.asmRegisterRegister(tag, first_reg, registerAlias(rhs_reg, 1)); + try self.asmRegisterRegister(tag, first_reg, registerAlias(shift_reg, 1)); try self.asmRegisterImmediate( .{ ._, .cmp }, - registerAlias(rhs_reg, 1), + registerAlias(shift_reg, 1), Immediate.u(64), ); try self.asmCmovccRegisterRegister(.ae, second_reg, first_reg); @@ -7948,21 +8691,75 @@ fn genShiftBinOpMir( }, first_reg, ); + return; }, - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), + else => {}, } }, - else => return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ - @tagName(lhs_mcv), - @tagName(rhs_mcv), - }), + else => {}, } - } else return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + } else switch (lhs_mcv) { + .register => |lhs_reg| switch (shift_mcv) { + .immediate => |shift_imm| return self.asmRegisterImmediate( + tag, + registerAlias(lhs_reg, abi_size), + Immediate.u(shift_imm), + ), + .register => |shift_reg| return self.asmRegisterRegister( + tag, + registerAlias(lhs_reg, abi_size), + registerAlias(shift_reg, 1), + ), + else => {}, + }, + .memory, .indirect, .load_frame => { + const lhs_mem: Memory = switch (lhs_mcv) { + .memory => |addr| .{ + .base = .{ .reg = .ds }, + .mod = .{ .rm = .{ + .size = Memory.Size.fromSize(abi_size), + .disp = math.cast(i32, @as(i64, @bitCast(addr))) orelse + return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ + @tagName(lhs_mcv), + @tagName(shift_mcv), + }), + } }, + }, + .indirect => |reg_off| .{ + .base = .{ .reg = reg_off.reg }, + .mod = .{ .rm = .{ + .size = Memory.Size.fromSize(abi_size), + .disp = reg_off.off, + } }, + }, + .load_frame => |frame_addr| .{ + .base = .{ .frame = frame_addr.index }, + .mod = .{ .rm = .{ + .size = Memory.Size.fromSize(abi_size), + .disp = frame_addr.off, + } }, + }, + else => unreachable, + }; + switch (shift_mcv) { + .immediate => |shift_imm| return self.asmMemoryImmediate( + tag, + lhs_mem, + Immediate.u(shift_imm), + ), + .register => |shift_reg| return self.asmMemoryRegister( + tag, + lhs_mem, + registerAlias(shift_reg, 1), + ), + else => {}, + } + }, + else => {}, + } + return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{ @tagName(lhs_mcv), - @tagName(rhs_mcv), + @tagName(shift_mcv), }); } @@ -7983,17 +8780,9 @@ fn genShiftBinOp( lhs_ty.fmt(mod), }); - assert(rhs_ty.abiSize(mod) == 1); - try self.spillEflagsIfOccupied(); - - const lhs_abi_size = lhs_ty.abiSize(mod); - if (lhs_abi_size > 16) return self.fail("TODO implement genShiftBinOp for {}", .{ - lhs_ty.fmt(mod), - }); - try self.register_manager.getReg(.rcx, null); - const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx); - defer self.register_manager.unlockReg(rcx_lock); + const rcx_lock = self.register_manager.lockReg(.rcx); + defer if (rcx_lock) |lock| self.register_manager.unlockReg(lock); const lhs_lock = switch (lhs_mcv) { .register => |reg| self.register_manager.lockReg(reg), @@ -8013,7 +8802,7 @@ fn genShiftBinOp( if (self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv)) break :dst lhs_mcv; } const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); - try self.genCopy(lhs_ty, dst_mcv, lhs_mcv); + try self.genCopy(lhs_ty, dst_mcv, lhs_mcv, .{}); break :dst dst_mcv; }; @@ -8028,7 +8817,7 @@ fn genShiftBinOp( .unsigned => .{ ._r, .sh }, }, else => unreachable, - }, lhs_ty, dst_mcv, rhs_mcv); + }, lhs_ty, dst_mcv, rhs_ty, rhs_mcv); return dst_mcv; } @@ -8053,13 +8842,14 @@ fn genMulDivBinOp( const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); assert(self.register_manager.isRegFree(.rax)); + assert(self.register_manager.isRegFree(.rcx)); assert(self.register_manager.isRegFree(.rdx)); assert(self.eflags_inst == null); if (dst_abi_size == 16 and src_abi_size == 16) { 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); + const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx }); + defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock); const mat_lhs_mcv = switch (lhs_mcv) { .load_symbol => mat_lhs_mcv: { @@ -8124,10 +8914,172 @@ fn genMulDivBinOp( else => unreachable, .mul, .mul_wrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2, .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_abi_size != src_abi_size, - } or src_abi_size > 8) return self.fail( - "TODO implement genMulDivBinOp for {s} from {} to {}", - .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, - ); + } or src_abi_size > 8) { + const src_info = src_ty.intInfo(mod); + switch (tag) { + .mul, .mul_wrap => { + const slow_inc = self.hasFeature(.slow_incdec); + const limb_len = std.math.divCeil(u32, src_abi_size, 8) catch unreachable; + + try self.spillRegisters(&.{ .rax, .rcx, .rdx }); + const reg_locks = self.register_manager.lockRegs(3, .{ .rax, .rcx, .rdx }); + defer for (reg_locks) |reg_lock| if (reg_lock) |lock| + self.register_manager.unlockReg(lock); + + const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); + try self.genInlineMemset( + dst_mcv.address(), + .{ .immediate = 0 }, + .{ .immediate = src_abi_size }, + .{}, + ); + + const temp_regs = + try self.register_manager.allocRegs(4, .{null} ** 4, abi.RegisterClass.gp); + const temp_locks = self.register_manager.lockRegsAssumeUnused(4, temp_regs); + defer for (temp_locks) |lock| self.register_manager.unlockReg(lock); + + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[0].to32(), temp_regs[0].to32()); + + const outer_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterMemory(.{ ._, .mov }, temp_regs[1].to64(), .{ + .base = .{ .frame = rhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[0].to64(), + .scale = .@"8", + .disp = rhs_mcv.load_frame.off, + } }, + }); + try self.asmRegisterRegister(.{ ._, .@"test" }, temp_regs[1].to64(), temp_regs[1].to64()); + const skip_inner = try self.asmJccReloc(.z, undefined); + + try self.asmRegisterRegister(.{ ._, .xor }, temp_regs[2].to32(), temp_regs[2].to32()); + try self.asmRegisterRegister(.{ ._, .mov }, temp_regs[3].to32(), temp_regs[0].to32()); + try self.asmRegisterRegister(.{ ._, .xor }, .ecx, .ecx); + try self.asmRegisterRegister(.{ ._, .xor }, .edx, .edx); + + const inner_loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmRegisterImmediate(.{ ._r, .sh }, .cl, Immediate.u(1)); + try self.asmMemoryRegister(.{ ._, .adc }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[3].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, .rdx); + try self.asmSetccRegister(.c, .cl); + + try self.asmRegisterMemory(.{ ._, .mov }, .rax, .{ + .base = .{ .frame = lhs_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[2].to64(), + .scale = .@"8", + .disp = lhs_mcv.load_frame.off, + } }, + }); + try self.asmRegister(.{ ._, .mul }, temp_regs[1].to64()); + + try self.asmRegisterImmediate(.{ ._r, .sh }, .ch, Immediate.u(1)); + try self.asmMemoryRegister(.{ ._, .adc }, .{ + .base = .{ .frame = dst_mcv.load_frame.index }, + .mod = .{ .rm = .{ + .size = .qword, + .index = temp_regs[3].to64(), + .scale = .@"8", + .disp = dst_mcv.load_frame.off, + } }, + }, .rax); + try self.asmSetccRegister(.c, .ch); + + if (slow_inc) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), Immediate.u(1)); + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32()); + try self.asmRegister(.{ ._, .inc }, temp_regs[3].to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[3].to32(), + Immediate.u(limb_len), + ); + _ = try self.asmJccReloc(.b, inner_loop); + + self.performReloc(skip_inner); + if (slow_inc) { + try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + temp_regs[0].to32(), + Immediate.u(limb_len), + ); + _ = try self.asmJccReloc(.b, outer_loop); + + return dst_mcv; + }, + .div_trunc, .div_floor, .div_exact, .rem, .mod => switch (src_info.signedness) { + .signed => {}, + .unsigned => { + const dst_mcv = try self.allocRegOrMemAdvanced(dst_ty, maybe_inst, false); + const manyptr_u32_ty = try mod.ptrType(.{ + .child = .u32_type, + .flags = .{ + .size = .Many, + }, + }); + const manyptr_const_u32_ty = try mod.ptrType(.{ + .child = .u32_type, + .flags = .{ + .size = .Many, + .is_const = true, + }, + }); + _ = try self.genCall(.{ .lib = .{ + .return_type = .void_type, + .param_types = &.{ + manyptr_u32_ty.toIntern(), + manyptr_const_u32_ty.toIntern(), + manyptr_const_u32_ty.toIntern(), + .usize_type, + }, + .callee = switch (tag) { + .div_trunc, + .div_floor, + .div_exact, + => "__udivei4", + .rem, + .mod, + => "__umodei4", + else => unreachable, + }, + } }, &.{ + manyptr_u32_ty, + manyptr_const_u32_ty, + manyptr_const_u32_ty, + Type.usize, + }, &.{ + dst_mcv.address(), + lhs_mcv.address(), + rhs_mcv.address(), + .{ .immediate = src_info.bits }, + }); + return dst_mcv; + }, + }, + else => {}, + } + return self.fail( + "TODO implement genMulDivBinOp for {s} from {} to {}", + .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, + ); + } const ty = if (dst_abi_size <= 8) dst_ty else src_ty; const abi_size = if (dst_abi_size <= 8) dst_abi_size else src_abi_size; @@ -8311,6 +9263,7 @@ fn genBinOp( .div_float, .div_trunc, .div_floor, + .div_exact, => std.fmt.bufPrint(&callee_buf, "__{s}{c}f3", .{ @tagName(air_tag)[0..3], floatCompilerRtAbiName(float_bits), @@ -8464,7 +9417,7 @@ fn genBinOp( else => false, .Float => true, .Vector => switch (lhs_ty.childType(mod).toIntern()) { - .bool_type => false, + .bool_type, .u1_type => false, else => true, }, }; @@ -8490,6 +9443,7 @@ fn genBinOp( const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(mod) and switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Bool => false, .Int => switch (air_tag) { .cmp_lt, .cmp_gte => true, else => false, @@ -8548,14 +9502,14 @@ fn genBinOp( const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs); break :locks .{ locks[0], locks[1] }; }, - else => .{ null, null }, + else => .{null} ** 2, }; defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock); const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) { .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null }, .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs), - else => .{ null, null }, + else => .{null} ** 2, }; defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock); @@ -8581,14 +9535,14 @@ fn genBinOp( if (sse_op and lhs_mcv.isRegister() and self.hasFeature(.avx)) copied_to_dst = false else - try self.genCopy(lhs_ty, dst_mcv, lhs_mcv); + try self.genCopy(lhs_ty, dst_mcv, lhs_mcv, .{}); rhs_mcv = try self.resolveInst(ordered_air[1]); break :dst dst_mcv; }; const dst_locks: [2]?RegisterLock = switch (dst_mcv) { .register => |dst_reg| .{ self.register_manager.lockReg(dst_reg), null }, .register_pair => |dst_regs| self.register_manager.lockRegs(2, dst_regs), - else => .{ null, null }, + else => .{null} ** 2, }; defer for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock); @@ -8596,7 +9550,7 @@ fn genBinOp( const src_mcv: MCValue = if (maybe_mask_reg) |mask_reg| if (self.hasFeature(.avx) and unmat_src_mcv.isRegister() and maybe_inst != null and self.liveness.operandDies(maybe_inst.?, if (flipped) 0 else 1)) unmat_src_mcv else src: { - try self.genSetReg(mask_reg, rhs_ty, unmat_src_mcv); + try self.genSetReg(mask_reg, rhs_ty, unmat_src_mcv, .{}); break :src .{ .register = mask_reg }; } else @@ -8604,7 +9558,7 @@ fn genBinOp( const src_locks: [2]?RegisterLock = switch (src_mcv) { .register => |src_reg| .{ self.register_manager.lockReg(src_reg), null }, .register_pair => |src_regs| self.register_manager.lockRegs(2, src_regs), - else => .{ null, null }, + else => .{null} ** 2, }; defer for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock); @@ -8664,14 +9618,13 @@ fn genBinOp( else => dst: { const dst_regs = try self.register_manager.allocRegs( 2, - .{ null, null }, + .{null} ** 2, abi.RegisterClass.gp, ); - const dst_regs_locks = self.register_manager.lockRegs(2, dst_regs); - defer for (dst_regs_locks) |dst_lock| if (dst_lock) |lock| - self.register_manager.unlockReg(lock); + const dst_regs_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); + defer for (dst_regs_locks) |lock| self.register_manager.unlockReg(lock); - try self.genCopy(lhs_ty, .{ .register_pair = dst_regs }, dst_mcv); + try self.genCopy(lhs_ty, .{ .register_pair = dst_regs }, dst_mcv, .{}); break :dst dst_regs; }, }; @@ -8726,7 +9679,7 @@ fn genBinOp( try self.asmCmovccRegisterRegister(cc, dst_regs[0], src_mcv.register_pair[0]); try self.asmCmovccRegisterRegister(cc, dst_regs[1], src_mcv.register_pair[1]); } - try self.genCopy(lhs_ty, dst_mcv, .{ .register_pair = dst_regs }); + try self.genCopy(lhs_ty, dst_mcv, .{ .register_pair = dst_regs }, .{}); } else { const mat_src_mcv: MCValue = if (switch (resolved_src_mcv) { .immediate, @@ -8799,6 +9752,7 @@ fn genBinOp( .load_tlv, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -8836,7 +9790,17 @@ fn genBinOp( }, ), } - try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }); + try self.genCopy(lhs_ty, dst_mcv, .{ .register = tmp_reg }, .{}); + } + }, + + .cmp_eq, .cmp_neq => { + assert(lhs_ty.isVector(mod) and lhs_ty.childType(mod).toIntern() == .bool_type); + try self.genBinOpMir(.{ ._, .xor }, lhs_ty, dst_mcv, src_mcv); + switch (air_tag) { + .cmp_eq => try self.genUnOpMir(.{ ._, .not }, lhs_ty, dst_mcv), + .cmp_neq => {}, + else => unreachable, } }, @@ -10034,6 +10998,7 @@ fn genBinOpMir( .lea_tlv, .lea_frame, .lea_symbol, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // unmodifiable destination @@ -10068,6 +11033,7 @@ fn genBinOpMir( .dead, .undef, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, => unreachable, .register, .register_pair => try self.asmRegisterRegister( @@ -10209,7 +11175,7 @@ fn genBinOpMir( const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); errdefer self.register_manager.unlockReg(dst_addr_lock); - try self.genSetReg(dst_addr_reg, Type.usize, dst_mcv.address()); + try self.genSetReg(dst_addr_reg, Type.usize, dst_mcv.address(), .{}); break :dst .{ .addr_reg = dst_addr_reg, .addr_lock = dst_addr_lock }; }, .load_frame => null, @@ -10226,6 +11192,7 @@ fn genBinOpMir( .dead, .undef, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -10256,7 +11223,7 @@ fn genBinOpMir( const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); errdefer self.register_manager.unlockReg(src_addr_lock); - try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address()); + try self.genSetReg(src_addr_reg, Type.usize, resolved_src_mcv.address(), .{}); break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; }, }; @@ -10320,6 +11287,7 @@ fn genBinOpMir( .dead, .undef, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -10455,6 +11423,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .lea_got, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // unmodifiable destination @@ -10474,6 +11443,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .undef, .register_pair, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -10557,7 +11527,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M defer self.register_manager.unlockReg(tmp_lock); try self.genIntMulComplexOpMir(dst_ty, tmp_mcv, src_mcv); - try self.genCopy(dst_ty, dst_mcv, tmp_mcv); + try self.genCopy(dst_ty, dst_mcv, tmp_mcv, .{}); }, } } @@ -10580,7 +11550,93 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { .indirect => |reg_off| dst: { self.register_manager.getRegAssumeFree(reg_off.reg, inst); const dst_mcv = try self.allocRegOrMem(inst, false); - try self.genCopy(arg_ty, dst_mcv, src_mcv); + try self.genCopy(arg_ty, dst_mcv, src_mcv, .{}); + break :dst dst_mcv; + }, + .elementwise_regs_then_frame => |regs_frame_addr| dst: { + try self.spillEflagsIfOccupied(); + + const fn_info = mod.typeToFunc(self.fn_type).?; + const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); + const param_int_regs = abi.getCAbiIntParamRegs(cc); + var prev_reg: Register = undefined; + for ( + param_int_regs[param_int_regs.len - regs_frame_addr.regs ..], + 0.., + ) |dst_reg, elem_index| { + assert(self.register_manager.isRegFree(dst_reg)); + if (elem_index > 0) { + try self.asmRegisterImmediate( + .{ ._l, .sh }, + dst_reg.to8(), + Immediate.u(elem_index), + ); + try self.asmRegisterRegister( + .{ ._, .@"or" }, + dst_reg.to8(), + prev_reg.to8(), + ); + } + prev_reg = dst_reg; + } + + const prev_lock = if (regs_frame_addr.regs > 0) + self.register_manager.lockRegAssumeUnused(prev_reg) + else + null; + defer if (prev_lock) |lock| self.register_manager.unlockReg(lock); + + const dst_mcv = try self.allocRegOrMem(inst, false); + if (regs_frame_addr.regs > 0) try self.asmMemoryRegister( + .{ ._, .mov }, + try dst_mcv.mem(self, .byte), + prev_reg.to8(), + ); + try self.genInlineMemset( + dst_mcv.address().offset(@intFromBool(regs_frame_addr.regs > 0)), + .{ .immediate = 0 }, + .{ .immediate = arg_ty.abiSize(mod) - @intFromBool(regs_frame_addr.regs > 0) }, + .{}, + ); + + const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); + const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); + defer self.register_manager.unlockReg(index_lock); + + try self.asmRegisterImmediate( + .{ ._, .mov }, + index_reg.to32(), + Immediate.u(regs_frame_addr.regs), + ); + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmMemoryImmediate(.{ ._, .cmp }, .{ + .base = .{ .frame = regs_frame_addr.frame_index }, + .mod = .{ .rm = .{ + .size = .byte, + .index = index_reg.to64(), + .scale = .@"8", + .disp = regs_frame_addr.frame_off - @as(u6, regs_frame_addr.regs) * 8, + } }, + }, Immediate.u(0)); + const unset = try self.asmJccReloc(.e, undefined); + try self.asmMemoryRegister( + .{ ._s, .bt }, + try dst_mcv.mem(self, .dword), + index_reg.to32(), + ); + self.performReloc(unset); + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, index_reg.to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + index_reg.to32(), + Immediate.u(arg_ty.vectorLen(mod)), + ); + _ = try self.asmJccReloc(.b, loop); + break :dst dst_mcv; }, else => return self.fail("TODO implement arg for {}", .{src_mcv}), @@ -10605,7 +11661,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { regs[0].dwarfNum(), regs[1].dwarfNum(), } }, // TODO use a frame index - .load_frame => return, + .load_frame, .elementwise_regs_then_frame => return, //.stack_offset => |off| .{ // .stack = .{ // // TODO handle -fomit-frame-pointer @@ -10688,13 +11744,13 @@ fn airBreakpoint(self: *Self) !void { fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void { const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }); + try self.genCopy(Type.usize, dst_mcv, .{ .load_frame = .{ .index = .ret_addr } }, .{}); return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); } fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }); + try self.genCopy(Type.usize, dst_mcv, .{ .lea_frame = .{ .index = .base_ptr } }, .{}); return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); } @@ -10833,14 +11889,69 @@ fn genCall(self: *Self, info: union(enum) { }, .indirect => |reg_off| { frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod)); - try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg); + try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{}); try self.register_manager.getReg(reg_off.reg, null); try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); }, .load_frame => { - try self.genCopy(arg_ty, dst_arg, src_arg); + try self.genCopy(arg_ty, dst_arg, src_arg, .{}); try self.freeValue(src_arg); }, + .elementwise_regs_then_frame => |regs_frame_addr| { + const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); + const index_lock = self.register_manager.lockRegAssumeUnused(index_reg); + defer self.register_manager.unlockReg(index_lock); + + const src_mem: Memory = if (src_arg.isMemory()) try src_arg.mem(self, .dword) else .{ + .base = .{ .reg = try self.copyToTmpRegister( + Type.usize, + switch (src_arg) { + else => src_arg, + .air_ref => |src_ref| try self.resolveInst(src_ref), + }.address(), + ) }, + .mod = .{ .rm = .{ .size = .dword } }, + }; + const src_lock = switch (src_mem.base) { + .reg => |src_reg| self.register_manager.lockReg(src_reg), + else => null, + }; + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + + try self.asmRegisterImmediate( + .{ ._, .mov }, + index_reg.to32(), + Immediate.u(regs_frame_addr.regs), + ); + const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); + try self.asmMemoryRegister(.{ ._, .bt }, src_mem, index_reg.to32()); + try self.asmSetccMemory(.c, .{ + .base = .{ .frame = regs_frame_addr.frame_index }, + .mod = .{ .rm = .{ + .size = .byte, + .index = index_reg.to64(), + .scale = .@"8", + .disp = regs_frame_addr.frame_off - @as(u6, regs_frame_addr.regs) * 8, + } }, + }); + if (self.hasFeature(.slow_incdec)) { + try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), Immediate.u(1)); + } else { + try self.asmRegister(.{ ._, .inc }, index_reg.to32()); + } + try self.asmRegisterImmediate( + .{ ._, .cmp }, + index_reg.to32(), + Immediate.u(arg_ty.vectorLen(mod)), + ); + _ = try self.asmJccReloc(.b, loop); + + const param_int_regs = abi.getCAbiIntParamRegs(resolved_cc); + for (param_int_regs[param_int_regs.len - regs_frame_addr.regs ..]) |dst_reg| { + try self.register_manager.getReg(dst_reg, null); + try reg_locks.append(self.register_manager.lockReg(dst_reg)); + } + }, else => unreachable, }; @@ -10852,7 +11963,7 @@ fn genCall(self: *Self, info: union(enum) { const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ret_ty, mod)); try self.genSetReg(reg_off.reg, Type.usize, .{ .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, - }); + }, .{}); call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } }; try reg_locks.append(self.register_manager.lockReg(reg_off.reg)); }, @@ -10867,20 +11978,52 @@ fn genCall(self: *Self, info: union(enum) { registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))), arg_ty, src_arg, + .{}, ), .C, .SysV, .Win64 => { const promoted_ty = self.promoteInt(arg_ty); const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod)); const dst_alias = registerAlias(dst_reg, promoted_abi_size); - try self.genSetReg(dst_alias, promoted_ty, src_arg); + try self.genSetReg(dst_alias, promoted_ty, src_arg, .{}); if (promoted_ty.toIntern() != arg_ty.toIntern()) try self.truncateRegister(arg_ty, dst_alias); }, }, - .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg), + .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, .{}), .indirect => |reg_off| try self.genSetReg(reg_off.reg, Type.usize, .{ .lea_frame = .{ .index = frame_index, .off = -reg_off.off }, - }), + }, .{}), + .elementwise_regs_then_frame => |regs_frame_addr| { + const src_mem: Memory = if (src_arg.isMemory()) try src_arg.mem(self, .dword) else .{ + .base = .{ .reg = try self.copyToTmpRegister( + Type.usize, + switch (src_arg) { + else => src_arg, + .air_ref => |src_ref| try self.resolveInst(src_ref), + }.address(), + ) }, + .mod = .{ .rm = .{ .size = .dword } }, + }; + const src_lock = switch (src_mem.base) { + .reg => |src_reg| self.register_manager.lockReg(src_reg), + else => null, + }; + defer if (src_lock) |lock| self.register_manager.unlockReg(lock); + + const param_int_regs = abi.getCAbiIntParamRegs(resolved_cc); + for ( + param_int_regs[param_int_regs.len - regs_frame_addr.regs ..], + 0.., + ) |dst_reg, elem_index| { + try self.asmRegisterRegister(.{ ._, .xor }, dst_reg.to32(), dst_reg.to32()); + try self.asmMemoryImmediate( + .{ ._, .bt }, + src_mem, + Immediate.u(elem_index), + ); + try self.asmSetccRegister(.c, dst_reg.to8()); + } + }, else => unreachable, }; @@ -10921,6 +12064,7 @@ fn genCall(self: *Self, info: union(enum) { callee_reg, Type.usize, .{ .load_symbol = .{ .sym = sym.esym_index } }, + .{}, ); try self.asmRegister(.{ ._, .call }, callee_reg); } else try self.asmMemory(.{ ._, .call }, .{ @@ -10933,12 +12077,17 @@ fn genCall(self: *Self, info: union(enum) { } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; - try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); + try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{}); try self.asmRegister(.{ ._, .call }, .rax); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl); const sym = macho_file.getSymbol(sym_index); - try self.genSetReg(.rax, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }); + try self.genSetReg( + .rax, + Type.usize, + .{ .load_symbol = .{ .sym = sym.nlist_idx } }, + .{}, + ); try self.asmRegister(.{ ._, .call }, .rax); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { const atom_index = try p9.seeDecl(func.owner_decl); @@ -10963,7 +12112,7 @@ fn genCall(self: *Self, info: union(enum) { } } else { assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer); - try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }); + try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{}); try self.asmRegister(.{ ._, .call }, .rax); }, .lib => |lib| try self.genExternSymbolRef(.call, lib.lib, lib.callee), @@ -10971,7 +12120,7 @@ fn genCall(self: *Self, info: union(enum) { return call_info.return_value.short; } -fn airRet(self: *Self, inst: Air.Inst.Index) !void { +fn airRet(self: *Self, inst: Air.Inst.Index, safety: bool) !void { const mod = self.bin_file.comp.module.?; const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; @@ -10980,14 +12129,20 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { .none => {}, .register, .register_pair, - => try self.genCopy(ret_ty, self.ret_mcv.short, .{ .air_ref = un_op }), + => try self.genCopy(ret_ty, self.ret_mcv.short, .{ .air_ref = un_op }, .{ .safety = safety }), .indirect => |reg_off| { try self.register_manager.getReg(reg_off.reg, null); const lock = self.register_manager.lockRegAssumeUnused(reg_off.reg); defer self.register_manager.unlockReg(lock); - try self.genSetReg(reg_off.reg, Type.usize, self.ret_mcv.long); - try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ret_ty, .{ .air_ref = un_op }); + try self.genSetReg(reg_off.reg, Type.usize, self.ret_mcv.long, .{}); + try self.genSetMem( + .{ .reg = reg_off.reg }, + reg_off.off, + ret_ty, + .{ .air_ref = un_op }, + .{ .safety = safety }, + ); }, else => unreachable, } @@ -11008,7 +12163,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { switch (self.ret_mcv.short) { .none => {}, .register, .register_pair => try self.load(self.ret_mcv.short, ptr_ty, ptr), - .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr), + .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr, .{}), else => unreachable, } self.ret_mcv.liveOut(self, inst); @@ -11113,7 +12268,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { const dst_mcv = if (unmat_dst_mcv.isRegister() or (abi_size <= 8 and unmat_dst_mcv.isMemory())) unmat_dst_mcv else dst: { const dst_mcv = try self.allocTempRegOrMem(ty, true); - try self.genCopy(ty, dst_mcv, unmat_dst_mcv); + try self.genCopy(ty, dst_mcv, unmat_dst_mcv, .{}); break :dst dst_mcv; }; const dst_lock = @@ -11155,6 +12310,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .lea_tlv, .lea_frame, .lea_symbol, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -11184,6 +12340,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { dst_addr_reg, Type.usize, resolved_dst_mcv.address(), + .{}, ); break :dst .{ .addr_reg = dst_addr_reg, @@ -11214,6 +12371,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .lea_got, .lea_tlv, .lea_frame, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -11243,6 +12401,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { src_addr_reg, Type.usize, resolved_src_mcv.address(), + .{}, ); break :src .{ .addr_reg = src_addr_reg, @@ -11255,7 +12414,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { const regs = try self.register_manager.allocRegs( 2, - .{ null, null }, + .{null} ** 2, abi.RegisterClass.gp, ); const acc_reg = regs[0].to64(); @@ -11284,7 +12443,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .off = frame_addr.off + off, } }, else => unreachable, - }); + }, .{}); try self.genBinOpMir( .{ ._, .xor }, @@ -11497,7 +12656,7 @@ fn genTry( .close_scope = true, }); - try self.performReloc(reloc); + self.performReloc(reloc); for (liveness_cond_br.then_deaths) |death| try self.processDeath(death); @@ -11611,7 +12770,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { .close_scope = true, }); - try self.performReloc(reloc); + self.performReloc(reloc); for (liveness_cond_br.else_deaths) |death| try self.processDeath(death); try self.genBody(else_body); @@ -11658,6 +12817,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC .lea_tlv, .lea_frame, .lea_symbol, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, @@ -11690,7 +12850,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_reg_lock); - try self.genSetReg(addr_reg, Type.usize, opt_mcv.address()); + try self.genSetReg(addr_reg, Type.usize, opt_mcv.address(), .{}); const some_abi_size: u32 = @intCast(some_info.ty.abiSize(mod)); try self.asmMemoryImmediate( .{ ._, .cmp }, @@ -11789,6 +12949,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) .{ ._r, .sh }, eu_ty, .{ .register = tmp_reg }, + Type.u8, .{ .immediate = @as(u6, @intCast(err_off * 8)) }, ); } else { @@ -11994,7 +13155,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { .resurrect = true, .close_scope = true, }); - for (block_data.value.relocs.items) |reloc| try self.performReloc(reloc); + for (block_data.value.relocs.items) |reloc| self.performReloc(reloc); } if (std.debug.runtime_safety) assert(self.inst_tracking.getIndex(inst).? == inst_tracking_i); @@ -12054,7 +13215,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { for (liveness.deaths[case_i]) |operand| try self.processDeath(operand); - for (relocs[0 .. relocs.len - 1]) |reloc| try self.performReloc(reloc); + for (relocs[0 .. relocs.len - 1]) |reloc| self.performReloc(reloc); try self.genBody(case_body); try self.restoreState(state, &.{}, .{ .emit_instructions = false, @@ -12063,7 +13224,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { .close_scope = true, }); - try self.performReloc(relocs[relocs.len - 1]); + self.performReloc(relocs[relocs.len - 1]); } if (switch_br.data.else_body_len > 0) { @@ -12086,7 +13247,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void { self.finishAirBookkeeping(); } -fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { +fn performReloc(self: *Self, reloc: Mir.Inst.Index) void { const next_inst: u32 = @intCast(self.mir_instructions.len); switch (self.mir_instructions.items(.tag)[reloc]) { .j, .jmp => {}, @@ -12130,7 +13291,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { try self.getValue(block_tracking.short, br.block_inst); break :dst block_tracking.short; }; - try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand)); + try self.genCopy(block_ty, dst_mcv, try self.resolveInst(br.operand), .{}); break :result dst_mcv; }; @@ -12294,7 +13455,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { rc.isSet(RegisterManager.indexOfRegIntoTracked(input_mcv.getReg().?).?)) break :arg input_mcv; const reg = try self.register_manager.allocReg(null, rc); - try self.genSetReg(reg, ty, input_mcv); + try self.genSetReg(reg, ty, input_mcv, .{}); break :arg .{ .register = registerAlias(reg, @intCast(ty.abiSize(mod))) }; } else if (mem.eql(u8, constraint, "i") or mem.eql(u8, constraint, "n")) switch (input_mcv) { @@ -12311,16 +13472,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { .load_symbol, .load_direct, .load_got, .load_tlv => {}, else => { const temp_mcv = try self.allocTempRegOrMem(ty, false); - try self.genCopy(ty, temp_mcv, input_mcv); + try self.genCopy(ty, temp_mcv, input_mcv, .{}); break :arg temp_mcv; }, } const addr_reg = self.register_manager.tryAllocReg(null, abi.RegisterClass.gp) orelse { const temp_mcv = try self.allocTempRegOrMem(ty, false); - try self.genCopy(ty, temp_mcv, input_mcv); + try self.genCopy(ty, temp_mcv, input_mcv, .{}); break :arg temp_mcv; }; - try self.genSetReg(addr_reg, Type.usize, input_mcv.address()); + try self.genSetReg(addr_reg, Type.usize, input_mcv.address(), .{}); break :arg .{ .indirect = .{ .reg = addr_reg } }; } else if (mem.eql(u8, constraint, "g") or mem.eql(u8, constraint, "rm") or mem.eql(u8, constraint, "mr") or @@ -12333,7 +13494,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { else => {}, } const temp_mcv = try self.allocTempRegOrMem(ty, true); - try self.genCopy(ty, temp_mcv, input_mcv); + try self.genCopy(ty, temp_mcv, input_mcv, .{}); break :arg temp_mcv; } else if (mem.eql(u8, constraint, "X")) input_mcv @@ -12341,7 +13502,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { const reg = parseRegName(constraint["{".len .. constraint.len - "}".len]) orelse return self.fail("invalid register constraint: '{s}'", .{constraint}); try self.register_manager.getReg(reg, null); - try self.genSetReg(reg, ty, input_mcv); + try self.genSetReg(reg, ty, input_mcv, .{}); break :arg .{ .register = reg }; } else if (constraint.len == 1 and std.ascii.isDigit(constraint[0])) arg: { const index = std.fmt.charToDigit(constraint[0], 10) catch unreachable; @@ -12435,7 +13596,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { if (!anon and label_gop.value_ptr.pending_relocs.items.len == 0) return self.fail("redefined label: '{s}'", .{label_name}); for (label_gop.value_ptr.pending_relocs.items) |pending_reloc| - try self.performReloc(pending_reloc); + self.performReloc(pending_reloc); if (anon) label_gop.value_ptr.pending_relocs.clearRetainingCapacity() else @@ -12795,7 +13956,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { if (output == .none) continue; if (arg_mcv != .register) continue; if (constraint.len == 2 and std.ascii.isDigit(constraint[1])) continue; - try self.store(self.typeOf(output), .{ .air_ref = output }, arg_mcv); + try self.store(self.typeOf(output), .{ .air_ref = output }, arg_mcv, .{}); } simple: { @@ -12952,7 +14113,13 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo else => {}, }, .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { - .Bool => {}, + .Bool => switch (ty.vectorLen(mod)) { + 33...64 => return .{ .move = if (self.hasFeature(.avx)) + .{ .v_q, .mov } + else + .{ ._q, .mov } }, + else => {}, + }, .Int => switch (ty.childType(mod).intInfo(mod).bits) { 8 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ @@ -13167,7 +14334,11 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)}); } -fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { +const CopyOptions = struct { + safety: bool = false, +}; + +fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: CopyOptions) InnerError!void { const mod = self.bin_file.comp.module.?; const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; @@ -13186,16 +14357,18 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .lea_tlv, .lea_frame, .lea_symbol, + .elementwise_regs_then_frame, .reserved_frame, .air_ref, => unreachable, // unmodifiable destination - .register => |reg| try self.genSetReg(reg, ty, src_mcv), + .register => |reg| try self.genSetReg(reg, ty, src_mcv, opts), .register_offset => |dst_reg_off| try self.genSetReg(dst_reg_off.reg, ty, switch (src_mcv) { .none, .unreach, .dead, .undef, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, => unreachable, .immediate, @@ -13207,7 +14380,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .reg = try self.copyToTmpRegister(ty, src_mcv), .off = -dst_reg_off.off, } }, - }), + }, opts), .register_pair => |dst_regs| { const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { .register_pair, .memory, .indirect, .load_frame => null, @@ -13217,10 +14390,15 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); errdefer self.register_manager.unlockReg(src_addr_lock); - try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address()); + try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address(), opts); break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; }, - .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)), + .air_ref => |src_ref| return self.genCopy( + ty, + dst_mcv, + try self.resolveInst(src_ref), + opts, + ), else => return self.fail("TODO implement genCopy for {s} of {}", .{ @tagName(src_mcv), ty.fmt(mod), }), @@ -13237,15 +14415,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .off = part_disp, } }, else => unreachable, - }); + }, opts); part_disp += @intCast(dst_ty.abiSize(mod)); } }, - .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv), + .indirect => |reg_off| try self.genSetMem( + .{ .reg = reg_off.reg }, + reg_off.off, + ty, + src_mcv, + opts, + ), .memory, .load_symbol, .load_direct, .load_got, .load_tlv => { switch (dst_mcv) { .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr| - return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv), + return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv, opts), .load_symbol, .load_direct, .load_got, .load_tlv => {}, else => unreachable, } @@ -13254,18 +14438,25 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); defer self.register_manager.unlockReg(addr_lock); - try self.genSetMem(.{ .reg = addr_reg }, 0, ty, src_mcv); + try self.genSetMem(.{ .reg = addr_reg }, 0, ty, src_mcv, opts); }, .load_frame => |frame_addr| try self.genSetMem( .{ .frame = frame_addr.index }, frame_addr.off, ty, src_mcv, + opts, ), } } -fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void { +fn genSetReg( + self: *Self, + dst_reg: Register, + ty: Type, + src_mcv: MCValue, + opts: CopyOptions, +) InnerError!void { const mod = self.bin_file.comp.module.?; const abi_size: u32 = @intCast(ty.abiSize(mod)); if (ty.bitSize(mod) > dst_reg.bitSize()) @@ -13275,9 +14466,30 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr .unreach, .dead, .register_overflow, + .elementwise_regs_then_frame, .reserved_frame, => unreachable, - .undef => {}, + .undef => if (opts.safety) switch (dst_reg.class()) { + .general_purpose => switch (abi_size) { + 1 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to8(), Immediate.u(0xAA)), + 2 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to16(), Immediate.u(0xAAAA)), + 3...4 => try self.asmRegisterImmediate( + .{ ._, .mov }, + dst_reg.to32(), + Immediate.s(@as(i32, @bitCast(@as(u32, 0xAAAAAAAA)))), + ), + 5...8 => try self.asmRegisterImmediate( + .{ ._, .mov }, + dst_reg.to64(), + Immediate.u(0xAAAAAAAAAAAAAAAA), + ), + else => unreachable, + }, + .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(.{ + .ty = ty, + .val = try mod.undefValue(ty), + }), opts), + }, .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), .immediate => |imm| { if (imm == 0) { @@ -13362,6 +14574,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr dst_reg, ty, .{ .register = try self.copyToTmpRegister(ty, src_mcv) }, + opts, ), .x87, .mmx => unreachable, .sse => try self.asmRegisterRegister( @@ -13391,21 +14604,23 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr ), }, }, - .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }), + .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }, opts), .register_offset, .indirect, .load_frame, .lea_frame, => try @as(MoveStrategy, switch (src_mcv) { .register_offset => |reg_off| switch (reg_off.off) { - 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), + 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }, opts), else => .{ .move = .{ ._, .lea } }, }, .indirect => try self.moveStrategy(ty, dst_reg.class(), false), .load_frame => |frame_addr| try self.moveStrategy( ty, dst_reg.class(), - self.getFrameAddrAlignment(frame_addr).compare(.gte, ty.abiAlignment(mod)), + self.getFrameAddrAlignment(frame_addr).compare(.gte, Alignment.fromLog2Units( + std.math.log2_int_ceil(u10, @divExact(dst_reg.bitSize(), 8)), + )), ), .lea_frame => .{ .move = .{ ._, .lea } }, else => unreachable, @@ -13540,11 +14755,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr }); }, .lea_tlv => unreachable, // TODO: remove this - .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref)), + .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref), opts), } } -fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void { +fn genSetMem( + self: *Self, + base: Memory.Base, + disp: i32, + ty: Type, + src_mcv: MCValue, + opts: CopyOptions, +) InnerError!void { const mod = self.bin_file.comp.module.?; const abi_size: u32 = @intCast(ty.abiSize(mod)); const dst_ptr_mcv: MCValue = switch (base) { @@ -13554,11 +14776,17 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal .reloc => |base_symbol| .{ .lea_symbol = .{ .sym = base_symbol.sym_index, .off = disp } }, }; switch (src_mcv) { - .none, .unreach, .dead, .reserved_frame => unreachable, - .undef => try self.genInlineMemset( + .none, + .unreach, + .dead, + .elementwise_regs_then_frame, + .reserved_frame, + => unreachable, + .undef => if (opts.safety) try self.genInlineMemset( dst_ptr_mcv, - .{ .immediate = 0xaa }, + src_mcv, .{ .immediate = abi_size }, + opts, ), .immediate => |imm| switch (abi_size) { 1, 2, 4 => { @@ -13639,7 +14867,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal } } }, src_alias, ); - try self.genSetMem(base, disp, ty, frame_mcv); + try self.genSetMem(base, disp, ty, frame_mcv, opts); try self.freeValue(frame_mcv); } else try (try self.moveStrategy(ty, src_alias.class(), switch (base) { .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))), @@ -13663,7 +14891,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal .register_pair => |src_regs| { var part_disp: i32 = disp; for (try self.splitType(ty), src_regs) |src_ty, src_reg| { - try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }); + try self.genSetMem(base, part_disp, src_ty, .{ .register = src_reg }, opts); part_disp += @intCast(src_ty.abiSize(mod)); } }, @@ -13674,23 +14902,26 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))), ty.structFieldType(0, mod), .{ .register = ro.reg }, + opts, ); try self.genSetMem( base, disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))), ty.structFieldType(1, mod), .{ .eflags = ro.eflags }, + opts, ); }, .Optional => { assert(!ty.optionalReprIsPayload(mod)); const child_ty = ty.optionalChild(mod); - try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }); + try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg }, opts); try self.genSetMem( base, disp + @as(i32, @intCast(child_ty.abiSize(mod))), Type.bool, .{ .eflags = ro.eflags }, + opts, ); }, else => return self.fail("TODO implement genSetMem for {s} of {}", .{ @@ -13717,27 +14948,37 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); defer self.register_manager.unlockReg(src_lock); - try self.genSetMem(base, disp, ty, .{ .register = src_reg }); + try self.genSetMem(base, disp, ty, .{ .register = src_reg }, opts); }, - else => try self.genInlineMemcpy(dst_ptr_mcv, src_mcv.address(), .{ .immediate = abi_size }), + else => try self.genInlineMemcpy( + dst_ptr_mcv, + src_mcv.address(), + .{ .immediate = abi_size }, + ), }, - .air_ref => |src_ref| try self.genSetMem(base, disp, ty, try self.resolveInst(src_ref)), + .air_ref => |src_ref| try self.genSetMem(base, disp, ty, try self.resolveInst(src_ref), opts), } } fn genInlineMemcpy(self: *Self, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void { try self.spillRegisters(&.{ .rsi, .rdi, .rcx }); - try self.genSetReg(.rsi, Type.usize, src_ptr); - try self.genSetReg(.rdi, Type.usize, dst_ptr); - try self.genSetReg(.rcx, Type.usize, len); + try self.genSetReg(.rsi, Type.usize, src_ptr, .{}); + try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); + try self.genSetReg(.rcx, Type.usize, len, .{}); try self.asmOpOnly(.{ .@"rep _sb", .mov }); } -fn genInlineMemset(self: *Self, dst_ptr: MCValue, value: MCValue, len: MCValue) InnerError!void { +fn genInlineMemset( + self: *Self, + dst_ptr: MCValue, + value: MCValue, + len: MCValue, + opts: CopyOptions, +) InnerError!void { try self.spillRegisters(&.{ .rdi, .al, .rcx }); - try self.genSetReg(.rdi, Type.usize, dst_ptr); - try self.genSetReg(.al, Type.u8, value); - try self.genSetReg(.rcx, Type.usize, len); + try self.genSetReg(.rdi, Type.usize, dst_ptr, .{}); + try self.genSetReg(.al, Type.u8, value, opts); + try self.genSetReg(.rcx, Type.usize, len, .{}); try self.asmOpOnly(.{ .@"rep _sb", .sto }); } @@ -13801,10 +15042,10 @@ fn genLazySymbolRef( switch (tag) { .lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.esym_index }, - }), + }, .{}), .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.esym_index }, - }), + }, .{}), else => unreachable, } switch (tag) { @@ -13861,8 +15102,8 @@ fn genLazySymbolRef( return self.fail("{s} creating lazy symbol", .{@errorName(err)}); const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; switch (tag) { - .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }), - .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }), + .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }, .{}), + .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }, .{}), else => unreachable, } switch (tag) { @@ -13875,8 +15116,13 @@ fn genLazySymbolRef( return self.fail("{s} creating lazy symbol", .{@errorName(err)}); const sym = macho_file.getSymbol(sym_index); switch (tag) { - .lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }), - .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }), + .lea, .call => try self.genSetReg( + reg, + Type.usize, + .{ .load_symbol = .{ .sym = sym.nlist_idx } }, + .{}, + ), + .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }, .{}), else => unreachable, } switch (tag) { @@ -13898,7 +15144,7 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { const dst_mcv = try self.allocRegOrMem(inst, true); const dst_ty = self.typeOfIndex(inst); - try self.genCopy(dst_ty, dst_mcv, src_mcv); + try self.genCopy(dst_ty, dst_mcv, src_mcv, .{}); break :result dst_mcv; }; return self.finishAir(inst, result, .{ un_op, .none, .none }); @@ -13925,7 +15171,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { .lt => dst_ty, .eq => if (!dst_mcv.isMemory() or src_mcv.isMemory()) dst_ty else src_ty, .gt => src_ty, - }, dst_mcv, src_mcv); + }, dst_mcv, src_mcv, .{}); break :dst dst_mcv; }; @@ -13956,6 +15202,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { if (abi_size <= 8) dst_ty else Type.usize, high_mcv, .{ .register = high_reg }, + .{}, ); break :result dst_mcv; }; @@ -13973,12 +15220,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const array_len = array_ty.arrayLen(mod); const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(slice_ty, mod)); - try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); + try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr, .{}); try self.genSetMem( .{ .frame = frame_index }, @intCast(ptr_ty.abiSize(mod)), Type.usize, .{ .immediate = array_len }, + .{}, ); const result = MCValue{ .load_frame = .{ .index = frame_index } }; @@ -14158,9 +15406,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { if (exp_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; defer if (exp_addr_lock) |lock| self.register_manager.unlockReg(lock); - try self.genSetReg(.rax, Type.usize, exp_addr_mcv.deref()); - try self.genSetReg(.rdx, Type.usize, exp_addr_mcv.offset(8).deref()); - } else try self.genSetReg(.rax, val_ty, exp_mcv); + try self.genSetReg(.rax, Type.usize, exp_addr_mcv.deref(), .{}); + try self.genSetReg(.rdx, Type.usize, exp_addr_mcv.offset(8).deref(), .{}); + } else try self.genSetReg(.rax, val_ty, exp_mcv, .{}); const new_mcv = try self.resolveInst(extra.new_value); const new_reg = if (val_abi_size > 8) new: { @@ -14172,8 +15420,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { if (new_addr_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; defer if (new_addr_lock) |lock| self.register_manager.unlockReg(lock); - try self.genSetReg(.rbx, Type.usize, new_addr_mcv.deref()); - try self.genSetReg(.rcx, Type.usize, new_addr_mcv.offset(8).deref()); + try self.genSetReg(.rbx, Type.usize, new_addr_mcv.deref(), .{}); + try self.genSetReg(.rcx, Type.usize, new_addr_mcv.offset(8).deref(), .{}); break :new null; } else try self.copyToTmpRegister(val_ty, new_mcv); const new_lock = if (new_reg) |reg| self.register_manager.lockRegAssumeUnused(reg) else null; @@ -14214,9 +15462,9 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { } const dst_mcv = try self.allocRegOrMem(inst, false); - try self.genCopy(Type.usize, dst_mcv, .{ .register = .rax }); - try self.genCopy(Type.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }); - try self.genCopy(Type.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }); + try self.genCopy(Type.usize, dst_mcv, .{ .register = .rax }, .{}); + try self.genCopy(Type.usize, dst_mcv.address().offset(8).deref(), .{ .register = .rdx }, .{}); + try self.genCopy(Type.bool, dst_mcv.address().offset(16).deref(), .{ .eflags = .ne }, .{}); break :result dst_mcv; }; return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value }); @@ -14300,7 +15548,7 @@ fn atomicOp( const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_lock); - try self.genSetReg(dst_reg, val_ty, val_mcv); + try self.genSetReg(dst_reg, val_ty, val_mcv, .{}); if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) { try self.genUnOpMir(.{ ._, .neg }, val_ty, dst_mcv); } @@ -14333,7 +15581,7 @@ fn atomicOp( try self.asmRegisterMemory(.{ ._, .mov }, registerAlias(.rax, val_abi_size), ptr_mem); const loop: Mir.Inst.Index = @intCast(self.mir_instructions.len); if (!use_sse and rmw_op orelse .Xchg != .Xchg) { - try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax }); + try self.genSetReg(tmp_reg, val_ty, .{ .register = .rax }, .{}); } if (rmw_op) |op| if (use_sse) { const mir_tag = @as(?Mir.Inst.FixedTag, switch (op) { @@ -14361,7 +15609,7 @@ fn atomicOp( }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{ @tagName(op), val_ty.fmt(mod), }); - try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }); + try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{}); switch (mir_tag[0]) { .v_ss, .v_sd => if (val_mcv.isMemory()) try self.asmRegisterRegisterMemory( mir_tag, @@ -14391,9 +15639,9 @@ fn atomicOp( ), else => unreachable, } - try self.genSetReg(tmp_reg, val_ty, .{ .register = sse_reg }); + try self.genSetReg(tmp_reg, val_ty, .{ .register = sse_reg }, .{}); } else switch (op) { - .Xchg => try self.genSetReg(tmp_reg, val_ty, val_mcv), + .Xchg => try self.genSetReg(tmp_reg, val_ty, val_mcv, .{}), .Add => try self.genBinOpMir(.{ ._, .add }, val_ty, tmp_mcv, val_mcv), .Sub => try self.genBinOpMir(.{ ._, .sub }, val_ty, tmp_mcv, val_mcv), .And => try self.genBinOpMir(.{ ._, .@"and" }, val_ty, tmp_mcv, val_mcv), @@ -14683,7 +15931,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { }; defer if (len_lock) |lock| self.register_manager.unlockReg(lock); - try self.genInlineMemset(ptr, src_val, len); + try self.genInlineMemset(ptr, src_val, len, .{ .safety = safety }); break :result; } @@ -14705,11 +15953,11 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { const len_lock = self.register_manager.lockRegAssumeUnused(len_reg); defer self.register_manager.unlockReg(len_lock); - try self.genSetReg(len_reg, Type.usize, len); + try self.genSetReg(len_reg, Type.usize, len, .{}); try self.asmRegisterRegister(.{ ._, .@"test" }, len_reg, len_reg); const skip_reloc = try self.asmJccReloc(.z, undefined); - try self.store(slice_ptr_ty, ptr, src_val); + try self.store(slice_ptr_ty, ptr, src_val, .{ .safety = safety }); const second_elem_ptr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); @@ -14721,7 +15969,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ .reg = try self.copyToTmpRegister(Type.usize, ptr), .off = elem_abi_size, - } }); + } }, .{}); try self.genBinOpMir(.{ ._, .sub }, Type.usize, len_mcv, .{ .immediate = 1 }); try self.asmRegisterRegisterImmediate( @@ -14732,7 +15980,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { ); try self.genInlineMemcpy(second_elem_ptr_mcv, ptr, len_mcv); - try self.performReloc(skip_reloc); + self.performReloc(skip_reloc); }, .One => { const elem_ptr_ty = try mod.singleMutPtrType(elem_ty); @@ -14740,7 +15988,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { const len = dst_ptr_ty.childType(mod).arrayLen(mod); assert(len != 0); // prevented by Sema - try self.store(elem_ptr_ty, dst_ptr, src_val); + try self.store(elem_ptr_ty, dst_ptr, src_val, .{ .safety = safety }); const second_elem_ptr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); @@ -14752,7 +16000,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { try self.genSetReg(second_elem_ptr_reg, Type.usize, .{ .register_offset = .{ .reg = try self.copyToTmpRegister(Type.usize, dst_ptr), .off = elem_abi_size, - } }); + } }, .{}); const bytes_to_copy: MCValue = .{ .immediate = elem_abi_size * (len - 1) }; try self.genInlineMemcpy(second_elem_ptr_mcv, dst_ptr, bytes_to_copy); @@ -14846,10 +16094,10 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { const param_regs = abi.getCAbiIntParamRegs(resolved_cc); const dst_mcv = try self.allocRegOrMem(inst, false); - try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address()); + try self.genSetReg(param_regs[0], Type.usize, dst_mcv.address(), .{}); const operand = try self.resolveInst(un_op); - try self.genSetReg(param_regs[1], enum_ty, operand); + try self.genSetReg(param_regs[1], enum_ty, operand, .{}); try self.genLazySymbolRef( .call, @@ -14979,11 +16227,12 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { const reg_locks = self.register_manager.lockRegsAssumeUnused(2, regs); defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); - try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }); + try self.genSetReg(regs[1], vector_ty, .{ .immediate = 0 }, .{}); try self.genSetReg( regs[1], vector_ty, .{ .immediate = @as(u64, math.maxInt(u64)) >> @intCast(64 - vector_len) }, + .{}, ); const src_mcv = try self.resolveInst(ty_op.operand); const abi_size = @max(math.divCeil(u32, vector_len, 8) catch unreachable, 4); @@ -15048,7 +16297,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { try src_mcv.mem(self, self.memSize(scalar_ty)), ) else { if (mir_tag[0] == .vp_i128) break :avx2; - try self.genSetReg(dst_reg, scalar_ty, src_mcv); + try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); try self.asmRegisterRegister( mir_tag, registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))), @@ -15061,7 +16310,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_lock); - try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }); + try self.genSetReg(dst_reg, scalar_ty, .{ .air_ref = ty_op.operand }, .{}); if (vector_len == 1) break :result .{ .register = dst_reg }; const dst_alias = registerAlias(dst_reg, @intCast(vector_ty.abiSize(mod))); @@ -15111,7 +16360,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { const src_mcv = try self.resolveInst(ty_op.operand); if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); - try self.genSetReg(dst_reg, scalar_ty, src_mcv); + try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); break :result .{ .register = dst_reg }; }, 2...4 => { @@ -15194,7 +16443,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { const src_mcv = try self.resolveInst(ty_op.operand); if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); - try self.genSetReg(dst_reg, scalar_ty, src_mcv); + try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); break :result .{ .register = dst_reg }; }, 2 => { @@ -15263,7 +16512,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { const src_mcv = try self.resolveInst(ty_op.operand); if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); - try self.genSetReg(dst_reg, scalar_ty, src_mcv); + try self.genSetReg(dst_reg, scalar_ty, src_mcv, .{}); break :result .{ .register = dst_reg }; }, 2 => if (self.hasFeature(.avx)) { @@ -15387,6 +16636,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { .{ .lea_frame = .{ .index = frame_index } }, .{ .immediate = 0 }, .{ .immediate = result_ty.abiSize(mod) }, + .{}, ); for (elements, 0..) |elem, elem_i_usize| { const elem_i: u32 = @intCast(elem_i_usize); @@ -15431,6 +16681,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { .{ ._l, .sh }, elem_ty, .{ .register = elem_reg }, + Type.u8, .{ .immediate = elem_bit_off }, ); try self.genBinOpMir( @@ -15448,6 +16699,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { .{ ._r, .sh }, elem_ty, .{ .register = reg }, + Type.u8, .{ .immediate = elem_abi_bits - elem_bit_off }, ); try self.genBinOpMir( @@ -15471,7 +16723,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, else => elem_mcv, }; - try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv); + try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv, .{}); } break :result .{ .load_frame = .{ .index = frame_index } }; }, @@ -15519,13 +16771,20 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { else => elem_mcv, }; const elem_off: i32 = @intCast(elem_size * elem_i); - try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv); + try self.genSetMem( + .{ .frame = frame_index }, + elem_off, + elem_ty, + mat_elem_mcv, + .{}, + ); } if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem( .{ .frame = frame_index }, @intCast(elem_size * elements.len), elem_ty, try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }), + .{}, ); break :result .{ .load_frame = .{ .index = frame_index } }; } @@ -15560,7 +16819,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(src_ty, dst_mcv, src_mcv); + try self.genCopy(src_ty, dst_mcv, src_mcv, .{}); break :result dst_mcv; } @@ -15577,13 +16836,18 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { @intCast(layout.payload_size) else 0; - try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int }); + try self.genCopy( + tag_ty, + dst_mcv.address().offset(tag_off).deref(), + .{ .immediate = tag_int }, + .{}, + ); const pl_off: i32 = if (layout.tag_align.compare(.lt, layout.payload_align)) 0 else @intCast(layout.tag_size); - try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv); + try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv, .{}); break :result dst_mcv; }; @@ -15781,6 +17045,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { field_off, Type.c_uint, .{ .immediate = info.gp_count * 8 }, + .{}, ); field_off += @intCast(Type.c_uint.abiSize(mod)); // fp_offset: c_uint, @@ -15789,6 +17054,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { field_off, Type.c_uint, .{ .immediate = abi.SysV.c_abi_int_param_regs.len * 8 + info.fp_count * 16 }, + .{}, ); field_off += @intCast(Type.c_uint.abiSize(mod)); // overflow_arg_area: *anyopaque, @@ -15797,6 +17063,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { field_off, ptr_anyopaque_ty, .{ .lea_frame = info.overflow_arg_area }, + .{}, ); field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); // reg_save_area: *anyopaque, @@ -15805,6 +17072,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { field_off, ptr_anyopaque_ty, .{ .lea_frame = info.reg_save_area }, + .{}, ); field_off += @intCast(ptr_anyopaque_ty.abiSize(mod)); break :result .{ .load_frame = .{ .index = dst_fi } }; @@ -15831,7 +17099,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { try self.spillEflagsIfOccupied(); const tmp_regs = - try self.register_manager.allocRegs(2, .{ null, null }, abi.RegisterClass.gp); + try self.register_manager.allocRegs(2, .{null} ** 2, abi.RegisterClass.gp); const offset_reg = tmp_regs[0].to32(); const addr_reg = tmp_regs[1].to64(); const tmp_locks = self.register_manager.lockRegsAssumeUnused(2, tmp_regs); @@ -15859,13 +17127,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { .integer => { assert(classes.len == 1); - try self.genSetReg(offset_reg, Type.c_uint, gp_offset); + try self.genSetReg(offset_reg, Type.c_uint, gp_offset, .{}); try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( abi.SysV.c_abi_int_param_regs.len * 8, )); const mem_reloc = try self.asmJccReloc(.ae, undefined); - try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); + try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area, .{}); if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ @@ -15880,11 +17148,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { .disp = 8, } }, }); - try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }); + try self.genCopy(Type.c_uint, gp_offset, .{ .register = offset_reg }, .{}); const done_reloc = try self.asmJmpReloc(undefined); - try self.performReloc(mem_reloc); - try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); + self.performReloc(mem_reloc); + try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area, .{}); try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ @@ -15896,23 +17164,24 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { ptr_anyopaque_ty, overflow_arg_area, .{ .register = offset_reg.to64() }, + .{}, ); - try self.performReloc(done_reloc); + self.performReloc(done_reloc); if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ .indirect = .{ .reg = addr_reg }, - }); + }, .{}); }, .sse => { assert(classes.len == 1); - try self.genSetReg(offset_reg, Type.c_uint, fp_offset); + try self.genSetReg(offset_reg, Type.c_uint, fp_offset, .{}); try self.asmRegisterImmediate(.{ ._, .cmp }, offset_reg, Immediate.u( abi.SysV.c_abi_int_param_regs.len * 8 + abi.SysV.c_abi_sse_param_regs.len * 16, )); const mem_reloc = try self.asmJccReloc(.ae, undefined); - try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area); + try self.genSetReg(addr_reg, ptr_anyopaque_ty, reg_save_area, .{}); if (!unused) try self.asmRegisterMemory(.{ ._, .lea }, addr_reg, .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ @@ -15927,11 +17196,11 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { .disp = 16, } }, }); - try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }); + try self.genCopy(Type.c_uint, fp_offset, .{ .register = offset_reg }, .{}); const done_reloc = try self.asmJmpReloc(undefined); - try self.performReloc(mem_reloc); - try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area); + self.performReloc(mem_reloc); + try self.genSetReg(addr_reg, ptr_anyopaque_ty, overflow_arg_area, .{}); try self.asmRegisterMemory(.{ ._, .lea }, offset_reg.to64(), .{ .base = .{ .reg = addr_reg }, .mod = .{ .rm = .{ @@ -15943,12 +17212,13 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { ptr_anyopaque_ty, overflow_arg_area, .{ .register = offset_reg.to64() }, + .{}, ); - try self.performReloc(done_reloc); + self.performReloc(done_reloc); if (!unused) try self.genCopy(promote_ty, promote_mcv, .{ .indirect = .{ .reg = addr_reg }, - }); + }, .{}); }, .memory => { assert(classes.len == 1); @@ -15964,7 +17234,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { if (!promote_ty.isRuntimeFloat()) { const dst_mcv = try self.allocRegOrMem(inst, true); - try self.genCopy(ty, dst_mcv, promote_mcv); + try self.genCopy(ty, dst_mcv, promote_mcv, .{}); break :result dst_mcv; } @@ -16055,6 +17325,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { 0, Type.usize, .{ .lea_symbol = .{ .sym = tlv_sym } }, + .{}, ); break :init .{ .load_frame = .{ .index = frame_index } }; }, @@ -16249,7 +17520,7 @@ fn resolveCallingConventionValues( }; ret_tracking_i += 1; }, - .none => unreachable, + .none, .integer_per_element => unreachable, }; result.return_value = switch (ret_tracking_i) { else => unreachable, @@ -16324,6 +17595,32 @@ fn resolveCallingConventionValues( else => unreachable, }, .none => unreachable, + .integer_per_element => { + const param_int_regs_len: u32 = + @intCast(abi.getCAbiIntParamRegs(resolved_cc).len); + const remaining_param_int_regs: u3 = + @intCast(param_int_regs_len - param_int_reg_i); + param_int_reg_i = param_int_regs_len; + + const frame_elem_align = 8; + const frame_elems_len = ty.vectorLen(mod) - remaining_param_int_regs; + const frame_elem_size = mem.alignForward( + u64, + ty.childType(mod).abiSize(mod), + frame_elem_align, + ); + const frame_size: u31 = @intCast(frame_elems_len * frame_elem_size); + + result.stack_byte_count = + mem.alignForward(u31, result.stack_byte_count, frame_elem_align); + arg_mcv[arg_mcv_i] = .{ .elementwise_regs_then_frame = .{ + .regs = remaining_param_int_regs, + .frame_off = @intCast(result.stack_byte_count), + .frame_index = stack_frame_base, + } }; + arg_mcv_i += 1; + result.stack_byte_count += frame_size; + }, } else { arg.* = switch (arg_mcv_i) { else => unreachable, @@ -16506,12 +17803,14 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { .{ ._l, .sa }, Type.isize, .{ .register = reg }, + Type.u8, .{ .immediate = shift }, ); try self.genShiftBinOpMir( .{ ._r, .sa }, Type.isize, .{ .register = reg }, + Type.u8, .{ .immediate = shift }, ); }, diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index 85c43903ba5540d2b931a50190cd6b4e894112c8..8b91a20a4f8639378c1095fd0ffae0be4ae93b48 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -232,8 +232,7 @@ pub const Mnemonic = enum { cmps, cmpsb, cmpsd, cmpsq, cmpsw, cmpxchg, cmpxchg8b, cmpxchg16b, cpuid, cqo, cwd, cwde, - div, - idiv, imul, int3, + dec, div, idiv, imul, inc, int3, ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe, jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, jmp, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index e70298af757614665beeba32603de5e1136dbe84..dea9bb50cb94df55fc1eac689ebf1c907bfd6bd2 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -325,6 +325,8 @@ pub const Inst = struct { cwd, /// Convert word to doubleword cwde, + /// Decrement by 1 + dec, /// Unsigned division /// Signed division /// Divide packed single-precision floating-point values @@ -332,7 +334,9 @@ pub const Inst = struct { /// Divide packed double-precision floating-point values /// Divide scalar double-precision floating-point values div, - /// + /// Increment by 1 + inc, + /// Call to interrupt procedure int3, /// Conditional jump j, diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index 1046e73fb6e310fa5954ea222b381ab78ff4dd98..601fc1933e5c955fbe889e936a25c21ba64fcb81 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -10,6 +10,7 @@ pub const Class = enum { win_i128, float, float_combine, + integer_per_element, }; pub fn classifyWindows(ty: Type, mod: *Module) Class { @@ -161,6 +162,31 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class { .Vector => { const elem_ty = ty.childType(mod); const bits = elem_ty.bitSize(mod) * ty.arrayLen(mod); + if (elem_ty.toIntern() == .bool_type) { + if (bits <= 32) return .{ + .integer, .none, .none, .none, + .none, .none, .none, .none, + }; + if (bits <= 64) return .{ + .sse, .none, .none, .none, + .none, .none, .none, .none, + }; + if (ctx == .arg) { + if (bits <= 128) return .{ + .integer_per_element, .none, .none, .none, + .none, .none, .none, .none, + }; + if (bits <= 256 and std.Target.x86.featureSetHas(target.cpu.features, .avx)) return .{ + .integer_per_element, .none, .none, .none, + .none, .none, .none, .none, + }; + if (bits <= 512 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ + .integer_per_element, .none, .none, .none, + .none, .none, .none, .none, + }; + } + return memory_class; + } if (bits <= 64) return .{ .sse, .none, .none, .none, .none, .none, .none, .none, diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 3e62bd4d592acf3022cb05a5fa95764c9cfd3813..545e6b23ceb4ece10f4e68639ca015079b5d8b7d 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -269,6 +269,12 @@ pub const table = [_]Entry{ .{ .cpuid, .zo, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none }, + .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .none, .none }, + .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .rex, .none }, + .{ .dec, .m, &.{ .rm16 }, &.{ 0xff }, 1, .short, .none }, + .{ .dec, .m, &.{ .rm32 }, &.{ 0xff }, 1, .none, .none }, + .{ .dec, .m, &.{ .rm64 }, &.{ 0xff }, 1, .long, .none }, + .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .none, .none }, .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .rex, .none }, .{ .div, .m, &.{ .rm16 }, &.{ 0xf7 }, 6, .short, .none }, @@ -296,6 +302,12 @@ pub const table = [_]Entry{ .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none, .none }, .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long, .none }, + .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .none, .none }, + .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .rex, .none }, + .{ .inc, .m, &.{ .rm16 }, &.{ 0xff }, 0, .short, .none }, + .{ .inc, .m, &.{ .rm32 }, &.{ 0xff }, 0, .none, .none }, + .{ .inc, .m, &.{ .rm64 }, &.{ 0xff }, 0, .long, .none }, + .{ .int3, .zo, &.{}, &.{ 0xcc }, 0, .none, .none }, .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none }, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 504c9ae1d196780cb95c1a42b948155b7d2c0108..2dae20879adc81ace46eb2edf0d636173079e0dd 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -11139,6 +11139,9 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E .memory => unreachable, // handled above .win_i128 => unreachable, // windows only .none => break, + .integer_per_element => { + @panic("TODO"); + }, } } const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer}); @@ -11417,6 +11420,9 @@ const ParamTypeIterator = struct { .memory => unreachable, // handled above .win_i128 => unreachable, // windows only .none => break, + .integer_per_element => { + @panic("TODO"); + }, } } const first_non_integer = std.mem.indexOfNone(x86_64_abi.Class, &classes, &.{.integer}); diff --git a/test/behavior/math.zig b/test/behavior/math.zig index 8864f6e4f6eefd9d2d482127c76ef83677e9bbc2..2201efa1d227bdc3260f244d4c72dc06b475846e 100644 --- a/test/behavior/math.zig +++ b/test/behavior/math.zig @@ -1059,6 +1059,40 @@ test "@mulWithOverflow bitsize > 32" { } } +test "@mulWithOverflow u256" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + { + const const_lhs: u256 = 8035709466408580321693645878924206181189; + const const_rhs: u256 = 343954217539185679456797259115612849079; + const const_result = @mulWithOverflow(const_lhs, const_rhs); + comptime assert(const_result[0] == 100698109432518020450541558444080472799095368135495022414802684874680804056403); + comptime assert(const_result[1] == 1); + + var var_lhs = const_lhs; + var var_rhs = const_rhs; + _ = .{ &var_lhs, &var_rhs }; + const var_result = @mulWithOverflow(var_lhs, var_rhs); + try std.testing.expect(var_result[0] == const_result[0]); + try std.testing.expect(var_result[1] == const_result[1]); + } + { + const const_lhs: u256 = 100477140835310762407466294984162740292250605075409128262608; + const const_rhs: u256 = 406310585934439581231; + const const_result = @mulWithOverflow(const_lhs, const_rhs); + comptime assert(const_result[0] == 66110554277021146912650321519727251744526528332039438002889524600764482652976); + comptime assert(const_result[1] == 1); + + var var_lhs = const_lhs; + var var_rhs = const_rhs; + _ = .{ &var_lhs, &var_rhs }; + const var_result = @mulWithOverflow(var_lhs, var_rhs); + try std.testing.expect(var_result[0] == const_result[0]); + try std.testing.expect(var_result[1] == const_result[1]); + } +} + test "@subWithOverflow" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index 27f460e175b67f826ed9c676184700bbd0381f50..423d7f78e81aadb20bdee147537890efba46cd20 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -1130,10 +1130,6 @@ test "pointer loaded correctly from packed struct" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_x86_64) { - // Careful enabling this test, fails randomly. - return error.SkipZigTest; - } var ram = try RAM.new(); var cpu = try CPU.new(&ram); diff --git a/test/behavior/undefined.zig b/test/behavior/undefined.zig index ea8fc4a283d39486370824bd0f74352fb6969719..bb8dfda9dfc010b20e3aaffbd080fab452197314 100644 --- a/test/behavior/undefined.zig +++ b/test/behavior/undefined.zig @@ -99,7 +99,6 @@ test "reslice of undefined global var slice" { } test "returned undef is 0xaa bytes when runtime safety is enabled" { - 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_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index 6fc3cb0058b70f067da375b2be5e5e6d2d4bb4a1..cb9cd4a87a3fe3a2721badcec057aecc72b0214b 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -485,7 +485,6 @@ test "initialize vector which is a struct field" { test "vector comparison operators" { if (builtin.zig_backend == .stage2_wasm) 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_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c index 34aab7f93461b1fc0a58f6a788303eff88380f89..92b6f2bb4384659b032c0273293793d478fcf97f 100644 --- a/test/c_abi/cfuncs.c +++ b/test/c_abi/cfuncs.c @@ -236,6 +236,2156 @@ struct SplitStructMixed zig_ret_split_struct_mixed(); struct BigStruct zig_big_struct_both(struct BigStruct); +#if defined(ZIG_BACKEND_STAGE2_X86_64) || defined(ZIG_PPC32) + +typedef bool Vector2Bool __attribute__((ext_vector_type(2))); +typedef bool Vector4Bool __attribute__((ext_vector_type(4))); +typedef bool Vector8Bool __attribute__((ext_vector_type(8))); +typedef bool Vector16Bool __attribute__((ext_vector_type(16))); +typedef bool Vector32Bool __attribute__((ext_vector_type(32))); +typedef bool Vector64Bool __attribute__((ext_vector_type(64))); +typedef bool Vector128Bool __attribute__((ext_vector_type(128))); +typedef bool Vector256Bool __attribute__((ext_vector_type(256))); +typedef bool Vector512Bool __attribute__((ext_vector_type(512))); + +void c_vector_2_bool(Vector2Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); +} + +void c_vector_4_bool(Vector4Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == true); +} + +void c_vector_8_bool(Vector8Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == true); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == true); +} + +void c_vector_16_bool(Vector16Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == false); +} + +void c_vector_32_bool(Vector32Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == true); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == false); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == false); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == true); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == false); + assert_or_panic(vec[17] == true); + assert_or_panic(vec[18] == false); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == true); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == true); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == true); + assert_or_panic(vec[31] == false); +} + +void c_vector_64_bool(Vector64Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == false); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == false); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == true); + assert_or_panic(vec[14] == true); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == true); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == false); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == false); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == false); + assert_or_panic(vec[23] == true); + assert_or_panic(vec[24] == true); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == true); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == false); + assert_or_panic(vec[31] == false); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == true); + assert_or_panic(vec[34] == false); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == false); + assert_or_panic(vec[37] == false); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == true); + assert_or_panic(vec[41] == false); + assert_or_panic(vec[42] == false); + assert_or_panic(vec[43] == true); + assert_or_panic(vec[44] == true); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == true); + assert_or_panic(vec[47] == false); + assert_or_panic(vec[48] == true); + assert_or_panic(vec[49] == false); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == true); + assert_or_panic(vec[52] == false); + assert_or_panic(vec[53] == true); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == true); + assert_or_panic(vec[56] == true); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == false); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == false); + assert_or_panic(vec[62] == true); + assert_or_panic(vec[63] == false); +} + +void c_vector_128_bool(Vector128Bool vec) { + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == false); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == true); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == true); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == true); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == false); + assert_or_panic(vec[19] == false); + assert_or_panic(vec[20] == false); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == false); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == false); + assert_or_panic(vec[31] == false); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == false); + assert_or_panic(vec[34] == false); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == true); + assert_or_panic(vec[37] == true); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == false); + assert_or_panic(vec[41] == true); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == true); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == false); + assert_or_panic(vec[48] == true); + assert_or_panic(vec[49] == true); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == true); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == true); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == true); + assert_or_panic(vec[56] == false); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == true); + assert_or_panic(vec[59] == false); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == false); + assert_or_panic(vec[62] == false); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == true); + assert_or_panic(vec[65] == false); + assert_or_panic(vec[66] == true); + assert_or_panic(vec[67] == true); + assert_or_panic(vec[68] == false); + assert_or_panic(vec[69] == true); + assert_or_panic(vec[70] == false); + assert_or_panic(vec[71] == false); + assert_or_panic(vec[72] == true); + assert_or_panic(vec[73] == true); + assert_or_panic(vec[74] == false); + assert_or_panic(vec[75] == true); + assert_or_panic(vec[76] == true); + assert_or_panic(vec[77] == true); + assert_or_panic(vec[78] == false); + assert_or_panic(vec[79] == true); + assert_or_panic(vec[80] == false); + assert_or_panic(vec[81] == false); + assert_or_panic(vec[82] == false); + assert_or_panic(vec[83] == false); + assert_or_panic(vec[84] == true); + assert_or_panic(vec[85] == false); + assert_or_panic(vec[86] == false); + assert_or_panic(vec[87] == false); + assert_or_panic(vec[88] == true); + assert_or_panic(vec[89] == true); + assert_or_panic(vec[90] == false); + assert_or_panic(vec[91] == false); + assert_or_panic(vec[92] == true); + assert_or_panic(vec[93] == true); + assert_or_panic(vec[94] == true); + assert_or_panic(vec[95] == true); + assert_or_panic(vec[96] == false); + assert_or_panic(vec[97] == false); + assert_or_panic(vec[98] == false); + assert_or_panic(vec[99] == false); + assert_or_panic(vec[100] == false); + assert_or_panic(vec[101] == true); + assert_or_panic(vec[102] == false); + assert_or_panic(vec[103] == false); + assert_or_panic(vec[104] == false); + assert_or_panic(vec[105] == false); + assert_or_panic(vec[106] == true); + assert_or_panic(vec[107] == true); + assert_or_panic(vec[108] == true); + assert_or_panic(vec[109] == true); + assert_or_panic(vec[110] == true); + assert_or_panic(vec[111] == false); + assert_or_panic(vec[112] == false); + assert_or_panic(vec[113] == true); + assert_or_panic(vec[114] == false); + assert_or_panic(vec[115] == true); + assert_or_panic(vec[116] == false); + assert_or_panic(vec[117] == false); + assert_or_panic(vec[118] == true); + assert_or_panic(vec[119] == false); + assert_or_panic(vec[120] == true); + assert_or_panic(vec[121] == false); + assert_or_panic(vec[122] == true); + assert_or_panic(vec[123] == true); + assert_or_panic(vec[124] == true); + assert_or_panic(vec[125] == true); + assert_or_panic(vec[126] == true); + assert_or_panic(vec[127] == true); +} + +void c_vector_256_bool(Vector256Bool vec) { + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == false); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == true); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == false); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == true); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == false); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == false); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == false); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == true); + assert_or_panic(vec[31] == false); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == false); + assert_or_panic(vec[34] == false); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == false); + assert_or_panic(vec[37] == true); + assert_or_panic(vec[38] == false); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == true); + assert_or_panic(vec[41] == true); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == false); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == true); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == false); + assert_or_panic(vec[48] == false); + assert_or_panic(vec[49] == false); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == false); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == true); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == true); + assert_or_panic(vec[56] == true); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == true); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == false); + assert_or_panic(vec[62] == false); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == false); + assert_or_panic(vec[65] == false); + assert_or_panic(vec[66] == false); + assert_or_panic(vec[67] == false); + assert_or_panic(vec[68] == false); + assert_or_panic(vec[69] == false); + assert_or_panic(vec[70] == true); + assert_or_panic(vec[71] == true); + assert_or_panic(vec[72] == true); + assert_or_panic(vec[73] == false); + assert_or_panic(vec[74] == false); + assert_or_panic(vec[75] == false); + assert_or_panic(vec[76] == true); + assert_or_panic(vec[77] == false); + assert_or_panic(vec[78] == true); + assert_or_panic(vec[79] == true); + assert_or_panic(vec[80] == false); + assert_or_panic(vec[81] == false); + assert_or_panic(vec[82] == true); + assert_or_panic(vec[83] == true); + assert_or_panic(vec[84] == false); + assert_or_panic(vec[85] == true); + assert_or_panic(vec[86] == true); + assert_or_panic(vec[87] == true); + assert_or_panic(vec[88] == true); + assert_or_panic(vec[89] == true); + assert_or_panic(vec[90] == true); + assert_or_panic(vec[91] == true); + assert_or_panic(vec[92] == false); + assert_or_panic(vec[93] == true); + assert_or_panic(vec[94] == true); + assert_or_panic(vec[95] == false); + assert_or_panic(vec[96] == false); + assert_or_panic(vec[97] == true); + assert_or_panic(vec[98] == true); + assert_or_panic(vec[99] == false); + assert_or_panic(vec[100] == true); + assert_or_panic(vec[101] == false); + assert_or_panic(vec[102] == false); + assert_or_panic(vec[103] == true); + assert_or_panic(vec[104] == false); + assert_or_panic(vec[105] == true); + assert_or_panic(vec[106] == true); + assert_or_panic(vec[107] == true); + assert_or_panic(vec[108] == true); + assert_or_panic(vec[109] == true); + assert_or_panic(vec[110] == false); + assert_or_panic(vec[111] == false); + assert_or_panic(vec[112] == false); + assert_or_panic(vec[113] == false); + assert_or_panic(vec[114] == true); + assert_or_panic(vec[115] == true); + assert_or_panic(vec[116] == false); + assert_or_panic(vec[117] == true); + assert_or_panic(vec[118] == false); + assert_or_panic(vec[119] == false); + assert_or_panic(vec[120] == true); + assert_or_panic(vec[121] == false); + assert_or_panic(vec[122] == false); + assert_or_panic(vec[123] == true); + assert_or_panic(vec[124] == false); + assert_or_panic(vec[125] == true); + assert_or_panic(vec[126] == true); + assert_or_panic(vec[127] == true); + assert_or_panic(vec[128] == true); + assert_or_panic(vec[129] == false); + assert_or_panic(vec[130] == true); + assert_or_panic(vec[131] == true); + assert_or_panic(vec[132] == false); + assert_or_panic(vec[133] == false); + assert_or_panic(vec[134] == true); + assert_or_panic(vec[135] == false); + assert_or_panic(vec[136] == false); + assert_or_panic(vec[137] == true); + assert_or_panic(vec[138] == false); + assert_or_panic(vec[139] == true); + assert_or_panic(vec[140] == false); + assert_or_panic(vec[141] == true); + assert_or_panic(vec[142] == true); + assert_or_panic(vec[143] == true); + assert_or_panic(vec[144] == true); + assert_or_panic(vec[145] == false); + assert_or_panic(vec[146] == true); + assert_or_panic(vec[147] == false); + assert_or_panic(vec[148] == false); + assert_or_panic(vec[149] == false); + assert_or_panic(vec[150] == true); + assert_or_panic(vec[151] == true); + assert_or_panic(vec[152] == true); + assert_or_panic(vec[153] == true); + assert_or_panic(vec[154] == true); + assert_or_panic(vec[155] == false); + assert_or_panic(vec[156] == true); + assert_or_panic(vec[157] == false); + assert_or_panic(vec[158] == false); + assert_or_panic(vec[159] == false); + assert_or_panic(vec[160] == true); + assert_or_panic(vec[161] == true); + assert_or_panic(vec[162] == false); + assert_or_panic(vec[163] == true); + assert_or_panic(vec[164] == true); + assert_or_panic(vec[165] == false); + assert_or_panic(vec[166] == false); + assert_or_panic(vec[167] == false); + assert_or_panic(vec[168] == false); + assert_or_panic(vec[169] == true); + assert_or_panic(vec[170] == false); + assert_or_panic(vec[171] == true); + assert_or_panic(vec[172] == false); + assert_or_panic(vec[173] == false); + assert_or_panic(vec[174] == false); + assert_or_panic(vec[175] == false); + assert_or_panic(vec[176] == true); + assert_or_panic(vec[177] == true); + assert_or_panic(vec[178] == true); + assert_or_panic(vec[179] == false); + assert_or_panic(vec[180] == true); + assert_or_panic(vec[181] == false); + assert_or_panic(vec[182] == true); + assert_or_panic(vec[183] == true); + assert_or_panic(vec[184] == false); + assert_or_panic(vec[185] == false); + assert_or_panic(vec[186] == true); + assert_or_panic(vec[187] == false); + assert_or_panic(vec[188] == false); + assert_or_panic(vec[189] == false); + assert_or_panic(vec[190] == false); + assert_or_panic(vec[191] == true); + assert_or_panic(vec[192] == true); + assert_or_panic(vec[193] == true); + assert_or_panic(vec[194] == true); + assert_or_panic(vec[195] == true); + assert_or_panic(vec[196] == true); + assert_or_panic(vec[197] == true); + assert_or_panic(vec[198] == false); + assert_or_panic(vec[199] == true); + assert_or_panic(vec[200] == false); + assert_or_panic(vec[201] == false); + assert_or_panic(vec[202] == true); + assert_or_panic(vec[203] == false); + assert_or_panic(vec[204] == true); + assert_or_panic(vec[205] == true); + assert_or_panic(vec[206] == true); + assert_or_panic(vec[207] == false); + assert_or_panic(vec[208] == false); + assert_or_panic(vec[209] == true); + assert_or_panic(vec[210] == true); + assert_or_panic(vec[211] == true); + assert_or_panic(vec[212] == false); + assert_or_panic(vec[213] == true); + assert_or_panic(vec[214] == true); + assert_or_panic(vec[215] == true); + assert_or_panic(vec[216] == true); + assert_or_panic(vec[217] == true); + assert_or_panic(vec[218] == false); + assert_or_panic(vec[219] == false); + assert_or_panic(vec[220] == false); + assert_or_panic(vec[221] == false); + assert_or_panic(vec[222] == false); + assert_or_panic(vec[223] == true); + assert_or_panic(vec[224] == true); + assert_or_panic(vec[225] == false); + assert_or_panic(vec[226] == true); + assert_or_panic(vec[227] == false); + assert_or_panic(vec[228] == false); + assert_or_panic(vec[229] == true); + assert_or_panic(vec[230] == false); + assert_or_panic(vec[231] == true); + assert_or_panic(vec[232] == false); + assert_or_panic(vec[233] == false); + assert_or_panic(vec[234] == false); + assert_or_panic(vec[235] == true); + assert_or_panic(vec[236] == false); + assert_or_panic(vec[237] == false); + assert_or_panic(vec[238] == false); + assert_or_panic(vec[239] == true); + assert_or_panic(vec[240] == true); + assert_or_panic(vec[241] == true); + assert_or_panic(vec[242] == true); + assert_or_panic(vec[243] == true); + assert_or_panic(vec[244] == true); + assert_or_panic(vec[245] == false); + assert_or_panic(vec[246] == false); + assert_or_panic(vec[247] == true); + assert_or_panic(vec[248] == false); + assert_or_panic(vec[249] == true); + assert_or_panic(vec[250] == true); + assert_or_panic(vec[251] == false); + assert_or_panic(vec[252] == true); + assert_or_panic(vec[253] == true); + assert_or_panic(vec[254] == true); + assert_or_panic(vec[255] == false); +} + +void c_vector_512_bool(Vector512Bool vec) { + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == true); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == true); + assert_or_panic(vec[13] == true); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == false); + assert_or_panic(vec[16] == false); + assert_or_panic(vec[17] == true); + assert_or_panic(vec[18] == true); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == true); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == false); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == true); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == false); + assert_or_panic(vec[27] == false); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == false); + assert_or_panic(vec[30] == false); + assert_or_panic(vec[31] == true); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == false); + assert_or_panic(vec[34] == true); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == true); + assert_or_panic(vec[37] == true); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == false); + assert_or_panic(vec[41] == true); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == false); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == true); + assert_or_panic(vec[47] == true); + assert_or_panic(vec[48] == false); + assert_or_panic(vec[49] == true); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == true); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == false); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == false); + assert_or_panic(vec[56] == false); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == true); + assert_or_panic(vec[59] == false); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == true); + assert_or_panic(vec[62] == false); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == false); + assert_or_panic(vec[65] == true); + assert_or_panic(vec[66] == true); + assert_or_panic(vec[67] == true); + assert_or_panic(vec[68] == true); + assert_or_panic(vec[69] == true); + assert_or_panic(vec[70] == true); + assert_or_panic(vec[71] == true); + assert_or_panic(vec[72] == true); + assert_or_panic(vec[73] == true); + assert_or_panic(vec[74] == false); + assert_or_panic(vec[75] == true); + assert_or_panic(vec[76] == false); + assert_or_panic(vec[77] == true); + assert_or_panic(vec[78] == false); + assert_or_panic(vec[79] == false); + assert_or_panic(vec[80] == false); + assert_or_panic(vec[81] == true); + assert_or_panic(vec[82] == false); + assert_or_panic(vec[83] == true); + assert_or_panic(vec[84] == true); + assert_or_panic(vec[85] == false); + assert_or_panic(vec[86] == true); + assert_or_panic(vec[87] == true); + assert_or_panic(vec[88] == true); + assert_or_panic(vec[89] == false); + assert_or_panic(vec[90] == true); + assert_or_panic(vec[91] == true); + assert_or_panic(vec[92] == false); + assert_or_panic(vec[93] == true); + assert_or_panic(vec[94] == false); + assert_or_panic(vec[95] == true); + assert_or_panic(vec[96] == true); + assert_or_panic(vec[97] == false); + assert_or_panic(vec[98] == false); + assert_or_panic(vec[99] == false); + assert_or_panic(vec[100] == true); + assert_or_panic(vec[101] == true); + assert_or_panic(vec[102] == false); + assert_or_panic(vec[103] == true); + assert_or_panic(vec[104] == false); + assert_or_panic(vec[105] == false); + assert_or_panic(vec[106] == true); + assert_or_panic(vec[107] == false); + assert_or_panic(vec[108] == false); + assert_or_panic(vec[109] == true); + assert_or_panic(vec[110] == false); + assert_or_panic(vec[111] == false); + assert_or_panic(vec[112] == false); + assert_or_panic(vec[113] == false); + assert_or_panic(vec[114] == false); + assert_or_panic(vec[115] == true); + assert_or_panic(vec[116] == true); + assert_or_panic(vec[117] == false); + assert_or_panic(vec[118] == false); + assert_or_panic(vec[119] == false); + assert_or_panic(vec[120] == false); + assert_or_panic(vec[121] == true); + assert_or_panic(vec[122] == false); + assert_or_panic(vec[123] == false); + assert_or_panic(vec[124] == true); + assert_or_panic(vec[125] == true); + assert_or_panic(vec[126] == false); + assert_or_panic(vec[127] == true); + assert_or_panic(vec[128] == false); + assert_or_panic(vec[129] == true); + assert_or_panic(vec[130] == true); + assert_or_panic(vec[131] == false); + assert_or_panic(vec[132] == true); + assert_or_panic(vec[133] == false); + assert_or_panic(vec[134] == false); + assert_or_panic(vec[135] == false); + assert_or_panic(vec[136] == false); + assert_or_panic(vec[137] == true); + assert_or_panic(vec[138] == true); + assert_or_panic(vec[139] == false); + assert_or_panic(vec[140] == false); + assert_or_panic(vec[141] == false); + assert_or_panic(vec[142] == true); + assert_or_panic(vec[143] == true); + assert_or_panic(vec[144] == false); + assert_or_panic(vec[145] == false); + assert_or_panic(vec[146] == true); + assert_or_panic(vec[147] == true); + assert_or_panic(vec[148] == true); + assert_or_panic(vec[149] == true); + assert_or_panic(vec[150] == true); + assert_or_panic(vec[151] == true); + assert_or_panic(vec[152] == true); + assert_or_panic(vec[153] == false); + assert_or_panic(vec[154] == true); + assert_or_panic(vec[155] == false); + assert_or_panic(vec[156] == false); + assert_or_panic(vec[157] == true); + assert_or_panic(vec[158] == false); + assert_or_panic(vec[159] == true); + assert_or_panic(vec[160] == false); + assert_or_panic(vec[161] == true); + assert_or_panic(vec[162] == true); + assert_or_panic(vec[163] == true); + assert_or_panic(vec[164] == true); + assert_or_panic(vec[165] == true); + assert_or_panic(vec[166] == true); + assert_or_panic(vec[167] == true); + assert_or_panic(vec[168] == true); + assert_or_panic(vec[169] == false); + assert_or_panic(vec[170] == true); + assert_or_panic(vec[171] == true); + assert_or_panic(vec[172] == false); + assert_or_panic(vec[173] == true); + assert_or_panic(vec[174] == true); + assert_or_panic(vec[175] == false); + assert_or_panic(vec[176] == false); + assert_or_panic(vec[177] == false); + assert_or_panic(vec[178] == true); + assert_or_panic(vec[179] == false); + assert_or_panic(vec[180] == false); + assert_or_panic(vec[181] == true); + assert_or_panic(vec[182] == true); + assert_or_panic(vec[183] == true); + assert_or_panic(vec[184] == true); + assert_or_panic(vec[185] == true); + assert_or_panic(vec[186] == true); + assert_or_panic(vec[187] == true); + assert_or_panic(vec[188] == true); + assert_or_panic(vec[189] == true); + assert_or_panic(vec[190] == false); + assert_or_panic(vec[191] == true); + assert_or_panic(vec[192] == true); + assert_or_panic(vec[193] == false); + assert_or_panic(vec[194] == false); + assert_or_panic(vec[195] == true); + assert_or_panic(vec[196] == true); + assert_or_panic(vec[197] == false); + assert_or_panic(vec[198] == true); + assert_or_panic(vec[199] == true); + assert_or_panic(vec[200] == false); + assert_or_panic(vec[201] == true); + assert_or_panic(vec[202] == true); + assert_or_panic(vec[203] == false); + assert_or_panic(vec[204] == true); + assert_or_panic(vec[205] == true); + assert_or_panic(vec[206] == true); + assert_or_panic(vec[207] == true); + assert_or_panic(vec[208] == false); + assert_or_panic(vec[209] == true); + assert_or_panic(vec[210] == false); + assert_or_panic(vec[211] == true); + assert_or_panic(vec[212] == true); + assert_or_panic(vec[213] == false); + assert_or_panic(vec[214] == true); + assert_or_panic(vec[215] == false); + assert_or_panic(vec[216] == true); + assert_or_panic(vec[217] == false); + assert_or_panic(vec[218] == true); + assert_or_panic(vec[219] == false); + assert_or_panic(vec[220] == false); + assert_or_panic(vec[221] == true); + assert_or_panic(vec[222] == false); + assert_or_panic(vec[223] == false); + assert_or_panic(vec[224] == false); + assert_or_panic(vec[225] == true); + assert_or_panic(vec[226] == true); + assert_or_panic(vec[227] == false); + assert_or_panic(vec[228] == false); + assert_or_panic(vec[229] == false); + assert_or_panic(vec[230] == true); + assert_or_panic(vec[231] == false); + assert_or_panic(vec[232] == true); + assert_or_panic(vec[233] == false); + assert_or_panic(vec[234] == false); + assert_or_panic(vec[235] == false); + assert_or_panic(vec[236] == true); + assert_or_panic(vec[237] == true); + assert_or_panic(vec[238] == false); + assert_or_panic(vec[239] == false); + assert_or_panic(vec[240] == false); + assert_or_panic(vec[241] == false); + assert_or_panic(vec[242] == false); + assert_or_panic(vec[243] == true); + assert_or_panic(vec[244] == true); + assert_or_panic(vec[245] == false); + assert_or_panic(vec[246] == true); + assert_or_panic(vec[247] == false); + assert_or_panic(vec[248] == false); + assert_or_panic(vec[249] == true); + assert_or_panic(vec[250] == false); + assert_or_panic(vec[251] == false); + assert_or_panic(vec[252] == false); + assert_or_panic(vec[253] == true); + assert_or_panic(vec[254] == false); + assert_or_panic(vec[255] == false); + assert_or_panic(vec[256] == false); + assert_or_panic(vec[257] == false); + assert_or_panic(vec[258] == true); + assert_or_panic(vec[259] == true); + assert_or_panic(vec[260] == true); + assert_or_panic(vec[261] == true); + assert_or_panic(vec[262] == false); + assert_or_panic(vec[263] == true); + assert_or_panic(vec[264] == false); + assert_or_panic(vec[265] == false); + assert_or_panic(vec[266] == false); + assert_or_panic(vec[267] == true); + assert_or_panic(vec[268] == false); + assert_or_panic(vec[269] == false); + assert_or_panic(vec[270] == true); + assert_or_panic(vec[271] == true); + assert_or_panic(vec[272] == false); + assert_or_panic(vec[273] == false); + assert_or_panic(vec[274] == false); + assert_or_panic(vec[275] == false); + assert_or_panic(vec[276] == false); + assert_or_panic(vec[277] == true); + assert_or_panic(vec[278] == false); + assert_or_panic(vec[279] == true); + assert_or_panic(vec[280] == true); + assert_or_panic(vec[281] == true); + assert_or_panic(vec[282] == true); + assert_or_panic(vec[283] == true); + assert_or_panic(vec[284] == false); + assert_or_panic(vec[285] == false); + assert_or_panic(vec[286] == false); + assert_or_panic(vec[287] == false); + assert_or_panic(vec[288] == false); + assert_or_panic(vec[289] == false); + assert_or_panic(vec[290] == false); + assert_or_panic(vec[291] == false); + assert_or_panic(vec[292] == false); + assert_or_panic(vec[293] == true); + assert_or_panic(vec[294] == true); + assert_or_panic(vec[295] == true); + assert_or_panic(vec[296] == true); + assert_or_panic(vec[297] == true); + assert_or_panic(vec[298] == true); + assert_or_panic(vec[299] == false); + assert_or_panic(vec[300] == true); + assert_or_panic(vec[301] == false); + assert_or_panic(vec[302] == true); + assert_or_panic(vec[303] == true); + assert_or_panic(vec[304] == true); + assert_or_panic(vec[305] == false); + assert_or_panic(vec[306] == false); + assert_or_panic(vec[307] == true); + assert_or_panic(vec[308] == true); + assert_or_panic(vec[309] == true); + assert_or_panic(vec[310] == false); + assert_or_panic(vec[311] == true); + assert_or_panic(vec[312] == true); + assert_or_panic(vec[313] == true); + assert_or_panic(vec[314] == false); + assert_or_panic(vec[315] == true); + assert_or_panic(vec[316] == true); + assert_or_panic(vec[317] == true); + assert_or_panic(vec[318] == false); + assert_or_panic(vec[319] == true); + assert_or_panic(vec[320] == true); + assert_or_panic(vec[321] == false); + assert_or_panic(vec[322] == false); + assert_or_panic(vec[323] == true); + assert_or_panic(vec[324] == false); + assert_or_panic(vec[325] == false); + assert_or_panic(vec[326] == false); + assert_or_panic(vec[327] == false); + assert_or_panic(vec[328] == true); + assert_or_panic(vec[329] == false); + assert_or_panic(vec[330] == true); + assert_or_panic(vec[331] == true); + assert_or_panic(vec[332] == true); + assert_or_panic(vec[333] == true); + assert_or_panic(vec[334] == false); + assert_or_panic(vec[335] == false); + assert_or_panic(vec[336] == true); + assert_or_panic(vec[337] == false); + assert_or_panic(vec[338] == true); + assert_or_panic(vec[339] == false); + assert_or_panic(vec[340] == false); + assert_or_panic(vec[341] == false); + assert_or_panic(vec[342] == true); + assert_or_panic(vec[343] == false); + assert_or_panic(vec[344] == true); + assert_or_panic(vec[345] == false); + assert_or_panic(vec[346] == false); + assert_or_panic(vec[347] == true); + assert_or_panic(vec[348] == true); + assert_or_panic(vec[349] == true); + assert_or_panic(vec[350] == true); + assert_or_panic(vec[351] == false); + assert_or_panic(vec[352] == false); + assert_or_panic(vec[353] == false); + assert_or_panic(vec[354] == true); + assert_or_panic(vec[355] == true); + assert_or_panic(vec[356] == false); + assert_or_panic(vec[357] == true); + assert_or_panic(vec[358] == false); + assert_or_panic(vec[359] == false); + assert_or_panic(vec[360] == true); + assert_or_panic(vec[361] == false); + assert_or_panic(vec[362] == true); + assert_or_panic(vec[363] == false); + assert_or_panic(vec[364] == true); + assert_or_panic(vec[365] == true); + assert_or_panic(vec[366] == false); + assert_or_panic(vec[367] == false); + assert_or_panic(vec[368] == true); + assert_or_panic(vec[369] == true); + assert_or_panic(vec[370] == true); + assert_or_panic(vec[371] == true); + assert_or_panic(vec[372] == false); + assert_or_panic(vec[373] == false); + assert_or_panic(vec[374] == true); + assert_or_panic(vec[375] == false); + assert_or_panic(vec[376] == true); + assert_or_panic(vec[377] == true); + assert_or_panic(vec[378] == false); + assert_or_panic(vec[379] == true); + assert_or_panic(vec[380] == true); + assert_or_panic(vec[381] == false); + assert_or_panic(vec[382] == true); + assert_or_panic(vec[383] == true); + assert_or_panic(vec[384] == true); + assert_or_panic(vec[385] == false); + assert_or_panic(vec[386] == true); + assert_or_panic(vec[387] == true); + assert_or_panic(vec[388] == true); + assert_or_panic(vec[389] == false); + assert_or_panic(vec[390] == false); + assert_or_panic(vec[391] == true); + assert_or_panic(vec[392] == false); + assert_or_panic(vec[393] == true); + assert_or_panic(vec[394] == true); + assert_or_panic(vec[395] == true); + assert_or_panic(vec[396] == false); + assert_or_panic(vec[397] == false); + assert_or_panic(vec[398] == false); + assert_or_panic(vec[399] == false); + assert_or_panic(vec[400] == false); + assert_or_panic(vec[401] == true); + assert_or_panic(vec[402] == false); + assert_or_panic(vec[403] == false); + assert_or_panic(vec[404] == false); + assert_or_panic(vec[405] == false); + assert_or_panic(vec[406] == true); + assert_or_panic(vec[407] == false); + assert_or_panic(vec[408] == false); + assert_or_panic(vec[409] == true); + assert_or_panic(vec[410] == true); + assert_or_panic(vec[411] == false); + assert_or_panic(vec[412] == false); + assert_or_panic(vec[413] == false); + assert_or_panic(vec[414] == false); + assert_or_panic(vec[415] == true); + assert_or_panic(vec[416] == true); + assert_or_panic(vec[417] == true); + assert_or_panic(vec[418] == true); + assert_or_panic(vec[419] == true); + assert_or_panic(vec[420] == false); + assert_or_panic(vec[421] == false); + assert_or_panic(vec[422] == false); + assert_or_panic(vec[423] == true); + assert_or_panic(vec[424] == false); + assert_or_panic(vec[425] == false); + assert_or_panic(vec[426] == false); + assert_or_panic(vec[427] == false); + assert_or_panic(vec[428] == true); + assert_or_panic(vec[429] == false); + assert_or_panic(vec[430] == true); + assert_or_panic(vec[431] == false); + assert_or_panic(vec[432] == true); + assert_or_panic(vec[433] == true); + assert_or_panic(vec[434] == true); + assert_or_panic(vec[435] == true); + assert_or_panic(vec[436] == false); + assert_or_panic(vec[437] == false); + assert_or_panic(vec[438] == false); + assert_or_panic(vec[439] == false); + assert_or_panic(vec[440] == false); + assert_or_panic(vec[441] == true); + assert_or_panic(vec[442] == true); + assert_or_panic(vec[443] == true); + assert_or_panic(vec[444] == true); + assert_or_panic(vec[445] == true); + assert_or_panic(vec[446] == true); + assert_or_panic(vec[447] == true); + assert_or_panic(vec[448] == true); + assert_or_panic(vec[449] == true); + assert_or_panic(vec[450] == false); + assert_or_panic(vec[451] == false); + assert_or_panic(vec[452] == true); + assert_or_panic(vec[453] == false); + assert_or_panic(vec[454] == true); + assert_or_panic(vec[455] == false); + assert_or_panic(vec[456] == false); + assert_or_panic(vec[457] == true); + assert_or_panic(vec[458] == false); + assert_or_panic(vec[459] == false); + assert_or_panic(vec[460] == true); + assert_or_panic(vec[461] == true); + assert_or_panic(vec[462] == true); + assert_or_panic(vec[463] == true); + assert_or_panic(vec[464] == true); + assert_or_panic(vec[465] == true); + assert_or_panic(vec[466] == false); + assert_or_panic(vec[467] == true); + assert_or_panic(vec[468] == false); + assert_or_panic(vec[469] == false); + assert_or_panic(vec[470] == false); + assert_or_panic(vec[471] == true); + assert_or_panic(vec[472] == true); + assert_or_panic(vec[473] == false); + assert_or_panic(vec[474] == true); + assert_or_panic(vec[475] == true); + assert_or_panic(vec[476] == false); + assert_or_panic(vec[477] == false); + assert_or_panic(vec[478] == true); + assert_or_panic(vec[479] == true); + assert_or_panic(vec[480] == false); + assert_or_panic(vec[481] == false); + assert_or_panic(vec[482] == true); + assert_or_panic(vec[483] == true); + assert_or_panic(vec[484] == false); + assert_or_panic(vec[485] == true); + assert_or_panic(vec[486] == false); + assert_or_panic(vec[487] == true); + assert_or_panic(vec[488] == true); + assert_or_panic(vec[489] == true); + assert_or_panic(vec[490] == true); + assert_or_panic(vec[491] == true); + assert_or_panic(vec[492] == true); + assert_or_panic(vec[493] == true); + assert_or_panic(vec[494] == true); + assert_or_panic(vec[495] == true); + assert_or_panic(vec[496] == false); + assert_or_panic(vec[497] == true); + assert_or_panic(vec[498] == true); + assert_or_panic(vec[499] == true); + assert_or_panic(vec[500] == false); + assert_or_panic(vec[501] == false); + assert_or_panic(vec[502] == true); + assert_or_panic(vec[503] == false); + assert_or_panic(vec[504] == false); + assert_or_panic(vec[505] == false); + assert_or_panic(vec[506] == true); + assert_or_panic(vec[507] == true); + assert_or_panic(vec[508] == false); + assert_or_panic(vec[509] == true); + assert_or_panic(vec[510] == false); + assert_or_panic(vec[511] == true); +} + +Vector2Bool c_ret_vector_2_bool(void) { + return (Vector2Bool){ + true, + false, + }; +} + +Vector4Bool c_ret_vector_4_bool(void) { + return (Vector4Bool){ + true, + false, + true, + false, + }; +} + +Vector8Bool c_ret_vector_8_bool(void) { + return (Vector8Bool){ + false, + true, + false, + false, + true, + false, + false, + true, + }; +} + +Vector16Bool c_ret_vector_16_bool(void) { + return (Vector16Bool){ + true, + true, + false, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + }; +} + +Vector32Bool c_ret_vector_32_bool(void) { + return (Vector32Bool){ + true, + false, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + false, + true, + false, + false, + true, + false, + false, + false, + }; +} + +Vector64Bool c_ret_vector_64_bool(void) { + return (Vector64Bool){ + false, + true, + false, + true, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + }; +} + +Vector128Bool c_ret_vector_128_bool(void) { + return (Vector128Bool){ + false, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + }; +} + +Vector256Bool c_ret_vector_256_bool(void) { + return (Vector256Bool){ + true, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + true, + true, + false, + false, + true, + false, + true, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + true, + false, + true, + true, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + false, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + false, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + false, + false, + false, + }; +} + +Vector512Bool c_ret_vector_512_bool(void) { + return (Vector512Bool){ + false, + true, + false, + false, + false, + true, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + true, + true, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + false, + false, + false, + true, + false, + true, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + true, + false, + true, + false, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + false, + true, + false, + true, + false, + false, + true, + false, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + true, + false, + true, + true, + false, + false, + true, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + false, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + true, + false, + }; +} + +void zig_vector_2_bool(Vector2Bool vec); +void zig_vector_4_bool(Vector4Bool vec); +void zig_vector_8_bool(Vector8Bool vec); +void zig_vector_16_bool(Vector16Bool vec); +void zig_vector_32_bool(Vector32Bool vec); +void zig_vector_64_bool(Vector64Bool vec); +void zig_vector_128_bool(Vector128Bool vec); +void zig_vector_256_bool(Vector256Bool vec); +void zig_vector_512_bool(Vector512Bool vec); + +Vector2Bool zig_ret_vector_2_bool(void); +Vector4Bool zig_ret_vector_4_bool(void); +Vector8Bool zig_ret_vector_8_bool(void); +Vector16Bool zig_ret_vector_16_bool(void); +Vector32Bool zig_ret_vector_32_bool(void); +Vector64Bool zig_ret_vector_64_bool(void); +Vector128Bool zig_ret_vector_128_bool(void); +Vector256Bool zig_ret_vector_256_bool(void); +Vector512Bool zig_ret_vector_512_bool(void); + +#endif + typedef struct Vector3 { float x; float y; @@ -450,6 +2600,2107 @@ void run_c_tests(void) { assert_or_panic(zig_ret_i32() == -1); assert_or_panic(zig_ret_i64() == -1); } + +#if defined(ZIG_BACKEND_STAGE2_X86_64) || defined(ZIG_PPC32) + { + zig_vector_2_bool((Vector2Bool){ + false, + true, + }); + + Vector2Bool vec = zig_ret_vector_2_bool(); + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == false); + } + { + zig_vector_4_bool((Vector4Bool){ + false, + false, + false, + false, + }); + + Vector4Bool vec = zig_ret_vector_4_bool(); + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == true); + } + { + zig_vector_8_bool((Vector8Bool){ + true, + true, + false, + true, + false, + true, + true, + false, + }); + + Vector8Bool vec = zig_ret_vector_8_bool(); + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == false); + } + { + zig_vector_16_bool((Vector16Bool){ + true, + false, + true, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + }); + + Vector16Bool vec = zig_ret_vector_16_bool(); + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == false); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == false); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == true); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == false); + } + { + zig_vector_32_bool((Vector32Bool){ + false, + false, + false, + true, + true, + false, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + }); + + Vector32Bool vec = zig_ret_vector_32_bool(); + assert_or_panic(vec[0] == false); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == false); + assert_or_panic(vec[16] == false); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == true); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == true); + assert_or_panic(vec[21] == false); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == true); + assert_or_panic(vec[25] == false); + assert_or_panic(vec[26] == false); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == false); + assert_or_panic(vec[30] == true); + assert_or_panic(vec[31] == true); + } + { + zig_vector_64_bool((Vector64Bool){ + true, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + true, + false, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + true, + false, + false, + false, + false, + false, + true, + false, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + }); + + Vector64Bool vec = zig_ret_vector_64_bool(); + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == false); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == false); + assert_or_panic(vec[10] == true); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == true); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == false); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == true); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == false); + assert_or_panic(vec[21] == false); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == true); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == false); + assert_or_panic(vec[31] == false); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == true); + assert_or_panic(vec[34] == true); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == false); + assert_or_panic(vec[37] == true); + assert_or_panic(vec[38] == false); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == true); + assert_or_panic(vec[41] == true); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == true); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == true); + assert_or_panic(vec[48] == true); + assert_or_panic(vec[49] == true); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == true); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == true); + assert_or_panic(vec[54] == false); + assert_or_panic(vec[55] == false); + assert_or_panic(vec[56] == false); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == false); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == false); + assert_or_panic(vec[62] == true); + assert_or_panic(vec[63] == false); + } + { + zig_vector_128_bool((Vector128Bool){ + true, + true, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + false, + true, + false, + }); + + Vector128Bool vec = zig_ret_vector_128_bool(); + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == false); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == true); + assert_or_panic(vec[7] == false); + assert_or_panic(vec[8] == false); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == true); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == true); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == false); + assert_or_panic(vec[19] == true); + assert_or_panic(vec[20] == true); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == true); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == false); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == true); + assert_or_panic(vec[28] == true); + assert_or_panic(vec[29] == false); + assert_or_panic(vec[30] == false); + assert_or_panic(vec[31] == true); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == false); + assert_or_panic(vec[34] == true); + assert_or_panic(vec[35] == true); + assert_or_panic(vec[36] == true); + assert_or_panic(vec[37] == false); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == true); + assert_or_panic(vec[41] == false); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == true); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == true); + assert_or_panic(vec[48] == false); + assert_or_panic(vec[49] == false); + assert_or_panic(vec[50] == false); + assert_or_panic(vec[51] == false); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == false); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == false); + assert_or_panic(vec[56] == true); + assert_or_panic(vec[57] == false); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == true); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == true); + assert_or_panic(vec[62] == true); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == false); + assert_or_panic(vec[65] == false); + assert_or_panic(vec[66] == false); + assert_or_panic(vec[67] == true); + assert_or_panic(vec[68] == true); + assert_or_panic(vec[69] == false); + assert_or_panic(vec[70] == true); + assert_or_panic(vec[71] == true); + assert_or_panic(vec[72] == false); + assert_or_panic(vec[73] == true); + assert_or_panic(vec[74] == true); + assert_or_panic(vec[75] == false); + assert_or_panic(vec[76] == false); + assert_or_panic(vec[77] == true); + assert_or_panic(vec[78] == false); + assert_or_panic(vec[79] == true); + assert_or_panic(vec[80] == false); + assert_or_panic(vec[81] == false); + assert_or_panic(vec[82] == true); + assert_or_panic(vec[83] == true); + assert_or_panic(vec[84] == false); + assert_or_panic(vec[85] == true); + assert_or_panic(vec[86] == false); + assert_or_panic(vec[87] == false); + assert_or_panic(vec[88] == true); + assert_or_panic(vec[89] == true); + assert_or_panic(vec[90] == true); + assert_or_panic(vec[91] == true); + assert_or_panic(vec[92] == true); + assert_or_panic(vec[93] == false); + assert_or_panic(vec[94] == false); + assert_or_panic(vec[95] == true); + assert_or_panic(vec[96] == false); + assert_or_panic(vec[97] == false); + assert_or_panic(vec[98] == true); + assert_or_panic(vec[99] == true); + assert_or_panic(vec[100] == true); + assert_or_panic(vec[101] == true); + assert_or_panic(vec[102] == true); + assert_or_panic(vec[103] == true); + assert_or_panic(vec[104] == true); + assert_or_panic(vec[105] == false); + assert_or_panic(vec[106] == false); + assert_or_panic(vec[107] == true); + assert_or_panic(vec[108] == false); + assert_or_panic(vec[109] == false); + assert_or_panic(vec[110] == true); + assert_or_panic(vec[111] == false); + assert_or_panic(vec[112] == false); + assert_or_panic(vec[113] == true); + assert_or_panic(vec[114] == false); + assert_or_panic(vec[115] == false); + assert_or_panic(vec[116] == false); + assert_or_panic(vec[117] == false); + assert_or_panic(vec[118] == false); + assert_or_panic(vec[119] == false); + assert_or_panic(vec[120] == true); + assert_or_panic(vec[121] == true); + assert_or_panic(vec[122] == true); + assert_or_panic(vec[123] == false); + assert_or_panic(vec[124] == true); + assert_or_panic(vec[125] == false); + assert_or_panic(vec[126] == false); + assert_or_panic(vec[127] == true); + } + { + zig_vector_256_bool((Vector256Bool){ + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + false, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + false, + false, + true, + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + false, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + false, + false, + true, + true, + true, + true, + }); + + Vector256Bool vec = zig_ret_vector_256_bool(); + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == false); + assert_or_panic(vec[4] == true); + assert_or_panic(vec[5] == false); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == false); + assert_or_panic(vec[9] == false); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == false); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == false); + assert_or_panic(vec[16] == true); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == true); + assert_or_panic(vec[19] == false); + assert_or_panic(vec[20] == false); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == true); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == true); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == false); + assert_or_panic(vec[28] == true); + assert_or_panic(vec[29] == true); + assert_or_panic(vec[30] == true); + assert_or_panic(vec[31] == false); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == false); + assert_or_panic(vec[34] == true); + assert_or_panic(vec[35] == false); + assert_or_panic(vec[36] == true); + assert_or_panic(vec[37] == false); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == false); + assert_or_panic(vec[40] == false); + assert_or_panic(vec[41] == false); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == true); + assert_or_panic(vec[44] == true); + assert_or_panic(vec[45] == false); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == false); + assert_or_panic(vec[48] == true); + assert_or_panic(vec[49] == false); + assert_or_panic(vec[50] == true); + assert_or_panic(vec[51] == false); + assert_or_panic(vec[52] == true); + assert_or_panic(vec[53] == false); + assert_or_panic(vec[54] == true); + assert_or_panic(vec[55] == true); + assert_or_panic(vec[56] == false); + assert_or_panic(vec[57] == false); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == true); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == true); + assert_or_panic(vec[62] == false); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == false); + assert_or_panic(vec[65] == true); + assert_or_panic(vec[66] == false); + assert_or_panic(vec[67] == true); + assert_or_panic(vec[68] == true); + assert_or_panic(vec[69] == false); + assert_or_panic(vec[70] == true); + assert_or_panic(vec[71] == false); + assert_or_panic(vec[72] == true); + assert_or_panic(vec[73] == true); + assert_or_panic(vec[74] == false); + assert_or_panic(vec[75] == false); + assert_or_panic(vec[76] == false); + assert_or_panic(vec[77] == false); + assert_or_panic(vec[78] == false); + assert_or_panic(vec[79] == false); + assert_or_panic(vec[80] == false); + assert_or_panic(vec[81] == false); + assert_or_panic(vec[82] == false); + assert_or_panic(vec[83] == true); + assert_or_panic(vec[84] == false); + assert_or_panic(vec[85] == false); + assert_or_panic(vec[86] == false); + assert_or_panic(vec[87] == true); + assert_or_panic(vec[88] == false); + assert_or_panic(vec[89] == true); + assert_or_panic(vec[90] == true); + assert_or_panic(vec[91] == false); + assert_or_panic(vec[92] == false); + assert_or_panic(vec[93] == true); + assert_or_panic(vec[94] == true); + assert_or_panic(vec[95] == false); + assert_or_panic(vec[96] == false); + assert_or_panic(vec[97] == true); + assert_or_panic(vec[98] == false); + assert_or_panic(vec[99] == false); + assert_or_panic(vec[100] == false); + assert_or_panic(vec[101] == false); + assert_or_panic(vec[102] == false); + assert_or_panic(vec[103] == false); + assert_or_panic(vec[104] == false); + assert_or_panic(vec[105] == true); + assert_or_panic(vec[106] == true); + assert_or_panic(vec[107] == false); + assert_or_panic(vec[108] == true); + assert_or_panic(vec[109] == false); + assert_or_panic(vec[110] == true); + assert_or_panic(vec[111] == true); + assert_or_panic(vec[112] == false); + assert_or_panic(vec[113] == false); + assert_or_panic(vec[114] == false); + assert_or_panic(vec[115] == false); + assert_or_panic(vec[116] == false); + assert_or_panic(vec[117] == false); + assert_or_panic(vec[118] == false); + assert_or_panic(vec[119] == true); + assert_or_panic(vec[120] == true); + assert_or_panic(vec[121] == true); + assert_or_panic(vec[122] == false); + assert_or_panic(vec[123] == true); + assert_or_panic(vec[124] == true); + assert_or_panic(vec[125] == false); + assert_or_panic(vec[126] == false); + assert_or_panic(vec[127] == true); + assert_or_panic(vec[128] == true); + assert_or_panic(vec[129] == true); + assert_or_panic(vec[130] == true); + assert_or_panic(vec[131] == true); + assert_or_panic(vec[132] == false); + assert_or_panic(vec[133] == true); + assert_or_panic(vec[134] == true); + assert_or_panic(vec[135] == false); + assert_or_panic(vec[136] == false); + assert_or_panic(vec[137] == true); + assert_or_panic(vec[138] == true); + assert_or_panic(vec[139] == false); + assert_or_panic(vec[140] == true); + assert_or_panic(vec[141] == false); + assert_or_panic(vec[142] == true); + assert_or_panic(vec[143] == false); + assert_or_panic(vec[144] == true); + assert_or_panic(vec[145] == true); + assert_or_panic(vec[146] == true); + assert_or_panic(vec[147] == true); + assert_or_panic(vec[148] == false); + assert_or_panic(vec[149] == false); + assert_or_panic(vec[150] == false); + assert_or_panic(vec[151] == true); + assert_or_panic(vec[152] == false); + assert_or_panic(vec[153] == true); + assert_or_panic(vec[154] == false); + assert_or_panic(vec[155] == true); + assert_or_panic(vec[156] == true); + assert_or_panic(vec[157] == false); + assert_or_panic(vec[158] == true); + assert_or_panic(vec[159] == true); + assert_or_panic(vec[160] == true); + assert_or_panic(vec[161] == true); + assert_or_panic(vec[162] == true); + assert_or_panic(vec[163] == false); + assert_or_panic(vec[164] == false); + assert_or_panic(vec[165] == true); + assert_or_panic(vec[166] == false); + assert_or_panic(vec[167] == true); + assert_or_panic(vec[168] == true); + assert_or_panic(vec[169] == true); + assert_or_panic(vec[170] == true); + assert_or_panic(vec[171] == false); + assert_or_panic(vec[172] == true); + assert_or_panic(vec[173] == true); + assert_or_panic(vec[174] == true); + assert_or_panic(vec[175] == true); + assert_or_panic(vec[176] == true); + assert_or_panic(vec[177] == true); + assert_or_panic(vec[178] == true); + assert_or_panic(vec[179] == false); + assert_or_panic(vec[180] == true); + assert_or_panic(vec[181] == false); + assert_or_panic(vec[182] == false); + assert_or_panic(vec[183] == false); + assert_or_panic(vec[184] == true); + assert_or_panic(vec[185] == false); + assert_or_panic(vec[186] == true); + assert_or_panic(vec[187] == true); + assert_or_panic(vec[188] == false); + assert_or_panic(vec[189] == true); + assert_or_panic(vec[190] == false); + assert_or_panic(vec[191] == true); + assert_or_panic(vec[192] == false); + assert_or_panic(vec[193] == true); + assert_or_panic(vec[194] == false); + assert_or_panic(vec[195] == false); + assert_or_panic(vec[196] == true); + assert_or_panic(vec[197] == true); + assert_or_panic(vec[198] == true); + assert_or_panic(vec[199] == true); + assert_or_panic(vec[200] == true); + assert_or_panic(vec[201] == true); + assert_or_panic(vec[202] == true); + assert_or_panic(vec[203] == false); + assert_or_panic(vec[204] == true); + assert_or_panic(vec[205] == false); + assert_or_panic(vec[206] == false); + assert_or_panic(vec[207] == true); + assert_or_panic(vec[208] == true); + assert_or_panic(vec[209] == false); + assert_or_panic(vec[210] == false); + assert_or_panic(vec[211] == false); + assert_or_panic(vec[212] == true); + assert_or_panic(vec[213] == true); + assert_or_panic(vec[214] == true); + assert_or_panic(vec[215] == false); + assert_or_panic(vec[216] == false); + assert_or_panic(vec[217] == true); + assert_or_panic(vec[218] == true); + assert_or_panic(vec[219] == true); + assert_or_panic(vec[220] == true); + assert_or_panic(vec[221] == false); + assert_or_panic(vec[222] == true); + assert_or_panic(vec[223] == false); + assert_or_panic(vec[224] == true); + assert_or_panic(vec[225] == true); + assert_or_panic(vec[226] == true); + assert_or_panic(vec[227] == false); + assert_or_panic(vec[228] == false); + assert_or_panic(vec[229] == false); + assert_or_panic(vec[230] == false); + assert_or_panic(vec[231] == false); + assert_or_panic(vec[232] == true); + assert_or_panic(vec[233] == true); + assert_or_panic(vec[234] == false); + assert_or_panic(vec[235] == false); + assert_or_panic(vec[236] == false); + assert_or_panic(vec[237] == true); + assert_or_panic(vec[238] == true); + assert_or_panic(vec[239] == false); + assert_or_panic(vec[240] == true); + assert_or_panic(vec[241] == true); + assert_or_panic(vec[242] == true); + assert_or_panic(vec[243] == false); + assert_or_panic(vec[244] == true); + assert_or_panic(vec[245] == true); + assert_or_panic(vec[246] == false); + assert_or_panic(vec[247] == true); + assert_or_panic(vec[248] == false); + assert_or_panic(vec[249] == false); + assert_or_panic(vec[250] == true); + assert_or_panic(vec[251] == true); + assert_or_panic(vec[252] == false); + assert_or_panic(vec[253] == true); + assert_or_panic(vec[254] == false); + assert_or_panic(vec[255] == true); + } + { + zig_vector_512_bool((Vector512Bool){ + false, + true, + true, + false, + true, + false, + true, + false, + false, + false, + false, + false, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + true, + false, + false, + true, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + false, + false, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + false, + false, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + false, + false, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + false, + false, + true, + false, + true, + true, + false, + false, + true, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + false, + false, + true, + false, + false, + true, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + true, + true, + false, + false, + false, + false, + true, + false, + true, + false, + false, + false, + false, + true, + false, + false, + true, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + true, + }); + + Vector512Bool vec = zig_ret_vector_512_bool(); + assert_or_panic(vec[0] == true); + assert_or_panic(vec[1] == true); + assert_or_panic(vec[2] == true); + assert_or_panic(vec[3] == true); + assert_or_panic(vec[4] == false); + assert_or_panic(vec[5] == true); + assert_or_panic(vec[6] == false); + assert_or_panic(vec[7] == true); + assert_or_panic(vec[8] == true); + assert_or_panic(vec[9] == true); + assert_or_panic(vec[10] == false); + assert_or_panic(vec[11] == true); + assert_or_panic(vec[12] == false); + assert_or_panic(vec[13] == false); + assert_or_panic(vec[14] == false); + assert_or_panic(vec[15] == true); + assert_or_panic(vec[16] == true); + assert_or_panic(vec[17] == false); + assert_or_panic(vec[18] == false); + assert_or_panic(vec[19] == false); + assert_or_panic(vec[20] == true); + assert_or_panic(vec[21] == true); + assert_or_panic(vec[22] == false); + assert_or_panic(vec[23] == false); + assert_or_panic(vec[24] == false); + assert_or_panic(vec[25] == false); + assert_or_panic(vec[26] == true); + assert_or_panic(vec[27] == false); + assert_or_panic(vec[28] == false); + assert_or_panic(vec[29] == false); + assert_or_panic(vec[30] == true); + assert_or_panic(vec[31] == true); + assert_or_panic(vec[32] == true); + assert_or_panic(vec[33] == true); + assert_or_panic(vec[34] == false); + assert_or_panic(vec[35] == false); + assert_or_panic(vec[36] == false); + assert_or_panic(vec[37] == true); + assert_or_panic(vec[38] == true); + assert_or_panic(vec[39] == true); + assert_or_panic(vec[40] == false); + assert_or_panic(vec[41] == false); + assert_or_panic(vec[42] == true); + assert_or_panic(vec[43] == false); + assert_or_panic(vec[44] == false); + assert_or_panic(vec[45] == true); + assert_or_panic(vec[46] == false); + assert_or_panic(vec[47] == false); + assert_or_panic(vec[48] == true); + assert_or_panic(vec[49] == true); + assert_or_panic(vec[50] == true); + assert_or_panic(vec[51] == true); + assert_or_panic(vec[52] == false); + assert_or_panic(vec[53] == false); + assert_or_panic(vec[54] == false); + assert_or_panic(vec[55] == true); + assert_or_panic(vec[56] == false); + assert_or_panic(vec[57] == true); + assert_or_panic(vec[58] == false); + assert_or_panic(vec[59] == true); + assert_or_panic(vec[60] == true); + assert_or_panic(vec[61] == false); + assert_or_panic(vec[62] == false); + assert_or_panic(vec[63] == true); + assert_or_panic(vec[64] == true); + assert_or_panic(vec[65] == false); + assert_or_panic(vec[66] == true); + assert_or_panic(vec[67] == false); + assert_or_panic(vec[68] == false); + assert_or_panic(vec[69] == false); + assert_or_panic(vec[70] == true); + assert_or_panic(vec[71] == true); + assert_or_panic(vec[72] == true); + assert_or_panic(vec[73] == true); + assert_or_panic(vec[74] == true); + assert_or_panic(vec[75] == false); + assert_or_panic(vec[76] == true); + assert_or_panic(vec[77] == false); + assert_or_panic(vec[78] == true); + assert_or_panic(vec[79] == true); + assert_or_panic(vec[80] == true); + assert_or_panic(vec[81] == true); + assert_or_panic(vec[82] == true); + assert_or_panic(vec[83] == false); + assert_or_panic(vec[84] == true); + assert_or_panic(vec[85] == true); + assert_or_panic(vec[86] == false); + assert_or_panic(vec[87] == true); + assert_or_panic(vec[88] == false); + assert_or_panic(vec[89] == false); + assert_or_panic(vec[90] == true); + assert_or_panic(vec[91] == false); + assert_or_panic(vec[92] == true); + assert_or_panic(vec[93] == false); + assert_or_panic(vec[94] == false); + assert_or_panic(vec[95] == false); + assert_or_panic(vec[96] == true); + assert_or_panic(vec[97] == true); + assert_or_panic(vec[98] == false); + assert_or_panic(vec[99] == true); + assert_or_panic(vec[100] == true); + assert_or_panic(vec[101] == false); + assert_or_panic(vec[102] == true); + assert_or_panic(vec[103] == false); + assert_or_panic(vec[104] == true); + assert_or_panic(vec[105] == false); + assert_or_panic(vec[106] == true); + assert_or_panic(vec[107] == false); + assert_or_panic(vec[108] == false); + assert_or_panic(vec[109] == true); + assert_or_panic(vec[110] == false); + assert_or_panic(vec[111] == false); + assert_or_panic(vec[112] == true); + assert_or_panic(vec[113] == false); + assert_or_panic(vec[114] == true); + assert_or_panic(vec[115] == false); + assert_or_panic(vec[116] == true); + assert_or_panic(vec[117] == false); + assert_or_panic(vec[118] == false); + assert_or_panic(vec[119] == true); + assert_or_panic(vec[120] == true); + assert_or_panic(vec[121] == true); + assert_or_panic(vec[122] == false); + assert_or_panic(vec[123] == true); + assert_or_panic(vec[124] == false); + assert_or_panic(vec[125] == false); + assert_or_panic(vec[126] == true); + assert_or_panic(vec[127] == true); + assert_or_panic(vec[128] == false); + assert_or_panic(vec[129] == true); + assert_or_panic(vec[130] == true); + assert_or_panic(vec[131] == false); + assert_or_panic(vec[132] == true); + assert_or_panic(vec[133] == true); + assert_or_panic(vec[134] == false); + assert_or_panic(vec[135] == true); + assert_or_panic(vec[136] == true); + assert_or_panic(vec[137] == false); + assert_or_panic(vec[138] == false); + assert_or_panic(vec[139] == false); + assert_or_panic(vec[140] == true); + assert_or_panic(vec[141] == false); + assert_or_panic(vec[142] == true); + assert_or_panic(vec[143] == false); + assert_or_panic(vec[144] == false); + assert_or_panic(vec[145] == false); + assert_or_panic(vec[146] == true); + assert_or_panic(vec[147] == false); + assert_or_panic(vec[148] == true); + assert_or_panic(vec[149] == false); + assert_or_panic(vec[150] == false); + assert_or_panic(vec[151] == true); + assert_or_panic(vec[152] == false); + assert_or_panic(vec[153] == true); + assert_or_panic(vec[154] == true); + assert_or_panic(vec[155] == false); + assert_or_panic(vec[156] == true); + assert_or_panic(vec[157] == true); + assert_or_panic(vec[158] == false); + assert_or_panic(vec[159] == true); + assert_or_panic(vec[160] == true); + assert_or_panic(vec[161] == false); + assert_or_panic(vec[162] == false); + assert_or_panic(vec[163] == false); + assert_or_panic(vec[164] == true); + assert_or_panic(vec[165] == false); + assert_or_panic(vec[166] == true); + assert_or_panic(vec[167] == true); + assert_or_panic(vec[168] == true); + assert_or_panic(vec[169] == true); + assert_or_panic(vec[170] == false); + assert_or_panic(vec[171] == true); + assert_or_panic(vec[172] == false); + assert_or_panic(vec[173] == false); + assert_or_panic(vec[174] == true); + assert_or_panic(vec[175] == true); + assert_or_panic(vec[176] == true); + assert_or_panic(vec[177] == false); + assert_or_panic(vec[178] == false); + assert_or_panic(vec[179] == false); + assert_or_panic(vec[180] == true); + assert_or_panic(vec[181] == false); + assert_or_panic(vec[182] == false); + assert_or_panic(vec[183] == true); + assert_or_panic(vec[184] == true); + assert_or_panic(vec[185] == false); + assert_or_panic(vec[186] == true); + assert_or_panic(vec[187] == false); + assert_or_panic(vec[188] == true); + assert_or_panic(vec[189] == true); + assert_or_panic(vec[190] == true); + assert_or_panic(vec[191] == true); + assert_or_panic(vec[192] == true); + assert_or_panic(vec[193] == true); + assert_or_panic(vec[194] == true); + assert_or_panic(vec[195] == false); + assert_or_panic(vec[196] == false); + assert_or_panic(vec[197] == false); + assert_or_panic(vec[198] == false); + assert_or_panic(vec[199] == false); + assert_or_panic(vec[200] == true); + assert_or_panic(vec[201] == false); + assert_or_panic(vec[202] == true); + assert_or_panic(vec[203] == false); + assert_or_panic(vec[204] == true); + assert_or_panic(vec[205] == true); + assert_or_panic(vec[206] == false); + assert_or_panic(vec[207] == false); + assert_or_panic(vec[208] == false); + assert_or_panic(vec[209] == true); + assert_or_panic(vec[210] == true); + assert_or_panic(vec[211] == true); + assert_or_panic(vec[212] == false); + assert_or_panic(vec[213] == false); + assert_or_panic(vec[214] == true); + assert_or_panic(vec[215] == true); + assert_or_panic(vec[216] == true); + assert_or_panic(vec[217] == false); + assert_or_panic(vec[218] == false); + assert_or_panic(vec[219] == true); + assert_or_panic(vec[220] == false); + assert_or_panic(vec[221] == true); + assert_or_panic(vec[222] == true); + assert_or_panic(vec[223] == false); + assert_or_panic(vec[224] == true); + assert_or_panic(vec[225] == false); + assert_or_panic(vec[226] == false); + assert_or_panic(vec[227] == true); + assert_or_panic(vec[228] == false); + assert_or_panic(vec[229] == false); + assert_or_panic(vec[230] == true); + assert_or_panic(vec[231] == true); + assert_or_panic(vec[232] == false); + assert_or_panic(vec[233] == true); + assert_or_panic(vec[234] == true); + assert_or_panic(vec[235] == true); + assert_or_panic(vec[236] == true); + assert_or_panic(vec[237] == true); + assert_or_panic(vec[238] == false); + assert_or_panic(vec[239] == true); + assert_or_panic(vec[240] == false); + assert_or_panic(vec[241] == false); + assert_or_panic(vec[242] == true); + assert_or_panic(vec[243] == false); + assert_or_panic(vec[244] == true); + assert_or_panic(vec[245] == false); + assert_or_panic(vec[246] == true); + assert_or_panic(vec[247] == false); + assert_or_panic(vec[248] == true); + assert_or_panic(vec[249] == true); + assert_or_panic(vec[250] == true); + assert_or_panic(vec[251] == true); + assert_or_panic(vec[252] == true); + assert_or_panic(vec[253] == false); + assert_or_panic(vec[254] == false); + assert_or_panic(vec[255] == false); + assert_or_panic(vec[256] == false); + assert_or_panic(vec[257] == false); + assert_or_panic(vec[258] == false); + assert_or_panic(vec[259] == true); + assert_or_panic(vec[260] == true); + assert_or_panic(vec[261] == true); + assert_or_panic(vec[262] == true); + assert_or_panic(vec[263] == false); + assert_or_panic(vec[264] == false); + assert_or_panic(vec[265] == false); + assert_or_panic(vec[266] == true); + assert_or_panic(vec[267] == false); + assert_or_panic(vec[268] == true); + assert_or_panic(vec[269] == false); + assert_or_panic(vec[270] == true); + assert_or_panic(vec[271] == true); + assert_or_panic(vec[272] == true); + assert_or_panic(vec[273] == true); + assert_or_panic(vec[274] == true); + assert_or_panic(vec[275] == true); + assert_or_panic(vec[276] == false); + assert_or_panic(vec[277] == false); + assert_or_panic(vec[278] == true); + assert_or_panic(vec[279] == true); + assert_or_panic(vec[280] == false); + assert_or_panic(vec[281] == false); + assert_or_panic(vec[282] == false); + assert_or_panic(vec[283] == false); + assert_or_panic(vec[284] == true); + assert_or_panic(vec[285] == true); + assert_or_panic(vec[286] == true); + assert_or_panic(vec[287] == false); + assert_or_panic(vec[288] == false); + assert_or_panic(vec[289] == false); + assert_or_panic(vec[290] == true); + assert_or_panic(vec[291] == false); + assert_or_panic(vec[292] == true); + assert_or_panic(vec[293] == true); + assert_or_panic(vec[294] == false); + assert_or_panic(vec[295] == true); + assert_or_panic(vec[296] == true); + assert_or_panic(vec[297] == true); + assert_or_panic(vec[298] == false); + assert_or_panic(vec[299] == true); + assert_or_panic(vec[300] == true); + assert_or_panic(vec[301] == false); + assert_or_panic(vec[302] == false); + assert_or_panic(vec[303] == true); + assert_or_panic(vec[304] == false); + assert_or_panic(vec[305] == false); + assert_or_panic(vec[306] == true); + assert_or_panic(vec[307] == true); + assert_or_panic(vec[308] == true); + assert_or_panic(vec[309] == true); + assert_or_panic(vec[310] == false); + assert_or_panic(vec[311] == false); + assert_or_panic(vec[312] == false); + assert_or_panic(vec[313] == false); + assert_or_panic(vec[314] == false); + assert_or_panic(vec[315] == true); + assert_or_panic(vec[316] == false); + assert_or_panic(vec[317] == false); + assert_or_panic(vec[318] == true); + assert_or_panic(vec[319] == false); + assert_or_panic(vec[320] == false); + assert_or_panic(vec[321] == true); + assert_or_panic(vec[322] == true); + assert_or_panic(vec[323] == true); + assert_or_panic(vec[324] == true); + assert_or_panic(vec[325] == false); + assert_or_panic(vec[326] == false); + assert_or_panic(vec[327] == false); + assert_or_panic(vec[328] == true); + assert_or_panic(vec[329] == true); + assert_or_panic(vec[330] == false); + assert_or_panic(vec[331] == true); + assert_or_panic(vec[332] == true); + assert_or_panic(vec[333] == false); + assert_or_panic(vec[334] == false); + assert_or_panic(vec[335] == true); + assert_or_panic(vec[336] == true); + assert_or_panic(vec[337] == false); + assert_or_panic(vec[338] == true); + assert_or_panic(vec[339] == true); + assert_or_panic(vec[340] == true); + assert_or_panic(vec[341] == false); + assert_or_panic(vec[342] == false); + assert_or_panic(vec[343] == false); + assert_or_panic(vec[344] == true); + assert_or_panic(vec[345] == true); + assert_or_panic(vec[346] == false); + assert_or_panic(vec[347] == true); + assert_or_panic(vec[348] == false); + assert_or_panic(vec[349] == true); + assert_or_panic(vec[350] == false); + assert_or_panic(vec[351] == false); + assert_or_panic(vec[352] == true); + assert_or_panic(vec[353] == false); + assert_or_panic(vec[354] == true); + assert_or_panic(vec[355] == false); + assert_or_panic(vec[356] == false); + assert_or_panic(vec[357] == false); + assert_or_panic(vec[358] == false); + assert_or_panic(vec[359] == false); + assert_or_panic(vec[360] == true); + assert_or_panic(vec[361] == true); + assert_or_panic(vec[362] == false); + assert_or_panic(vec[363] == false); + assert_or_panic(vec[364] == false); + assert_or_panic(vec[365] == false); + assert_or_panic(vec[366] == true); + assert_or_panic(vec[367] == false); + assert_or_panic(vec[368] == true); + assert_or_panic(vec[369] == false); + assert_or_panic(vec[370] == true); + assert_or_panic(vec[371] == true); + assert_or_panic(vec[372] == false); + assert_or_panic(vec[373] == true); + assert_or_panic(vec[374] == true); + assert_or_panic(vec[375] == true); + assert_or_panic(vec[376] == true); + assert_or_panic(vec[377] == true); + assert_or_panic(vec[378] == false); + assert_or_panic(vec[379] == true); + assert_or_panic(vec[380] == false); + assert_or_panic(vec[381] == true); + assert_or_panic(vec[382] == true); + assert_or_panic(vec[383] == true); + assert_or_panic(vec[384] == true); + assert_or_panic(vec[385] == true); + assert_or_panic(vec[386] == false); + assert_or_panic(vec[387] == true); + assert_or_panic(vec[388] == true); + assert_or_panic(vec[389] == false); + assert_or_panic(vec[390] == true); + assert_or_panic(vec[391] == false); + assert_or_panic(vec[392] == true); + assert_or_panic(vec[393] == false); + assert_or_panic(vec[394] == true); + assert_or_panic(vec[395] == false); + assert_or_panic(vec[396] == true); + assert_or_panic(vec[397] == false); + assert_or_panic(vec[398] == false); + assert_or_panic(vec[399] == true); + assert_or_panic(vec[400] == true); + assert_or_panic(vec[401] == true); + assert_or_panic(vec[402] == true); + assert_or_panic(vec[403] == false); + assert_or_panic(vec[404] == false); + assert_or_panic(vec[405] == true); + assert_or_panic(vec[406] == false); + assert_or_panic(vec[407] == false); + assert_or_panic(vec[408] == false); + assert_or_panic(vec[409] == true); + assert_or_panic(vec[410] == false); + assert_or_panic(vec[411] == true); + assert_or_panic(vec[412] == true); + assert_or_panic(vec[413] == false); + assert_or_panic(vec[414] == true); + assert_or_panic(vec[415] == true); + assert_or_panic(vec[416] == false); + assert_or_panic(vec[417] == true); + assert_or_panic(vec[418] == true); + assert_or_panic(vec[419] == false); + assert_or_panic(vec[420] == false); + assert_or_panic(vec[421] == true); + assert_or_panic(vec[422] == false); + assert_or_panic(vec[423] == false); + assert_or_panic(vec[424] == true); + assert_or_panic(vec[425] == false); + assert_or_panic(vec[426] == true); + assert_or_panic(vec[427] == false); + assert_or_panic(vec[428] == false); + assert_or_panic(vec[429] == true); + assert_or_panic(vec[430] == false); + assert_or_panic(vec[431] == true); + assert_or_panic(vec[432] == true); + assert_or_panic(vec[433] == false); + assert_or_panic(vec[434] == true); + assert_or_panic(vec[435] == false); + assert_or_panic(vec[436] == true); + assert_or_panic(vec[437] == false); + assert_or_panic(vec[438] == true); + assert_or_panic(vec[439] == false); + assert_or_panic(vec[440] == false); + assert_or_panic(vec[441] == true); + assert_or_panic(vec[442] == true); + assert_or_panic(vec[443] == false); + assert_or_panic(vec[444] == true); + assert_or_panic(vec[445] == true); + assert_or_panic(vec[446] == false); + assert_or_panic(vec[447] == true); + assert_or_panic(vec[448] == true); + assert_or_panic(vec[449] == false); + assert_or_panic(vec[450] == false); + assert_or_panic(vec[451] == false); + assert_or_panic(vec[452] == false); + assert_or_panic(vec[453] == false); + assert_or_panic(vec[454] == true); + assert_or_panic(vec[455] == false); + assert_or_panic(vec[456] == false); + assert_or_panic(vec[457] == true); + assert_or_panic(vec[458] == false); + assert_or_panic(vec[459] == true); + assert_or_panic(vec[460] == false); + assert_or_panic(vec[461] == false); + assert_or_panic(vec[462] == false); + assert_or_panic(vec[463] == true); + assert_or_panic(vec[464] == false); + assert_or_panic(vec[465] == true); + assert_or_panic(vec[466] == false); + assert_or_panic(vec[467] == false); + assert_or_panic(vec[468] == false); + assert_or_panic(vec[469] == false); + assert_or_panic(vec[470] == true); + assert_or_panic(vec[471] == true); + assert_or_panic(vec[472] == false); + assert_or_panic(vec[473] == true); + assert_or_panic(vec[474] == true); + assert_or_panic(vec[475] == false); + assert_or_panic(vec[476] == false); + assert_or_panic(vec[477] == true); + assert_or_panic(vec[478] == true); + assert_or_panic(vec[479] == true); + assert_or_panic(vec[480] == false); + assert_or_panic(vec[481] == false); + assert_or_panic(vec[482] == true); + assert_or_panic(vec[483] == false); + assert_or_panic(vec[484] == false); + assert_or_panic(vec[485] == false); + assert_or_panic(vec[486] == true); + assert_or_panic(vec[487] == true); + assert_or_panic(vec[488] == false); + assert_or_panic(vec[489] == false); + assert_or_panic(vec[490] == false); + assert_or_panic(vec[491] == false); + assert_or_panic(vec[492] == false); + assert_or_panic(vec[493] == true); + assert_or_panic(vec[494] == true); + assert_or_panic(vec[495] == true); + assert_or_panic(vec[496] == true); + assert_or_panic(vec[497] == false); + assert_or_panic(vec[498] == false); + assert_or_panic(vec[499] == false); + assert_or_panic(vec[500] == true); + assert_or_panic(vec[501] == false); + assert_or_panic(vec[502] == true); + assert_or_panic(vec[503] == true); + assert_or_panic(vec[504] == true); + assert_or_panic(vec[505] == true); + assert_or_panic(vec[506] == false); + assert_or_panic(vec[507] == false); + assert_or_panic(vec[508] == true); + assert_or_panic(vec[509] == true); + assert_or_panic(vec[510] == false); + assert_or_panic(vec[511] == false); + } +#endif } void c_u8(uint8_t x) { diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index 90bfe174ca9ab4d3fafd06a63b3feab5298ae71e..24cbcc82a901c8f42f4dcd64cb3fbab65d4850ac 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -890,6 +890,4264 @@ test "big simd vector" { try expect(x[7] == 16); } +const Vector2Bool = @Vector(2, bool); +const Vector4Bool = @Vector(4, bool); +const Vector8Bool = @Vector(8, bool); +const Vector16Bool = @Vector(16, bool); +const Vector32Bool = @Vector(32, bool); +const Vector64Bool = @Vector(64, bool); +const Vector128Bool = @Vector(128, bool); +const Vector256Bool = @Vector(256, bool); +const Vector512Bool = @Vector(512, bool); + +extern fn c_vector_2_bool(Vector2Bool) void; +extern fn c_vector_4_bool(Vector4Bool) void; +extern fn c_vector_8_bool(Vector8Bool) void; +extern fn c_vector_16_bool(Vector16Bool) void; +extern fn c_vector_32_bool(Vector32Bool) void; +extern fn c_vector_64_bool(Vector64Bool) void; +extern fn c_vector_128_bool(Vector128Bool) void; +extern fn c_vector_256_bool(Vector256Bool) void; +extern fn c_vector_512_bool(Vector512Bool) void; + +extern fn c_ret_vector_2_bool() Vector2Bool; +extern fn c_ret_vector_4_bool() Vector4Bool; +extern fn c_ret_vector_8_bool() Vector8Bool; +extern fn c_ret_vector_16_bool() Vector16Bool; +extern fn c_ret_vector_32_bool() Vector32Bool; +extern fn c_ret_vector_64_bool() Vector64Bool; +extern fn c_ret_vector_128_bool() Vector128Bool; +extern fn c_ret_vector_256_bool() Vector256Bool; +extern fn c_ret_vector_512_bool() Vector512Bool; + +test "bool simd vector" { + if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch != .powerpc) return error.SkipZigTest; + + { + c_vector_2_bool(.{ + true, + true, + }); + + const vec = c_ret_vector_2_bool(); + try expect(vec[0] == true); + try expect(vec[1] == false); + } + { + c_vector_4_bool(.{ + true, + true, + false, + true, + }); + + const vec = c_ret_vector_4_bool(); + try expect(vec[0] == true); + try expect(vec[1] == false); + try expect(vec[2] == true); + try expect(vec[3] == false); + } + { + c_vector_8_bool(.{ + true, + false, + true, + true, + true, + true, + false, + true, + }); + + const vec = c_ret_vector_8_bool(); + try expect(vec[0] == false); + try expect(vec[1] == true); + try expect(vec[2] == false); + try expect(vec[3] == false); + try expect(vec[4] == true); + try expect(vec[5] == false); + try expect(vec[6] == false); + try expect(vec[7] == true); + } + { + c_vector_16_bool(.{ + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + }); + + const vec = c_ret_vector_16_bool(); + try expect(vec[0] == true); + try expect(vec[1] == true); + try expect(vec[2] == false); + try expect(vec[3] == false); + try expect(vec[4] == false); + try expect(vec[5] == false); + try expect(vec[6] == true); + try expect(vec[7] == false); + try expect(vec[8] == true); + try expect(vec[9] == false); + try expect(vec[10] == false); + try expect(vec[11] == true); + try expect(vec[12] == true); + try expect(vec[13] == false); + try expect(vec[14] == true); + try expect(vec[15] == true); + } + { + c_vector_32_bool(.{ + true, + false, + true, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + }); + + const vec = c_ret_vector_32_bool(); + try expect(vec[0] == true); + try expect(vec[1] == false); + try expect(vec[2] == true); + try expect(vec[3] == true); + try expect(vec[4] == true); + try expect(vec[5] == false); + try expect(vec[6] == true); + try expect(vec[7] == false); + try expect(vec[8] == true); + try expect(vec[9] == true); + try expect(vec[10] == true); + try expect(vec[11] == false); + try expect(vec[12] == true); + try expect(vec[13] == true); + try expect(vec[14] == false); + try expect(vec[15] == false); + try expect(vec[16] == true); + try expect(vec[17] == false); + try expect(vec[18] == false); + try expect(vec[19] == false); + try expect(vec[20] == false); + try expect(vec[21] == true); + try expect(vec[22] == true); + try expect(vec[23] == true); + try expect(vec[24] == false); + try expect(vec[25] == true); + try expect(vec[26] == false); + try expect(vec[27] == false); + try expect(vec[28] == true); + try expect(vec[29] == false); + try expect(vec[30] == false); + try expect(vec[31] == false); + } + { + c_vector_64_bool(.{ + true, + true, + true, + false, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + true, + false, + true, + false, + false, + true, + true, + true, + false, + false, + true, + true, + false, + true, + false, + true, + false, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + false, + }); + + const vec = c_ret_vector_64_bool(); + try expect(vec[0] == false); + try expect(vec[1] == true); + try expect(vec[2] == false); + try expect(vec[3] == true); + try expect(vec[4] == true); + try expect(vec[5] == true); + try expect(vec[6] == false); + try expect(vec[7] == true); + try expect(vec[8] == true); + try expect(vec[9] == true); + try expect(vec[10] == true); + try expect(vec[11] == true); + try expect(vec[12] == true); + try expect(vec[13] == false); + try expect(vec[14] == true); + try expect(vec[15] == true); + try expect(vec[16] == true); + try expect(vec[17] == false); + try expect(vec[18] == false); + try expect(vec[19] == false); + try expect(vec[20] == true); + try expect(vec[21] == true); + try expect(vec[22] == false); + try expect(vec[23] == true); + try expect(vec[24] == false); + try expect(vec[25] == true); + try expect(vec[26] == false); + try expect(vec[27] == true); + try expect(vec[28] == false); + try expect(vec[29] == true); + try expect(vec[30] == false); + try expect(vec[31] == true); + try expect(vec[32] == false); + try expect(vec[33] == false); + try expect(vec[34] == true); + try expect(vec[35] == true); + try expect(vec[36] == false); + try expect(vec[37] == false); + try expect(vec[38] == false); + try expect(vec[39] == true); + try expect(vec[40] == true); + try expect(vec[41] == true); + try expect(vec[42] == true); + try expect(vec[43] == false); + try expect(vec[44] == false); + try expect(vec[45] == false); + try expect(vec[46] == true); + try expect(vec[47] == true); + try expect(vec[48] == false); + try expect(vec[49] == false); + try expect(vec[50] == true); + try expect(vec[51] == false); + try expect(vec[52] == false); + try expect(vec[53] == false); + try expect(vec[54] == false); + try expect(vec[55] == true); + try expect(vec[56] == false); + try expect(vec[57] == false); + try expect(vec[58] == false); + try expect(vec[59] == true); + try expect(vec[60] == true); + try expect(vec[61] == true); + try expect(vec[62] == true); + try expect(vec[63] == true); + } + { + c_vector_128_bool(.{ + false, + false, + false, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + true, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + true, + false, + true, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + }); + + const vec = c_ret_vector_128_bool(); + try expect(vec[0] == false); + try expect(vec[1] == true); + try expect(vec[2] == true); + try expect(vec[3] == false); + try expect(vec[4] == true); + try expect(vec[5] == false); + try expect(vec[6] == false); + try expect(vec[7] == true); + try expect(vec[8] == true); + try expect(vec[9] == false); + try expect(vec[10] == true); + try expect(vec[11] == false); + try expect(vec[12] == false); + try expect(vec[13] == false); + try expect(vec[14] == true); + try expect(vec[15] == false); + try expect(vec[16] == true); + try expect(vec[17] == false); + try expect(vec[18] == false); + try expect(vec[19] == true); + try expect(vec[20] == false); + try expect(vec[21] == true); + try expect(vec[22] == false); + try expect(vec[23] == false); + try expect(vec[24] == false); + try expect(vec[25] == true); + try expect(vec[26] == true); + try expect(vec[27] == true); + try expect(vec[28] == false); + try expect(vec[29] == false); + try expect(vec[30] == false); + try expect(vec[31] == false); + try expect(vec[32] == true); + try expect(vec[33] == true); + try expect(vec[34] == true); + try expect(vec[35] == false); + try expect(vec[36] == true); + try expect(vec[37] == true); + try expect(vec[38] == false); + try expect(vec[39] == false); + try expect(vec[40] == false); + try expect(vec[41] == false); + try expect(vec[42] == true); + try expect(vec[43] == true); + try expect(vec[44] == true); + try expect(vec[45] == false); + try expect(vec[46] == false); + try expect(vec[47] == false); + try expect(vec[48] == false); + try expect(vec[49] == true); + try expect(vec[50] == false); + try expect(vec[51] == false); + try expect(vec[52] == true); + try expect(vec[53] == false); + try expect(vec[54] == false); + try expect(vec[55] == false); + try expect(vec[56] == false); + try expect(vec[57] == false); + try expect(vec[58] == true); + try expect(vec[59] == true); + try expect(vec[60] == true); + try expect(vec[61] == false); + try expect(vec[62] == true); + try expect(vec[63] == true); + try expect(vec[64] == false); + try expect(vec[65] == false); + try expect(vec[66] == false); + try expect(vec[67] == false); + try expect(vec[68] == false); + try expect(vec[69] == false); + try expect(vec[70] == false); + try expect(vec[71] == false); + try expect(vec[72] == true); + try expect(vec[73] == true); + try expect(vec[74] == true); + try expect(vec[75] == true); + try expect(vec[76] == true); + try expect(vec[77] == false); + try expect(vec[78] == false); + try expect(vec[79] == false); + try expect(vec[80] == false); + try expect(vec[81] == false); + try expect(vec[82] == false); + try expect(vec[83] == true); + try expect(vec[84] == false); + try expect(vec[85] == true); + try expect(vec[86] == false); + try expect(vec[87] == true); + try expect(vec[88] == false); + try expect(vec[89] == true); + try expect(vec[90] == false); + try expect(vec[91] == true); + try expect(vec[92] == true); + try expect(vec[93] == true); + try expect(vec[94] == true); + try expect(vec[95] == false); + try expect(vec[96] == false); + try expect(vec[97] == true); + try expect(vec[98] == false); + try expect(vec[99] == false); + try expect(vec[100] == true); + try expect(vec[101] == true); + try expect(vec[102] == true); + try expect(vec[103] == true); + try expect(vec[104] == false); + try expect(vec[105] == true); + try expect(vec[106] == true); + try expect(vec[107] == true); + try expect(vec[108] == false); + try expect(vec[109] == false); + try expect(vec[110] == true); + try expect(vec[111] == false); + try expect(vec[112] == false); + try expect(vec[113] == true); + try expect(vec[114] == true); + try expect(vec[115] == false); + try expect(vec[116] == true); + try expect(vec[117] == false); + try expect(vec[118] == true); + try expect(vec[119] == true); + try expect(vec[120] == true); + try expect(vec[121] == true); + try expect(vec[122] == true); + try expect(vec[123] == false); + try expect(vec[124] == false); + try expect(vec[125] == true); + try expect(vec[126] == false); + try expect(vec[127] == true); + } + { + c_vector_256_bool(.{ + false, + true, + true, + false, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + false, + false, + true, + true, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + false, + true, + true, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + false, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + true, + false, + true, + true, + true, + false, + }); + + const vec = c_ret_vector_256_bool(); + try expect(vec[0] == true); + try expect(vec[1] == false); + try expect(vec[2] == true); + try expect(vec[3] == true); + try expect(vec[4] == false); + try expect(vec[5] == false); + try expect(vec[6] == false); + try expect(vec[7] == false); + try expect(vec[8] == false); + try expect(vec[9] == true); + try expect(vec[10] == false); + try expect(vec[11] == true); + try expect(vec[12] == false); + try expect(vec[13] == true); + try expect(vec[14] == false); + try expect(vec[15] == false); + try expect(vec[16] == true); + try expect(vec[17] == true); + try expect(vec[18] == true); + try expect(vec[19] == false); + try expect(vec[20] == false); + try expect(vec[21] == false); + try expect(vec[22] == true); + try expect(vec[23] == false); + try expect(vec[24] == true); + try expect(vec[25] == false); + try expect(vec[26] == false); + try expect(vec[27] == true); + try expect(vec[28] == true); + try expect(vec[29] == true); + try expect(vec[30] == false); + try expect(vec[31] == false); + try expect(vec[32] == true); + try expect(vec[33] == true); + try expect(vec[34] == true); + try expect(vec[35] == false); + try expect(vec[36] == true); + try expect(vec[37] == true); + try expect(vec[38] == true); + try expect(vec[39] == false); + try expect(vec[40] == true); + try expect(vec[41] == false); + try expect(vec[42] == true); + try expect(vec[43] == true); + try expect(vec[44] == false); + try expect(vec[45] == true); + try expect(vec[46] == false); + try expect(vec[47] == true); + try expect(vec[48] == true); + try expect(vec[49] == false); + try expect(vec[50] == false); + try expect(vec[51] == true); + try expect(vec[52] == true); + try expect(vec[53] == false); + try expect(vec[54] == false); + try expect(vec[55] == true); + try expect(vec[56] == false); + try expect(vec[57] == true); + try expect(vec[58] == true); + try expect(vec[59] == true); + try expect(vec[60] == false); + try expect(vec[61] == true); + try expect(vec[62] == true); + try expect(vec[63] == false); + try expect(vec[64] == true); + try expect(vec[65] == true); + try expect(vec[66] == false); + try expect(vec[67] == true); + try expect(vec[68] == false); + try expect(vec[69] == true); + try expect(vec[70] == true); + try expect(vec[71] == true); + try expect(vec[72] == false); + try expect(vec[73] == true); + try expect(vec[74] == true); + try expect(vec[75] == false); + try expect(vec[76] == true); + try expect(vec[77] == true); + try expect(vec[78] == true); + try expect(vec[79] == true); + try expect(vec[80] == false); + try expect(vec[81] == true); + try expect(vec[82] == false); + try expect(vec[83] == true); + try expect(vec[84] == true); + try expect(vec[85] == true); + try expect(vec[86] == false); + try expect(vec[87] == true); + try expect(vec[88] == false); + try expect(vec[89] == true); + try expect(vec[90] == false); + try expect(vec[91] == false); + try expect(vec[92] == true); + try expect(vec[93] == false); + try expect(vec[94] == false); + try expect(vec[95] == false); + try expect(vec[96] == true); + try expect(vec[97] == true); + try expect(vec[98] == false); + try expect(vec[99] == false); + try expect(vec[100] == false); + try expect(vec[101] == true); + try expect(vec[102] == true); + try expect(vec[103] == true); + try expect(vec[104] == false); + try expect(vec[105] == false); + try expect(vec[106] == false); + try expect(vec[107] == true); + try expect(vec[108] == false); + try expect(vec[109] == true); + try expect(vec[110] == true); + try expect(vec[111] == true); + try expect(vec[112] == true); + try expect(vec[113] == true); + try expect(vec[114] == true); + try expect(vec[115] == true); + try expect(vec[116] == true); + try expect(vec[117] == false); + try expect(vec[118] == true); + try expect(vec[119] == false); + try expect(vec[120] == true); + try expect(vec[121] == false); + try expect(vec[122] == false); + try expect(vec[123] == true); + try expect(vec[124] == true); + try expect(vec[125] == false); + try expect(vec[126] == true); + try expect(vec[127] == false); + try expect(vec[128] == false); + try expect(vec[129] == false); + try expect(vec[130] == false); + try expect(vec[131] == true); + try expect(vec[132] == false); + try expect(vec[133] == false); + try expect(vec[134] == true); + try expect(vec[135] == false); + try expect(vec[136] == false); + try expect(vec[137] == false); + try expect(vec[138] == false); + try expect(vec[139] == false); + try expect(vec[140] == false); + try expect(vec[141] == true); + try expect(vec[142] == false); + try expect(vec[143] == true); + try expect(vec[144] == false); + try expect(vec[145] == true); + try expect(vec[146] == true); + try expect(vec[147] == true); + try expect(vec[148] == false); + try expect(vec[149] == true); + try expect(vec[150] == true); + try expect(vec[151] == false); + try expect(vec[152] == true); + try expect(vec[153] == true); + try expect(vec[154] == false); + try expect(vec[155] == true); + try expect(vec[156] == true); + try expect(vec[157] == true); + try expect(vec[158] == true); + try expect(vec[159] == true); + try expect(vec[160] == true); + try expect(vec[161] == true); + try expect(vec[162] == false); + try expect(vec[163] == false); + try expect(vec[164] == false); + try expect(vec[165] == true); + try expect(vec[166] == false); + try expect(vec[167] == false); + try expect(vec[168] == true); + try expect(vec[169] == false); + try expect(vec[170] == true); + try expect(vec[171] == true); + try expect(vec[172] == true); + try expect(vec[173] == false); + try expect(vec[174] == false); + try expect(vec[175] == true); + try expect(vec[176] == true); + try expect(vec[177] == true); + try expect(vec[178] == true); + try expect(vec[179] == false); + try expect(vec[180] == true); + try expect(vec[181] == true); + try expect(vec[182] == false); + try expect(vec[183] == true); + try expect(vec[184] == false); + try expect(vec[185] == false); + try expect(vec[186] == false); + try expect(vec[187] == true); + try expect(vec[188] == true); + try expect(vec[189] == true); + try expect(vec[190] == true); + try expect(vec[191] == true); + try expect(vec[192] == true); + try expect(vec[193] == true); + try expect(vec[194] == true); + try expect(vec[195] == false); + try expect(vec[196] == false); + try expect(vec[197] == true); + try expect(vec[198] == false); + try expect(vec[199] == false); + try expect(vec[200] == false); + try expect(vec[201] == true); + try expect(vec[202] == true); + try expect(vec[203] == true); + try expect(vec[204] == true); + try expect(vec[205] == true); + try expect(vec[206] == true); + try expect(vec[207] == false); + try expect(vec[208] == false); + try expect(vec[209] == false); + try expect(vec[210] == true); + try expect(vec[211] == true); + try expect(vec[212] == true); + try expect(vec[213] == false); + try expect(vec[214] == true); + try expect(vec[215] == false); + try expect(vec[216] == true); + try expect(vec[217] == false); + try expect(vec[218] == true); + try expect(vec[219] == false); + try expect(vec[220] == true); + try expect(vec[221] == true); + try expect(vec[222] == true); + try expect(vec[223] == false); + try expect(vec[224] == true); + try expect(vec[225] == false); + try expect(vec[226] == true); + try expect(vec[227] == false); + try expect(vec[228] == true); + try expect(vec[229] == false); + try expect(vec[230] == true); + try expect(vec[231] == false); + try expect(vec[232] == false); + try expect(vec[233] == true); + try expect(vec[234] == false); + try expect(vec[235] == true); + try expect(vec[236] == true); + try expect(vec[237] == false); + try expect(vec[238] == false); + try expect(vec[239] == true); + try expect(vec[240] == false); + try expect(vec[241] == false); + try expect(vec[242] == false); + try expect(vec[243] == true); + try expect(vec[244] == true); + try expect(vec[245] == false); + try expect(vec[246] == false); + try expect(vec[247] == false); + try expect(vec[248] == false); + try expect(vec[249] == false); + try expect(vec[250] == true); + try expect(vec[251] == false); + try expect(vec[252] == true); + try expect(vec[253] == false); + try expect(vec[254] == false); + try expect(vec[255] == false); + } + { + c_vector_512_bool(.{ + true, + true, + true, + true, + true, + false, + false, + true, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + true, + false, + true, + true, + true, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + true, + true, + false, + false, + true, + true, + true, + true, + false, + false, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + true, + false, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + false, + false, + true, + false, + false, + true, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + }); + + const vec = c_ret_vector_512_bool(); + try expect(vec[0] == false); + try expect(vec[1] == true); + try expect(vec[2] == false); + try expect(vec[3] == false); + try expect(vec[4] == false); + try expect(vec[5] == true); + try expect(vec[6] == false); + try expect(vec[7] == false); + try expect(vec[8] == false); + try expect(vec[9] == true); + try expect(vec[10] == false); + try expect(vec[11] == false); + try expect(vec[12] == false); + try expect(vec[13] == true); + try expect(vec[14] == false); + try expect(vec[15] == true); + try expect(vec[16] == false); + try expect(vec[17] == false); + try expect(vec[18] == false); + try expect(vec[19] == false); + try expect(vec[20] == false); + try expect(vec[21] == false); + try expect(vec[22] == true); + try expect(vec[23] == true); + try expect(vec[24] == false); + try expect(vec[25] == false); + try expect(vec[26] == false); + try expect(vec[27] == false); + try expect(vec[28] == true); + try expect(vec[29] == true); + try expect(vec[30] == false); + try expect(vec[31] == true); + try expect(vec[32] == false); + try expect(vec[33] == true); + try expect(vec[34] == true); + try expect(vec[35] == true); + try expect(vec[36] == false); + try expect(vec[37] == false); + try expect(vec[38] == true); + try expect(vec[39] == true); + try expect(vec[40] == false); + try expect(vec[41] == false); + try expect(vec[42] == false); + try expect(vec[43] == false); + try expect(vec[44] == false); + try expect(vec[45] == true); + try expect(vec[46] == false); + try expect(vec[47] == true); + try expect(vec[48] == true); + try expect(vec[49] == false); + try expect(vec[50] == true); + try expect(vec[51] == true); + try expect(vec[52] == true); + try expect(vec[53] == true); + try expect(vec[54] == false); + try expect(vec[55] == false); + try expect(vec[56] == false); + try expect(vec[57] == true); + try expect(vec[58] == true); + try expect(vec[59] == false); + try expect(vec[60] == false); + try expect(vec[61] == false); + try expect(vec[62] == false); + try expect(vec[63] == true); + try expect(vec[64] == true); + try expect(vec[65] == true); + try expect(vec[66] == true); + try expect(vec[67] == true); + try expect(vec[68] == false); + try expect(vec[69] == false); + try expect(vec[70] == false); + try expect(vec[71] == false); + try expect(vec[72] == false); + try expect(vec[73] == true); + try expect(vec[74] == false); + try expect(vec[75] == true); + try expect(vec[76] == false); + try expect(vec[77] == false); + try expect(vec[78] == true); + try expect(vec[79] == true); + try expect(vec[80] == false); + try expect(vec[81] == false); + try expect(vec[82] == false); + try expect(vec[83] == true); + try expect(vec[84] == false); + try expect(vec[85] == true); + try expect(vec[86] == true); + try expect(vec[87] == true); + try expect(vec[88] == false); + try expect(vec[89] == true); + try expect(vec[90] == false); + try expect(vec[91] == false); + try expect(vec[92] == true); + try expect(vec[93] == true); + try expect(vec[94] == false); + try expect(vec[95] == true); + try expect(vec[96] == true); + try expect(vec[97] == false); + try expect(vec[98] == true); + try expect(vec[99] == false); + try expect(vec[100] == true); + try expect(vec[101] == true); + try expect(vec[102] == false); + try expect(vec[103] == true); + try expect(vec[104] == true); + try expect(vec[105] == false); + try expect(vec[106] == false); + try expect(vec[107] == false); + try expect(vec[108] == true); + try expect(vec[109] == false); + try expect(vec[110] == false); + try expect(vec[111] == false); + try expect(vec[112] == true); + try expect(vec[113] == true); + try expect(vec[114] == true); + try expect(vec[115] == false); + try expect(vec[116] == true); + try expect(vec[117] == false); + try expect(vec[118] == true); + try expect(vec[119] == false); + try expect(vec[120] == true); + try expect(vec[121] == true); + try expect(vec[122] == false); + try expect(vec[123] == true); + try expect(vec[124] == false); + try expect(vec[125] == true); + try expect(vec[126] == true); + try expect(vec[127] == true); + try expect(vec[128] == false); + try expect(vec[129] == true); + try expect(vec[130] == false); + try expect(vec[131] == false); + try expect(vec[132] == false); + try expect(vec[133] == false); + try expect(vec[134] == false); + try expect(vec[135] == false); + try expect(vec[136] == true); + try expect(vec[137] == false); + try expect(vec[138] == true); + try expect(vec[139] == false); + try expect(vec[140] == true); + try expect(vec[141] == true); + try expect(vec[142] == false); + try expect(vec[143] == true); + try expect(vec[144] == false); + try expect(vec[145] == false); + try expect(vec[146] == true); + try expect(vec[147] == false); + try expect(vec[148] == false); + try expect(vec[149] == true); + try expect(vec[150] == false); + try expect(vec[151] == true); + try expect(vec[152] == false); + try expect(vec[153] == true); + try expect(vec[154] == false); + try expect(vec[155] == false); + try expect(vec[156] == true); + try expect(vec[157] == false); + try expect(vec[158] == true); + try expect(vec[159] == true); + try expect(vec[160] == true); + try expect(vec[161] == false); + try expect(vec[162] == false); + try expect(vec[163] == true); + try expect(vec[164] == false); + try expect(vec[165] == false); + try expect(vec[166] == false); + try expect(vec[167] == true); + try expect(vec[168] == true); + try expect(vec[169] == true); + try expect(vec[170] == false); + try expect(vec[171] == true); + try expect(vec[172] == false); + try expect(vec[173] == false); + try expect(vec[174] == false); + try expect(vec[175] == false); + try expect(vec[176] == false); + try expect(vec[177] == true); + try expect(vec[178] == true); + try expect(vec[179] == false); + try expect(vec[180] == false); + try expect(vec[181] == true); + try expect(vec[182] == false); + try expect(vec[183] == false); + try expect(vec[184] == false); + try expect(vec[185] == false); + try expect(vec[186] == false); + try expect(vec[187] == true); + try expect(vec[188] == true); + try expect(vec[189] == false); + try expect(vec[190] == false); + try expect(vec[191] == false); + try expect(vec[192] == false); + try expect(vec[193] == false); + try expect(vec[194] == false); + try expect(vec[195] == true); + try expect(vec[196] == true); + try expect(vec[197] == false); + try expect(vec[198] == true); + try expect(vec[199] == true); + try expect(vec[200] == true); + try expect(vec[201] == true); + try expect(vec[202] == true); + try expect(vec[203] == true); + try expect(vec[204] == false); + try expect(vec[205] == false); + try expect(vec[206] == false); + try expect(vec[207] == false); + try expect(vec[208] == true); + try expect(vec[209] == false); + try expect(vec[210] == true); + try expect(vec[211] == true); + try expect(vec[212] == true); + try expect(vec[213] == true); + try expect(vec[214] == false); + try expect(vec[215] == false); + try expect(vec[216] == false); + try expect(vec[217] == true); + try expect(vec[218] == true); + try expect(vec[219] == false); + try expect(vec[220] == true); + try expect(vec[221] == true); + try expect(vec[222] == false); + try expect(vec[223] == false); + try expect(vec[224] == false); + try expect(vec[225] == true); + try expect(vec[226] == true); + try expect(vec[227] == true); + try expect(vec[228] == true); + try expect(vec[229] == false); + try expect(vec[230] == true); + try expect(vec[231] == false); + try expect(vec[232] == true); + try expect(vec[233] == true); + try expect(vec[234] == true); + try expect(vec[235] == true); + try expect(vec[236] == false); + try expect(vec[237] == true); + try expect(vec[238] == false); + try expect(vec[239] == true); + try expect(vec[240] == false); + try expect(vec[241] == true); + try expect(vec[242] == false); + try expect(vec[243] == false); + try expect(vec[244] == false); + try expect(vec[245] == true); + try expect(vec[246] == true); + try expect(vec[247] == false); + try expect(vec[248] == true); + try expect(vec[249] == false); + try expect(vec[250] == false); + try expect(vec[251] == false); + try expect(vec[252] == true); + try expect(vec[253] == true); + try expect(vec[254] == true); + try expect(vec[255] == true); + try expect(vec[256] == true); + try expect(vec[257] == false); + try expect(vec[258] == true); + try expect(vec[259] == true); + try expect(vec[260] == true); + try expect(vec[261] == true); + try expect(vec[262] == false); + try expect(vec[263] == true); + try expect(vec[264] == false); + try expect(vec[265] == false); + try expect(vec[266] == true); + try expect(vec[267] == false); + try expect(vec[268] == true); + try expect(vec[269] == false); + try expect(vec[270] == false); + try expect(vec[271] == true); + try expect(vec[272] == true); + try expect(vec[273] == false); + try expect(vec[274] == true); + try expect(vec[275] == false); + try expect(vec[276] == false); + try expect(vec[277] == true); + try expect(vec[278] == false); + try expect(vec[279] == false); + try expect(vec[280] == true); + try expect(vec[281] == true); + try expect(vec[282] == true); + try expect(vec[283] == false); + try expect(vec[284] == false); + try expect(vec[285] == true); + try expect(vec[286] == true); + try expect(vec[287] == true); + try expect(vec[288] == false); + try expect(vec[289] == false); + try expect(vec[290] == false); + try expect(vec[291] == false); + try expect(vec[292] == false); + try expect(vec[293] == false); + try expect(vec[294] == true); + try expect(vec[295] == false); + try expect(vec[296] == true); + try expect(vec[297] == false); + try expect(vec[298] == true); + try expect(vec[299] == true); + try expect(vec[300] == false); + try expect(vec[301] == false); + try expect(vec[302] == false); + try expect(vec[303] == false); + try expect(vec[304] == true); + try expect(vec[305] == true); + try expect(vec[306] == true); + try expect(vec[307] == true); + try expect(vec[308] == true); + try expect(vec[309] == false); + try expect(vec[310] == true); + try expect(vec[311] == true); + try expect(vec[312] == true); + try expect(vec[313] == true); + try expect(vec[314] == true); + try expect(vec[315] == false); + try expect(vec[316] == true); + try expect(vec[317] == true); + try expect(vec[318] == true); + try expect(vec[319] == false); + try expect(vec[320] == true); + try expect(vec[321] == false); + try expect(vec[322] == true); + try expect(vec[323] == true); + try expect(vec[324] == true); + try expect(vec[325] == false); + try expect(vec[326] == false); + try expect(vec[327] == true); + try expect(vec[328] == true); + try expect(vec[329] == true); + try expect(vec[330] == false); + try expect(vec[331] == false); + try expect(vec[332] == true); + try expect(vec[333] == true); + try expect(vec[334] == false); + try expect(vec[335] == true); + try expect(vec[336] == true); + try expect(vec[337] == true); + try expect(vec[338] == true); + try expect(vec[339] == true); + try expect(vec[340] == true); + try expect(vec[341] == false); + try expect(vec[342] == true); + try expect(vec[343] == false); + try expect(vec[344] == true); + try expect(vec[345] == false); + try expect(vec[346] == false); + try expect(vec[347] == false); + try expect(vec[348] == false); + try expect(vec[349] == true); + try expect(vec[350] == true); + try expect(vec[351] == true); + try expect(vec[352] == true); + try expect(vec[353] == false); + try expect(vec[354] == true); + try expect(vec[355] == false); + try expect(vec[356] == true); + try expect(vec[357] == true); + try expect(vec[358] == false); + try expect(vec[359] == true); + try expect(vec[360] == false); + try expect(vec[361] == false); + try expect(vec[362] == true); + try expect(vec[363] == false); + try expect(vec[364] == false); + try expect(vec[365] == false); + try expect(vec[366] == false); + try expect(vec[367] == false); + try expect(vec[368] == false); + try expect(vec[369] == false); + try expect(vec[370] == true); + try expect(vec[371] == false); + try expect(vec[372] == true); + try expect(vec[373] == true); + try expect(vec[374] == false); + try expect(vec[375] == false); + try expect(vec[376] == true); + try expect(vec[377] == false); + try expect(vec[378] == false); + try expect(vec[379] == true); + try expect(vec[380] == false); + try expect(vec[381] == false); + try expect(vec[382] == true); + try expect(vec[383] == false); + try expect(vec[384] == false); + try expect(vec[385] == false); + try expect(vec[386] == false); + try expect(vec[387] == true); + try expect(vec[388] == true); + try expect(vec[389] == true); + try expect(vec[390] == true); + try expect(vec[391] == true); + try expect(vec[392] == true); + try expect(vec[393] == true); + try expect(vec[394] == false); + try expect(vec[395] == true); + try expect(vec[396] == true); + try expect(vec[397] == false); + try expect(vec[398] == false); + try expect(vec[399] == false); + try expect(vec[400] == true); + try expect(vec[401] == false); + try expect(vec[402] == true); + try expect(vec[403] == true); + try expect(vec[404] == false); + try expect(vec[405] == true); + try expect(vec[406] == true); + try expect(vec[407] == true); + try expect(vec[408] == true); + try expect(vec[409] == false); + try expect(vec[410] == false); + try expect(vec[411] == false); + try expect(vec[412] == true); + try expect(vec[413] == true); + try expect(vec[414] == false); + try expect(vec[415] == true); + try expect(vec[416] == false); + try expect(vec[417] == true); + try expect(vec[418] == false); + try expect(vec[419] == false); + try expect(vec[420] == false); + try expect(vec[421] == false); + try expect(vec[422] == true); + try expect(vec[423] == true); + try expect(vec[424] == true); + try expect(vec[425] == false); + try expect(vec[426] == true); + try expect(vec[427] == false); + try expect(vec[428] == false); + try expect(vec[429] == false); + try expect(vec[430] == true); + try expect(vec[431] == true); + try expect(vec[432] == false); + try expect(vec[433] == true); + try expect(vec[434] == false); + try expect(vec[435] == false); + try expect(vec[436] == true); + try expect(vec[437] == true); + try expect(vec[438] == true); + try expect(vec[439] == true); + try expect(vec[440] == true); + try expect(vec[441] == true); + try expect(vec[442] == false); + try expect(vec[443] == false); + try expect(vec[444] == false); + try expect(vec[445] == true); + try expect(vec[446] == true); + try expect(vec[447] == true); + try expect(vec[448] == false); + try expect(vec[449] == false); + try expect(vec[450] == false); + try expect(vec[451] == false); + try expect(vec[452] == false); + try expect(vec[453] == false); + try expect(vec[454] == false); + try expect(vec[455] == false); + try expect(vec[456] == false); + try expect(vec[457] == false); + try expect(vec[458] == false); + try expect(vec[459] == true); + try expect(vec[460] == false); + try expect(vec[461] == false); + try expect(vec[462] == false); + try expect(vec[463] == true); + try expect(vec[464] == false); + try expect(vec[465] == false); + try expect(vec[466] == false); + try expect(vec[467] == false); + try expect(vec[468] == true); + try expect(vec[469] == true); + try expect(vec[470] == true); + try expect(vec[471] == true); + try expect(vec[472] == true); + try expect(vec[473] == false); + try expect(vec[474] == false); + try expect(vec[475] == true); + try expect(vec[476] == true); + try expect(vec[477] == true); + try expect(vec[478] == false); + try expect(vec[479] == true); + try expect(vec[480] == true); + try expect(vec[481] == true); + try expect(vec[482] == false); + try expect(vec[483] == true); + try expect(vec[484] == false); + try expect(vec[485] == true); + try expect(vec[486] == false); + try expect(vec[487] == true); + try expect(vec[488] == false); + try expect(vec[489] == true); + try expect(vec[490] == true); + try expect(vec[491] == true); + try expect(vec[492] == true); + try expect(vec[493] == false); + try expect(vec[494] == true); + try expect(vec[495] == true); + try expect(vec[496] == false); + try expect(vec[497] == true); + try expect(vec[498] == false); + try expect(vec[499] == false); + try expect(vec[500] == false); + try expect(vec[501] == false); + try expect(vec[502] == false); + try expect(vec[503] == false); + try expect(vec[504] == false); + try expect(vec[505] == false); + try expect(vec[506] == false); + try expect(vec[507] == true); + try expect(vec[508] == true); + try expect(vec[509] == false); + try expect(vec[510] == true); + try expect(vec[511] == false); + } +} + +comptime { + skip: { + if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .wasm32) break :skip; + if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) break :skip; + + _ = struct { + export fn zig_vector_2_bool(vec: Vector2Bool) void { + expect(vec[0] == false) catch @panic("test failure"); + expect(vec[1] == true) catch @panic("test failure"); + } + + export fn zig_vector_4_bool(vec: Vector4Bool) void { + expect(vec[0] == false) catch @panic("test failure"); + expect(vec[1] == false) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == false) catch @panic("test failure"); + } + + export fn zig_vector_8_bool(vec: Vector8Bool) void { + expect(vec[0] == true) catch @panic("test failure"); + expect(vec[1] == true) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == true) catch @panic("test failure"); + expect(vec[4] == false) catch @panic("test failure"); + expect(vec[5] == true) catch @panic("test failure"); + expect(vec[6] == true) catch @panic("test failure"); + expect(vec[7] == false) catch @panic("test failure"); + } + + export fn zig_vector_16_bool(vec: Vector16Bool) void { + expect(vec[0] == true) catch @panic("test failure"); + expect(vec[1] == false) catch @panic("test failure"); + expect(vec[2] == true) catch @panic("test failure"); + expect(vec[3] == true) catch @panic("test failure"); + expect(vec[4] == true) catch @panic("test failure"); + expect(vec[5] == false) catch @panic("test failure"); + expect(vec[6] == false) catch @panic("test failure"); + expect(vec[7] == false) catch @panic("test failure"); + expect(vec[8] == true) catch @panic("test failure"); + expect(vec[9] == true) catch @panic("test failure"); + expect(vec[10] == true) catch @panic("test failure"); + expect(vec[11] == true) catch @panic("test failure"); + expect(vec[12] == false) catch @panic("test failure"); + expect(vec[13] == false) catch @panic("test failure"); + expect(vec[14] == false) catch @panic("test failure"); + expect(vec[15] == true) catch @panic("test failure"); + } + + export fn zig_vector_32_bool(vec: Vector32Bool) void { + expect(vec[0] == false) catch @panic("test failure"); + expect(vec[1] == false) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == true) catch @panic("test failure"); + expect(vec[4] == true) catch @panic("test failure"); + expect(vec[5] == false) catch @panic("test failure"); + expect(vec[6] == false) catch @panic("test failure"); + expect(vec[7] == true) catch @panic("test failure"); + expect(vec[8] == false) catch @panic("test failure"); + expect(vec[9] == true) catch @panic("test failure"); + expect(vec[10] == true) catch @panic("test failure"); + expect(vec[11] == true) catch @panic("test failure"); + expect(vec[12] == false) catch @panic("test failure"); + expect(vec[13] == false) catch @panic("test failure"); + expect(vec[14] == true) catch @panic("test failure"); + expect(vec[15] == true) catch @panic("test failure"); + expect(vec[16] == true) catch @panic("test failure"); + expect(vec[17] == true) catch @panic("test failure"); + expect(vec[18] == true) catch @panic("test failure"); + expect(vec[19] == false) catch @panic("test failure"); + expect(vec[20] == true) catch @panic("test failure"); + expect(vec[21] == true) catch @panic("test failure"); + expect(vec[22] == true) catch @panic("test failure"); + expect(vec[23] == false) catch @panic("test failure"); + expect(vec[24] == false) catch @panic("test failure"); + expect(vec[25] == true) catch @panic("test failure"); + expect(vec[26] == true) catch @panic("test failure"); + expect(vec[27] == false) catch @panic("test failure"); + expect(vec[28] == true) catch @panic("test failure"); + expect(vec[29] == true) catch @panic("test failure"); + expect(vec[30] == false) catch @panic("test failure"); + expect(vec[31] == true) catch @panic("test failure"); + } + + export fn zig_vector_64_bool(vec: Vector64Bool) void { + expect(vec[0] == true) catch @panic("test failure"); + expect(vec[1] == true) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == true) catch @panic("test failure"); + expect(vec[4] == false) catch @panic("test failure"); + expect(vec[5] == true) catch @panic("test failure"); + expect(vec[6] == false) catch @panic("test failure"); + expect(vec[7] == false) catch @panic("test failure"); + expect(vec[8] == true) catch @panic("test failure"); + expect(vec[9] == true) catch @panic("test failure"); + expect(vec[10] == true) catch @panic("test failure"); + expect(vec[11] == true) catch @panic("test failure"); + expect(vec[12] == true) catch @panic("test failure"); + expect(vec[13] == true) catch @panic("test failure"); + expect(vec[14] == true) catch @panic("test failure"); + expect(vec[15] == false) catch @panic("test failure"); + expect(vec[16] == false) catch @panic("test failure"); + expect(vec[17] == true) catch @panic("test failure"); + expect(vec[18] == true) catch @panic("test failure"); + expect(vec[19] == false) catch @panic("test failure"); + expect(vec[20] == true) catch @panic("test failure"); + expect(vec[21] == true) catch @panic("test failure"); + expect(vec[22] == true) catch @panic("test failure"); + expect(vec[23] == true) catch @panic("test failure"); + expect(vec[24] == false) catch @panic("test failure"); + expect(vec[25] == false) catch @panic("test failure"); + expect(vec[26] == true) catch @panic("test failure"); + expect(vec[27] == false) catch @panic("test failure"); + expect(vec[28] == false) catch @panic("test failure"); + expect(vec[29] == true) catch @panic("test failure"); + expect(vec[30] == false) catch @panic("test failure"); + expect(vec[31] == true) catch @panic("test failure"); + expect(vec[32] == false) catch @panic("test failure"); + expect(vec[33] == true) catch @panic("test failure"); + expect(vec[34] == true) catch @panic("test failure"); + expect(vec[35] == false) catch @panic("test failure"); + expect(vec[36] == true) catch @panic("test failure"); + expect(vec[37] == true) catch @panic("test failure"); + expect(vec[38] == false) catch @panic("test failure"); + expect(vec[39] == false) catch @panic("test failure"); + expect(vec[40] == true) catch @panic("test failure"); + expect(vec[41] == true) catch @panic("test failure"); + expect(vec[42] == true) catch @panic("test failure"); + expect(vec[43] == true) catch @panic("test failure"); + expect(vec[44] == true) catch @panic("test failure"); + expect(vec[45] == false) catch @panic("test failure"); + expect(vec[46] == true) catch @panic("test failure"); + expect(vec[47] == false) catch @panic("test failure"); + expect(vec[48] == false) catch @panic("test failure"); + expect(vec[49] == false) catch @panic("test failure"); + expect(vec[50] == false) catch @panic("test failure"); + expect(vec[51] == false) catch @panic("test failure"); + expect(vec[52] == true) catch @panic("test failure"); + expect(vec[53] == false) catch @panic("test failure"); + expect(vec[54] == false) catch @panic("test failure"); + expect(vec[55] == true) catch @panic("test failure"); + expect(vec[56] == true) catch @panic("test failure"); + expect(vec[57] == false) catch @panic("test failure"); + expect(vec[58] == false) catch @panic("test failure"); + expect(vec[59] == false) catch @panic("test failure"); + expect(vec[60] == true) catch @panic("test failure"); + expect(vec[61] == true) catch @panic("test failure"); + expect(vec[62] == true) catch @panic("test failure"); + expect(vec[63] == true) catch @panic("test failure"); + } + + export fn zig_vector_128_bool(vec: Vector128Bool) void { + expect(vec[0] == true) catch @panic("test failure"); + expect(vec[1] == true) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == true) catch @panic("test failure"); + expect(vec[4] == true) catch @panic("test failure"); + expect(vec[5] == false) catch @panic("test failure"); + expect(vec[6] == false) catch @panic("test failure"); + expect(vec[7] == true) catch @panic("test failure"); + expect(vec[8] == true) catch @panic("test failure"); + expect(vec[9] == true) catch @panic("test failure"); + expect(vec[10] == true) catch @panic("test failure"); + expect(vec[11] == true) catch @panic("test failure"); + expect(vec[12] == false) catch @panic("test failure"); + expect(vec[13] == false) catch @panic("test failure"); + expect(vec[14] == false) catch @panic("test failure"); + expect(vec[15] == true) catch @panic("test failure"); + expect(vec[16] == false) catch @panic("test failure"); + expect(vec[17] == true) catch @panic("test failure"); + expect(vec[18] == false) catch @panic("test failure"); + expect(vec[19] == false) catch @panic("test failure"); + expect(vec[20] == true) catch @panic("test failure"); + expect(vec[21] == false) catch @panic("test failure"); + expect(vec[22] == true) catch @panic("test failure"); + expect(vec[23] == false) catch @panic("test failure"); + expect(vec[24] == false) catch @panic("test failure"); + expect(vec[25] == false) catch @panic("test failure"); + expect(vec[26] == true) catch @panic("test failure"); + expect(vec[27] == false) catch @panic("test failure"); + expect(vec[28] == true) catch @panic("test failure"); + expect(vec[29] == true) catch @panic("test failure"); + expect(vec[30] == false) catch @panic("test failure"); + expect(vec[31] == true) catch @panic("test failure"); + expect(vec[32] == false) catch @panic("test failure"); + expect(vec[33] == true) catch @panic("test failure"); + expect(vec[34] == true) catch @panic("test failure"); + expect(vec[35] == false) catch @panic("test failure"); + expect(vec[36] == false) catch @panic("test failure"); + expect(vec[37] == false) catch @panic("test failure"); + expect(vec[38] == false) catch @panic("test failure"); + expect(vec[39] == true) catch @panic("test failure"); + expect(vec[40] == true) catch @panic("test failure"); + expect(vec[41] == false) catch @panic("test failure"); + expect(vec[42] == true) catch @panic("test failure"); + expect(vec[43] == false) catch @panic("test failure"); + expect(vec[44] == false) catch @panic("test failure"); + expect(vec[45] == true) catch @panic("test failure"); + expect(vec[46] == false) catch @panic("test failure"); + expect(vec[47] == false) catch @panic("test failure"); + expect(vec[48] == true) catch @panic("test failure"); + expect(vec[49] == true) catch @panic("test failure"); + expect(vec[50] == false) catch @panic("test failure"); + expect(vec[51] == false) catch @panic("test failure"); + expect(vec[52] == true) catch @panic("test failure"); + expect(vec[53] == false) catch @panic("test failure"); + expect(vec[54] == false) catch @panic("test failure"); + expect(vec[55] == true) catch @panic("test failure"); + expect(vec[56] == true) catch @panic("test failure"); + expect(vec[57] == true) catch @panic("test failure"); + expect(vec[58] == true) catch @panic("test failure"); + expect(vec[59] == true) catch @panic("test failure"); + expect(vec[60] == true) catch @panic("test failure"); + expect(vec[61] == true) catch @panic("test failure"); + expect(vec[62] == true) catch @panic("test failure"); + expect(vec[63] == false) catch @panic("test failure"); + expect(vec[64] == false) catch @panic("test failure"); + expect(vec[65] == true) catch @panic("test failure"); + expect(vec[66] == false) catch @panic("test failure"); + expect(vec[67] == true) catch @panic("test failure"); + expect(vec[68] == true) catch @panic("test failure"); + expect(vec[69] == true) catch @panic("test failure"); + expect(vec[70] == true) catch @panic("test failure"); + expect(vec[71] == false) catch @panic("test failure"); + expect(vec[72] == false) catch @panic("test failure"); + expect(vec[73] == false) catch @panic("test failure"); + expect(vec[74] == true) catch @panic("test failure"); + expect(vec[75] == true) catch @panic("test failure"); + expect(vec[76] == false) catch @panic("test failure"); + expect(vec[77] == true) catch @panic("test failure"); + expect(vec[78] == true) catch @panic("test failure"); + expect(vec[79] == true) catch @panic("test failure"); + expect(vec[80] == true) catch @panic("test failure"); + expect(vec[81] == false) catch @panic("test failure"); + expect(vec[82] == true) catch @panic("test failure"); + expect(vec[83] == true) catch @panic("test failure"); + expect(vec[84] == true) catch @panic("test failure"); + expect(vec[85] == true) catch @panic("test failure"); + expect(vec[86] == true) catch @panic("test failure"); + expect(vec[87] == true) catch @panic("test failure"); + expect(vec[88] == false) catch @panic("test failure"); + expect(vec[89] == true) catch @panic("test failure"); + expect(vec[90] == true) catch @panic("test failure"); + expect(vec[91] == true) catch @panic("test failure"); + expect(vec[92] == true) catch @panic("test failure"); + expect(vec[93] == true) catch @panic("test failure"); + expect(vec[94] == true) catch @panic("test failure"); + expect(vec[95] == false) catch @panic("test failure"); + expect(vec[96] == false) catch @panic("test failure"); + expect(vec[97] == false) catch @panic("test failure"); + expect(vec[98] == true) catch @panic("test failure"); + expect(vec[99] == true) catch @panic("test failure"); + expect(vec[100] == true) catch @panic("test failure"); + expect(vec[101] == true) catch @panic("test failure"); + expect(vec[102] == true) catch @panic("test failure"); + expect(vec[103] == true) catch @panic("test failure"); + expect(vec[104] == true) catch @panic("test failure"); + expect(vec[105] == false) catch @panic("test failure"); + expect(vec[106] == false) catch @panic("test failure"); + expect(vec[107] == false) catch @panic("test failure"); + expect(vec[108] == false) catch @panic("test failure"); + expect(vec[109] == false) catch @panic("test failure"); + expect(vec[110] == true) catch @panic("test failure"); + expect(vec[111] == true) catch @panic("test failure"); + expect(vec[112] == true) catch @panic("test failure"); + expect(vec[113] == false) catch @panic("test failure"); + expect(vec[114] == false) catch @panic("test failure"); + expect(vec[115] == false) catch @panic("test failure"); + expect(vec[116] == false) catch @panic("test failure"); + expect(vec[117] == false) catch @panic("test failure"); + expect(vec[118] == true) catch @panic("test failure"); + expect(vec[119] == false) catch @panic("test failure"); + expect(vec[120] == false) catch @panic("test failure"); + expect(vec[121] == false) catch @panic("test failure"); + expect(vec[122] == false) catch @panic("test failure"); + expect(vec[123] == true) catch @panic("test failure"); + expect(vec[124] == true) catch @panic("test failure"); + expect(vec[125] == false) catch @panic("test failure"); + expect(vec[126] == true) catch @panic("test failure"); + expect(vec[127] == false) catch @panic("test failure"); + } + + export fn zig_vector_256_bool(vec: Vector256Bool) void { + expect(vec[0] == false) catch @panic("test failure"); + expect(vec[1] == false) catch @panic("test failure"); + expect(vec[2] == false) catch @panic("test failure"); + expect(vec[3] == false) catch @panic("test failure"); + expect(vec[4] == true) catch @panic("test failure"); + expect(vec[5] == true) catch @panic("test failure"); + expect(vec[6] == false) catch @panic("test failure"); + expect(vec[7] == false) catch @panic("test failure"); + expect(vec[8] == false) catch @panic("test failure"); + expect(vec[9] == true) catch @panic("test failure"); + expect(vec[10] == true) catch @panic("test failure"); + expect(vec[11] == false) catch @panic("test failure"); + expect(vec[12] == true) catch @panic("test failure"); + expect(vec[13] == false) catch @panic("test failure"); + expect(vec[14] == false) catch @panic("test failure"); + expect(vec[15] == false) catch @panic("test failure"); + expect(vec[16] == false) catch @panic("test failure"); + expect(vec[17] == true) catch @panic("test failure"); + expect(vec[18] == true) catch @panic("test failure"); + expect(vec[19] == true) catch @panic("test failure"); + expect(vec[20] == false) catch @panic("test failure"); + expect(vec[21] == true) catch @panic("test failure"); + expect(vec[22] == true) catch @panic("test failure"); + expect(vec[23] == false) catch @panic("test failure"); + expect(vec[24] == true) catch @panic("test failure"); + expect(vec[25] == false) catch @panic("test failure"); + expect(vec[26] == false) catch @panic("test failure"); + expect(vec[27] == true) catch @panic("test failure"); + expect(vec[28] == true) catch @panic("test failure"); + expect(vec[29] == true) catch @panic("test failure"); + expect(vec[30] == false) catch @panic("test failure"); + expect(vec[31] == true) catch @panic("test failure"); + expect(vec[32] == false) catch @panic("test failure"); + expect(vec[33] == true) catch @panic("test failure"); + expect(vec[34] == false) catch @panic("test failure"); + expect(vec[35] == false) catch @panic("test failure"); + expect(vec[36] == false) catch @panic("test failure"); + expect(vec[37] == true) catch @panic("test failure"); + expect(vec[38] == false) catch @panic("test failure"); + expect(vec[39] == false) catch @panic("test failure"); + expect(vec[40] == true) catch @panic("test failure"); + expect(vec[41] == true) catch @panic("test failure"); + expect(vec[42] == false) catch @panic("test failure"); + expect(vec[43] == true) catch @panic("test failure"); + expect(vec[44] == true) catch @panic("test failure"); + expect(vec[45] == false) catch @panic("test failure"); + expect(vec[46] == true) catch @panic("test failure"); + expect(vec[47] == false) catch @panic("test failure"); + expect(vec[48] == true) catch @panic("test failure"); + expect(vec[49] == false) catch @panic("test failure"); + expect(vec[50] == true) catch @panic("test failure"); + expect(vec[51] == false) catch @panic("test failure"); + expect(vec[52] == true) catch @panic("test failure"); + expect(vec[53] == true) catch @panic("test failure"); + expect(vec[54] == true) catch @panic("test failure"); + expect(vec[55] == false) catch @panic("test failure"); + expect(vec[56] == false) catch @panic("test failure"); + expect(vec[57] == true) catch @panic("test failure"); + expect(vec[58] == true) catch @panic("test failure"); + expect(vec[59] == false) catch @panic("test failure"); + expect(vec[60] == false) catch @panic("test failure"); + expect(vec[61] == true) catch @panic("test failure"); + expect(vec[62] == true) catch @panic("test failure"); + expect(vec[63] == false) catch @panic("test failure"); + expect(vec[64] == false) catch @panic("test failure"); + expect(vec[65] == false) catch @panic("test failure"); + expect(vec[66] == true) catch @panic("test failure"); + expect(vec[67] == true) catch @panic("test failure"); + expect(vec[68] == false) catch @panic("test failure"); + expect(vec[69] == true) catch @panic("test failure"); + expect(vec[70] == false) catch @panic("test failure"); + expect(vec[71] == true) catch @panic("test failure"); + expect(vec[72] == false) catch @panic("test failure"); + expect(vec[73] == true) catch @panic("test failure"); + expect(vec[74] == false) catch @panic("test failure"); + expect(vec[75] == false) catch @panic("test failure"); + expect(vec[76] == true) catch @panic("test failure"); + expect(vec[77] == false) catch @panic("test failure"); + expect(vec[78] == false) catch @panic("test failure"); + expect(vec[79] == false) catch @panic("test failure"); + expect(vec[80] == false) catch @panic("test failure"); + expect(vec[81] == false) catch @panic("test failure"); + expect(vec[82] == true) catch @panic("test failure"); + expect(vec[83] == false) catch @panic("test failure"); + expect(vec[84] == false) catch @panic("test failure"); + expect(vec[85] == false) catch @panic("test failure"); + expect(vec[86] == true) catch @panic("test failure"); + expect(vec[87] == true) catch @panic("test failure"); + expect(vec[88] == true) catch @panic("test failure"); + expect(vec[89] == false) catch @panic("test failure"); + expect(vec[90] == true) catch @panic("test failure"); + expect(vec[91] == false) catch @panic("test failure"); + expect(vec[92] == true) catch @panic("test failure"); + expect(vec[93] == false) catch @panic("test failure"); + expect(vec[94] == true) catch @panic("test failure"); + expect(vec[95] == true) catch @panic("test failure"); + expect(vec[96] == true) catch @panic("test failure"); + expect(vec[97] == true) catch @panic("test failure"); + expect(vec[98] == false) catch @panic("test failure"); + expect(vec[99] == true) catch @panic("test failure"); + expect(vec[100] == false) catch @panic("test failure"); + expect(vec[101] == true) catch @panic("test failure"); + expect(vec[102] == true) catch @panic("test failure"); + expect(vec[103] == false) catch @panic("test failure"); + expect(vec[104] == false) catch @panic("test failure"); + expect(vec[105] == true) catch @panic("test failure"); + expect(vec[106] == false) catch @panic("test failure"); + expect(vec[107] == true) catch @panic("test failure"); + expect(vec[108] == false) catch @panic("test failure"); + expect(vec[109] == false) catch @panic("test failure"); + expect(vec[110] == false) catch @panic("test failure"); + expect(vec[111] == false) catch @panic("test failure"); + expect(vec[112] == false) catch @panic("test failure"); + expect(vec[113] == false) catch @panic("test failure"); + expect(vec[114] == false) catch @panic("test failure"); + expect(vec[115] == false) catch @panic("test failure"); + expect(vec[116] == false) catch @panic("test failure"); + expect(vec[117] == false) catch @panic("test failure"); + expect(vec[118] == false) catch @panic("test failure"); + expect(vec[119] == false) catch @panic("test failure"); + expect(vec[120] == false) catch @panic("test failure"); + expect(vec[121] == false) catch @panic("test failure"); + expect(vec[122] == true) catch @panic("test failure"); + expect(vec[123] == true) catch @panic("test failure"); + expect(vec[124] == false) catch @panic("test failure"); + expect(vec[125] == false) catch @panic("test failure"); + expect(vec[126] == false) catch @panic("test failure"); + expect(vec[127] == true) catch @panic("test failure"); + expect(vec[128] == true) catch @panic("test failure"); + expect(vec[129] == true) catch @panic("test failure"); + expect(vec[130] == true) catch @panic("test failure"); + expect(vec[131] == false) catch @panic("test failure"); + expect(vec[132] == false) catch @panic("test failure"); + expect(vec[133] == false) catch @panic("test failure"); + expect(vec[134] == true) catch @panic("test failure"); + expect(vec[135] == true) catch @panic("test failure"); + expect(vec[136] == false) catch @panic("test failure"); + expect(vec[137] == false) catch @panic("test failure"); + expect(vec[138] == true) catch @panic("test failure"); + expect(vec[139] == true) catch @panic("test failure"); + expect(vec[140] == true) catch @panic("test failure"); + expect(vec[141] == true) catch @panic("test failure"); + expect(vec[142] == true) catch @panic("test failure"); + expect(vec[143] == false) catch @panic("test failure"); + expect(vec[144] == true) catch @panic("test failure"); + expect(vec[145] == true) catch @panic("test failure"); + expect(vec[146] == true) catch @panic("test failure"); + expect(vec[147] == false) catch @panic("test failure"); + expect(vec[148] == false) catch @panic("test failure"); + expect(vec[149] == false) catch @panic("test failure"); + expect(vec[150] == false) catch @panic("test failure"); + expect(vec[151] == false) catch @panic("test failure"); + expect(vec[152] == false) catch @panic("test failure"); + expect(vec[153] == false) catch @panic("test failure"); + expect(vec[154] == true) catch @panic("test failure"); + expect(vec[155] == false) catch @panic("test failure"); + expect(vec[156] == false) catch @panic("test failure"); + expect(vec[157] == false) catch @panic("test failure"); + expect(vec[158] == true) catch @panic("test failure"); + expect(vec[159] == true) catch @panic("test failure"); + expect(vec[160] == false) catch @panic("test failure"); + expect(vec[161] == true) catch @panic("test failure"); + expect(vec[162] == false) catch @panic("test failure"); + expect(vec[163] == false) catch @panic("test failure"); + expect(vec[164] == false) catch @panic("test failure"); + expect(vec[165] == true) catch @panic("test failure"); + expect(vec[166] == false) catch @panic("test failure"); + expect(vec[167] == true) catch @panic("test failure"); + expect(vec[168] == false) catch @panic("test failure"); + expect(vec[169] == false) catch @panic("test failure"); + expect(vec[170] == false) catch @panic("test failure"); + expect(vec[171] == false) catch @panic("test failure"); + expect(vec[172] == true) catch @panic("test failure"); + expect(vec[173] == true) catch @panic("test failure"); + expect(vec[174] == true) catch @panic("test failure"); + expect(vec[175] == true) catch @panic("test failure"); + expect(vec[176] == true) catch @panic("test failure"); + expect(vec[177] == true) catch @panic("test failure"); + expect(vec[178] == false) catch @panic("test failure"); + expect(vec[179] == true) catch @panic("test failure"); + expect(vec[180] == true) catch @panic("test failure"); + expect(vec[181] == false) catch @panic("test failure"); + expect(vec[182] == true) catch @panic("test failure"); + expect(vec[183] == false) catch @panic("test failure"); + expect(vec[184] == true) catch @panic("test failure"); + expect(vec[185] == false) catch @panic("test failure"); + expect(vec[186] == true) catch @panic("test failure"); + expect(vec[187] == false) catch @panic("test failure"); + expect(vec[188] == true) catch @panic("test failure"); + expect(vec[189] == false) catch @panic("test failure"); + expect(vec[190] == false) catch @panic("test failure"); + expect(vec[191] == false) catch @panic("test failure"); + expect(vec[192] == false) catch @panic("test failure"); + expect(vec[193] == true) catch @panic("test failure"); + expect(vec[194] == true) catch @panic("test failure"); + expect(vec[195] == true) catch @panic("test failure"); + expect(vec[196] == false) catch @panic("test failure"); + expect(vec[197] == false) catch @panic("test failure"); + expect(vec[198] == true) catch @panic("test failure"); + expect(vec[199] == false) catch @panic("test failure"); + expect(vec[200] == false) catch @panic("test failure"); + expect(vec[201] == true) catch @panic("test failure"); + expect(vec[202] == true) catch @panic("test failure"); + expect(vec[203] == false) catch @panic("test failure"); + expect(vec[204] == true) catch @panic("test failure"); + expect(vec[205] == false) catch @panic("test failure"); + expect(vec[206] == true) catch @panic("test failure"); + expect(vec[207] == false) catch @panic("test failure"); + expect(vec[208] == false) catch @panic("test failure"); + expect(vec[209] == false) catch @panic("test failure"); + expect(vec[210] == true) catch @panic("test failure"); + expect(vec[211] == true) catch @panic("test failure"); + expect(vec[212] == false) catch @panic("test failure"); + expect(vec[213] == false) catch @panic("test failure"); + expect(vec[214] == false) catch @panic("test failure"); + expect(vec[215] == true) catch @panic("test failure"); + expect(vec[216] == false) catch @panic("test failure"); + expect(vec[217] == true) catch @panic("test failure"); + expect(vec[218] == true) catch @panic("test failure"); + expect(vec[219] == true) catch @panic("test failure"); + expect(vec[220] == false) catch @panic("test failure"); + expect(vec[221] == true) catch @panic("test failure"); + expect(vec[222] == false) catch @panic("test failure"); + expect(vec[223] == true) catch @panic("test failure"); + expect(vec[224] == false) catch @panic("test failure"); + expect(vec[225] == false) catch @panic("test failure"); + expect(vec[226] == false) catch @panic("test failure"); + expect(vec[227] == true) catch @panic("test failure"); + expect(vec[228] == true) catch @panic("test failure"); + expect(vec[229] == false) catch @panic("test failure"); + expect(vec[230] == false) catch @panic("test failure"); + expect(vec[231] == false) catch @panic("test failure"); + expect(vec[232] == false) catch @panic("test failure"); + expect(vec[233] == false) catch @panic("test failure"); + expect(vec[234] == true) catch @panic("test failure"); + expect(vec[235] == false) catch @panic("test failure"); + expect(vec[236] == false) catch @panic("test failure"); + expect(vec[237] == false) catch @panic("test failure"); + expect(vec[238] == true) catch @panic("test failure"); + expect(vec[239] == false) catch @panic("test failure"); + expect(vec[240] == true) catch @panic("test failure"); + expect(vec[241] == true) catch @panic("test failure"); + expect(vec[242] == true) catch @panic("test failure"); + expect(vec[243] == false) catch @panic("test failure"); + expect(vec[244] == false) catch @panic("test failure"); + expect(vec[245] == true) catch @panic("test failure"); + expect(vec[246] == false) catch @panic("test failure"); + expect(vec[247] == false) catch @panic("test failure"); + expect(vec[248] == false) catch @panic("test failure"); + expect(vec[249] == true) catch @panic("test failure"); + expect(vec[250] == false) catch @panic("test failure"); + expect(vec[251] == false) catch @panic("test failure"); + expect(vec[252] == true) catch @panic("test failure"); + expect(vec[253] == true) catch @panic("test failure"); + expect(vec[254] == true) catch @panic("test failure"); + expect(vec[255] == true) catch @panic("test failure"); + } + + export fn zig_vector_512_bool(vec: Vector512Bool) void { + expect(vec[0] == false) catch @panic("test failure"); + expect(vec[1] == true) catch @panic("test failure"); + expect(vec[2] == true) catch @panic("test failure"); + expect(vec[3] == false) catch @panic("test failure"); + expect(vec[4] == true) catch @panic("test failure"); + expect(vec[5] == false) catch @panic("test failure"); + expect(vec[6] == true) catch @panic("test failure"); + expect(vec[7] == false) catch @panic("test failure"); + expect(vec[8] == false) catch @panic("test failure"); + expect(vec[9] == false) catch @panic("test failure"); + expect(vec[10] == false) catch @panic("test failure"); + expect(vec[11] == false) catch @panic("test failure"); + expect(vec[12] == true) catch @panic("test failure"); + expect(vec[13] == false) catch @panic("test failure"); + expect(vec[14] == true) catch @panic("test failure"); + expect(vec[15] == false) catch @panic("test failure"); + expect(vec[16] == false) catch @panic("test failure"); + expect(vec[17] == false) catch @panic("test failure"); + expect(vec[18] == true) catch @panic("test failure"); + expect(vec[19] == true) catch @panic("test failure"); + expect(vec[20] == true) catch @panic("test failure"); + expect(vec[21] == true) catch @panic("test failure"); + expect(vec[22] == false) catch @panic("test failure"); + expect(vec[23] == false) catch @panic("test failure"); + expect(vec[24] == false) catch @panic("test failure"); + expect(vec[25] == true) catch @panic("test failure"); + expect(vec[26] == true) catch @panic("test failure"); + expect(vec[27] == false) catch @panic("test failure"); + expect(vec[28] == true) catch @panic("test failure"); + expect(vec[29] == true) catch @panic("test failure"); + expect(vec[30] == false) catch @panic("test failure"); + expect(vec[31] == false) catch @panic("test failure"); + expect(vec[32] == true) catch @panic("test failure"); + expect(vec[33] == true) catch @panic("test failure"); + expect(vec[34] == false) catch @panic("test failure"); + expect(vec[35] == false) catch @panic("test failure"); + expect(vec[36] == false) catch @panic("test failure"); + expect(vec[37] == false) catch @panic("test failure"); + expect(vec[38] == false) catch @panic("test failure"); + expect(vec[39] == false) catch @panic("test failure"); + expect(vec[40] == false) catch @panic("test failure"); + expect(vec[41] == true) catch @panic("test failure"); + expect(vec[42] == true) catch @panic("test failure"); + expect(vec[43] == true) catch @panic("test failure"); + expect(vec[44] == false) catch @panic("test failure"); + expect(vec[45] == true) catch @panic("test failure"); + expect(vec[46] == true) catch @panic("test failure"); + expect(vec[47] == true) catch @panic("test failure"); + expect(vec[48] == true) catch @panic("test failure"); + expect(vec[49] == true) catch @panic("test failure"); + expect(vec[50] == false) catch @panic("test failure"); + expect(vec[51] == true) catch @panic("test failure"); + expect(vec[52] == true) catch @panic("test failure"); + expect(vec[53] == true) catch @panic("test failure"); + expect(vec[54] == false) catch @panic("test failure"); + expect(vec[55] == true) catch @panic("test failure"); + expect(vec[56] == false) catch @panic("test failure"); + expect(vec[57] == false) catch @panic("test failure"); + expect(vec[58] == true) catch @panic("test failure"); + expect(vec[59] == false) catch @panic("test failure"); + expect(vec[60] == true) catch @panic("test failure"); + expect(vec[61] == true) catch @panic("test failure"); + expect(vec[62] == false) catch @panic("test failure"); + expect(vec[63] == false) catch @panic("test failure"); + expect(vec[64] == false) catch @panic("test failure"); + expect(vec[65] == true) catch @panic("test failure"); + expect(vec[66] == true) catch @panic("test failure"); + expect(vec[67] == true) catch @panic("test failure"); + expect(vec[68] == true) catch @panic("test failure"); + expect(vec[69] == false) catch @panic("test failure"); + expect(vec[70] == false) catch @panic("test failure"); + expect(vec[71] == true) catch @panic("test failure"); + expect(vec[72] == true) catch @panic("test failure"); + expect(vec[73] == false) catch @panic("test failure"); + expect(vec[74] == true) catch @panic("test failure"); + expect(vec[75] == true) catch @panic("test failure"); + expect(vec[76] == false) catch @panic("test failure"); + expect(vec[77] == false) catch @panic("test failure"); + expect(vec[78] == true) catch @panic("test failure"); + expect(vec[79] == false) catch @panic("test failure"); + expect(vec[80] == false) catch @panic("test failure"); + expect(vec[81] == false) catch @panic("test failure"); + expect(vec[82] == true) catch @panic("test failure"); + expect(vec[83] == true) catch @panic("test failure"); + expect(vec[84] == true) catch @panic("test failure"); + expect(vec[85] == false) catch @panic("test failure"); + expect(vec[86] == false) catch @panic("test failure"); + expect(vec[87] == true) catch @panic("test failure"); + expect(vec[88] == false) catch @panic("test failure"); + expect(vec[89] == true) catch @panic("test failure"); + expect(vec[90] == false) catch @panic("test failure"); + expect(vec[91] == false) catch @panic("test failure"); + expect(vec[92] == true) catch @panic("test failure"); + expect(vec[93] == false) catch @panic("test failure"); + expect(vec[94] == false) catch @panic("test failure"); + expect(vec[95] == true) catch @panic("test failure"); + expect(vec[96] == true) catch @panic("test failure"); + expect(vec[97] == false) catch @panic("test failure"); + expect(vec[98] == false) catch @panic("test failure"); + expect(vec[99] == false) catch @panic("test failure"); + expect(vec[100] == false) catch @panic("test failure"); + expect(vec[101] == true) catch @panic("test failure"); + expect(vec[102] == false) catch @panic("test failure"); + expect(vec[103] == false) catch @panic("test failure"); + expect(vec[104] == false) catch @panic("test failure"); + expect(vec[105] == false) catch @panic("test failure"); + expect(vec[106] == false) catch @panic("test failure"); + expect(vec[107] == false) catch @panic("test failure"); + expect(vec[108] == true) catch @panic("test failure"); + expect(vec[109] == true) catch @panic("test failure"); + expect(vec[110] == true) catch @panic("test failure"); + expect(vec[111] == true) catch @panic("test failure"); + expect(vec[112] == true) catch @panic("test failure"); + expect(vec[113] == false) catch @panic("test failure"); + expect(vec[114] == false) catch @panic("test failure"); + expect(vec[115] == false) catch @panic("test failure"); + expect(vec[116] == false) catch @panic("test failure"); + expect(vec[117] == true) catch @panic("test failure"); + expect(vec[118] == true) catch @panic("test failure"); + expect(vec[119] == false) catch @panic("test failure"); + expect(vec[120] == true) catch @panic("test failure"); + expect(vec[121] == true) catch @panic("test failure"); + expect(vec[122] == false) catch @panic("test failure"); + expect(vec[123] == false) catch @panic("test failure"); + expect(vec[124] == true) catch @panic("test failure"); + expect(vec[125] == false) catch @panic("test failure"); + expect(vec[126] == false) catch @panic("test failure"); + expect(vec[127] == false) catch @panic("test failure"); + expect(vec[128] == false) catch @panic("test failure"); + expect(vec[129] == true) catch @panic("test failure"); + expect(vec[130] == true) catch @panic("test failure"); + expect(vec[131] == true) catch @panic("test failure"); + expect(vec[132] == true) catch @panic("test failure"); + expect(vec[133] == false) catch @panic("test failure"); + expect(vec[134] == false) catch @panic("test failure"); + expect(vec[135] == false) catch @panic("test failure"); + expect(vec[136] == false) catch @panic("test failure"); + expect(vec[137] == true) catch @panic("test failure"); + expect(vec[138] == false) catch @panic("test failure"); + expect(vec[139] == false) catch @panic("test failure"); + expect(vec[140] == false) catch @panic("test failure"); + expect(vec[141] == false) catch @panic("test failure"); + expect(vec[142] == true) catch @panic("test failure"); + expect(vec[143] == true) catch @panic("test failure"); + expect(vec[144] == false) catch @panic("test failure"); + expect(vec[145] == true) catch @panic("test failure"); + expect(vec[146] == false) catch @panic("test failure"); + expect(vec[147] == true) catch @panic("test failure"); + expect(vec[148] == false) catch @panic("test failure"); + expect(vec[149] == false) catch @panic("test failure"); + expect(vec[150] == true) catch @panic("test failure"); + expect(vec[151] == true) catch @panic("test failure"); + expect(vec[152] == false) catch @panic("test failure"); + expect(vec[153] == true) catch @panic("test failure"); + expect(vec[154] == true) catch @panic("test failure"); + expect(vec[155] == false) catch @panic("test failure"); + expect(vec[156] == false) catch @panic("test failure"); + expect(vec[157] == false) catch @panic("test failure"); + expect(vec[158] == true) catch @panic("test failure"); + expect(vec[159] == false) catch @panic("test failure"); + expect(vec[160] == false) catch @panic("test failure"); + expect(vec[161] == false) catch @panic("test failure"); + expect(vec[162] == false) catch @panic("test failure"); + expect(vec[163] == true) catch @panic("test failure"); + expect(vec[164] == true) catch @panic("test failure"); + expect(vec[165] == false) catch @panic("test failure"); + expect(vec[166] == false) catch @panic("test failure"); + expect(vec[167] == true) catch @panic("test failure"); + expect(vec[168] == false) catch @panic("test failure"); + expect(vec[169] == true) catch @panic("test failure"); + expect(vec[170] == true) catch @panic("test failure"); + expect(vec[171] == false) catch @panic("test failure"); + expect(vec[172] == false) catch @panic("test failure"); + expect(vec[173] == false) catch @panic("test failure"); + expect(vec[174] == false) catch @panic("test failure"); + expect(vec[175] == false) catch @panic("test failure"); + expect(vec[176] == false) catch @panic("test failure"); + expect(vec[177] == true) catch @panic("test failure"); + expect(vec[178] == false) catch @panic("test failure"); + expect(vec[179] == false) catch @panic("test failure"); + expect(vec[180] == false) catch @panic("test failure"); + expect(vec[181] == false) catch @panic("test failure"); + expect(vec[182] == false) catch @panic("test failure"); + expect(vec[183] == false) catch @panic("test failure"); + expect(vec[184] == true) catch @panic("test failure"); + expect(vec[185] == false) catch @panic("test failure"); + expect(vec[186] == false) catch @panic("test failure"); + expect(vec[187] == false) catch @panic("test failure"); + expect(vec[188] == false) catch @panic("test failure"); + expect(vec[189] == true) catch @panic("test failure"); + expect(vec[190] == false) catch @panic("test failure"); + expect(vec[191] == false) catch @panic("test failure"); + expect(vec[192] == false) catch @panic("test failure"); + expect(vec[193] == false) catch @panic("test failure"); + expect(vec[194] == false) catch @panic("test failure"); + expect(vec[195] == false) catch @panic("test failure"); + expect(vec[196] == true) catch @panic("test failure"); + expect(vec[197] == true) catch @panic("test failure"); + expect(vec[198] == true) catch @panic("test failure"); + expect(vec[199] == false) catch @panic("test failure"); + expect(vec[200] == true) catch @panic("test failure"); + expect(vec[201] == true) catch @panic("test failure"); + expect(vec[202] == false) catch @panic("test failure"); + expect(vec[203] == false) catch @panic("test failure"); + expect(vec[204] == false) catch @panic("test failure"); + expect(vec[205] == false) catch @panic("test failure"); + expect(vec[206] == false) catch @panic("test failure"); + expect(vec[207] == true) catch @panic("test failure"); + expect(vec[208] == true) catch @panic("test failure"); + expect(vec[209] == false) catch @panic("test failure"); + expect(vec[210] == false) catch @panic("test failure"); + expect(vec[211] == false) catch @panic("test failure"); + expect(vec[212] == true) catch @panic("test failure"); + expect(vec[213] == false) catch @panic("test failure"); + expect(vec[214] == false) catch @panic("test failure"); + expect(vec[215] == true) catch @panic("test failure"); + expect(vec[216] == true) catch @panic("test failure"); + expect(vec[217] == true) catch @panic("test failure"); + expect(vec[218] == false) catch @panic("test failure"); + expect(vec[219] == false) catch @panic("test failure"); + expect(vec[220] == true) catch @panic("test failure"); + expect(vec[221] == false) catch @panic("test failure"); + expect(vec[222] == true) catch @panic("test failure"); + expect(vec[223] == true) catch @panic("test failure"); + expect(vec[224] == true) catch @panic("test failure"); + expect(vec[225] == true) catch @panic("test failure"); + expect(vec[226] == false) catch @panic("test failure"); + expect(vec[227] == true) catch @panic("test failure"); + expect(vec[228] == false) catch @panic("test failure"); + expect(vec[229] == false) catch @panic("test failure"); + expect(vec[230] == false) catch @panic("test failure"); + expect(vec[231] == true) catch @panic("test failure"); + expect(vec[232] == false) catch @panic("test failure"); + expect(vec[233] == false) catch @panic("test failure"); + expect(vec[234] == false) catch @panic("test failure"); + expect(vec[235] == false) catch @panic("test failure"); + expect(vec[236] == false) catch @panic("test failure"); + expect(vec[237] == false) catch @panic("test failure"); + expect(vec[238] == false) catch @panic("test failure"); + expect(vec[239] == true) catch @panic("test failure"); + expect(vec[240] == false) catch @panic("test failure"); + expect(vec[241] == false) catch @panic("test failure"); + expect(vec[242] == false) catch @panic("test failure"); + expect(vec[243] == true) catch @panic("test failure"); + expect(vec[244] == true) catch @panic("test failure"); + expect(vec[245] == true) catch @panic("test failure"); + expect(vec[246] == true) catch @panic("test failure"); + expect(vec[247] == false) catch @panic("test failure"); + expect(vec[248] == true) catch @panic("test failure"); + expect(vec[249] == true) catch @panic("test failure"); + expect(vec[250] == false) catch @panic("test failure"); + expect(vec[251] == false) catch @panic("test failure"); + expect(vec[252] == false) catch @panic("test failure"); + expect(vec[253] == true) catch @panic("test failure"); + expect(vec[254] == false) catch @panic("test failure"); + expect(vec[255] == false) catch @panic("test failure"); + expect(vec[256] == true) catch @panic("test failure"); + expect(vec[257] == true) catch @panic("test failure"); + expect(vec[258] == false) catch @panic("test failure"); + expect(vec[259] == true) catch @panic("test failure"); + expect(vec[260] == false) catch @panic("test failure"); + expect(vec[261] == true) catch @panic("test failure"); + expect(vec[262] == true) catch @panic("test failure"); + expect(vec[263] == false) catch @panic("test failure"); + expect(vec[264] == false) catch @panic("test failure"); + expect(vec[265] == false) catch @panic("test failure"); + expect(vec[266] == false) catch @panic("test failure"); + expect(vec[267] == true) catch @panic("test failure"); + expect(vec[268] == false) catch @panic("test failure"); + expect(vec[269] == true) catch @panic("test failure"); + expect(vec[270] == true) catch @panic("test failure"); + expect(vec[271] == false) catch @panic("test failure"); + expect(vec[272] == false) catch @panic("test failure"); + expect(vec[273] == true) catch @panic("test failure"); + expect(vec[274] == true) catch @panic("test failure"); + expect(vec[275] == true) catch @panic("test failure"); + expect(vec[276] == false) catch @panic("test failure"); + expect(vec[277] == true) catch @panic("test failure"); + expect(vec[278] == false) catch @panic("test failure"); + expect(vec[279] == false) catch @panic("test failure"); + expect(vec[280] == true) catch @panic("test failure"); + expect(vec[281] == true) catch @panic("test failure"); + expect(vec[282] == false) catch @panic("test failure"); + expect(vec[283] == true) catch @panic("test failure"); + expect(vec[284] == false) catch @panic("test failure"); + expect(vec[285] == true) catch @panic("test failure"); + expect(vec[286] == true) catch @panic("test failure"); + expect(vec[287] == true) catch @panic("test failure"); + expect(vec[288] == true) catch @panic("test failure"); + expect(vec[289] == true) catch @panic("test failure"); + expect(vec[290] == true) catch @panic("test failure"); + expect(vec[291] == true) catch @panic("test failure"); + expect(vec[292] == true) catch @panic("test failure"); + expect(vec[293] == true) catch @panic("test failure"); + expect(vec[294] == true) catch @panic("test failure"); + expect(vec[295] == false) catch @panic("test failure"); + expect(vec[296] == true) catch @panic("test failure"); + expect(vec[297] == false) catch @panic("test failure"); + expect(vec[298] == true) catch @panic("test failure"); + expect(vec[299] == false) catch @panic("test failure"); + expect(vec[300] == true) catch @panic("test failure"); + expect(vec[301] == true) catch @panic("test failure"); + expect(vec[302] == false) catch @panic("test failure"); + expect(vec[303] == true) catch @panic("test failure"); + expect(vec[304] == false) catch @panic("test failure"); + expect(vec[305] == true) catch @panic("test failure"); + expect(vec[306] == false) catch @panic("test failure"); + expect(vec[307] == true) catch @panic("test failure"); + expect(vec[308] == true) catch @panic("test failure"); + expect(vec[309] == false) catch @panic("test failure"); + expect(vec[310] == true) catch @panic("test failure"); + expect(vec[311] == true) catch @panic("test failure"); + expect(vec[312] == true) catch @panic("test failure"); + expect(vec[313] == false) catch @panic("test failure"); + expect(vec[314] == false) catch @panic("test failure"); + expect(vec[315] == false) catch @panic("test failure"); + expect(vec[316] == false) catch @panic("test failure"); + expect(vec[317] == true) catch @panic("test failure"); + expect(vec[318] == true) catch @panic("test failure"); + expect(vec[319] == true) catch @panic("test failure"); + expect(vec[320] == true) catch @panic("test failure"); + expect(vec[321] == true) catch @panic("test failure"); + expect(vec[322] == true) catch @panic("test failure"); + expect(vec[323] == true) catch @panic("test failure"); + expect(vec[324] == true) catch @panic("test failure"); + expect(vec[325] == true) catch @panic("test failure"); + expect(vec[326] == false) catch @panic("test failure"); + expect(vec[327] == true) catch @panic("test failure"); + expect(vec[328] == false) catch @panic("test failure"); + expect(vec[329] == false) catch @panic("test failure"); + expect(vec[330] == true) catch @panic("test failure"); + expect(vec[331] == false) catch @panic("test failure"); + expect(vec[332] == false) catch @panic("test failure"); + expect(vec[333] == false) catch @panic("test failure"); + expect(vec[334] == false) catch @panic("test failure"); + expect(vec[335] == false) catch @panic("test failure"); + expect(vec[336] == false) catch @panic("test failure"); + expect(vec[337] == false) catch @panic("test failure"); + expect(vec[338] == false) catch @panic("test failure"); + expect(vec[339] == false) catch @panic("test failure"); + expect(vec[340] == false) catch @panic("test failure"); + expect(vec[341] == false) catch @panic("test failure"); + expect(vec[342] == true) catch @panic("test failure"); + expect(vec[343] == true) catch @panic("test failure"); + expect(vec[344] == false) catch @panic("test failure"); + expect(vec[345] == false) catch @panic("test failure"); + expect(vec[346] == false) catch @panic("test failure"); + expect(vec[347] == false) catch @panic("test failure"); + expect(vec[348] == false) catch @panic("test failure"); + expect(vec[349] == true) catch @panic("test failure"); + expect(vec[350] == true) catch @panic("test failure"); + expect(vec[351] == true) catch @panic("test failure"); + expect(vec[352] == true) catch @panic("test failure"); + expect(vec[353] == false) catch @panic("test failure"); + expect(vec[354] == false) catch @panic("test failure"); + expect(vec[355] == false) catch @panic("test failure"); + expect(vec[356] == false) catch @panic("test failure"); + expect(vec[357] == true) catch @panic("test failure"); + expect(vec[358] == true) catch @panic("test failure"); + expect(vec[359] == false) catch @panic("test failure"); + expect(vec[360] == false) catch @panic("test failure"); + expect(vec[361] == false) catch @panic("test failure"); + expect(vec[362] == true) catch @panic("test failure"); + expect(vec[363] == true) catch @panic("test failure"); + expect(vec[364] == false) catch @panic("test failure"); + expect(vec[365] == false) catch @panic("test failure"); + expect(vec[366] == false) catch @panic("test failure"); + expect(vec[367] == false) catch @panic("test failure"); + expect(vec[368] == false) catch @panic("test failure"); + expect(vec[369] == true) catch @panic("test failure"); + expect(vec[370] == true) catch @panic("test failure"); + expect(vec[371] == false) catch @panic("test failure"); + expect(vec[372] == true) catch @panic("test failure"); + expect(vec[373] == true) catch @panic("test failure"); + expect(vec[374] == false) catch @panic("test failure"); + expect(vec[375] == true) catch @panic("test failure"); + expect(vec[376] == true) catch @panic("test failure"); + expect(vec[377] == false) catch @panic("test failure"); + expect(vec[378] == true) catch @panic("test failure"); + expect(vec[379] == true) catch @panic("test failure"); + expect(vec[380] == false) catch @panic("test failure"); + expect(vec[381] == true) catch @panic("test failure"); + expect(vec[382] == true) catch @panic("test failure"); + expect(vec[383] == false) catch @panic("test failure"); + expect(vec[384] == true) catch @panic("test failure"); + expect(vec[385] == false) catch @panic("test failure"); + expect(vec[386] == true) catch @panic("test failure"); + expect(vec[387] == true) catch @panic("test failure"); + expect(vec[388] == true) catch @panic("test failure"); + expect(vec[389] == true) catch @panic("test failure"); + expect(vec[390] == false) catch @panic("test failure"); + expect(vec[391] == false) catch @panic("test failure"); + expect(vec[392] == false) catch @panic("test failure"); + expect(vec[393] == true) catch @panic("test failure"); + expect(vec[394] == true) catch @panic("test failure"); + expect(vec[395] == true) catch @panic("test failure"); + expect(vec[396] == true) catch @panic("test failure"); + expect(vec[397] == false) catch @panic("test failure"); + expect(vec[398] == true) catch @panic("test failure"); + expect(vec[399] == true) catch @panic("test failure"); + expect(vec[400] == true) catch @panic("test failure"); + expect(vec[401] == false) catch @panic("test failure"); + expect(vec[402] == false) catch @panic("test failure"); + expect(vec[403] == true) catch @panic("test failure"); + expect(vec[404] == false) catch @panic("test failure"); + expect(vec[405] == false) catch @panic("test failure"); + expect(vec[406] == false) catch @panic("test failure"); + expect(vec[407] == true) catch @panic("test failure"); + expect(vec[408] == true) catch @panic("test failure"); + expect(vec[409] == true) catch @panic("test failure"); + expect(vec[410] == false) catch @panic("test failure"); + expect(vec[411] == true) catch @panic("test failure"); + expect(vec[412] == false) catch @panic("test failure"); + expect(vec[413] == false) catch @panic("test failure"); + expect(vec[414] == false) catch @panic("test failure"); + expect(vec[415] == true) catch @panic("test failure"); + expect(vec[416] == false) catch @panic("test failure"); + expect(vec[417] == false) catch @panic("test failure"); + expect(vec[418] == true) catch @panic("test failure"); + expect(vec[419] == true) catch @panic("test failure"); + expect(vec[420] == true) catch @panic("test failure"); + expect(vec[421] == true) catch @panic("test failure"); + expect(vec[422] == false) catch @panic("test failure"); + expect(vec[423] == true) catch @panic("test failure"); + expect(vec[424] == true) catch @panic("test failure"); + expect(vec[425] == false) catch @panic("test failure"); + expect(vec[426] == false) catch @panic("test failure"); + expect(vec[427] == false) catch @panic("test failure"); + expect(vec[428] == true) catch @panic("test failure"); + expect(vec[429] == false) catch @panic("test failure"); + expect(vec[430] == true) catch @panic("test failure"); + expect(vec[431] == true) catch @panic("test failure"); + expect(vec[432] == false) catch @panic("test failure"); + expect(vec[433] == false) catch @panic("test failure"); + expect(vec[434] == false) catch @panic("test failure"); + expect(vec[435] == false) catch @panic("test failure"); + expect(vec[436] == true) catch @panic("test failure"); + expect(vec[437] == false) catch @panic("test failure"); + expect(vec[438] == true) catch @panic("test failure"); + expect(vec[439] == false) catch @panic("test failure"); + expect(vec[440] == false) catch @panic("test failure"); + expect(vec[441] == false) catch @panic("test failure"); + expect(vec[442] == false) catch @panic("test failure"); + expect(vec[443] == true) catch @panic("test failure"); + expect(vec[444] == false) catch @panic("test failure"); + expect(vec[445] == false) catch @panic("test failure"); + expect(vec[446] == true) catch @panic("test failure"); + expect(vec[447] == true) catch @panic("test failure"); + expect(vec[448] == true) catch @panic("test failure"); + expect(vec[449] == false) catch @panic("test failure"); + expect(vec[450] == true) catch @panic("test failure"); + expect(vec[451] == true) catch @panic("test failure"); + expect(vec[452] == false) catch @panic("test failure"); + expect(vec[453] == true) catch @panic("test failure"); + expect(vec[454] == false) catch @panic("test failure"); + expect(vec[455] == true) catch @panic("test failure"); + expect(vec[456] == false) catch @panic("test failure"); + expect(vec[457] == false) catch @panic("test failure"); + expect(vec[458] == false) catch @panic("test failure"); + expect(vec[459] == true) catch @panic("test failure"); + expect(vec[460] == false) catch @panic("test failure"); + expect(vec[461] == false) catch @panic("test failure"); + expect(vec[462] == false) catch @panic("test failure"); + expect(vec[463] == true) catch @panic("test failure"); + expect(vec[464] == true) catch @panic("test failure"); + expect(vec[465] == true) catch @panic("test failure"); + expect(vec[466] == true) catch @panic("test failure"); + expect(vec[467] == true) catch @panic("test failure"); + expect(vec[468] == false) catch @panic("test failure"); + expect(vec[469] == false) catch @panic("test failure"); + expect(vec[470] == false) catch @panic("test failure"); + expect(vec[471] == false) catch @panic("test failure"); + expect(vec[472] == false) catch @panic("test failure"); + expect(vec[473] == false) catch @panic("test failure"); + expect(vec[474] == true) catch @panic("test failure"); + expect(vec[475] == true) catch @panic("test failure"); + expect(vec[476] == true) catch @panic("test failure"); + expect(vec[477] == true) catch @panic("test failure"); + expect(vec[478] == true) catch @panic("test failure"); + expect(vec[479] == false) catch @panic("test failure"); + expect(vec[480] == true) catch @panic("test failure"); + expect(vec[481] == true) catch @panic("test failure"); + expect(vec[482] == false) catch @panic("test failure"); + expect(vec[483] == true) catch @panic("test failure"); + expect(vec[484] == false) catch @panic("test failure"); + expect(vec[485] == true) catch @panic("test failure"); + expect(vec[486] == false) catch @panic("test failure"); + expect(vec[487] == true) catch @panic("test failure"); + expect(vec[488] == false) catch @panic("test failure"); + expect(vec[489] == false) catch @panic("test failure"); + expect(vec[490] == false) catch @panic("test failure"); + expect(vec[491] == true) catch @panic("test failure"); + expect(vec[492] == false) catch @panic("test failure"); + expect(vec[493] == false) catch @panic("test failure"); + expect(vec[494] == false) catch @panic("test failure"); + expect(vec[495] == true) catch @panic("test failure"); + expect(vec[496] == true) catch @panic("test failure"); + expect(vec[497] == false) catch @panic("test failure"); + expect(vec[498] == false) catch @panic("test failure"); + expect(vec[499] == true) catch @panic("test failure"); + expect(vec[500] == false) catch @panic("test failure"); + expect(vec[501] == true) catch @panic("test failure"); + expect(vec[502] == false) catch @panic("test failure"); + expect(vec[503] == false) catch @panic("test failure"); + expect(vec[504] == false) catch @panic("test failure"); + expect(vec[505] == true) catch @panic("test failure"); + expect(vec[506] == true) catch @panic("test failure"); + expect(vec[507] == true) catch @panic("test failure"); + expect(vec[508] == true) catch @panic("test failure"); + expect(vec[509] == false) catch @panic("test failure"); + expect(vec[510] == false) catch @panic("test failure"); + expect(vec[511] == true) catch @panic("test failure"); + } + + export fn zig_ret_vector_2_bool() Vector2Bool { + return .{ + false, + false, + }; + } + + export fn zig_ret_vector_4_bool() Vector4Bool { + return .{ + false, + true, + true, + true, + }; + } + + export fn zig_ret_vector_8_bool() Vector8Bool { + return .{ + false, + false, + false, + false, + true, + false, + false, + false, + }; + } + + export fn zig_ret_vector_16_bool() Vector16Bool { + return .{ + false, + true, + false, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + true, + false, + false, + }; + } + + export fn zig_ret_vector_32_bool() Vector32Bool { + return .{ + false, + true, + false, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + }; + } + + export fn zig_ret_vector_64_bool() Vector64Bool { + return .{ + true, + false, + true, + false, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + false, + true, + true, + true, + false, + false, + false, + true, + false, + false, + true, + false, + true, + false, + }; + } + + export fn zig_ret_vector_128_bool() Vector128Bool { + return .{ + true, + true, + false, + false, + false, + true, + true, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + false, + false, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + false, + false, + true, + }; + } + + export fn zig_ret_vector_256_bool() Vector256Bool { + return .{ + true, + true, + true, + false, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + true, + false, + true, + true, + false, + false, + false, + true, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + false, + true, + true, + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + false, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + true, + true, + false, + false, + true, + true, + true, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + true, + true, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + true, + false, + false, + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + }; + } + + export fn zig_ret_vector_512_bool() Vector512Bool { + return .{ + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + false, + false, + false, + true, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + false, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + false, + true, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + false, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true, + true, + true, + false, + false, + true, + false, + true, + true, + false, + true, + false, + false, + true, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + false, + false, + true, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + true, + true, + true, + true, + true, + true, + false, + false, + true, + true, + false, + false, + false, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + true, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + true, + false, + true, + true, + true, + false, + false, + false, + true, + true, + false, + true, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + false, + false, + true, + true, + false, + false, + false, + false, + true, + false, + true, + false, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + true, + false, + false, + true, + false, + true, + false, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + true, + true, + false, + true, + true, + false, + true, + true, + false, + false, + false, + false, + false, + true, + false, + false, + true, + false, + true, + false, + false, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + false, + true, + true, + false, + false, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + true, + true, + true, + false, + false, + true, + true, + false, + false, + }; + } + }; + } +} + const Vector2 = extern struct { x: f32, y: f32 }; extern fn c_ptr_size_float_struct(Vector2) void;