authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-22 11:04:36-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-22 11:04:36-07:00
log21aa55d34e432b677f71cbb377aa89c8cdbd1483
tree87b831f51d09d923bfaf9f7a44477e50e773ae73
parentc7067ef6e823a0eaa87880e7a4b8bc89c0b31ab2
parentf5cf732659d1bf3112c828ef9798db445ff53f3c
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15356 from jacobly0/cbe-std-tests

cbe: enable CI for std tests

38 files changed, 1339 insertions(+), 1189 deletions(-)

lib/std/Thread.zig+1-1
......@@ -1141,7 +1141,7 @@ test "setName, getName" {
11411141 thread.join();
11421142}
11431143
1144test "std.Thread" {
1144test {
11451145 // Doesn't use testing.refAllDecls() since that would pull in the compileError spinLoopHint.
11461146 _ = Futex;
11471147 _ = ResetEvent;
lib/std/atomic.zig+1-1
......@@ -7,7 +7,7 @@ pub const Stack = @import("atomic/stack.zig").Stack;
77pub const Queue = @import("atomic/queue.zig").Queue;
88pub const Atomic = @import("atomic/Atomic.zig").Atomic;
99
10test "std.atomic" {
10test {
1111 _ = @import("atomic/stack.zig");
1212 _ = @import("atomic/queue.zig");
1313 _ = @import("atomic/Atomic.zig");
lib/std/bit_set.zig+2
......@@ -1635,6 +1635,8 @@ fn testStaticBitSet(comptime Set: type) !void {
16351635}
16361636
16371637test "IntegerBitSet" {
1638 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
1639
16381640 try testStaticBitSet(IntegerBitSet(0));
16391641 try testStaticBitSet(IntegerBitSet(1));
16401642 try testStaticBitSet(IntegerBitSet(2));
lib/std/crypto/aes.zig+3-2
......@@ -5,9 +5,10 @@ const testing = std.testing;
55const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);
66const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
77const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
8const impl = if (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) impl: {
8// C backend doesn't currently support passing vectors to inline asm.
9const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: {
910 break :impl @import("aes/aesni.zig");
10} else if (builtin.cpu.arch == .aarch64 and has_armaes)
11} else if (builtin.cpu.arch == .aarch64 and builtin.zig_backend != .stage2_c and has_armaes)
1112impl: {
1213 break :impl @import("aes/armcrypto.zig");
1314} else impl: {
lib/std/crypto/aes_ocb.zig+8
......@@ -257,6 +257,8 @@ inline fn xorWith(x: *Block, y: Block) void {
257257const hexToBytes = std.fmt.hexToBytes;
258258
259259test "AesOcb test vector 1" {
260 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
261
260262 var k: [Aes128Ocb.key_length]u8 = undefined;
261263 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
262264 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -274,6 +276,8 @@ test "AesOcb test vector 1" {
274276}
275277
276278test "AesOcb test vector 2" {
279 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
280
277281 var k: [Aes128Ocb.key_length]u8 = undefined;
278282 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
279283 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -293,6 +297,8 @@ test "AesOcb test vector 2" {
293297}
294298
295299test "AesOcb test vector 3" {
300 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
301
296302 var k: [Aes128Ocb.key_length]u8 = undefined;
297303 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
298304 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -315,6 +321,8 @@ test "AesOcb test vector 3" {
315321}
316322
317323test "AesOcb test vector 4" {
324 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
325
318326 var k: [Aes128Ocb.key_length]u8 = undefined;
319327 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
320328 var tag: [Aes128Ocb.tag_length]u8 = undefined;
lib/std/crypto/ecdsa.zig+13
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const crypto = std.crypto;
34const fmt = std.fmt;
......@@ -373,6 +374,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
373374}
374375
375376test "ECDSA - Basic operations over EcdsaP384Sha384" {
377 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
378
376379 const Scheme = EcdsaP384Sha384;
377380 const kp = try Scheme.KeyPair.create(null);
378381 const msg = "test";
......@@ -387,6 +390,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha384" {
387390}
388391
389392test "ECDSA - Basic operations over Secp256k1" {
393 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
394
390395 const Scheme = EcdsaSecp256k1Sha256oSha256;
391396 const kp = try Scheme.KeyPair.create(null);
392397 const msg = "test";
......@@ -401,6 +406,8 @@ test "ECDSA - Basic operations over Secp256k1" {
401406}
402407
403408test "ECDSA - Basic operations over EcdsaP384Sha256" {
409 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
410
404411 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
405412 const kp = try Scheme.KeyPair.create(null);
406413 const msg = "test";
......@@ -415,6 +422,8 @@ test "ECDSA - Basic operations over EcdsaP384Sha256" {
415422}
416423
417424test "ECDSA - Verifying a existing signature with EcdsaP384Sha256" {
425 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
426
418427 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
419428 // zig fmt: off
420429 const sk_bytes = [_]u8{
......@@ -457,6 +466,8 @@ const TestVector = struct {
457466};
458467
459468test "ECDSA - Test vectors from Project Wycheproof" {
469 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
470
460471 const vectors = [_]TestVector{
461472 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76", .result = .valid },
462473 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db", .result = .acceptable },
......@@ -869,6 +880,8 @@ fn tvTry(vector: TestVector) !void {
869880}
870881
871882test "ECDSA - Sec1 encoding/decoding" {
883 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
884
872885 const Scheme = EcdsaP384Sha384;
873886 const kp = try Scheme.KeyPair.create(null);
874887 const pk = kp.public_key;
lib/std/crypto/ghash_polyval.zig+3-2
......@@ -248,9 +248,10 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type {
248248 const has_pclmul = std.Target.x86.featureSetHas(builtin.cpu.features, .pclmul);
249249 const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
250250 const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
251 const clmul = if (builtin.cpu.arch == .x86_64 and has_pclmul and has_avx) impl: {
251 // C backend doesn't currently support passing vectors to inline asm.
252 const clmul = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_pclmul and has_avx) impl: {
252253 break :impl clmulPclmul;
253 } else if (builtin.cpu.arch == .aarch64 and has_armaes) impl: {
254 } else if (builtin.cpu.arch == .aarch64 and builtin.zig_backend != .stage2_c and has_armaes) impl: {
254255 break :impl clmulPmull;
255256 } else impl: {
256257 break :impl clmulSoft;
lib/std/crypto/pcurves/p256.zig+1-1
......@@ -473,6 +473,6 @@ pub const AffineCoordinates = struct {
473473 }
474474};
475475
476test "p256" {
476test {
477477 _ = @import("tests/p256.zig");
478478}
lib/std/crypto/pcurves/p384.zig+3-1
......@@ -473,6 +473,8 @@ pub const AffineCoordinates = struct {
473473 }
474474};
475475
476test "p384" {
476test {
477 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
478
477479 _ = @import("tests/p384.zig");
478480}
lib/std/crypto/pcurves/secp256k1.zig+3-1
......@@ -551,6 +551,8 @@ pub const AffineCoordinates = struct {
551551 }
552552};
553553
554test "secp256k1" {
554test {
555 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
556
555557 _ = @import("tests/secp256k1.zig");
556558}
lib/std/crypto/sha2.zig+3-2
......@@ -205,7 +205,7 @@ fn Sha2x32(comptime params: Sha2Params32) type {
205205
206206 if (!isComptime()) {
207207 switch (builtin.cpu.arch) {
208 .aarch64 => if (comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {
208 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {
209209 var x: v4u32 = d.s[0..4].*;
210210 var y: v4u32 = d.s[4..8].*;
211211 const s_v = @ptrCast(*[16]v4u32, &s);
......@@ -242,7 +242,8 @@ fn Sha2x32(comptime params: Sha2Params32) type {
242242 d.s[4..8].* = y +% @as(v4u32, d.s[4..8].*);
243243 return;
244244 },
245 .x86_64 => if (comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sha)) {
245 // C backend doesn't currently support passing vectors to inline asm.
246 .x86_64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sha)) {
246247 var x: v4u32 = [_]u32{ d.s[5], d.s[4], d.s[1], d.s[0] };
247248 var y: v4u32 = [_]u32{ d.s[7], d.s[6], d.s[3], d.s[2] };
248249 const s_v = @ptrCast(*[16]v4u32, &s);
lib/std/debug.zig+2
......@@ -2189,6 +2189,8 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
21892189}
21902190
21912191test "manage resources correctly" {
2192 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // error.UnsupportedBackend
2193
21922194 if (builtin.os.tag == .wasi) return error.SkipZigTest;
21932195
21942196 if (builtin.os.tag == .windows and builtin.cpu.arch == .x86_64) {
lib/std/hash.zig+1-1
......@@ -36,7 +36,7 @@ const xxhash = @import("hash/xxhash.zig");
3636pub const XxHash64 = xxhash.XxHash64;
3737pub const XxHash32 = xxhash.XxHash32;
3838
39test "hash" {
39test {
4040 _ = adler;
4141 _ = auto_hash;
4242 _ = crc;
lib/std/math/big/int_test.zig+26
......@@ -915,6 +915,8 @@ test "big.int mul multi-single" {
915915}
916916
917917test "big.int mul multi-multi" {
918 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
919
918920 var op1: u256 = 0x998888efefefefefefefef;
919921 var op2: u256 = 0x333000abababababababab;
920922 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1034,6 +1036,8 @@ test "big.int mulWrap single-single signed" {
10341036}
10351037
10361038test "big.int mulWrap multi-multi unsigned" {
1039 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1040
10371041 var op1: u256 = 0x998888efefefefefefefef;
10381042 var op2: u256 = 0x333000abababababababab;
10391043 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1049,6 +1053,8 @@ test "big.int mulWrap multi-multi unsigned" {
10491053}
10501054
10511055test "big.int mulWrap multi-multi signed" {
1056 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1057
10521058 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);
10531059 defer a.deinit();
10541060 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));
......@@ -1252,6 +1258,8 @@ test "big.int div q=0 alias" {
12521258}
12531259
12541260test "big.int div multi-multi q < r" {
1261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1262
12551263 const op1 = 0x1ffffffff0078f432;
12561264 const op2 = 0x1ffffffff01000000;
12571265 var a = try Managed.initSet(testing.allocator, op1);
......@@ -1608,6 +1616,8 @@ test "big.int div floor positive close to zero" {
16081616}
16091617
16101618test "big.int div multi-multi with rem" {
1619 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1620
16111621 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
16121622 defer a.deinit();
16131623 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -1624,6 +1634,8 @@ test "big.int div multi-multi with rem" {
16241634}
16251635
16261636test "big.int div multi-multi no rem" {
1637 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1638
16271639 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
16281640 defer a.deinit();
16291641 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -1640,6 +1652,8 @@ test "big.int div multi-multi no rem" {
16401652}
16411653
16421654test "big.int div multi-multi (2 branch)" {
1655 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1656
16431657 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
16441658 defer a.deinit();
16451659 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
......@@ -1656,6 +1670,8 @@ test "big.int div multi-multi (2 branch)" {
16561670}
16571671
16581672test "big.int div multi-multi (3.1/3.3 branch)" {
1673 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1674
16591675 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
16601676 defer a.deinit();
16611677 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
......@@ -1672,6 +1688,8 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
16721688}
16731689
16741690test "big.int div multi-single zero-limb trailing" {
1691 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1692
16751693 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
16761694 defer a.deinit();
16771695 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
......@@ -1690,6 +1708,8 @@ test "big.int div multi-single zero-limb trailing" {
16901708}
16911709
16921710test "big.int div multi-multi zero-limb trailing (with rem)" {
1711 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1712
16931713 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
16941714 defer a.deinit();
16951715 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -1709,6 +1729,8 @@ test "big.int div multi-multi zero-limb trailing (with rem)" {
17091729}
17101730
17111731test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
1732 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1733
17121734 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
17131735 defer a.deinit();
17141736 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -1728,6 +1750,8 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li
17281750}
17291751
17301752test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
1753 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1754
17311755 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
17321756 defer a.deinit();
17331757 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
......@@ -2486,6 +2510,8 @@ test "big.int gcd non-one large" {
24862510}
24872511
24882512test "big.int gcd large multi-limb result" {
2513 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2514
24892515 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
24902516 defer a.deinit();
24912517 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
lib/std/math/complex.zig+1-1
......@@ -189,7 +189,7 @@ test "complex.magnitude" {
189189 try testing.expect(math.approxEqAbs(f32, c, 5.83095, epsilon));
190190}
191191
192test "complex.cmath" {
192test {
193193 _ = @import("complex/abs.zig");
194194 _ = @import("complex/acosh.zig");
195195 _ = @import("complex/acos.zig");
lib/std/mem.zig+6
......@@ -1504,6 +1504,8 @@ test "comptime read/write int" {
15041504}
15051505
15061506test "readIntBig and readIntLittle" {
1507 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1508
15071509 try testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0);
15081510 try testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0);
15091511
......@@ -1795,6 +1797,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
17951797}
17961798
17971799test "writeIntBig and writeIntLittle" {
1800 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1801
17981802 var buf0: [0]u8 = undefined;
17991803 var buf1: [1]u8 = undefined;
18001804 var buf2: [2]u8 = undefined;
......@@ -4011,6 +4015,8 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
40114015}
40124016
40134017test "read/write(Var)PackedInt" {
4018 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
4019
40144020 switch (builtin.cpu.arch) {
40154021 // This test generates too much code to execute on WASI.
40164022 // LLVM backend fails with "too many locals: locals exceed maximum"
lib/std/meta.zig+1-1
......@@ -10,7 +10,7 @@ pub const TrailerFlags = @import("meta/trailer_flags.zig").TrailerFlags;
1010
1111const Type = std.builtin.Type;
1212
13test "std.meta.TrailerFlags" {
13test {
1414 _ = TrailerFlags;
1515}
1616
lib/std/os/test.zig+6-2
......@@ -502,8 +502,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
502502}
503503
504504test "dl_iterate_phdr" {
505 if (native_os == .windows or native_os == .wasi or native_os == .macos)
506 return error.SkipZigTest;
505 if (builtin.object_format != .elf) return error.SkipZigTest;
507506
508507 var counter: usize = 0;
509508 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
......@@ -797,6 +796,11 @@ test "sigaction" {
797796 if (native_os == .linux and builtin.target.cpu.arch == .x86)
798797 return error.SkipZigTest;
799798
799 // https://github.com/ziglang/zig/issues/15381
800 if (native_os == .macos and builtin.target.cpu.arch == .x86_64) {
801 return error.SkipZigTest;
802 }
803
800804 const S = struct {
801805 var handler_called_count: u32 = 0;
802806
lib/std/rand/Xoshiro256.zig+2
......@@ -90,6 +90,8 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {
9090}
9191
9292test "xoroshiro sequence" {
93 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
94
9395 var r = Xoshiro256.init(0);
9496
9597 const seq1 = [_]u64{
lib/zig.h+619-349
......@@ -253,97 +253,6 @@ typedef char bool;
253253#define zig_concat(lhs, rhs) lhs##rhs
254254#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
255255
256#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
257#include <stdatomic.h>
258#define zig_atomic(type) _Atomic(type)
259#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
260#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
261#define zig_atomicrmw_xchg(obj, arg, order, type) atomic_exchange_explicit (obj, arg, order)
262#define zig_atomicrmw_add(obj, arg, order, type) atomic_fetch_add_explicit (obj, arg, order)
263#define zig_atomicrmw_sub(obj, arg, order, type) atomic_fetch_sub_explicit (obj, arg, order)
264#define zig_atomicrmw_or(obj, arg, order, type) atomic_fetch_or_explicit (obj, arg, order)
265#define zig_atomicrmw_xor(obj, arg, order, type) atomic_fetch_xor_explicit (obj, arg, order)
266#define zig_atomicrmw_and(obj, arg, order, type) atomic_fetch_and_explicit (obj, arg, order)
267#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand (obj, arg, order)
268#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
269#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
270#define zig_atomic_store(obj, arg, order, type) atomic_store_explicit (obj, arg, order)
271#define zig_atomic_load(obj, order, type) atomic_load_explicit (obj, order)
272#define zig_fence(order) atomic_thread_fence(order)
273#elif defined(__GNUC__)
274#define memory_order_relaxed __ATOMIC_RELAXED
275#define memory_order_consume __ATOMIC_CONSUME
276#define memory_order_acquire __ATOMIC_ACQUIRE
277#define memory_order_release __ATOMIC_RELEASE
278#define memory_order_acq_rel __ATOMIC_ACQ_REL
279#define memory_order_seq_cst __ATOMIC_SEQ_CST
280#define zig_atomic(type) type
281#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
282#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
283#define zig_atomicrmw_xchg(obj, arg, order, type) __atomic_exchange_n(obj, arg, order)
284#define zig_atomicrmw_add(obj, arg, order, type) __atomic_fetch_add (obj, arg, order)
285#define zig_atomicrmw_sub(obj, arg, order, type) __atomic_fetch_sub (obj, arg, order)
286#define zig_atomicrmw_or(obj, arg, order, type) __atomic_fetch_or (obj, arg, order)
287#define zig_atomicrmw_xor(obj, arg, order, type) __atomic_fetch_xor (obj, arg, order)
288#define zig_atomicrmw_and(obj, arg, order, type) __atomic_fetch_and (obj, arg, order)
289#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand(obj, arg, order)
290#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
291#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
292#define zig_atomic_store(obj, arg, order, type) __atomic_store_n (obj, arg, order)
293#define zig_atomic_load(obj, order, type) __atomic_load_n (obj, order)
294#define zig_fence(order) __atomic_thread_fence(order)
295#elif _MSC_VER && (_M_IX86 || _M_X64)
296#define memory_order_relaxed 0
297#define memory_order_consume 1
298#define memory_order_acquire 2
299#define memory_order_release 3
300#define memory_order_acq_rel 4
301#define memory_order_seq_cst 5
302#define zig_atomic(type) type
303#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, &(expected), desired)
304#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_cmpxchg_strong(obj, expected, desired, succ, fail, type)
305#define zig_atomicrmw_xchg(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xchg_, type)(obj, arg)
306#define zig_atomicrmw_add(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_add_, type)(obj, arg)
307#define zig_atomicrmw_sub(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_sub_, type)(obj, arg)
308#define zig_atomicrmw_or(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_or_, type)(obj, arg)
309#define zig_atomicrmw_xor(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xor_, type)(obj, arg)
310#define zig_atomicrmw_and(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_and_, type)(obj, arg)
311#define zig_atomicrmw_nand(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_nand_, type)(obj, arg)
312#define zig_atomicrmw_min(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_min_, type)(obj, arg)
313#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
314#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
315#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
316#if _M_X64
317#define zig_fence(order) __faststorefence()
318#else
319#define zig_fence(order) zig_msvc_atomic_barrier()
320#endif
321
322// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
323#else
324#define memory_order_relaxed 0
325#define memory_order_consume 1
326#define memory_order_acquire 2
327#define memory_order_release 3
328#define memory_order_acq_rel 4
329#define memory_order_seq_cst 5
330#define zig_atomic(type) type
331#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_unimplemented()
332#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_unimplemented()
333#define zig_atomicrmw_xchg(obj, arg, order, type) zig_unimplemented()
334#define zig_atomicrmw_add(obj, arg, order, type) zig_unimplemented()
335#define zig_atomicrmw_sub(obj, arg, order, type) zig_unimplemented()
336#define zig_atomicrmw_or(obj, arg, order, type) zig_unimplemented()
337#define zig_atomicrmw_xor(obj, arg, order, type) zig_unimplemented()
338#define zig_atomicrmw_and(obj, arg, order, type) zig_unimplemented()
339#define zig_atomicrmw_nand(obj, arg, order, type) zig_unimplemented()
340#define zig_atomicrmw_min(obj, arg, order, type) zig_unimplemented()
341#define zig_atomicrmw_max(obj, arg, order, type) zig_unimplemented()
342#define zig_atomic_store(obj, arg, order, type) zig_unimplemented()
343#define zig_atomic_load(obj, order, type) zig_unimplemented()
344#define zig_fence(order) zig_unimplemented()
345#endif
346
347256#if __STDC_VERSION__ >= 201112L
348257#define zig_noreturn _Noreturn
349258#elif zig_has_attribute(noreturn) || defined(zig_gnuc)
......@@ -502,15 +411,6 @@ typedef ptrdiff_t intptr_t;
502411
503412#endif
504413
505#define zig_make_small_i8(val) INT8_C(val)
506#define zig_make_small_u8(val) UINT8_C(val)
507#define zig_make_small_i16(val) INT16_C(val)
508#define zig_make_small_u16(val) UINT16_C(val)
509#define zig_make_small_i32(val) INT32_C(val)
510#define zig_make_small_u32(val) UINT32_C(val)
511#define zig_make_small_i64(val) INT64_C(val)
512#define zig_make_small_u64(val) UINT64_C(val)
513
514414#define zig_minInt_i8 INT8_MIN
515415#define zig_maxInt_i8 INT8_MAX
516416#define zig_minInt_u8 UINT8_C(0)
......@@ -534,24 +434,24 @@ typedef ptrdiff_t intptr_t;
534434#define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits)
535435#define zig_maxInt_u(w, bits) zig_intLimit(u, w, max, bits)
536436
537#define zig_int_operator(Type, RhsType, operation, operator) \
437#define zig_operator(Type, RhsType, operation, operator) \
538438 static inline Type zig_##operation(Type lhs, RhsType rhs) { \
539439 return lhs operator rhs; \
540440 }
541#define zig_int_basic_operator(Type, operation, operator) \
542 zig_int_operator(Type, Type, operation, operator)
543#define zig_int_shift_operator(Type, operation, operator) \
544 zig_int_operator(Type, uint8_t, operation, operator)
441#define zig_basic_operator(Type, operation, operator) \
442 zig_operator(Type, Type, operation, operator)
443#define zig_shift_operator(Type, operation, operator) \
444 zig_operator(Type, uint8_t, operation, operator)
545445#define zig_int_helpers(w) \
546 zig_int_basic_operator(uint##w##_t, and_u##w, &) \
547 zig_int_basic_operator( int##w##_t, and_i##w, &) \
548 zig_int_basic_operator(uint##w##_t, or_u##w, |) \
549 zig_int_basic_operator( int##w##_t, or_i##w, |) \
550 zig_int_basic_operator(uint##w##_t, xor_u##w, ^) \
551 zig_int_basic_operator( int##w##_t, xor_i##w, ^) \
552 zig_int_shift_operator(uint##w##_t, shl_u##w, <<) \
553 zig_int_shift_operator( int##w##_t, shl_i##w, <<) \
554 zig_int_shift_operator(uint##w##_t, shr_u##w, >>) \
446 zig_basic_operator(uint##w##_t, and_u##w, &) \
447 zig_basic_operator( int##w##_t, and_i##w, &) \
448 zig_basic_operator(uint##w##_t, or_u##w, |) \
449 zig_basic_operator( int##w##_t, or_i##w, |) \
450 zig_basic_operator(uint##w##_t, xor_u##w, ^) \
451 zig_basic_operator( int##w##_t, xor_i##w, ^) \
452 zig_shift_operator(uint##w##_t, shl_u##w, <<) \
453 zig_shift_operator( int##w##_t, shl_i##w, <<) \
454 zig_shift_operator(uint##w##_t, shr_u##w, >>) \
555455\
556456 static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \
557457 int##w##_t sign_mask = lhs < INT##w##_C(0) ? -INT##w##_C(1) : INT##w##_C(0); \
......@@ -576,13 +476,13 @@ typedef ptrdiff_t intptr_t;
576476 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
577477 } \
578478\
579 zig_int_basic_operator(uint##w##_t, div_floor_u##w, /) \
479 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \
580480\
581481 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \
582482 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < INT##w##_C(0)); \
583483 } \
584484\
585 zig_int_basic_operator(uint##w##_t, mod_u##w, %) \
485 zig_basic_operator(uint##w##_t, mod_u##w, %) \
586486\
587487 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
588488 int##w##_t rem = lhs % rhs; \
......@@ -1253,8 +1153,8 @@ typedef signed __int128 zig_i128;
12531153#define zig_lo_u128(val) ((uint64_t)((val) >> 0))
12541154#define zig_hi_i128(val) (( int64_t)((val) >> 64))
12551155#define zig_lo_i128(val) ((uint64_t)((val) >> 0))
1256#define zig_bitcast_u128(val) ((zig_u128)(val))
1257#define zig_bitcast_i128(val) ((zig_i128)(val))
1156#define zig_bitCast_u128(val) ((zig_u128)(val))
1157#define zig_bitCast_i128(val) ((zig_i128)(val))
12581158#define zig_cmp_int128(Type) \
12591159 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
12601160 return (lhs > rhs) - (lhs < rhs); \
......@@ -1288,8 +1188,8 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
12881188#define zig_lo_u128(val) ((val).lo)
12891189#define zig_hi_i128(val) ((val).hi)
12901190#define zig_lo_i128(val) ((val).lo)
1291#define zig_bitcast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)
1292#define zig_bitcast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)
1191#define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)
1192#define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)
12931193#define zig_cmp_int128(Type) \
12941194 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
12951195 return (lhs.hi == rhs.hi) \
......@@ -1303,9 +1203,6 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
13031203
13041204#endif /* zig_has_int128 */
13051205
1306#define zig_make_small_u128(val) zig_make_u128(0, val)
1307#define zig_make_small_i128(val) zig_make_i128((val) < 0 ? -INT64_C(1) : INT64_C(0), val)
1308
13091206#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
13101207#define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64)
13111208#define zig_minInt_i128 zig_make_i128(zig_minInt_i64, zig_minInt_u64)
......@@ -1466,18 +1363,18 @@ static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
14661363}
14671364
14681365static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
1469 return zig_bitcast_u128(zig_mul_i128(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));
1366 return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs)));
14701367}
14711368
14721369zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
14731370static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
14741371 return __udivti3(lhs, rhs);
1475};
1372}
14761373
14771374zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
14781375static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
14791376 return __divti3(lhs, rhs);
1480};
1377}
14811378
14821379zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
14831380static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
......@@ -1503,10 +1400,6 @@ static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
15031400#define zig_div_floor_u128 zig_div_trunc_u128
15041401#define zig_mod_u128 zig_rem_u128
15051402
1506static inline zig_u128 zig_nand_u128(zig_u128 lhs, zig_u128 rhs) {
1507 return zig_not_u128(zig_and_u128(lhs, rhs), 128);
1508}
1509
15101403static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) {
15111404 return zig_cmp_u128(lhs, rhs) < INT32_C(0) ? lhs : rhs;
15121405}
......@@ -1538,7 +1431,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
15381431}
15391432
15401433static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
1541 return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), rhs)), bits);
1434 return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits);
15421435}
15431436
15441437static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
......@@ -1546,7 +1439,7 @@ static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
15461439}
15471440
15481441static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1549 return zig_wrap_i128(zig_bitcast_i128(zig_add_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1442 return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
15501443}
15511444
15521445static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
......@@ -1554,7 +1447,7 @@ static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
15541447}
15551448
15561449static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1557 return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1450 return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
15581451}
15591452
15601453static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
......@@ -1562,7 +1455,7 @@ static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
15621455}
15631456
15641457static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1565 return zig_wrap_i128(zig_bitcast_i128(zig_mul_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);
1458 return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
15661459}
15671460
15681461#if zig_has_int128
......@@ -1697,7 +1590,7 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
16971590
16981591static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
16991592 *res = zig_shlw_i128(lhs, rhs, bits);
1700 zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));
1593 zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));
17011594 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
17021595 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
17031596}
......@@ -1711,7 +1604,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
17111604
17121605static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
17131606 zig_i128 res;
1714 if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;
1607 if (zig_cmp_u128(zig_bitCast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;
17151608 return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
17161609}
17171610
......@@ -1755,7 +1648,7 @@ static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {
17551648}
17561649
17571650static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {
1758 return zig_clz_u128(zig_bitcast_u128(val), bits);
1651 return zig_clz_u128(zig_bitCast_u128(val), bits);
17591652}
17601653
17611654static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {
......@@ -1764,7 +1657,7 @@ static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {
17641657}
17651658
17661659static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {
1767 return zig_ctz_u128(zig_bitcast_u128(val), bits);
1660 return zig_ctz_u128(zig_bitCast_u128(val), bits);
17681661}
17691662
17701663static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {
......@@ -1773,7 +1666,7 @@ static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {
17731666}
17741667
17751668static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {
1776 return zig_popcount_u128(zig_bitcast_u128(val), bits);
1669 return zig_popcount_u128(zig_bitCast_u128(val), bits);
17771670}
17781671
17791672static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {
......@@ -1788,7 +1681,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {
17881681}
17891682
17901683static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {
1791 return zig_bitcast_i128(zig_byte_swap_u128(zig_bitcast_u128(val), bits));
1684 return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits));
17921685}
17931686
17941687static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {
......@@ -1798,7 +1691,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {
17981691}
17991692
18001693static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
1801 return zig_bitcast_i128(zig_bit_reverse_u128(zig_bitcast_u128(val), bits));
1694 return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits));
18021695}
18031696
18041697/* ========================== Big Integer Support =========================== */
......@@ -1972,6 +1865,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
19721865 return 0;
19731866}
19741867
1868static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1869 uint8_t *res_bytes = res;
1870 const uint8_t *lhs_bytes = lhs;
1871 const uint8_t *rhs_bytes = rhs;
1872 uint16_t byte_offset = 0;
1873 uint16_t remaining_bytes = zig_int_bytes(bits);
1874 (void)is_signed;
1875
1876 while (remaining_bytes >= 128 / CHAR_BIT) {
1877 zig_u128 res_limb;
1878 zig_u128 lhs_limb;
1879 zig_u128 rhs_limb;
1880
1881 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1882 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1883 res_limb = zig_and_u128(lhs_limb, rhs_limb);
1884 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1885
1886 remaining_bytes -= 128 / CHAR_BIT;
1887 byte_offset += 128 / CHAR_BIT;
1888 }
1889
1890 while (remaining_bytes >= 64 / CHAR_BIT) {
1891 uint64_t res_limb;
1892 uint64_t lhs_limb;
1893 uint64_t rhs_limb;
1894
1895 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1896 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1897 res_limb = zig_and_u64(lhs_limb, rhs_limb);
1898 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1899
1900 remaining_bytes -= 64 / CHAR_BIT;
1901 byte_offset += 64 / CHAR_BIT;
1902 }
1903
1904 while (remaining_bytes >= 32 / CHAR_BIT) {
1905 uint32_t res_limb;
1906 uint32_t lhs_limb;
1907 uint32_t rhs_limb;
1908
1909 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1910 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1911 res_limb = zig_and_u32(lhs_limb, rhs_limb);
1912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1913
1914 remaining_bytes -= 32 / CHAR_BIT;
1915 byte_offset += 32 / CHAR_BIT;
1916 }
1917
1918 while (remaining_bytes >= 16 / CHAR_BIT) {
1919 uint16_t res_limb;
1920 uint16_t lhs_limb;
1921 uint16_t rhs_limb;
1922
1923 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1924 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1925 res_limb = zig_and_u16(lhs_limb, rhs_limb);
1926 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1927
1928 remaining_bytes -= 16 / CHAR_BIT;
1929 byte_offset += 16 / CHAR_BIT;
1930 }
1931
1932 while (remaining_bytes >= 8 / CHAR_BIT) {
1933 uint8_t res_limb;
1934 uint8_t lhs_limb;
1935 uint8_t rhs_limb;
1936
1937 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1938 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1939 res_limb = zig_and_u8(lhs_limb, rhs_limb);
1940 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1941
1942 remaining_bytes -= 8 / CHAR_BIT;
1943 byte_offset += 8 / CHAR_BIT;
1944 }
1945}
1946
1947static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1948 uint8_t *res_bytes = res;
1949 const uint8_t *lhs_bytes = lhs;
1950 const uint8_t *rhs_bytes = rhs;
1951 uint16_t byte_offset = 0;
1952 uint16_t remaining_bytes = zig_int_bytes(bits);
1953 (void)is_signed;
1954
1955 while (remaining_bytes >= 128 / CHAR_BIT) {
1956 zig_u128 res_limb;
1957 zig_u128 lhs_limb;
1958 zig_u128 rhs_limb;
1959
1960 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1961 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1962 res_limb = zig_or_u128(lhs_limb, rhs_limb);
1963 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1964
1965 remaining_bytes -= 128 / CHAR_BIT;
1966 byte_offset += 128 / CHAR_BIT;
1967 }
1968
1969 while (remaining_bytes >= 64 / CHAR_BIT) {
1970 uint64_t res_limb;
1971 uint64_t lhs_limb;
1972 uint64_t rhs_limb;
1973
1974 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1975 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1976 res_limb = zig_or_u64(lhs_limb, rhs_limb);
1977 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1978
1979 remaining_bytes -= 64 / CHAR_BIT;
1980 byte_offset += 64 / CHAR_BIT;
1981 }
1982
1983 while (remaining_bytes >= 32 / CHAR_BIT) {
1984 uint32_t res_limb;
1985 uint32_t lhs_limb;
1986 uint32_t 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_or_u32(lhs_limb, rhs_limb);
1991 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1992
1993 remaining_bytes -= 32 / CHAR_BIT;
1994 byte_offset += 32 / CHAR_BIT;
1995 }
1996
1997 while (remaining_bytes >= 16 / CHAR_BIT) {
1998 uint16_t res_limb;
1999 uint16_t lhs_limb;
2000 uint16_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_or_u16(lhs_limb, rhs_limb);
2005 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2006
2007 remaining_bytes -= 16 / CHAR_BIT;
2008 byte_offset += 16 / CHAR_BIT;
2009 }
2010
2011 while (remaining_bytes >= 8 / CHAR_BIT) {
2012 uint8_t res_limb;
2013 uint8_t lhs_limb;
2014 uint8_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_or_u8(lhs_limb, rhs_limb);
2019 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2020
2021 remaining_bytes -= 8 / CHAR_BIT;
2022 byte_offset += 8 / CHAR_BIT;
2023 }
2024}
2025
2026static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2027 uint8_t *res_bytes = res;
2028 const uint8_t *lhs_bytes = lhs;
2029 const uint8_t *rhs_bytes = rhs;
2030 uint16_t byte_offset = 0;
2031 uint16_t remaining_bytes = zig_int_bytes(bits);
2032 (void)is_signed;
2033
2034 while (remaining_bytes >= 128 / CHAR_BIT) {
2035 zig_u128 res_limb;
2036 zig_u128 lhs_limb;
2037 zig_u128 rhs_limb;
2038
2039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2040 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2041 res_limb = zig_xor_u128(lhs_limb, rhs_limb);
2042 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2043
2044 remaining_bytes -= 128 / CHAR_BIT;
2045 byte_offset += 128 / CHAR_BIT;
2046 }
2047
2048 while (remaining_bytes >= 64 / CHAR_BIT) {
2049 uint64_t res_limb;
2050 uint64_t lhs_limb;
2051 uint64_t rhs_limb;
2052
2053 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2054 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2055 res_limb = zig_xor_u64(lhs_limb, rhs_limb);
2056 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2057
2058 remaining_bytes -= 64 / CHAR_BIT;
2059 byte_offset += 64 / CHAR_BIT;
2060 }
2061
2062 while (remaining_bytes >= 32 / CHAR_BIT) {
2063 uint32_t res_limb;
2064 uint32_t lhs_limb;
2065 uint32_t 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_xor_u32(lhs_limb, rhs_limb);
2070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2071
2072 remaining_bytes -= 32 / CHAR_BIT;
2073 byte_offset += 32 / CHAR_BIT;
2074 }
2075
2076 while (remaining_bytes >= 16 / CHAR_BIT) {
2077 uint16_t res_limb;
2078 uint16_t lhs_limb;
2079 uint16_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_xor_u16(lhs_limb, rhs_limb);
2084 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2085
2086 remaining_bytes -= 16 / CHAR_BIT;
2087 byte_offset += 16 / CHAR_BIT;
2088 }
2089
2090 while (remaining_bytes >= 8 / CHAR_BIT) {
2091 uint8_t res_limb;
2092 uint8_t lhs_limb;
2093 uint8_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_xor_u8(lhs_limb, rhs_limb);
2098 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2099
2100 remaining_bytes -= 8 / CHAR_BIT;
2101 byte_offset += 8 / CHAR_BIT;
2102 }
2103}
2104
19752105static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
19762106 uint8_t *res_bytes = res;
19772107 const uint8_t *lhs_bytes = lhs;
......@@ -2827,24 +2957,20 @@ long double __cdecl nanl(char const* input);
28272957#endif
28282958
28292959#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gnuc)
2830#define zig_has_float_builtins 1
2831#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16(__builtin_##name, )(arg)
2832#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32(__builtin_##name, )(arg)
2833#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64(__builtin_##name, )(arg)
2834#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80(__builtin_##name, )(arg)
2960#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16 (__builtin_##name, )(arg)
2961#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32 (__builtin_##name, )(arg)
2962#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64 (__builtin_##name, )(arg)
2963#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
28352964#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
28362965#else
2837#define zig_has_float_builtins 0
2838#define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr)
2839#define zig_make_special_f32(sign, name, arg, repr) zig_float_from_repr_f32(repr)
2840#define zig_make_special_f64(sign, name, arg, repr) zig_float_from_repr_f64(repr)
2841#define zig_make_special_f80(sign, name, arg, repr) zig_float_from_repr_f80(repr)
2842#define zig_make_special_f128(sign, name, arg, repr) zig_float_from_repr_f128(repr)
2966#define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr)
2967#define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr)
2968#define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr)
2969#define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr)
2970#define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr)
28432971#endif
28442972
28452973#define zig_has_f16 1
2846#define zig_bitSizeOf_f16 16
2847typedef uint16_t zig_repr_f16;
28482974#define zig_libc_name_f16(name) __##name##h
28492975#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
28502976#if FLT_MANT_DIG == 11
......@@ -2854,10 +2980,6 @@ typedef float zig_f16;
28542980typedef double zig_f16;
28552981#define zig_make_f16(fp, repr) fp
28562982#elif LDBL_MANT_DIG == 11
2857#define zig_bitSizeOf_c_longdouble 16
2858#ifndef ZIG_TARGET_ABI_MSVC
2859typedef zig_repr_f16 zig_repr_c_longdouble;
2860#endif
28612983typedef long double zig_f16;
28622984#define zig_make_f16(fp, repr) fp##l
28632985#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
......@@ -2869,8 +2991,8 @@ typedef __fp16 zig_f16;
28692991#else
28702992#undef zig_has_f16
28712993#define zig_has_f16 0
2872#define zig_bitSizeOf_repr_f16 16
2873typedef zig_repr_f16 zig_f16;
2994#define zig_repr_f16 u16
2995typedef uint16_t zig_f16;
28742996#define zig_make_f16(fp, repr) repr
28752997#undef zig_make_special_f16
28762998#define zig_make_special_f16(sign, name, arg, repr) repr
......@@ -2878,15 +3000,12 @@ typedef zig_repr_f16 zig_f16;
28783000#define zig_init_special_f16(sign, name, arg, repr) repr
28793001#endif
28803002#if __APPLE__ && (defined(__i386__) || defined(__x86_64__))
2881typedef zig_repr_f16 zig_compiler_rt_f16;
3003typedef uint16_t zig_compiler_rt_f16;
28823004#else
28833005typedef zig_f16 zig_compiler_rt_f16;
28843006#endif
2885#define zig_compiler_rt_abbrev_zig_compiler_rt_f16 zig_compiler_rt_abbrev_zig_f16
28863007
28873008#define zig_has_f32 1
2888#define zig_bitSizeOf_f32 32
2889typedef uint32_t zig_repr_f32;
28903009#define zig_libc_name_f32(name) name##f
28913010#if _MSC_VER
28923011#define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )
......@@ -2900,10 +3019,6 @@ typedef float zig_f32;
29003019typedef double zig_f32;
29013020#define zig_make_f32(fp, repr) fp
29023021#elif LDBL_MANT_DIG == 24
2903#define zig_bitSizeOf_c_longdouble 32
2904#ifndef ZIG_TARGET_ABI_MSVC
2905typedef zig_repr_f32 zig_repr_c_longdouble;
2906#endif
29073022typedef long double zig_f32;
29083023#define zig_make_f32(fp, repr) fp##l
29093024#elif FLT32_MANT_DIG == 24
......@@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32;
29123027#else
29133028#undef zig_has_f32
29143029#define zig_has_f32 0
2915#define zig_bitSizeOf_repr_f32 32
2916typedef zig_repr_f32 zig_f32;
3030#define zig_repr_f32 u32
3031ypedef uint32_t zig_f32;
29173032#define zig_make_f32(fp, repr) repr
29183033#undef zig_make_special_f32
29193034#define zig_make_special_f32(sign, name, arg, repr) repr
......@@ -2922,20 +3037,12 @@ typedef zig_repr_f32 zig_f32;
29223037#endif
29233038
29243039#define zig_has_f64 1
2925#define zig_bitSizeOf_f64 64
2926typedef uint64_t zig_repr_f64;
29273040#define zig_libc_name_f64(name) name
29283041#if _MSC_VER
2929#ifdef ZIG_TARGET_ABI_MSVC
2930#define zig_bitSizeOf_c_longdouble 64
2931#ifndef ZIG_TARGET_ABI_MSVC
2932typedef zig_repr_f64 zig_repr_c_longdouble;
2933#endif
2934#endif
29353042#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
2936#else /* _MSC_VER */
3043#else
29373044#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
2938#endif /* _MSC_VER */
3045#endif
29393046#if FLT_MANT_DIG == 53
29403047typedef float zig_f64;
29413048#define zig_make_f64(fp, repr) fp##f
......@@ -2943,10 +3050,6 @@ typedef float zig_f64;
29433050typedef double zig_f64;
29443051#define zig_make_f64(fp, repr) fp
29453052#elif LDBL_MANT_DIG == 53
2946#define zig_bitSizeOf_c_longdouble 64
2947#ifndef ZIG_TARGET_ABI_MSVC
2948typedef zig_repr_f64 zig_repr_c_longdouble;
2949#endif
29503053typedef long double zig_f64;
29513054#define zig_make_f64(fp, repr) fp##l
29523055#elif FLT64_MANT_DIG == 53
......@@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64;
29583061#else
29593062#undef zig_has_f64
29603063#define zig_has_f64 0
2961#define zig_bitSizeOf_repr_f64 64
2962typedef zig_repr_f64 zig_f64;
3064#define zig_repr_f64 u64
3065typedef uint64_t zig_f64;
29633066#define zig_make_f64(fp, repr) repr
29643067#undef zig_make_special_f64
29653068#define zig_make_special_f64(sign, name, arg, repr) repr
......@@ -2968,8 +3071,6 @@ typedef zig_repr_f64 zig_f64;
29683071#endif
29693072
29703073#define zig_has_f80 1
2971#define zig_bitSizeOf_f80 80
2972typedef zig_u128 zig_repr_f80;
29733074#define zig_libc_name_f80(name) __##name##x
29743075#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
29753076#if FLT_MANT_DIG == 64
......@@ -2979,10 +3080,6 @@ typedef float zig_f80;
29793080typedef double zig_f80;
29803081#define zig_make_f80(fp, repr) fp
29813082#elif LDBL_MANT_DIG == 64
2982#define zig_bitSizeOf_c_longdouble 80
2983#ifndef ZIG_TARGET_ABI_MSVC
2984typedef zig_repr_f80 zig_repr_c_longdouble;
2985#endif
29863083typedef long double zig_f80;
29873084#define zig_make_f80(fp, repr) fp##l
29883085#elif FLT80_MANT_DIG == 64
......@@ -2997,8 +3094,8 @@ typedef __float80 zig_f80;
29973094#else
29983095#undef zig_has_f80
29993096#define zig_has_f80 0
3000#define zig_bitSizeOf_repr_f80 128
3001typedef zig_repr_f80 zig_f80;
3097#define zig_repr_f80 u128
3098typedef zig_u128 zig_f80;
30023099#define zig_make_f80(fp, repr) repr
30033100#undef zig_make_special_f80
30043101#define zig_make_special_f80(sign, name, arg, repr) repr
......@@ -3007,8 +3104,6 @@ typedef zig_repr_f80 zig_f80;
30073104#endif
30083105
30093106#define zig_has_f128 1
3010#define zig_bitSizeOf_f128 128
3011typedef zig_u128 zig_repr_f128;
30123107#define zig_libc_name_f128(name) name##q
30133108#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
30143109#if FLT_MANT_DIG == 113
......@@ -3018,10 +3113,6 @@ typedef float zig_f128;
30183113typedef double zig_f128;
30193114#define zig_make_f128(fp, repr) fp
30203115#elif LDBL_MANT_DIG == 113
3021#define zig_bitSizeOf_c_longdouble 128
3022#ifndef ZIG_TARGET_ABI_MSVC
3023typedef zig_repr_f128 zig_repr_c_longdouble;
3024#endif
30253116typedef long double zig_f128;
30263117#define zig_make_f128(fp, repr) fp##l
30273118#elif FLT128_MANT_DIG == 113
......@@ -3038,50 +3129,49 @@ typedef __float128 zig_f128;
30383129#else
30393130#undef zig_has_f128
30403131#define zig_has_f128 0
3041#define zig_bitSizeOf_repr_f128 128
3042typedef zig_repr_f128 zig_f128;
3043#define zig_make_f128(fp, repr) repr
30443132#undef zig_make_special_f128
3045#define zig_make_special_f128(sign, name, arg, repr) repr
30463133#undef zig_init_special_f128
3134#if __APPLE__ || defined(__aarch64__)
3135typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;
3136zig_basic_operator(zig_v2u64, xor_v2u64, ^)
3137#define zig_repr_f128 v2u64
3138typedef zig_v2u64 zig_f128;
3139#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }
3140#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128
3141#define zig_make_f128(fp, repr) zig_make_f128_##repr
3142#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3143#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3144#else
3145#define zig_repr_f128 u128
3146typedef zig_u128 zig_f128;
3147#define zig_make_f128(fp, repr) repr
3148#define zig_make_special_f128(sign, name, arg, repr) repr
30473149#define zig_init_special_f128(sign, name, arg, repr) repr
30483150#endif
3151#endif
30493152
3050#ifdef zig_bitSizeOf_c_longdouble
3051
3052#define zig_has_c_longdouble 1
3053#ifdef ZIG_TARGET_ABI_MSVC
3054#undef zig_bitSizeOf_c_longdouble
3055#define zig_bitSizeOf_c_longdouble 64
3153#if !_MSC_VER && defined(ZIG_TARGET_ABI_MSVC)
3154/* Emulate msvc abi on a gnu compiler */
30563155typedef zig_f64 zig_c_longdouble;
3057typedef zig_repr_f64 zig_repr_c_longdouble;
3156#elif _MSC_VER && !defined(ZIG_TARGET_ABI_MSVC)
3157/* Emulate gnu abi on an msvc compiler */
3158typedef zig_f128 zig_c_longdouble;
30583159#else
3160/* Target and compiler abi match */
30593161typedef long double zig_c_longdouble;
30603162#endif
30613163
3062#else /* zig_bitSizeOf_c_longdouble */
3063
3064#define zig_has_c_longdouble 0
3065#define zig_bitSizeOf_repr_c_longdouble 128
3066typedef zig_f128 zig_c_longdouble;
3067typedef zig_repr_f128 zig_repr_c_longdouble;
3068
3069#endif /* zig_bitSizeOf_c_longdouble */
3070
3071#if !zig_has_float_builtins
3072#define zig_float_from_repr(Type) \
3073 static inline zig_##Type zig_float_from_repr_##Type(zig_repr_##Type repr) { \
3164#define zig_bitCast_float(Type, ReprType) \
3165 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \
30743166 zig_##Type result; \
30753167 memcpy(&result, &repr, sizeof(result)); \
30763168 return result; \
30773169 }
3078
3079zig_float_from_repr(f16)
3080zig_float_from_repr(f32)
3081zig_float_from_repr(f64)
3082zig_float_from_repr(f80)
3083zig_float_from_repr(f128)
3084#endif
3170zig_bitCast_float(f16, uint16_t)
3171zig_bitCast_float(f32, uint32_t)
3172zig_bitCast_float(f64, uint64_t)
3173zig_bitCast_float(f80, zig_u128)
3174zig_bitCast_float(f128, zig_u128)
30853175
30863176#define zig_cast_f16 (zig_f16)
30873177#define zig_cast_f32 (zig_f32)
......@@ -3095,44 +3185,53 @@ zig_float_from_repr(f128)
30953185#define zig_cast_f128 (zig_f128)
30963186#endif
30973187
3098#define zig_convert_builtin(ResType, operation, ArgType, version) \
3099 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3100 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType);
3101zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f32, 2)
3102zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f64, 2)
3103zig_convert_builtin(zig_f16, trunc, zig_f80, 2)
3104zig_convert_builtin(zig_f16, trunc, zig_f128, 2)
3105zig_convert_builtin(zig_f32, extend, zig_compiler_rt_f16, 2)
3106zig_convert_builtin(zig_f32, trunc, zig_f64, 2)
3107zig_convert_builtin(zig_f32, trunc, zig_f80, 2)
3108zig_convert_builtin(zig_f32, trunc, zig_f128, 2)
3109zig_convert_builtin(zig_f64, extend, zig_compiler_rt_f16, 2)
3110zig_convert_builtin(zig_f64, extend, zig_f32, 2)
3111zig_convert_builtin(zig_f64, trunc, zig_f80, 2)
3112zig_convert_builtin(zig_f64, trunc, zig_f128, 2)
3113zig_convert_builtin(zig_f80, extend, zig_f16, 2)
3114zig_convert_builtin(zig_f80, extend, zig_f32, 2)
3115zig_convert_builtin(zig_f80, extend, zig_f64, 2)
3116zig_convert_builtin(zig_f80, trunc, zig_f128, 2)
3117zig_convert_builtin(zig_f128, extend, zig_f16, 2)
3118zig_convert_builtin(zig_f128, extend, zig_f32, 2)
3119zig_convert_builtin(zig_f128, extend, zig_f64, 2)
3120zig_convert_builtin(zig_f128, extend, zig_f80, 2)
3121
3122#define zig_float_negate_builtin_0(w) \
3123 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3124 return zig_expand_concat(zig_xor_u, zig_bitSizeOf_repr_f##w)( \
3125 arg, \
3126 zig_expand_concat(zig_shl_u, zig_bitSizeOf_repr_f##w)( \
3127 zig_expand_concat(zig_make_small_u, zig_bitSizeOf_repr_f##w)(1), \
3128 UINT8_C(w - 1) \
3129 ) \
3130 ); \
3131 }
3132#define zig_float_negate_builtin_1(w) \
3188#define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \
3189 zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3190 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \
3191 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
3192 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
3193 ResType res; \
3194 ExternResType extern_res; \
3195 ExternArgType extern_arg; \
3196 memcpy(&extern_arg, &arg, sizeof(extern_arg)); \
3197 extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3198 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \
3199 memcpy(&res, &extern_res, sizeof(res)); \
3200 return extern_res; \
3201 }
3202zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)
3203zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)
3204zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)
3205zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)
3206zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)
3207zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3208zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)
3209zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)
3210zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)
3211zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3212zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)
3213zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)
3214zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)
3215zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)
3216zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)
3217zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3218zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3219zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3220zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3221zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2)
3222
3223#define zig_float_negate_builtin_0(w, c, sb) \
3224 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb))
3225#define zig_float_negate_builtin_1(w, c, sb) -arg
3226#define zig_float_negate_builtin(w, c, sb) \
31333227 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3134 return -arg; \
3228 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \
31353229 }
3230zig_float_negate_builtin(16, , UINT16_C(1) << 15 )
3231zig_float_negate_builtin(32, , UINT32_C(1) << 31 )
3232zig_float_negate_builtin(64, , UINT64_C(1) << 63 )
3233zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))
3234zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
31363235
31373236#define zig_float_less_builtin_0(Type, operation) \
31383237 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \
......@@ -3164,19 +3263,18 @@ zig_convert_builtin(zig_f128, extend, zig_f80, 2)
31643263 }
31653264
31663265#define zig_float_builtins(w) \
3167 zig_convert_builtin( int32_t, fix, zig_f##w, ) \
3168 zig_convert_builtin(uint32_t, fixuns, zig_f##w, ) \
3169 zig_convert_builtin( int64_t, fix, zig_f##w, ) \
3170 zig_convert_builtin(uint64_t, fixuns, zig_f##w, ) \
3171 zig_convert_builtin(zig_i128, fix, zig_f##w, ) \
3172 zig_convert_builtin(zig_u128, fixuns, zig_f##w, ) \
3173 zig_convert_builtin(zig_f##w, float, int32_t, ) \
3174 zig_convert_builtin(zig_f##w, floatun, uint32_t, ) \
3175 zig_convert_builtin(zig_f##w, float, int64_t, ) \
3176 zig_convert_builtin(zig_f##w, floatun, uint64_t, ) \
3177 zig_convert_builtin(zig_f##w, float, zig_i128, ) \
3178 zig_convert_builtin(zig_f##w, floatun, zig_u128, ) \
3179 zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w) \
3266 zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \
3267 zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \
3268 zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \
3269 zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \
3270 zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \
3271 zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \
3272 zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \
3273 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \
3274 zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \
3275 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) \
3276 zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \
3277 zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \
31803278 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
31813279 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
31823280 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
......@@ -3224,9 +3322,238 @@ zig_float_builtins(64)
32243322zig_float_builtins(80)
32253323zig_float_builtins(128)
32263324
3325/* ============================ Atomics Support ============================= */
3326
3327/* Note that atomics should be implemented as macros because most
3328 compilers silently discard runtime atomic order information. */
3329
3330/* Define fallback implementations first that can later be undef'd on compilers with builtin support. */
3331/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
3332#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
3333 zig_##Type zig_atomicrmw_expected; \
3334 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3335 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3336 res = zig_atomicrmw_expected; \
3337} while (0)
3338#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
3339 zig_##Type zig_atomicrmw_expected; \
3340 zig_##Type zig_atomicrmw_desired; \
3341 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3342 do { \
3343 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3344 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3345 res = zig_atomicrmw_expected; \
3346} while (0)
3347#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
3348 zig_##Type zig_atomicrmw_expected; \
3349 zig_##Type zig_atomicrmw_desired; \
3350 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3351 do { \
3352 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3353 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3354 res = zig_atomicrmw_expected; \
3355} while (0)
3356#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
3357 zig_##Type zig_atomicrmw_expected; \
3358 zig_##Type zig_atomicrmw_desired; \
3359 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3360 do { \
3361 zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \
3362 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3363 res = zig_atomicrmw_expected; \
3364} while (0)
3365#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
3366 zig_##Type zig_atomicrmw_expected; \
3367 zig_##Type zig_atomicrmw_desired; \
3368 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3369 do { \
3370 zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \
3371 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3372 res = zig_atomicrmw_expected; \
3373} while (0)
3374
3375#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
3376 zig_##Type zig_atomicrmw_expected; \
3377 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3378 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3379 res = zig_atomicrmw_expected; \
3380} while (0)
3381#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
3382 zig_##Type zig_atomicrmw_expected; \
3383 zig_##Type zig_atomicrmw_desired; \
3384 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3385 do { \
3386 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3387 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3388 res = zig_atomicrmw_expected; \
3389} while (0)
3390#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
3391 zig_##Type zig_atomicrmw_expected; \
3392 zig_##Type zig_atomicrmw_desired; \
3393 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3394 do { \
3395 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3396 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3397 res = zig_atomicrmw_expected; \
3398} while (0)
3399#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
3400 zig_##Type zig_atomicrmw_expected; \
3401 zig_##Type zig_atomicrmw_desired; \
3402 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3403 do { \
3404 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \
3405 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3406 res = zig_atomicrmw_expected; \
3407} while (0)
3408#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
3409 zig_##Type zig_atomicrmw_expected; \
3410 zig_##Type zig_atomicrmw_desired; \
3411 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3412 do { \
3413 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \
3414 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3415 res = zig_atomicrmw_expected; \
3416} while (0)
3417#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
3418 zig_##Type zig_atomicrmw_expected; \
3419 zig_##Type zig_atomicrmw_desired; \
3420 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3421 do { \
3422 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \
3423 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3424 res = zig_atomicrmw_expected; \
3425} while (0)
3426#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
3427 zig_##Type zig_atomicrmw_expected; \
3428 zig_##Type zig_atomicrmw_desired; \
3429 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3430 do { \
3431 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \
3432 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3433 res = zig_atomicrmw_expected; \
3434} while (0)
3435#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
3436 zig_##Type zig_atomicrmw_expected; \
3437 zig_##Type zig_atomicrmw_desired; \
3438 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3439 do { \
3440 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
3441 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3442 res = zig_atomicrmw_expected; \
3443} while (0)
3444#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
3445 zig_##Type zig_atomicrmw_expected; \
3446 zig_##Type zig_atomicrmw_desired; \
3447 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3448 do { \
3449 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
3450 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3451 res = zig_atomicrmw_expected; \
3452} while (0)
3453
3454#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
3455#include <stdatomic.h>
3456typedef enum memory_order zig_memory_order;
3457#define zig_atomic(Type) _Atomic(Type)
3458#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
3459#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
3460#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = atomic_exchange_explicit (obj, arg, order)
3461#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = atomic_fetch_add_explicit (obj, arg, order)
3462#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = atomic_fetch_sub_explicit (obj, arg, order)
3463#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = atomic_fetch_or_explicit (obj, arg, order)
3464#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = atomic_fetch_xor_explicit (obj, arg, order)
3465#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = atomic_fetch_and_explicit (obj, arg, order)
3466#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3467#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3468#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3469#define zig_atomic_store( obj, arg, order, Type, ReprType) atomic_store_explicit (obj, arg, order)
3470#define zig_atomic_load(res, obj, order, Type, ReprType) res = atomic_load_explicit (obj, order)
3471#undef zig_atomicrmw_xchg_float
3472#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3473#undef zig_atomicrmw_add_float
3474#define zig_atomicrmw_add_float zig_atomicrmw_add
3475#undef zig_atomicrmw_sub_float
3476#define zig_atomicrmw_sub_float zig_atomicrmw_sub
3477#define zig_fence(order) atomic_thread_fence(order)
3478#elif defined(__GNUC__)
3479typedef int zig_memory_order;
3480#define memory_order_relaxed __ATOMIC_RELAXED
3481#define memory_order_consume __ATOMIC_CONSUME
3482#define memory_order_acquire __ATOMIC_ACQUIRE
3483#define memory_order_release __ATOMIC_RELEASE
3484#define memory_order_acq_rel __ATOMIC_ACQ_REL
3485#define memory_order_seq_cst __ATOMIC_SEQ_CST
3486#define zig_atomic(Type) Type
3487#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
3488#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)
3489#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, &(arg), &(res), order)
3490#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order)
3491#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order)
3492#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order)
3493#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_xor (obj, arg, order)
3494#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_and (obj, arg, order)
3495#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3496#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3497#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3498#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, &(arg), order)
3499#define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order)
3500#undef zig_atomicrmw_xchg_float
3501#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3502#define zig_fence(order) __atomic_thread_fence(order)
3503#elif _MSC_VER && (_M_IX86 || _M_X64)
3504#define memory_order_relaxed 0
3505#define memory_order_consume 1
3506#define memory_order_acquire 2
3507#define memory_order_release 3
3508#define memory_order_acq_rel 4
3509#define memory_order_seq_cst 5
3510#define zig_atomic(Type) Type
3511#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
3512#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)
3513#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xchg_##Type(obj, arg)
3514#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_add_ ##Type(obj, arg)
3515#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_sub_ ##Type(obj, arg)
3516#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_or_ ##Type(obj, arg)
3517#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xor_ ##Type(obj, arg)
3518#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_and_ ##Type(obj, arg)
3519#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_nand_##Type(obj, arg)
3520#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_min_ ##Type(obj, arg)
3521#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg)
3522#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg)
3523#define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##Type(obj)
3524#if _M_X64
3525#define zig_fence(order) __faststorefence()
3526#else
3527#define zig_fence(order) zig_msvc_atomic_barrier()
3528#endif
3529/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */
3530#else
3531#define memory_order_relaxed 0
3532#define memory_order_consume 1
3533#define memory_order_acquire 2
3534#define memory_order_release 3
3535#define memory_order_acq_rel 4
3536#define memory_order_seq_cst 5
3537#define zig_atomic(Type) Type
3538#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3539#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3540#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3541#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3542#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3543#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3544#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3545#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3546#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3547#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3548#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3549#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable
3550#define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable
3551#define zig_fence(order) zig_fence_unavailable
3552#endif
3553
32273554#if _MSC_VER && (_M_IX86 || _M_X64)
32283555
3229// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64
3556/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
32303557
32313558#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \
32323559 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
......@@ -3316,51 +3643,30 @@ zig_msvc_atomics(u64, uint64_t, __int64, 64)
33163643zig_msvc_atomics(i64, int64_t, __int64, 64)
33173644#endif
33183645
3319#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
3646#define zig_msvc_flt_atomics(Type, SigType, suffix) \
33203647 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
3321 ReprType exchange; \
3322 ReprType comparand; \
3323 ReprType initial; \
3648 SigType exchange; \
3649 SigType comparand; \
3650 SigType initial; \
33243651 bool success; \
33253652 memcpy(&comparand, expected, sizeof(comparand)); \
33263653 memcpy(&exchange, &desired, sizeof(exchange)); \
3327 initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, exchange, comparand); \
3654 initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, exchange, comparand); \
33283655 success = initial == comparand; \
33293656 if (!success) memcpy(expected, &initial, sizeof(*expected)); \
33303657 return success; \
33313658 } \
3332 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3333 ReprType repr; \
3334 ReprType initial; \
3659 static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type arg) { \
3660 SigType value; \
3661 memcpy(&value, &arg, sizeof(value)); \
3662 (void)_InterlockedExchange##suffix((SigType volatile*)obj, value); \
3663 } \
3664 static inline zig_##Type zig_msvc_atomic_load_##Type(zig_##Type volatile* obj) { \
33353665 zig_##Type result; \
3336 memcpy(&repr, &value, sizeof(repr)); \
3337 initial = _InterlockedExchange##suffix((ReprType volatile*)obj, repr); \
3666 SigType initial = _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \
33383667 memcpy(&result, &initial, sizeof(result)); \
33393668 return result; \
3340 } \
3341 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3342 ReprType repr; \
3343 zig_##Type expected; \
3344 zig_##Type desired; \
3345 repr = *(ReprType volatile*)obj; \
3346 memcpy(&expected, &repr, sizeof(expected)); \
3347 do { \
3348 desired = expected + value; \
3349 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
3350 return expected; \
3351 } \
3352 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3353 ReprType repr; \
3354 zig_##Type expected; \
3355 zig_##Type desired; \
3356 repr = *(ReprType volatile*)obj; \
3357 memcpy(&expected, &repr, sizeof(expected)); \
3358 do { \
3359 desired = expected - value; \
3360 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
3361 return expected; \
33623669 }
3363
33643670zig_msvc_flt_atomics(f32, long, )
33653671#if _M_X64
33663672zig_msvc_flt_atomics(f64, int64_t, 64)
......@@ -3421,42 +3727,6 @@ static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expec
34213727static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
34223728 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
34233729}
3424
3425#define zig_msvc_atomics_128xchg(Type) \
3426 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3427 bool success = false; \
3428 zig_##Type prev; \
3429 while (!success) { \
3430 prev = *obj; \
3431 success = zig_msvc_cmpxchg_##Type(obj, &prev, value); \
3432 } \
3433 return prev; \
3434 }
3435
3436zig_msvc_atomics_128xchg(u128)
3437zig_msvc_atomics_128xchg(i128)
3438
3439#define zig_msvc_atomics_128op(Type, operation) \
3440 static inline zig_##Type zig_msvc_atomicrmw_##operation##_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3441 bool success = false; \
3442 zig_##Type new; \
3443 zig_##Type prev; \
3444 while (!success) { \
3445 prev = *obj; \
3446 new = zig_##operation##_##Type(prev, value); \
3447 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \
3448 } \
3449 return prev; \
3450 }
3451
3452zig_msvc_atomics_128op(u128, add)
3453zig_msvc_atomics_128op(u128, sub)
3454zig_msvc_atomics_128op(u128, or)
3455zig_msvc_atomics_128op(u128, xor)
3456zig_msvc_atomics_128op(u128, and)
3457zig_msvc_atomics_128op(u128, nand)
3458zig_msvc_atomics_128op(u128, min)
3459zig_msvc_atomics_128op(u128, max)
34603730#endif /* _M_IX86 */
34613731
34623732#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
src/Sema.zig+2-2
......@@ -21319,8 +21319,8 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2131921319 return sema.fail(block, op_src, "@atomicRmw with bool only allowed with .Xchg", .{});
2132021320 },
2132121321 .Float => switch (op) {
21322 .Xchg, .Add, .Sub => {},
21323 else => return sema.fail(block, op_src, "@atomicRmw with float only allowed with .Xchg, .Add, and .Sub", .{}),
21322 .Xchg, .Add, .Sub, .Max, .Min => {},
21323 else => return sema.fail(block, op_src, "@atomicRmw with float only allowed with .Xchg, .Add, .Sub, .Max, and .Min", .{}),
2132421324 },
2132521325 else => {},
2132621326 }
src/codegen/c.zig+559-550
......@@ -45,9 +45,6 @@ pub const CValue = union(enum) {
4545 identifier: []const u8,
4646 /// Render the slice as an payload.identifier (using fmtIdent)
4747 payload_identifier: []const u8,
48 /// Render these bytes literally.
49 /// TODO make this a [*:0]const u8 to save memory
50 bytes: []const u8,
5148};
5249
5350const BlockData = struct {
......@@ -434,7 +431,7 @@ pub const Function = struct {
434431 return f.object.dg.renderCType(w, t);
435432 }
436433
437 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void {
434 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
438435 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
439436 }
440437
......@@ -811,11 +808,13 @@ pub const DeclGen = struct {
811808
812809 try writer.writeByte('{');
813810 var empty = true;
814 for (ty.structFields().values()) |field| {
815 if (!field.ty.hasRuntimeBits()) continue;
811 for (0..ty.structFieldCount()) |field_i| {
812 if (ty.structFieldIsComptime(field_i)) continue;
813 const field_ty = ty.structFieldType(field_i);
814 if (!field_ty.hasRuntimeBits()) continue;
816815
817816 if (!empty) try writer.writeByte(',');
818 try dg.renderValue(writer, field.ty, val, initializer_type);
817 try dg.renderValue(writer, field_ty, val, initializer_type);
819818
820819 empty = false;
821820 }
......@@ -837,19 +836,27 @@ pub const DeclGen = struct {
837836 if (layout.tag_size != 0) {
838837 try writer.writeAll(" .tag = ");
839838 try dg.renderValue(writer, tag_ty, val, initializer_type);
840 try writer.writeByte(',');
841839 }
840 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
841 if (layout.tag_size != 0) try writer.writeByte(',');
842842 try writer.writeAll(" .payload = {");
843843 }
844844 for (ty.unionFields().values()) |field| {
845845 if (!field.ty.hasRuntimeBits()) continue;
846846 try dg.renderValue(writer, field.ty, val, initializer_type);
847847 break;
848 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)});
848 }
849849 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
850850 return writer.writeByte('}');
851851 },
852852 .ErrorUnion => {
853 const payload_ty = ty.errorUnionPayload();
854 const error_ty = ty.errorUnionSet();
855
856 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
857 return dg.renderValue(writer, error_ty, val, location);
858 }
859
853860 if (!location.isInitializer()) {
854861 try writer.writeByte('(');
855862 try dg.renderType(writer, ty);
......@@ -857,18 +864,12 @@ pub const DeclGen = struct {
857864 }
858865
859866 try writer.writeAll("{ .payload = ");
860 try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type);
861 return writer.print(", .error = {x} }}", .{
862 try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other),
863 });
867 try dg.renderValue(writer, payload_ty, val, initializer_type);
868 try writer.writeAll(", .error = ");
869 try dg.renderValue(writer, error_ty, val, initializer_type);
870 return writer.writeAll(" }");
864871 },
865872 .Array, .Vector => {
866 if (!location.isInitializer()) {
867 try writer.writeByte('(');
868 try dg.renderType(writer, ty);
869 try writer.writeByte(')');
870 }
871
872873 const ai = ty.arrayInfo();
873874 if (ai.elem_type.eql(Type.u8, dg.module)) {
874875 var literal = stringLiteral(writer);
......@@ -879,6 +880,12 @@ pub const DeclGen = struct {
879880 try literal.writeChar(0xaa);
880881 return literal.end();
881882 } else {
883 if (!location.isInitializer()) {
884 try writer.writeByte('(');
885 try dg.renderType(writer, ty);
886 try writer.writeByte(')');
887 }
888
882889 try writer.writeByte('{');
883890 const c_len = ty.arrayLenIncludingSentinel();
884891 var index: u64 = 0;
......@@ -1199,23 +1206,20 @@ pub const DeclGen = struct {
11991206 try writer.writeAll(" }");
12001207 },
12011208 .ErrorSet => {
1202 const error_name = if (val.castTag(.@"error")) |error_pl|
1203 error_pl.data.name
1204 else
1205 dg.module.error_name_list.items[0];
1206 // Error values are already defined by genErrDecls.
1207 try writer.print("zig_error_{}", .{fmtIdent(error_name)});
1209 if (val.castTag(.@"error")) |error_pl| {
1210 // Error values are already defined by genErrDecls.
1211 try writer.print("zig_error_{}", .{fmtIdent(error_pl.data.name)});
1212 } else {
1213 try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, .Other)});
1214 }
12081215 },
12091216 .ErrorUnion => {
1210 const error_ty = ty.errorUnionSet();
12111217 const payload_ty = ty.errorUnionPayload();
1218 const error_ty = ty.errorUnionSet();
1219 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
12121220
1213 if (!payload_ty.hasRuntimeBits()) {
1214 // We use the error type directly as the type.
1215 if (val.errorUnionIsPayload()) {
1216 return try writer.writeByte('0');
1217 }
1218 return dg.renderValue(writer, error_ty, val, location);
1221 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1222 return dg.renderValue(writer, error_ty, error_val, location);
12191223 }
12201224
12211225 if (!location.isInitializer()) {
......@@ -1225,8 +1229,6 @@ pub const DeclGen = struct {
12251229 }
12261230
12271231 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
12301232 try writer.writeAll("{ .payload = ");
12311233 try dg.renderValue(writer, payload_ty, payload_val, initializer_type);
12321234 try writer.writeAll(", .error = ");
......@@ -1290,9 +1292,10 @@ pub const DeclGen = struct {
12901292
12911293 try writer.writeByte('{');
12921294 var empty = true;
1293 for (field_vals, 0..) |field_val, field_index| {
1294 const field_ty = ty.structFieldType(field_index);
1295 if (!field_ty.hasRuntimeBits()) continue;
1295 for (field_vals, 0..) |field_val, field_i| {
1296 if (ty.structFieldIsComptime(field_i)) continue;
1297 const field_ty = ty.structFieldType(field_i);
1298 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
12961299
12971300 if (!empty) try writer.writeByte(',');
12981301 try dg.renderValue(writer, field_ty, field_val, initializer_type);
......@@ -1315,8 +1318,9 @@ pub const DeclGen = struct {
13151318 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
13161319
13171320 var eff_num_fields: usize = 0;
1318 for (0..field_vals.len) |index| {
1319 const field_ty = ty.structFieldType(index);
1321 for (0..field_vals.len) |field_i| {
1322 if (ty.structFieldIsComptime(field_i)) continue;
1323 const field_ty = ty.structFieldType(field_i);
13201324 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13211325
13221326 eff_num_fields += 1;
......@@ -1337,8 +1341,9 @@ pub const DeclGen = struct {
13371341
13381342 var eff_index: usize = 0;
13391343 var needs_closing_paren = false;
1340 for (field_vals, 0..) |field_val, index| {
1341 const field_ty = ty.structFieldType(index);
1344 for (field_vals, 0..) |field_val, field_i| {
1345 if (ty.structFieldIsComptime(field_i)) continue;
1346 const field_ty = ty.structFieldType(field_i);
13421347 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13431348
13441349 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
......@@ -1365,8 +1370,9 @@ pub const DeclGen = struct {
13651370 try writer.writeByte('(');
13661371 // a << a_off | b << b_off | c << c_off
13671372 var empty = true;
1368 for (field_vals, 0..) |field_val, index| {
1369 const field_ty = ty.structFieldType(index);
1373 for (field_vals, 0..) |field_val, field_i| {
1374 if (ty.structFieldIsComptime(field_i)) continue;
1375 const field_ty = ty.structFieldType(field_i);
13701376 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
13711377
13721378 if (!empty) try writer.writeAll(" | ");
......@@ -1398,9 +1404,9 @@ pub const DeclGen = struct {
13981404 try writer.writeByte(')');
13991405 }
14001406
1401 const index = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
1402 const field_ty = ty.unionFields().values()[index].ty;
1403 const field_name = ty.unionFields().keys()[index];
1407 const field_i = ty.unionTagFieldIndex(union_obj.tag, dg.module).?;
1408 const field_ty = ty.unionFields().values()[field_i].ty;
1409 const field_name = ty.unionFields().keys()[field_i];
14041410 if (ty.containerLayout() == .Packed) {
14051411 if (field_ty.hasRuntimeBits()) {
14061412 if (field_ty.isPtrAtRuntime()) {
......@@ -1419,32 +1425,27 @@ pub const DeclGen = struct {
14191425 return;
14201426 }
14211427
1422 var has_payload_init = false;
14231428 try writer.writeByte('{');
14241429 if (ty.unionTagTypeSafety()) |tag_ty| {
14251430 const layout = ty.unionGetLayout(target);
14261431 if (layout.tag_size != 0) {
1427 try writer.writeAll(".tag = ");
1432 try writer.writeAll(" .tag = ");
14281433 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;
14341434 }
1435 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
1436 if (layout.tag_size != 0) try writer.writeByte(',');
1437 try writer.writeAll(" .payload = {");
14351438 }
1436
1437 var it = ty.unionFields().iterator();
14381439 if (field_ty.hasRuntimeBits()) {
1439 try writer.print(".{ } = ", .{fmtIdent(field_name)});
1440 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
14401441 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);
1441 } else while (it.next()) |field| {
1442 if (!field.value_ptr.ty.hasRuntimeBits()) continue;
1443 try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)});
1444 try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type);
1442 try writer.writeByte(' ');
1443 } else for (ty.unionFields().values()) |field| {
1444 if (!field.ty.hasRuntimeBits()) continue;
1445 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);
14451446 break;
14461447 }
1447 if (has_payload_init) try writer.writeByte('}');
1448 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
14481449 try writer.writeByte('}');
14491450 },
14501451
......@@ -1585,7 +1586,7 @@ pub const DeclGen = struct {
15851586 c_value: struct {
15861587 f: *Function,
15871588 value: CValue,
1588 v: Vectorizer,
1589 v: Vectorize,
15891590 },
15901591 value: struct {
15911592 value: Value,
......@@ -1766,7 +1767,6 @@ pub const DeclGen = struct {
17661767 fmtIdent("payload"),
17671768 fmtIdent(ident),
17681769 }),
1769 .bytes => |bytes| return w.writeAll(bytes),
17701770 }
17711771 }
17721772
......@@ -1795,11 +1795,6 @@ pub const DeclGen = struct {
17951795 fmtIdent("payload"),
17961796 fmtIdent(ident),
17971797 }),
1798 .bytes => |bytes| {
1799 try w.writeAll("(*");
1800 try w.writeAll(bytes);
1801 return w.writeByte(')');
1802 },
18031798 }
18041799 }
18051800
......@@ -1812,7 +1807,7 @@ pub const DeclGen = struct {
18121807 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
18131808 switch (c_value) {
18141809 .none, .constant, .field, .undef => unreachable,
1815 .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier, .bytes => {
1810 .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier => {
18161811 try dg.writeCValue(writer, c_value);
18171812 try writer.writeAll("->");
18181813 },
......@@ -3073,15 +3068,17 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
30733068 const inst_ty = f.air.typeOfIndex(inst);
30743069 const operand = try f.resolveInst(ty_op.operand);
30753070 try reap(f, inst, &.{ty_op.operand});
3071
30763072 const writer = f.object.writer();
30773073 const local = try f.allocLocal(inst, inst_ty);
3074 const a = try Assignment.start(f, writer, inst_ty);
30783075 try f.writeCValue(writer, local, .Other);
3079 try writer.writeAll(" = ");
3076 try a.assign(f, writer);
30803077 if (is_ptr) {
30813078 try writer.writeByte('&');
30823079 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });
30833080 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });
3084 try writer.writeAll(";\n");
3081 try a.end(f, writer);
30853082 return local;
30863083}
30873084
......@@ -3097,29 +3094,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
30973094 const index = try f.resolveInst(bin_op.rhs);
30983095 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
30993096
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);
31043097 const writer = f.object.writer();
3105 if (is_array) {
3106 try writer.writeAll("memcpy(");
3107 try f.writeCValue(writer, local, .FunctionArgument);
3108 try writer.writeAll(", ");
3109 } else {
3110 try f.writeCValue(writer, local, .Other);
3111 try writer.writeAll(" = ");
3112 }
3098 const local = try f.allocLocal(inst, inst_ty);
3099 const a = try Assignment.start(f, writer, inst_ty);
3100 try f.writeCValue(writer, local, .Other);
3101 try a.assign(f, writer);
31133102 try f.writeCValue(writer, ptr, .Other);
31143103 try writer.writeByte('[');
31153104 try f.writeCValue(writer, index, .Other);
31163105 try writer.writeByte(']');
3117 if (is_array) {
3118 try writer.writeAll(", sizeof(");
3119 try f.renderType(writer, inst_ty);
3120 try writer.writeAll("))");
3121 }
3122 try writer.writeAll(";\n");
3106 try a.end(f, writer);
31233107 return local;
31243108}
31253109
......@@ -3129,35 +3113,32 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
31293113
31303114 const inst_ty = f.air.typeOfIndex(inst);
31313115 const ptr_ty = f.air.typeOf(bin_op.lhs);
3132 const child_ty = ptr_ty.childType();
3116 const elem_ty = ptr_ty.childType();
3117 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
31333118
31343119 const ptr = try f.resolveInst(bin_op.lhs);
31353120 const index = try f.resolveInst(bin_op.rhs);
31363121 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31373122
31383123 const writer = f.object.writer();
3139 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
3124 const local = try f.allocLocal(inst, inst_ty);
3125 const a = try Assignment.start(f, writer, inst_ty);
31403126 try f.writeCValue(writer, local, .Other);
3141 try writer.writeAll(" = ");
3142
3143 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
3144 try f.writeCValue(writer, ptr, .Initializer);
3145 try writer.writeAll(";\n");
3146 return local;
3147 }
3148
3127 try a.assign(f, writer);
31493128 try writer.writeByte('(');
31503129 try f.renderType(writer, inst_ty);
3151 try writer.writeAll(")&(");
3152 if (ptr_ty.ptrSize() == .One) {
3130 try writer.writeByte(')');
3131 if (elem_has_bits) try writer.writeByte('&');
3132 if (elem_has_bits and ptr_ty.ptrSize() == .One) {
31533133 // It's a pointer to an array, so we need to de-reference.
31543134 try f.writeCValueDeref(writer, ptr);
3155 } else {
3156 try f.writeCValue(writer, ptr, .Other);
3135 } else try f.writeCValue(writer, ptr, .Other);
3136 if (elem_has_bits) {
3137 try writer.writeByte('[');
3138 try f.writeCValue(writer, index, .Other);
3139 try writer.writeByte(']');
31573140 }
3158 try writer.writeAll(")[");
3159 try f.writeCValue(writer, index, .Other);
3160 try writer.writeAll("];\n");
3141 try a.end(f, writer);
31613142 return local;
31623143}
31633144
......@@ -3173,29 +3154,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
31733154 const index = try f.resolveInst(bin_op.rhs);
31743155 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31753156
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);
31803157 const writer = f.object.writer();
3181 if (is_array) {
3182 try writer.writeAll("memcpy(");
3183 try f.writeCValue(writer, local, .FunctionArgument);
3184 try writer.writeAll(", ");
3185 } else {
3186 try f.writeCValue(writer, local, .Other);
3187 try writer.writeAll(" = ");
3188 }
3189 try f.writeCValue(writer, slice, .Other);
3190 try writer.writeAll(".ptr[");
3158 const local = try f.allocLocal(inst, inst_ty);
3159 const a = try Assignment.start(f, writer, inst_ty);
3160 try f.writeCValue(writer, local, .Other);
3161 try a.assign(f, writer);
3162 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3163 try writer.writeByte('[');
31913164 try f.writeCValue(writer, index, .Other);
31923165 try writer.writeByte(']');
3193 if (is_array) {
3194 try writer.writeAll(", sizeof(");
3195 try f.renderType(writer, inst_ty);
3196 try writer.writeAll("))");
3197 }
3198 try writer.writeAll(";\n");
3166 try a.end(f, writer);
31993167 return local;
32003168}
32013169
......@@ -3203,25 +3171,28 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
32033171 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
32043172 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
32053173
3174 const inst_ty = f.air.typeOfIndex(inst);
32063175 const slice_ty = f.air.typeOf(bin_op.lhs);
3207 const child_ty = slice_ty.elemType2();
3176 const elem_ty = slice_ty.elemType2();
3177 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
3178
32083179 const slice = try f.resolveInst(bin_op.lhs);
32093180 const index = try f.resolveInst(bin_op.rhs);
32103181 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32113182
32123183 const writer = f.object.writer();
3213 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));
3184 const local = try f.allocLocal(inst, inst_ty);
3185 const a = try Assignment.start(f, writer, inst_ty);
32143186 try f.writeCValue(writer, local, .Other);
3215 try writer.writeAll(" = ");
3216 if (child_ty.hasRuntimeBitsIgnoreComptime()) try writer.writeByte('&');
3217 try f.writeCValue(writer, slice, .Other);
3218 try writer.writeAll(".ptr");
3219 if (child_ty.hasRuntimeBitsIgnoreComptime()) {
3187 try a.assign(f, writer);
3188 if (elem_has_bits) try writer.writeByte('&');
3189 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3190 if (elem_has_bits) {
32203191 try writer.writeByte('[');
32213192 try f.writeCValue(writer, index, .Other);
32223193 try writer.writeByte(']');
32233194 }
3224 try writer.writeAll(";\n");
3195 try a.end(f, writer);
32253196 return local;
32263197}
32273198
......@@ -3237,29 +3208,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
32373208 const index = try f.resolveInst(bin_op.rhs);
32383209 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32393210
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);
32443211 const writer = f.object.writer();
3245 if (is_array) {
3246 try writer.writeAll("memcpy(");
3247 try f.writeCValue(writer, local, .FunctionArgument);
3248 try writer.writeAll(", ");
3249 } else {
3250 try f.writeCValue(writer, local, .Other);
3251 try writer.writeAll(" = ");
3252 }
3212 const local = try f.allocLocal(inst, inst_ty);
3213 const a = try Assignment.start(f, writer, inst_ty);
3214 try f.writeCValue(writer, local, .Other);
3215 try a.assign(f, writer);
32533216 try f.writeCValue(writer, array, .Other);
32543217 try writer.writeByte('[');
32553218 try f.writeCValue(writer, index, .Other);
32563219 try writer.writeByte(']');
3257 if (is_array) {
3258 try writer.writeAll(", sizeof(");
3259 try f.renderType(writer, inst_ty);
3260 try writer.writeAll("))");
3261 }
3262 try writer.writeAll(";\n");
3220 try a.end(f, writer);
32633221 return local;
32643222}
32653223
......@@ -3343,7 +3301,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33433301
33443302 const writer = f.object.writer();
33453303 const local = try f.allocLocal(inst, src_ty);
3346 const v = try Vectorizer.start(f, inst, writer, ptr_ty);
3304 const v = try Vectorize.start(f, inst, writer, ptr_ty);
33473305
33483306 if (need_memcpy) {
33493307 try writer.writeAll("memcpy(");
......@@ -3484,12 +3442,13 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
34843442
34853443 const writer = f.object.writer();
34863444 const local = try f.allocLocal(inst, inst_ty);
3487 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3445 const v = try Vectorize.start(f, inst, writer, operand_ty);
3446 const a = try Assignment.start(f, writer, scalar_ty);
34883447 try f.writeCValue(writer, local, .Other);
34893448 try v.elem(f, writer);
3490 try writer.writeAll(" = ");
3449 try a.assign(f, writer);
34913450 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);
3492 try writer.writeAll(";\n");
3451 try a.end(f, writer);
34933452 try v.end(f, inst, writer);
34943453
34953454 return local;
......@@ -3513,7 +3472,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35133472
35143473 const writer = f.object.writer();
35153474 const local = try f.allocLocal(inst, inst_ty);
3516 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3475 const v = try Vectorize.start(f, inst, writer, operand_ty);
35173476
35183477 try f.writeCValue(writer, local, .Other);
35193478 try v.elem(f, writer);
......@@ -3564,13 +3523,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35643523 try writer.writeAll("zig_shr_");
35653524 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
35663525 if (c_bits == 128) {
3567 try writer.print("(zig_bitcast_i{d}(", .{c_bits});
3526 try writer.print("(zig_bitCast_i{d}(", .{c_bits});
35683527 } else {
35693528 try writer.print("((int{d}_t)", .{c_bits});
35703529 }
35713530 try writer.print("zig_shl_u{d}(", .{c_bits});
35723531 if (c_bits == 128) {
3573 try writer.print("zig_bitcast_u{d}(", .{c_bits});
3532 try writer.print("zig_bitCast_u{d}(", .{c_bits});
35743533 } else {
35753534 try writer.print("(uint{d}_t)", .{c_bits});
35763535 }
......@@ -3597,10 +3556,11 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
35973556 const writer = f.object.writer();
35983557 const inst_ty = f.air.typeOfIndex(inst);
35993558 const local = try f.allocLocal(inst, inst_ty);
3559 const a = try Assignment.start(f, writer, inst_ty);
36003560 try f.writeCValue(writer, local, .Other);
3601 try writer.writeAll(" = ");
3561 try a.assign(f, writer);
36023562 try f.writeCValue(writer, operand, .Other);
3603 try writer.writeAll(";\n");
3563 try a.end(f, writer);
36043564 return local;
36053565}
36063566
......@@ -3632,8 +3592,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
36323592 const src_val_is_undefined =
36333593 if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
36343594 if (src_val_is_undefined) {
3635 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3636 return try storeUndefined(f, ptr_info.pointee_type, ptr_val);
3595 if (ptr_info.host_size == 0) {
3596 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3597 return try storeUndefined(f, ptr_info.pointee_type, ptr_val);
3598 } else if (!f.wantSafety()) {
3599 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3600 return .none;
3601 }
36373602 }
36383603
36393604 const target = f.object.dg.module.getTarget();
......@@ -3646,7 +3611,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
36463611 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36473612
36483613 const writer = f.object.writer();
3649 const v = try Vectorizer.start(f, inst, writer, ptr_ty);
3614 const v = try Vectorize.start(f, inst, writer, ptr_ty);
36503615
36513616 if (need_memcpy) {
36523617 // For this memcpy to safely work we need the rhs to have the same
......@@ -3775,7 +3740,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37753740
37763741 const w = f.object.writer();
37773742 const local = try f.allocLocal(inst, inst_ty);
3778 const v = try Vectorizer.start(f, inst, w, operand_ty);
3743 const v = try Vectorize.start(f, inst, w, operand_ty);
37793744 try f.writeCValueMember(w, local, .{ .field = 1 });
37803745 try v.elem(f, w);
37813746 try w.writeAll(" = zig_");
......@@ -3811,7 +3776,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
38113776
38123777 const writer = f.object.writer();
38133778 const local = try f.allocLocal(inst, inst_ty);
3814 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3779 const v = try Vectorize.start(f, inst, writer, operand_ty);
38153780 try f.writeCValue(writer, local, .Other);
38163781 try v.elem(f, writer);
38173782 try writer.writeAll(" = ");
......@@ -3846,7 +3811,7 @@ fn airBinOp(
38463811
38473812 const writer = f.object.writer();
38483813 const local = try f.allocLocal(inst, inst_ty);
3849 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3814 const v = try Vectorize.start(f, inst, writer, operand_ty);
38503815 try f.writeCValue(writer, local, .Other);
38513816 try v.elem(f, writer);
38523817 try writer.writeAll(" = ");
......@@ -3893,7 +3858,7 @@ fn airCmpOp(
38933858
38943859 const writer = f.object.writer();
38953860 const local = try f.allocLocal(inst, inst_ty);
3896 const v = try Vectorizer.start(f, inst, writer, operand_ty);
3861 const v = try Vectorize.start(f, inst, writer, operand_ty);
38973862 try f.writeCValue(writer, local, .Other);
38983863 try v.elem(f, writer);
38993864 try writer.writeAll(" = ");
......@@ -3942,7 +3907,7 @@ fn airEquality(
39423907 try f.writeCValue(writer, local, .Other);
39433908 try writer.writeAll(" = ");
39443909
3945 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.isPtrLikeOptional()) {
3910 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.optionalReprIsPayload()) {
39463911 // (A && B) || (C && (A == B))
39473912 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
39483913
......@@ -4008,7 +3973,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
40083973
40093974 const local = try f.allocLocal(inst, inst_ty);
40103975 const writer = f.object.writer();
4011 const v = try Vectorizer.start(f, inst, writer, inst_ty);
3976 const v = try Vectorize.start(f, inst, writer, inst_ty);
40123977 try f.writeCValue(writer, local, .Other);
40133978 try v.elem(f, writer);
40143979 try writer.writeAll(" = ");
......@@ -4059,7 +4024,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
40594024
40604025 const writer = f.object.writer();
40614026 const local = try f.allocLocal(inst, inst_ty);
4062 const v = try Vectorizer.start(f, inst, writer, inst_ty);
4027 const v = try Vectorize.start(f, inst, writer, inst_ty);
40634028 try f.writeCValue(writer, local, .Other);
40644029 try v.elem(f, writer);
40654030 // (lhs <> rhs) ? lhs : rhs
......@@ -4091,21 +4056,29 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
40914056 const len = try f.resolveInst(bin_op.rhs);
40924057 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
40934058
4094 const writer = f.object.writer();
40954059 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 = (");
40994060 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4100 try f.renderType(writer, inst_ty.slicePtrFieldType(&buf));
4101 try writer.writeByte(')');
4102 try f.writeCValue(writer, ptr, .Other);
4103 try writer.writeAll("; ");
4104 try f.writeCValue(writer, local, .Other);
4105 try writer.writeAll(".len = ");
4106 try f.writeCValue(writer, len, .Initializer);
4107 try writer.writeAll(";\n");
4061 const ptr_ty = inst_ty.slicePtrFieldType(&buf);
41084062
4063 const writer = f.object.writer();
4064 const local = try f.allocLocal(inst, inst_ty);
4065 {
4066 const a = try Assignment.start(f, writer, ptr_ty);
4067 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
4068 try a.assign(f, writer);
4069 try writer.writeByte('(');
4070 try f.renderType(writer, ptr_ty);
4071 try writer.writeByte(')');
4072 try f.writeCValue(writer, ptr, .Other);
4073 try a.end(f, writer);
4074 }
4075 {
4076 const a = try Assignment.start(f, writer, Type.usize);
4077 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
4078 try a.assign(f, writer);
4079 try f.writeCValue(writer, len, .Other);
4080 try a.end(f, writer);
4081 }
41094082 return local;
41104083}
41114084
......@@ -4346,10 +4319,10 @@ fn lowerTry(
43464319 operand: Air.Inst.Ref,
43474320 body: []const Air.Inst.Index,
43484321 err_union_ty: Type,
4349 operand_is_ptr: bool,
4322 is_ptr: bool,
43504323) !CValue {
43514324 const err_union = try f.resolveInst(operand);
4352 const result_ty = f.air.typeOfIndex(inst);
4325 const inst_ty = f.air.typeOfIndex(inst);
43534326 const liveness_condbr = f.liveness.getCondBr(inst);
43544327 const writer = f.object.writer();
43554328 const payload_ty = err_union_ty.errorUnionPayload();
......@@ -4358,7 +4331,7 @@ fn lowerTry(
43584331 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
43594332 try writer.writeAll("if (");
43604333 if (!payload_has_bits) {
4361 if (operand_is_ptr)
4334 if (is_ptr)
43624335 try f.writeCValueDeref(writer, err_union)
43634336 else
43644337 try f.writeCValue(writer, err_union, .Other);
......@@ -4367,7 +4340,7 @@ fn lowerTry(
43674340 // Remember we must avoid calling reap() twice for the same operand
43684341 // in this function.
43694342 try reap(f, inst, &.{operand});
4370 if (operand_is_ptr or isByRef(err_union_ty))
4343 if (is_ptr)
43714344 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })
43724345 else
43734346 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });
......@@ -4384,7 +4357,7 @@ fn lowerTry(
43844357 }
43854358
43864359 if (!payload_has_bits) {
4387 if (!operand_is_ptr) {
4360 if (!is_ptr) {
43884361 return .none;
43894362 } else {
43904363 return err_union;
......@@ -4397,26 +4370,15 @@ fn lowerTry(
43974370 return .none;
43984371 }
43994372
4400 const target = f.object.dg.module.getTarget();
4401 const is_array = lowersToArray(payload_ty, target);
4402 const local = try f.allocLocal(inst, result_ty);
4403 if (is_array) {
4404 try writer.writeAll("memcpy(");
4405 try f.writeCValue(writer, local, .FunctionArgument);
4406 try writer.writeAll(", ");
4407 try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4408 try writer.writeAll(", sizeof(");
4409 try f.renderType(writer, payload_ty);
4410 try writer.writeAll("));\n");
4411 } else {
4412 try f.writeCValue(writer, local, .Other);
4413 try writer.writeAll(" = ");
4414 if (operand_is_ptr or isByRef(payload_ty)) {
4415 try writer.writeByte('&');
4416 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4417 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4418 try writer.writeAll(";\n");
4419 }
4373 const local = try f.allocLocal(inst, inst_ty);
4374 const a = try Assignment.start(f, writer, inst_ty);
4375 try f.writeCValue(writer, local, .Other);
4376 try a.assign(f, writer);
4377 if (is_ptr) {
4378 try writer.writeByte('&');
4379 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4380 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
4381 try a.end(f, writer);
44204382 return local;
44214383}
44224384
......@@ -4428,25 +4390,15 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
44284390
44294391 // If result is .none then the value of the block is unused.
44304392 if (result != .none) {
4393 const operand_ty = f.air.typeOf(branch.operand);
44314394 const operand = try f.resolveInst(branch.operand);
44324395 try reap(f, inst, &.{branch.operand});
44334396
4434 const operand_ty = f.air.typeOf(branch.operand);
4435 const target = f.object.dg.module.getTarget();
4436 if (lowersToArray(operand_ty, target)) {
4437 try writer.writeAll("memcpy(");
4438 try f.writeCValue(writer, result, .FunctionArgument);
4439 try writer.writeAll(", ");
4440 try f.writeCValue(writer, operand, .FunctionArgument);
4441 try writer.writeAll(", sizeof(");
4442 try f.renderType(writer, operand_ty);
4443 try writer.writeAll("))");
4444 } else {
4445 try f.writeCValue(writer, result, .Other);
4446 try writer.writeAll(" = ");
4447 try f.writeCValue(writer, operand, .Other);
4448 }
4449 try writer.writeAll(";\n");
4397 const a = try Assignment.start(f, writer, operand_ty);
4398 try f.writeCValue(writer, result, .Other);
4399 try a.assign(f, writer);
4400 try f.writeCValue(writer, operand, .Other);
4401 try a.end(f, writer);
44504402 }
44514403
44524404 try writer.print("goto zig_block_{d};\n", .{block.block_id});
......@@ -4532,7 +4484,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
45324484 }
45334485 try writer.writeAll(" = ");
45344486 if (need_bitcasts) {
4535 try writer.writeAll("zig_bitcast_");
4487 try writer.writeAll("zig_bitCast_");
45364488 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_cty.?.toUnsigned());
45374489 try writer.writeByte('(');
45384490 }
......@@ -4544,7 +4496,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
45444496 try f.object.dg.renderTypeForBuiltinFnName(writer, info_ty);
45454497 try writer.writeByte('(');
45464498 if (need_bitcasts) {
4547 try writer.writeAll("zig_bitcast_");
4499 try writer.writeAll("zig_bitCast_");
45484500 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_cty.?);
45494501 try writer.writeByte('(');
45504502 }
......@@ -4771,7 +4723,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
47714723 if (f.wantSafety()) {
47724724 try f.writeCValue(writer, local, .Other);
47734725 try writer.writeAll(" = ");
4774 try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer);
4726 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
47754727 try writer.writeAll(";\n");
47764728 }
47774729 break :local local;
......@@ -4806,7 +4758,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48064758 try writer.writeAll("\")");
48074759 if (f.wantSafety()) {
48084760 try writer.writeAll(" = ");
4809 try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer);
4761 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);
48104762 }
48114763 try writer.writeAll(";\n");
48124764 }
......@@ -4840,7 +4792,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48404792 try writer.writeAll("\")");
48414793 }
48424794 try writer.writeAll(" = ");
4843 try f.writeCValue(writer, input_val, .Initializer);
4795 try f.writeCValue(writer, input_val, .Other);
48444796 try writer.writeAll(";\n");
48454797 }
48464798 }
......@@ -5072,8 +5024,8 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50725024 }
50735025
50745026 const inst_ty = f.air.typeOfIndex(inst);
5075 const local = try f.allocLocal(inst, inst_ty);
50765027 const writer = f.object.writer();
5028 const local = try f.allocLocal(inst, inst_ty);
50775029
50785030 if (opt_ty.optionalReprIsPayload()) {
50795031 try f.writeCValue(writer, local, .Other);
......@@ -5083,24 +5035,11 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50835035 return local;
50845036 }
50855037
5086 const target = f.object.dg.module.getTarget();
5087 const is_array = lowersToArray(inst_ty, target);
5088
5089 if (is_array) {
5090 try writer.writeAll("memcpy(");
5091 try f.writeCValue(writer, local, .FunctionArgument);
5092 try writer.writeAll(", ");
5093 } else {
5094 try f.writeCValue(writer, local, .Other);
5095 try writer.writeAll(" = ");
5096 }
5038 const a = try Assignment.start(f, writer, inst_ty);
5039 try f.writeCValue(writer, local, .Other);
5040 try a.assign(f, writer);
50975041 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5098 if (is_array) {
5099 try writer.writeAll(", sizeof(");
5100 try f.renderType(writer, inst_ty);
5101 try writer.writeAll("))");
5102 }
5103 try writer.writeAll(";\n");
5042 try a.end(f, writer);
51045043 return local;
51055044}
51065045
......@@ -5193,6 +5132,7 @@ fn fieldLocation(
51935132 if (container_ty.structFieldIsComptime(next_field_index)) continue;
51945133 const field_ty = container_ty.structFieldType(next_field_index);
51955134 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5135
51965136 break .{ .field = if (container_ty.isSimpleTuple())
51975137 .{ .field = next_field_index }
51985138 else
......@@ -5437,13 +5377,17 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54375377 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
54385378 try writer.writeByte('(');
54395379 }
5440 try writer.writeAll("zig_shr_");
5441 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5442 try writer.writeByte('(');
5380 if (bit_offset_val_pl.data > 0) {
5381 try writer.writeAll("zig_shr_");
5382 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5383 try writer.writeByte('(');
5384 }
54435385 try f.writeCValue(writer, struct_byval, .Other);
5444 try writer.writeAll(", ");
5445 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5446 try writer.writeByte(')');
5386 if (bit_offset_val_pl.data > 0) {
5387 try writer.writeAll(", ");
5388 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5389 try writer.writeByte(')');
5390 }
54475391 if (cant_cast) try writer.writeByte(')');
54485392 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
54495393 try writer.writeAll(");\n");
......@@ -5473,9 +5417,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54735417
54745418 const local = try f.allocLocal(inst, inst_ty);
54755419 try writer.writeAll("memcpy(&");
5476 try f.writeCValue(writer, local, .FunctionArgument);
5420 try f.writeCValue(writer, local, .Other);
54775421 try writer.writeAll(", &");
5478 try f.writeCValue(writer, operand_lval, .FunctionArgument);
5422 try f.writeCValue(writer, operand_lval, .Other);
54795423 try writer.writeAll(", sizeof(");
54805424 try f.renderType(writer, inst_ty);
54815425 try writer.writeAll("));\n");
......@@ -5496,20 +5440,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54965440 };
54975441
54985442 const local = try f.allocLocal(inst, inst_ty);
5499 if (lowersToArray(inst_ty, target)) {
5500 try writer.writeAll("memcpy(");
5501 try f.writeCValue(writer, local, .FunctionArgument);
5502 try writer.writeAll(", ");
5503 try f.writeCValueMember(writer, struct_byval, field_name);
5504 try writer.writeAll(", sizeof(");
5505 try f.renderType(writer, inst_ty);
5506 try writer.writeAll("))");
5507 } else {
5508 try f.writeCValue(writer, local, .Other);
5509 try writer.writeAll(" = ");
5510 try f.writeCValueMember(writer, struct_byval, field_name);
5511 }
5512 try writer.writeAll(";\n");
5443 const a = try Assignment.start(f, writer, inst_ty);
5444 try f.writeCValue(writer, local, .Other);
5445 try a.assign(f, writer);
5446 try f.writeCValueMember(writer, struct_byval, field_name);
5447 try a.end(f, writer);
55135448 return local;
55145449}
55155450
......@@ -5554,33 +5489,31 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
55545489 const operand = try f.resolveInst(ty_op.operand);
55555490 try reap(f, inst, &.{ty_op.operand});
55565491 const operand_ty = f.air.typeOf(ty_op.operand);
5557 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
5558 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5492 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
55595493
5494 const writer = f.object.writer();
55605495 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {
55615496 if (!is_ptr) return .none;
55625497
5563 const w = f.object.writer();
55645498 const local = try f.allocLocal(inst, inst_ty);
5565 try f.writeCValue(w, local, .Other);
5566 try w.writeAll(" = (");
5567 try f.renderType(w, inst_ty);
5568 try w.writeByte(')');
5569 try f.writeCValue(w, operand, .Initializer);
5570 try w.writeAll(";\n");
5499 try f.writeCValue(writer, local, .Other);
5500 try writer.writeAll(" = (");
5501 try f.renderType(writer, inst_ty);
5502 try writer.writeByte(')');
5503 try f.writeCValue(writer, operand, .Initializer);
5504 try writer.writeAll(";\n");
55715505 return local;
55725506 }
55735507
5574 const writer = f.object.writer();
55755508 const local = try f.allocLocal(inst, inst_ty);
5509 const a = try Assignment.start(f, writer, inst_ty);
55765510 try f.writeCValue(writer, local, .Other);
5577 try writer.writeAll(" = ");
5578 if (is_ptr) try writer.writeByte('&');
5579 if (operand_is_ptr)
5580 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" })
5581 else
5582 try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5583 try writer.writeAll(";\n");
5511 try a.assign(f, writer);
5512 if (is_ptr) {
5513 try writer.writeByte('&');
5514 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
5515 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5516 try a.end(f, writer);
55845517 return local;
55855518}
55865519
......@@ -5588,40 +5521,29 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
55885521 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55895522
55905523 const inst_ty = f.air.typeOfIndex(inst);
5524 const repr_is_payload = inst_ty.optionalReprIsPayload();
5525 const payload_ty = f.air.typeOf(ty_op.operand);
55915526 const payload = try f.resolveInst(ty_op.operand);
55925527 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);
56075528
5529 const writer = f.object.writer();
56085530 const local = try f.allocLocal(inst, inst_ty);
5609 if (!is_array) {
5610 try f.writeCValue(writer, local, .Other);
5611 try writer.writeAll(".payload = ");
5531 {
5532 const a = try Assignment.start(f, writer, payload_ty);
5533 if (repr_is_payload)
5534 try f.writeCValue(writer, local, .Other)
5535 else
5536 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5537 try a.assign(f, writer);
56125538 try f.writeCValue(writer, payload, .Other);
5613 try writer.writeAll("; ");
5539 try a.end(f, writer);
56145540 }
5615 try f.writeCValue(writer, local, .Other);
5616 try writer.writeAll(".is_null = false;\n");
5617 if (is_array) {
5618 try writer.writeAll("memcpy(");
5619 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5620 try writer.writeAll(", ");
5621 try f.writeCValue(writer, payload, .FunctionArgument);
5622 try writer.writeAll(", sizeof(");
5623 try f.renderType(writer, payload_ty);
5624 try writer.writeAll("));\n");
5541 if (!repr_is_payload) {
5542 const a = try Assignment.start(f, writer, Type.bool);
5543 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
5544 try a.assign(f, writer);
5545 try f.object.dg.renderValue(writer, Type.bool, Value.false, .Other);
5546 try a.end(f, writer);
56255547 }
56265548 return local;
56275549}
......@@ -5629,29 +5551,32 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
56295551fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
56305552 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56315553
5632 const writer = f.object.writer();
5633 const operand = try f.resolveInst(ty_op.operand);
5554 const inst_ty = f.air.typeOfIndex(inst);
5555 const payload_ty = inst_ty.errorUnionPayload();
5556 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5557 const err_ty = inst_ty.errorUnionSet();
5558 const err = try f.resolveInst(ty_op.operand);
56345559 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);
56385560
5639 if (!payload_ty.hasRuntimeBits()) {
5640 try f.writeCValue(writer, local, .Other);
5641 try writer.writeAll(" = ");
5642 try f.writeCValue(writer, operand, .Other);
5643 try writer.writeAll(";\n");
5644 return local;
5561 const writer = f.object.writer();
5562 const local = try f.allocLocal(inst, inst_ty);
5563 if (!repr_is_err) {
5564 const a = try Assignment.start(f, writer, payload_ty);
5565 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5566 try a.assign(f, writer);
5567 try f.object.dg.renderValue(writer, payload_ty, Value.undef, .Other);
5568 try a.end(f, writer);
56455569 }
5646
56475570 {
5648 // TODO: set the payload to undefined
5649 //try f.writeCValue(writer, local, .Other);
5571 const a = try Assignment.start(f, writer, err_ty);
5572 if (repr_is_err)
5573 try f.writeCValue(writer, local, .Other)
5574 else
5575 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5576 try a.assign(f, writer);
5577 try f.writeCValue(writer, err, .Other);
5578 try a.end(f, writer);
56505579 }
5651 try f.writeCValue(writer, local, .Other);
5652 try writer.writeAll(".error = ");
5653 try f.writeCValue(writer, operand, .Other);
5654 try writer.writeAll(";\n");
56555580 return local;
56565581}
56575582
......@@ -5711,29 +5636,28 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
57115636 const inst_ty = f.air.typeOfIndex(inst);
57125637 const payload_ty = inst_ty.errorUnionPayload();
57135638 const payload = try f.resolveInst(ty_op.operand);
5639 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5640 const err_ty = inst_ty.errorUnionSet();
57145641 try reap(f, inst, &.{ty_op.operand});
57155642
5716 const target = f.object.dg.module.getTarget();
5717 const is_array = lowersToArray(payload_ty, target);
5718
57195643 const writer = f.object.writer();
57205644 const local = try f.allocLocal(inst, inst_ty);
5721 if (!is_array) {
5722 try f.writeCValue(writer, local, .Other);
5723 try writer.writeAll(".payload = ");
5645 if (!repr_is_err) {
5646 const a = try Assignment.start(f, writer, payload_ty);
5647 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5648 try a.assign(f, writer);
57245649 try f.writeCValue(writer, payload, .Other);
5725 try writer.writeAll("; ");
5650 try a.end(f, writer);
57265651 }
5727 try f.writeCValue(writer, local, .Other);
5728 try writer.writeAll(".error = 0;\n");
5729 if (is_array) {
5730 try writer.writeAll("memcpy(");
5731 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
5732 try writer.writeAll(", ");
5733 try f.writeCValue(writer, payload, .FunctionArgument);
5734 try writer.writeAll(", sizeof(");
5735 try f.renderType(writer, payload_ty);
5736 try writer.writeAll("));\n");
5652 {
5653 const a = try Assignment.start(f, writer, err_ty);
5654 if (repr_is_err)
5655 try f.writeCValue(writer, local, .Other)
5656 else
5657 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5658 try a.assign(f, writer);
5659 try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other);
5660 try a.end(f, writer);
57375661 }
57385662 return local;
57395663}
......@@ -5831,11 +5755,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
58315755 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
58325756 try writer.writeByte('(');
58335757 }
5834 try writer.writeAll("__");
5758 try writer.writeAll("zig_");
58355759 try writer.writeAll(operation);
58365760 try writer.writeAll(compilerRtAbbrev(operand_ty, target));
58375761 try writer.writeAll(compilerRtAbbrev(inst_ty, target));
5838 if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat()) try writer.writeByte('2');
58395762 try writer.writeByte('(');
58405763 try f.writeCValue(writer, operand, .FunctionArgument);
58415764 try writer.writeByte(')');
......@@ -5885,7 +5808,7 @@ fn airUnBuiltinCall(
58855808
58865809 const writer = f.object.writer();
58875810 const local = try f.allocLocal(inst, inst_ty);
5888 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5811 const v = try Vectorize.start(f, inst, writer, operand_ty);
58895812 if (!ref_ret) {
58905813 try f.writeCValue(writer, local, .Other);
58915814 try v.elem(f, writer);
......@@ -5934,7 +5857,7 @@ fn airBinBuiltinCall(
59345857 const writer = f.object.writer();
59355858 const local = try f.allocLocal(inst, inst_ty);
59365859 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
5937 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5860 const v = try Vectorize.start(f, inst, writer, operand_ty);
59385861 if (!ref_ret) {
59395862 try f.writeCValue(writer, local, .Other);
59405863 try v.elem(f, writer);
......@@ -5982,7 +5905,7 @@ fn airCmpBuiltinCall(
59825905
59835906 const writer = f.object.writer();
59845907 const local = try f.allocLocal(inst, inst_ty);
5985 const v = try Vectorizer.start(f, inst, writer, operand_ty);
5908 const v = try Vectorize.start(f, inst, writer, operand_ty);
59865909 if (!ref_ret) {
59875910 try f.writeCValue(writer, local, .Other);
59885911 try v.elem(f, writer);
......@@ -6023,18 +5946,33 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
60235946 const ptr = try f.resolveInst(extra.ptr);
60245947 const expected_value = try f.resolveInst(extra.expected_value);
60255948 const new_value = try f.resolveInst(extra.new_value);
6026 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
6027 const writer = f.object.writer();
60285949 const ptr_ty = f.air.typeOf(extra.ptr);
5950 const ty = ptr_ty.childType();
5951
5952 const writer = f.object.writer();
5953 const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);
5954 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
5955
5956 const target = f.object.dg.module.getTarget();
5957 var repr_pl = Type.Payload.Bits{
5958 .base = .{ .tag = .int_unsigned },
5959 .data = @intCast(u16, ty.abiSize(target) * 8),
5960 };
5961 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
5962
60295963 const local = try f.allocLocal(inst, inst_ty);
60305964 if (inst_ty.isPtrLikeOptional()) {
6031 try f.writeCValue(writer, local, .Other);
6032 try writer.writeAll(" = ");
6033 try f.writeCValue(writer, expected_value, .Initializer);
6034 try writer.writeAll(";\n");
5965 {
5966 const a = try Assignment.start(f, writer, ty);
5967 try f.writeCValue(writer, local, .Other);
5968 try a.assign(f, writer);
5969 try f.writeCValue(writer, expected_value, .Other);
5970 try a.end(f, writer);
5971 }
5972
60355973 try writer.writeAll("if (");
60365974 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6037 try f.renderType(writer, ptr_ty.childType());
5975 try f.renderType(writer, ty);
60385976 try writer.writeByte(')');
60395977 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
60405978 try writer.writeAll(" *)");
......@@ -6042,45 +5980,62 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
60425980 try writer.writeAll(", ");
60435981 try f.writeCValue(writer, local, .FunctionArgument);
60445982 try writer.writeAll(", ");
6045 try f.writeCValue(writer, new_value, .FunctionArgument);
5983 try new_value_mat.mat(f, writer);
60465984 try writer.writeAll(", ");
60475985 try writeMemoryOrder(writer, extra.successOrder());
60485986 try writer.writeAll(", ");
60495987 try writeMemoryOrder(writer, extra.failureOrder());
60505988 try writer.writeAll(", ");
6051 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
5989 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
5990 try writer.writeAll(", ");
5991 try f.object.dg.renderType(writer, repr_ty);
60525992 try writer.writeByte(')');
60535993 try writer.writeAll(") {\n");
60545994 f.object.indent_writer.pushIndent();
6055 try f.writeCValue(writer, local, .Other);
6056 try writer.writeAll(" = NULL;\n");
5995 {
5996 const a = try Assignment.start(f, writer, ty);
5997 try f.writeCValue(writer, local, .Other);
5998 try a.assign(f, writer);
5999 try writer.writeAll("NULL");
6000 try a.end(f, writer);
6001 }
60576002 f.object.indent_writer.popIndent();
60586003 try writer.writeAll("}\n");
60596004 } else {
6060 try f.writeCValue(writer, local, .Other);
6061 try writer.writeAll(".payload = ");
6062 try f.writeCValue(writer, expected_value, .Other);
6063 try writer.writeAll(";\n");
6064 try f.writeCValue(writer, local, .Other);
6065 try writer.print(".is_null = zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6066 try f.renderType(writer, ptr_ty.childType());
6067 try writer.writeByte(')');
6068 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6069 try writer.writeAll(" *)");
6070 try f.writeCValue(writer, ptr, .Other);
6071 try writer.writeAll(", ");
6072 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6073 try writer.writeAll(", ");
6074 try f.writeCValue(writer, new_value, .FunctionArgument);
6075 try writer.writeAll(", ");
6076 try writeMemoryOrder(writer, extra.successOrder());
6077 try writer.writeAll(", ");
6078 try writeMemoryOrder(writer, extra.failureOrder());
6079 try writer.writeAll(", ");
6080 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6081 try writer.writeByte(')');
6082 try writer.writeAll(";\n");
6005 {
6006 const a = try Assignment.start(f, writer, ty);
6007 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6008 try a.assign(f, writer);
6009 try f.writeCValue(writer, expected_value, .Other);
6010 try a.end(f, writer);
6011 }
6012 {
6013 const a = try Assignment.start(f, writer, Type.bool);
6014 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
6015 try a.assign(f, writer);
6016 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6017 try f.renderType(writer, ty);
6018 try writer.writeByte(')');
6019 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6020 try writer.writeAll(" *)");
6021 try f.writeCValue(writer, ptr, .Other);
6022 try writer.writeAll(", ");
6023 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6024 try writer.writeAll(", ");
6025 try new_value_mat.mat(f, writer);
6026 try writer.writeAll(", ");
6027 try writeMemoryOrder(writer, extra.successOrder());
6028 try writer.writeAll(", ");
6029 try writeMemoryOrder(writer, extra.failureOrder());
6030 try writer.writeAll(", ");
6031 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6032 try writer.writeAll(", ");
6033 try f.object.dg.renderType(writer, repr_ty);
6034 try writer.writeByte(')');
6035 try a.end(f, writer);
6036 }
60836037 }
6038 try new_value_mat.end(f, inst);
60846039
60856040 if (f.liveness.isUnused(inst)) {
60866041 try freeLocal(f, inst, local.new_local, 0);
......@@ -6095,35 +6050,50 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
60956050 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
60966051 const inst_ty = f.air.typeOfIndex(inst);
60976052 const ptr_ty = f.air.typeOf(pl_op.operand);
6053 const ty = ptr_ty.childType();
60986054 const ptr = try f.resolveInst(pl_op.operand);
60996055 const operand = try f.resolveInst(extra.operand);
6100 try reap(f, inst, &.{ pl_op.operand, extra.operand });
6056
61016057 const writer = f.object.writer();
6102 const local = try f.allocLocal(inst, inst_ty);
6058 const operand_mat = try Materialize.start(f, inst, writer, ty, operand);
6059 try reap(f, inst, &.{ pl_op.operand, extra.operand });
61036060
6061 const target = f.object.dg.module.getTarget();
6062 var repr_pl = Type.Payload.Bits{
6063 .base = .{ .tag = .int_unsigned },
6064 .data = @intCast(u16, ty.abiSize(target) * 8),
6065 };
6066 const is_float = ty.isRuntimeFloat();
6067 const is_128 = repr_pl.data == 128;
6068 const repr_ty = if (is_float) Type.initPayload(&repr_pl.base) else ty;
6069
6070 const local = try f.allocLocal(inst, inst_ty);
6071 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6072 if (is_float) try writer.writeAll("_float") else if (is_128) try writer.writeAll("_int128");
6073 try writer.writeByte('(');
61046074 try f.writeCValue(writer, local, .Other);
6105 try writer.print(" = zig_atomicrmw_{s}((", .{toAtomicRmwSuffix(extra.op())});
6106 switch (extra.op()) {
6107 else => {
6108 try writer.writeAll("zig_atomic(");
6109 try f.renderType(writer, ptr_ty.elemType());
6110 try writer.writeByte(')');
6111 },
6112 .Nand, .Min, .Max => {
6113 // These are missing from stdatomic.h, so no atomic types for now.
6114 try f.renderType(writer, ptr_ty.elemType());
6115 },
6116 }
6075 try writer.writeAll(", (");
6076 const use_atomic = switch (extra.op()) {
6077 else => true,
6078 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.
6079 .Nand, .Min, .Max => is_float or is_128,
6080 };
6081 if (use_atomic) try writer.writeAll("zig_atomic(");
6082 try f.renderType(writer, ty);
6083 if (use_atomic) try writer.writeByte(')');
61176084 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
61186085 try writer.writeAll(" *)");
61196086 try f.writeCValue(writer, ptr, .Other);
61206087 try writer.writeAll(", ");
6121 try f.writeCValue(writer, operand, .FunctionArgument);
6088 try operand_mat.mat(f, writer);
61226089 try writer.writeAll(", ");
61236090 try writeMemoryOrder(writer, extra.ordering());
61246091 try writer.writeAll(", ");
6125 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6092 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6093 try writer.writeAll(", ");
6094 try f.object.dg.renderType(writer, repr_ty);
61266095 try writer.writeAll(");\n");
6096 try operand_mat.end(f, inst);
61276097
61286098 if (f.liveness.isUnused(inst)) {
61296099 try freeLocal(f, inst, local.new_local, 0);
......@@ -6138,14 +6108,23 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
61386108 const ptr = try f.resolveInst(atomic_load.ptr);
61396109 try reap(f, inst, &.{atomic_load.ptr});
61406110 const ptr_ty = f.air.typeOf(atomic_load.ptr);
6111 const ty = ptr_ty.childType();
6112
6113 const target = f.object.dg.module.getTarget();
6114 var repr_pl = Type.Payload.Bits{
6115 .base = .{ .tag = .int_unsigned },
6116 .data = @intCast(u16, ty.abiSize(target) * 8),
6117 };
6118 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
61416119
61426120 const inst_ty = f.air.typeOfIndex(inst);
61436121 const writer = f.object.writer();
61446122 const local = try f.allocLocal(inst, inst_ty);
6145 try f.writeCValue(writer, local, .Other);
61466123
6147 try writer.writeAll(" = zig_atomic_load((zig_atomic(");
6148 try f.renderType(writer, ptr_ty.elemType());
6124 try writer.writeAll("zig_atomic_load(");
6125 try f.writeCValue(writer, local, .Other);
6126 try writer.writeAll(", (zig_atomic(");
6127 try f.renderType(writer, ty);
61496128 try writer.writeByte(')');
61506129 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
61516130 try writer.writeAll(" *)");
......@@ -6153,7 +6132,9 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
61536132 try writer.writeAll(", ");
61546133 try writeMemoryOrder(writer, atomic_load.order);
61556134 try writer.writeAll(", ");
6156 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6135 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6136 try writer.writeAll(", ");
6137 try f.object.dg.renderType(writer, repr_ty);
61576138 try writer.writeAll(");\n");
61586139
61596140 return local;
......@@ -6162,22 +6143,35 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
61626143fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
61636144 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
61646145 const ptr_ty = f.air.typeOf(bin_op.lhs);
6146 const ty = ptr_ty.childType();
61656147 const ptr = try f.resolveInst(bin_op.lhs);
61666148 const element = try f.resolveInst(bin_op.rhs);
6167 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6149
61686150 const writer = f.object.writer();
6151 const element_mat = try Materialize.start(f, inst, writer, ty, element);
6152 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6153
6154 const target = f.object.dg.module.getTarget();
6155 var repr_pl = Type.Payload.Bits{
6156 .base = .{ .tag = .int_unsigned },
6157 .data = @intCast(u16, ty.abiSize(target) * 8),
6158 };
6159 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
61696160
61706161 try writer.writeAll("zig_atomic_store((zig_atomic(");
6171 try f.renderType(writer, ptr_ty.elemType());
6162 try f.renderType(writer, ty);
61726163 try writer.writeByte(')');
61736164 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
61746165 try writer.writeAll(" *)");
61756166 try f.writeCValue(writer, ptr, .Other);
61766167 try writer.writeAll(", ");
6177 try f.writeCValue(writer, element, .FunctionArgument);
6168 try element_mat.mat(f, writer);
61786169 try writer.print(", {s}, ", .{order});
6179 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6170 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6171 try writer.writeAll(", ");
6172 try f.object.dg.renderType(writer, repr_ty);
61806173 try writer.writeAll(");\n");
6174 try element_mat.end(f, inst);
61816175
61826176 return .none;
61836177}
......@@ -6262,19 +6256,19 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
62626256 const union_ptr = try f.resolveInst(bin_op.lhs);
62636257 const new_tag = try f.resolveInst(bin_op.rhs);
62646258 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6265 const writer = f.object.writer();
62666259
6267 const union_ty = f.air.typeOf(bin_op.lhs).childType();
62686260 const target = f.object.dg.module.getTarget();
6261 const union_ty = f.air.typeOf(bin_op.lhs).childType();
62696262 const layout = union_ty.unionGetLayout(target);
62706263 if (layout.tag_size == 0) return .none;
6264 const tag_ty = union_ty.unionTagTypeSafety().?;
62716265
6272 try writer.writeByte('(');
6273 try f.writeCValue(writer, union_ptr, .Other);
6274 try writer.writeAll(")->tag = ");
6266 const writer = f.object.writer();
6267 const a = try Assignment.start(f, writer, tag_ty);
6268 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });
6269 try a.assign(f, writer);
62756270 try f.writeCValue(writer, new_tag, .Other);
6276 try writer.writeAll(";\n");
6277
6271 try a.end(f, writer);
62786272 return .none;
62796273}
62806274
......@@ -6284,20 +6278,19 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
62846278 const operand = try f.resolveInst(ty_op.operand);
62856279 try reap(f, inst, &.{ty_op.operand});
62866280
6287 const un_ty = f.air.typeOf(ty_op.operand);
6288
6281 const union_ty = f.air.typeOf(ty_op.operand);
62896282 const target = f.object.dg.module.getTarget();
6290 const layout = un_ty.unionGetLayout(target);
6283 const layout = union_ty.unionGetLayout(target);
62916284 if (layout.tag_size == 0) return .none;
62926285
62936286 const inst_ty = f.air.typeOfIndex(inst);
62946287 const writer = f.object.writer();
62956288 const local = try f.allocLocal(inst, inst_ty);
6289 const a = try Assignment.start(f, writer, inst_ty);
62966290 try f.writeCValue(writer, local, .Other);
6297
6298 try writer.writeAll(" = ");
6299 try f.writeCValue(writer, operand, .Other);
6300 try writer.writeAll(".tag;\n");
6291 try a.assign(f, writer);
6292 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });
6293 try a.end(f, writer);
63016294 return local;
63026295}
63036296
......@@ -6350,7 +6343,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
63506343
63516344 const writer = f.object.writer();
63526345 const local = try f.allocLocal(inst, inst_ty);
6353 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6346 const v = try Vectorize.start(f, inst, writer, inst_ty);
63546347 if (need_memcpy) try writer.writeAll("memcpy(&");
63556348 try f.writeCValue(writer, local, .Other);
63566349 try v.elem(f, writer);
......@@ -6380,7 +6373,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
63806373
63816374 const writer = f.object.writer();
63826375 const local = try f.allocLocal(inst, inst_ty);
6383 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6376 const v = try Vectorize.start(f, inst, writer, inst_ty);
63846377 try f.writeCValue(writer, local, .Other);
63856378 try v.elem(f, writer);
63866379 try writer.writeAll(" = ");
......@@ -6547,7 +6540,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
65476540 }, .Initializer);
65486541 try writer.writeAll(";\n");
65496542
6550 const v = try Vectorizer.start(f, inst, writer, operand_ty);
6543 const v = try Vectorize.start(f, inst, writer, operand_ty);
65516544 try f.writeCValue(writer, accum, .Other);
65526545 switch (op) {
65536546 .float_op => |func| {
......@@ -6621,87 +6614,38 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
66216614 switch (inst_ty.zigTypeTag()) {
66226615 .Array, .Vector => {
66236616 const elem_ty = inst_ty.childType();
6624
6625 const is_array = lowersToArray(elem_ty, target);
6626 const need_memcpy = is_array;
6627 if (need_memcpy) {
6628 for (resolved_elements, 0..) |element, i| {
6629 try writer.writeAll("memcpy(");
6630 try f.writeCValue(writer, local, .Other);
6631 try writer.print("[{d}]", .{i});
6632 try writer.writeAll(", ");
6633 try f.writeCValue(writer, element, .Other);
6634 try writer.writeAll(", sizeof(");
6635 try f.renderType(writer, elem_ty);
6636 try writer.writeAll("))");
6637 try writer.writeAll(";\n");
6638 }
6639 assert(inst_ty.sentinel() == null);
6640 } else {
6641 for (resolved_elements, 0..) |element, i| {
6642 try f.writeCValue(writer, local, .Other);
6643 try writer.print("[{d}] = ", .{i});
6644 try f.writeCValue(writer, element, .Other);
6645 try writer.writeAll(";\n");
6646 }
6647 if (inst_ty.sentinel()) |sentinel| {
6648 try f.writeCValue(writer, local, .Other);
6649 try writer.print("[{d}] = ", .{resolved_elements.len});
6650 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6651 try writer.writeAll(";\n");
6652 }
6617 const a = try Assignment.init(f, elem_ty);
6618 for (resolved_elements, 0..) |element, i| {
6619 try a.restart(f, writer);
6620 try f.writeCValue(writer, local, .Other);
6621 try writer.print("[{d}]", .{i});
6622 try a.assign(f, writer);
6623 try f.writeCValue(writer, element, .Other);
6624 try a.end(f, writer);
6625 }
6626 if (inst_ty.sentinel()) |sentinel| {
6627 try a.restart(f, writer);
6628 try f.writeCValue(writer, local, .Other);
6629 try writer.print("[{d}]", .{resolved_elements.len});
6630 try a.assign(f, writer);
6631 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
6632 try a.end(f, writer);
66536633 }
66546634 },
66556635 .Struct => switch (inst_ty.containerLayout()) {
6656 .Auto, .Extern => {
6657 try f.writeCValue(writer, local, .Other);
6658 try writer.writeAll(" = (");
6659 try f.renderType(writer, inst_ty);
6660 try writer.writeAll(")");
6661 try writer.writeByte('{');
6662 var empty = true;
6663 for (elements, resolved_elements, 0..) |element, resolved_element, field_i| {
6664 if (inst_ty.structFieldValueComptime(field_i)) |_| continue;
6665
6666 if (!empty) try writer.writeAll(", ");
6667
6668 const field_name: CValue = if (inst_ty.isSimpleTuple())
6669 .{ .field = field_i }
6670 else
6671 .{ .identifier = inst_ty.structFieldName(field_i) };
6672 try writer.writeByte('.');
6673 try f.object.dg.writeCValue(writer, field_name);
6674 try writer.writeAll(" = ");
6675
6676 const element_ty = f.air.typeOf(element);
6677 try f.writeCValue(writer, switch (element_ty.zigTypeTag()) {
6678 .Array => .{ .undef = element_ty },
6679 else => resolved_element,
6680 }, .Initializer);
6681 empty = false;
6682 }
6683 try writer.writeAll("};\n");
6684
6685 for (elements, resolved_elements, 0..) |element, resolved_element, field_i| {
6686 if (inst_ty.structFieldValueComptime(field_i)) |_| continue;
6687
6688 const element_ty = f.air.typeOf(element);
6689 if (element_ty.zigTypeTag() != .Array) continue;
6690
6691 const field_name: CValue = if (inst_ty.isSimpleTuple())
6692 .{ .field = field_i }
6693 else
6694 .{ .identifier = inst_ty.structFieldName(field_i) };
6636 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {
6637 if (inst_ty.structFieldIsComptime(field_i)) continue;
6638 const field_ty = inst_ty.structFieldType(field_i);
6639 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
66956640
6696 try writer.writeAll(";\n");
6697 try writer.writeAll("memcpy(");
6698 try f.writeCValueMember(writer, local, field_name);
6699 try writer.writeAll(", ");
6700 try f.writeCValue(writer, resolved_element, .FunctionArgument);
6701 try writer.writeAll(", sizeof(");
6702 try f.renderType(writer, element_ty);
6703 try writer.writeAll("));\n");
6704 }
6641 const a = try Assignment.start(f, writer, field_ty);
6642 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())
6643 .{ .field = field_i }
6644 else
6645 .{ .identifier = inst_ty.structFieldName(field_i) });
6646 try a.assign(f, writer);
6647 try f.writeCValue(writer, element, .Other);
6648 try a.end(f, writer);
67056649 },
67066650 .Packed => {
67076651 try f.writeCValue(writer, local, .Other);
......@@ -6718,8 +6662,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67186662 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
67196663
67206664 var empty = true;
6721 for (0..elements.len) |index| {
6722 const field_ty = inst_ty.structFieldType(index);
6665 for (0..elements.len) |field_i| {
6666 if (inst_ty.structFieldIsComptime(field_i)) continue;
6667 const field_ty = inst_ty.structFieldType(field_i);
67236668 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67246669
67256670 if (!empty) {
......@@ -6730,8 +6675,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67306675 empty = false;
67316676 }
67326677 empty = true;
6733 for (resolved_elements, 0..) |element, index| {
6734 const field_ty = inst_ty.structFieldType(index);
6678 for (resolved_elements, 0..) |element, field_i| {
6679 if (inst_ty.structFieldIsComptime(field_i)) continue;
6680 const field_ty = inst_ty.structFieldType(field_i);
67356681 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
67366682
67376683 if (!empty) try writer.writeAll(", ");
......@@ -6784,6 +6730,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
67846730 const target = f.object.dg.module.getTarget();
67856731 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
67866732 const field_name = union_obj.fields.keys()[extra.field_index];
6733 const payload_ty = f.air.typeOf(extra.init);
67876734 const payload = try f.resolveInst(extra.init);
67886735 try reap(f, inst, &.{extra.init});
67896736
......@@ -6811,16 +6758,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
68116758 var int_pl: Value.Payload.U64 = undefined;
68126759 const int_val = tag_val.enumToInt(tag_ty, &int_pl);
68136760
6814 try f.writeCValue(writer, local, .Other);
6815 try writer.print(".tag = {}; ", .{try f.fmtIntLiteral(tag_ty, int_val)});
6761 const a = try Assignment.start(f, writer, tag_ty);
6762 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
6763 try a.assign(f, writer);
6764 try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
6765 try a.end(f, writer);
68166766 }
68176767 break :field .{ .payload_identifier = field_name };
68186768 } else .{ .identifier = field_name };
68196769
6770 const a = try Assignment.start(f, writer, payload_ty);
68206771 try f.writeCValueMember(writer, local, field);
6821 try writer.writeAll(" = ");
6772 try a.assign(f, writer);
68226773 try f.writeCValue(writer, payload, .Other);
6823 try writer.writeAll(";\n");
6774 try a.end(f, writer);
68246775 return local;
68256776}
68266777
......@@ -6887,7 +6838,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
68876838
68886839 const writer = f.object.writer();
68896840 const local = try f.allocLocal(inst, operand_ty);
6890 const v = try Vectorizer.start(f, inst, writer, operand_ty);
6841 const v = try Vectorize.start(f, inst, writer, operand_ty);
68916842 try f.writeCValue(writer, local, .Other);
68926843 try v.elem(f, writer);
68936844 try writer.writeAll(" = zig_neg_");
......@@ -6912,7 +6863,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
69126863
69136864 const writer = f.object.writer();
69146865 const local = try f.allocLocal(inst, inst_ty);
6915 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6866 const v = try Vectorize.start(f, inst, writer, inst_ty);
69166867 try f.writeCValue(writer, local, .Other);
69176868 try v.elem(f, writer);
69186869 try writer.writeAll(" = zig_libc_name_");
......@@ -6940,7 +6891,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
69406891
69416892 const writer = f.object.writer();
69426893 const local = try f.allocLocal(inst, inst_ty);
6943 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6894 const v = try Vectorize.start(f, inst, writer, inst_ty);
69446895 try f.writeCValue(writer, local, .Other);
69456896 try v.elem(f, writer);
69466897 try writer.writeAll(" = zig_libc_name_");
......@@ -6973,7 +6924,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
69736924
69746925 const writer = f.object.writer();
69756926 const local = try f.allocLocal(inst, inst_ty);
6976 const v = try Vectorizer.start(f, inst, writer, inst_ty);
6927 const v = try Vectorize.start(f, inst, writer, inst_ty);
69776928 try f.writeCValue(writer, local, .Other);
69786929 try v.elem(f, writer);
69796930 try writer.writeAll(" = zig_libc_name_");
......@@ -7480,10 +7431,96 @@ fn formatIntLiteral(
74807431 try data.cty.renderLiteralSuffix(writer);
74817432}
74827433
7483const Vectorizer = struct {
7434const Materialize = struct {
7435 local: CValue,
7436
7437 pub fn start(
7438 f: *Function,
7439 inst: Air.Inst.Index,
7440 writer: anytype,
7441 ty: Type,
7442 value: CValue,
7443 ) !Materialize {
7444 switch (value) {
7445 .local_ref, .constant, .decl_ref, .undef => {
7446 const local = try f.allocLocal(inst, ty);
7447
7448 const a = try Assignment.start(f, writer, ty);
7449 try f.writeCValue(writer, local, .Other);
7450 try a.assign(f, writer);
7451 try f.writeCValue(writer, value, .Other);
7452 try a.end(f, writer);
7453
7454 return .{ .local = local };
7455 },
7456 .new_local => |local| return .{ .local = .{ .local = local } },
7457 else => return .{ .local = value },
7458 }
7459 }
7460
7461 pub fn mat(self: Materialize, f: *Function, writer: anytype) !void {
7462 try f.writeCValue(writer, self.local, .Other);
7463 }
7464
7465 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
7466 switch (self.local) {
7467 .new_local => |local| try freeLocal(f, inst, local, 0),
7468 else => {},
7469 }
7470 }
7471};
7472
7473const Assignment = struct {
7474 cty: CType.Index,
7475
7476 pub fn init(f: *Function, ty: Type) !Assignment {
7477 return .{ .cty = try f.typeToIndex(ty, .complete) };
7478 }
7479
7480 pub fn start(f: *Function, writer: anytype, ty: Type) !Assignment {
7481 const self = try init(f, ty);
7482 try self.restart(f, writer);
7483 return self;
7484 }
7485
7486 pub fn restart(self: Assignment, f: *Function, writer: anytype) !void {
7487 switch (self.strategy(f)) {
7488 .assign => {},
7489 .memcpy => try writer.writeAll("memcpy("),
7490 }
7491 }
7492
7493 pub fn assign(self: Assignment, f: *Function, writer: anytype) !void {
7494 switch (self.strategy(f)) {
7495 .assign => try writer.writeAll(" = "),
7496 .memcpy => try writer.writeAll(", "),
7497 }
7498 }
7499
7500 pub fn end(self: Assignment, f: *Function, writer: anytype) !void {
7501 switch (self.strategy(f)) {
7502 .assign => {},
7503 .memcpy => {
7504 try writer.writeAll(", sizeof(");
7505 try f.renderCType(writer, self.cty);
7506 try writer.writeAll("))");
7507 },
7508 }
7509 try writer.writeAll(";\n");
7510 }
7511
7512 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
7513 return switch (f.indexToCType(self.cty).tag()) {
7514 else => .assign,
7515 .array, .vector => .memcpy,
7516 };
7517 }
7518};
7519
7520const Vectorize = struct {
74847521 index: CValue = .none,
74857522
7486 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorizer {
7523 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
74877524 return if (ty.zigTypeTag() == .Vector) index: {
74887525 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };
74897526
......@@ -7504,7 +7541,7 @@ const Vectorizer = struct {
75047541 } else .{};
75057542 }
75067543
7507 pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void {
7544 pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void {
75087545 if (self.index != .none) {
75097546 try writer.writeByte('[');
75107547 try f.writeCValue(writer, self.index, .Other);
......@@ -7512,7 +7549,7 @@ const Vectorizer = struct {
75127549 }
75137550 }
75147551
7515 pub fn end(self: Vectorizer, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {
7552 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {
75167553 if (self.index != .none) {
75177554 f.object.indent_writer.popIndent();
75187555 try writer.writeAll("}\n");
......@@ -7521,11 +7558,6 @@ const Vectorizer = struct {
75217558 }
75227559};
75237560
7524fn isByRef(ty: Type) bool {
7525 _ = ty;
7526 return false;
7527}
7528
75297561const LowerFnRetTyBuffer = struct {
75307562 names: [1][]const u8,
75317563 types: [1]Type,
......@@ -7557,29 +7589,6 @@ fn lowersToArray(ty: Type, target: std.Target) bool {
75577589 };
75587590}
75597591
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
75837592fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !void {
75847593 assert(operands.len <= Liveness.bpi - 1);
75857594 var tomb_bits = f.liveness.getTombBits(inst);
src/codegen/llvm.zig+4-4
......@@ -10135,14 +10135,14 @@ fn toLlvmAtomicRmwBinOp(
1013510135) llvm.AtomicRMWBinOp {
1013610136 return switch (op) {
1013710137 .Xchg => .Xchg,
10138 .Add => if (is_float) llvm.AtomicRMWBinOp.FAdd else return .Add,
10139 .Sub => if (is_float) llvm.AtomicRMWBinOp.FSub else return .Sub,
10138 .Add => if (is_float) .FAdd else return .Add,
10139 .Sub => if (is_float) .FSub else return .Sub,
1014010140 .And => .And,
1014110141 .Nand => .Nand,
1014210142 .Or => .Or,
1014310143 .Xor => .Xor,
10144 .Max => if (is_signed) llvm.AtomicRMWBinOp.Max else return .UMax,
10145 .Min => if (is_signed) llvm.AtomicRMWBinOp.Min else return .UMin,
10144 .Max => if (is_float) .FMax else if (is_signed) .Max else return .UMax,
10145 .Min => if (is_float) .FMin else if (is_signed) .Min else return .UMin,
1014610146 };
1014710147}
1014810148
src/codegen/llvm/bindings.zig+2
......@@ -1436,6 +1436,8 @@ pub const AtomicRMWBinOp = enum(c_int) {
14361436 UMin,
14371437 FAdd,
14381438 FSub,
1439 FMax,
1440 FMin,
14391441};
14401442
14411443pub const TypeKind = enum(c_int) {
src/target.zig+6-4
......@@ -575,9 +575,6 @@ pub fn atomicPtrAlignment(
575575 .xtensa,
576576 => 32,
577577
578 .aarch64,
579 .aarch64_be,
580 .aarch64_32,
581578 .amdgcn,
582579 .bpfel,
583580 .bpfeb,
......@@ -600,7 +597,12 @@ pub fn atomicPtrAlignment(
600597 .loongarch64,
601598 => 64,
602599
603 .x86_64 => 128,
600 .aarch64,
601 .aarch64_be,
602 .aarch64_32,
603 => 128,
604
605 .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .cx16)) 128 else 64,
604606 };
605607
606608 var buffer: Type.Payload.Bits = undefined;
test/behavior/align.zig+1-10
......@@ -286,20 +286,11 @@ test "page aligned array on stack" {
286286 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
287287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
288288
289 if (builtin.zig_backend == .stage2_llvm and
290 builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows)
291 {
289 if (builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) {
292290 // https://github.com/ziglang/zig/issues/13679
293291 return error.SkipZigTest;
294292 }
295293
296 if (builtin.zig_backend == .stage2_c and
297 builtin.os.tag == .windows and builtin.cpu.arch == .aarch64)
298 {
299 // https://github.com/ziglang/zig/issues/13876
300 return error.SkipZigTest;
301 }
302
303294 // Large alignment value to make it hard to accidentally pass.
304295 var array align(0x1000) = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
305296 var number1: u8 align(16) = 42;
test/behavior/atomics.zig+21-26
......@@ -3,6 +3,13 @@ const builtin = @import("builtin");
33const expect = std.testing.expect;
44const expectEqual = std.testing.expectEqual;
55
6const supports_128_bit_atomics = switch (builtin.cpu.arch) {
7 // TODO: Ideally this could be sync'd with the logic in Sema.
8 .aarch64, .aarch64_be, .aarch64_32 => true,
9 .x86_64 => std.Target.x86.featureSetHas(builtin.cpu.features, .cx16),
10 else => false,
11};
12
613test "cmpxchg" {
714 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
815 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -107,15 +114,14 @@ test "cmpxchg with ignored result" {
107114}
108115
109116test "128-bit cmpxchg" {
117 if (!supports_128_bit_atomics) return error.SkipZigTest;
118
110119 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
111120 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
112121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
113122 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
114123 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
115124
116 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
117 if (comptime !std.Target.x86.featureSetHas(builtin.cpu.features, .cx16)) return error.SkipZigTest;
118
119125 try test_u128_cmpxchg();
120126 comptime try test_u128_cmpxchg();
121127}
......@@ -209,15 +215,7 @@ test "atomicrmw with floats" {
209215 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
210216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
211217
212 if (builtin.zig_backend == .stage2_c) {
213 // TODO: test.c:34929:7: error: address argument to atomic operation must be a pointer to integer or pointer ('zig_f32 *' (aka 'float *') invalid
214 // when compiling with -std=c99 -pedantic
215 return error.SkipZigTest;
216 }
217
218 if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and
219 builtin.cpu.arch == .aarch64)
220 {
218 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
221219 // https://github.com/ziglang/zig/issues/10627
222220 return error.SkipZigTest;
223221 }
......@@ -234,6 +232,10 @@ fn testAtomicRmwFloat() !void {
234232 try expect(x == 6);
235233 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
236234 try expect(x == 4);
235 _ = @atomicRmw(f32, &x, .Max, 13, .SeqCst);
236 try expect(x == 13);
237 _ = @atomicRmw(f32, &x, .Min, 42, .SeqCst);
238 try expect(x == 13);
237239}
238240
239241test "atomicrmw with ints" {
......@@ -242,10 +244,6 @@ test "atomicrmw with ints" {
242244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
243245 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
244246
245 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
246 return error.SkipZigTest;
247 }
248
249247 try testAtomicRmwInts();
250248 comptime try testAtomicRmwInts();
251249}
......@@ -311,24 +309,25 @@ fn testAtomicRmwInt(comptime signedness: std.builtin.Signedness, comptime N: usi
311309}
312310
313311test "atomicrmw with 128-bit ints" {
314 if (builtin.cpu.arch != .x86_64) {
315 // TODO: Ideally this could use target.atomicPtrAlignment and check for IntTooBig
316 return error.SkipZigTest;
317 }
312 if (!supports_128_bit_atomics) return error.SkipZigTest;
318313
314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
319315 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
320316
321317 // TODO "ld.lld: undefined symbol: __sync_lock_test_and_set_16" on -mcpu x86_64
322 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
318 if (builtin.cpu.arch == .x86_64 and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
323319
320 try testAtomicRmwInt128(.signed);
324321 try testAtomicRmwInt128(.unsigned);
322 comptime try testAtomicRmwInt128(.signed);
325323 comptime try testAtomicRmwInt128(.unsigned);
326324}
327325
328326fn testAtomicRmwInt128(comptime signedness: std.builtin.Signedness) !void {
327 const uint = std.meta.Int(.unsigned, 128);
329328 const int = std.meta.Int(signedness, 128);
330329
331 const initial: int = 0xaaaaaaaa_bbbbbbbb_cccccccc_dddddddd;
330 const initial: int = @bitCast(int, @as(uint, 0xaaaaaaaa_bbbbbbbb_cccccccc_dddddddd));
332331 const replacement: int = 0x00000000_00000005_00000000_00000003;
333332
334333 var x: int align(16) = initial;
......@@ -390,10 +389,6 @@ test "atomics with different types" {
390389 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
391390 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
392391
393 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
394 return error.SkipZigTest;
395 }
396
397392 try testAtomicsWithType(bool, true, false);
398393
399394 try testAtomicsWithType(u1, 0, 1);
test/behavior/builtin_functions_returning_void_or_noreturn.zig-1
......@@ -7,7 +7,6 @@ var x: u8 = 1;
77// This excludes builtin functions that return void or noreturn that cannot be tested.
88test {
99 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1110 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/cast.zig-27
......@@ -1313,16 +1313,6 @@ test "cast f16 to wider types" {
13131313 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13141314 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13151315
1316 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1317 // TODO: test is failing
1318 return error.SkipZigTest;
1319 }
1320
1321 if (builtin.os.tag == .windows and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
1322 // TODO: test is failing
1323 return error.SkipZigTest;
1324 }
1325
13261316 const S = struct {
13271317 fn doTheTest() !void {
13281318 var x: f16 = 1234.0;
......@@ -1342,18 +1332,6 @@ test "cast f128 to narrower types" {
13421332 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
13431333 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13441334
1345 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
1346 builtin.zig_backend == .stage2_c)
1347 {
1348 // https://github.com/ziglang/zig/issues/13876
1349 return error.SkipZigTest;
1350 }
1351
1352 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1353 // TODO: test is failing
1354 return error.SkipZigTest;
1355 }
1356
13571335 const S = struct {
13581336 fn doTheTest() !void {
13591337 var x: f128 = 1234.0;
......@@ -1444,11 +1422,6 @@ test "coerce between pointers of compatible differently-named floats" {
14441422 return error.SkipZigTest;
14451423 }
14461424
1447 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
1448 // TODO: test is failing
1449 return error.SkipZigTest;
1450 }
1451
14521425 const F = switch (@typeInfo(c_longdouble).Float.bits) {
14531426 16 => f16,
14541427 32 => f32,
test/behavior/floatop.zig-56
......@@ -535,18 +535,6 @@ test "another, possibly redundant, @fabs test" {
535535 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
536536 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
537537
538 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
539 builtin.zig_backend == .stage2_c)
540 {
541 // https://github.com/ziglang/zig/issues/13876
542 return error.SkipZigTest;
543 }
544
545 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
546 // TODO: test is failing
547 return error.SkipZigTest;
548 }
549
550538 try testFabsLegacy(f128, 12.0);
551539 comptime try testFabsLegacy(f128, 12.0);
552540 try testFabsLegacy(f64, 12.0);
......@@ -584,18 +572,6 @@ test "a third @fabs test, surely there should not be three fabs tests" {
584572 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
585573 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
586574
587 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
588 builtin.zig_backend == .stage2_c)
589 {
590 // https://github.com/ziglang/zig/issues/13876
591 return error.SkipZigTest;
592 }
593
594 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
595 // TODO: test is failing
596 return error.SkipZigTest;
597 }
598
599575 inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
600576 // normals
601577 try expect(@fabs(@as(T, 1.0)) == 1.0);
......@@ -698,11 +674,6 @@ test "@floor f128" {
698674 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
699675 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
700676
701 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
702 // TODO: test is failing
703 return error.SkipZigTest;
704 }
705
706677 try testFloorLegacy(f128, 12.0);
707678 comptime try testFloorLegacy(f128, 12.0);
708679}
......@@ -793,11 +764,6 @@ test "@ceil f128" {
793764 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
794765 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
795766
796 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86_64) {
797 // TODO: test is failing
798 return error.SkipZigTest;
799 }
800
801767 try testCeilLegacy(f128, 12.0);
802768 comptime try testCeilLegacy(f128, 12.0);
803769}
......@@ -894,11 +860,6 @@ test "@trunc f128" {
894860 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
895861 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
896862
897 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
898 // TODO: test is failing
899 return error.SkipZigTest;
900 }
901
902863 try testTruncLegacy(f128, 12.0);
903864 comptime try testTruncLegacy(f128, 12.0);
904865}
......@@ -1010,18 +971,6 @@ test "negation f128" {
1010971 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1011972 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1012973
1013 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
1014 builtin.zig_backend == .stage2_c)
1015 {
1016 // https://github.com/ziglang/zig/issues/13876
1017 return error.SkipZigTest;
1018 }
1019
1020 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1021 // TODO: test is failing
1022 return error.SkipZigTest;
1023 }
1024
1025974 const S = struct {
1026975 fn doTheTest() !void {
1027976 var a: f128 = 1;
......@@ -1065,11 +1014,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" {
10651014 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10661015 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10671016
1068 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86_64) {
1069 // TODO: test is failing
1070 return error.SkipZigTest;
1071 }
1072
10731017 inline for (.{ f16, f32, f64, f80, f128 }) |F| {
10741018 try expect(math.isNan(@as(F, 0) / @as(F, 0)));
10751019 }
test/behavior/math.zig-63
......@@ -615,18 +615,6 @@ test "f128" {
615615 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
616616 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
617617
618 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
619 builtin.zig_backend == .stage2_c)
620 {
621 // https://github.com/ziglang/zig/issues/13876
622 return error.SkipZigTest;
623 }
624
625 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
626 // TODO: test is failing
627 return error.SkipZigTest;
628 }
629
630618 try test_f128();
631619 comptime try test_f128();
632620}
......@@ -1297,18 +1285,6 @@ test "remainder division" {
12971285 return error.SkipZigTest;
12981286 }
12991287
1300 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and
1301 builtin.cpu.arch == .aarch64)
1302 {
1303 // https://github.com/ziglang/zig/issues/13876
1304 return error.SkipZigTest;
1305 }
1306
1307 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1308 // TODO: test is failing
1309 return error.SkipZigTest;
1310 }
1311
13121288 comptime try remdiv(f16);
13131289 comptime try remdiv(f32);
13141290 comptime try remdiv(f64);
......@@ -1340,11 +1316,6 @@ test "float remainder division using @rem" {
13401316 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13411317 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13421318
1343 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86_64) {
1344 // TODO: test is failing
1345 return error.SkipZigTest;
1346 }
1347
13481319 comptime try frem(f16);
13491320 comptime try frem(f32);
13501321 comptime try frem(f64);
......@@ -1387,11 +1358,6 @@ test "float modulo division using @mod" {
13871358 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13881359 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13891360
1390 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86_64) {
1391 // TODO: test is failing
1392 return error.SkipZigTest;
1393 }
1394
13951361 comptime try fmod(f16);
13961362 comptime try fmod(f32);
13971363 comptime try fmod(f64);
......@@ -1465,11 +1431,6 @@ test "@round f128" {
14651431 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14661432 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14671433
1468 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1469 // TODO: test is failing
1470 return error.SkipZigTest;
1471 }
1472
14731434 try testRound(f128, 12.0);
14741435 comptime try testRound(f128, 12.0);
14751436}
......@@ -1508,18 +1469,6 @@ test "NaN comparison" {
15081469 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
15091470 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15101471
1511 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and
1512 builtin.cpu.arch == .aarch64)
1513 {
1514 // https://github.com/ziglang/zig/issues/13876
1515 return error.SkipZigTest;
1516 }
1517
1518 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
1519 // TODO: test is failing
1520 return error.SkipZigTest;
1521 }
1522
15231472 try testNanEqNan(f16);
15241473 try testNanEqNan(f32);
15251474 try testNanEqNan(f64);
......@@ -1589,18 +1538,6 @@ test "signed zeros are represented properly" {
15891538 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
15901539 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15911540
1592 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
1593 builtin.zig_backend == .stage2_c)
1594 {
1595 // TODO: test is failing
1596 return error.SkipZigTest;
1597 }
1598
1599 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
1600 // TODO: test is failing
1601 return error.SkipZigTest;
1602 }
1603
16041541 const S = struct {
16051542 fn doTheTest() !void {
16061543 try testOne(f16);
test/behavior/muladd.zig-24
......@@ -68,18 +68,6 @@ test "@mulAdd f128" {
6868 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6969 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7070
71 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
72 builtin.zig_backend == .stage2_c)
73 {
74 // https://github.com/ziglang/zig/issues/13876
75 return error.SkipZigTest;
76 }
77
78 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
79 // TODO: test is failing
80 return error.SkipZigTest;
81 }
82
8371 comptime try testMulAdd128();
8472 try testMulAdd128();
8573}
......@@ -201,18 +189,6 @@ test "vector f128" {
201189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
202190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
203191
204 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
205 builtin.zig_backend == .stage2_c)
206 {
207 // https://github.com/ziglang/zig/issues/13876
208 return error.SkipZigTest;
209 }
210
211 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) {
212 // TODO: test is failing
213 return error.SkipZigTest;
214 }
215
216192 comptime try vector128();
217193 try vector128();
218194}
test/behavior/packed-struct.zig+12
......@@ -615,3 +615,15 @@ test "pointer to container level packed struct field" {
615615 @ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true;
616616 try expect(S.arr[0] == 0x10000000);
617617}
618
619test "store undefined to packed result location" {
620 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
621 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
622 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
623 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
624 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
625
626 var x: u4 = 0;
627 var s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined };
628 try expectEqual(x, s.x);
629}
test/behavior/vector.zig-12
......@@ -96,18 +96,6 @@ test "vector float operators" {
9696 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9797 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9898
99 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
100 builtin.zig_backend == .stage2_c)
101 {
102 // https://github.com/ziglang/zig/issues/13876
103 return error.SkipZigTest;
104 }
105
106 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
107 // TODO: test is failing
108 return error.SkipZigTest;
109 }
110
11199 inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
112100 const S = struct {
113101 fn doTheTest() !void {
test/behavior/widening.zig-24
......@@ -43,18 +43,6 @@ test "float widening" {
4343 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
4444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4545
46 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
47 builtin.zig_backend == .stage2_c)
48 {
49 // https://github.com/ziglang/zig/issues/13876
50 return error.SkipZigTest;
51 }
52
53 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
54 // TODO: test is failing
55 return error.SkipZigTest;
56 }
57
5846 var a: f16 = 12.34;
5947 var b: f32 = a;
6048 var c: f64 = b;
......@@ -75,18 +63,6 @@ test "float widening f16 to f128" {
7563 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7664 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7765
78 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and
79 builtin.zig_backend == .stage2_c)
80 {
81 // https://github.com/ziglang/zig/issues/13876
82 return error.SkipZigTest;
83 }
84
85 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
86 // TODO: test is failing
87 return error.SkipZigTest;
88 }
89
9066 var x: f16 = 12.34;
9167 var y: f128 = x;
9268 try expect(x == y);
test/cases/compile_errors/atomicrmw_with_float_op_not_.Xchg_.Add_.Sub_.Max_or_.Min.zig created+10
......@@ -0,0 +1,10 @@
1export fn entry() void {
2 var x: f32 = 0;
3 _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:30: error: @atomicRmw with float only allowed with .Xchg, .Add, .Sub, .Max, and .Min
test/cases/compile_errors/atomicrmw_with_float_op_not_.Xchg_.Add_or_.Sub.zig deleted-10
......@@ -1,10 +0,0 @@
1export fn entry() void {
2 var x: f32 = 0;
3 _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:30: error: @atomicRmw with float only allowed with .Xchg, .Add, and .Sub
test/tests.zig+17-11
......@@ -962,13 +962,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
962962 if (test_target.use_llvm == false and mem.eql(u8, options.name, "std"))
963963 continue;
964964
965 // TODO get std lib tests passing for the C backend
966 if (test_target.target.ofmt == std.Target.ObjectFormat.c and
967 mem.eql(u8, options.name, "std"))
968 {
969 continue;
970 }
971
972965 const want_this_mode = for (options.optimize_modes) |m| {
973966 if (m == test_target.optimize_mode) break true;
974967 } else false;
......@@ -1033,6 +1026,8 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10331026 "-std=c99",
10341027 "-pedantic",
10351028 "-Werror",
1029 // TODO stop violating these pedantic errors. spotted everywhere
1030 "-Wno-builtin-requires-header",
10361031 // TODO stop violating these pedantic errors. spotted on linux
10371032 "-Wno-address-of-packed-member",
10381033 "-Wno-gnu-folding-constant",
......@@ -1044,10 +1039,21 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10441039 },
10451040 });
10461041 compile_c.addIncludePath("lib"); // for zig.h
1047 if (test_target.link_libc == false and test_target.target.getOsTag() == .windows) {
1048 compile_c.subsystem = .Console;
1049 compile_c.linkSystemLibrary("kernel32");
1050 compile_c.linkSystemLibrary("ntdll");
1042 if (test_target.target.getOsTag() == .windows) {
1043 if (test_target.link_libc == false) {
1044 compile_c.subsystem = .Console;
1045 compile_c.linkSystemLibrary("kernel32");
1046 compile_c.linkSystemLibrary("ntdll");
1047 }
1048 if (mem.eql(u8, options.name, "std")) {
1049 if (test_target.link_libc == false) {
1050 compile_c.linkSystemLibrary("shell32");
1051 compile_c.linkSystemLibrary("advapi32");
1052 }
1053 compile_c.linkSystemLibrary("crypt32");
1054 compile_c.linkSystemLibrary("ws2_32");
1055 compile_c.linkSystemLibrary("ole32");
1056 }
10511057 }
10521058
10531059 const run = b.addRunArtifact(compile_c);