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 {...@@ -1635,6 +1635,8 @@ fn testStaticBitSet(comptime Set: type) !void {
1635}1635}
16361636
1637test "IntegerBitSet" {1637test "IntegerBitSet" {
1638 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
1639
1638 try testStaticBitSet(IntegerBitSet(0));1640 try testStaticBitSet(IntegerBitSet(0));
1639 try testStaticBitSet(IntegerBitSet(1));1641 try testStaticBitSet(IntegerBitSet(1));
1640 try testStaticBitSet(IntegerBitSet(2));1642 try testStaticBitSet(IntegerBitSet(2));
lib/std/crypto/aes.zig+2-1
...@@ -5,7 +5,8 @@ const testing = std.testing;...@@ -5,7 +5,8 @@ const testing = std.testing;
5const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);5const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);
6const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);6const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
7const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);7const 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: {
9 break :impl @import("aes/aesni.zig");10 break :impl @import("aes/aesni.zig");
10} else if (builtin.cpu.arch == .aarch64 and has_armaes)11} else if (builtin.cpu.arch == .aarch64 and has_armaes)
11impl: {12impl: {
lib/std/crypto/aes_ocb.zig+8
...@@ -257,6 +257,8 @@ inline fn xorWith(x: *Block, y: Block) void {...@@ -257,6 +257,8 @@ inline fn xorWith(x: *Block, y: Block) void {
257const hexToBytes = std.fmt.hexToBytes;257const hexToBytes = std.fmt.hexToBytes;
258258
259test "AesOcb test vector 1" {259test "AesOcb test vector 1" {
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
261
260 var k: [Aes128Ocb.key_length]u8 = undefined;262 var k: [Aes128Ocb.key_length]u8 = undefined;
261 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;263 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
262 var tag: [Aes128Ocb.tag_length]u8 = undefined;264 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -274,6 +276,8 @@ test "AesOcb test vector 1" {...@@ -274,6 +276,8 @@ test "AesOcb test vector 1" {
274}276}
275277
276test "AesOcb test vector 2" {278test "AesOcb test vector 2" {
279 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
280
277 var k: [Aes128Ocb.key_length]u8 = undefined;281 var k: [Aes128Ocb.key_length]u8 = undefined;
278 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;282 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
279 var tag: [Aes128Ocb.tag_length]u8 = undefined;283 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -293,6 +297,8 @@ test "AesOcb test vector 2" {...@@ -293,6 +297,8 @@ test "AesOcb test vector 2" {
293}297}
294298
295test "AesOcb test vector 3" {299test "AesOcb test vector 3" {
300 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
301
296 var k: [Aes128Ocb.key_length]u8 = undefined;302 var k: [Aes128Ocb.key_length]u8 = undefined;
297 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;303 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
298 var tag: [Aes128Ocb.tag_length]u8 = undefined;304 var tag: [Aes128Ocb.tag_length]u8 = undefined;
...@@ -315,6 +321,8 @@ test "AesOcb test vector 3" {...@@ -315,6 +321,8 @@ test "AesOcb test vector 3" {
315}321}
316322
317test "AesOcb test vector 4" {323test "AesOcb test vector 4" {
324 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
325
318 var k: [Aes128Ocb.key_length]u8 = undefined;326 var k: [Aes128Ocb.key_length]u8 = undefined;
319 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;327 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
320 var tag: [Aes128Ocb.tag_length]u8 = undefined;328 var tag: [Aes128Ocb.tag_length]u8 = undefined;
lib/std/crypto/ecdsa.zig+13
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const crypto = std.crypto;3const crypto = std.crypto;
3const fmt = std.fmt;4const fmt = std.fmt;
...@@ -373,6 +374,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {...@@ -373,6 +374,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
373}374}
374375
375test "ECDSA - Basic operations over EcdsaP384Sha384" {376test "ECDSA - Basic operations over EcdsaP384Sha384" {
377 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
378
376 const Scheme = EcdsaP384Sha384;379 const Scheme = EcdsaP384Sha384;
377 const kp = try Scheme.KeyPair.create(null);380 const kp = try Scheme.KeyPair.create(null);
378 const msg = "test";381 const msg = "test";
...@@ -387,6 +390,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" {...@@ -387,6 +390,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" {
387}390}
388391
389test "ECDSA - Basic operations over Secp256k1" {392test "ECDSA - Basic operations over Secp256k1" {
393 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
394
390 const Scheme = EcdsaSecp256k1Sha256oSha256;395 const Scheme = EcdsaSecp256k1Sha256oSha256;
391 const kp = try Scheme.KeyPair.create(null);396 const kp = try Scheme.KeyPair.create(null);
392 const msg = "test";397 const msg = "test";
...@@ -401,6 +406,8 @@ test "ECDSA - Basic operations over Secp256k1" {...@@ -401,6 +406,8 @@ test "ECDSA - Basic operations over Secp256k1" {
401}406}
402407
403test "ECDSA - Basic operations over EcdsaP384Sha256" {408test "ECDSA - Basic operations over EcdsaP384Sha256" {
409 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
410
404 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);411 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
405 const kp = try Scheme.KeyPair.create(null);412 const kp = try Scheme.KeyPair.create(null);
406 const msg = "test";413 const msg = "test";
...@@ -415,6 +422,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha256" {...@@ -415,6 +422,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha256" {
415}422}
416423
417test "ECDSA - Verifying a existing signature with EcdsaP384Sha256" {424test "ECDSA - Verifying a existing signature with EcdsaP384Sha256" {
425 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
426
418 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);427 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
419 // zig fmt: off428 // zig fmt: off
420 const sk_bytes = [_]u8{429 const sk_bytes = [_]u8{
...@@ -457,6 +466,8 @@ const TestVector = struct {...@@ -457,6 +466,8 @@ const TestVector = struct {
457};466};
458467
459test "ECDSA - Test vectors from Project Wycheproof" {468test "ECDSA - Test vectors from Project Wycheproof" {
469 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
470
460 const vectors = [_]TestVector{471 const vectors = [_]TestVector{
461 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", .result = .valid },472 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", .result = .valid },
462 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", .result = .acceptable },473 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", .result = .acceptable },
...@@ -869,6 +880,8 @@ fn tvTry(vector: TestVector) !void {...@@ -869,6 +880,8 @@ fn tvTry(vector: TestVector) !void {
869}880}
870881
871test "ECDSA - Sec1 encoding/decoding" {882test "ECDSA - Sec1 encoding/decoding" {
883 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
884
872 const Scheme = EcdsaP384Sha384;885 const Scheme = EcdsaP384Sha384;
873 const kp = try Scheme.KeyPair.create(null);886 const kp = try Scheme.KeyPair.create(null);
874 const pk = kp.public_key;887 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 {...@@ -248,7 +248,8 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type {
248 const has_pclmul = std.Target.x86.featureSetHas(builtin.cpu.features, .pclmul);248 const has_pclmul = std.Target.x86.featureSetHas(builtin.cpu.features, .pclmul);
249 const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);249 const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
250 const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);250 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: {
252 break :impl clmulPclmul;253 break :impl clmulPclmul;
253 } else if (builtin.cpu.arch == .aarch64 and has_armaes) impl: {254 } else if (builtin.cpu.arch == .aarch64 and has_armaes) impl: {
254 break :impl clmulPmull;255 break :impl clmulPmull;
lib/std/crypto/pcurves/p384.zig+2
...@@ -474,5 +474,7 @@ pub const AffineCoordinates = struct {...@@ -474,5 +474,7 @@ pub const AffineCoordinates = struct {
474};474};
475475
476test "p384" {476test "p384" {
477 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
478
477 _ = @import("tests/p384.zig");479 _ = @import("tests/p384.zig");
478}480}
lib/std/crypto/pcurves/secp256k1.zig+2
...@@ -552,5 +552,7 @@ pub const AffineCoordinates = struct {...@@ -552,5 +552,7 @@ pub const AffineCoordinates = struct {
552};552};
553553
554test "secp256k1" {554test "secp256k1" {
555 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
556
555 _ = @import("tests/secp256k1.zig");557 _ = @import("tests/secp256k1.zig");
556}558}
lib/std/crypto/sha2.zig+2-1
...@@ -242,7 +242,8 @@ fn Sha2x32(comptime params: Sha2Params32) type {...@@ -242,7 +242,8 @@ fn Sha2x32(comptime params: Sha2Params32) type {
242 d.s[4..8].* = y +% @as(v4u32, d.s[4..8].*);242 d.s[4..8].* = y +% @as(v4u32, d.s[4..8].*);
243 return;243 return;
244 },244 },
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)) {
246 var x: v4u32 = [_]u32{ d.s[5], d.s[4], d.s[1], d.s[0] };247 var x: v4u32 = [_]u32{ d.s[5], d.s[4], d.s[1], d.s[0] };
247 var y: v4u32 = [_]u32{ d.s[7], d.s[6], d.s[3], d.s[2] };248 var y: v4u32 = [_]u32{ d.s[7], d.s[6], d.s[3], d.s[2] };
248 const s_v = @ptrCast(*[16]v4u32, &s);249 const s_v = @ptrCast(*[16]v4u32, &s);
lib/std/debug.zig+2
...@@ -2189,6 +2189,8 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {...@@ -2189,6 +2189,8 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
2189}2189}
21902190
2191test "manage resources correctly" {2191test "manage resources correctly" {
2192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // error.UnsupportedBackend
2193
2192 if (builtin.os.tag == .wasi) return error.SkipZigTest;2194 if (builtin.os.tag == .wasi) return error.SkipZigTest;
21932195
2194 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86_64) {2196 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" {...@@ -915,6 +915,8 @@ test "big.int mul multi-single" {
915}915}
916916
917test "big.int mul multi-multi" {917test "big.int mul multi-multi" {
918 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
919
918 var op1: u256 = 0x998888efefefefefefefef;920 var op1: u256 = 0x998888efefefefefefefef;
919 var op2: u256 = 0x333000abababababababab;921 var op2: u256 = 0x333000abababababababab;
920 var a = try Managed.initSet(testing.allocator, op1);922 var a = try Managed.initSet(testing.allocator, op1);
...@@ -1034,6 +1036,8 @@ test "big.int mulWrap single-single signed" {...@@ -1034,6 +1036,8 @@ test "big.int mulWrap single-single signed" {
1034}1036}
10351037
1036test "big.int mulWrap multi-multi unsigned" {1038test "big.int mulWrap multi-multi unsigned" {
1039 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1040
1037 var op1: u256 = 0x998888efefefefefefefef;1041 var op1: u256 = 0x998888efefefefefefefef;
1038 var op2: u256 = 0x333000abababababababab;1042 var op2: u256 = 0x333000abababababababab;
1039 var a = try Managed.initSet(testing.allocator, op1);1043 var a = try Managed.initSet(testing.allocator, op1);
...@@ -1049,6 +1053,8 @@ test "big.int mulWrap multi-multi unsigned" {...@@ -1049,6 +1053,8 @@ test "big.int mulWrap multi-multi unsigned" {
1049}1053}
10501054
1051test "big.int mulWrap multi-multi signed" {1055test "big.int mulWrap multi-multi signed" {
1056 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1057
1052 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);1058 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);
1053 defer a.deinit();1059 defer a.deinit();
1054 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));1060 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));
...@@ -1252,6 +1258,8 @@ test "big.int div q=0 alias" {...@@ -1252,6 +1258,8 @@ test "big.int div q=0 alias" {
1252}1258}
12531259
1254test "big.int div multi-multi q < r" {1260test "big.int div multi-multi q < r" {
1261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1262
1255 const op1 = 0x1ffffffff0078f432;1263 const op1 = 0x1ffffffff0078f432;
1256 const op2 = 0x1ffffffff01000000;1264 const op2 = 0x1ffffffff01000000;
1257 var a = try Managed.initSet(testing.allocator, op1);1265 var a = try Managed.initSet(testing.allocator, op1);
...@@ -1608,6 +1616,8 @@ test "big.int div floor positive close to zero" {...@@ -1608,6 +1616,8 @@ test "big.int div floor positive close to zero" {
1608}1616}
16091617
1610test "big.int div multi-multi with rem" {1618test "big.int div multi-multi with rem" {
1619 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1620
1611 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);1621 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
1612 defer a.deinit();1622 defer a.deinit();
1613 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);1623 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
...@@ -1624,6 +1634,8 @@ test "big.int div multi-multi with rem" {...@@ -1624,6 +1634,8 @@ test "big.int div multi-multi with rem" {
1624}1634}
16251635
1626test "big.int div multi-multi no rem" {1636test "big.int div multi-multi no rem" {
1637 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1638
1627 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);1639 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
1628 defer a.deinit();1640 defer a.deinit();
1629 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);1641 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
...@@ -1640,6 +1652,8 @@ test "big.int div multi-multi no rem" {...@@ -1640,6 +1652,8 @@ test "big.int div multi-multi no rem" {
1640}1652}
16411653
1642test "big.int div multi-multi (2 branch)" {1654test "big.int div multi-multi (2 branch)" {
1655 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1656
1643 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);1657 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
1644 defer a.deinit();1658 defer a.deinit();
1645 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);1659 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
...@@ -1656,6 +1670,8 @@ test "big.int div multi-multi (2 branch)" {...@@ -1656,6 +1670,8 @@ test "big.int div multi-multi (2 branch)" {
1656}1670}
16571671
1658test "big.int div multi-multi (3.1/3.3 branch)" {1672test "big.int div multi-multi (3.1/3.3 branch)" {
1673 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1674
1659 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);1675 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
1660 defer a.deinit();1676 defer a.deinit();
1661 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);1677 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
...@@ -1672,6 +1688,8 @@ test "big.int div multi-multi (3.1/3.3 branch)" {...@@ -1672,6 +1688,8 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
1672}1688}
16731689
1674test "big.int div multi-single zero-limb trailing" {1690test "big.int div multi-single zero-limb trailing" {
1691 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1692
1675 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);1693 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
1676 defer a.deinit();1694 defer a.deinit();
1677 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);1695 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
...@@ -1690,6 +1708,8 @@ test "big.int div multi-single zero-limb trailing" {...@@ -1690,6 +1708,8 @@ test "big.int div multi-single zero-limb trailing" {
1690}1708}
16911709
1692test "big.int div multi-multi zero-limb trailing (with rem)" {1710test "big.int div multi-multi zero-limb trailing (with rem)" {
1711 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1712
1693 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);1713 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
1694 defer a.deinit();1714 defer a.deinit();
1695 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);1715 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
...@@ -1709,6 +1729,8 @@ test "big.int div multi-multi zero-limb trailing (with rem)" {...@@ -1709,6 +1729,8 @@ test "big.int div multi-multi zero-limb trailing (with rem)" {
1709}1729}
17101730
1711test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {1731test "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
1712 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);1734 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
1713 defer a.deinit();1735 defer a.deinit();
1714 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);1736 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...@@ -1728,6 +1750,8 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li
1728}1750}
17291751
1730test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {1752test "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
1731 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);1755 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
1732 defer a.deinit();1756 defer a.deinit();
1733 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);1757 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
...@@ -2486,6 +2510,8 @@ test "big.int gcd non-one large" {...@@ -2486,6 +2510,8 @@ test "big.int gcd non-one large" {
2486}2510}
24872511
2488test "big.int gcd large multi-limb result" {2512test "big.int gcd large multi-limb result" {
2513 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2514
2489 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);2515 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
2490 defer a.deinit();2516 defer a.deinit();
2491 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);2517 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
lib/std/mem.zig+6
...@@ -1504,6 +1504,8 @@ test "comptime read/write int" {...@@ -1504,6 +1504,8 @@ test "comptime read/write int" {
1504}1504}
15051505
1506test "readIntBig and readIntLittle" {1506test "readIntBig and readIntLittle" {
1507 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1508
1507 try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0);1509 try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0);
1508 try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0);1510 try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0);
15091511
...@@ -1795,6 +1797,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value...@@ -1795,6 +1797,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
1795}1797}
17961798
1797test "writeIntBig and writeIntLittle" {1799test "writeIntBig and writeIntLittle" {
1800 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1801
1798 var buf0: [0]u8 = undefined;1802 var buf0: [0]u8 = undefined;
1799 var buf1: [1]u8 = undefined;1803 var buf1: [1]u8 = undefined;
1800 var buf2: [2]u8 = undefined;1804 var buf2: [2]u8 = undefined;
...@@ -4011,6 +4015,8 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice...@@ -4011,6 +4015,8 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
4011}4015}
40124016
4013test "read/write(Var)PackedInt" {4017test "read/write(Var)PackedInt" {
4018 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
4019
4014 switch (builtin.cpu.arch) {4020 switch (builtin.cpu.arch) {
4015 // This test generates too much code to execute on WASI.4021 // This test generates too much code to execute on WASI.
4016 // LLVM backend fails with "too many locals: locals exceed maximum"4022 // 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 {...@@ -502,8 +502,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
502}502}
503503
504test "dl_iterate_phdr" {504test "dl_iterate_phdr" {
505 if (native_os == .windows or native_os == .wasi or native_os == .macos)505 if (builtin.object_format != .elf) return error.SkipZigTest;
506 return error.SkipZigTest;
507506
508 var counter: usize = 0;507 var counter: usize = 0;
509 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);508 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 {...@@ -90,6 +90,8 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {
90}90}
9191
92test "xoroshiro sequence" {92test "xoroshiro sequence" {
93 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
94
93 var r = Xoshiro256.init(0);95 var r = Xoshiro256.init(0);
9496
95 const seq1 = [_]u64{97 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...@@ -1972,6 +1972,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
1972 return 0;1972 return 0;
1973}1973}
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
1975static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {2212static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1976 uint8_t *res_bytes = res;2213 uint8_t *res_bytes = res;
1977 const uint8_t *lhs_bytes = lhs;2214 const uint8_t *lhs_bytes = lhs;
src/codegen/c.zig+385-476
...@@ -434,7 +434,7 @@ pub const Function = struct {...@@ -434,7 +434,7 @@ pub const Function = struct {
434 return f.object.dg.renderCType(w, t);434 return f.object.dg.renderCType(w, t);
435 }435 }
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 {
438 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);438 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
439 }439 }
440440
...@@ -811,11 +811,13 @@ pub const DeclGen = struct {...@@ -811,11 +811,13 @@ pub const DeclGen = struct {
811811
812 try writer.writeByte('{');812 try writer.writeByte('{');
813 var empty = true;813 var empty = true;
814 for (ty.structFields().values()) |field| {814 for (0..ty.structFieldCount()) |field_i| {
815 if (!field.ty.hasRuntimeBits()) continue;815 if (ty.structFieldIsComptime(field_i)) continue;
816 const field_ty = ty.structFieldType(field_i);
817 if (!field_ty.hasRuntimeBits()) continue;
816818
817 if (!empty) try writer.writeByte(',');819 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
820 empty = false;822 empty = false;
821 }823 }
...@@ -837,19 +839,27 @@ pub const DeclGen = struct {...@@ -837,19 +839,27 @@ pub const DeclGen = struct {
837 if (layout.tag_size != 0) {839 if (layout.tag_size != 0) {
838 try writer.writeAll(" .tag = ");840 try writer.writeAll(" .tag = ");
839 try dg.renderValue(writer, tag_ty, val, initializer_type);841 try dg.renderValue(writer, tag_ty, val, initializer_type);
840 try writer.writeByte(',');
841 }842 }
843 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
844 if (layout.tag_size != 0) try writer.writeByte(',');
842 try writer.writeAll(" .payload = {");845 try writer.writeAll(" .payload = {");
843 }846 }
844 for (ty.unionFields().values()) |field| {847 for (ty.unionFields().values()) |field| {
845 if (!field.ty.hasRuntimeBits()) continue;848 if (!field.ty.hasRuntimeBits()) continue;
846 try dg.renderValue(writer, field.ty, val, initializer_type);849 try dg.renderValue(writer, field.ty, val, initializer_type);
847 break;850 break;
848 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)});851 }
849 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');852 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
850 return writer.writeByte('}');853 return writer.writeByte('}');
851 },854 },
852 .ErrorUnion => {855 .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
853 if (!location.isInitializer()) {863 if (!location.isInitializer()) {
854 try writer.writeByte('(');864 try writer.writeByte('(');
855 try dg.renderType(writer, ty);865 try dg.renderType(writer, ty);
...@@ -857,18 +867,12 @@ pub const DeclGen = struct {...@@ -857,18 +867,12 @@ pub const DeclGen = struct {
857 }867 }
858868
859 try writer.writeAll("{ .payload = ");869 try writer.writeAll("{ .payload = ");
860 try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type);870 try dg.renderValue(writer, payload_ty, val, initializer_type);
861 return writer.print(", .error = {x} }}", .{871 try writer.writeAll(", .error = ");
862 try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other),872 try dg.renderValue(writer, error_ty, val, initializer_type);
863 });873 return writer.writeAll(" }");
864 },874 },
865 .Array, .Vector => {875 .Array, .Vector => {
866 if (!location.isInitializer()) {
867 try writer.writeByte('(');
868 try dg.renderType(writer, ty);
869 try writer.writeByte(')');
870 }
871
872 const ai = ty.arrayInfo();876 const ai = ty.arrayInfo();
873 if (ai.elem_type.eql(Type.u8, dg.module)) {877 if (ai.elem_type.eql(Type.u8, dg.module)) {
874 var literal = stringLiteral(writer);878 var literal = stringLiteral(writer);
...@@ -879,6 +883,12 @@ pub const DeclGen = struct {...@@ -879,6 +883,12 @@ pub const DeclGen = struct {
879 try literal.writeChar(0xaa);883 try literal.writeChar(0xaa);
880 return literal.end();884 return literal.end();
881 } else {885 } else {
886 if (!location.isInitializer()) {
887 try writer.writeByte('(');
888 try dg.renderType(writer, ty);
889 try writer.writeByte(')');
890 }
891
882 try writer.writeByte('{');892 try writer.writeByte('{');
883 const c_len = ty.arrayLenIncludingSentinel();893 const c_len = ty.arrayLenIncludingSentinel();
884 var index: u64 = 0;894 var index: u64 = 0;
...@@ -1199,23 +1209,20 @@ pub const DeclGen = struct {...@@ -1199,23 +1209,20 @@ pub const DeclGen = struct {
1199 try writer.writeAll(" }");1209 try writer.writeAll(" }");
1200 },1210 },
1201 .ErrorSet => {1211 .ErrorSet => {
1202 const error_name = if (val.castTag(.@"error")) |error_pl|1212 if (val.castTag(.@"error")) |error_pl| {
1203 error_pl.data.name1213 // Error values are already defined by genErrDecls.
1204 else1214 try writer.print("zig_error_{}", .{fmtIdent(error_pl.data.name)});
1205 dg.module.error_name_list.items[0];1215 } else {
1206 // Error values are already defined by genErrDecls.1216 try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, .Other)});
1207 try writer.print("zig_error_{}", .{fmtIdent(error_name)});1217 }
1208 },1218 },
1209 .ErrorUnion => {1219 .ErrorUnion => {
1210 const error_ty = ty.errorUnionSet();
1211 const payload_ty = ty.errorUnionPayload();1220 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()) {1224 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1214 // We use the error type directly as the type.1225 return dg.renderValue(writer, error_ty, error_val, location);
1215 if (val.errorUnionIsPayload()) {
1216 return try writer.writeByte('0');
1217 }
1218 return dg.renderValue(writer, error_ty, val, location);
1219 }1226 }
12201227
1221 if (!location.isInitializer()) {1228 if (!location.isInitializer()) {
...@@ -1225,8 +1232,6 @@ pub const DeclGen = struct {...@@ -1225,8 +1232,6 @@ pub const DeclGen = struct {
1225 }1232 }
12261233
1227 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef;1234 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
1230 try writer.writeAll("{ .payload = ");1235 try writer.writeAll("{ .payload = ");
1231 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);1236 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);
1232 try writer.writeAll(", .error = ");1237 try writer.writeAll(", .error = ");
...@@ -1290,9 +1295,10 @@ pub const DeclGen = struct {...@@ -1290,9 +1295,10 @@ pub const DeclGen = struct {
12901295
1291 try writer.writeByte('{');1296 try writer.writeByte('{');
1292 var empty = true;1297 var empty = true;
1293 for (field_vals, 0..) |field_val, field_index| {1298 for (field_vals, 0..) |field_val, field_i| {
1294 const field_ty = ty.structFieldType(field_index);1299 if (ty.structFieldIsComptime(field_i)) continue;
1295 if (!field_ty.hasRuntimeBits()) continue;1300 const field_ty = ty.structFieldType(field_i);
1301 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
12961302
1297 if (!empty) try writer.writeByte(',');1303 if (!empty) try writer.writeByte(',');
1298 try dg.renderValue(writer, field_ty, field_val, initializer_type);1304 try dg.renderValue(writer, field_ty, field_val, initializer_type);
...@@ -1315,8 +1321,9 @@ pub const DeclGen = struct {...@@ -1315,8 +1321,9 @@ pub const DeclGen = struct {
1315 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);1321 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
13161322
1317 var eff_num_fields: usize = 0;1323 var eff_num_fields: usize = 0;
1318 for (0..field_vals.len) |index| {1324 for (0..field_vals.len) |field_i| {
1319 const field_ty = ty.structFieldType(index);1325 if (ty.structFieldIsComptime(field_i)) continue;
1326 const field_ty = ty.structFieldType(field_i);
1320 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1327 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13211328
1322 eff_num_fields += 1;1329 eff_num_fields += 1;
...@@ -1337,8 +1344,9 @@ pub const DeclGen = struct {...@@ -1337,8 +1344,9 @@ pub const DeclGen = struct {
13371344
1338 var eff_index: usize = 0;1345 var eff_index: usize = 0;
1339 var needs_closing_paren = false;1346 var needs_closing_paren = false;
1340 for (field_vals, 0..) |field_val, index| {1347 for (field_vals, 0..) |field_val, field_i| {
1341 const field_ty = ty.structFieldType(index);1348 if (ty.structFieldIsComptime(field_i)) continue;
1349 const field_ty = ty.structFieldType(field_i);
1342 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1350 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13431351
1344 const cast_context = IntCastContext{ .value = .{ .value = field_val } };1352 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
...@@ -1365,8 +1373,9 @@ pub const DeclGen = struct {...@@ -1365,8 +1373,9 @@ pub const DeclGen = struct {
1365 try writer.writeByte('(');1373 try writer.writeByte('(');
1366 // a << a_off | b << b_off | c << c_off1374 // a << a_off | b << b_off | c << c_off
1367 var empty = true;1375 var empty = true;
1368 for (field_vals, 0..) |field_val, index| {1376 for (field_vals, 0..) |field_val, field_i| {
1369 const field_ty = ty.structFieldType(index);1377 if (ty.structFieldIsComptime(field_i)) continue;
1378 const field_ty = ty.structFieldType(field_i);
1370 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;1379 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13711380
1372 if (!empty) try writer.writeAll(" | ");1381 if (!empty) try writer.writeAll(" | ");
...@@ -1398,9 +1407,9 @@ pub const DeclGen = struct {...@@ -1398,9 +1407,9 @@ pub const DeclGen = struct {
1398 try writer.writeByte(')');1407 try writer.writeByte(')');
1399 }1408 }
14001409
1401 const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;1410 const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
1402 const field_ty = ty.unionFields().values()[index].ty;1411 const field_ty = ty.unionFields().values()[field_i].ty;
1403 const field_name = ty.unionFields().keys()[index];1412 const field_name = ty.unionFields().keys()[field_i];
1404 if (ty.containerLayout() == .Packed) {1413 if (ty.containerLayout() == .Packed) {
1405 if (field_ty.hasRuntimeBits()) {1414 if (field_ty.hasRuntimeBits()) {
1406 if (field_ty.isPtrAtRuntime()) {1415 if (field_ty.isPtrAtRuntime()) {
...@@ -1419,32 +1428,27 @@ pub const DeclGen = struct {...@@ -1419,32 +1428,27 @@ pub const DeclGen = struct {
1419 return;1428 return;
1420 }1429 }
14211430
1422 var has_payload_init = false;
1423 try writer.writeByte('{');1431 try writer.writeByte('{');
1424 if (ty.unionTagTypeSafety()) |tag_ty| {1432 if (ty.unionTagTypeSafety()) |tag_ty| {
1425 const layout = ty.unionGetLayout(target);1433 const layout = ty.unionGetLayout(target);
1426 if (layout.tag_size != 0) {1434 if (layout.tag_size != 0) {
1427 try writer.writeAll(".tag = ");1435 try writer.writeAll(" .tag = ");
1428 try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type);1436 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;
1434 }1437 }
1438 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
1439 if (layout.tag_size != 0) try writer.writeByte(',');
1440 try writer.writeAll(" .payload = {");
1435 }1441 }
1436
1437 var it = ty.unionFields().iterator();
1438 if (field_ty.hasRuntimeBits()) {1442 if (field_ty.hasRuntimeBits()) {
1439 try writer.print(".{ } = ", .{fmtIdent(field_name)});1443 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
1440 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);1444 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);
1441 } else while (it.next()) |field| {1445 try writer.writeByte(' ');
1442 if (!field.value_ptr.ty.hasRuntimeBits()) continue;1446 } else for (ty.unionFields().values()) |field| {
1443 try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)});1447 if (!field.ty.hasRuntimeBits()) continue;
1444 try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type);1448 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);
1445 break;1449 break;
1446 }1450 }
1447 if (has_payload_init) try writer.writeByte('}');1451 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
1448 try writer.writeByte('}');1452 try writer.writeByte('}');
1449 },1453 },
14501454
...@@ -1585,7 +1589,7 @@ pub const DeclGen = struct {...@@ -1585,7 +1589,7 @@ pub const DeclGen = struct {
1585 c_value: struct {1589 c_value: struct {
1586 f: *Function,1590 f: *Function,
1587 value: CValue,1591 value: CValue,
1588 v: Vectorizer,1592 v: Vectorize,
1589 },1593 },
1590 value: struct {1594 value: struct {
1591 value: Value,1595 value: Value,
...@@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3073,15 +3077,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3073 const inst_ty = f.air.typeOfIndex(inst);3077 const inst_ty = f.air.typeOfIndex(inst);
3074 const operand = try f.resolveInst(ty_op.operand);3078 const operand = try f.resolveInst(ty_op.operand);
3075 try reap(f, inst, &.{ty_op.operand});3079 try reap(f, inst, &.{ty_op.operand});
3080
3076 const writer = f.object.writer();3081 const writer = f.object.writer();
3077 const local = try f.allocLocal(inst, inst_ty);3082 const local = try f.allocLocal(inst, inst_ty);
3083 const a = try Assignment.start(f, writer, inst_ty);
3078 try f.writeCValue(writer, local, .Other);3084 try f.writeCValue(writer, local, .Other);
3079 try writer.writeAll(" = ");3085 try a.assign(f, writer);
3080 if (is_ptr) {3086 if (is_ptr) {
3081 try writer.writeByte('&');3087 try writer.writeByte('&');
3082 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });3088 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });
3083 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });3089 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });
3084 try writer.writeAll(";\n");3090 try a.end(f, writer);
3085 return local;3091 return local;
3086}3092}
30873093
...@@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3097,29 +3103,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3097 const index = try f.resolveInst(bin_op.rhs);3103 const index = try f.resolveInst(bin_op.rhs);
3098 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3104 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);
3104 const writer = f.object.writer();3106 const writer = f.object.writer();
3105 if (is_array) {3107 const local = try f.allocLocal(inst, inst_ty);
3106 try writer.writeAll("memcpy(");3108 const a = try Assignment.start(f, writer, inst_ty);
3107 try f.writeCValue(writer, local, .FunctionArgument);3109 try f.writeCValue(writer, local, .Other);
3108 try writer.writeAll(", ");3110 try a.assign(f, writer);
3109 } else {
3110 try f.writeCValue(writer, local, .Other);
3111 try writer.writeAll(" = ");
3112 }
3113 try f.writeCValue(writer, ptr, .Other);3111 try f.writeCValue(writer, ptr, .Other);
3114 try writer.writeByte('[');3112 try writer.writeByte('[');
3115 try f.writeCValue(writer, index, .Other);3113 try f.writeCValue(writer, index, .Other);
3116 try writer.writeByte(']');3114 try writer.writeByte(']');
3117 if (is_array) {3115 try a.end(f, writer);
3118 try writer.writeAll(", sizeof(");
3119 try f.renderType(writer, inst_ty);
3120 try writer.writeAll("))");
3121 }
3122 try writer.writeAll(";\n");
3123 return local;3116 return local;
3124}3117}
31253118
...@@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3129,35 +3122,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
31293122
3130 const inst_ty = f.air.typeOfIndex(inst);3123 const inst_ty = f.air.typeOfIndex(inst);
3131 const ptr_ty = f.air.typeOf(bin_op.lhs);3124 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
3134 const ptr = try f.resolveInst(bin_op.lhs);3128 const ptr = try f.resolveInst(bin_op.lhs);
3135 const index = try f.resolveInst(bin_op.rhs);3129 const index = try f.resolveInst(bin_op.rhs);
3136 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3130 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31373131
3138 const writer = f.object.writer();3132 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);
3140 try f.writeCValue(writer, local, .Other);3135 try f.writeCValue(writer, local, .Other);
3141 try writer.writeAll(" = ");3136 try a.assign(f, writer);
3142
3143 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
3144 try f.writeCValue(writer, ptr, .Initializer);
3145 try writer.writeAll(";\n");
3146 return local;
3147 }
3148
3149 try writer.writeByte('(');3137 try writer.writeByte('(');
3150 try f.renderType(writer, inst_ty);3138 try f.renderType(writer, inst_ty);
3151 try writer.writeAll(")&(");3139 try writer.writeByte(')');
3152 if (ptr_ty.ptrSize() == .One) {3140 if (elem_has_bits) try writer.writeByte('&');
3141 if (elem_has_bits and ptr_ty.ptrSize() == .One) {
3153 // It's a pointer to an array, so we need to de-reference.3142 // It's a pointer to an array, so we need to de-reference.
3154 try f.writeCValueDeref(writer, ptr);3143 try f.writeCValueDeref(writer, ptr);
3155 } else {3144 } else try f.writeCValue(writer, ptr, .Other);
3156 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(']');
3157 }3149 }
3158 try writer.writeAll(")[");3150 try a.end(f, writer);
3159 try f.writeCValue(writer, index, .Other);
3160 try writer.writeAll("];\n");
3161 return local;3151 return local;
3162}3152}
31633153
...@@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3173,29 +3163,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3173 const index = try f.resolveInst(bin_op.rhs);3163 const index = try f.resolveInst(bin_op.rhs);
3174 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3164 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);
3180 const writer = f.object.writer();3166 const writer = f.object.writer();
3181 if (is_array) {3167 const local = try f.allocLocal(inst, inst_ty);
3182 try writer.writeAll("memcpy(");3168 const a = try Assignment.start(f, writer, inst_ty);
3183 try f.writeCValue(writer, local, .FunctionArgument);3169 try f.writeCValue(writer, local, .Other);
3184 try writer.writeAll(", ");3170 try a.assign(f, writer);
3185 } else {3171 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3186 try f.writeCValue(writer, local, .Other);3172 try writer.writeByte('[');
3187 try writer.writeAll(" = ");
3188 }
3189 try f.writeCValue(writer, slice, .Other);
3190 try writer.writeAll(".ptr[");
3191 try f.writeCValue(writer, index, .Other);3173 try f.writeCValue(writer, index, .Other);
3192 try writer.writeByte(']');3174 try writer.writeByte(']');
3193 if (is_array) {3175 try a.end(f, writer);
3194 try writer.writeAll(", sizeof(");
3195 try f.renderType(writer, inst_ty);
3196 try writer.writeAll("))");
3197 }
3198 try writer.writeAll(";\n");
3199 return local;3176 return local;
3200}3177}
32013178
...@@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3203,25 +3180,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3203 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3180 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3204 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3181 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
32053182
3183 const inst_ty = f.air.typeOfIndex(inst);
3206 const slice_ty = f.air.typeOf(bin_op.lhs);3184 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
3208 const slice = try f.resolveInst(bin_op.lhs);3188 const slice = try f.resolveInst(bin_op.lhs);
3209 const index = try f.resolveInst(bin_op.rhs);3189 const index = try f.resolveInst(bin_op.rhs);
3210 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3190 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32113191
3212 const writer = f.object.writer();3192 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);
3214 try f.writeCValue(writer, local, .Other);3195 try f.writeCValue(writer, local, .Other);
3215 try writer.writeAll(" = ");3196 try a.assign(f, writer);
3216 if (child_ty.hasRuntimeBitsIgnoreComptime()) try writer.writeByte('&');3197 if (elem_has_bits) try writer.writeByte('&');
3217 try f.writeCValue(writer, slice, .Other);3198 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3218 try writer.writeAll(".ptr");3199 if (elem_has_bits) {
3219 if (child_ty.hasRuntimeBitsIgnoreComptime()) {
3220 try writer.writeByte('[');3200 try writer.writeByte('[');
3221 try f.writeCValue(writer, index, .Other);3201 try f.writeCValue(writer, index, .Other);
3222 try writer.writeByte(']');3202 try writer.writeByte(']');
3223 }3203 }
3224 try writer.writeAll(";\n");3204 try a.end(f, writer);
3225 return local;3205 return local;
3226}3206}
32273207
...@@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3237,29 +3217,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3237 const index = try f.resolveInst(bin_op.rhs);3217 const index = try f.resolveInst(bin_op.rhs);
3238 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3218 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);
3244 const writer = f.object.writer();3220 const writer = f.object.writer();
3245 if (is_array) {3221 const local = try f.allocLocal(inst, inst_ty);
3246 try writer.writeAll("memcpy(");3222 const a = try Assignment.start(f, writer, inst_ty);
3247 try f.writeCValue(writer, local, .FunctionArgument);3223 try f.writeCValue(writer, local, .Other);
3248 try writer.writeAll(", ");3224 try a.assign(f, writer);
3249 } else {
3250 try f.writeCValue(writer, local, .Other);
3251 try writer.writeAll(" = ");
3252 }
3253 try f.writeCValue(writer, array, .Other);3225 try f.writeCValue(writer, array, .Other);
3254 try writer.writeByte('[');3226 try writer.writeByte('[');
3255 try f.writeCValue(writer, index, .Other);3227 try f.writeCValue(writer, index, .Other);
3256 try writer.writeByte(']');3228 try writer.writeByte(']');
3257 if (is_array) {3229 try a.end(f, writer);
3258 try writer.writeAll(", sizeof(");
3259 try f.renderType(writer, inst_ty);
3260 try writer.writeAll("))");
3261 }
3262 try writer.writeAll(";\n");
3263 return local;3230 return local;
3264}3231}
32653232
...@@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3343,7 +3310,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33433310
3344 const writer = f.object.writer();3311 const writer = f.object.writer();
3345 const local = try f.allocLocal(inst, src_ty);3312 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
3348 if (need_memcpy) {3315 if (need_memcpy) {
3349 try writer.writeAll("memcpy(");3316 try writer.writeAll("memcpy(");
...@@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3484,12 +3451,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
34843451
3485 const writer = f.object.writer();3452 const writer = f.object.writer();
3486 const local = try f.allocLocal(inst, inst_ty);3453 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);
3488 try f.writeCValue(writer, local, .Other);3456 try f.writeCValue(writer, local, .Other);
3489 try v.elem(f, writer);3457 try v.elem(f, writer);
3490 try writer.writeAll(" = ");3458 try a.assign(f, writer);
3491 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);3459 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);
3492 try writer.writeAll(";\n");3460 try a.end(f, writer);
3493 try v.end(f, inst, writer);3461 try v.end(f, inst, writer);
34943462
3495 return local;3463 return local;
...@@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3513,7 +3481,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35133481
3514 const writer = f.object.writer();3482 const writer = f.object.writer();
3515 const local = try f.allocLocal(inst, inst_ty);3483 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
3518 try f.writeCValue(writer, local, .Other);3486 try f.writeCValue(writer, local, .Other);
3519 try v.elem(f, writer);3487 try v.elem(f, writer);
...@@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3597,10 +3565,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
3597 const writer = f.object.writer();3565 const writer = f.object.writer();
3598 const inst_ty = f.air.typeOfIndex(inst);3566 const inst_ty = f.air.typeOfIndex(inst);
3599 const local = try f.allocLocal(inst, inst_ty);3567 const local = try f.allocLocal(inst, inst_ty);
3568 const a = try Assignment.start(f, writer, inst_ty);
3600 try f.writeCValue(writer, local, .Other);3569 try f.writeCValue(writer, local, .Other);
3601 try writer.writeAll(" = ");3570 try a.assign(f, writer);
3602 try f.writeCValue(writer, operand, .Other);3571 try f.writeCValue(writer, operand, .Other);
3603 try writer.writeAll(";\n");3572 try a.end(f, writer);
3604 return local;3573 return local;
3605}3574}
36063575
...@@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3632,8 +3601,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
3632 const src_val_is_undefined =3601 const src_val_is_undefined =
3633 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;3602 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
3634 if (src_val_is_undefined) {3603 if (src_val_is_undefined) {
3635 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3604 if (ptr_info.host_size == 0) {
3636 return try storeUndefined(f, ptr_info.pointee_type, ptr_val);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 }
3637 }3611 }
36383612
3639 const target = f.object.dg.module.getTarget();3613 const target = f.object.dg.module.getTarget();
...@@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3646,7 +3620,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
3646 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3620 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36473621
3648 const writer = f.object.writer();3622 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
3651 if (need_memcpy) {3625 if (need_memcpy) {
3652 // For this memcpy to safely work we need the rhs to have the same3626 // 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:...@@ -3775,7 +3749,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37753749
3776 const w = f.object.writer();3750 const w = f.object.writer();
3777 const local = try f.allocLocal(inst, inst_ty);3751 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);
3779 try f.writeCValueMember(w, local, .{ .field = 1 });3753 try f.writeCValueMember(w, local, .{ .field = 1 });
3780 try v.elem(f, w);3754 try v.elem(f, w);
3781 try w.writeAll(" = zig_");3755 try w.writeAll(" = zig_");
...@@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3811,7 +3785,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
38113785
3812 const writer = f.object.writer();3786 const writer = f.object.writer();
3813 const local = try f.allocLocal(inst, inst_ty);3787 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);
3815 try f.writeCValue(writer, local, .Other);3789 try f.writeCValue(writer, local, .Other);
3816 try v.elem(f, writer);3790 try v.elem(f, writer);
3817 try writer.writeAll(" = ");3791 try writer.writeAll(" = ");
...@@ -3846,7 +3820,7 @@ fn airBinOp(...@@ -3846,7 +3820,7 @@ fn airBinOp(
38463820
3847 const writer = f.object.writer();3821 const writer = f.object.writer();
3848 const local = try f.allocLocal(inst, inst_ty);3822 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);
3850 try f.writeCValue(writer, local, .Other);3824 try f.writeCValue(writer, local, .Other);
3851 try v.elem(f, writer);3825 try v.elem(f, writer);
3852 try writer.writeAll(" = ");3826 try writer.writeAll(" = ");
...@@ -3893,7 +3867,7 @@ fn airCmpOp(...@@ -3893,7 +3867,7 @@ fn airCmpOp(
38933867
3894 const writer = f.object.writer();3868 const writer = f.object.writer();
3895 const local = try f.allocLocal(inst, inst_ty);3869 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);
3897 try f.writeCValue(writer, local, .Other);3871 try f.writeCValue(writer, local, .Other);
3898 try v.elem(f, writer);3872 try v.elem(f, writer);
3899 try writer.writeAll(" = ");3873 try writer.writeAll(" = ");
...@@ -3942,7 +3916,7 @@ fn airEquality(...@@ -3942,7 +3916,7 @@ fn airEquality(
3942 try f.writeCValue(writer, local, .Other);3916 try f.writeCValue(writer, local, .Other);
3943 try writer.writeAll(" = ");3917 try writer.writeAll(" = ");
39443918
3945 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) {3919 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.optionalReprIsPayload()) {
3946 // (A && B) || (C && (A == B))3920 // (A && B) || (C && (A == B))
3947 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload3921 // 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 {...@@ -4008,7 +3982,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
40083982
4009 const local = try f.allocLocal(inst, inst_ty);3983 const local = try f.allocLocal(inst, inst_ty);
4010 const writer = f.object.writer();3984 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);
4012 try f.writeCValue(writer, local, .Other);3986 try f.writeCValue(writer, local, .Other);
4013 try v.elem(f, writer);3987 try v.elem(f, writer);
4014 try writer.writeAll(" = ");3988 try writer.writeAll(" = ");
...@@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4059,7 +4033,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
40594033
4060 const writer = f.object.writer();4034 const writer = f.object.writer();
4061 const local = try f.allocLocal(inst, inst_ty);4035 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);
4063 try f.writeCValue(writer, local, .Other);4037 try f.writeCValue(writer, local, .Other);
4064 try v.elem(f, writer);4038 try v.elem(f, writer);
4065 // (lhs <> rhs) ? lhs : rhs4039 // (lhs <> rhs) ? lhs : rhs
...@@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4091,21 +4065,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4091 const len = try f.resolveInst(bin_op.rhs);4065 const len = try f.resolveInst(bin_op.rhs);
4092 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4066 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
40934067
4094 const writer = f.object.writer();
4095 const inst_ty = f.air.typeOfIndex(inst);4068 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 = (");
4099 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4069 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4100 try f.renderType(writer, inst_ty.slicePtrFieldType(&buf));4070 const ptr_ty = 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");
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 }
4109 return local;4091 return local;
4110}4092}
41114093
...@@ -4346,10 +4328,10 @@ fn lowerTry(...@@ -4346,10 +4328,10 @@ fn lowerTry(
4346 operand: Air.Inst.Ref,4328 operand: Air.Inst.Ref,
4347 body: []const Air.Inst.Index,4329 body: []const Air.Inst.Index,
4348 err_union_ty: Type,4330 err_union_ty: Type,
4349 operand_is_ptr: bool,4331 is_ptr: bool,
4350) !CValue {4332) !CValue {
4351 const err_union = try f.resolveInst(operand);4333 const err_union = try f.resolveInst(operand);
4352 const result_ty = f.air.typeOfIndex(inst);4334 const inst_ty = f.air.typeOfIndex(inst);
4353 const liveness_condbr = f.liveness.getCondBr(inst);4335 const liveness_condbr = f.liveness.getCondBr(inst);
4354 const writer = f.object.writer();4336 const writer = f.object.writer();
4355 const payload_ty = err_union_ty.errorUnionPayload();4337 const payload_ty = err_union_ty.errorUnionPayload();
...@@ -4358,7 +4340,7 @@ fn lowerTry(...@@ -4358,7 +4340,7 @@ fn lowerTry(
4358 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {4340 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
4359 try writer.writeAll("if (");4341 try writer.writeAll("if (");
4360 if (!payload_has_bits) {4342 if (!payload_has_bits) {
4361 if (operand_is_ptr)4343 if (is_ptr)
4362 try f.writeCValueDeref(writer, err_union)4344 try f.writeCValueDeref(writer, err_union)
4363 else4345 else
4364 try f.writeCValue(writer, err_union, .Other);4346 try f.writeCValue(writer, err_union, .Other);
...@@ -4367,7 +4349,7 @@ fn lowerTry(...@@ -4367,7 +4349,7 @@ fn lowerTry(
4367 // Remember we must avoid calling reap() twice for the same operand4349 // Remember we must avoid calling reap() twice for the same operand
4368 // in this function.4350 // in this function.
4369 try reap(f, inst, &.{operand});4351 try reap(f, inst, &.{operand});
4370 if (operand_is_ptr or isByRef(err_union_ty))4352 if (is_ptr)
4371 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })4353 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })
4372 else4354 else
4373 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });4355 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });
...@@ -4384,7 +4366,7 @@ fn lowerTry(...@@ -4384,7 +4366,7 @@ fn lowerTry(
4384 }4366 }
43854367
4386 if (!payload_has_bits) {4368 if (!payload_has_bits) {
4387 if (!operand_is_ptr) {4369 if (!is_ptr) {
4388 return .none;4370 return .none;
4389 } else {4371 } else {
4390 return err_union;4372 return err_union;
...@@ -4397,26 +4379,15 @@ fn lowerTry(...@@ -4397,26 +4379,15 @@ fn lowerTry(
4397 return .none;4379 return .none;
4398 }4380 }
43994381
4400 const target = f.object.dg.module.getTarget();4382 const local = try f.allocLocal(inst, inst_ty);
4401 const is_array = lowersToArray(payload_ty, target);4383 const a = try Assignment.start(f, writer, inst_ty);
4402 const local = try f.allocLocal(inst, result_ty);4384 try f.writeCValue(writer, local, .Other);
4403 if (is_array) {4385 try a.assign(f, writer);
4404 try writer.writeAll("memcpy(");4386 if (is_ptr) {
4405 try f.writeCValue(writer, local, .FunctionArgument);4387 try writer.writeByte('&');
4406 try writer.writeAll(", ");4388 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4407 try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });4389 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4408 try writer.writeAll(", sizeof(");4390 try a.end(f, writer);
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 }
4420 return local;4391 return local;
4421}4392}
44224393
...@@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4428,25 +4399,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
44284399
4429 // If result is .none then the value of the block is unused.4400 // If result is .none then the value of the block is unused.
4430 if (result != .none) {4401 if (result != .none) {
4402 const operand_ty = f.air.typeOf(branch.operand);
4431 const operand = try f.resolveInst(branch.operand);4403 const operand = try f.resolveInst(branch.operand);
4432 try reap(f, inst, &.{branch.operand});4404 try reap(f, inst, &.{branch.operand});
44334405
4434 const operand_ty = f.air.typeOf(branch.operand);4406 const a = try Assignment.start(f, writer, operand_ty);
4435 const target = f.object.dg.module.getTarget();4407 try f.writeCValue(writer, result, .Other);
4436 if (lowersToArray(operand_ty, target)) {4408 try a.assign(f, writer);
4437 try writer.writeAll("memcpy(");4409 try f.writeCValue(writer, operand, .Other);
4438 try f.writeCValue(writer, result, .FunctionArgument);4410 try a.end(f, writer);
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");
4450 }4411 }
44514412
4452 try writer.print("goto zig_block_{d};\n", .{block.block_id});4413 try writer.print("goto zig_block_{d};\n", .{block.block_id});
...@@ -4771,7 +4732,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4771,7 +4732,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4771 if (f.wantSafety()) {4732 if (f.wantSafety()) {
4772 try f.writeCValue(writer, local, .Other);4733 try f.writeCValue(writer, local, .Other);
4773 try writer.writeAll(" = ");4734 try writer.writeAll(" = ");
4774 try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);4735 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
4775 try writer.writeAll(";\n");4736 try writer.writeAll(";\n");
4776 }4737 }
4777 break :local local;4738 break :local local;
...@@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4806,7 +4767,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4806 try writer.writeAll("\")");4767 try writer.writeAll("\")");
4807 if (f.wantSafety()) {4768 if (f.wantSafety()) {
4808 try writer.writeAll(" = ");4769 try writer.writeAll(" = ");
4809 try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer);4770 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);
4810 }4771 }
4811 try writer.writeAll(";\n");4772 try writer.writeAll(";\n");
4812 }4773 }
...@@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4840,7 +4801,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4840 try writer.writeAll("\")");4801 try writer.writeAll("\")");
4841 }4802 }
4842 try writer.writeAll(" = ");4803 try writer.writeAll(" = ");
4843 try f.writeCValue(writer, input_val, .Initializer);4804 try f.writeCValue(writer, input_val, .Other);
4844 try writer.writeAll(";\n");4805 try writer.writeAll(";\n");
4845 }4806 }
4846 }4807 }
...@@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5072,8 +5033,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5072 }5033 }
50735034
5074 const inst_ty = f.air.typeOfIndex(inst);5035 const inst_ty = f.air.typeOfIndex(inst);
5075 const local = try f.allocLocal(inst, inst_ty);
5076 const writer = f.object.writer();5036 const writer = f.object.writer();
5037 const local = try f.allocLocal(inst, inst_ty);
50775038
5078 if (opt_ty.optionalReprIsPayload()) {5039 if (opt_ty.optionalReprIsPayload()) {
5079 try f.writeCValue(writer, local, .Other);5040 try f.writeCValue(writer, local, .Other);
...@@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5083,24 +5044,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5083 return local;5044 return local;
5084 }5045 }
50855046
5086 const target = f.object.dg.module.getTarget();5047 const a = try Assignment.start(f, writer, inst_ty);
5087 const is_array = lowersToArray(inst_ty, target);5048 try f.writeCValue(writer, local, .Other);
50885049 try a.assign(f, writer);
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 }
5097 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });5050 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5098 if (is_array) {5051 try a.end(f, writer);
5099 try writer.writeAll(", sizeof(");
5100 try f.renderType(writer, inst_ty);
5101 try writer.writeAll("))");
5102 }
5103 try writer.writeAll(";\n");
5104 return local;5052 return local;
5105}5053}
51065054
...@@ -5193,6 +5141,7 @@ fn fieldLocation(...@@ -5193,6 +5141,7 @@ fn fieldLocation(
5193 if (container_ty.structFieldIsComptime(next_field_index)) continue;5141 if (container_ty.structFieldIsComptime(next_field_index)) continue;
5194 const field_ty = container_ty.structFieldType(next_field_index);5142 const field_ty = container_ty.structFieldType(next_field_index);
5195 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;5143 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5144
5196 break .{ .field = if (container_ty.isSimpleTuple())5145 break .{ .field = if (container_ty.isSimpleTuple())
5197 .{ .field = next_field_index }5146 .{ .field = next_field_index }
5198 else5147 else
...@@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5437,13 +5386,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5437 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5386 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5438 try writer.writeByte('(');5387 try writer.writeByte('(');
5439 }5388 }
5440 try writer.writeAll("zig_shr_");5389 if (bit_offset_val_pl.data > 0) {
5441 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);5390 try writer.writeAll("zig_shr_");
5442 try writer.writeByte('(');5391 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5392 try writer.writeByte('(');
5393 }
5443 try f.writeCValue(writer, struct_byval, .Other);5394 try f.writeCValue(writer, struct_byval, .Other);
5444 try writer.writeAll(", ");5395 if (bit_offset_val_pl.data > 0) {
5445 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);5396 try writer.writeAll(", ");
5446 try writer.writeByte(')');5397 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5398 try writer.writeByte(')');
5399 }
5447 if (cant_cast) try writer.writeByte(')');5400 if (cant_cast) try writer.writeByte(')');
5448 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);5401 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
5449 try writer.writeAll(");\n");5402 try writer.writeAll(");\n");
...@@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5473,9 +5426,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54735426
5474 const local = try f.allocLocal(inst, inst_ty);5427 const local = try f.allocLocal(inst, inst_ty);
5475 try writer.writeAll("memcpy(&");5428 try writer.writeAll("memcpy(&");
5476 try f.writeCValue(writer, local, .FunctionArgument);5429 try f.writeCValue(writer, local, .Other);
5477 try writer.writeAll(", &");5430 try writer.writeAll(", &");
5478 try f.writeCValue(writer, operand_lval, .FunctionArgument);5431 try f.writeCValue(writer, operand_lval, .Other);
5479 try writer.writeAll(", sizeof(");5432 try writer.writeAll(", sizeof(");
5480 try f.renderType(writer, inst_ty);5433 try f.renderType(writer, inst_ty);
5481 try writer.writeAll("));\n");5434 try writer.writeAll("));\n");
...@@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5496,20 +5449,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5496 };5449 };
54975450
5498 const local = try f.allocLocal(inst, inst_ty);5451 const local = try f.allocLocal(inst, inst_ty);
5499 if (lowersToArray(inst_ty, target)) {5452 const a = try Assignment.start(f, writer, inst_ty);
5500 try writer.writeAll("memcpy(");5453 try f.writeCValue(writer, local, .Other);
5501 try f.writeCValue(writer, local, .FunctionArgument);5454 try a.assign(f, writer);
5502 try writer.writeAll(", ");5455 try f.writeCValueMember(writer, struct_byval, field_name);
5503 try f.writeCValueMember(writer, struct_byval, field_name);5456 try a.end(f, writer);
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");
5513 return local;5457 return local;
5514}5458}
55155459
...@@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5554,33 +5498,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5554 const operand = try f.resolveInst(ty_op.operand);5498 const operand = try f.resolveInst(ty_op.operand);
5555 try reap(f, inst, &.{ty_op.operand});5499 try reap(f, inst, &.{ty_op.operand});
5556 const operand_ty = f.air.typeOf(ty_op.operand);5500 const operand_ty = f.air.typeOf(ty_op.operand);
5557 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;5501 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
5558 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
55595502
5503 const writer = f.object.writer();
5560 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {5504 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {
5561 if (!is_ptr) return .none;5505 if (!is_ptr) return .none;
55625506
5563 const w = f.object.writer();
5564 const local = try f.allocLocal(inst, inst_ty);5507 const local = try f.allocLocal(inst, inst_ty);
5565 try f.writeCValue(w, local, .Other);5508 try f.writeCValue(writer, local, .Other);
5566 try w.writeAll(" = (");5509 try writer.writeAll(" = (");
5567 try f.renderType(w, inst_ty);5510 try f.renderType(writer, inst_ty);
5568 try w.writeByte(')');5511 try writer.writeByte(')');
5569 try f.writeCValue(w, operand, .Initializer);5512 try f.writeCValue(writer, operand, .Initializer);
5570 try w.writeAll(";\n");5513 try writer.writeAll(";\n");
5571 return local;5514 return local;
5572 }5515 }
55735516
5574 const writer = f.object.writer();
5575 const local = try f.allocLocal(inst, inst_ty);5517 const local = try f.allocLocal(inst, inst_ty);
5518 const a = try Assignment.start(f, writer, inst_ty);
5576 try f.writeCValue(writer, local, .Other);5519 try f.writeCValue(writer, local, .Other);
5577 try writer.writeAll(" = ");5520 try a.assign(f, writer);
5578 if (is_ptr) try writer.writeByte('&');5521 if (is_ptr) {
5579 if (operand_is_ptr)5522 try writer.writeByte('&');
5580 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" })5523 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
5581 else5524 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5582 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });5525 try a.end(f, writer);
5583 try writer.writeAll(";\n");
5584 return local;5526 return local;
5585}5527}
55865528
...@@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5588,40 +5530,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5588 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5530 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55895531
5590 const inst_ty = f.air.typeOfIndex(inst);5532 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);
5591 const payload = try f.resolveInst(ty_op.operand);5535 const payload = try f.resolveInst(ty_op.operand);
5592 try reap(f, inst, &.{ty_op.operand});5536 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();
5608 const local = try f.allocLocal(inst, inst_ty);5539 const local = try f.allocLocal(inst, inst_ty);
5609 if (!is_array) {5540 {
5610 try f.writeCValue(writer, local, .Other);5541 const a = try Assignment.start(f, writer, payload_ty);
5611 try writer.writeAll(".payload = ");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);
5612 try f.writeCValue(writer, payload, .Other);5547 try f.writeCValue(writer, payload, .Other);
5613 try writer.writeAll("; ");5548 try a.end(f, writer);
5614 }5549 }
5615 try f.writeCValue(writer, local, .Other);5550 if (!repr_is_payload) {
5616 try writer.writeAll(".is_null = false;\n");5551 const a = try Assignment.start(f, writer, Type.bool);
5617 if (is_array) {5552 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
5618 try writer.writeAll("memcpy(");5553 try a.assign(f, writer);
5619 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });5554 try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other);
5620 try writer.writeAll(", ");5555 try a.end(f, writer);
5621 try f.writeCValue(writer, payload, .FunctionArgument);
5622 try writer.writeAll(", sizeof(");
5623 try f.renderType(writer, payload_ty);
5624 try writer.writeAll("));\n");
5625 }5556 }
5626 return local;5557 return local;
5627}5558}
...@@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5629,29 +5560,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5629fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {5560fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5630 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5561 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56315562
5632 const writer = f.object.writer();5563 const inst_ty = f.air.typeOfIndex(inst);
5633 const operand = try f.resolveInst(ty_op.operand);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);
5634 try reap(f, inst, &.{ty_op.operand});5568 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()) {5570 const writer = f.object.writer();
5640 try f.writeCValue(writer, local, .Other);5571 const local = try f.allocLocal(inst, inst_ty);
5641 try writer.writeAll(" = ");5572 if (!repr_is_err) {
5642 try f.writeCValue(writer, operand, .Other);5573 const a = try Assignment.start(f, writer, payload_ty);
5643 try writer.writeAll(";\n");5574 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5644 return local;5575 try a.assign(f, writer);
5576 try f.object.dg.renderValue(writer, payload_ty, Value.undef, .Other);
5577 try a.end(f, writer);
5645 }5578 }
5646
5647 {5579 {
5648 // TODO: set the payload to undefined5580 const a = try Assignment.start(f, writer, err_ty);
5649 //try f.writeCValue(writer, local, .Other);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);
5650 }5588 }
5651 try f.writeCValue(writer, local, .Other);
5652 try writer.writeAll(".error = ");
5653 try f.writeCValue(writer, operand, .Other);
5654 try writer.writeAll(";\n");
5655 return local;5589 return local;
5656}5590}
56575591
...@@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5711,29 +5645,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5711 const inst_ty = f.air.typeOfIndex(inst);5645 const inst_ty = f.air.typeOfIndex(inst);
5712 const payload_ty = inst_ty.errorUnionPayload();5646 const payload_ty = inst_ty.errorUnionPayload();
5713 const payload = try f.resolveInst(ty_op.operand);5647 const payload = try f.resolveInst(ty_op.operand);
5648 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5649 const err_ty = inst_ty.errorUnionSet();
5714 try reap(f, inst, &.{ty_op.operand});5650 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
5719 const writer = f.object.writer();5652 const writer = f.object.writer();
5720 const local = try f.allocLocal(inst, inst_ty);5653 const local = try f.allocLocal(inst, inst_ty);
5721 if (!is_array) {5654 if (!repr_is_err) {
5722 try f.writeCValue(writer, local, .Other);5655 const a = try Assignment.start(f, writer, payload_ty);
5723 try writer.writeAll(".payload = ");5656 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5657 try a.assign(f, writer);
5724 try f.writeCValue(writer, payload, .Other);5658 try f.writeCValue(writer, payload, .Other);
5725 try writer.writeAll("; ");5659 try a.end(f, writer);
5726 }5660 }
5727 try f.writeCValue(writer, local, .Other);5661 {
5728 try writer.writeAll(".error = 0;\n");5662 const a = try Assignment.start(f, writer, err_ty);
5729 if (is_array) {5663 if (repr_is_err)
5730 try writer.writeAll("memcpy(");5664 try f.writeCValue(writer, local, .Other)
5731 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });5665 else
5732 try writer.writeAll(", ");5666 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5733 try f.writeCValue(writer, payload, .FunctionArgument);5667 try a.assign(f, writer);
5734 try writer.writeAll(", sizeof(");5668 try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other);
5735 try f.renderType(writer, payload_ty);5669 try a.end(f, writer);
5736 try writer.writeAll("));\n");
5737 }5670 }
5738 return local;5671 return local;
5739}5672}
...@@ -5885,7 +5818,7 @@ fn airUnBuiltinCall(...@@ -5885,7 +5818,7 @@ fn airUnBuiltinCall(
58855818
5886 const writer = f.object.writer();5819 const writer = f.object.writer();
5887 const local = try f.allocLocal(inst, inst_ty);5820 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);
5889 if (!ref_ret) {5822 if (!ref_ret) {
5890 try f.writeCValue(writer, local, .Other);5823 try f.writeCValue(writer, local, .Other);
5891 try v.elem(f, writer);5824 try v.elem(f, writer);
...@@ -5934,7 +5867,7 @@ fn airBinBuiltinCall(...@@ -5934,7 +5867,7 @@ fn airBinBuiltinCall(
5934 const writer = f.object.writer();5867 const writer = f.object.writer();
5935 const local = try f.allocLocal(inst, inst_ty);5868 const local = try f.allocLocal(inst, inst_ty);
5936 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });5869 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);
5938 if (!ref_ret) {5871 if (!ref_ret) {
5939 try f.writeCValue(writer, local, .Other);5872 try f.writeCValue(writer, local, .Other);
5940 try v.elem(f, writer);5873 try v.elem(f, writer);
...@@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall(...@@ -5982,7 +5915,7 @@ fn airCmpBuiltinCall(
59825915
5983 const writer = f.object.writer();5916 const writer = f.object.writer();
5984 const local = try f.allocLocal(inst, inst_ty);5917 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);
5986 if (!ref_ret) {5919 if (!ref_ret) {
5987 try f.writeCValue(writer, local, .Other);5920 try f.writeCValue(writer, local, .Other);
5988 try v.elem(f, writer);5921 try v.elem(f, writer);
...@@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6262,19 +6195,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6262 const union_ptr = try f.resolveInst(bin_op.lhs);6195 const union_ptr = try f.resolveInst(bin_op.lhs);
6263 const new_tag = try f.resolveInst(bin_op.rhs);6196 const new_tag = try f.resolveInst(bin_op.rhs);
6264 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6197 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();
6268 const target = f.object.dg.module.getTarget();6199 const target = f.object.dg.module.getTarget();
6200 const union_ty = f.air.typeOf(bin_op.lhs).childType();
6269 const layout = union_ty.unionGetLayout(target);6201 const layout = union_ty.unionGetLayout(target);
6270 if (layout.tag_size == 0) return .none;6202 if (layout.tag_size == 0) return .none;
6203 const tag_ty = union_ty.unionTagTypeSafety().?;
62716204
6272 try writer.writeByte('(');6205 const writer = f.object.writer();
6273 try f.writeCValue(writer, union_ptr, .Other);6206 const a = try Assignment.start(f, writer, tag_ty);
6274 try writer.writeAll(")->tag = ");6207 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });
6208 try a.assign(f, writer);
6275 try f.writeCValue(writer, new_tag, .Other);6209 try f.writeCValue(writer, new_tag, .Other);
6276 try writer.writeAll(";\n");6210 try a.end(f, writer);
6277
6278 return .none;6211 return .none;
6279}6212}
62806213
...@@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6284,20 +6217,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6284 const operand = try f.resolveInst(ty_op.operand);6217 const operand = try f.resolveInst(ty_op.operand);
6285 try reap(f, inst, &.{ty_op.operand});6218 try reap(f, inst, &.{ty_op.operand});
62866219
6287 const un_ty = f.air.typeOf(ty_op.operand);6220 const union_ty = f.air.typeOf(ty_op.operand);
6288
6289 const target = f.object.dg.module.getTarget();6221 const target = f.object.dg.module.getTarget();
6290 const layout = un_ty.unionGetLayout(target);6222 const layout = union_ty.unionGetLayout(target);
6291 if (layout.tag_size == 0) return .none;6223 if (layout.tag_size == 0) return .none;
62926224
6293 const inst_ty = f.air.typeOfIndex(inst);6225 const inst_ty = f.air.typeOfIndex(inst);
6294 const writer = f.object.writer();6226 const writer = f.object.writer();
6295 const local = try f.allocLocal(inst, inst_ty);6227 const local = try f.allocLocal(inst, inst_ty);
6228 const a = try Assignment.start(f, writer, inst_ty);
6296 try f.writeCValue(writer, local, .Other);6229 try f.writeCValue(writer, local, .Other);
62976230 try a.assign(f, writer);
6298 try writer.writeAll(" = ");6231 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });
6299 try f.writeCValue(writer, operand, .Other);6232 try a.end(f, writer);
6300 try writer.writeAll(".tag;\n");
6301 return local;6233 return local;
6302}6234}
63036235
...@@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6350,7 +6282,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
63506282
6351 const writer = f.object.writer();6283 const writer = f.object.writer();
6352 const local = try f.allocLocal(inst, inst_ty);6284 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);
6354 if (need_memcpy) try writer.writeAll("memcpy(&");6286 if (need_memcpy) try writer.writeAll("memcpy(&");
6355 try f.writeCValue(writer, local, .Other);6287 try f.writeCValue(writer, local, .Other);
6356 try v.elem(f, writer);6288 try v.elem(f, writer);
...@@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6380,7 +6312,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
63806312
6381 const writer = f.object.writer();6313 const writer = f.object.writer();
6382 const local = try f.allocLocal(inst, inst_ty);6314 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);
6384 try f.writeCValue(writer, local, .Other);6316 try f.writeCValue(writer, local, .Other);
6385 try v.elem(f, writer);6317 try v.elem(f, writer);
6386 try writer.writeAll(" = ");6318 try writer.writeAll(" = ");
...@@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6547,7 +6479,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6547 }, .Initializer);6479 }, .Initializer);
6548 try writer.writeAll(";\n");6480 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);
6551 try f.writeCValue(writer, accum, .Other);6483 try f.writeCValue(writer, accum, .Other);
6552 switch (op) {6484 switch (op) {
6553 .float_op => |func| {6485 .float_op => |func| {
...@@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6621,87 +6553,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6621 switch (inst_ty.zigTypeTag()) {6553 switch (inst_ty.zigTypeTag()) {
6622 .Array, .Vector => {6554 .Array, .Vector => {
6623 const elem_ty = inst_ty.childType();6555 const elem_ty = inst_ty.childType();
66246556 const a = try Assignment.init(f, elem_ty);
6625 const is_array = lowersToArray(elem_ty, target);6557 for (resolved_elements, 0..) |element, i| {
6626 const need_memcpy = is_array;6558 try a.restart(f, writer);
6627 if (need_memcpy) {6559 try f.writeCValue(writer, local, .Other);
6628 for (resolved_elements, 0..) |element, i| {6560 try writer.print("[{d}]", .{i});
6629 try writer.writeAll("memcpy(");6561 try a.assign(f, writer);
6630 try f.writeCValue(writer, local, .Other);6562 try f.writeCValue(writer, element, .Other);
6631 try writer.print("[{d}]", .{i});6563 try a.end(f, writer);
6632 try writer.writeAll(", ");6564 }
6633 try f.writeCValue(writer, element, .Other);6565 if (inst_ty.sentinel()) |sentinel| {
6634 try writer.writeAll(", sizeof(");6566 try a.restart(f, writer);
6635 try f.renderType(writer, elem_ty);6567 try f.writeCValue(writer, local, .Other);
6636 try writer.writeAll("))");6568 try writer.print("[{d}]", .{resolved_elements.len});
6637 try writer.writeAll(";\n");6569 try a.assign(f, writer);
6638 }6570 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6639 assert(inst_ty.sentinel() == null);6571 try a.end(f, writer);
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 }
6653 }6572 }
6654 },6573 },
6655 .Struct => switch (inst_ty.containerLayout()) {6574 .Struct => switch (inst_ty.containerLayout()) {
6656 .Auto, .Extern => {6575 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {
6657 try f.writeCValue(writer, local, .Other);6576 if (inst_ty.structFieldIsComptime(field_i)) continue;
6658 try writer.writeAll(" = (");6577 const field_ty = inst_ty.structFieldType(field_i);
6659 try f.renderType(writer, inst_ty);6578 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
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) };
66956579
6696 try writer.writeAll(";\n");6580 const a = try Assignment.start(f, writer, field_ty);
6697 try writer.writeAll("memcpy(");6581 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())
6698 try f.writeCValueMember(writer, local, field_name);6582 .{ .field = field_i }
6699 try writer.writeAll(", ");6583 else
6700 try f.writeCValue(writer, resolved_element, .FunctionArgument);6584 .{ .identifier = inst_ty.structFieldName(field_i) });
6701 try writer.writeAll(", sizeof(");6585 try a.assign(f, writer);
6702 try f.renderType(writer, element_ty);6586 try f.writeCValue(writer, element, .Other);
6703 try writer.writeAll("));\n");6587 try a.end(f, writer);
6704 }
6705 },6588 },
6706 .Packed => {6589 .Packed => {
6707 try f.writeCValue(writer, local, .Other);6590 try f.writeCValue(writer, local, .Other);
...@@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6718,8 +6601,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6718 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);6601 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
67196602
6720 var empty = true;6603 var empty = true;
6721 for (0..elements.len) |index| {6604 for (0..elements.len) |field_i| {
6722 const field_ty = inst_ty.structFieldType(index);6605 if (inst_ty.structFieldIsComptime(field_i)) continue;
6606 const field_ty = inst_ty.structFieldType(field_i);
6723 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;6607 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67246608
6725 if (!empty) {6609 if (!empty) {
...@@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6730,8 +6614,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6730 empty = false;6614 empty = false;
6731 }6615 }
6732 empty = true;6616 empty = true;
6733 for (resolved_elements, 0..) |element, index| {6617 for (resolved_elements, 0..) |element, field_i| {
6734 const field_ty = inst_ty.structFieldType(index);6618 if (inst_ty.structFieldIsComptime(field_i)) continue;
6619 const field_ty = inst_ty.structFieldType(field_i);
6735 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;6620 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67366621
6737 if (!empty) try writer.writeAll(", ");6622 if (!empty) try writer.writeAll(", ");
...@@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6784,6 +6669,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6784 const target = f.object.dg.module.getTarget();6669 const target = f.object.dg.module.getTarget();
6785 const union_obj = union_ty.cast(Type.Payload.Union).?.data;6670 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
6786 const field_name = union_obj.fields.keys()[extra.field_index];6671 const field_name = union_obj.fields.keys()[extra.field_index];
6672 const payload_ty = f.air.typeOf(extra.init);
6787 const payload = try f.resolveInst(extra.init);6673 const payload = try f.resolveInst(extra.init);
6788 try reap(f, inst, &.{extra.init});6674 try reap(f, inst, &.{extra.init});
67896675
...@@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6811,16 +6697,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6811 var int_pl: Value.Payload.U64 = undefined;6697 var int_pl: Value.Payload.U64 = undefined;
6812 const int_val = tag_val.enumToInt(tag_ty, &int_pl);6698 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
68136699
6814 try f.writeCValue(writer, local, .Other);6700 const a = try Assignment.start(f, writer, tag_ty);
6815 try writer.print(".tag = {}; ", .{try f.fmtIntLiteral(tag_ty, int_val)});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);
6816 }6705 }
6817 break :field .{ .payload_identifier = field_name };6706 break :field .{ .payload_identifier = field_name };
6818 } else .{ .identifier = field_name };6707 } else .{ .identifier = field_name };
68196708
6709 const a = try Assignment.start(f, writer, payload_ty);
6820 try f.writeCValueMember(writer, local, field);6710 try f.writeCValueMember(writer, local, field);
6821 try writer.writeAll(" = ");6711 try a.assign(f, writer);
6822 try f.writeCValue(writer, payload, .Other);6712 try f.writeCValue(writer, payload, .Other);
6823 try writer.writeAll(";\n");6713 try a.end(f, writer);
6824 return local;6714 return local;
6825}6715}
68266716
...@@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6887,7 +6777,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
68876777
6888 const writer = f.object.writer();6778 const writer = f.object.writer();
6889 const local = try f.allocLocal(inst, operand_ty);6779 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);
6891 try f.writeCValue(writer, local, .Other);6781 try f.writeCValue(writer, local, .Other);
6892 try v.elem(f, writer);6782 try v.elem(f, writer);
6893 try writer.writeAll(" = zig_neg_");6783 try writer.writeAll(" = zig_neg_");
...@@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal...@@ -6912,7 +6802,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
69126802
6913 const writer = f.object.writer();6803 const writer = f.object.writer();
6914 const local = try f.allocLocal(inst, inst_ty);6804 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);
6916 try f.writeCValue(writer, local, .Other);6806 try f.writeCValue(writer, local, .Other);
6917 try v.elem(f, writer);6807 try v.elem(f, writer);
6918 try writer.writeAll(" = zig_libc_name_");6808 try writer.writeAll(" = zig_libc_name_");
...@@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -6940,7 +6830,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
69406830
6941 const writer = f.object.writer();6831 const writer = f.object.writer();
6942 const local = try f.allocLocal(inst, inst_ty);6832 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);
6944 try f.writeCValue(writer, local, .Other);6834 try f.writeCValue(writer, local, .Other);
6945 try v.elem(f, writer);6835 try v.elem(f, writer);
6946 try writer.writeAll(" = zig_libc_name_");6836 try writer.writeAll(" = zig_libc_name_");
...@@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6973,7 +6863,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
69736863
6974 const writer = f.object.writer();6864 const writer = f.object.writer();
6975 const local = try f.allocLocal(inst, inst_ty);6865 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);
6977 try f.writeCValue(writer, local, .Other);6867 try f.writeCValue(writer, local, .Other);
6978 try v.elem(f, writer);6868 try v.elem(f, writer);
6979 try writer.writeAll(" = zig_libc_name_");6869 try writer.writeAll(" = zig_libc_name_");
...@@ -7480,10 +7370,57 @@ fn formatIntLiteral(...@@ -7480,10 +7370,57 @@ fn formatIntLiteral(
7480 try data.cty.renderLiteralSuffix(writer);7370 try data.cty.renderLiteralSuffix(writer);
7481}7371}
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 {
7484 index: CValue = .none,7421 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 {
7487 return if (ty.zigTypeTag() == .Vector) index: {7424 return if (ty.zigTypeTag() == .Vector) index: {
7488 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };7425 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };
74897426
...@@ -7504,7 +7441,7 @@ const Vectorizer = struct {...@@ -7504,7 +7441,7 @@ const Vectorizer = struct {
7504 } else .{};7441 } else .{};
7505 }7442 }
75067443
7507 pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void {7444 pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void {
7508 if (self.index != .none) {7445 if (self.index != .none) {
7509 try writer.writeByte('[');7446 try writer.writeByte('[');
7510 try f.writeCValue(writer, self.index, .Other);7447 try f.writeCValue(writer, self.index, .Other);
...@@ -7512,7 +7449,7 @@ const Vectorizer = struct {...@@ -7512,7 +7449,7 @@ const Vectorizer = struct {
7512 }7449 }
7513 }7450 }
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 {
7516 if (self.index != .none) {7453 if (self.index != .none) {
7517 f.object.indent_writer.popIndent();7454 f.object.indent_writer.popIndent();
7518 try writer.writeAll("}\n");7455 try writer.writeAll("}\n");
...@@ -7521,11 +7458,6 @@ const Vectorizer = struct {...@@ -7521,11 +7458,6 @@ const Vectorizer = struct {
7521 }7458 }
7522};7459};
75237460
7524fn isByRef(ty: Type) bool {
7525 _ = ty;
7526 return false;
7527}
7528
7529const LowerFnRetTyBuffer = struct {7461const LowerFnRetTyBuffer = struct {
7530 names: [1][]const u8,7462 names: [1][]const u8,
7531 types: [1]Type,7463 types: [1]Type,
...@@ -7557,29 +7489,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool {...@@ -7557,29 +7489,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool {
7557 };7489 };
7558}7490}
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
7583fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void {7492fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void {
7584 assert(operands.len <= Liveness.bpi - 1);7493 assert(operands.len <= Liveness.bpi - 1);
7585 var tomb_bits = f.liveness.getTombBits(inst);7494 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" {...@@ -615,3 +615,15 @@ test "pointer to container level packed struct field" {
615 @ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true;615 @ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true;
616 try expect(S.arr[0] == 0x10000000);616 try expect(S.arr[0] == 0x10000000);
617}617}
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 {...@@ -962,13 +962,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
962 if (test_target.use_llvm == false and mem.eql(u8, options.name, "std"))962 if (test_target.use_llvm == false and mem.eql(u8, options.name, "std"))
963 continue;963 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
972 const want_this_mode = for (options.optimize_modes) |m| {965 const want_this_mode = for (options.optimize_modes) |m| {
973 if (m == test_target.optimize_mode) break true;966 if (m == test_target.optimize_mode) break true;
974 } else false;967 } else false;