authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-18 20:18:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-21 16:36:10-04:00
logbf6fd9ae3f68f1c91e8776b69080221777225091
tree36ef28fb369779812dcf08b02ba920c1fe6c3bf4
parent528b66f6ec9cfb140abff3dc0c4735c179520f42

cbe: enable CI for std tests


17 files changed, 704 insertions(+), 488 deletions(-)

lib/std/bit_set.zig+2
......@@ -1635,6 +1635,8 @@ fn testStaticBitSet(comptime Set: type) !void {
16351635}
16361636
16371637test "IntegerBitSet" {
1638 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
1639
16381640 try testStaticBitSet(IntegerBitSet(0));
16391641 try testStaticBitSet(IntegerBitSet(1));
16401642 try testStaticBitSet(IntegerBitSet(2));
lib/std/crypto/aes.zig+2-1
......@@ -5,7 +5,8 @@ const testing = std.testing;
55const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);
66const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
77const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
8const impl = if (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) impl: {
8// C backend doesn't currently support passing vectors to inline asm.
9const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: {
910 break :impl @import("aes/aesni.zig");
1011} else if (builtin.cpu.arch == .aarch64 and has_armaes)
1112impl: {
lib/std/crypto/aes_ocb.zig+8
......@@ -257,6 +257,8 @@ inline fn xorWith(x: *Block, y: Block) void {
257257const hexToBytes = std.fmt.hexToBytes;
258258
259259test "AesOcb test vector 1" {
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
261
260262 var k: [Aes128Ocb.key_length]u8 = undefined;
261263 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
262264 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -274,6 +276,8 @@ test "AesOcb test vector 1" {
274276}
275277
276278test "AesOcb test vector 2" {
279 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
280
277281 var k: [Aes128Ocb.key_length]u8 = undefined;
278282 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
279283 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -293,6 +297,8 @@ test "AesOcb test vector 2" {
293297}
294298
295299test "AesOcb test vector 3" {
300 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
301
296302 var k: [Aes128Ocb.key_length]u8 = undefined;
297303 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
298304 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -315,6 +321,8 @@ test "AesOcb test vector 3" {
315321}
316322
317323test "AesOcb test vector 4" {
324 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
325
318326 var k: [Aes128Ocb.key_length]u8 = undefined;
319327 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
320328 var tag: [Aes128Ocb.tag_length]u8 = undefined;
lib/std/crypto/ecdsa.zig+13
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const crypto = std.crypto;
34const fmt = std.fmt;
......@@ -373,6 +374,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
373374}
374375
375376test "ECDSA - Basic operations over EcdsaP384Sha384" {
377 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
378
376379 const Scheme = EcdsaP384Sha384;
377380 const kp = try Scheme.KeyPair.create(null);
378381 const msg = "test";
......@@ -387,6 +390,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" {
387390}
388391
389392test "ECDSA - Basic operations over Secp256k1" {
393 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
394
390395 const Scheme = EcdsaSecp256k1Sha256oSha256;
391396 const kp = try Scheme.KeyPair.create(null);
392397 const msg = "test";
......@@ -401,6 +406,8 @@ test "ECDSA - Basic operations over Secp256k1" {
401406}
402407
403408test "ECDSA - Basic operations over EcdsaP384Sha256" {
409 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
410
404411 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
405412 const kp = try Scheme.KeyPair.create(null);
406413 const msg = "test";
......@@ -415,6 +422,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha256" {
415422}
416423
417424test "ECDSA - Verifying a existing signature with EcdsaP384Sha256" {
425 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
426
418427 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
419428 // zig fmt: off
420429 const sk_bytes = [_]u8{
......@@ -457,6 +466,8 @@ const TestVector = struct {
457466};
458467
459468test "ECDSA - Test vectors from Project Wycheproof" {
469 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
470
460471 const vectors = [_]TestVector{
461472 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", .result = .valid },
462473 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", .result = .acceptable },
......@@ -869,6 +880,8 @@ fn tvTry(vector: TestVector) !void {
869880}
870881
871882test "ECDSA - Sec1 encoding/decoding" {
883 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
884
872885 const Scheme = EcdsaP384Sha384;
873886 const kp = try Scheme.KeyPair.create(null);
874887 const pk = kp.public_key;
lib/std/crypto/ghash_polyval.zig+2-1
......@@ -248,7 +248,8 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type {
248248 const has_pclmul = std.Target.x86.featureSetHas(builtin.cpu.features, .pclmul);
249249 const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
250250 const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
251 const clmul = if (builtin.cpu.arch == .x86_64 and has_pclmul and has_avx) impl: {
251 // C backend doesn't currently support passing vectors to inline asm.
252 const clmul = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_pclmul and has_avx) impl: {
252253 break :impl clmulPclmul;
253254 } else if (builtin.cpu.arch == .aarch64 and has_armaes) impl: {
254255 break :impl clmulPmull;
lib/std/crypto/pcurves/p384.zig+2
......@@ -474,5 +474,7 @@ pub const AffineCoordinates = struct {
474474};
475475
476476test "p384" {
477 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
478
477479 _ = @import("tests/p384.zig");
478480}
lib/std/crypto/pcurves/secp256k1.zig+2
......@@ -552,5 +552,7 @@ pub const AffineCoordinates = struct {
552552};
553553
554554test "secp256k1" {
555 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
556
555557 _ = @import("tests/secp256k1.zig");
556558}
lib/std/crypto/sha2.zig+2-1
......@@ -242,7 +242,8 @@ fn Sha2x32(comptime params: Sha2Params32) type {
242242 d.s[4..8].* = y +% @as(v4u32, d.s[4..8].*);
243243 return;
244244 },
245 .x86_64 => if (comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sha)) {
245 // C backend doesn't currently support passing vectors to inline asm.
246 .x86_64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sha)) {
246247 var x: v4u32 = [_]u32{ d.s[5], d.s[4], d.s[1], d.s[0] };
247248 var y: v4u32 = [_]u32{ d.s[7], d.s[6], d.s[3], d.s[2] };
248249 const s_v = @ptrCast(*[16]v4u32, &s);
lib/std/debug.zig+2
......@@ -2189,6 +2189,8 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
21892189}
21902190
21912191test "manage resources correctly" {
2192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // error.UnsupportedBackend
2193
21922194 if (builtin.os.tag == .wasi) return error.SkipZigTest;
21932195
21942196 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86_64) {
lib/std/math/big/int_test.zig+26
......@@ -915,6 +915,8 @@ test "big.int mul multi-single" {
915915}
916916
917917test "big.int mul multi-multi" {
918 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
919
918920 var op1: u256 = 0x998888efefefefefefefef;
919921 var op2: u256 = 0x333000abababababababab;
920922 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1034,6 +1036,8 @@ test "big.int mulWrap single-single signed" {
10341036}
10351037
10361038test "big.int mulWrap multi-multi unsigned" {
1039 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1040
10371041 var op1: u256 = 0x998888efefefefefefefef;
10381042 var op2: u256 = 0x333000abababababababab;
10391043 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1049,6 +1053,8 @@ test "big.int mulWrap multi-multi unsigned" {
10491053}
10501054
10511055test "big.int mulWrap multi-multi signed" {
1056 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1057
10521058 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);
10531059 defer a.deinit();
10541060 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));
......@@ -1252,6 +1258,8 @@ test "big.int div q=0 alias" {
12521258}
12531259
12541260test "big.int div multi-multi q < r" {
1261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1262
12551263 const op1 = 0x1ffffffff0078f432;
12561264 const op2 = 0x1ffffffff01000000;
12571265 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1608,6 +1616,8 @@ test "big.int div floor positive close to zero" {
16081616}
16091617
16101618test "big.int div multi-multi with rem" {
1619 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1620
16111621 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
16121622 defer a.deinit();
16131623 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -1624,6 +1634,8 @@ test "big.int div multi-multi with rem" {
16241634}
16251635
16261636test "big.int div multi-multi no rem" {
1637 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1638
16271639 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
16281640 defer a.deinit();
16291641 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -1640,6 +1652,8 @@ test "big.int div multi-multi no rem" {
16401652}
16411653
16421654test "big.int div multi-multi (2 branch)" {
1655 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1656
16431657 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
16441658 defer a.deinit();
16451659 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
......@@ -1656,6 +1670,8 @@ test "big.int div multi-multi (2 branch)" {
16561670}
16571671
16581672test "big.int div multi-multi (3.1/3.3 branch)" {
1673 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1674
16591675 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
16601676 defer a.deinit();
16611677 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
......@@ -1672,6 +1688,8 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
16721688}
16731689
16741690test "big.int div multi-single zero-limb trailing" {
1691 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1692
16751693 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
16761694 defer a.deinit();
16771695 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
......@@ -1690,6 +1708,8 @@ test "big.int div multi-single zero-limb trailing" {
16901708}
16911709
16921710test "big.int div multi-multi zero-limb trailing (with rem)" {
1711 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1712
16931713 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
16941714 defer a.deinit();
16951715 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -1709,6 +1729,8 @@ test "big.int div multi-multi zero-limb trailing (with rem)" {
17091729}
17101730
17111731test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
1732 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1733
17121734 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
17131735 defer a.deinit();
17141736 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -1728,6 +1750,8 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li
17281750}
17291751
17301752test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
1753 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1754
17311755 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
17321756 defer a.deinit();
17331757 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
......@@ -2486,6 +2510,8 @@ test "big.int gcd non-one large" {
24862510}
24872511
24882512test "big.int gcd large multi-limb result" {
2513 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2514
24892515 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
24902516 defer a.deinit();
24912517 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
lib/std/mem.zig+6
......@@ -1504,6 +1504,8 @@ test "comptime read/write int" {
15041504}
15051505
15061506test "readIntBig and readIntLittle" {
1507 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1508
15071509 try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0);
15081510 try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0);
15091511
......@@ -1795,6 +1797,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
17951797}
17961798
17971799test "writeIntBig and writeIntLittle" {
1800 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1801
17981802 var buf0: [0]u8 = undefined;
17991803 var buf1: [1]u8 = undefined;
18001804 var buf2: [2]u8 = undefined;
......@@ -4011,6 +4015,8 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
40114015}
40124016
40134017test "read/write(Var)PackedInt" {
4018 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
4019
40144020 switch (builtin.cpu.arch) {
40154021 // This test generates too much code to execute on WASI.
40164022 // LLVM backend fails with "too many locals: locals exceed maximum"
lib/std/os/test.zig+1-2
......@@ -502,8 +502,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
502502}
503503
504504test "dl_iterate_phdr" {
505 if (native_os == .windows or native_os == .wasi or native_os == .macos)
506 return error.SkipZigTest;
505 if (builtin.object_format != .elf) return error.SkipZigTest;
507506
508507 var counter: usize = 0;
509508 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
lib/std/rand/Xoshiro256.zig+2
......@@ -90,6 +90,8 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {
9090}
9191
9292test "xoroshiro sequence" {
93 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
94
9395 var r = Xoshiro256.init(0);
9496
9597 const seq1 = [_]u64{
lib/zig.h+237
......@@ -1972,6 +1972,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
19721972 return 0;
19731973}
19741974
1975static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1976 uint8_t *res_bytes = res;
1977 const uint8_t *lhs_bytes = lhs;
1978 const uint8_t *rhs_bytes = rhs;
1979 uint16_t byte_offset = 0;
1980 uint16_t remaining_bytes = zig_int_bytes(bits);
1981 (void)is_signed;
1982
1983 while (remaining_bytes >= 128 / CHAR_BIT) {
1984 zig_u128 res_limb;
1985 zig_u128 lhs_limb;
1986 zig_u128 rhs_limb;
1987
1988 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1989 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1990 res_limb = zig_and_u128(lhs_limb, rhs_limb);
1991 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1992
1993 remaining_bytes -= 128 / CHAR_BIT;
1994 byte_offset += 128 / CHAR_BIT;
1995 }
1996
1997 while (remaining_bytes >= 64 / CHAR_BIT) {
1998 uint64_t res_limb;
1999 uint64_t lhs_limb;
2000 uint64_t rhs_limb;
2001
2002 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2003 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2004 res_limb = zig_and_u64(lhs_limb, rhs_limb);
2005 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2006
2007 remaining_bytes -= 64 / CHAR_BIT;
2008 byte_offset += 64 / CHAR_BIT;
2009 }
2010
2011 while (remaining_bytes >= 32 / CHAR_BIT) {
2012 uint32_t res_limb;
2013 uint32_t lhs_limb;
2014 uint32_t rhs_limb;
2015
2016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2017 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2018 res_limb = zig_and_u32(lhs_limb, rhs_limb);
2019 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2020
2021 remaining_bytes -= 32 / CHAR_BIT;
2022 byte_offset += 32 / CHAR_BIT;
2023 }
2024
2025 while (remaining_bytes >= 16 / CHAR_BIT) {
2026 uint16_t res_limb;
2027 uint16_t lhs_limb;
2028 uint16_t rhs_limb;
2029
2030 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2031 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2032 res_limb = zig_and_u16(lhs_limb, rhs_limb);
2033 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2034
2035 remaining_bytes -= 16 / CHAR_BIT;
2036 byte_offset += 16 / CHAR_BIT;
2037 }
2038
2039 while (remaining_bytes >= 8 / CHAR_BIT) {
2040 uint8_t res_limb;
2041 uint8_t lhs_limb;
2042 uint8_t rhs_limb;
2043
2044 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2045 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2046 res_limb = zig_and_u8(lhs_limb, rhs_limb);
2047 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2048
2049 remaining_bytes -= 8 / CHAR_BIT;
2050 byte_offset += 8 / CHAR_BIT;
2051 }
2052}
2053
2054static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2055 uint8_t *res_bytes = res;
2056 const uint8_t *lhs_bytes = lhs;
2057 const uint8_t *rhs_bytes = rhs;
2058 uint16_t byte_offset = 0;
2059 uint16_t remaining_bytes = zig_int_bytes(bits);
2060 (void)is_signed;
2061
2062 while (remaining_bytes >= 128 / CHAR_BIT) {
2063 zig_u128 res_limb;
2064 zig_u128 lhs_limb;
2065 zig_u128 rhs_limb;
2066
2067 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2068 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2069 res_limb = zig_or_u128(lhs_limb, rhs_limb);
2070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2071
2072 remaining_bytes -= 128 / CHAR_BIT;
2073 byte_offset += 128 / CHAR_BIT;
2074 }
2075
2076 while (remaining_bytes >= 64 / CHAR_BIT) {
2077 uint64_t res_limb;
2078 uint64_t lhs_limb;
2079 uint64_t rhs_limb;
2080
2081 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2082 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2083 res_limb = zig_or_u64(lhs_limb, rhs_limb);
2084 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2085
2086 remaining_bytes -= 64 / CHAR_BIT;
2087 byte_offset += 64 / CHAR_BIT;
2088 }
2089
2090 while (remaining_bytes >= 32 / CHAR_BIT) {
2091 uint32_t res_limb;
2092 uint32_t lhs_limb;
2093 uint32_t rhs_limb;
2094
2095 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2096 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2097 res_limb = zig_or_u32(lhs_limb, rhs_limb);
2098 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2099
2100 remaining_bytes -= 32 / CHAR_BIT;
2101 byte_offset += 32 / CHAR_BIT;
2102 }
2103
2104 while (remaining_bytes >= 16 / CHAR_BIT) {
2105 uint16_t res_limb;
2106 uint16_t lhs_limb;
2107 uint16_t rhs_limb;
2108
2109 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2110 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2111 res_limb = zig_or_u16(lhs_limb, rhs_limb);
2112 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2113
2114 remaining_bytes -= 16 / CHAR_BIT;
2115 byte_offset += 16 / CHAR_BIT;
2116 }
2117
2118 while (remaining_bytes >= 8 / CHAR_BIT) {
2119 uint8_t res_limb;
2120 uint8_t lhs_limb;
2121 uint8_t rhs_limb;
2122
2123 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2124 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2125 res_limb = zig_or_u8(lhs_limb, rhs_limb);
2126 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2127
2128 remaining_bytes -= 8 / CHAR_BIT;
2129 byte_offset += 8 / CHAR_BIT;
2130 }
2131}
2132
2133static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2134 uint8_t *res_bytes = res;
2135 const uint8_t *lhs_bytes = lhs;
2136 const uint8_t *rhs_bytes = rhs;
2137 uint16_t byte_offset = 0;
2138 uint16_t remaining_bytes = zig_int_bytes(bits);
2139 (void)is_signed;
2140
2141 while (remaining_bytes >= 128 / CHAR_BIT) {
2142 zig_u128 res_limb;
2143 zig_u128 lhs_limb;
2144 zig_u128 rhs_limb;
2145
2146 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2147 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2148 res_limb = zig_xor_u128(lhs_limb, rhs_limb);
2149 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2150
2151 remaining_bytes -= 128 / CHAR_BIT;
2152 byte_offset += 128 / CHAR_BIT;
2153 }
2154
2155 while (remaining_bytes >= 64 / CHAR_BIT) {
2156 uint64_t res_limb;
2157 uint64_t lhs_limb;
2158 uint64_t rhs_limb;
2159
2160 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2161 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2162 res_limb = zig_xor_u64(lhs_limb, rhs_limb);
2163 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2164
2165 remaining_bytes -= 64 / CHAR_BIT;
2166 byte_offset += 64 / CHAR_BIT;
2167 }
2168
2169 while (remaining_bytes >= 32 / CHAR_BIT) {
2170 uint32_t res_limb;
2171 uint32_t lhs_limb;
2172 uint32_t rhs_limb;
2173
2174 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2175 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2176 res_limb = zig_xor_u32(lhs_limb, rhs_limb);
2177 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2178
2179 remaining_bytes -= 32 / CHAR_BIT;
2180 byte_offset += 32 / CHAR_BIT;
2181 }
2182
2183 while (remaining_bytes >= 16 / CHAR_BIT) {
2184 uint16_t res_limb;
2185 uint16_t lhs_limb;
2186 uint16_t rhs_limb;
2187
2188 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2189 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2190 res_limb = zig_xor_u16(lhs_limb, rhs_limb);
2191 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2192
2193 remaining_bytes -= 16 / CHAR_BIT;
2194 byte_offset += 16 / CHAR_BIT;
2195 }
2196
2197 while (remaining_bytes >= 8 / CHAR_BIT) {
2198 uint8_t res_limb;
2199 uint8_t lhs_limb;
2200 uint8_t rhs_limb;
2201
2202 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2203 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2204 res_limb = zig_xor_u8(lhs_limb, rhs_limb);
2205 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2206
2207 remaining_bytes -= 8 / CHAR_BIT;
2208 byte_offset += 8 / CHAR_BIT;
2209 }
2210}
2211
19752212static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
19762213 uint8_t *res_bytes = res;
19772214 const uint8_t *lhs_bytes = lhs;
src/codegen/c.zig+385-476
......@@ -434,7 +434,7 @@ pub const Function = struct {
434434 return f.object.dg.renderCType(w, t);
435435 }
436436
437 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void {
437 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
438438 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
439439 }
440440
......@@ -811,11 +811,13 @@ pub const DeclGen = struct {
811811
812812 try writer.writeByte('{');
813813 var empty = true;
814 for (ty.structFields().values()) |field| {
815 if (!field.ty.hasRuntimeBits()) continue;
814 for (0..ty.structFieldCount()) |field_i| {
815 if (ty.structFieldIsComptime(field_i)) continue;
816 const field_ty = ty.structFieldType(field_i);
817 if (!field_ty.hasRuntimeBits()) continue;
816818
817819 if (!empty) try writer.writeByte(',');
818 try dg.renderValue(writer, field.ty, val, initializer_type);
820 try dg.renderValue(writer, field_ty, val, initializer_type);
819821
820822 empty = false;
821823 }
......@@ -837,19 +839,27 @@ pub const DeclGen = struct {
837839 if (layout.tag_size != 0) {
838840 try writer.writeAll(" .tag = ");
839841 try dg.renderValue(writer, tag_ty, val, initializer_type);
840 try writer.writeByte(',');
841842 }
843 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
844 if (layout.tag_size != 0) try writer.writeByte(',');
842845 try writer.writeAll(" .payload = {");
843846 }
844847 for (ty.unionFields().values()) |field| {
845848 if (!field.ty.hasRuntimeBits()) continue;
846849 try dg.renderValue(writer, field.ty, val, initializer_type);
847850 break;
848 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)});
851 }
849852 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
850853 return writer.writeByte('}');
851854 },
852855 .ErrorUnion => {
856 const payload_ty = ty.errorUnionPayload();
857 const error_ty = ty.errorUnionSet();
858
859 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
860 return dg.renderValue(writer, error_ty, val, location);
861 }
862
853863 if (!location.isInitializer()) {
854864 try writer.writeByte('(');
855865 try dg.renderType(writer, ty);
......@@ -857,18 +867,12 @@ pub const DeclGen = struct {
857867 }
858868
859869 try writer.writeAll("{ .payload = ");
860 try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type);
861 return writer.print(", .error = {x} }}", .{
862 try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other),
863 });
870 try dg.renderValue(writer, payload_ty, val, initializer_type);
871 try writer.writeAll(", .error = ");
872 try dg.renderValue(writer, error_ty, val, initializer_type);
873 return writer.writeAll(" }");
864874 },
865875 .Array, .Vector => {
866 if (!location.isInitializer()) {
867 try writer.writeByte('(');
868 try dg.renderType(writer, ty);
869 try writer.writeByte(')');
870 }
871
872876 const ai = ty.arrayInfo();
873877 if (ai.elem_type.eql(Type.u8, dg.module)) {
874878 var literal = stringLiteral(writer);
......@@ -879,6 +883,12 @@ pub const DeclGen = struct {
879883 try literal.writeChar(0xaa);
880884 return literal.end();
881885 } else {
886 if (!location.isInitializer()) {
887 try writer.writeByte('(');
888 try dg.renderType(writer, ty);
889 try writer.writeByte(')');
890 }
891
882892 try writer.writeByte('{');
883893 const c_len = ty.arrayLenIncludingSentinel();
884894 var index: u64 = 0;
......@@ -1199,23 +1209,20 @@ pub const DeclGen = struct {
11991209 try writer.writeAll(" }");
12001210 },
12011211 .ErrorSet => {
1202 const error_name = if (val.castTag(.@"error")) |error_pl|
1203 error_pl.data.name
1204 else
1205 dg.module.error_name_list.items[0];
1206 // Error values are already defined by genErrDecls.
1207 try writer.print("zig_error_{}", .{fmtIdent(error_name)});
1212 if (val.castTag(.@"error")) |error_pl| {
1213 // Error values are already defined by genErrDecls.
1214 try writer.print("zig_error_{}", .{fmtIdent(error_pl.data.name)});
1215 } else {
1216 try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, .Other)});
1217 }
12081218 },
12091219 .ErrorUnion => {
1210 const error_ty = ty.errorUnionSet();
12111220 const payload_ty = ty.errorUnionPayload();
1221 const error_ty = ty.errorUnionSet();
1222 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
12121223
1213 if (!payload_ty.hasRuntimeBits()) {
1214 // We use the error type directly as the type.
1215 if (val.errorUnionIsPayload()) {
1216 return try writer.writeByte('0');
1217 }
1218 return dg.renderValue(writer, error_ty, val, location);
1224 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1225 return dg.renderValue(writer, error_ty, error_val, location);
12191226 }
12201227
12211228 if (!location.isInitializer()) {
......@@ -1225,8 +1232,6 @@ pub const DeclGen = struct {
12251232 }
12261233
12271234 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef;
1228 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
1229
12301235 try writer.writeAll("{ .payload = ");
12311236 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);
12321237 try writer.writeAll(", .error = ");
......@@ -1290,9 +1295,10 @@ pub const DeclGen = struct {
12901295
12911296 try writer.writeByte('{');
12921297 var empty = true;
1293 for (field_vals, 0..) |field_val, field_index| {
1294 const field_ty = ty.structFieldType(field_index);
1295 if (!field_ty.hasRuntimeBits()) continue;
1298 for (field_vals, 0..) |field_val, field_i| {
1299 if (ty.structFieldIsComptime(field_i)) continue;
1300 const field_ty = ty.structFieldType(field_i);
1301 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
12961302
12971303 if (!empty) try writer.writeByte(',');
12981304 try dg.renderValue(writer, field_ty, field_val, initializer_type);
......@@ -1315,8 +1321,9 @@ pub const DeclGen = struct {
13151321 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
13161322
13171323 var eff_num_fields: usize = 0;
1318 for (0..field_vals.len) |index| {
1319 const field_ty = ty.structFieldType(index);
1324 for (0..field_vals.len) |field_i| {
1325 if (ty.structFieldIsComptime(field_i)) continue;
1326 const field_ty = ty.structFieldType(field_i);
13201327 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13211328
13221329 eff_num_fields += 1;
......@@ -1337,8 +1344,9 @@ pub const DeclGen = struct {
13371344
13381345 var eff_index: usize = 0;
13391346 var needs_closing_paren = false;
1340 for (field_vals, 0..) |field_val, index| {
1341 const field_ty = ty.structFieldType(index);
1347 for (field_vals, 0..) |field_val, field_i| {
1348 if (ty.structFieldIsComptime(field_i)) continue;
1349 const field_ty = ty.structFieldType(field_i);
13421350 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13431351
13441352 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
......@@ -1365,8 +1373,9 @@ pub const DeclGen = struct {
13651373 try writer.writeByte('(');
13661374 // a << a_off | b << b_off | c << c_off
13671375 var empty = true;
1368 for (field_vals, 0..) |field_val, index| {
1369 const field_ty = ty.structFieldType(index);
1376 for (field_vals, 0..) |field_val, field_i| {
1377 if (ty.structFieldIsComptime(field_i)) continue;
1378 const field_ty = ty.structFieldType(field_i);
13701379 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13711380
13721381 if (!empty) try writer.writeAll(" | ");
......@@ -1398,9 +1407,9 @@ pub const DeclGen = struct {
13981407 try writer.writeByte(')');
13991408 }
14001409
1401 const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
1402 const field_ty = ty.unionFields().values()[index].ty;
1403 const field_name = ty.unionFields().keys()[index];
1410 const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
1411 const field_ty = ty.unionFields().values()[field_i].ty;
1412 const field_name = ty.unionFields().keys()[field_i];
14041413 if (ty.containerLayout() == .Packed) {
14051414 if (field_ty.hasRuntimeBits()) {
14061415 if (field_ty.isPtrAtRuntime()) {
......@@ -1419,32 +1428,27 @@ pub const DeclGen = struct {
14191428 return;
14201429 }
14211430
1422 var has_payload_init = false;
14231431 try writer.writeByte('{');
14241432 if (ty.unionTagTypeSafety()) |tag_ty| {
14251433 const layout = ty.unionGetLayout(target);
14261434 if (layout.tag_size != 0) {
1427 try writer.writeAll(".tag = ");
1435 try writer.writeAll(" .tag = ");
14281436 try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type);
1429 try writer.writeAll(", ");
1430 }
1431 if (!ty.unionHasAllZeroBitFieldTypes()) {
1432 try writer.writeAll(".payload = {");
1433 has_payload_init = true;
14341437 }
1438 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
1439 if (layout.tag_size != 0) try writer.writeByte(',');
1440 try writer.writeAll(" .payload = {");
14351441 }
1436
1437 var it = ty.unionFields().iterator();
14381442 if (field_ty.hasRuntimeBits()) {
1439 try writer.print(".{ } = ", .{fmtIdent(field_name)});
1443 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
14401444 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);
1441 } else while (it.next()) |field| {
1442 if (!field.value_ptr.ty.hasRuntimeBits()) continue;
1443 try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)});
1444 try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type);
1445 try writer.writeByte(' ');
1446 } else for (ty.unionFields().values()) |field| {
1447 if (!field.ty.hasRuntimeBits()) continue;
1448 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);
14451449 break;
14461450 }
1447 if (has_payload_init) try writer.writeByte('}');
1451 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
14481452 try writer.writeByte('}');
14491453 },
14501454
......@@ -1585,7 +1589,7 @@ pub const DeclGen = struct {
15851589 c_value: struct {
15861590 f: *Function,
15871591 value: CValue,
1588 v: Vectorizer,
1592 v: Vectorize,
15891593 },
15901594 value: struct {
15911595 value: Value,
......@@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
30733077 const inst_ty = f.air.typeOfIndex(inst);
30743078 const operand = try f.resolveInst(ty_op.operand);
30753079 try reap(f, inst, &.{ty_op.operand});
3080
30763081 const writer = f.object.writer();
30773082 const local = try f.allocLocal(inst, inst_ty);
3083 const a = try Assignment.start(f, writer, inst_ty);
30783084 try f.writeCValue(writer, local, .Other);
3079 try writer.writeAll(" = ");
3085 try a.assign(f, writer);
30803086 if (is_ptr) {
30813087 try writer.writeByte('&');
30823088 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });
30833089 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });
3084 try writer.writeAll(";\n");
3090 try a.end(f, writer);
30853091 return local;
30863092}
30873093
......@@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
30973103 const index = try f.resolveInst(bin_op.rhs);
30983104 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
30993105
3100 const target = f.object.dg.module.getTarget();
3101 const is_array = lowersToArray(inst_ty, target);
3102
3103 const local = try f.allocLocal(inst, inst_ty);
31043106 const writer = f.object.writer();
3105 if (is_array) {
3106 try writer.writeAll("memcpy(");
3107 try f.writeCValue(writer, local, .FunctionArgument);
3108 try writer.writeAll(", ");
3109 } else {
3110 try f.writeCValue(writer, local, .Other);
3111 try writer.writeAll(" = ");
3112 }
3107 const local = try f.allocLocal(inst, inst_ty);
3108 const a = try Assignment.start(f, writer, inst_ty);
3109 try f.writeCValue(writer, local, .Other);
3110 try a.assign(f, writer);
31133111 try f.writeCValue(writer, ptr, .Other);
31143112 try writer.writeByte('[');
31153113 try f.writeCValue(writer, index, .Other);
31163114 try writer.writeByte(']');
3117 if (is_array) {
3118 try writer.writeAll(", sizeof(");
3119 try f.renderType(writer, inst_ty);
3120 try writer.writeAll("))");
3121 }
3122 try writer.writeAll(";\n");
3115 try a.end(f, writer);
31233116 return local;
31243117}
31253118
......@@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
31293122
31303123 const inst_ty = f.air.typeOfIndex(inst);
31313124 const ptr_ty = f.air.typeOf(bin_op.lhs);
3132 const child_ty = ptr_ty.childType();
3125 const elem_ty = ptr_ty.childType();
3126 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
31333127
31343128 const ptr = try f.resolveInst(bin_op.lhs);
31353129 const index = try f.resolveInst(bin_op.rhs);
31363130 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31373131
31383132 const writer = f.object.writer();
3139 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
3133 const local = try f.allocLocal(inst, inst_ty);
3134 const a = try Assignment.start(f, writer, inst_ty);
31403135 try f.writeCValue(writer, local, .Other);
3141 try writer.writeAll(" = ");
3142
3143 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
3144 try f.writeCValue(writer, ptr, .Initializer);
3145 try writer.writeAll(";\n");
3146 return local;
3147 }
3148
3136 try a.assign(f, writer);
31493137 try writer.writeByte('(');
31503138 try f.renderType(writer, inst_ty);
3151 try writer.writeAll(")&(");
3152 if (ptr_ty.ptrSize() == .One) {
3139 try writer.writeByte(')');
3140 if (elem_has_bits) try writer.writeByte('&');
3141 if (elem_has_bits and ptr_ty.ptrSize() == .One) {
31533142 // It's a pointer to an array, so we need to de-reference.
31543143 try f.writeCValueDeref(writer, ptr);
3155 } else {
3156 try f.writeCValue(writer, ptr, .Other);
3144 } else try f.writeCValue(writer, ptr, .Other);
3145 if (elem_has_bits) {
3146 try writer.writeByte('[');
3147 try f.writeCValue(writer, index, .Other);
3148 try writer.writeByte(']');
31573149 }
3158 try writer.writeAll(")[");
3159 try f.writeCValue(writer, index, .Other);
3160 try writer.writeAll("];\n");
3150 try a.end(f, writer);
31613151 return local;
31623152}
31633153
......@@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
31733163 const index = try f.resolveInst(bin_op.rhs);
31743164 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31753165
3176 const target = f.object.dg.module.getTarget();
3177 const is_array = lowersToArray(inst_ty, target);
3178
3179 const local = try f.allocLocal(inst, inst_ty);
31803166 const writer = f.object.writer();
3181 if (is_array) {
3182 try writer.writeAll("memcpy(");
3183 try f.writeCValue(writer, local, .FunctionArgument);
3184 try writer.writeAll(", ");
3185 } else {
3186 try f.writeCValue(writer, local, .Other);
3187 try writer.writeAll(" = ");
3188 }
3189 try f.writeCValue(writer, slice, .Other);
3190 try writer.writeAll(".ptr[");
3167 const local = try f.allocLocal(inst, inst_ty);
3168 const a = try Assignment.start(f, writer, inst_ty);
3169 try f.writeCValue(writer, local, .Other);
3170 try a.assign(f, writer);
3171 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3172 try writer.writeByte('[');
31913173 try f.writeCValue(writer, index, .Other);
31923174 try writer.writeByte(']');
3193 if (is_array) {
3194 try writer.writeAll(", sizeof(");
3195 try f.renderType(writer, inst_ty);
3196 try writer.writeAll("))");
3197 }
3198 try writer.writeAll(";\n");
3175 try a.end(f, writer);
31993176 return local;
32003177}
32013178
......@@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
32033180 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
32043181 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
32053182
3183 const inst_ty = f.air.typeOfIndex(inst);
32063184 const slice_ty = f.air.typeOf(bin_op.lhs);
3207 const child_ty = slice_ty.elemType2();
3185 const elem_ty = slice_ty.elemType2();
3186 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
3187
32083188 const slice = try f.resolveInst(bin_op.lhs);
32093189 const index = try f.resolveInst(bin_op.rhs);
32103190 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32113191
32123192 const writer = f.object.writer();
3213 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
3193 const local = try f.allocLocal(inst, inst_ty);
3194 const a = try Assignment.start(f, writer, inst_ty);
32143195 try f.writeCValue(writer, local, .Other);
3215 try writer.writeAll(" = ");
3216 if (child_ty.hasRuntimeBitsIgnoreComptime()) try writer.writeByte('&');
3217 try f.writeCValue(writer, slice, .Other);
3218 try writer.writeAll(".ptr");
3219 if (child_ty.hasRuntimeBitsIgnoreComptime()) {
3196 try a.assign(f, writer);
3197 if (elem_has_bits) try writer.writeByte('&');
3198 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3199 if (elem_has_bits) {
32203200 try writer.writeByte('[');
32213201 try f.writeCValue(writer, index, .Other);
32223202 try writer.writeByte(']');
32233203 }
3224 try writer.writeAll(";\n");
3204 try a.end(f, writer);
32253205 return local;
32263206}
32273207
......@@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
32373217 const index = try f.resolveInst(bin_op.rhs);
32383218 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32393219
3240 const target = f.object.dg.module.getTarget();
3241 const is_array = lowersToArray(inst_ty, target);
3242
3243 const local = try f.allocLocal(inst, inst_ty);
32443220 const writer = f.object.writer();
3245 if (is_array) {
3246 try writer.writeAll("memcpy(");
3247 try f.writeCValue(writer, local, .FunctionArgument);
3248 try writer.writeAll(", ");
3249 } else {
3250 try f.writeCValue(writer, local, .Other);
3251 try writer.writeAll(" = ");
3252 }
3221 const local = try f.allocLocal(inst, inst_ty);
3222 const a = try Assignment.start(f, writer, inst_ty);
3223 try f.writeCValue(writer, local, .Other);
3224 try a.assign(f, writer);
32533225 try f.writeCValue(writer, array, .Other);
32543226 try writer.writeByte('[');
32553227 try f.writeCValue(writer, index, .Other);
32563228 try writer.writeByte(']');
3257 if (is_array) {
3258 try writer.writeAll(", sizeof(");
3259 try f.renderType(writer, inst_ty);
3260 try writer.writeAll("))");
3261 }
3262 try writer.writeAll(";\n");
3229 try a.end(f, writer);
32633230 return local;
32643231}
32653232
......@@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33433310
33443311 const writer = f.object.writer();
33453312 const local = try f.allocLocal(inst, src_ty);
3346 const v = try Vectorizer.start(f, inst, writer, ptr_ty);
3313 const v = try Vectorize.start(f, inst, writer, ptr_ty);
33473314
33483315 if (need_memcpy) {
33493316 try writer.writeAll("memcpy(");
......@@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
34843451
34853452 const writer = f.object.writer();
34863453 const local = try f.allocLocal(inst, inst_ty);
3487 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3454 const v = try Vectorize.start(f, inst, writer, operand_ty);
3455 const a = try Assignment.start(f, writer, scalar_ty);
34883456 try f.writeCValue(writer, local, .Other);
34893457 try v.elem(f, writer);
3490 try writer.writeAll(" = ");
3458 try a.assign(f, writer);
34913459 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);
3492 try writer.writeAll(";\n");
3460 try a.end(f, writer);
34933461 try v.end(f, inst, writer);
34943462
34953463 return local;
......@@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35133481
35143482 const writer = f.object.writer();
35153483 const local = try f.allocLocal(inst, inst_ty);
3516 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3484 const v = try Vectorize.start(f, inst, writer, operand_ty);
35173485
35183486 try f.writeCValue(writer, local, .Other);
35193487 try v.elem(f, writer);
......@@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
35973565 const writer = f.object.writer();
35983566 const inst_ty = f.air.typeOfIndex(inst);
35993567 const local = try f.allocLocal(inst, inst_ty);
3568 const a = try Assignment.start(f, writer, inst_ty);
36003569 try f.writeCValue(writer, local, .Other);
3601 try writer.writeAll(" = ");
3570 try a.assign(f, writer);
36023571 try f.writeCValue(writer, operand, .Other);
3603 try writer.writeAll(";\n");
3572 try a.end(f, writer);
36043573 return local;
36053574}
36063575
......@@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
36323601 const src_val_is_undefined =
36333602 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
36343603 if (src_val_is_undefined) {
3635 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3636 return try storeUndefined(f, ptr_info.pointee_type, ptr_val);
3604 if (ptr_info.host_size == 0) {
3605 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3606 return try storeUndefined(f, ptr_info.pointee_type, ptr_val);
3607 } else if (!f.wantSafety()) {
3608 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3609 return .none;
3610 }
36373611 }
36383612
36393613 const target = f.object.dg.module.getTarget();
......@@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
36463620 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36473621
36483622 const writer = f.object.writer();
3649 const v = try Vectorizer.start(f, inst, writer, ptr_ty);
3623 const v = try Vectorize.start(f, inst, writer, ptr_ty);
36503624
36513625 if (need_memcpy) {
36523626 // For this memcpy to safely work we need the rhs to have the same
......@@ -3775,7 +3749,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37753749
37763750 const w = f.object.writer();
37773751 const local = try f.allocLocal(inst, inst_ty);
3778 const v = try Vectorizer.start(f, inst, w, operand_ty);
3752 const v = try Vectorize.start(f, inst, w, operand_ty);
37793753 try f.writeCValueMember(w, local, .{ .field = 1 });
37803754 try v.elem(f, w);
37813755 try w.writeAll(" = zig_");
......@@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
38113785
38123786 const writer = f.object.writer();
38133787 const local = try f.allocLocal(inst, inst_ty);
3814 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3788 const v = try Vectorize.start(f, inst, writer, operand_ty);
38153789 try f.writeCValue(writer, local, .Other);
38163790 try v.elem(f, writer);
38173791 try writer.writeAll(" = ");
......@@ -3846,7 +3820,7 @@ fn airBinOp(
38463820
38473821 const writer = f.object.writer();
38483822 const local = try f.allocLocal(inst, inst_ty);
3849 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3823 const v = try Vectorize.start(f, inst, writer, operand_ty);
38503824 try f.writeCValue(writer, local, .Other);
38513825 try v.elem(f, writer);
38523826 try writer.writeAll(" = ");
......@@ -3893,7 +3867,7 @@ fn airCmpOp(
38933867
38943868 const writer = f.object.writer();
38953869 const local = try f.allocLocal(inst, inst_ty);
3896 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3870 const v = try Vectorize.start(f, inst, writer, operand_ty);
38973871 try f.writeCValue(writer, local, .Other);
38983872 try v.elem(f, writer);
38993873 try writer.writeAll(" = ");
......@@ -3942,7 +3916,7 @@ fn airEquality(
39423916 try f.writeCValue(writer, local, .Other);
39433917 try writer.writeAll(" = ");
39443918
3945 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) {
3919 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.optionalReprIsPayload()) {
39463920 // (A && B) || (C && (A == B))
39473921 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
39483922
......@@ -4008,7 +3982,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
40083982
40093983 const local = try f.allocLocal(inst, inst_ty);
40103984 const writer = f.object.writer();
4011 const v = try Vectorizer.start(f, inst, writer, inst_ty);
3985 const v = try Vectorize.start(f, inst, writer, inst_ty);
40123986 try f.writeCValue(writer, local, .Other);
40133987 try v.elem(f, writer);
40143988 try writer.writeAll(" = ");
......@@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
40594033
40604034 const writer = f.object.writer();
40614035 const local = try f.allocLocal(inst, inst_ty);
4062 const v = try Vectorizer.start(f, inst, writer, inst_ty);
4036 const v = try Vectorize.start(f, inst, writer, inst_ty);
40634037 try f.writeCValue(writer, local, .Other);
40644038 try v.elem(f, writer);
40654039 // (lhs <> rhs) ? lhs : rhs
......@@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
40914065 const len = try f.resolveInst(bin_op.rhs);
40924066 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
40934067
4094 const writer = f.object.writer();
40954068 const inst_ty = f.air.typeOfIndex(inst);
4096 const local = try f.allocLocal(inst, inst_ty);
4097 try f.writeCValue(writer, local, .Other);
4098 try writer.writeAll(".ptr = (");
40994069 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4100 try f.renderType(writer, inst_ty.slicePtrFieldType(&buf));
4101 try writer.writeByte(')');
4102 try f.writeCValue(writer, ptr, .Other);
4103 try writer.writeAll("; ");
4104 try f.writeCValue(writer, local, .Other);
4105 try writer.writeAll(".len = ");
4106 try f.writeCValue(writer, len, .Initializer);
4107 try writer.writeAll(";\n");
4070 const ptr_ty = inst_ty.slicePtrFieldType(&buf);
41084071
4072 const writer = f.object.writer();
4073 const local = try f.allocLocal(inst, inst_ty);
4074 {
4075 const a = try Assignment.start(f, writer, ptr_ty);
4076 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
4077 try a.assign(f, writer);
4078 try writer.writeByte('(');
4079 try f.renderType(writer, ptr_ty);
4080 try writer.writeByte(')');
4081 try f.writeCValue(writer, ptr, .Other);
4082 try a.end(f, writer);
4083 }
4084 {
4085 const a = try Assignment.start(f, writer, Type.usize);
4086 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
4087 try a.assign(f, writer);
4088 try f.writeCValue(writer, len, .Other);
4089 try a.end(f, writer);
4090 }
41094091 return local;
41104092}
41114093
......@@ -4346,10 +4328,10 @@ fn lowerTry(
43464328 operand: Air.Inst.Ref,
43474329 body: []const Air.Inst.Index,
43484330 err_union_ty: Type,
4349 operand_is_ptr: bool,
4331 is_ptr: bool,
43504332) !CValue {
43514333 const err_union = try f.resolveInst(operand);
4352 const result_ty = f.air.typeOfIndex(inst);
4334 const inst_ty = f.air.typeOfIndex(inst);
43534335 const liveness_condbr = f.liveness.getCondBr(inst);
43544336 const writer = f.object.writer();
43554337 const payload_ty = err_union_ty.errorUnionPayload();
......@@ -4358,7 +4340,7 @@ fn lowerTry(
43584340 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
43594341 try writer.writeAll("if (");
43604342 if (!payload_has_bits) {
4361 if (operand_is_ptr)
4343 if (is_ptr)
43624344 try f.writeCValueDeref(writer, err_union)
43634345 else
43644346 try f.writeCValue(writer, err_union, .Other);
......@@ -4367,7 +4349,7 @@ fn lowerTry(
43674349 // Remember we must avoid calling reap() twice for the same operand
43684350 // in this function.
43694351 try reap(f, inst, &.{operand});
4370 if (operand_is_ptr or isByRef(err_union_ty))
4352 if (is_ptr)
43714353 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })
43724354 else
43734355 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });
......@@ -4384,7 +4366,7 @@ fn lowerTry(
43844366 }
43854367
43864368 if (!payload_has_bits) {
4387 if (!operand_is_ptr) {
4369 if (!is_ptr) {
43884370 return .none;
43894371 } else {
43904372 return err_union;
......@@ -4397,26 +4379,15 @@ fn lowerTry(
43974379 return .none;
43984380 }
43994381
4400 const target = f.object.dg.module.getTarget();
4401 const is_array = lowersToArray(payload_ty, target);
4402 const local = try f.allocLocal(inst, result_ty);
4403 if (is_array) {
4404 try writer.writeAll("memcpy(");
4405 try f.writeCValue(writer, local, .FunctionArgument);
4406 try writer.writeAll(", ");
4407 try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4408 try writer.writeAll(", sizeof(");
4409 try f.renderType(writer, payload_ty);
4410 try writer.writeAll("));\n");
4411 } else {
4412 try f.writeCValue(writer, local, .Other);
4413 try writer.writeAll(" = ");
4414 if (operand_is_ptr or isByRef(payload_ty)) {
4415 try writer.writeByte('&');
4416 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4417 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4418 try writer.writeAll(";\n");
4419 }
4382 const local = try f.allocLocal(inst, inst_ty);
4383 const a = try Assignment.start(f, writer, inst_ty);
4384 try f.writeCValue(writer, local, .Other);
4385 try a.assign(f, writer);
4386 if (is_ptr) {
4387 try writer.writeByte('&');
4388 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4389 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4390 try a.end(f, writer);
44204391 return local;
44214392}
44224393
......@@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
44284399
44294400 // If result is .none then the value of the block is unused.
44304401 if (result != .none) {
4402 const operand_ty = f.air.typeOf(branch.operand);
44314403 const operand = try f.resolveInst(branch.operand);
44324404 try reap(f, inst, &.{branch.operand});
44334405
4434 const operand_ty = f.air.typeOf(branch.operand);
4435 const target = f.object.dg.module.getTarget();
4436 if (lowersToArray(operand_ty, target)) {
4437 try writer.writeAll("memcpy(");
4438 try f.writeCValue(writer, result, .FunctionArgument);
4439 try writer.writeAll(", ");
4440 try f.writeCValue(writer, operand, .FunctionArgument);
4441 try writer.writeAll(", sizeof(");
4442 try f.renderType(writer, operand_ty);
4443 try writer.writeAll("))");
4444 } else {
4445 try f.writeCValue(writer, result, .Other);
4446 try writer.writeAll(" = ");
4447 try f.writeCValue(writer, operand, .Other);
4448 }
4449 try writer.writeAll(";\n");
4406 const a = try Assignment.start(f, writer, operand_ty);
4407 try f.writeCValue(writer, result, .Other);
4408 try a.assign(f, writer);
4409 try f.writeCValue(writer, operand, .Other);
4410 try a.end(f, writer);
44504411 }
44514412
44524413 try writer.print("goto zig_block_{d};\n", .{block.block_id});
......@@ -4771,7 +4732,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
47714732 if (f.wantSafety()) {
47724733 try f.writeCValue(writer, local, .Other);
47734734 try writer.writeAll(" = ");
4774 try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);
4735 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
47754736 try writer.writeAll(";\n");
47764737 }
47774738 break :local local;
......@@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48064767 try writer.writeAll("\")");
48074768 if (f.wantSafety()) {
48084769 try writer.writeAll(" = ");
4809 try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer);
4770 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);
48104771 }
48114772 try writer.writeAll(";\n");
48124773 }
......@@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48404801 try writer.writeAll("\")");
48414802 }
48424803 try writer.writeAll(" = ");
4843 try f.writeCValue(writer, input_val, .Initializer);
4804 try f.writeCValue(writer, input_val, .Other);
48444805 try writer.writeAll(";\n");
48454806 }
48464807 }
......@@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50725033 }
50735034
50745035 const inst_ty = f.air.typeOfIndex(inst);
5075 const local = try f.allocLocal(inst, inst_ty);
50765036 const writer = f.object.writer();
5037 const local = try f.allocLocal(inst, inst_ty);
50775038
50785039 if (opt_ty.optionalReprIsPayload()) {
50795040 try f.writeCValue(writer, local, .Other);
......@@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50835044 return local;
50845045 }
50855046
5086 const target = f.object.dg.module.getTarget();
5087 const is_array = lowersToArray(inst_ty, target);
5088
5089 if (is_array) {
5090 try writer.writeAll("memcpy(");
5091 try f.writeCValue(writer, local, .FunctionArgument);
5092 try writer.writeAll(", ");
5093 } else {
5094 try f.writeCValue(writer, local, .Other);
5095 try writer.writeAll(" = ");
5096 }
5047 const a = try Assignment.start(f, writer, inst_ty);
5048 try f.writeCValue(writer, local, .Other);
5049 try a.assign(f, writer);
50975050 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5098 if (is_array) {
5099 try writer.writeAll(", sizeof(");
5100 try f.renderType(writer, inst_ty);
5101 try writer.writeAll("))");
5102 }
5103 try writer.writeAll(";\n");
5051 try a.end(f, writer);
51045052 return local;
51055053}
51065054
......@@ -5193,6 +5141,7 @@ fn fieldLocation(
51935141 if (container_ty.structFieldIsComptime(next_field_index)) continue;
51945142 const field_ty = container_ty.structFieldType(next_field_index);
51955143 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5144
51965145 break .{ .field = if (container_ty.isSimpleTuple())
51975146 .{ .field = next_field_index }
51985147 else
......@@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54375386 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
54385387 try writer.writeByte('(');
54395388 }
5440 try writer.writeAll("zig_shr_");
5441 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5442 try writer.writeByte('(');
5389 if (bit_offset_val_pl.data > 0) {
5390 try writer.writeAll("zig_shr_");
5391 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5392 try writer.writeByte('(');
5393 }
54435394 try f.writeCValue(writer, struct_byval, .Other);
5444 try writer.writeAll(", ");
5445 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5446 try writer.writeByte(')');
5395 if (bit_offset_val_pl.data > 0) {
5396 try writer.writeAll(", ");
5397 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5398 try writer.writeByte(')');
5399 }
54475400 if (cant_cast) try writer.writeByte(')');
54485401 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
54495402 try writer.writeAll(");\n");
......@@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54735426
54745427 const local = try f.allocLocal(inst, inst_ty);
54755428 try writer.writeAll("memcpy(&");
5476 try f.writeCValue(writer, local, .FunctionArgument);
5429 try f.writeCValue(writer, local, .Other);
54775430 try writer.writeAll(", &");
5478 try f.writeCValue(writer, operand_lval, .FunctionArgument);
5431 try f.writeCValue(writer, operand_lval, .Other);
54795432 try writer.writeAll(", sizeof(");
54805433 try f.renderType(writer, inst_ty);
54815434 try writer.writeAll("));\n");
......@@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54965449 };
54975450
54985451 const local = try f.allocLocal(inst, inst_ty);
5499 if (lowersToArray(inst_ty, target)) {
5500 try writer.writeAll("memcpy(");
5501 try f.writeCValue(writer, local, .FunctionArgument);
5502 try writer.writeAll(", ");
5503 try f.writeCValueMember(writer, struct_byval, field_name);
5504 try writer.writeAll(", sizeof(");
5505 try f.renderType(writer, inst_ty);
5506 try writer.writeAll("))");
5507 } else {
5508 try f.writeCValue(writer, local, .Other);
5509 try writer.writeAll(" = ");
5510 try f.writeCValueMember(writer, struct_byval, field_name);
5511 }
5512 try writer.writeAll(";\n");
5452 const a = try Assignment.start(f, writer, inst_ty);
5453 try f.writeCValue(writer, local, .Other);
5454 try a.assign(f, writer);
5455 try f.writeCValueMember(writer, struct_byval, field_name);
5456 try a.end(f, writer);
55135457 return local;
55145458}
55155459
......@@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
55545498 const operand = try f.resolveInst(ty_op.operand);
55555499 try reap(f, inst, &.{ty_op.operand});
55565500 const operand_ty = f.air.typeOf(ty_op.operand);
5557 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
5558 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5501 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
55595502
5503 const writer = f.object.writer();
55605504 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {
55615505 if (!is_ptr) return .none;
55625506
5563 const w = f.object.writer();
55645507 const local = try f.allocLocal(inst, inst_ty);
5565 try f.writeCValue(w, local, .Other);
5566 try w.writeAll(" = (");
5567 try f.renderType(w, inst_ty);
5568 try w.writeByte(')');
5569 try f.writeCValue(w, operand, .Initializer);
5570 try w.writeAll(";\n");
5508 try f.writeCValue(writer, local, .Other);
5509 try writer.writeAll(" = (");
5510 try f.renderType(writer, inst_ty);
5511 try writer.writeByte(')');
5512 try f.writeCValue(writer, operand, .Initializer);
5513 try writer.writeAll(";\n");
55715514 return local;
55725515 }
55735516
5574 const writer = f.object.writer();
55755517 const local = try f.allocLocal(inst, inst_ty);
5518 const a = try Assignment.start(f, writer, inst_ty);
55765519 try f.writeCValue(writer, local, .Other);
5577 try writer.writeAll(" = ");
5578 if (is_ptr) try writer.writeByte('&');
5579 if (operand_is_ptr)
5580 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" })
5581 else
5582 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5583 try writer.writeAll(";\n");
5520 try a.assign(f, writer);
5521 if (is_ptr) {
5522 try writer.writeByte('&');
5523 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
5524 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5525 try a.end(f, writer);
55845526 return local;
55855527}
55865528
......@@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
55885530 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55895531
55905532 const inst_ty = f.air.typeOfIndex(inst);
5533 const repr_is_payload = inst_ty.optionalReprIsPayload();
5534 const payload_ty = f.air.typeOf(ty_op.operand);
55915535 const payload = try f.resolveInst(ty_op.operand);
55925536 try reap(f, inst, &.{ty_op.operand});
5593 const writer = f.object.writer();
5594
5595 if (inst_ty.optionalReprIsPayload()) {
5596 const local = try f.allocLocal(inst, inst_ty);
5597 try f.writeCValue(writer, local, .Other);
5598 try writer.writeAll(" = ");
5599 try f.writeCValue(writer, payload, .Other);
5600 try writer.writeAll(";\n");
5601 return local;
5602 }
5603
5604 const payload_ty = f.air.typeOf(ty_op.operand);
5605 const target = f.object.dg.module.getTarget();
5606 const is_array = lowersToArray(payload_ty, target);
56075537
5538 const writer = f.object.writer();
56085539 const local = try f.allocLocal(inst, inst_ty);
5609 if (!is_array) {
5610 try f.writeCValue(writer, local, .Other);
5611 try writer.writeAll(".payload = ");
5540 {
5541 const a = try Assignment.start(f, writer, payload_ty);
5542 if (repr_is_payload)
5543 try f.writeCValue(writer, local, .Other)
5544 else
5545 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5546 try a.assign(f, writer);
56125547 try f.writeCValue(writer, payload, .Other);
5613 try writer.writeAll("; ");
5548 try a.end(f, writer);
56145549 }
5615 try f.writeCValue(writer, local, .Other);
5616 try writer.writeAll(".is_null = false;\n");
5617 if (is_array) {
5618 try writer.writeAll("memcpy(");
5619 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5620 try writer.writeAll(", ");
5621 try f.writeCValue(writer, payload, .FunctionArgument);
5622 try writer.writeAll(", sizeof(");
5623 try f.renderType(writer, payload_ty);
5624 try writer.writeAll("));\n");
5550 if (!repr_is_payload) {
5551 const a = try Assignment.start(f, writer, Type.bool);
5552 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
5553 try a.assign(f, writer);
5554 try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other);
5555 try a.end(f, writer);
56255556 }
56265557 return local;
56275558}
......@@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
56295560fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
56305561 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56315562
5632 const writer = f.object.writer();
5633 const operand = try f.resolveInst(ty_op.operand);
5563 const inst_ty = f.air.typeOfIndex(inst);
5564 const payload_ty = inst_ty.errorUnionPayload();
5565 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5566 const err_ty = inst_ty.errorUnionSet();
5567 const err = try f.resolveInst(ty_op.operand);
56345568 try reap(f, inst, &.{ty_op.operand});
5635 const error_union_ty = f.air.typeOfIndex(inst);
5636 const payload_ty = error_union_ty.errorUnionPayload();
5637 const local = try f.allocLocal(inst, error_union_ty);
56385569
5639 if (!payload_ty.hasRuntimeBits()) {
5640 try f.writeCValue(writer, local, .Other);
5641 try writer.writeAll(" = ");
5642 try f.writeCValue(writer, operand, .Other);
5643 try writer.writeAll(";\n");
5644 return local;
5570 const writer = f.object.writer();
5571 const local = try f.allocLocal(inst, inst_ty);
5572 if (!repr_is_err) {
5573 const a = try Assignment.start(f, writer, payload_ty);
5574 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5575 try a.assign(f, writer);
5576 try f.object.dg.renderValue(writer, payload_ty, Value.undef, .Other);
5577 try a.end(f, writer);
56455578 }
5646
56475579 {
5648 // TODO: set the payload to undefined
5649 //try f.writeCValue(writer, local, .Other);
5580 const a = try Assignment.start(f, writer, err_ty);
5581 if (repr_is_err)
5582 try f.writeCValue(writer, local, .Other)
5583 else
5584 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5585 try a.assign(f, writer);
5586 try f.writeCValue(writer, err, .Other);
5587 try a.end(f, writer);
56505588 }
5651 try f.writeCValue(writer, local, .Other);
5652 try writer.writeAll(".error = ");
5653 try f.writeCValue(writer, operand, .Other);
5654 try writer.writeAll(";\n");
56555589 return local;
56565590}
56575591
......@@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
57115645 const inst_ty = f.air.typeOfIndex(inst);
57125646 const payload_ty = inst_ty.errorUnionPayload();
57135647 const payload = try f.resolveInst(ty_op.operand);
5648 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5649 const err_ty = inst_ty.errorUnionSet();
57145650 try reap(f, inst, &.{ty_op.operand});
57155651
5716 const target = f.object.dg.module.getTarget();
5717 const is_array = lowersToArray(payload_ty, target);
5718
57195652 const writer = f.object.writer();
57205653 const local = try f.allocLocal(inst, inst_ty);
5721 if (!is_array) {
5722 try f.writeCValue(writer, local, .Other);
5723 try writer.writeAll(".payload = ");
5654 if (!repr_is_err) {
5655 const a = try Assignment.start(f, writer, payload_ty);
5656 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5657 try a.assign(f, writer);
57245658 try f.writeCValue(writer, payload, .Other);
5725 try writer.writeAll("; ");
5659 try a.end(f, writer);
57265660 }
5727 try f.writeCValue(writer, local, .Other);
5728 try writer.writeAll(".error = 0;\n");
5729 if (is_array) {
5730 try writer.writeAll("memcpy(");
5731 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5732 try writer.writeAll(", ");
5733 try f.writeCValue(writer, payload, .FunctionArgument);
5734 try writer.writeAll(", sizeof(");
5735 try f.renderType(writer, payload_ty);
5736 try writer.writeAll("));\n");
5661 {
5662 const a = try Assignment.start(f, writer, err_ty);
5663 if (repr_is_err)
5664 try f.writeCValue(writer, local, .Other)
5665 else
5666 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5667 try a.assign(f, writer);
5668 try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other);
5669 try a.end(f, writer);
57375670 }
57385671 return local;
57395672}
......@@ -5885,7 +5818,7 @@ fn airUnBuiltinCall(
58855818
58865819 const writer = f.object.writer();
58875820 const local = try f.allocLocal(inst, inst_ty);
5888 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5821 const v = try Vectorize.start(f, inst, writer, operand_ty);
58895822 if (!ref_ret) {
58905823 try f.writeCValue(writer, local, .Other);
58915824 try v.elem(f, writer);
......@@ -5934,7 +5867,7 @@ fn airBinBuiltinCall(
59345867 const writer = f.object.writer();
59355868 const local = try f.allocLocal(inst, inst_ty);
59365869 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
5937 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5870 const v = try Vectorize.start(f, inst, writer, operand_ty);
59385871 if (!ref_ret) {
59395872 try f.writeCValue(writer, local, .Other);
59405873 try v.elem(f, writer);
......@@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall(
59825915
59835916 const writer = f.object.writer();
59845917 const local = try f.allocLocal(inst, inst_ty);
5985 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5918 const v = try Vectorize.start(f, inst, writer, operand_ty);
59865919 if (!ref_ret) {
59875920 try f.writeCValue(writer, local, .Other);
59885921 try v.elem(f, writer);
......@@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
62626195 const union_ptr = try f.resolveInst(bin_op.lhs);
62636196 const new_tag = try f.resolveInst(bin_op.rhs);
62646197 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6265 const writer = f.object.writer();
62666198
6267 const union_ty = f.air.typeOf(bin_op.lhs).childType();
62686199 const target = f.object.dg.module.getTarget();
6200 const union_ty = f.air.typeOf(bin_op.lhs).childType();
62696201 const layout = union_ty.unionGetLayout(target);
62706202 if (layout.tag_size == 0) return .none;
6203 const tag_ty = union_ty.unionTagTypeSafety().?;
62716204
6272 try writer.writeByte('(');
6273 try f.writeCValue(writer, union_ptr, .Other);
6274 try writer.writeAll(")->tag = ");
6205 const writer = f.object.writer();
6206 const a = try Assignment.start(f, writer, tag_ty);
6207 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });
6208 try a.assign(f, writer);
62756209 try f.writeCValue(writer, new_tag, .Other);
6276 try writer.writeAll(";\n");
6277
6210 try a.end(f, writer);
62786211 return .none;
62796212}
62806213
......@@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
62846217 const operand = try f.resolveInst(ty_op.operand);
62856218 try reap(f, inst, &.{ty_op.operand});
62866219
6287 const un_ty = f.air.typeOf(ty_op.operand);
6288
6220 const union_ty = f.air.typeOf(ty_op.operand);
62896221 const target = f.object.dg.module.getTarget();
6290 const layout = un_ty.unionGetLayout(target);
6222 const layout = union_ty.unionGetLayout(target);
62916223 if (layout.tag_size == 0) return .none;
62926224
62936225 const inst_ty = f.air.typeOfIndex(inst);
62946226 const writer = f.object.writer();
62956227 const local = try f.allocLocal(inst, inst_ty);
6228 const a = try Assignment.start(f, writer, inst_ty);
62966229 try f.writeCValue(writer, local, .Other);
6297
6298 try writer.writeAll(" = ");
6299 try f.writeCValue(writer, operand, .Other);
6300 try writer.writeAll(".tag;\n");
6230 try a.assign(f, writer);
6231 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });
6232 try a.end(f, writer);
63016233 return local;
63026234}
63036235
......@@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
63506282
63516283 const writer = f.object.writer();
63526284 const local = try f.allocLocal(inst, inst_ty);
6353 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6285 const v = try Vectorize.start(f, inst, writer, inst_ty);
63546286 if (need_memcpy) try writer.writeAll("memcpy(&");
63556287 try f.writeCValue(writer, local, .Other);
63566288 try v.elem(f, writer);
......@@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
63806312
63816313 const writer = f.object.writer();
63826314 const local = try f.allocLocal(inst, inst_ty);
6383 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6315 const v = try Vectorize.start(f, inst, writer, inst_ty);
63846316 try f.writeCValue(writer, local, .Other);
63856317 try v.elem(f, writer);
63866318 try writer.writeAll(" = ");
......@@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
65476479 }, .Initializer);
65486480 try writer.writeAll(";\n");
65496481
6550 const v = try Vectorizer.start(f, inst, writer, operand_ty);
6482 const v = try Vectorize.start(f, inst, writer, operand_ty);
65516483 try f.writeCValue(writer, accum, .Other);
65526484 switch (op) {
65536485 .float_op => |func| {
......@@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
66216553 switch (inst_ty.zigTypeTag()) {
66226554 .Array, .Vector => {
66236555 const elem_ty = inst_ty.childType();
6624
6625 const is_array = lowersToArray(elem_ty, target);
6626 const need_memcpy = is_array;
6627 if (need_memcpy) {
6628 for (resolved_elements, 0..) |element, i| {
6629 try writer.writeAll("memcpy(");
6630 try f.writeCValue(writer, local, .Other);
6631 try writer.print("[{d}]", .{i});
6632 try writer.writeAll(", ");
6633 try f.writeCValue(writer, element, .Other);
6634 try writer.writeAll(", sizeof(");
6635 try f.renderType(writer, elem_ty);
6636 try writer.writeAll("))");
6637 try writer.writeAll(";\n");
6638 }
6639 assert(inst_ty.sentinel() == null);
6640 } else {
6641 for (resolved_elements, 0..) |element, i| {
6642 try f.writeCValue(writer, local, .Other);
6643 try writer.print("[{d}] = ", .{i});
6644 try f.writeCValue(writer, element, .Other);
6645 try writer.writeAll(";\n");
6646 }
6647 if (inst_ty.sentinel()) |sentinel| {
6648 try f.writeCValue(writer, local, .Other);
6649 try writer.print("[{d}] = ", .{resolved_elements.len});
6650 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6651 try writer.writeAll(";\n");
6652 }
6556 const a = try Assignment.init(f, elem_ty);
6557 for (resolved_elements, 0..) |element, i| {
6558 try a.restart(f, writer);
6559 try f.writeCValue(writer, local, .Other);
6560 try writer.print("[{d}]", .{i});
6561 try a.assign(f, writer);
6562 try f.writeCValue(writer, element, .Other);
6563 try a.end(f, writer);
6564 }
6565 if (inst_ty.sentinel()) |sentinel| {
6566 try a.restart(f, writer);
6567 try f.writeCValue(writer, local, .Other);
6568 try writer.print("[{d}]", .{resolved_elements.len});
6569 try a.assign(f, writer);
6570 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6571 try a.end(f, writer);
66536572 }
66546573 },
66556574 .Struct => switch (inst_ty.containerLayout()) {
6656 .Auto, .Extern => {
6657 try f.writeCValue(writer, local, .Other);
6658 try writer.writeAll(" = (");
6659 try f.renderType(writer, inst_ty);
6660 try writer.writeAll(")");
6661 try writer.writeByte('{');
6662 var empty = true;
6663 for (elements, resolved_elements, 0..) |element, resolved_element, field_i| {
6664 if (inst_ty.structFieldValueComptime(field_i)) |_| continue;
6665
6666 if (!empty) try writer.writeAll(", ");
6667
6668 const field_name: CValue = if (inst_ty.isSimpleTuple())
6669 .{ .field = field_i }
6670 else
6671 .{ .identifier = inst_ty.structFieldName(field_i) };
6672 try writer.writeByte('.');
6673 try f.object.dg.writeCValue(writer, field_name);
6674 try writer.writeAll(" = ");
6675
6676 const element_ty = f.air.typeOf(element);
6677 try f.writeCValue(writer, switch (element_ty.zigTypeTag()) {
6678 .Array => .{ .undef = element_ty },
6679 else => resolved_element,
6680 }, .Initializer);
6681 empty = false;
6682 }
6683 try writer.writeAll("};\n");
6684
6685 for (elements, resolved_elements, 0..) |element, resolved_element, field_i| {
6686 if (inst_ty.structFieldValueComptime(field_i)) |_| continue;
6687
6688 const element_ty = f.air.typeOf(element);
6689 if (element_ty.zigTypeTag() != .Array) continue;
6690
6691 const field_name: CValue = if (inst_ty.isSimpleTuple())
6692 .{ .field = field_i }
6693 else
6694 .{ .identifier = inst_ty.structFieldName(field_i) };
6575 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {
6576 if (inst_ty.structFieldIsComptime(field_i)) continue;
6577 const field_ty = inst_ty.structFieldType(field_i);
6578 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
66956579
6696 try writer.writeAll(";\n");
6697 try writer.writeAll("memcpy(");
6698 try f.writeCValueMember(writer, local, field_name);
6699 try writer.writeAll(", ");
6700 try f.writeCValue(writer, resolved_element, .FunctionArgument);
6701 try writer.writeAll(", sizeof(");
6702 try f.renderType(writer, element_ty);
6703 try writer.writeAll("));\n");
6704 }
6580 const a = try Assignment.start(f, writer, field_ty);
6581 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())
6582 .{ .field = field_i }
6583 else
6584 .{ .identifier = inst_ty.structFieldName(field_i) });
6585 try a.assign(f, writer);
6586 try f.writeCValue(writer, element, .Other);
6587 try a.end(f, writer);
67056588 },
67066589 .Packed => {
67076590 try f.writeCValue(writer, local, .Other);
......@@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67186601 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
67196602
67206603 var empty = true;
6721 for (0..elements.len) |index| {
6722 const field_ty = inst_ty.structFieldType(index);
6604 for (0..elements.len) |field_i| {
6605 if (inst_ty.structFieldIsComptime(field_i)) continue;
6606 const field_ty = inst_ty.structFieldType(field_i);
67236607 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67246608
67256609 if (!empty) {
......@@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67306614 empty = false;
67316615 }
67326616 empty = true;
6733 for (resolved_elements, 0..) |element, index| {
6734 const field_ty = inst_ty.structFieldType(index);
6617 for (resolved_elements, 0..) |element, field_i| {
6618 if (inst_ty.structFieldIsComptime(field_i)) continue;
6619 const field_ty = inst_ty.structFieldType(field_i);
67356620 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67366621
67376622 if (!empty) try writer.writeAll(", ");
......@@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
67846669 const target = f.object.dg.module.getTarget();
67856670 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
67866671 const field_name = union_obj.fields.keys()[extra.field_index];
6672 const payload_ty = f.air.typeOf(extra.init);
67876673 const payload = try f.resolveInst(extra.init);
67886674 try reap(f, inst, &.{extra.init});
67896675
......@@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
68116697 var int_pl: Value.Payload.U64 = undefined;
68126698 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
68136699
6814 try f.writeCValue(writer, local, .Other);
6815 try writer.print(".tag = {}; ", .{try f.fmtIntLiteral(tag_ty, int_val)});
6700 const a = try Assignment.start(f, writer, tag_ty);
6701 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
6702 try a.assign(f, writer);
6703 try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
6704 try a.end(f, writer);
68166705 }
68176706 break :field .{ .payload_identifier = field_name };
68186707 } else .{ .identifier = field_name };
68196708
6709 const a = try Assignment.start(f, writer, payload_ty);
68206710 try f.writeCValueMember(writer, local, field);
6821 try writer.writeAll(" = ");
6711 try a.assign(f, writer);
68226712 try f.writeCValue(writer, payload, .Other);
6823 try writer.writeAll(";\n");
6713 try a.end(f, writer);
68246714 return local;
68256715}
68266716
......@@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
68876777
68886778 const writer = f.object.writer();
68896779 const local = try f.allocLocal(inst, operand_ty);
6890 const v = try Vectorizer.start(f, inst, writer, operand_ty);
6780 const v = try Vectorize.start(f, inst, writer, operand_ty);
68916781 try f.writeCValue(writer, local, .Other);
68926782 try v.elem(f, writer);
68936783 try writer.writeAll(" = zig_neg_");
......@@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
69126802
69136803 const writer = f.object.writer();
69146804 const local = try f.allocLocal(inst, inst_ty);
6915 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6805 const v = try Vectorize.start(f, inst, writer, inst_ty);
69166806 try f.writeCValue(writer, local, .Other);
69176807 try v.elem(f, writer);
69186808 try writer.writeAll(" = zig_libc_name_");
......@@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
69406830
69416831 const writer = f.object.writer();
69426832 const local = try f.allocLocal(inst, inst_ty);
6943 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6833 const v = try Vectorize.start(f, inst, writer, inst_ty);
69446834 try f.writeCValue(writer, local, .Other);
69456835 try v.elem(f, writer);
69466836 try writer.writeAll(" = zig_libc_name_");
......@@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
69736863
69746864 const writer = f.object.writer();
69756865 const local = try f.allocLocal(inst, inst_ty);
6976 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6866 const v = try Vectorize.start(f, inst, writer, inst_ty);
69776867 try f.writeCValue(writer, local, .Other);
69786868 try v.elem(f, writer);
69796869 try writer.writeAll(" = zig_libc_name_");
......@@ -7480,10 +7370,57 @@ fn formatIntLiteral(
74807370 try data.cty.renderLiteralSuffix(writer);
74817371}
74827372
7483const Vectorizer = struct {
7373const Assignment = struct {
7374 cty: CType.Index,
7375
7376 pub fn init(f: *Function, ty: Type) !Assignment {
7377 return .{ .cty = try f.typeToIndex(ty, .complete) };
7378 }
7379
7380 pub fn start(f: *Function, writer: anytype, ty: Type) !Assignment {
7381 const self = try init(f, ty);
7382 try self.restart(f, writer);
7383 return self;
7384 }
7385
7386 pub fn restart(self: Assignment, f: *Function, writer: anytype) !void {
7387 switch (self.strategy(f)) {
7388 .assign => {},
7389 .memcpy => try writer.writeAll("memcpy("),
7390 }
7391 }
7392
7393 pub fn assign(self: Assignment, f: *Function, writer: anytype) !void {
7394 switch (self.strategy(f)) {
7395 .assign => try writer.writeAll(" = "),
7396 .memcpy => try writer.writeAll(", "),
7397 }
7398 }
7399
7400 pub fn end(self: Assignment, f: *Function, writer: anytype) !void {
7401 switch (self.strategy(f)) {
7402 .assign => {},
7403 .memcpy => {
7404 try writer.writeAll(", sizeof(");
7405 try f.renderCType(writer, self.cty);
7406 try writer.writeAll("))");
7407 },
7408 }
7409 try writer.writeAll(";\n");
7410 }
7411
7412 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
7413 return switch (f.indexToCType(self.cty).tag()) {
7414 else => .assign,
7415 .array, .vector => .memcpy,
7416 };
7417 }
7418};
7419
7420const Vectorize = struct {
74847421 index: CValue = .none,
74857422
7486 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorizer {
7423 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
74877424 return if (ty.zigTypeTag() == .Vector) index: {
74887425 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };
74897426
......@@ -7504,7 +7441,7 @@ const Vectorizer = struct {
75047441 } else .{};
75057442 }
75067443
7507 pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void {
7444 pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void {
75087445 if (self.index != .none) {
75097446 try writer.writeByte('[');
75107447 try f.writeCValue(writer, self.index, .Other);
......@@ -7512,7 +7449,7 @@ const Vectorizer = struct {
75127449 }
75137450 }
75147451
7515 pub fn end(self: Vectorizer, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {
7452 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {
75167453 if (self.index != .none) {
75177454 f.object.indent_writer.popIndent();
75187455 try writer.writeAll("}\n");
......@@ -7521,11 +7458,6 @@ const Vectorizer = struct {
75217458 }
75227459};
75237460
7524fn isByRef(ty: Type) bool {
7525 _ = ty;
7526 return false;
7527}
7528
75297461const LowerFnRetTyBuffer = struct {
75307462 names: [1][]const u8,
75317463 types: [1]Type,
......@@ -7557,29 +7489,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool {
75577489 };
75587490}
75597491
7560fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo {
7561 if (!lowersToArray(ty, target)) return null;
7562
7563 switch (ty.zigTypeTag()) {
7564 .Array, .Vector => return ty.arrayInfo(),
7565 else => {
7566 const abi_size = ty.abiSize(target);
7567 const abi_align = ty.abiAlignment(target);
7568 return Type.ArrayInfo{
7569 .elem_type = switch (abi_align) {
7570 1 => Type.u8,
7571 2 => Type.u16,
7572 4 => Type.u32,
7573 8 => Type.u64,
7574 16 => Type.initTag(.u128),
7575 else => unreachable,
7576 },
7577 .len = @divExact(abi_size, abi_align),
7578 };
7579 },
7580 }
7581}
7582
75837492fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void {
75847493 assert(operands.len <= Liveness.bpi - 1);
75857494 var tomb_bits = f.liveness.getTombBits(inst);
test/behavior/packed-struct.zig+12
......@@ -615,3 +615,15 @@ test "pointer to container level packed struct field" {
615615 @ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true;
616616 try expect(S.arr[0] == 0x10000000);
617617}
618
619test "store undefined to packed result location" {
620 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
621 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
622 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
623 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
624 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
625
626 var x: u4 = 0;
627 var s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined };
628 try expectEqual(x, s.x);
629}
test/tests.zig-7
......@@ -962,13 +962,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
962962 if (test_target.use_llvm == false and mem.eql(u8, options.name, "std"))
963963 continue;
964964
965 // TODO get std lib tests passing for the C backend
966 if (test_target.target.ofmt == std.Target.ObjectFormat.c and
967 mem.eql(u8, options.name, "std"))
968 {
969 continue;
970 }
971
972965 const want_this_mode = for (options.optimize_modes) |m| {
973966 if (m == test_target.optimize_mode) break true;
974967 } else false;