authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-25 01:53:50-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 14:35:12-04:00
log865f329e4f9fd097bb9739566045f9b7179521c4
treedf3335def8df53356c399f4a7663dc29a506ae0e
parent69dd10144fc723d8006f2e563fc3edd82ee4b368

cbe: update for compiler_rt abi changes

* `tools/generate_c_size_and_align_checks.zig`: superceded by any cbe output artifact * `cTypePreferredAlignment`: no uses, if brought back, cbe should be updated to verify `__alignof` Closes #19991 Closes #20881 Closes #35523

60 files changed, 4055 insertions(+), 2069 deletions(-)

lib/compiler/test_runner.zig+1
......@@ -377,6 +377,7 @@ pub fn mainSimple() anyerror!void {
377377 else => false,
378378 };
379379
380 testing.allocator_instance = .init(std.heap.page_allocator, .{});
380381 testing.io_instance = .init(testing.allocator, .{});
381382
382383 var passed: u64 = 0;
lib/std/Io/Semaphore.zig-2
......@@ -4,8 +4,6 @@
44//! This API supports static initialization and does not require deinitialization.
55const Semaphore = @This();
66
7const builtin = @import("builtin");
8
97const std = @import("../std.zig");
108const Io = std.Io;
119const testing = std.testing;
lib/std/Io/Writer.zig+3-3
......@@ -874,7 +874,7 @@ pub fn splatBytes(w: *Writer, bytes: []const u8, n: usize) Error!usize {
874874}
875875
876876/// Asserts the `buffer` was initialized with a capacity of at least `@sizeOf(T)` bytes.
877pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
877pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.lang.Endian) Error!void {
878878 var bytes: [@divExact(@typeInfo(T).int.bits, 8)]u8 = undefined;
879879 std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
880880 return w.writeAll(&bytes);
......@@ -882,7 +882,7 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built
882882
883883/// The function is inline to avoid the dead code in case `endian` is
884884/// comptime-known and matches host endianness.
885pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void {
885pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.lang.Endian) Error!void {
886886 switch (@typeInfo(@TypeOf(value))) {
887887 .@"struct" => |info| switch (info.layout) {
888888 .auto => @compileError("ill-defined memory layout"),
......@@ -907,7 +907,7 @@ pub inline fn writeSliceEndian(
907907 w: *Writer,
908908 Elem: type,
909909 slice: []const Elem,
910 endian: std.builtin.Endian,
910 endian: std.lang.Endian,
911911) Error!void {
912912 switch (@typeInfo(Elem)) {
913913 .@"struct" => |info| comptime assert(info.layout != .auto),
lib/std/Random/RomuTrio.zig-1
......@@ -122,7 +122,6 @@ test fill {
122122}
123123
124124test "buf seeding test" {
125 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
126125 const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 });
127126 const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 };
128127 var r = RomuTrio.init(0);
lib/std/Random/Xoshiro256.zig-2
......@@ -89,8 +89,6 @@ pub fn fill(self: *Xoshiro256, buf: []u8) void {
8989}
9090
9191test "sequence" {
92 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
93
9492 var r = Xoshiro256.init(0);
9593
9694 const seq1 = [_]u64{
lib/std/Target.zig-114
......@@ -3575,120 +3575,6 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
35753575 );
35763576}
35773577
3578pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
3579 // Overrides for unusual alignments
3580 switch (target.cpu.arch) {
3581 .arc, .arceb => switch (c_type) {
3582 .longdouble => return 4,
3583 else => {},
3584 },
3585 .avr,
3586 .ez80,
3587 => return 1,
3588 .x86 => switch (target.os.tag) {
3589 .windows, .uefi => switch (c_type) {
3590 .longdouble => switch (target.abi) {
3591 .gnu => return 4,
3592 else => return 8,
3593 },
3594 else => {},
3595 },
3596 else => switch (c_type) {
3597 .longdouble => return 4,
3598 else => {},
3599 },
3600 },
3601 .m68k => switch (c_type) {
3602 .int, .uint, .long, .ulong => return 2,
3603 else => {},
3604 },
3605 .wasm32, .wasm64 => switch (target.os.tag) {
3606 .emscripten => switch (c_type) {
3607 .longdouble => return 8,
3608 else => {},
3609 },
3610 else => {},
3611 },
3612 else => {},
3613 }
3614
3615 // Next-power-of-two-aligned, up to a maximum.
3616 return @min(
3617 std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
3618 @as(u16, switch (target.cpu.arch) {
3619 .x86_16,
3620 .msp430,
3621 => 2,
3622
3623 .arc,
3624 .arceb,
3625 .csky,
3626 .kalimba,
3627 .microblaze,
3628 .microblazeel,
3629 .or1k,
3630 .propeller,
3631 .sh,
3632 .sheb,
3633 .xcore,
3634 .xtensa,
3635 .xtensaeb,
3636 => 4,
3637
3638 .amdgcn,
3639 .arm,
3640 .armeb,
3641 .bpfeb,
3642 .bpfel,
3643 .hexagon,
3644 .hppa,
3645 .lanai,
3646 .m68k,
3647 .m88k,
3648 .mips,
3649 .mipsel,
3650 .nvptx,
3651 .nvptx64,
3652 .s390x,
3653 .sparc,
3654 .thumb,
3655 .thumbeb,
3656 .x86,
3657 => 8,
3658
3659 .aarch64,
3660 .aarch64_be,
3661 .alpha,
3662 .hppa64,
3663 .kvx,
3664 .loongarch32,
3665 .loongarch64,
3666 .mips64,
3667 .mips64el,
3668 .powerpc,
3669 .powerpcle,
3670 .powerpc64,
3671 .powerpc64le,
3672 .riscv32,
3673 .riscv32be,
3674 .riscv64,
3675 .riscv64be,
3676 .sparc64,
3677 .spirv32,
3678 .spirv64,
3679 .ve,
3680 .wasm32,
3681 .wasm64,
3682 .x86_64,
3683 => 16,
3684
3685 .avr,
3686 .ez80,
3687 => unreachable, // Handled above.
3688 }),
3689 );
3690}
3691
36923578pub fn cMaxIntAlignment(target: *const Target) u16 {
36933579 return switch (target.cpu.arch) {
36943580 .avr,
lib/std/bit_set.zig-2
......@@ -1707,8 +1707,6 @@ fn testStaticBitSet(comptime Set: type) !void {
17071707}
17081708
17091709test Integer {
1710 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1711
17121710 try testStaticBitSet(Integer(0));
17131711 try testStaticBitSet(Integer(1));
17141712 try testStaticBitSet(Integer(2));
lib/std/crypto/aes.zig+2-2
......@@ -6,9 +6,9 @@ const has_aesni = builtin.cpu.has(.x86, .aes);
66const has_avx = builtin.cpu.has(.x86, .avx);
77const has_armaes = builtin.cpu.has(.aarch64, .aes);
88// 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: {
9const impl = if (builtin.cpu.arch == .x86_64 and has_aesni and has_avx) impl: {
1010 break :impl @import("aes/aesni.zig");
11} else if (builtin.cpu.arch == .aarch64 and builtin.zig_backend != .stage2_c and has_armaes) impl: {
11} else if (builtin.cpu.arch == .aarch64 and (builtin.zig_backend != .stage2_c or !builtin.os.tag.isDarwin()) and has_armaes) impl: {
1212 break :impl @import("aes/armcrypto.zig");
1313} else impl: {
1414 break :impl @import("aes/soft.zig");
lib/std/crypto/aes_ocb.zig-10
......@@ -262,8 +262,6 @@ const hexToBytes = std.fmt.hexToBytes;
262262const testing = std.testing;
263263
264264test "AesOcb test vector 1" {
265 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
266
267265 var k: [Aes128Ocb.key_length]u8 = undefined;
268266 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
269267 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -281,8 +279,6 @@ test "AesOcb test vector 1" {
281279}
282280
283281test "AesOcb test vector 2" {
284 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
285
286282 var k: [Aes128Ocb.key_length]u8 = undefined;
287283 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
288284 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -303,8 +299,6 @@ test "AesOcb test vector 2" {
303299}
304300
305301test "AesOcb test vector 3" {
306 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
307
308302 var k: [Aes128Ocb.key_length]u8 = undefined;
309303 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
310304 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -329,8 +323,6 @@ test "AesOcb test vector 3" {
329323}
330324
331325test "AesOcb test vector 4" {
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
333
334326 var k: [Aes128Ocb.key_length]u8 = undefined;
335327 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
336328 var tag: [Aes128Ocb.tag_length]u8 = undefined;
......@@ -356,8 +348,6 @@ test "AesOcb test vector 4" {
356348}
357349
358350test "AesOcb in-place encryption-decryption" {
359 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
360
361351 var k: [Aes128Ocb.key_length]u8 = undefined;
362352 var nonce: [Aes128Ocb.nonce_length]u8 = undefined;
363353 var tag: [Aes128Ocb.tag_length]u8 = undefined;
lib/std/crypto/ecdsa.zig-21
......@@ -1,4 +1,3 @@
1const builtin = @import("builtin");
21const std = @import("std");
32const crypto = std.crypto;
43const fmt = std.fmt;
......@@ -415,8 +414,6 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
415414}
416415
417416test "Basic operations over EcdsaP384Sha384" {
418 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
419
420417 const io = testing.io;
421418 const Scheme = EcdsaP384Sha384;
422419 const kp = Scheme.KeyPair.generate(io);
......@@ -432,8 +429,6 @@ test "Basic operations over EcdsaP384Sha384" {
432429}
433430
434431test "Basic operations over Secp256k1" {
435 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
436
437432 const io = testing.io;
438433 const Scheme = EcdsaSecp256k1Sha256oSha256;
439434 const kp = Scheme.KeyPair.generate(io);
......@@ -449,8 +444,6 @@ test "Basic operations over Secp256k1" {
449444}
450445
451446test "Basic operations over EcdsaP384Sha256" {
452 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
453
454447 const io = testing.io;
455448 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
456449 const kp = Scheme.KeyPair.generate(io);
......@@ -466,8 +459,6 @@ test "Basic operations over EcdsaP384Sha256" {
466459}
467460
468461test "Verifying a existing signature with EcdsaP384Sha256" {
469 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
470
471462 const Scheme = Ecdsa(crypto.ecc.P384, crypto.hash.sha2.Sha256);
472463 // zig fmt: off
473464 const sk_bytes = [_]u8{
......@@ -503,8 +494,6 @@ test "Verifying a existing signature with EcdsaP384Sha256" {
503494}
504495
505496test "Prehashed message operations" {
506 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
507
508497 const io = testing.io;
509498
510499 const Scheme = EcdsaP256Sha256;
......@@ -539,8 +528,6 @@ const TestVector = struct {
539528};
540529
541530test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {
542 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
543
544531 const vectors: []const TestVector = &.{
545532 // well-formed DER encoding -> expected valid
546533 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1802204cd60b855d442f5b3c7b11eb6c4e0ae7525fe710fab9aa7c77a67f79e6fadd76" },
......@@ -711,8 +698,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 valid" {
711698}
712699
713700test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {
714 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
715
716701 const vectors: []const TestVector = &.{
717702 // S encoded with negative sign -> expected invalid
718703 .{ .key = "042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e", .msg = "313233343030", .sig = "304402202ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e180220b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db" },
......@@ -1026,8 +1011,6 @@ test "Test vectors from Project Wycheproof - EcdsaP256Sha256 invalid" {
10261011}
10271012
10281013test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {
1029 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1030
10311014 const vectors: []const TestVector = &.{
10321015 // canonical sign-bit padding on R; canonical sign-bit padding on S -> expected valid
10331016 .{ .key = "0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3", .msg = "4d7367", .sig = "3066023100d7143a836608b25599a7f28dec6635494c2992ad1e2bbeecb7ef601a9c01746e710ce0d9c48accb38a79ede5b9638f3402310080f9e165e8c61035bf8aa7b5533960e46dd0e211c904a064edb6de41f797c0eae4e327612ee3f816f4157272bb4fabc9" },
......@@ -1243,8 +1226,6 @@ test "Test vectors from Project Wycheproof - EcdsaP384Sha384 valid" {
12431226}
12441227
12451228test "Test vectors from Project Wycheproof - EcdsaP384Sha384 invalid" {
1246 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1247
12481229 const vectors: []const TestVector = &.{
12491230 // S encoded with negative sign -> expected invalid
12501231 .{ .key = "042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b1836197d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f", .msg = "313233343030", .sig = "3064023012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d70230e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82" },
......@@ -1631,8 +1612,6 @@ fn tvTry(comptime Scheme: type, vector: TestVector) !void {
16311612}
16321613
16331614test "Sec1 encoding/decoding" {
1634 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1635
16361615 const io = testing.io;
16371616 const Scheme = EcdsaP384Sha384;
16381617 const kp = Scheme.KeyPair.generate(io);
lib/std/crypto/ff.zig-4
......@@ -966,8 +966,6 @@ const ct_unprotected = struct {
966966};
967967
968968test "finite field arithmetic" {
969 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
970
971969 const M = Modulus(256);
972970 const m = try M.fromPrimitive(u256, 3429938563481314093726330772853735541133072814650493833233);
973971 var x = try M.Fe.fromPrimitive(u256, m, 80169837251094269539116136208111827396136208141182357733);
......@@ -1066,8 +1064,6 @@ test "finite field arithmetic" {
10661064}
10671065
10681066fn testCt(ct_: anytype) !void {
1069 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1070
10711067 const l0: Limb = 0;
10721068 const l1: Limb = 1;
10731069 try testing.expectEqual(l1, ct_.select(true, l1, l0));
lib/std/crypto/pcurves/p384.zig+4-6
......@@ -56,7 +56,7 @@ pub const P384 = struct {
5656 }
5757
5858 /// Create a point from serialized affine coordinates.
59 pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!P384 {
59 pub fn fromSerializedAffineCoordinates(xs: [48]u8, ys: [48]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!P384 {
6060 const x = try Fe.fromBytes(xs, endian);
6161 const y = try Fe.fromBytes(ys, endian);
6262 return fromAffineCoordinates(.{ .x = x, .y = y });
......@@ -395,7 +395,7 @@ pub const P384 = struct {
395395
396396 /// Multiply an elliptic curve point by a scalar.
397397 /// Return error.IdentityElement if the result is the identity element.
398 pub fn mul(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {
398 pub fn mul(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
399399 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
400400 if (p.is_base) {
401401 return pcMul16(&basePointPc, s, false);
......@@ -407,7 +407,7 @@ pub const P384 = struct {
407407
408408 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*
409409 /// This can be used for signature verification.
410 pub fn mulPublic(p: P384, s_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {
410 pub fn mulPublic(p: P384, s_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
411411 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
412412 if (p.is_base) {
413413 return pcMul16(&basePointPc, s, true);
......@@ -419,7 +419,7 @@ pub const P384 = struct {
419419
420420 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*
421421 /// This can be used for signature verification.
422 pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.builtin.Endian) IdentityElementError!P384 {
422 pub fn mulDoubleBasePublic(p1: P384, s1_: [48]u8, p2: P384, s2_: [48]u8, endian: std.lang.Endian) IdentityElementError!P384 {
423423 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);
424424 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);
425425 try p1.rejectIdentity();
......@@ -478,7 +478,5 @@ pub const AffineCoordinates = struct {
478478};
479479
480480test {
481 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
482
483481 _ = @import("tests/p384.zig");
484482}
lib/std/crypto/pcurves/secp256k1.zig+5-7
......@@ -51,7 +51,7 @@ pub const Secp256k1 = struct {
5151 };
5252
5353 /// Compute r1 and r2 so that k = r1 + r2*lambda (mod L).
54 pub fn splitScalar(s: [32]u8, endian: std.builtin.Endian) NonCanonicalError!SplitScalar {
54 pub fn splitScalar(s: [32]u8, endian: std.lang.Endian) NonCanonicalError!SplitScalar {
5555 const b1_neg_s = comptime s: {
5656 var buf: [32]u8 = undefined;
5757 mem.writeInt(u256, &buf, 303414439467246543595250775667605759171, .little);
......@@ -109,7 +109,7 @@ pub const Secp256k1 = struct {
109109 }
110110
111111 /// Create a point from serialized affine coordinates.
112 pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.builtin.Endian) (NonCanonicalError || EncodingError)!Secp256k1 {
112 pub fn fromSerializedAffineCoordinates(xs: [32]u8, ys: [32]u8, endian: std.lang.Endian) (NonCanonicalError || EncodingError)!Secp256k1 {
113113 const x = try Fe.fromBytes(xs, endian);
114114 const y = try Fe.fromBytes(ys, endian);
115115 return fromAffineCoordinates(.{ .x = x, .y = y });
......@@ -423,7 +423,7 @@ pub const Secp256k1 = struct {
423423
424424 /// Multiply an elliptic curve point by a scalar.
425425 /// Return error.IdentityElement if the result is the identity element.
426 pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {
426 pub fn mul(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 {
427427 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
428428 if (p.is_base) {
429429 return pcMul16(&basePointPc, s, false);
......@@ -435,7 +435,7 @@ pub const Secp256k1 = struct {
435435
436436 /// Multiply an elliptic curve point by a *PUBLIC* scalar *IN VARIABLE TIME*
437437 /// This can be used for signature verification.
438 pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.builtin.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 {
438 pub fn mulPublic(p: Secp256k1, s_: [32]u8, endian: std.lang.Endian) (IdentityElementError || NonCanonicalError)!Secp256k1 {
439439 const s = if (endian == .little) s_ else Fe.orderSwap(s_);
440440 const zero = comptime scalar.Scalar.zero.toBytes(.little);
441441 if (mem.eql(u8, &zero, &s)) {
......@@ -497,7 +497,7 @@ pub const Secp256k1 = struct {
497497
498498 /// Double-base multiplication of public parameters - Compute (p1*s1)+(p2*s2) *IN VARIABLE TIME*
499499 /// This can be used for signature verification.
500 pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!Secp256k1 {
500 pub fn mulDoubleBasePublic(p1: Secp256k1, s1_: [32]u8, p2: Secp256k1, s2_: [32]u8, endian: std.lang.Endian) IdentityElementError!Secp256k1 {
501501 const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);
502502 const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);
503503 try p1.rejectIdentity();
......@@ -556,7 +556,5 @@ pub const AffineCoordinates = struct {
556556};
557557
558558test {
559 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
560
561559 _ = @import("tests/secp256k1.zig");
562560}
lib/std/debug/cpu_context.zig+2
......@@ -2020,6 +2020,8 @@ const signal_ucontext_t = switch (native_os) {
20202020 .mips64el,
20212021 .or1k,
20222022 .s390x,
2023 .sh,
2024 .sheb,
20232025 .x86,
20242026 .x86_64,
20252027 .xtensa,
lib/std/fmt.zig-2
......@@ -1082,8 +1082,6 @@ test "float.libc.sanity" {
10821082}
10831083
10841084test "union" {
1085 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1086
10871085 const TU = union(enum) {
10881086 float: f32,
10891087 int: u32,
lib/std/fmt/float.zig+1-1
......@@ -65,7 +65,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 {
6565
6666 const DT = if (@bitSizeOf(T) <= 64) u64 else u128;
6767 const tables = switch (DT) {
68 u64 => if (@import("builtin").mode == .small) &Backend64_TablesSmall else &Backend64_TablesFull,
68 u64 => if (builtin.mode == .small) &Backend64_TablesSmall else &Backend64_TablesFull,
6969 u128 => &Backend128_Tables,
7070 else => unreachable,
7171 };
lib/std/fs/test.zig+2-3
......@@ -2205,7 +2205,7 @@ test "'.' and '..' in absolute functions" {
22052205}
22062206
22072207test "chmod" {
2208 if (native_os == .windows or native_os == .wasi) return;
2208 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
22092209
22102210 const io = testing.io;
22112211
......@@ -2228,8 +2228,7 @@ test "chmod" {
22282228}
22292229
22302230test "change ownership" {
2231 if (native_os == .windows or native_os == .wasi)
2232 return error.SkipZigTest;
2231 if (native_os == .windows or native_os == .wasi) return error.SkipZigTest;
22332232
22342233 const io = testing.io;
22352234
lib/std/hash/auto_hash.zig+1-1
......@@ -225,7 +225,7 @@ fn testHashDeepRecursive(key: anytype) u64 {
225225
226226test "typeContainsSlice" {
227227 comptime {
228 try testing.expect(!typeContainsSlice(std.meta.Tag(std.builtin.Type)));
228 try testing.expect(!typeContainsSlice(std.meta.Tag(std.lang.Type)));
229229
230230 try testing.expect(typeContainsSlice([]const u8));
231231 try testing.expect(!typeContainsSlice(u8));
lib/std/hash/xxhash.zig-4
......@@ -1,5 +1,4 @@
11const std = @import("std");
2const builtin = @import("builtin");
32const mem = std.mem;
43const expectEqual = std.testing.expectEqual;
54
......@@ -788,7 +787,6 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64)
788787}
789788
790789test "xxhash3" {
791 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
792790 const H = XxHash3;
793791 // Non-Seeded Tests
794792 try testExpect(H, 0, "", 0x2d06800538d394c2);
......@@ -820,7 +818,6 @@ test "xxhash3" {
820818}
821819
822820test "xxhash3 smhasher" {
823 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
824821 const Test = struct {
825822 fn do() !void {
826823 try expectEqual(verify.smhasher(XxHash3.hash), 0x9a636405);
......@@ -832,7 +829,6 @@ test "xxhash3 smhasher" {
832829}
833830
834831test "xxhash3 iterative api" {
835 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
836832 const Test = struct {
837833 fn do() !void {
838834 try verify.iterativeApi(XxHash3);
lib/std/math.zig+2-1
......@@ -1385,7 +1385,8 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
13851385}
13861386
13871387test lerp {
1388 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
1388 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1389 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isX86()) return error.SkipZigTest;
13891390 if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
13901391
13911392 try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5));
lib/std/math/big/int_test.zig+1-38
......@@ -1,5 +1,4 @@
11const std = @import("../../std.zig");
2const builtin = @import("builtin");
32const mem = std.mem;
43const testing = std.testing;
54const Managed = std.math.big.int.Managed;
......@@ -276,8 +275,6 @@ fn setFloat(comptime Float: type) !void {
276275 try expectNormalized(1 << 10, res.toConst());
277276}
278277test setFloat {
279 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
280
281278 try setFloat(f16);
282279 try setFloat(f32);
283280 try setFloat(f64);
......@@ -484,7 +481,6 @@ fn toFloat(comptime Float: type) !void {
484481 );
485482}
486483test toFloat {
487 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
488484 try toFloat(f16);
489485 try toFloat(f32);
490486 try toFloat(f64);
......@@ -1391,8 +1387,6 @@ test "mul multi-single" {
13911387}
13921388
13931389test "mul multi-multi" {
1394 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1395
13961390 var op1: u256 = 0x998888efefefefefefefef;
13971391 var op2: u256 = 0x333000abababababababab;
13981392 _ = .{ &op1, &op2 };
......@@ -1514,8 +1508,6 @@ test "mulWrap single-single signed" {
15141508}
15151509
15161510test "mulWrap multi-multi unsigned" {
1517 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1518
15191511 var op1: u256 = 0x998888efefefefefefefef;
15201512 var op2: u256 = 0x333000abababababababab;
15211513 _ = .{ &op1, &op2 };
......@@ -1533,11 +1525,6 @@ test "mulWrap multi-multi unsigned" {
15331525}
15341526
15351527test "mulWrap multi-multi signed" {
1536 switch (builtin.zig_backend) {
1537 .stage2_c => return error.SkipZigTest,
1538 else => {},
1539 }
1540
15411528 var a = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb) - 1);
15421529 defer a.deinit();
15431530 var b = try Managed.initSet(testing.allocator, maxInt(SignedDoubleLimb));
......@@ -1744,8 +1731,6 @@ test "div q=0 alias" {
17441731}
17451732
17461733test "div multi-multi q < r" {
1747 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1748
17491734 const op1 = 0x1ffffffff0078f432;
17501735 const op2 = 0x1ffffffff01000000;
17511736 var a = try Managed.initSet(testing.allocator, op1);
......@@ -2166,8 +2151,6 @@ test "div ceil multi-limb" {
21662151}
21672152
21682153test "div multi-multi with rem" {
2169 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2170
21712154 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
21722155 defer a.deinit();
21732156 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -2184,8 +2167,6 @@ test "div multi-multi with rem" {
21842167}
21852168
21862169test "div multi-multi no rem" {
2187 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2188
21892170 var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
21902171 defer a.deinit();
21912172 var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
......@@ -2202,8 +2183,6 @@ test "div multi-multi no rem" {
22022183}
22032184
22042185test "div multi-multi (2 branch)" {
2205 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2206
22072186 var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
22082187 defer a.deinit();
22092188 var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
......@@ -2220,8 +2199,6 @@ test "div multi-multi (2 branch)" {
22202199}
22212200
22222201test "div multi-multi (3.1/3.3 branch)" {
2223 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2224
22252202 var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
22262203 defer a.deinit();
22272204 var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
......@@ -2238,8 +2215,6 @@ test "div multi-multi (3.1/3.3 branch)" {
22382215}
22392216
22402217test "div multi-single zero-limb trailing" {
2241 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2242
22432218 var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
22442219 defer a.deinit();
22452220 var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
......@@ -2258,8 +2233,6 @@ test "div multi-single zero-limb trailing" {
22582233}
22592234
22602235test "div multi-multi zero-limb trailing (with rem)" {
2261 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2262
22632236 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
22642237 defer a.deinit();
22652238 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -2279,8 +2252,6 @@ test "div multi-multi zero-limb trailing (with rem)" {
22792252}
22802253
22812254test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
2282 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2283
22842255 var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
22852256 defer a.deinit();
22862257 var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
......@@ -2300,8 +2271,6 @@ test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count
23002271}
23012272
23022273test "div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
2303 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2304
23052274 var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
23062275 defer a.deinit();
23072276 var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
......@@ -2832,10 +2801,6 @@ test "bitNotWrap signed multi" {
28322801}
28332802
28342803test "bitNotWrap more than two limbs" {
2835 // This test requires int sizes greater than 128 bits.
2836 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2837 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2838
28392804 var a = try Managed.initSet(testing.allocator, maxInt(Limb));
28402805 defer a.deinit();
28412806
......@@ -3179,8 +3144,6 @@ test "gcd non-one large" {
31793144}
31803145
31813146test "gcd large multi-limb result" {
3182 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
3183
31843147 var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
31853148 defer a.deinit();
31863149 var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
......@@ -3431,7 +3394,7 @@ test "big int conversion read/write twos complement" {
34313394 var buffer1 = try testing.allocator.alloc(u8, 64);
34323395 defer testing.allocator.free(buffer1);
34333396
3434 const endians = [_]std.builtin.Endian{ .little, .big };
3397 const endians = [_]std.lang.Endian{ .little, .big };
34353398 const abi_size = 64;
34363399
34373400 for (endians) |endian| {
lib/std/math/log10.zig-5
......@@ -1,5 +1,4 @@
11const std = @import("../std.zig");
2const builtin = @import("builtin");
32const testing = std.testing;
43
54/// Returns the base-10 logarithm of x.
......@@ -135,10 +134,6 @@ inline fn less_than_5(x: u32) u32 {
135134}
136135
137136test log10_int {
138 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
141
142137 inline for (
143138 .{ u8, u16, u32, u64, u128, u256, u512 },
144139 .{ 2, 4, 9, 19, 38, 77, 154 },
lib/std/math/signbit.zig+1
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("../std.zig");
23const math = std.math;
34const expect = std.testing.expect;
lib/std/mem.zig+35-53
......@@ -4780,62 +4780,47 @@ pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize {
47804780pub fn doNotOptimizeAway(val: anytype) void {
47814781 if (@inComptime()) return;
47824782
4783 if (builtin.zig_backend == .stage2_c and builtin.abi == .msvc) {
4784 _ = @atomicRmw(*const anyopaque, @as(*volatile *const anyopaque, &struct {
4785 var escape: *const anyopaque = undefined;
4786 }.escape), .Xchg, &val, .acq_rel); // TODO: syncscope("singlethreaded")
4787 return;
4788 }
4789
47834790 const max_gp_register_bits = @bitSizeOf(c_long);
4784 const t = @typeInfo(@TypeOf(val));
4785 switch (t) {
4791 switch (@typeInfo(@TypeOf(val))) {
47864792 .void, .null, .comptime_int, .comptime_float => return,
47874793 .@"enum" => doNotOptimizeAway(@backingInt(val)),
47884794 .bool => doNotOptimizeAway(@intFromBool(val)),
4789 .int => {
4790 const bits = t.int.bits;
4791 if (bits <= max_gp_register_bits and builtin.zig_backend != .stage2_c) {
4792 const val2 = @as(
4793 @Int(t.int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, bits))),
4794 val,
4795 );
4796 asm volatile (""
4797 :
4798 : [_] "r" (val2),
4799 );
4800 } else doNotOptimizeAway(&val);
4801 },
4802 .float => {
4803 if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c) {
4804 asm volatile (""
4805 :
4806 : [_] "rm" (val),
4807 );
4808 } else doNotOptimizeAway(&val);
4809 },
4810 .pointer => {
4811 if (builtin.zig_backend == .stage2_c) {
4812 doNotOptimizeAwayC(val);
4813 } else {
4814 asm volatile (""
4815 :
4816 : [_] "m" (val),
4817 : .{ .memory = true });
4818 }
4819 },
4820 .array => {
4821 if (t.array.len * @sizeOf(t.array.child) <= 64) {
4822 for (val) |v| doNotOptimizeAway(v);
4823 } else doNotOptimizeAway(&val);
4795 .int => |int| if (int.bits <= max_gp_register_bits) {
4796 const val2 = @as(
4797 @Int(int.signedness, @max(8, std.math.ceilPowerOfTwoAssert(u16, int.bits))),
4798 val,
4799 );
4800 asm volatile (""
4801 :
4802 : [_] "r" (val2),
4803 );
4804 } else doNotOptimizeAway(&val),
4805 .float => |float| switch (float.bits) {
4806 else => comptime unreachable,
4807 16, 80, 128 => doNotOptimizeAway(&val),
4808 32, 64 => asm volatile (""
4809 :
4810 : [_] "rm" (val),
4811 ),
48244812 },
4813 .pointer => asm volatile (""
4814 :
4815 : [_] "m" (val),
4816 : .{ .memory = true }),
4817 .array => |array| if (array.len * @sizeOf(array.child) <= 64) {
4818 for (val) |v| doNotOptimizeAway(v);
4819 } else doNotOptimizeAway(&val),
48254820 else => doNotOptimizeAway(&val),
48264821 }
48274822}
48284823
4829/// .stage2_c doesn't support asm blocks yet, so use volatile stores instead
4830var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined;
4831fn doNotOptimizeAwayC(ptr: anytype) void {
4832 const dest = @as(*volatile u8, @ptrCast(&deopt_target));
4833 for (asBytes(ptr)) |b| {
4834 dest.* = b;
4835 }
4836 dest.* = 0;
4837}
4838
48394824test doNotOptimizeAway {
48404825 comptime doNotOptimizeAway("test");
48414826
......@@ -4994,12 +4979,9 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice
49944979}
49954980
49964981test "read/write(Var)PackedInt" {
4997 switch (builtin.cpu.arch) {
4998 // This test generates too much code to execute on WASI.
4999 // LLVM backend fails with "too many locals: locals exceed maximum"
5000 .wasm32, .wasm64 => return error.SkipZigTest,
5001 else => {},
5002 }
4982 // This test generates too much code to execute on WASI.
4983 // LLVM backend fails with "too many locals: locals exceed maximum"
4984 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
50034985
50044986 const foreign_endian: Endian = if (native_endian == .big) .little else .big;
50054987 const expect = std.testing.expect;
lib/std/os/linux/aarch64.zig+1-1
......@@ -154,7 +154,7 @@ pub const restore = restore_rt;
154154pub fn restore_rt() callconv(.naked) noreturn {
155155 switch (builtin.zig_backend) {
156156 .stage2_c => asm volatile (
157 \\ mov x8, %[number]
157 \\ mov w8, %[number]
158158 \\ svc #0
159159 :
160160 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
lib/std/os/linux/s390x.zig+26-10
......@@ -174,19 +174,35 @@ pub fn clone() callconv(.naked) u64 {
174174}
175175
176176pub fn restore() callconv(.naked) noreturn {
177 asm volatile (
178 \\svc 0
179 :
180 : [number] "{r1}" (@backingInt(SYS.sigreturn)),
181 );
177 switch (builtin.zig_backend) {
178 .stage2_c => asm volatile (
179 \\lghi %%r1, %[number]
180 \\svc 0
181 :
182 : [number] "K" (@backingInt(SYS.sigreturn)),
183 ),
184 else => asm volatile (
185 \\svc 0
186 :
187 : [number] "{r1}" (@backingInt(SYS.sigreturn)),
188 ),
189 }
182190}
183191
184192pub fn restore_rt() callconv(.naked) noreturn {
185 asm volatile (
186 \\svc 0
187 :
188 : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)),
189 );
193 switch (builtin.zig_backend) {
194 .stage2_c => asm volatile (
195 \\lghi %%r1, %[number]
196 \\svc 0
197 :
198 : [number] "K" (@backingInt(SYS.rt_sigreturn)),
199 ),
200 else => asm volatile (
201 \\svc 0
202 :
203 : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)),
204 ),
205 }
190206}
191207
192208pub const time_t = i64;
lib/std/testing/Smith.zig+1-1
......@@ -708,7 +708,7 @@ fn constructInput(comptime values: []const union(enum) {
708708}
709709
710710test value {
711 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO
711 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
712712
713713 const S = struct {
714714 v: void = {},
lib/std/zon/parse.zig+1-6
......@@ -9,7 +9,6 @@
99//! For lower level control over parsing, see `std.zig.Zoir`.
1010
1111const std = @import("std");
12const builtin = @import("builtin");
1312const Allocator = std.mem.Allocator;
1413const Ast = std.zig.Ast;
1514const Zoir = std.zig.Zoir;
......@@ -1868,8 +1867,6 @@ test "std.zon tuples" {
18681867
18691868// Test sizes 0 to 3 since small sizes get parsed differently
18701869test "std.zon arrays and slices" {
1871 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20881
1872
18731870 const gpa = std.testing.allocator;
18741871
18751872 // Literals
......@@ -2802,8 +2799,6 @@ test "std.zon negative char" {
28022799}
28032800
28042801test "std.zon parse float" {
2805 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
2806
28072802 const gpa = std.testing.allocator;
28082803
28092804 // Test decimals
......@@ -3135,7 +3130,7 @@ test "std.zon free on error" {
31353130}
31363131
31373132test "std.zon vector" {
3138 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/15330
3133 const builtin = @import("builtin");
31393134 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957
31403135
31413136 const gpa = std.testing.allocator;
lib/std/zon/stringify.zig-3
......@@ -1151,9 +1151,6 @@ test "std.zon depth limits" {
11511151}
11521152
11531153test "std.zon stringify primitives" {
1154 // Issue: https://github.com/ziglang/zig/issues/20880
1155 if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest;
1156
11571154 try expectSerializeEqual(
11581155 \\.{
11591156 \\ .a = 1.5,
lib/zig.h+3076-981
......@@ -166,6 +166,12 @@
166166#endif
167167#define zig_expand_has_builtin(b) zig_has_builtin(b)
168168
169#if defined(__has_feature)
170#define zig_has_feature(feature) __has_feature(feature)
171#else
172#define zig_has_feature(feature) 0
173#endif
174
169175#if defined(__has_attribute)
170176#define zig_has_attribute(attribute) __has_attribute(attribute)
171177#else
......@@ -175,9 +181,9 @@
175181#if __STDC_VERSION__ >= 201112L
176182#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
177183#elif zig_has_attribute(unused)
178#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused))
184#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused))
179185#else
180#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)]
186#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1]
181187#endif
182188
183189#if __STDC_VERSION__ >= 202311L
......@@ -267,12 +273,20 @@
267273
268274#if __STDC_VERSION__ >= 202311L
269275#define zig_align(alignment) alignas(alignment)
270#elif __STDC_VERSION__ >= 201112L
276#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas)
271277#define zig_align(alignment) _Alignas(alignment)
272278#else
273279#define zig_align(alignment) zig_under_align(alignment)
274280#endif
275281
282#if __STDC_VERSION__ >= 202311L
283#define zig_alignOf(Type) alignof(Type)
284#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof)
285#define zig_alignOf(Type) _Alignof(Type)
286#else
287#define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type))
288#endif
289
276290#if zig_has_attribute(aligned) || defined(zig_tinyc)
277291#define zig_align_fn(alignment) __attribute__((aligned(alignment)))
278292#elif defined(zig_msvc)
......@@ -350,11 +364,9 @@
350364#define zig_export(symbol, name) __attribute__((alias(symbol)))
351365#else
352366#define zig_export(symbol, name) ; \
353 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))
367 __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol))
354368#endif
355369
356#define zig_mangled_tentative zig_mangled
357#define zig_mangled_final zig_mangled
358370#if defined(zig_msvc)
359371#define zig_mangled(mangled, unmangled) ; \
360372 zig_export(#mangled, unmangled)
......@@ -364,7 +376,7 @@
364376#else /* zig_msvc */
365377#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))
366378#define zig_mangled_export(mangled, unmangled, symbol) \
367 zig_mangled_final(mangled, unmangled) \
379 zig_mangled(mangled, unmangled) \
368380 zig_export(symbol, unmangled)
369381#endif /* zig_msvc */
370382
......@@ -550,6 +562,9 @@
550562#define zig_noreturn
551563#endif
552564
565#define zig_has_always 1
566#define zig_has_never 0
567
553568#define zig_compiler_rt_abbrev_uint32_t si
554569#define zig_compiler_rt_abbrev_int32_t si
555570#define zig_compiler_rt_abbrev_uint64_t di
......@@ -560,7 +575,11 @@
560575#define zig_compiler_rt_abbrev_zig_f32 sf
561576#define zig_compiler_rt_abbrev_zig_f64 df
562577#define zig_compiler_rt_abbrev_zig_f80 xf
578#ifdef zig_powerpc
579#define zig_compiler_rt_abbrev_zig_f128 kf
580#else
563581#define zig_compiler_rt_abbrev_zig_f128 tf
582#endif
564583
565584zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
566585zig_extern void *memset (void *, int, size_t);
......@@ -645,16 +664,6 @@ typedef signed long long int16_t;
645664#define INT16_MAX ( INT16_C(0x7FFF))
646665#define UINT16_MAX ( INT16_C(0xFFFF))
647666
648#if defined(zig_ez80)
649typedef unsigned int uint24_t;
650typedef signed int int24_t;
651#define INT24_C(c) c
652#define UINT24_C(c) c##U
653#endif
654#define INT24_MIN (~INT24_C(0x7FFF))
655#define INT24_MAX ( INT24_C(0x7FFF))
656#define UINT24_MAX ( INT24_C(0xFFFF))
657
658667#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
659668typedef unsigned char uint32_t;
660669typedef signed char int32_t;
......@@ -685,17 +694,6 @@ typedef signed long long int32_t;
685694#define INT32_MAX ( INT32_C(0x7FFFFFFF))
686695#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
687696
688#if defined(zig_ez80)
689typedef unsigned __int48 uint48_t;
690typedef signed __int48 int48_t;
691#define INT48_C(c) c
692/* no suffix */
693#define UINT48_C(c) ((uint48_t)(c))
694#endif
695#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
696#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
697#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
698
699697#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
700698typedef unsigned char uint64_t;
701699typedef signed char int64_t;
......@@ -726,6 +724,27 @@ typedef signed long long int64_t;
726724#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))
727725#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))
728726
727#if defined(zig_ez80)
728
729typedef unsigned int uint24_t;
730typedef signed int int24_t;
731#define INT24_C(c) c
732#define UINT24_C(c) c##U
733#define INT24_MIN (~INT24_C(0x7FFF))
734#define INT24_MAX ( INT24_C(0x7FFF))
735#define UINT24_MAX ( INT24_C(0xFFFF))
736
737typedef unsigned __int48 uint48_t;
738typedef signed __int48 int48_t;
739#define INT48_C(c) c
740/* no suffix */
741#define UINT48_C(c) ((uint48_t)(c))
742#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
743#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
744#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
745
746#endif
747
729748typedef size_t uintptr_t;
730749typedef ptrdiff_t intptr_t;
731750
......@@ -739,23 +758,145 @@ typedef ptrdiff_t intptr_t;
739758#define zig_maxInt_i16 INT16_MAX
740759#define zig_minInt_u16 UINT16_C(0)
741760#define zig_maxInt_u16 UINT16_MAX
742#define zig_minInt_i24 INT24_MIN
743#define zig_maxInt_i24 INT24_MAX
744#define zig_minInt_u24 UINT24_C(0)
745#define zig_maxInt_u24 UINT24_MAX
746761#define zig_minInt_i32 INT32_MIN
747762#define zig_maxInt_i32 INT32_MAX
748763#define zig_minInt_u32 UINT32_C(0)
749764#define zig_maxInt_u32 UINT32_MAX
750#define zig_minInt_i48 INT48_MIN
751#define zig_maxInt_i48 INT48_MAX
752#define zig_minInt_u48 UINT48_C(0)
753#define zig_maxInt_u48 UINT48_MAX
754765#define zig_minInt_i64 INT64_MIN
755766#define zig_maxInt_i64 INT64_MAX
756767#define zig_minInt_u64 UINT64_C(0)
757768#define zig_maxInt_u64 UINT64_MAX
758769
770// zig_promoted_T implements C integral promotions except with signedness preserved, which
771// allows wrapping operations to avoid the ub that would be caused by the normal promotion.
772
773#if INT8_MAX <= INT_MAX
774typedef unsigned int zig_promoted_i8;
775#elif INT8_MAX <= LONG_MAX
776typedef unsigned long zig_promoted_i8;
777#elif INT8_MAX <= LLONG_MAX
778typedef unsigned long long zig_promoted_i8;
779#else
780typedef int8_t zig_promoted_i8;
781#endif
782#if UINT8_MAX <= UINT_MAX
783typedef unsigned int zig_promoted_u8;
784#elif UINT8_MAX <= ULONG_MAX
785typedef unsigned long zig_promoted_u8;
786#elif UINT8_MAX <= ULLONG_MAX
787typedef unsigned long long zig_promoted_u8;
788#else
789typedef uint8_t zig_promoted_u8;
790#endif
791
792#if INT16_MAX <= INT_MAX
793typedef unsigned int zig_promoted_i16;
794#elif INT16_MAX <= LONG_MAX
795typedef unsigned long zig_promoted_i16;
796#elif INT16_MAX <= LLONG_MAX
797typedef unsigned long long zig_promoted_i16;
798#else
799typedef int16_t zig_promoted_i16;
800#endif
801#if UINT16_MAX <= UINT_MAX
802typedef unsigned int zig_promoted_u16;
803#elif UINT16_MAX <= ULONG_MAX
804typedef unsigned long zig_promoted_u16;
805#elif UINT16_MAX <= ULLONG_MAX
806typedef unsigned long long zig_promoted_u16;
807#else
808typedef uint16_t zig_promoted_u16;
809#endif
810
811#if INT32_MAX <= INT_MAX
812typedef unsigned int zig_promoted_i32;
813#elif INT32_MAX <= LONG_MAX
814typedef unsigned long zig_promoted_i32;
815#elif INT32_MAX <= LLONG_MAX
816typedef unsigned long long zig_promoted_i32;
817#else
818typedef int32_t zig_promoted_i32;
819#endif
820#if UINT32_MAX <= UINT_MAX
821typedef unsigned int zig_promoted_u32;
822#elif UINT32_MAX <= ULONG_MAX
823typedef unsigned long zig_promoted_u32;
824#elif UINT32_MAX <= ULLONG_MAX
825typedef unsigned long long zig_promoted_u32;
826#else
827typedef uint32_t zig_promoted_u32;
828#endif
829
830#if INT64_MAX <= INT_MAX
831typedef unsigned int zig_promoted_i64;
832#elif INT64_MAX <= LONG_MAX
833typedef unsigned long zig_promoted_i64;
834#elif INT64_MAX <= LLONG_MAX
835typedef unsigned long long zig_promoted_i64;
836#else
837typedef int64_t zig_promoted_i64;
838#endif
839#if UINT64_MAX <= UINT_MAX
840typedef unsigned int zig_promoted_u64;
841#elif UINT64_MAX <= ULONG_MAX
842typedef unsigned long zig_promoted_u64;
843#elif UINT64_MAX <= ULLONG_MAX
844typedef unsigned long long zig_promoted_u64;
845#else
846typedef uint64_t zig_promoted_u64;
847#endif
848
849#ifdef zig_ez80
850
851#define zig_minInt_i24 INT24_MIN
852#define zig_maxInt_i24 INT24_MAX
853#define zig_minInt_u24 UINT24_C(0)
854#define zig_maxInt_u24 UINT24_MAX
855#define zig_minInt_i48 INT48_MIN
856#define zig_maxInt_i48 INT48_MAX
857#define zig_minInt_u48 UINT48_C(0)
858#define zig_maxInt_u48 UINT48_MAX
859
860#if INT24_MAX <= INT_MAX
861typedef unsigned int zig_promoted_i24;
862#elif INT24_MAX <= LONG_MAX
863typedef unsigned long zig_promoted_i24;
864#elif INT24_MAX <= LLONG_MAX
865typedef unsigned long long zig_promoted_i24;
866#else
867typedef int24_t zig_promoted_i24;
868#endif
869#if UINT24_MAX <= UINT_MAX
870typedef unsigned int zig_promoted_u24;
871#elif UINT24_MAX <= ULONG_MAX
872typedef unsigned long zig_promoted_u24;
873#elif UINT24_MAX <= ULLONG_MAX
874typedef unsigned long long zig_promoted_u24;
875#else
876typedef uint24_t zig_promoted_u24;
877#endif
878
879#if INT48_MAX <= INT_MAX
880typedef unsigned int zig_promoted_i48;
881#elif INT48_MAX <= LONG_MAX
882typedef unsigned long zig_promoted_i48;
883#elif INT48_MAX <= LLONG_MAX
884typedef unsigned long long zig_promoted_i48;
885#else
886typedef int48_t zig_promoted_i48;
887#endif
888#if UINT48_MAX <= UINT_MAX
889typedef unsigned int zig_promoted_u48;
890#elif UINT48_MAX <= ULONG_MAX
891typedef unsigned long zig_promoted_u48;
892#elif UINT48_MAX <= ULLONG_MAX
893typedef unsigned long long zig_promoted_u48;
894#else
895typedef uint48_t zig_promoted_u48;
896#endif
897
898#endif
899
759900#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))
760901#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)
761902#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)
......@@ -770,7 +911,33 @@ typedef ptrdiff_t intptr_t;
770911 zig_operator(Type, Type, operation, operator)
771912#define zig_shift_operator(Type, operation, operator) \
772913 zig_operator(Type, uint8_t, operation, operator)
773#define zig_int_helpers(w, PromotedUnsigned) \
914
915#define zig_int_casts_common(bw, sw) \
916 static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \
917 return arg; \
918 } \
919\
920 static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \
921 return (uint##bw##_t)arg; \
922 } \
923\
924 static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \
925 return arg; \
926 } \
927\
928 static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \
929 return arg; \
930 } \
931\
932 static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \
933 return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \
934 } \
935\
936 static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \
937 return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \
938 ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \
939 }
940#define zig_int_operators(w) \
774941 zig_basic_operator(uint##w##_t, and_u##w, &) \
775942 zig_basic_operator( int##w##_t, and_i##w, &) \
776943 zig_basic_operator(uint##w##_t, or_u##w, |) \
......@@ -786,44 +953,48 @@ typedef ptrdiff_t intptr_t;
786953 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
787954 } \
788955\
789 static inline uint##w##_t zig_not_u##w(uint##w##_t val, uint8_t bits) { \
790 return val ^ zig_maxInt_u(w, bits); \
956 static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \
957 return arg ^ zig_maxInt_u(w, bits); \
791958 } \
792959\
793 static inline int##w##_t zig_not_i##w(int##w##_t val, uint8_t bits) { \
960 static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \
794961 (void)bits; \
795 return ~val; \
962 return ~arg; \
796963 } \
797964\
798 static inline uint##w##_t zig_wrap_u##w(uint##w##_t val, uint8_t bits) { \
799 return val & zig_maxInt_u(w, bits); \
965 zig_basic_operator(uint##w##_t, divFloor_u##w, /) \
966\
967 static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \
968 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
800969 } \
801970\
802 static inline int##w##_t zig_wrap_i##w(int##w##_t val, uint8_t bits) { \
803 return (val & UINT##w##_C(1) << (bits - UINT8_C(1))) != 0 \
804 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
971 static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
972 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \
805973 } \
806974\
807 static inline uint##w##_t zig_abs_i##w(int##w##_t val) { \
808 return (val < 0) ? -(uint##w##_t)val : (uint##w##_t)val; \
975 static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \
976 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \
977 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
809978 } \
810979\
811 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \
980 zig_basic_operator(uint##w##_t, mod_u##w, %) \
981 zig_int_casts_common(w, w) \
812982\
813 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \
814 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
983 static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
984 return zig_u##w##_truncate_u##w(arg, bits); \
815985 } \
816986\
817 static inline uint##w##_t zig_div_ceil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
818 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \
987 static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
988 return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \
819989 } \
820990\
821 static inline int##w##_t zig_div_ceil_i##w(int##w##_t lhs, int##w##_t rhs) { \
822 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \
823 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
991 static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
992 return zig_i##w##_truncate_i##w(arg, bits); \
824993 } \
825994\
826 zig_basic_operator(uint##w##_t, mod_u##w, %) \
995 static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
996 return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \
997 } \
827998\
828999 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
8291000 int##w##_t rem = lhs % rhs; \
......@@ -831,100 +1002,102 @@ typedef ptrdiff_t intptr_t;
8311002 } \
8321003\
8331004 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
834 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \
1005 return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \
8351006 } \
8361007\
8371008 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \
838 return zig_wrap_i##w((int##w##_t)zig_shl_u##w((uint##w##_t)lhs, rhs), bits); \
1009 return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \
8391010 } \
8401011\
8411012 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
842 return zig_wrap_u##w(lhs + rhs, bits); \
1013 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \
8431014 } \
8441015\
8451016 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
846 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs + (uint##w##_t)rhs), bits); \
1017 return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
8471018 } \
8481019\
8491020 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
850 return zig_wrap_u##w(lhs - rhs, bits); \
1021 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \
8511022 } \
8521023\
8531024 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
854 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs - (uint##w##_t)rhs), bits); \
1025 return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
8551026 } \
8561027\
8571028 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
858 return zig_wrap_u##w((PromotedUnsigned)lhs * rhs, bits); \
1029 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \
8591030 } \
8601031\
8611032 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
862 return zig_wrap_i##w((int##w##_t)((uint##w##_t)lhs * (uint##w##_t)rhs), bits); \
1033 return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1034 } \
1035\
1036 static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \
1037 int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \
1038 return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \
1039 } \
1040\
1041 static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1042 return lhs < rhs ? lhs : rhs; \
1043 } \
1044\
1045 static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \
1046 return lhs < rhs ? lhs : rhs; \
1047 } \
1048\
1049 static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1050 return lhs >= rhs ? lhs : rhs; \
1051 } \
1052\
1053 static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \
1054 return lhs >= rhs ? lhs : rhs; \
8631055 }
864#if UINT8_MAX <= UINT_MAX
865zig_int_helpers(8, unsigned int)
866#elif UINT8_MAX <= ULONG_MAX
867zig_int_helpers(8, unsigned long)
868#elif UINT8_MAX <= ULLONG_MAX
869zig_int_helpers(8, unsigned long long)
870#else
871zig_int_helpers(8, uint8_t)
872#endif
873#if UINT16_MAX <= UINT_MAX
874zig_int_helpers(16, unsigned int)
875#elif UINT16_MAX <= ULONG_MAX
876zig_int_helpers(16, unsigned long)
877#elif UINT16_MAX <= ULLONG_MAX
878zig_int_helpers(16, unsigned long long)
879#else
880zig_int_helpers(16, uint16_t)
881#endif
882#if defined(zig_ez80)
883#if UINT24_MAX <= UINT_MAX
884zig_int_helpers(24, unsigned int)
885#elif UINT24_MAX <= ULONG_MAX
886zig_int_helpers(24, unsigned long)
887#elif UINT24_MAX <= ULLONG_MAX
888zig_int_helpers(24, unsigned long long)
889#else
890zig_int_helpers(24, uint24_t)
891#endif
892#endif
893#if UINT32_MAX <= UINT_MAX
894zig_int_helpers(32, unsigned int)
895#elif UINT32_MAX <= ULONG_MAX
896zig_int_helpers(32, unsigned long)
897#elif UINT32_MAX <= ULLONG_MAX
898zig_int_helpers(32, unsigned long long)
899#else
900zig_int_helpers(32, uint32_t)
901#endif
902#if defined(zig_ez80)
903#if UINT24_MAX <= UINT_MAX
904zig_int_helpers(48, unsigned int)
905#elif UINT24_MAX <= ULONG_MAX
906zig_int_helpers(48, unsigned long)
907#elif UINT24_MAX <= ULLONG_MAX
908zig_int_helpers(48, unsigned long long)
909#else
910zig_int_helpers(48, uint48_t)
911#endif
912#endif
913#if UINT64_MAX <= UINT_MAX
914zig_int_helpers(64, unsigned int)
915#elif UINT64_MAX <= ULONG_MAX
916zig_int_helpers(64, unsigned long)
917#elif UINT64_MAX <= ULLONG_MAX
918zig_int_helpers(64, unsigned long long)
919#else
920zig_int_helpers(64, uint64_t)
1056zig_int_operators(8)
1057zig_int_operators(16)
1058zig_int_operators(32)
1059zig_int_operators(64)
1060#ifdef zig_ez80
1061zig_int_operators(24)
1062zig_int_operators(48)
1063#endif
1064
1065#define zig_int_casts(bw, sw) \
1066 static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \
1067 return (uint##sw##_t)arg; \
1068 } \
1069\
1070 static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \
1071 return (uint##sw##_t)arg; \
1072 } \
1073\
1074 static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \
1075 return (int##sw##_t)arg; \
1076 } \
1077\
1078 static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \
1079 return (int##sw##_t)arg; \
1080 } \
1081\
1082 zig_int_casts_common(bw, sw)
1083zig_int_casts(16, 8)
1084zig_int_casts(32, 8)
1085zig_int_casts(64, 8)
1086zig_int_casts(32, 16)
1087zig_int_casts(64, 16)
1088zig_int_casts(64, 32)
1089#ifdef zig_ez80
1090zig_int_casts(32, 24)
1091zig_int_casts(48, 24)
1092zig_int_casts(64, 24)
1093zig_int_casts(64, 48)
9211094#endif
9221095
9231096static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
9241097#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9251098 uint32_t full_res;
9261099 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
927 *res = zig_wrap_u32(full_res, bits);
1100 *res = zig_u32_truncate_u32(full_res, bits);
9281101 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
9291102#else
9301103 *res = zig_addw_u32(lhs, rhs, bits);
......@@ -936,19 +1109,19 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
9361109#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9371110 int32_t full_res;
9381111 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1112 *res = zig_i32_truncate_i32(full_res, bits);
1113 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
9391114#else
940 int32_t full_res = (int32_t)((uint32_t)lhs + (uint32_t)rhs);
941 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
1115 *res = zig_addw_i32(lhs, rhs, bits);
1116 return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0);
9421117#endif
943 *res = zig_wrap_i32(full_res, bits);
944 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
9451118}
9461119
9471120static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
9481121#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9491122 uint64_t full_res;
9501123 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
951 *res = zig_wrap_u64(full_res, bits);
1124 *res = zig_u64_truncate_u64(full_res, bits);
9521125 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
9531126#else
9541127 *res = zig_addw_u64(lhs, rhs, bits);
......@@ -960,24 +1133,24 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
9601133#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9611134 int64_t full_res;
9621135 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1136 *res = zig_i64_truncate_i64(full_res, bits);
1137 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
9631138#else
964 int64_t full_res = (int64_t)((uint64_t)lhs + (uint64_t)rhs);
965 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
1139 *res = zig_addw_i64(lhs, rhs, bits);
1140 return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0);
9661141#endif
967 *res = zig_wrap_i64(full_res, bits);
968 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
9691142}
9701143
9711144static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
9721145#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9731146 uint8_t full_res;
9741147 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
975 *res = zig_wrap_u8(full_res, bits);
1148 *res = zig_u8_truncate_u8(full_res, bits);
9761149 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
9771150#else
9781151 uint32_t full_res;
9791152 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
980 *res = (uint8_t)full_res;
1153 *res = zig_u8_intCast_u32(full_res);
9811154 return overflow;
9821155#endif
9831156}
......@@ -986,12 +1159,12 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
9861159#if zig_has_builtin(add_overflow) || defined(zig_gcc)
9871160 int8_t full_res;
9881161 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
989 *res = zig_wrap_i8(full_res, bits);
1162 *res = zig_i8_truncate_i8(full_res, bits);
9901163 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
9911164#else
9921165 int32_t full_res;
9931166 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
994 *res = (int8_t)full_res;
1167 *res = zig_i8_intCast_i32(full_res);
9951168 return overflow;
9961169#endif
9971170}
......@@ -1000,12 +1173,12 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
10001173#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10011174 uint16_t full_res;
10021175 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1003 *res = zig_wrap_u16(full_res, bits);
1176 *res = zig_u16_truncate_u16(full_res, bits);
10041177 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
10051178#else
10061179 uint32_t full_res;
10071180 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1008 *res = (uint16_t)full_res;
1181 *res = zig_u16_intCast_u32(full_res);
10091182 return overflow;
10101183#endif
10111184}
......@@ -1014,27 +1187,28 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
10141187#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10151188 int16_t full_res;
10161189 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1017 *res = zig_wrap_i16(full_res, bits);
1190 *res = zig_i16_truncate_i16(full_res, bits);
10181191 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
10191192#else
10201193 int32_t full_res;
10211194 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1022 *res = (int16_t)full_res;
1195 *res = zig_i16_intCast_i32(full_res);
10231196 return overflow;
10241197#endif
10251198}
10261199
10271200#if defined(zig_ez80)
1201
10281202static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
10291203#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10301204 uint24_t full_res;
10311205 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1032 *res = zig_wrap_u24(full_res, bits);
1206 *res = zig_u24_truncate_u24(full_res, bits);
10331207 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
10341208#else
10351209 uint32_t full_res;
10361210 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1037 *res = (uint24_t)full_res;
1211 *res = zig_u24_intCast_u32(full_res);
10381212 return overflow;
10391213#endif
10401214}
......@@ -1043,28 +1217,26 @@ static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
10431217#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10441218 int24_t full_res;
10451219 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1046 *res = zig_wrap_i24(full_res, bits);
1220 *res = zig_i24_truncate_i24(full_res, bits);
10471221 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
10481222#else
10491223 int32_t full_res;
10501224 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1051 *res = (int24_t)full_res;
1225 *res = zig_i24_intCast_i32(full_res);
10521226 return overflow;
10531227#endif
10541228}
1055#endif
10561229
1057#if defined(zig_ez80)
10581230static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
10591231#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10601232 uint48_t full_res;
10611233 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1062 *res = zig_wrap_u48(full_res, bits);
1234 *res = zig_u48_truncate_u48(full_res, bits);
10631235 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
10641236#else
10651237 uint64_t full_res;
10661238 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
1067 *res = (uint48_t)full_res;
1239 *res = zig_u48_intCast_u64(full_res);
10681240 return overflow;
10691241#endif
10701242}
......@@ -1073,22 +1245,23 @@ static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
10731245#if zig_has_builtin(add_overflow) || defined(zig_gcc)
10741246 int48_t full_res;
10751247 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1076 *res = zig_wrap_i48(full_res, bits);
1248 *res = zig_i48_truncate_i48(full_res, bits);
10771249 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
10781250#else
10791251 int64_t full_res;
10801252 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
1081 *res = (int48_t)full_res;
1253 *res = zig_i48_intCast_i64(full_res);
10821254 return overflow;
10831255#endif
10841256}
1257
10851258#endif
10861259
10871260static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
10881261#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
10891262 uint32_t full_res;
10901263 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1091 *res = zig_wrap_u32(full_res, bits);
1264 *res = zig_u32_truncate_u32(full_res, bits);
10921265 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
10931266#else
10941267 *res = zig_subw_u32(lhs, rhs, bits);
......@@ -1100,20 +1273,19 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
11001273#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11011274 int32_t full_res;
11021275 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1276 *res = zig_i32_truncate_i32(full_res, bits);
1277 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
11031278#else
1104 int32_t full_res = (int32_t)((uint32_t)lhs - (uint32_t)rhs);
1105 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
1279 *res = zig_subw_i32(lhs, rhs, bits);
1280 return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0);
11061281#endif
1107 *res = zig_wrap_i32(full_res, bits);
1108 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
11091282}
11101283
1111
11121284static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
11131285#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11141286 uint64_t full_res;
11151287 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1116 *res = zig_wrap_u64(full_res, bits);
1288 *res = zig_u64_truncate_u64(full_res, bits);
11171289 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
11181290#else
11191291 *res = zig_subw_u64(lhs, rhs, bits);
......@@ -1125,24 +1297,24 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
11251297#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11261298 int64_t full_res;
11271299 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1300 *res = zig_i64_truncate_i64(full_res, bits);
1301 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
11281302#else
1129 int64_t full_res = (int64_t)((uint64_t)lhs - (uint64_t)rhs);
1130 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
1303 *res = zig_subw_i64(lhs, rhs, bits);
1304 return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0);
11311305#endif
1132 *res = zig_wrap_i64(full_res, bits);
1133 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
11341306}
11351307
11361308static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
11371309#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11381310 uint8_t full_res;
11391311 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1140 *res = zig_wrap_u8(full_res, bits);
1312 *res = zig_u8_truncate_u8(full_res, bits);
11411313 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
11421314#else
11431315 uint32_t full_res;
11441316 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1145 *res = (uint8_t)full_res;
1317 *res = zig_u8_intCast_u32(full_res);
11461318 return overflow;
11471319#endif
11481320}
......@@ -1151,12 +1323,12 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
11511323#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11521324 int8_t full_res;
11531325 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1154 *res = zig_wrap_i8(full_res, bits);
1326 *res = zig_i8_truncate_i8(full_res, bits);
11551327 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
11561328#else
11571329 int32_t full_res;
11581330 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1159 *res = (int8_t)full_res;
1331 *res = zig_i8_intCast_i32(full_res);
11601332 return overflow;
11611333#endif
11621334}
......@@ -1165,12 +1337,12 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
11651337#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11661338 uint16_t full_res;
11671339 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1168 *res = zig_wrap_u16(full_res, bits);
1340 *res = zig_u16_truncate_u16(full_res, bits);
11691341 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
11701342#else
11711343 uint32_t full_res;
11721344 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1173 *res = (uint16_t)full_res;
1345 *res = zig_u16_intCast_u32(full_res);
11741346 return overflow;
11751347#endif
11761348}
......@@ -1179,27 +1351,28 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
11791351#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11801352 int16_t full_res;
11811353 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1182 *res = zig_wrap_i16(full_res, bits);
1354 *res = zig_i16_truncate_i16(full_res, bits);
11831355 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
11841356#else
11851357 int32_t full_res;
11861358 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1187 *res = (int16_t)full_res;
1359 *res = zig_i16_intCast_i32(full_res);
11881360 return overflow;
11891361#endif
11901362}
11911363
11921364#if defined(zig_ez80)
1365
11931366static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
11941367#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
11951368 uint24_t full_res;
11961369 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1197 *res = zig_wrap_u24(full_res, bits);
1370 *res = zig_u24_truncate_u24(full_res, bits);
11981371 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
11991372#else
12001373 uint32_t full_res;
12011374 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1202 *res = (uint24_t)full_res;
1375 *res = zig_u24_intCast_u32(full_res);
12031376 return overflow;
12041377#endif
12051378}
......@@ -1208,28 +1381,26 @@ static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
12081381#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
12091382 int24_t full_res;
12101383 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1211 *res = zig_wrap_i24(full_res, bits);
1384 *res = zig_i24_truncate_i24(full_res, bits);
12121385 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
12131386#else
12141387 int32_t full_res;
12151388 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1216 *res = (int24_t)full_res;
1389 *res = zig_i24_intCast_i32(full_res);
12171390 return overflow;
12181391#endif
12191392}
1220#endif
12211393
1222#if defined(zig_ez80)
12231394static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
12241395#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
12251396 uint48_t full_res;
12261397 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1227 *res = zig_wrap_u48(full_res, bits);
1398 *res = zig_u48_truncate_u48(full_res, bits);
12281399 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
12291400#else
12301401 uint64_t full_res;
12311402 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
1232 *res = (uint48_t)full_res;
1403 *res = zig_u48_intCast_u64(full_res);
12331404 return overflow;
12341405#endif
12351406}
......@@ -1238,22 +1409,23 @@ static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
12381409#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
12391410 int48_t full_res;
12401411 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1241 *res = zig_wrap_i48(full_res, bits);
1412 *res = zig_i48_truncate_i48(full_res, bits);
12421413 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
12431414#else
12441415 int64_t full_res;
12451416 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
1246 *res = (int48_t)full_res;
1417 *res = zig_i48_intCast_i64(full_res);
12471418 return overflow;
12481419#endif
12491420}
1421
12501422#endif
12511423
12521424static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
12531425#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
12541426 uint32_t full_res;
12551427 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1256 *res = zig_wrap_u32(full_res, bits);
1428 *res = zig_u32_truncate_u32(full_res, bits);
12571429 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
12581430#else
12591431 *res = zig_mulw_u32(lhs, rhs, bits);
......@@ -1261,8 +1433,8 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8
12611433#endif
12621434}
12631435
1264zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
12651436static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1437 zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
12661438#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
12671439 int32_t full_res;
12681440 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
......@@ -1271,7 +1443,7 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
12711443 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);
12721444 bool overflow = overflow_int != 0;
12731445#endif
1274 *res = zig_wrap_i32(full_res, bits);
1446 *res = zig_i32_truncate_i32(full_res, bits);
12751447 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
12761448}
12771449
......@@ -1279,7 +1451,7 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
12791451#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
12801452 uint64_t full_res;
12811453 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1282 *res = zig_wrap_u64(full_res, bits);
1454 *res = zig_u64_truncate_u64(full_res, bits);
12831455 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
12841456#else
12851457 *res = zig_mulw_u64(lhs, rhs, bits);
......@@ -1287,8 +1459,8 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8
12871459#endif
12881460}
12891461
1290zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
12911462static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1463 zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
12921464#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
12931465 int64_t full_res;
12941466 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
......@@ -1297,7 +1469,7 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t
12971469 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);
12981470 bool overflow = overflow_int != 0;
12991471#endif
1300 *res = zig_wrap_i64(full_res, bits);
1472 *res = zig_i64_truncate_i64(full_res, bits);
13011473 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
13021474}
13031475
......@@ -1305,12 +1477,12 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b
13051477#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13061478 uint8_t full_res;
13071479 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1308 *res = zig_wrap_u8(full_res, bits);
1480 *res = zig_u8_truncate_u8(full_res, bits);
13091481 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
13101482#else
13111483 uint32_t full_res;
13121484 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1313 *res = (uint8_t)full_res;
1485 *res = zig_u8_intCast_u32(full_res);
13141486 return overflow;
13151487#endif
13161488}
......@@ -1319,12 +1491,12 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits
13191491#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13201492 int8_t full_res;
13211493 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1322 *res = zig_wrap_i8(full_res, bits);
1494 *res = zig_i8_truncate_i8(full_res, bits);
13231495 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
13241496#else
13251497 int32_t full_res;
13261498 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1327 *res = (int8_t)full_res;
1499 *res = zig_i8_intCast_i32(full_res);
13281500 return overflow;
13291501#endif
13301502}
......@@ -1333,12 +1505,12 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8
13331505#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13341506 uint16_t full_res;
13351507 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1336 *res = zig_wrap_u16(full_res, bits);
1508 *res = zig_u16_truncate_u16(full_res, bits);
13371509 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
13381510#else
13391511 uint32_t full_res;
13401512 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1341 *res = (uint16_t)full_res;
1513 *res = zig_u16_intCast_u32(full_res);
13421514 return overflow;
13431515#endif
13441516}
......@@ -1347,27 +1519,28 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
13471519#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13481520 int16_t full_res;
13491521 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1350 *res = zig_wrap_i16(full_res, bits);
1522 *res = zig_i16_truncate_i16(full_res, bits);
13511523 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
13521524#else
13531525 int32_t full_res;
13541526 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1355 *res = (int16_t)full_res;
1527 *res = zig_i16_intCast_i32(full_res);
13561528 return overflow;
13571529#endif
13581530}
13591531
13601532#if defined(zig_ez80)
1533
13611534static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
13621535#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13631536 uint24_t full_res;
13641537 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1365 *res = zig_wrap_u24(full_res, bits);
1538 *res = zig_u24_truncate_u24(full_res, bits);
13661539 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
13671540#else
13681541 uint32_t full_res;
13691542 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1370 *res = (uint24_t)full_res;
1543 *res = zig_u24_intCast_u32(full_res);
13711544 return overflow;
13721545#endif
13731546}
......@@ -1376,28 +1549,26 @@ static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t
13761549#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13771550 int24_t full_res;
13781551 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1379 *res = zig_wrap_i24(full_res, bits);
1552 *res = zig_i24_truncate_i24(full_res, bits);
13801553 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
13811554#else
13821555 int32_t full_res;
13831556 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1384 *res = (int24_t)full_res;
1557 *res = zig_i24_intCast_i32(full_res);
13851558 return overflow;
13861559#endif
13871560}
1388#endif
13891561
1390#if defined(zig_ez80)
13911562static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
13921563#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
13931564 uint48_t full_res;
13941565 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1395 *res = zig_wrap_u48(full_res, bits);
1566 *res = zig_u48_truncate_u48(full_res, bits);
13961567 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
13971568#else
13981569 uint64_t full_res;
13991570 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
1400 *res = (uint48_t)full_res;
1571 *res = zig_u48_intCast_u64(full_res);
14011572 return overflow;
14021573#endif
14031574}
......@@ -1406,18 +1577,32 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
14061577#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
14071578 int48_t full_res;
14081579 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1409 *res = zig_wrap_i48(full_res, bits);
1580 *res = zig_i48_truncate_i48(full_res, bits);
14101581 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
14111582#else
14121583 int64_t full_res;
14131584 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
1414 *res = (int48_t)full_res;
1585 *res = zig_i48_intCast_i64(full_res);
14151586 return overflow;
14161587#endif
14171588}
1589
14181590#endif
14191591
1420#define zig_int_builtins(w) \
1592#define zig_shls_builtins(lw, rw) \
1593 static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1594 uint##lw##_t res; \
1595 if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1596 return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \
1597 } \
1598\
1599 static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1600 int##lw##_t res; \
1601 if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1602 return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \
1603 lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \
1604 }
1605#define zig_int_sat_builtins(w) \
14211606 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
14221607 *res = zig_shlw_u##w(lhs, rhs, bits); \
14231608 return lhs > zig_maxInt_u(w, bits) >> rhs; \
......@@ -1429,18 +1614,10 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
14291614 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \
14301615 } \
14311616\
1432 static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1433 uint##w##_t res; \
1434 if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \
1435 return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \
1436 } \
1437\
1438 static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1439 int##w##_t res; \
1440 if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
1441 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
1442 lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1443 } \
1617 zig_shls_builtins(w, 8) \
1618 zig_shls_builtins(w, 16) \
1619 zig_shls_builtins(w, 32) \
1620 zig_shls_builtins(w, 64) \
14441621\
14451622 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
14461623 uint##w##_t res; \
......@@ -1474,332 +1651,321 @@ static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t
14741651 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \
14751652 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
14761653 }
1477zig_int_builtins(8)
1478zig_int_builtins(16)
1479#if defined(zig_ez80)
1480zig_int_builtins(24)
1481#endif
1482zig_int_builtins(32)
1654zig_int_sat_builtins(8)
1655zig_int_sat_builtins(16)
1656zig_int_sat_builtins(32)
1657zig_int_sat_builtins(64)
14831658#if defined(zig_ez80)
1484zig_int_builtins(48)
1659zig_int_sat_builtins(24)
1660zig_int_sat_builtins(48)
14851661#endif
1486zig_int_builtins(64)
14871662
1488#define zig_builtin8(name, val) __builtin_##name(val)
1663#define zig_builtin8(name, arg) __builtin_##name(arg)
14891664typedef unsigned int zig_Builtin8;
14901665
1491#define zig_builtin16(name, val) __builtin_##name(val)
1666#define zig_builtin16(name, arg) __builtin_##name(arg)
14921667typedef unsigned int zig_Builtin16;
14931668
1494#if defined(zig_ez80)
1495#define zig_builtin24(name, val) __builtin_##name(val)
1496typedef unsigned int zig_Builtin24;
1497#endif
1498
14991669#if INT_MIN <= INT32_MIN
1500#define zig_builtin32(name, val) __builtin_##name(val)
1670#define zig_builtin32(name, arg) __builtin_##name(arg)
15011671typedef unsigned int zig_Builtin32;
15021672#elif LONG_MIN <= INT32_MIN
1503#define zig_builtin32(name, val) __builtin_##name##l(val)
1673#define zig_builtin32(name, arg) __builtin_##name##l(arg)
15041674typedef unsigned long zig_Builtin32;
15051675#endif
15061676
1507#if defined(zig_ez80)
1508#define zig_builtin48(name, val) __builtin_##name(val)
1509typedef unsigned long long zig_Builtin48;
1510#endif
1511
15121677#if INT_MIN <= INT64_MIN
1513#define zig_builtin64(name, val) __builtin_##name(val)
1678#define zig_builtin64(name, arg) __builtin_##name(arg)
15141679typedef unsigned int zig_Builtin64;
15151680#elif LONG_MIN <= INT64_MIN
1516#define zig_builtin64(name, val) __builtin_##name##l(val)
1681#define zig_builtin64(name, arg) __builtin_##name##l(arg)
15171682typedef unsigned long zig_Builtin64;
15181683#elif LLONG_MIN <= INT64_MIN
1519#define zig_builtin64(name, val) __builtin_##name##ll(val)
1684#define zig_builtin64(name, arg) __builtin_##name##ll(arg)
15201685typedef unsigned long long zig_Builtin64;
15211686#endif
15221687
1523static inline uint8_t zig_byte_swap_u8(uint8_t val, uint8_t bits) {
1524 return zig_wrap_u8(val >> (8 - bits), bits);
1688#if defined(zig_ez80)
1689#define zig_builtin24(name, arg) __builtin_##name(arg)
1690typedef unsigned int zig_Builtin24;
1691#define zig_builtin48(name, arg) __builtin_##name(arg)
1692typedef unsigned long long zig_Builtin48;
1693#endif
1694
1695static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) {
1696 return zig_u8_truncate_u8(arg >> (8 - bits), bits);
15251697}
15261698
1527static inline int8_t zig_byte_swap_i8(int8_t val, uint8_t bits) {
1528 return zig_wrap_i8((int8_t)zig_byte_swap_u8((uint8_t)val, bits), bits);
1699static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) {
1700 return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits);
15291701}
15301702
1531static inline uint16_t zig_byte_swap_u16(uint16_t val, uint8_t bits) {
1703static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) {
15321704 uint16_t full_res;
15331705#if zig_has_builtin(bswap16) || defined(zig_gcc)
1534 full_res = __builtin_bswap16(val);
1706 full_res = __builtin_bswap16(arg);
15351707#else
1536 full_res = (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 8 |
1537 (uint16_t)zig_byte_swap_u8((uint8_t)(val >> 8), 8) >> 0;
1708 full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 |
1709 (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0;
15381710#endif
1539 return zig_wrap_u16(full_res >> (16 - bits), bits);
1711 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
15401712}
15411713
1542static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {
1543 return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits);
1714static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) {
1715 return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits);
15441716}
15451717
15461718#if defined(zig_ez80)
1547static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) {
1719static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) {
15481720 uint24_t full_res;
15491721#if zig_has_builtin(bswap24) || defined(zig_gcc)
1550 full_res = __builtin_bswap24(val);
1722 full_res = __builtin_bswap24(arg);
15511723#else
1552 full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 |
1553 (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0;
1724 full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 |
1725 (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0;
15541726#endif
1555 return zig_wrap_u24(full_res >> (24 - bits), bits);
1727 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
15561728}
15571729
1558static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) {
1559 return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits);
1730static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) {
1731 return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits);
15601732}
15611733#endif
15621734
1563static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {
1735static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) {
15641736 uint32_t full_res;
15651737#if zig_has_builtin(bswap32) || defined(zig_gcc)
1566 full_res = __builtin_bswap32(val);
1738 full_res = __builtin_bswap32(arg);
15671739#else
1568 full_res = (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 0), 16) << 16 |
1569 (uint32_t)zig_byte_swap_u16((uint16_t)(val >> 16), 16) >> 0;
1740 full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 |
1741 (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0;
15701742#endif
1571 return zig_wrap_u32(full_res >> (32 - bits), bits);
1743 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
15721744}
15731745
1574static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) {
1575 return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits);
1746static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) {
1747 return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits);
15761748}
15771749
15781750#if defined(zig_ez80)
1579static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) {
1751static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) {
15801752 uint48_t full_res;
15811753#if zig_has_builtin(bswap48) || defined(zig_gcc)
1582 full_res = __builtin_bswap48(val);
1754 full_res = __builtin_bswap48(arg);
15831755#else
1584 full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 |
1585 (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0;
1756 full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 |
1757 (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0;
15861758#endif
1587 return zig_wrap_u48(full_res >> (48 - bits), bits);
1759 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
15881760}
15891761
1590static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) {
1591 return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits);
1762static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) {
1763 return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits);
15921764}
15931765#endif
15941766
1595static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {
1767static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) {
15961768 uint64_t full_res;
15971769#if zig_has_builtin(bswap64) || defined(zig_gcc)
1598 full_res = __builtin_bswap64(val);
1770 full_res = __builtin_bswap64(arg);
15991771#else
1600 full_res = (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 0), 32) << 32 |
1601 (uint64_t)zig_byte_swap_u32((uint32_t)(val >> 32), 32) >> 0;
1772 full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 |
1773 (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0;
16021774#endif
1603 return zig_wrap_u64(full_res >> (64 - bits), bits);
1775 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
16041776}
16051777
1606static inline int64_t zig_byte_swap_i64(int64_t val, uint8_t bits) {
1607 return zig_wrap_i64((int64_t)zig_byte_swap_u64((uint64_t)val, bits), bits);
1778static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) {
1779 return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits);
16081780}
16091781
1610static inline uint8_t zig_bit_reverse_u8(uint8_t val, uint8_t bits) {
1782static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) {
16111783 uint8_t full_res;
16121784#if zig_has_builtin(bitreverse8)
1613 full_res = __builtin_bitreverse8(val);
1785 full_res = __builtin_bitreverse8(arg);
16141786#else
16151787 static uint8_t const lut[0x10] = {
16161788 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
16171789 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
16181790 };
1619 full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0;
1791 full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0;
16201792#endif
1621 return zig_wrap_u8(full_res >> (8 - bits), bits);
1793 return zig_u8_truncate_u8(full_res >> (8 - bits), bits);
16221794}
16231795
1624static inline int8_t zig_bit_reverse_i8(int8_t val, uint8_t bits) {
1625 return zig_wrap_i8((int8_t)zig_bit_reverse_u8((uint8_t)val, bits), bits);
1796static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) {
1797 return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits);
16261798}
16271799
1628static inline uint16_t zig_bit_reverse_u16(uint16_t val, uint8_t bits) {
1800static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) {
16291801 uint16_t full_res;
16301802#if zig_has_builtin(bitreverse16)
1631 full_res = __builtin_bitreverse16(val);
1803 full_res = __builtin_bitreverse16(arg);
16321804#else
1633 full_res = (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 8 |
1634 (uint16_t)zig_bit_reverse_u8((uint8_t)(val >> 8), 8) >> 0;
1805 full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 |
1806 (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0;
16351807#endif
1636 return zig_wrap_u16(full_res >> (16 - bits), bits);
1808 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
16371809}
16381810
1639static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) {
1640 return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits);
1811static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) {
1812 return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits);
16411813}
16421814
16431815#if defined(zig_ez80)
1644static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) {
1816static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) {
16451817 uint24_t full_res;
16461818#if zig_has_builtin(bitreverse24)
1647 full_res = __builtin_bitreverse24(val);
1819 full_res = __builtin_bitreverse24(arg);
16481820#else
1649 full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 |
1650 (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0;
1821 full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 |
1822 (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0;
16511823#endif
1652 return zig_wrap_u24(full_res >> (24 - bits), bits);
1824 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
16531825}
16541826
1655static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) {
1656 return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits);
1827static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) {
1828 return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits);
16571829}
16581830#endif
16591831
1660static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) {
1832static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) {
16611833 uint32_t full_res;
16621834#if zig_has_builtin(bitreverse32)
1663 full_res = __builtin_bitreverse32(val);
1835 full_res = __builtin_bitreverse32(arg);
16641836#else
1665 full_res = (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 0), 16) << 16 |
1666 (uint32_t)zig_bit_reverse_u16((uint16_t)(val >> 16), 16) >> 0;
1837 full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 |
1838 (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0;
16671839#endif
1668 return zig_wrap_u32(full_res >> (32 - bits), bits);
1840 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
16691841}
16701842
1671static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) {
1672 return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits);
1843static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) {
1844 return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits);
16731845}
16741846
16751847#if defined(zig_ez80)
1676static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) {
1848static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) {
16771849 uint48_t full_res;
16781850#if zig_has_builtin(bitreverse48)
1679 full_res = __builtin_bitreverse48(val);
1851 full_res = __builtin_bitreverse48(arg);
16801852#else
1681 full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 |
1682 (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0;
1853 full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 |
1854 (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0;
16831855#endif
1684 return zig_wrap_u32(full_res >> (48 - bits), bits);
1856 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
16851857}
16861858
1687static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) {
1688 return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits);
1859static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) {
1860 return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits);
16891861}
16901862#endif
16911863
1692static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) {
1864static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) {
16931865 uint64_t full_res;
16941866#if zig_has_builtin(bitreverse64)
1695 full_res = __builtin_bitreverse64(val);
1867 full_res = __builtin_bitreverse64(arg);
16961868#else
1697 full_res = (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 0), 32) << 32 |
1698 (uint64_t)zig_bit_reverse_u32((uint32_t)(val >> 32), 32) >> 0;
1869 full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 |
1870 (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0;
16991871#endif
1700 return zig_wrap_u64(full_res >> (64 - bits), bits);
1872 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
17011873}
17021874
1703static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {
1704 return zig_wrap_i64((int64_t)zig_bit_reverse_u64((uint64_t)val, bits), bits);
1875static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) {
1876 return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits);
17051877}
17061878
1707#define zig_builtin_popcount_common(w) \
1708 static inline uint8_t zig_popcount_i##w(int##w##_t val, uint8_t bits) { \
1709 return zig_popcount_u##w((uint##w##_t)val, bits); \
1879#define zig_builtin_popCount_common(w) \
1880 static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \
1881 return zig_popCount_u##w((uint##w##_t)arg, bits); \
17101882 }
1711#if zig_has_builtin(popcount) || defined(zig_gcc) || defined(zig_tinyc)
1712#define zig_builtin_popcount(w) \
1713 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \
1883#if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc)
1884#define zig_builtin_popCount(w) \
1885 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
17141886 (void)bits; \
1715 return zig_builtin##w(popcount, val); \
1887 return zig_builtin##w(popcount, arg); \
17161888 } \
17171889\
1718 zig_builtin_popcount_common(w)
1890 zig_builtin_popCount_common(w)
17191891#else
1720#define zig_builtin_popcount(w) \
1721 static inline uint8_t zig_popcount_u##w(uint##w##_t val, uint8_t bits) { \
1892#define zig_builtin_popCount(w) \
1893 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
17221894 (void)bits; \
1723 uint##w##_t temp = val - ((val >> 1) & (UINT##w##_MAX / 3)); \
1895 uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \
17241896 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \
17251897 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \
17261898 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \
17271899 } \
17281900\
1729 zig_builtin_popcount_common(w)
1730#endif
1731zig_builtin_popcount(8)
1732zig_builtin_popcount(16)
1733#if defined(zig_ez80)
1734zig_builtin_popcount(24)
1901 zig_builtin_popCount_common(w)
17351902#endif
1736zig_builtin_popcount(32)
1903zig_builtin_popCount(8)
1904zig_builtin_popCount(16)
1905zig_builtin_popCount(32)
1906zig_builtin_popCount(64)
17371907#if defined(zig_ez80)
1738zig_builtin_popcount(48)
1908zig_builtin_popCount(24)
1909zig_builtin_popCount(48)
17391910#endif
1740zig_builtin_popcount(64)
17411911
17421912#define zig_builtin_ctz_common(w) \
1743 static inline uint8_t zig_ctz_i##w(int##w##_t val, uint8_t bits) { \
1744 return zig_ctz_u##w((uint##w##_t)val, bits); \
1913 static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \
1914 return zig_ctz_u##w((uint##w##_t)arg, bits); \
17451915 }
17461916#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)
17471917#define zig_builtin_ctz(w) \
1748 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \
1749 if (val == 0) return bits; \
1750 return zig_builtin##w(ctz, val); \
1918 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1919 if (arg == 0) return bits; \
1920 return zig_builtin##w(ctz, arg); \
17511921 } \
17521922\
17531923 zig_builtin_ctz_common(w)
17541924#else
17551925#define zig_builtin_ctz(w) \
1756 static inline uint8_t zig_ctz_u##w(uint##w##_t val, uint8_t bits) { \
1757 return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \
1926 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1927 return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \
17581928 } \
17591929\
17601930 zig_builtin_ctz_common(w)
17611931#endif
17621932zig_builtin_ctz(8)
17631933zig_builtin_ctz(16)
1764#if defined(zig_ez80)
1765zig_builtin_ctz(24)
1766#endif
17671934zig_builtin_ctz(32)
1935zig_builtin_ctz(64)
17681936#if defined(zig_ez80)
1937zig_builtin_ctz(24)
17691938zig_builtin_ctz(48)
17701939#endif
1771zig_builtin_ctz(64)
17721940
17731941#define zig_builtin_clz_common(w) \
1774 static inline uint8_t zig_clz_i##w(int##w##_t val, uint8_t bits) { \
1775 return zig_clz_u##w((uint##w##_t)val, bits); \
1942 static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \
1943 return zig_clz_u##w((uint##w##_t)arg, bits); \
17761944 }
17771945#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)
17781946#define zig_builtin_clz(w) \
1779 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \
1780 if (val == 0) return bits; \
1781 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
1947 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1948 if (arg == 0) return bits; \
1949 return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
17821950 } \
17831951\
17841952 zig_builtin_clz_common(w)
17851953#else
17861954#define zig_builtin_clz(w) \
1787 static inline uint8_t zig_clz_u##w(uint##w##_t val, uint8_t bits) { \
1788 return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \
1955 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1956 return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \
17891957 } \
17901958\
17911959 zig_builtin_clz_common(w)
17921960#endif
17931961zig_builtin_clz(8)
17941962zig_builtin_clz(16)
1795#if defined(zig_ez80)
1796zig_builtin_clz(24)
1797#endif
17981963zig_builtin_clz(32)
1964zig_builtin_clz(64)
17991965#if defined(zig_ez80)
1966zig_builtin_clz(24)
18001967zig_builtin_clz(48)
18011968#endif
1802zig_builtin_clz(64)
18031969
18041970/* ======================== 128-bit Integer Support ========================= */
18051971
......@@ -1816,16 +1982,14 @@ zig_builtin_clz(64)
18161982typedef unsigned __int128 zig_u128;
18171983typedef signed __int128 zig_i128;
18181984
1819#define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1820#define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))
1821#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)
1822#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)
1823#define zig_hi_u128(val) ((uint64_t)((val) >> 64))
1824#define zig_lo_u128(val) ((uint64_t)((val) >> 0))
1825#define zig_hi_i128(val) (( int64_t)((val) >> 64))
1826#define zig_lo_i128(val) ((uint64_t)((val) >> 0))
1827#define zig_bitCast_u128(val) ((zig_u128)(val))
1828#define zig_bitCast_i128(val) ((zig_i128)(val))
1985#define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1986#define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))
1987#define zig_make_u128(hi, lo) zig_init_u128(hi, lo)
1988#define zig_make_i128(hi, lo) zig_init_i128(hi, lo)
1989#define zig_hi_u128(arg) ((uint64_t)((arg) >> 64))
1990#define zig_lo_u128(arg) ((uint64_t)((arg) >> 0))
1991#define zig_hi_i128(arg) (( int64_t)((arg) >> 64))
1992#define zig_lo_i128(arg) ((uint64_t)((arg) >> 0))
18291993#define zig_cmp_int128(Type) \
18301994 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
18311995 return (lhs > rhs) - (lhs < rhs); \
......@@ -1835,32 +1999,49 @@ typedef signed __int128 zig_i128;
18351999 return lhs operator rhs; \
18362000 }
18372001
1838#else /* zig_has_int128 */
2002static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2003 return lhs << rhs;
2004}
18392005
1840#if zig_little_endian
1841typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128;
1842typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128;
2006static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2007 return lhs >> rhs;
2008}
2009
2010static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2011 return lhs << rhs;
2012}
2013
2014static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2015 // This works around a GCC miscompilation, but it has the side benefit of
2016 // emitting better code. It is behind the `#if` because it depends on
2017 // arithmetic right shift, which is implementation-defined in C, but should
2018 // be guaranteed on any GCC-compatible compiler.
2019#if defined(zig_gnuc)
2020 return lhs >> rhs;
18432021#else
1844typedef struct { zig_align(16) uint64_t hi; uint64_t lo; } zig_u128;
1845typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
2022 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
2023 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
18462024#endif
2025}
18472026
1848#define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })
1849#define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
2027#else /* zig_has_int128 */
18502028
1851#if defined(zig_msvc) /* MSVC doesn't allow struct literals in constant expressions */
1852#define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }
1853#define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }
1854#else /* But non-MSVC doesn't like the unprotected commas */
1855#define zig_init_u128(hi, lo) zig_make_u128(hi, lo)
1856#define zig_init_i128(hi, lo) zig_make_i128(hi, lo)
1857#endif
1858#define zig_hi_u128(val) ((val).hi)
1859#define zig_lo_u128(val) ((val).lo)
1860#define zig_hi_i128(val) ((val).hi)
1861#define zig_lo_i128(val) ((val).lo)
1862#define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)
1863#define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)
2029#if zig_little_endian
2030typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128;
2031typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128;
2032#else
2033typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128;
2034typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128;
2035#endif
2036
2037#define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo }
2038#define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo }
2039#define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo)
2040#define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo)
2041#define zig_hi_u128(arg) (arg).hi
2042#define zig_lo_u128(arg) (arg).lo
2043#define zig_hi_i128(arg) (arg).hi
2044#define zig_lo_i128(arg) (arg).lo
18642045#define zig_cmp_int128(Type) \
18652046 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
18662047 return (lhs.hi == rhs.hi) \
......@@ -1872,6 +2053,30 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
18722053 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \
18732054 }
18742055
2056static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2057 if (rhs == UINT8_C(0)) return lhs;
2058 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2059 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2060}
2061
2062static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2063 if (rhs == UINT8_C(0)) return lhs;
2064 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
2065 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
2066}
2067
2068static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2069 if (rhs == UINT8_C(0)) return lhs;
2070 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2071 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2072}
2073
2074static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2075 if (rhs == UINT8_C(0)) return lhs;
2076 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
2077 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
2078}
2079
18752080#endif /* zig_has_int128 */
18762081
18772082#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
......@@ -1891,42 +2096,177 @@ zig_bit_int128(i128, or, |)
18912096zig_bit_int128(u128, xor, ^)
18922097zig_bit_int128(i128, xor, ^)
18932098
1894static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs);
2099static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) {
2100 return (uint8_t)zig_lo_u128(arg);
2101}
2102static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) {
2103 return (uint8_t)zig_lo_i128(arg);
2104}
2105static inline int8_t zig_i8_intCast_i128(zig_i128 arg) {
2106 return (int8_t)zig_lo_i128(arg);
2107}
2108static inline int8_t zig_i8_intCast_u128(zig_u128 arg) {
2109 return (int8_t)zig_lo_u128(arg);
2110}
18952111
1896#if zig_has_int128
2112static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) {
2113 return (uint16_t)zig_lo_u128(arg);
2114}
2115static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) {
2116 return (uint16_t)zig_lo_i128(arg);
2117}
2118static inline int16_t zig_i16_intCast_i128(zig_i128 arg) {
2119 return (int16_t)zig_lo_i128(arg);
2120}
2121static inline int16_t zig_i16_intCast_u128(zig_u128 arg) {
2122 return (int16_t)zig_lo_u128(arg);
2123}
18972124
1898static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {
1899 return val ^ zig_maxInt_u(128, bits);
2125static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) {
2126 return (uint32_t)zig_lo_u128(arg);
2127}
2128static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) {
2129 return (uint32_t)zig_lo_i128(arg);
2130}
2131static inline int32_t zig_i32_intCast_i128(zig_i128 arg) {
2132 return (int32_t)zig_lo_i128(arg);
2133}
2134static inline int32_t zig_i32_intCast_u128(zig_u128 arg) {
2135 return (int32_t)zig_lo_u128(arg);
19002136}
19012137
1902static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {
1903 (void)bits;
1904 return ~val;
2138static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) {
2139 return zig_lo_u128(arg);
2140}
2141static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) {
2142 return zig_lo_i128(arg);
2143}
2144static inline int64_t zig_i64_intCast_i128(zig_i128 arg) {
2145 return (int64_t)zig_lo_i128(arg);
2146}
2147static inline int64_t zig_i64_intCast_u128(zig_u128 arg) {
2148 return (int64_t)zig_lo_u128(arg);
19052149}
19062150
1907static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1908 return lhs >> rhs;
2151static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) {
2152 return zig_make_u128(UINT8_C(0), arg);
2153}
2154static inline zig_u128 zig_u128_intCast_i8(int8_t arg) {
2155 return zig_make_u128(UINT8_C(0), (uint8_t)arg);
2156}
2157static inline zig_i128 zig_i128_intCast_i8(int8_t arg) {
2158 return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg);
2159}
2160static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) {
2161 return zig_make_i128(INT8_C(0), arg);
19092162}
19102163
1911static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
1912 return lhs << rhs;
2164static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) {
2165 return zig_make_u128(UINT16_C(0), arg);
2166}
2167static inline zig_u128 zig_u128_intCast_i16(int16_t arg) {
2168 return zig_make_u128(UINT16_C(0), (uint16_t)arg);
2169}
2170static inline zig_i128 zig_i128_intCast_i16(int16_t arg) {
2171 return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg);
2172}
2173static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) {
2174 return zig_make_i128(INT16_C(0), arg);
19132175}
19142176
1915static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1916 // This works around a GCC miscompilation, but it has the side benefit of
1917 // emitting better code. It is behind the `#if` because it depends on
1918 // arithmetic right shift, which is implementation-defined in C, but should
1919 // be guaranteed on any GCC-compatible compiler.
1920#if defined(zig_gnuc)
1921 return lhs >> rhs;
2177static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) {
2178 return zig_make_u128(UINT32_C(0), arg);
2179}
2180static inline zig_u128 zig_u128_intCast_i32(int32_t arg) {
2181 return zig_make_u128(UINT32_C(0), (uint32_t)arg);
2182}
2183static inline zig_i128 zig_i128_intCast_i32(int32_t arg) {
2184 return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg);
2185}
2186static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) {
2187 return zig_make_i128(INT32_C(0), arg);
2188}
2189
2190static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) {
2191 return zig_make_u128(UINT64_C(0), arg);
2192}
2193static inline zig_u128 zig_u128_intCast_i64(int64_t arg) {
2194 return zig_make_u128(UINT64_C(0), (uint64_t)arg);
2195}
2196static inline zig_i128 zig_i128_intCast_i64(int64_t arg) {
2197 return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg);
2198}
2199static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) {
2200 return zig_make_i128(INT64_C(0), arg);
2201}
2202
2203static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) {
2204 return arg;
2205}
2206static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) {
2207#if zig_has_int128
2208 return (zig_u128)arg;
19222209#else
1923 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
1924 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
2210 return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
2211#endif
2212}
2213static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) {
2214 return arg;
2215}
2216static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) {
2217#if zig_has_int128
2218 return (zig_i128)arg;
2219#else
2220 return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
19252221#endif
19262222}
19272223
1928static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
1929 return lhs << rhs;
2224#define zig_int128_cast_builtins(w) \
2225 static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \
2226 return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \
2227 } \
2228\
2229 static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \
2230 return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \
2231 }
2232zig_int128_cast_builtins(8)
2233zig_int128_cast_builtins(16)
2234zig_int128_cast_builtins(32)
2235zig_int128_cast_builtins(64)
2236
2237static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) {
2238 return zig_and_u128(arg, zig_maxInt_u(128, bits));
2239}
2240static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) {
2241 if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg));
2242 int64_t lo = zig_i64_truncate_i128(arg, bits);
2243 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2244}
2245
2246static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2247 (void)bits;
2248 return arg;
2249}
2250static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2251 return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits);
2252}
2253static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2254 (void)bits;
2255 return arg;
2256}
2257static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2258 return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits);
2259}
2260
2261#if zig_has_int128
2262
2263static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2264 return arg ^ zig_maxInt_u(128, bits);
2265}
2266
2267static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2268 (void)bits;
2269 return ~arg;
19302270}
19312271
19322272static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
......@@ -1953,11 +2293,11 @@ static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
19532293 return lhs * rhs;
19542294}
19552295
1956static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
2296static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
19572297 return lhs / rhs;
19582298}
19592299
1960static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
2300static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
19612301 return lhs / rhs;
19622302}
19632303
......@@ -1971,36 +2311,14 @@ static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
19712311
19722312#else /* zig_has_int128 */
19732313
1974static inline zig_u128 zig_not_u128(zig_u128 val, uint8_t bits) {
1975 return (zig_u128){ .hi = zig_not_u64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };
1976}
1977
1978static inline zig_i128 zig_not_i128(zig_i128 val, uint8_t bits) {
1979 return (zig_i128){ .hi = zig_not_i64(val.hi, bits - UINT8_C(64)), .lo = zig_not_u64(val.lo, UINT8_C(64)) };
1980}
1981
1982static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
1983 if (rhs == UINT8_C(0)) return lhs;
1984 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
1985 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
1986}
1987
1988static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
1989 if (rhs == UINT8_C(0)) return lhs;
1990 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
1991 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
1992}
1993
1994static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1995 if (rhs == UINT8_C(0)) return lhs;
1996 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
1997 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
2314static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2315 if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) };
2316 return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) };
19982317}
19992318
2000static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2001 if (rhs == UINT8_C(0)) return lhs;
2002 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2003 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2319static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2320 (void)bits;
2321 return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo };
20042322}
20052323
20062324static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
......@@ -2027,59 +2345,59 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
20272345 return res;
20282346}
20292347
2030zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
20312348static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
2349 zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
20322350 return __multi3(lhs, rhs);
20332351}
20342352
20352353static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
2036 return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs)));
2354 return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128));
20372355}
20382356
2039zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
2040static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
2357static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
2358 zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
20412359 return __udivti3(lhs, rhs);
20422360}
20432361
2044zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
2045static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
2362static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
2363 zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
20462364 return __divti3(lhs, rhs);
20472365}
20482366
2049zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
20502367static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
2368 zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
20512369 return __umodti3(lhs, rhs);
20522370}
20532371
2054zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
20552372static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
2373 zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
20562374 return __modti3(lhs, rhs);
20572375}
20582376
20592377#endif /* zig_has_int128 */
20602378
2061#define zig_div_floor_u128 zig_div_trunc_u128
2379#define zig_divFloor_u128 zig_divTrunc_u128
20622380
2063static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
2381static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) {
20642382 zig_i128 rem = zig_rem_i128(lhs, rhs);
20652383 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
20662384 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);
2067 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));
2385 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));
20682386}
20692387
2070static inline zig_u128 zig_div_ceil_u128(zig_u128 lhs, zig_u128 rhs) {
2388static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) {
20712389 zig_u128 rem = zig_rem_u128(lhs, rhs);
20722390 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)
20732391 ? UINT64_C(1) : UINT64_C(0);
2074 return zig_add_u128(zig_div_trunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));
2392 return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));
20752393}
20762394
2077static inline zig_i128 zig_div_ceil_i128(zig_i128 lhs, zig_i128 rhs) {
2395static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) {
20782396 zig_i128 rem = zig_rem_i128(lhs, rhs);
20792397 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
20802398 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)
20812399 : INT64_C(0);
2082 return zig_add_i128(zig_div_trunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));
2400 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));
20832401}
20842402
20852403#define zig_mod_u128 zig_rem_u128
......@@ -2107,51 +2425,41 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {
21072425 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
21082426}
21092427
2110static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) {
2111 return zig_and_u128(val, zig_maxInt_u(128, bits));
2112}
2113
2114static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) {
2115 if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val));
2116 int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits);
2117 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2118}
2119
21202428static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
2121 return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits);
2429 return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits);
21222430}
21232431
21242432static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2125 return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits);
2433 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits);
21262434}
21272435
21282436static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2129 return zig_wrap_u128(zig_add_u128(lhs, rhs), bits);
2437 return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits);
21302438}
21312439
21322440static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2133 return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
2441 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
21342442}
21352443
21362444static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2137 return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits);
2445 return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits);
21382446}
21392447
21402448static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2141 return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
2449 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
21422450}
21432451
21442452static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2145 return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits);
2453 return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits);
21462454}
21472455
21482456static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2149 return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
2457 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
21502458}
21512459
2152static inline zig_u128 zig_abs_i128(zig_i128 val) {
2153 zig_i128 tmp = zig_shr_i128(val, 127);
2154 return zig_bitCast_u128(zig_sub_i128(zig_xor_i128(val, tmp), tmp));
2460static inline zig_u128 zig_abs_i128(zig_i128 arg) {
2461 zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128));
2462 return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp);
21552463}
21562464
21572465#if zig_has_int128
......@@ -2160,7 +2468,7 @@ static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
21602468#if zig_has_builtin(add_overflow)
21612469 zig_u128 full_res;
21622470 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
2163 *res = zig_wrap_u128(full_res, bits);
2471 *res = zig_u128_truncate_u128(full_res, bits);
21642472 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
21652473#else
21662474 *res = zig_addw_u128(lhs, rhs, bits);
......@@ -2176,7 +2484,7 @@ static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
21762484 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);
21772485 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
21782486#endif
2179 *res = zig_wrap_i128(full_res, bits);
2487 *res = zig_i128_truncate_i128(full_res, bits);
21802488 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
21812489}
21822490
......@@ -2184,7 +2492,7 @@ static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
21842492#if zig_has_builtin(sub_overflow)
21852493 zig_u128 full_res;
21862494 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
2187 *res = zig_wrap_u128(full_res, bits);
2495 *res = zig_u128_truncate_u128(full_res, bits);
21882496 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
21892497#else
21902498 *res = zig_subw_u128(lhs, rhs, bits);
......@@ -2200,7 +2508,7 @@ static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
22002508 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);
22012509 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
22022510#endif
2203 *res = zig_wrap_i128(full_res, bits);
2511 *res = zig_i128_truncate_i128(full_res, bits);
22042512 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
22052513}
22062514
......@@ -2208,7 +2516,7 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
22082516#if zig_has_builtin(mul_overflow)
22092517 zig_u128 full_res;
22102518 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
2211 *res = zig_wrap_u128(full_res, bits);
2519 *res = zig_u128_truncate_u128(full_res, bits);
22122520 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
22132521#else
22142522 *res = zig_mulw_u128(lhs, rhs, bits);
......@@ -2216,8 +2524,8 @@ static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint
22162524#endif
22172525}
22182526
2219zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
22202527static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2528 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
22212529#if zig_has_builtin(mul_overflow)
22222530 zig_i128 full_res;
22232531 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
......@@ -2226,50 +2534,78 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
22262534 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
22272535 bool overflow = overflow_int != 0;
22282536#endif
2229 *res = zig_wrap_i128(full_res, bits);
2537 *res = zig_i128_truncate_i128(full_res, bits);
22302538 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
22312539}
22322540
22332541#else /* zig_has_int128 */
22342542
22352543static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2236 uint64_t hi;
2237 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64);
2238 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
2544 if (bits <= UINT8_C(64)) {
2545 uint64_t lo;
2546 bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2547 *res = zig_u128_intCast_u64(lo);
2548 return overflow;
2549 } else {
2550 uint64_t hi;
2551 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2552 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2553 }
22392554}
22402555
22412556static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2242 int64_t hi;
2243 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64);
2244 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
2557 if (bits <= UINT8_C(64)) {
2558 int64_t lo;
2559 bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2560 *res = zig_i128_intCast_i64(lo);
2561 return overflow;
2562 } else {
2563 int64_t hi;
2564 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2565 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2566 }
22452567}
22462568
22472569static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2248 uint64_t hi;
2249 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64);
2250 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
2570 if (bits <= UINT8_C(64)) {
2571 uint64_t lo;
2572 bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2573 *res = zig_u128_intCast_u64(lo);
2574 return overflow;
2575 } else {
2576 uint64_t hi;
2577 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2578 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2579 }
22512580}
22522581
22532582static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2254 int64_t hi;
2255 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64);
2256 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
2583 if (bits <= UINT8_C(64)) {
2584 int64_t lo;
2585 bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2586 *res = zig_i128_intCast_i64(lo);
2587 return overflow;
2588 } else {
2589 int64_t hi;
2590 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2591 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2592 }
22572593}
22582594
22592595static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
22602596 *res = zig_mulw_u128(lhs, rhs, bits);
2261 return zig_cmp_u128(*res, zig_make_u128(0, 0)) != INT32_C(0) &&
2262 zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
2597 return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) &&
2598 zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
22632599}
22642600
2265zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
22662601static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2602 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
22672603 int overflow_int;
22682604 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
22692605 bool overflow = overflow_int != 0 ||
22702606 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
22712607 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
2272 *res = zig_wrap_i128(full_res, bits);
2608 *res = zig_i128_truncate_i128(full_res, bits);
22732609 return overflow;
22742610}
22752611
......@@ -2282,28 +2618,54 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
22822618
22832619static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
22842620 *res = zig_shlw_i128(lhs, rhs, bits);
2285 zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));
2621 zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits);
22862622 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
22872623 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
22882624}
22892625
2290static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2626#define zig_int128_shls_builtins(rw) \
2627 static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2628 zig_u128 res; \
2629 if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2630 switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \
2631 case 0: return zig_minInt_u(128, bits); \
2632 case 1: return zig_maxInt_u(128, bits); \
2633 default: zig_unreachable(); \
2634 } \
2635 } \
2636\
2637 static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2638 zig_i128 res; \
2639 if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2640 switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \
2641 case -1: return zig_minInt_i(128, bits); \
2642 case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \
2643 case 1: return zig_maxInt_i(128, bits); \
2644 default: zig_unreachable(); \
2645 } \
2646 }
2647zig_int128_shls_builtins(8)
2648zig_int128_shls_builtins(16)
2649zig_int128_shls_builtins(32)
2650zig_int128_shls_builtins(64)
2651
2652static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
22912653 zig_u128 res;
22922654 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
22932655 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
2294 case 0: return zig_make_u128(0, 0);
2295 case 1: return zig_maxInt_u(128, bits);
2656 case INT32_C(0): return zig_make_u128(0, 0);
2657 case INT32_C(1): return zig_maxInt_u(128, bits);
22962658 default: zig_unreachable();
22972659 }
22982660}
22992661
2300static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
2662static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
23012663 zig_i128 res;
23022664 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
23032665 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {
2304 case -1: return zig_minInt_i(128, bits);
2305 case 0: return zig_make_i128(0, 0);
2306 case 1: return zig_maxInt_i(128, bits);
2666 case -INT32_C(1): return zig_minInt_i(128, bits);
2667 case INT32_C(0): return zig_make_i128(0, 0);
2668 case INT32_C(1): return zig_maxInt_i(128, bits);
23072669 default: zig_unreachable();
23082670 }
23092671}
......@@ -2341,57 +2703,60 @@ static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
23412703 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
23422704}
23432705
2344static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {
2345 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(val), bits);
2346 if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - UINT8_C(64));
2347 return zig_clz_u64(zig_lo_u128(val), UINT8_C(64)) + (bits - UINT8_C(64));
2706static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) {
2707 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits);
2708 if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64));
2709 return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64));
23482710}
23492711
2350static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {
2351 return zig_clz_u128(zig_bitCast_u128(val), bits);
2712static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) {
2713 return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits);
23522714}
23532715
2354static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {
2355 if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), UINT8_C(64));
2356 return zig_ctz_u64(zig_hi_u128(val), bits - UINT8_C(64)) + UINT8_C(64);
2716static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) {
2717 if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64));
2718 return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64);
23572719}
23582720
2359static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {
2360 return zig_ctz_u128(zig_bitCast_u128(val), bits);
2721static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) {
2722 return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits);
23612723}
23622724
2363static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {
2364 return zig_popcount_u64(zig_hi_u128(val), bits - UINT8_C(64)) +
2365 zig_popcount_u64(zig_lo_u128(val), UINT8_C(64));
2725static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) {
2726 return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) +
2727 zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64));
23662728}
23672729
2368static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {
2369 return zig_popcount_u128(zig_bitCast_u128(val), bits);
2730static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) {
2731 return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits);
23702732}
23712733
2372static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {
2734static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) {
23732735 zig_u128 full_res;
23742736#if zig_has_builtin(bswap128)
2375 full_res = __builtin_bswap128(val);
2737 full_res = __builtin_bswap128(arg);
23762738#else
2377 full_res = zig_make_u128(zig_byte_swap_u64(zig_lo_u128(val), UINT8_C(64)),
2378 zig_byte_swap_u64(zig_hi_u128(val), UINT8_C(64)));
2739 full_res = zig_make_u128(
2740 zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)),
2741 zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64))
2742 );
23792743#endif
23802744 return zig_shr_u128(full_res, UINT8_C(128) - bits);
23812745}
23822746
2383static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {
2384 return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits));
2747static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) {
2748 return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
23852749}
23862750
2387static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {
2388 return zig_shr_u128(zig_make_u128(zig_bit_reverse_u64(zig_lo_u128(val), UINT8_C(64)),
2389 zig_bit_reverse_u64(zig_hi_u128(val), UINT8_C(64))),
2390 UINT8_C(128) - bits);
2751static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) {
2752 return zig_shr_u128(zig_make_u128(
2753 zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)),
2754 zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64))
2755 ), UINT8_C(128) - bits);
23912756}
23922757
2393static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
2394 return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits));
2758static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) {
2759 return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
23952760}
23962761
23972762#if zig_has_int128
......@@ -2411,15 +2776,218 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
24112776/* ========================== Big Integer Support =========================== */
24122777
24132778static inline uint16_t zig_int_bytes(uint16_t bits) {
2414 uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT;
2779 uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1);
24152780 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;
2781
24162782 while (alignment / 2 >= bytes) alignment /= 2;
24172783 return (bytes + alignment - 1) / alignment * alignment;
24182784}
24192785
2420static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2786static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) {
2787 uint8_t *res_bytes = res;
2788 uint16_t size = zig_int_bytes(bits);
2789 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2790 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2791 uint8_t sign_byte;
2792 uint8_t fill_byte;
2793
2794 if (is_signed) {
2795 int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits);
2796
2797 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2798 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2799 } else {
2800 sign_byte = zig_minInt_u(8, remainder_bits);
2801 fill_byte = UINT8_C(0);
2802 }
2803
2804#if zig_little_endian
2805 memset(&res_bytes[0], zig_minInt_u8, byte_offset);
2806 res_bytes[byte_offset] = sign_byte;
2807 byte_offset += UINT16_C(1);
2808 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2809#else
2810 byte_offset = size - UINT16_C(1) - byte_offset;
2811 memset(&res_bytes[0], fill_byte, byte_offset);
2812 res_bytes[byte_offset] = sign_byte;
2813 byte_offset += UINT16_C(1);
2814 memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset);
2815#endif
2816}
2817
2818static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) {
2819 uint8_t *res_bytes = res;
2820 uint16_t size = zig_int_bytes(bits);
2821 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2822 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2823 uint8_t sign_byte;
2824 uint8_t fill_byte;
2825
2826 if (is_signed) {
2827 int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits);
2828
2829 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2830 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2831 } else {
2832 sign_byte = zig_maxInt_u(8, remainder_bits);
2833 fill_byte = UINT8_C(0);
2834 }
2835
2836#if zig_little_endian
2837 memset(&res_bytes[0], zig_maxInt_u8, byte_offset);
2838 res_bytes[byte_offset] = sign_byte;
2839 byte_offset += UINT16_C(1);
2840 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2841#else
2842 byte_offset = size - UINT16_C(1) - byte_offset;
2843 memset(&res_bytes[0], fill_byte, byte_offset);
2844 res_bytes[byte_offset] = sign_byte;
2845 byte_offset += UINT16_C(1);
2846 memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset);
2847#endif
2848}
2849
2850static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) {
2851 const uint8_t *arg_bytes = arg;
2852 uint16_t byte_offset = 0;
2853
2854 if (!is_signed) return INT8_C(0);
2855#if zig_little_endian
2856 byte_offset = zig_int_bytes(bits) - 1;
2857#endif
2858 return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7));
2859}
2860
2861static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2862 uint8_t *res_bytes = res;
2863 const uint8_t *arg_bytes = arg;
2864 uint16_t res_size = zig_int_bytes(res_bits);
2865 uint16_t arg_size = zig_int_bytes(arg_bits);
2866 uint16_t copy_size = zig_min_u16(res_size, arg_size);
2867 uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8));
2868
2869#if zig_little_endian
2870 memcpy(&res_bytes[0], &arg_bytes[0], copy_size);
2871 memset(&res_bytes[copy_size], sign_fill, res_size - copy_size);
2872#else
2873 memset(&res_bytes[0], sign_fill, res_size - copy_size);
2874 memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size);
2875#endif
2876}
2877
2878static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2879 uint8_t *res_bytes = res;
2880 const uint8_t *arg_bytes = arg;
2881 uint16_t res_size = zig_int_bytes(res_bits);
2882
2883 if (res_is_signed != arg_is_signed) zig_unreachable();
2884 if (res_bits > arg_bits) zig_unreachable();
2885
2886 if (res_is_signed) {
2887 uint16_t arg_byte_offset = UINT16_C(0);
2888
2889#if zig_big_endian
2890 arg_byte_offset = zig_int_bytes(arg_bits) - res_size;
2891#endif
2892
2893 memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size);
2894 } else {
2895 uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3));
2896 uint16_t arg_byte_offset = res_byte_offset;
2897
2898#if zig_little_endian
2899 memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset);
2900#else
2901 res_byte_offset = res_size - UINT16_C(1) - res_byte_offset;
2902 arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset;
2903
2904 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
2905#endif
2906
2907 res_bytes[res_byte_offset] = zig_u8_truncate_u8(
2908 arg_bytes[arg_byte_offset],
2909 zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1)
2910 );
2911 res_byte_offset += UINT16_C(1);
2912 arg_byte_offset += UINT16_C(1);
2913
2914#if zig_little_endian
2915 memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset);
2916#else
2917 memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset);
2918#endif
2919 }
2920}
2921
2922#define zig_big_casts(is, s, w, IntType) \
2923 static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \
2924 IntType res; \
2925 zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \
2926 return res; \
2927 } \
2928\
2929 static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2930 zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \
2931 } \
2932\
2933 static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \
2934 IntType res; \
2935 zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \
2936 return res; \
2937 } \
2938\
2939 static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2940 zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \
2941 }
2942zig_big_casts(false, u, 8, uint8_t)
2943zig_big_casts(true , i, 8, int8_t)
2944zig_big_casts(false, u, 16, uint16_t)
2945zig_big_casts(true , i, 16, int16_t)
2946zig_big_casts(false, u, 32, uint32_t)
2947zig_big_casts(true , i, 32, int32_t)
2948zig_big_casts(false, u, 64, uint64_t)
2949zig_big_casts(true , i, 64, int64_t)
2950zig_big_casts(false, u, 128, zig_u128)
2951zig_big_casts(true , i, 128, zig_i128)
2952
2953static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) {
2954 uint8_t *res_bytes = res;
2955 const uint8_t *arg_bytes = arg;
2956 uint16_t size = zig_int_bytes(bits);
2957 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2958 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2959 uint8_t sign_byte;
2960 uint8_t fill_byte;
2961
2962#if zig_big_endian
2963 byte_offset = size - UINT16_C(1) - byte_offset;
2964#endif
2965
2966 if (res_is_signed) {
2967 int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2968
2969 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2970 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2971 } else {
2972 sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2973 fill_byte = UINT8_C(0);
2974 }
2975
2976#if zig_little_endian
2977 memcpy(&res_bytes[0], &arg_bytes[0], byte_offset);
2978 res_bytes[byte_offset] = sign_byte;
2979 byte_offset += UINT16_C(1);
2980 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2981#else
2982 memset(&res_bytes[0], fill_byte, byte_offset);
2983 res_bytes[byte_offset] = sign_byte;
2984 byte_offset += UINT16_C(1);
2985 memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset);
2986#endif
2987}
2988
2989static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) {
24212990 const uint8_t *lhs_bytes = lhs;
2422 const uint8_t *rhs_bytes = rhs;
24232991 uint16_t byte_offset = 0;
24242992 bool do_signed = is_signed;
24252993 uint16_t remaining_bytes = zig_int_bytes(bits);
......@@ -2429,6 +2997,7 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24292997#endif
24302998
24312999 while (remaining_bytes >= 128 / CHAR_BIT) {
3000 uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0);
24323001 int32_t limb_cmp;
24333002
24343003#if zig_little_endian
......@@ -2437,18 +3006,16 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24373006
24383007 if (do_signed) {
24393008 zig_i128 lhs_limb;
2440 zig_i128 rhs_limb;
3009 zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte);
24413010
24423011 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2443 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
24443012 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
24453013 do_signed = false;
24463014 } else {
24473015 zig_u128 lhs_limb;
2448 zig_u128 rhs_limb;
3016 zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte);
24493017
24503018 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2451 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
24523019 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
24533020 }
24543021
......@@ -2461,24 +3028,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24613028 }
24623029
24633030 while (remaining_bytes >= 64 / CHAR_BIT) {
3031 uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0);
3032
24643033#if zig_little_endian
24653034 byte_offset -= 64 / CHAR_BIT;
24663035#endif
24673036
24683037 if (do_signed) {
24693038 int64_t lhs_limb;
2470 int64_t rhs_limb;
3039 int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte);
24713040
24723041 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2473 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
24743042 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
24753043 do_signed = false;
24763044 } else {
24773045 uint64_t lhs_limb;
2478 uint64_t rhs_limb;
3046 uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte);
24793047
24803048 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2481 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
24823049 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
24833050 }
24843051
......@@ -2490,24 +3057,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
24903057 }
24913058
24923059 while (remaining_bytes >= 32 / CHAR_BIT) {
3060 uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0);
3061
24933062#if zig_little_endian
24943063 byte_offset -= 32 / CHAR_BIT;
24953064#endif
24963065
24973066 if (do_signed) {
24983067 int32_t lhs_limb;
2499 int32_t rhs_limb;
3068 int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte);
25003069
25013070 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2502 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
25033071 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
25043072 do_signed = false;
25053073 } else {
25063074 uint32_t lhs_limb;
2507 uint32_t rhs_limb;
3075 uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte);
25083076
25093077 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2510 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
25113078 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
25123079 }
25133080
......@@ -2519,24 +3086,24 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
25193086 }
25203087
25213088 while (remaining_bytes >= 16 / CHAR_BIT) {
3089 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3090
25223091#if zig_little_endian
25233092 byte_offset -= 16 / CHAR_BIT;
25243093#endif
25253094
25263095 if (do_signed) {
25273096 int16_t lhs_limb;
2528 int16_t rhs_limb;
3097 int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte);
25293098
25303099 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2531 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
25323100 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
25333101 do_signed = false;
25343102 } else {
25353103 uint16_t lhs_limb;
2536 uint16_t rhs_limb;
3104 uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte);
25373105
25383106 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2539 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
25403107 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
25413108 }
25423109
......@@ -2548,24 +3115,26 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
25483115 }
25493116
25503117 while (remaining_bytes >= 8 / CHAR_BIT) {
3118 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3119
25513120#if zig_little_endian
25523121 byte_offset -= 8 / CHAR_BIT;
25533122#endif
25543123
25553124 if (do_signed) {
25563125 int8_t lhs_limb;
2557 int8_t rhs_limb;
3126 int16_t lhs_cmp_limb;
3127 int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte);
25583128
25593129 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2560 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2561 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3130 lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb);
3131 if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb);
25623132 do_signed = false;
25633133 } else {
25643134 uint8_t lhs_limb;
2565 uint8_t rhs_limb;
3135 uint8_t rhs_limb = rhs_byte;
25663136
25673137 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2568 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
25693138 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
25703139 }
25713140
......@@ -2579,148 +3148,472 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
25793148 return 0;
25803149}
25813150
2582static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2583 uint8_t *res_bytes = res;
3151static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
25843152 const uint8_t *lhs_bytes = lhs;
25853153 const uint8_t *rhs_bytes = rhs;
25863154 uint16_t byte_offset = 0;
3155 bool do_signed = is_signed;
25873156 uint16_t remaining_bytes = zig_int_bytes(bits);
2588 (void)is_signed;
3157
3158#if zig_little_endian
3159 byte_offset = remaining_bytes;
3160#endif
25893161
25903162 while (remaining_bytes >= 128 / CHAR_BIT) {
2591 zig_u128 res_limb;
2592 zig_u128 lhs_limb;
2593 zig_u128 rhs_limb;
3163 int32_t limb_cmp;
25943164
2595 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2596 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2597 res_limb = zig_and_u128(lhs_limb, rhs_limb);
2598 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3165#if zig_little_endian
3166 byte_offset -= 128 / CHAR_BIT;
3167#endif
3168
3169 if (do_signed) {
3170 zig_i128 lhs_limb;
3171 zig_i128 rhs_limb;
3172
3173 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3174 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3175 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
3176 do_signed = false;
3177 } else {
3178 zig_u128 lhs_limb;
3179 zig_u128 rhs_limb;
3180
3181 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3182 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3183 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
3184 }
25993185
3186 if (limb_cmp != 0) return limb_cmp;
26003187 remaining_bytes -= 128 / CHAR_BIT;
3188
3189#if zig_big_endian
26013190 byte_offset += 128 / CHAR_BIT;
3191#endif
26023192 }
26033193
26043194 while (remaining_bytes >= 64 / CHAR_BIT) {
2605 uint64_t res_limb;
2606 uint64_t lhs_limb;
2607 uint64_t rhs_limb;
3195#if zig_little_endian
3196 byte_offset -= 64 / CHAR_BIT;
3197#endif
26083198
2609 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2610 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2611 res_limb = zig_and_u64(lhs_limb, rhs_limb);
2612 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3199 if (do_signed) {
3200 int64_t lhs_limb;
3201 int64_t rhs_limb;
3202
3203 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3204 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3205 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3206 do_signed = false;
3207 } else {
3208 uint64_t lhs_limb;
3209 uint64_t rhs_limb;
3210
3211 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3212 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3213 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3214 }
26133215
26143216 remaining_bytes -= 64 / CHAR_BIT;
3217
3218#if zig_big_endian
26153219 byte_offset += 64 / CHAR_BIT;
3220#endif
26163221 }
26173222
26183223 while (remaining_bytes >= 32 / CHAR_BIT) {
2619 uint32_t res_limb;
2620 uint32_t lhs_limb;
2621 uint32_t rhs_limb;
3224#if zig_little_endian
3225 byte_offset -= 32 / CHAR_BIT;
3226#endif
26223227
2623 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2624 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2625 res_limb = zig_and_u32(lhs_limb, rhs_limb);
2626 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3228 if (do_signed) {
3229 int32_t lhs_limb;
3230 int32_t rhs_limb;
3231
3232 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3233 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3234 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3235 do_signed = false;
3236 } else {
3237 uint32_t lhs_limb;
3238 uint32_t rhs_limb;
3239
3240 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3241 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3242 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3243 }
26273244
26283245 remaining_bytes -= 32 / CHAR_BIT;
3246
3247#if zig_big_endian
26293248 byte_offset += 32 / CHAR_BIT;
3249#endif
26303250 }
26313251
26323252 while (remaining_bytes >= 16 / CHAR_BIT) {
2633 uint16_t res_limb;
2634 uint16_t lhs_limb;
2635 uint16_t rhs_limb;
3253#if zig_little_endian
3254 byte_offset -= 16 / CHAR_BIT;
3255#endif
26363256
2637 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2638 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2639 res_limb = zig_and_u16(lhs_limb, rhs_limb);
2640 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3257 if (do_signed) {
3258 int16_t lhs_limb;
3259 int16_t rhs_limb;
3260
3261 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3262 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3263 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3264 do_signed = false;
3265 } else {
3266 uint16_t lhs_limb;
3267 uint16_t rhs_limb;
3268
3269 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3270 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3271 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3272 }
26413273
26423274 remaining_bytes -= 16 / CHAR_BIT;
3275
3276#if zig_big_endian
26433277 byte_offset += 16 / CHAR_BIT;
3278#endif
26443279 }
26453280
26463281 while (remaining_bytes >= 8 / CHAR_BIT) {
2647 uint8_t res_limb;
2648 uint8_t lhs_limb;
2649 uint8_t rhs_limb;
3282#if zig_little_endian
3283 byte_offset -= 8 / CHAR_BIT;
3284#endif
26503285
2651 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2652 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2653 res_limb = zig_and_u8(lhs_limb, rhs_limb);
2654 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3286 if (do_signed) {
3287 int8_t lhs_limb;
3288 int8_t rhs_limb;
3289
3290 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3291 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3292 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3293 do_signed = false;
3294 } else {
3295 uint8_t lhs_limb;
3296 uint8_t rhs_limb;
3297
3298 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3299 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3300 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3301 }
26553302
26563303 remaining_bytes -= 8 / CHAR_BIT;
3304
3305#if zig_big_endian
26573306 byte_offset += 8 / CHAR_BIT;
3307#endif
26583308 }
3309
3310 return 0;
26593311}
26603312
2661static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3313static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
26623314 uint8_t *res_bytes = res;
2663 const uint8_t *lhs_bytes = lhs;
2664 const uint8_t *rhs_bytes = rhs;
3315 const uint8_t *arg_bytes = arg;
26653316 uint16_t byte_offset = 0;
26663317 uint16_t remaining_bytes = zig_int_bytes(bits);
2667 (void)is_signed;
3318 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3319
3320#if zig_big_endian
3321 byte_offset = remaining_bytes;
3322#endif
26683323
26693324 while (remaining_bytes >= 128 / CHAR_BIT) {
2670 zig_u128 res_limb;
2671 zig_u128 lhs_limb;
2672 zig_u128 rhs_limb;
3325 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
26733326
2674 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2675 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2676 res_limb = zig_or_u128(lhs_limb, rhs_limb);
2677 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3327#if zig_big_endian
3328 byte_offset -= 128 / CHAR_BIT;
3329#endif
3330
3331 if (remaining_bytes != 128 / CHAR_BIT || is_signed) {
3332 zig_i128 res_limb;
3333 zig_i128 arg_limb;
3334
3335 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3336 res_limb = zig_not_i128(arg_limb, limb_bits);
3337 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3338 } else {
3339 zig_u128 res_limb;
3340 zig_u128 arg_limb;
3341
3342 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3343 res_limb = zig_not_u128(arg_limb, limb_bits);
3344 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3345 }
26783346
26793347 remaining_bytes -= 128 / CHAR_BIT;
3348
3349#if zig_little_endian
26803350 byte_offset += 128 / CHAR_BIT;
3351#endif
26813352 }
26823353
26833354 while (remaining_bytes >= 64 / CHAR_BIT) {
2684 uint64_t res_limb;
2685 uint64_t lhs_limb;
2686 uint64_t rhs_limb;
3355 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
26873356
2688 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2689 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2690 res_limb = zig_or_u64(lhs_limb, rhs_limb);
2691 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3357#if zig_big_endian
3358 byte_offset -= 64 / CHAR_BIT;
3359#endif
3360
3361 if (remaining_bytes != 64 / CHAR_BIT || is_signed) {
3362 int64_t res_limb;
3363 int64_t arg_limb;
3364
3365 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3366 res_limb = zig_not_i64(arg_limb, limb_bits);
3367 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3368 } else {
3369 uint64_t res_limb;
3370 uint64_t arg_limb;
3371
3372 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3373 res_limb = zig_not_u64(arg_limb, limb_bits);
3374 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3375 }
26923376
26933377 remaining_bytes -= 64 / CHAR_BIT;
3378
3379#if zig_little_endian
26943380 byte_offset += 64 / CHAR_BIT;
3381#endif
26953382 }
26963383
26973384 while (remaining_bytes >= 32 / CHAR_BIT) {
2698 uint32_t res_limb;
2699 uint32_t lhs_limb;
2700 uint32_t rhs_limb;
3385 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
27013386
2702 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2703 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2704 res_limb = zig_or_u32(lhs_limb, rhs_limb);
2705 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3387#if zig_big_endian
3388 byte_offset -= 32 / CHAR_BIT;
3389#endif
3390
3391 if (remaining_bytes != 32 / CHAR_BIT || is_signed) {
3392 int32_t res_limb;
3393 int32_t arg_limb;
3394
3395 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3396 res_limb = zig_not_i32(arg_limb, limb_bits);
3397 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3398 } else {
3399 uint32_t res_limb;
3400 uint32_t arg_limb;
3401
3402 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3403 res_limb = zig_not_u32(arg_limb, limb_bits);
3404 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3405 }
27063406
27073407 remaining_bytes -= 32 / CHAR_BIT;
3408
3409#if zig_little_endian
27083410 byte_offset += 32 / CHAR_BIT;
3411#endif
27093412 }
27103413
27113414 while (remaining_bytes >= 16 / CHAR_BIT) {
2712 uint16_t res_limb;
2713 uint16_t lhs_limb;
2714 uint16_t rhs_limb;
3415 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
27153416
2716 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2717 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2718 res_limb = zig_or_u16(lhs_limb, rhs_limb);
2719 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3417#if zig_big_endian
3418 byte_offset -= 16 / CHAR_BIT;
3419#endif
27203420
2721 remaining_bytes -= 16 / CHAR_BIT;
2722 byte_offset += 16 / CHAR_BIT;
2723 }
3421 if (remaining_bytes != 16 / CHAR_BIT || is_signed) {
3422 int16_t res_limb;
3423 int16_t arg_limb;
3424
3425 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3426 res_limb = zig_not_i16(arg_limb, limb_bits);
3427 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3428 } else {
3429 uint16_t res_limb;
3430 uint16_t arg_limb;
3431
3432 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3433 res_limb = zig_not_u16(arg_limb, limb_bits);
3434 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3435 }
3436
3437 remaining_bytes -= 16 / CHAR_BIT;
3438
3439#if zig_little_endian
3440 byte_offset += 16 / CHAR_BIT;
3441#endif
3442 }
3443
3444 while (remaining_bytes >= 8 / CHAR_BIT) {
3445 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3446
3447#if zig_big_endian
3448 byte_offset -= 8 / CHAR_BIT;
3449#endif
3450
3451 if (remaining_bytes != 8 / CHAR_BIT || is_signed) {
3452 int8_t res_limb;
3453 int8_t arg_limb;
3454
3455 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3456 res_limb = zig_not_i8(arg_limb, limb_bits);
3457 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3458 } else {
3459 uint8_t res_limb;
3460 uint8_t arg_limb;
3461
3462 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3463 res_limb = zig_not_u8(arg_limb, limb_bits);
3464 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3465 }
3466
3467 remaining_bytes -= 8 / CHAR_BIT;
3468
3469#if zig_little_endian
3470 byte_offset += 8 / CHAR_BIT;
3471#endif
3472 }
3473}
3474
3475static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3476 uint8_t *res_bytes = res;
3477 const uint8_t *lhs_bytes = lhs;
3478 const uint8_t *rhs_bytes = rhs;
3479 uint16_t byte_offset = 0;
3480 uint16_t remaining_bytes = zig_int_bytes(bits);
3481 (void)is_signed;
3482
3483 while (remaining_bytes >= 128 / CHAR_BIT) {
3484 zig_u128 res_limb;
3485 zig_u128 lhs_limb;
3486 zig_u128 rhs_limb;
3487
3488 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3489 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3490 res_limb = zig_and_u128(lhs_limb, rhs_limb);
3491 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3492
3493 remaining_bytes -= 128 / CHAR_BIT;
3494 byte_offset += 128 / CHAR_BIT;
3495 }
3496
3497 while (remaining_bytes >= 64 / CHAR_BIT) {
3498 uint64_t res_limb;
3499 uint64_t lhs_limb;
3500 uint64_t rhs_limb;
3501
3502 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3503 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3504 res_limb = zig_and_u64(lhs_limb, rhs_limb);
3505 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3506
3507 remaining_bytes -= 64 / CHAR_BIT;
3508 byte_offset += 64 / CHAR_BIT;
3509 }
3510
3511 while (remaining_bytes >= 32 / CHAR_BIT) {
3512 uint32_t res_limb;
3513 uint32_t lhs_limb;
3514 uint32_t rhs_limb;
3515
3516 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3517 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3518 res_limb = zig_and_u32(lhs_limb, rhs_limb);
3519 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3520
3521 remaining_bytes -= 32 / CHAR_BIT;
3522 byte_offset += 32 / CHAR_BIT;
3523 }
3524
3525 while (remaining_bytes >= 16 / CHAR_BIT) {
3526 uint16_t res_limb;
3527 uint16_t lhs_limb;
3528 uint16_t rhs_limb;
3529
3530 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3531 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3532 res_limb = zig_and_u16(lhs_limb, rhs_limb);
3533 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3534
3535 remaining_bytes -= 16 / CHAR_BIT;
3536 byte_offset += 16 / CHAR_BIT;
3537 }
3538
3539 while (remaining_bytes >= 8 / CHAR_BIT) {
3540 uint8_t res_limb;
3541 uint8_t lhs_limb;
3542 uint8_t rhs_limb;
3543
3544 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3545 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3546 res_limb = zig_and_u8(lhs_limb, rhs_limb);
3547 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3548
3549 remaining_bytes -= 8 / CHAR_BIT;
3550 byte_offset += 8 / CHAR_BIT;
3551 }
3552}
3553
3554static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3555 uint8_t *res_bytes = res;
3556 const uint8_t *lhs_bytes = lhs;
3557 const uint8_t *rhs_bytes = rhs;
3558 uint16_t byte_offset = 0;
3559 uint16_t remaining_bytes = zig_int_bytes(bits);
3560 (void)is_signed;
3561
3562 while (remaining_bytes >= 128 / CHAR_BIT) {
3563 zig_u128 res_limb;
3564 zig_u128 lhs_limb;
3565 zig_u128 rhs_limb;
3566
3567 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3568 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3569 res_limb = zig_or_u128(lhs_limb, rhs_limb);
3570 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3571
3572 remaining_bytes -= 128 / CHAR_BIT;
3573 byte_offset += 128 / CHAR_BIT;
3574 }
3575
3576 while (remaining_bytes >= 64 / CHAR_BIT) {
3577 uint64_t res_limb;
3578 uint64_t lhs_limb;
3579 uint64_t rhs_limb;
3580
3581 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3582 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3583 res_limb = zig_or_u64(lhs_limb, rhs_limb);
3584 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3585
3586 remaining_bytes -= 64 / CHAR_BIT;
3587 byte_offset += 64 / CHAR_BIT;
3588 }
3589
3590 while (remaining_bytes >= 32 / CHAR_BIT) {
3591 uint32_t res_limb;
3592 uint32_t lhs_limb;
3593 uint32_t rhs_limb;
3594
3595 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3596 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3597 res_limb = zig_or_u32(lhs_limb, rhs_limb);
3598 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3599
3600 remaining_bytes -= 32 / CHAR_BIT;
3601 byte_offset += 32 / CHAR_BIT;
3602 }
3603
3604 while (remaining_bytes >= 16 / CHAR_BIT) {
3605 uint16_t res_limb;
3606 uint16_t lhs_limb;
3607 uint16_t rhs_limb;
3608
3609 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3610 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3611 res_limb = zig_or_u16(lhs_limb, rhs_limb);
3612 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3613
3614 remaining_bytes -= 16 / CHAR_BIT;
3615 byte_offset += 16 / CHAR_BIT;
3616 }
27243617
27253618 while (remaining_bytes >= 8 / CHAR_BIT) {
27263619 uint8_t res_limb;
......@@ -2811,9 +3704,411 @@ static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool
28113704 res_limb = zig_xor_u8(lhs_limb, rhs_limb);
28123705 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
28133706
2814 remaining_bytes -= 8 / CHAR_BIT;
2815 byte_offset += 8 / CHAR_BIT;
2816 }
3707 remaining_bytes -= 8 / CHAR_BIT;
3708 byte_offset += 8 / CHAR_BIT;
3709 }
3710}
3711
3712static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) {
3713 uint8_t *res_bytes = res;
3714 uint16_t byte_offset = 0;
3715 uint16_t remaining_bytes = zig_int_bytes(bits);
3716 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3717
3718#if zig_big_endian
3719 byte_offset = remaining_bytes;
3720#endif
3721
3722 while (remaining_bytes >= 128 / CHAR_BIT) {
3723 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3724
3725#if zig_big_endian
3726 byte_offset -= 128 / CHAR_BIT;
3727#endif
3728
3729 {
3730 zig_u128 res_limb;
3731 bool limb_overflow;
3732
3733 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3734 limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3735 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3736 if (!limb_overflow) return;
3737 }
3738
3739 remaining_bytes -= 128 / CHAR_BIT;
3740
3741#if zig_little_endian
3742 byte_offset += 128 / CHAR_BIT;
3743#endif
3744 }
3745
3746 while (remaining_bytes >= 64 / CHAR_BIT) {
3747 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3748
3749#if zig_big_endian
3750 byte_offset -= 64 / CHAR_BIT;
3751#endif
3752
3753 {
3754 uint64_t res_limb;
3755 bool limb_overflow;
3756
3757 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3758 limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3759 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3760 if (!limb_overflow) return;
3761 }
3762
3763 remaining_bytes -= 64 / CHAR_BIT;
3764
3765#if zig_little_endian
3766 byte_offset += 64 / CHAR_BIT;
3767#endif
3768 }
3769
3770 while (remaining_bytes >= 32 / CHAR_BIT) {
3771 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3772
3773#if zig_big_endian
3774 byte_offset -= 32 / CHAR_BIT;
3775#endif
3776
3777 {
3778 uint32_t res_limb;
3779 bool limb_overflow;
3780
3781 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3782 limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3783 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3784 if (!limb_overflow) return;
3785 }
3786
3787 remaining_bytes -= 32 / CHAR_BIT;
3788
3789#if zig_little_endian
3790 byte_offset += 32 / CHAR_BIT;
3791#endif
3792 }
3793
3794 while (remaining_bytes >= 16 / CHAR_BIT) {
3795 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3796
3797#if zig_big_endian
3798 byte_offset -= 16 / CHAR_BIT;
3799#endif
3800
3801 {
3802 uint16_t res_limb;
3803 bool limb_overflow;
3804
3805 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3806 limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3807 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3808 if (!limb_overflow) return;
3809 }
3810
3811 remaining_bytes -= 16 / CHAR_BIT;
3812
3813#if zig_little_endian
3814 byte_offset += 16 / CHAR_BIT;
3815#endif
3816 }
3817
3818 while (remaining_bytes >= 8 / CHAR_BIT) {
3819 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3820
3821#if zig_big_endian
3822 byte_offset -= 8 / CHAR_BIT;
3823#endif
3824
3825 {
3826 uint8_t res_limb;
3827 bool limb_overflow;
3828
3829 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3830 limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3831 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3832 if (!limb_overflow) return;
3833 }
3834
3835 remaining_bytes -= 8 / CHAR_BIT;
3836
3837#if zig_little_endian
3838 byte_offset += 8 / CHAR_BIT;
3839#endif
3840 }
3841}
3842
3843static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) {
3844 uint8_t *res_bytes = res;
3845 uint16_t byte_offset = 0;
3846 uint16_t remaining_bytes = zig_int_bytes(bits);
3847 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3848
3849#if zig_big_endian
3850 byte_offset = remaining_bytes;
3851#endif
3852
3853 while (remaining_bytes >= 128 / CHAR_BIT) {
3854 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3855
3856#if zig_big_endian
3857 byte_offset -= 128 / CHAR_BIT;
3858#endif
3859
3860 {
3861 zig_u128 res_limb;
3862 bool limb_overflow;
3863
3864 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3865 limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3866 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3867 if (!limb_overflow) return;
3868 }
3869
3870 remaining_bytes -= 128 / CHAR_BIT;
3871
3872#if zig_little_endian
3873 byte_offset += 128 / CHAR_BIT;
3874#endif
3875 }
3876
3877 while (remaining_bytes >= 64 / CHAR_BIT) {
3878 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3879
3880#if zig_big_endian
3881 byte_offset -= 64 / CHAR_BIT;
3882#endif
3883
3884 {
3885 uint64_t res_limb;
3886 bool limb_overflow;
3887
3888 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3889 limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3890 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3891 if (!limb_overflow) return;
3892 }
3893
3894 remaining_bytes -= 64 / CHAR_BIT;
3895
3896#if zig_little_endian
3897 byte_offset += 64 / CHAR_BIT;
3898#endif
3899 }
3900
3901 while (remaining_bytes >= 32 / CHAR_BIT) {
3902 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3903
3904#if zig_big_endian
3905 byte_offset -= 32 / CHAR_BIT;
3906#endif
3907
3908 {
3909 uint32_t res_limb;
3910 bool limb_overflow;
3911
3912 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3913 limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3914 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3915 if (!limb_overflow) return;
3916 }
3917
3918 remaining_bytes -= 32 / CHAR_BIT;
3919
3920#if zig_little_endian
3921 byte_offset += 32 / CHAR_BIT;
3922#endif
3923 }
3924
3925 while (remaining_bytes >= 16 / CHAR_BIT) {
3926 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3927
3928#if zig_big_endian
3929 byte_offset -= 16 / CHAR_BIT;
3930#endif
3931
3932 {
3933 uint16_t res_limb;
3934 bool limb_overflow;
3935
3936 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3937 limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3938 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3939 if (!limb_overflow) return;
3940 }
3941
3942 remaining_bytes -= 16 / CHAR_BIT;
3943
3944#if zig_little_endian
3945 byte_offset += 16 / CHAR_BIT;
3946#endif
3947 }
3948
3949 while (remaining_bytes >= 8 / CHAR_BIT) {
3950 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3951
3952#if zig_big_endian
3953 byte_offset -= 8 / CHAR_BIT;
3954#endif
3955
3956 {
3957 uint8_t res_limb;
3958 bool limb_overflow;
3959
3960 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3961 limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3962 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3963 if (!limb_overflow) return;
3964 }
3965
3966 remaining_bytes -= 8 / CHAR_BIT;
3967
3968#if zig_little_endian
3969 byte_offset += 8 / CHAR_BIT;
3970#endif
3971 }
3972}
3973
3974static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3975 uint8_t *res_bytes = res;
3976 const uint8_t *arg_bytes = arg;
3977 uint16_t byte_offset = 0;
3978 uint16_t remaining_bytes = zig_int_bytes(bits);
3979 if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) {
3980 memcpy(res, arg, remaining_bytes);
3981 return;
3982 }
3983 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3984 bool overflow = true;
3985
3986#if zig_big_endian
3987 byte_offset = remaining_bytes;
3988#endif
3989
3990 while (remaining_bytes >= 128 / CHAR_BIT) {
3991 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3992
3993#if zig_big_endian
3994 byte_offset -= 128 / CHAR_BIT;
3995#endif
3996
3997 {
3998 zig_u128 res_limb;
3999 zig_u128 arg_limb;
4000
4001 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4002 overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4003 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4004 }
4005
4006 remaining_bytes -= 128 / CHAR_BIT;
4007
4008#if zig_little_endian
4009 byte_offset += 128 / CHAR_BIT;
4010#endif
4011 }
4012
4013 while (remaining_bytes >= 64 / CHAR_BIT) {
4014 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4015
4016#if zig_big_endian
4017 byte_offset -= 64 / CHAR_BIT;
4018#endif
4019
4020 {
4021 uint64_t res_limb;
4022 uint64_t arg_limb;
4023
4024 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4025 overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4026 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4027 }
4028
4029 remaining_bytes -= 64 / CHAR_BIT;
4030
4031#if zig_little_endian
4032 byte_offset += 64 / CHAR_BIT;
4033#endif
4034 }
4035
4036 while (remaining_bytes >= 32 / CHAR_BIT) {
4037 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4038
4039#if zig_big_endian
4040 byte_offset -= 32 / CHAR_BIT;
4041#endif
4042
4043 {
4044 uint32_t res_limb;
4045 uint32_t arg_limb;
4046
4047 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4048 overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4049 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4050 }
4051
4052 remaining_bytes -= 32 / CHAR_BIT;
4053
4054#if zig_little_endian
4055 byte_offset += 32 / CHAR_BIT;
4056#endif
4057 }
4058
4059 while (remaining_bytes >= 16 / CHAR_BIT) {
4060 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4061
4062#if zig_big_endian
4063 byte_offset -= 16 / CHAR_BIT;
4064#endif
4065
4066 {
4067 uint16_t res_limb;
4068 uint16_t arg_limb;
4069
4070 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4071 overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4072 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4073 }
4074
4075 remaining_bytes -= 16 / CHAR_BIT;
4076
4077#if zig_little_endian
4078 byte_offset += 16 / CHAR_BIT;
4079#endif
4080 }
4081
4082 while (remaining_bytes >= 8 / CHAR_BIT) {
4083 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4084
4085#if zig_big_endian
4086 byte_offset -= 8 / CHAR_BIT;
4087#endif
4088
4089 {
4090 uint8_t res_limb;
4091 uint8_t arg_limb;
4092
4093 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4094 overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4095 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4096 }
4097
4098 remaining_bytes -= 8 / CHAR_BIT;
4099
4100#if zig_little_endian
4101 byte_offset += 8 / CHAR_BIT;
4102#endif
4103 }
4104}
4105
4106static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4107 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4108}
4109
4110static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4111 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
28174112}
28184113
28194114static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
......@@ -2822,7 +4117,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
28224117 const uint8_t *rhs_bytes = rhs;
28234118 uint16_t byte_offset = 0;
28244119 uint16_t remaining_bytes = zig_int_bytes(bits);
2825 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);
4120 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
28264121 bool overflow = false;
28274122
28284123#if zig_big_endian
......@@ -3038,7 +4333,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
30384333 const uint8_t *rhs_bytes = rhs;
30394334 uint16_t byte_offset = 0;
30404335 uint16_t remaining_bytes = zig_int_bytes(bits);
3041 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);
4336 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
30424337 bool overflow = false;
30434338
30444339#if zig_big_endian
......@@ -3238,218 +4533,890 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
32384533 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
32394534 }
32404535
3241 remaining_bytes -= 8 / CHAR_BIT;
4536 remaining_bytes -= 8 / CHAR_BIT;
4537
4538#if zig_little_endian
4539 byte_offset += 8 / CHAR_BIT;
4540#endif
4541 }
4542
4543 return overflow;
4544}
4545
4546static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4547 if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4548}
4549
4550static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4551 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);
4552}
4553
4554static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4555 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits);
4556
4557 if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return;
4558 switch (sat_sign) {
4559 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4560 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4561 }
4562}
4563
4564static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4565 if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4566}
4567
4568static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4569 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
4570}
4571
4572static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4573 int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1);
4574
4575 if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return;
4576 switch (sat_sign) {
4577 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4578 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4579 }
4580}
4581
4582static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4583 uint8_t *res_bytes = res;
4584 const uint8_t *lhs_bytes = lhs;
4585 const uint8_t *rhs_bytes = rhs;
4586 uint16_t size = zig_int_bytes(bits);
4587 uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4588 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4589 uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8));
4590 uint16_t lhs_byte_offset = sign_byte_offset;
4591 uint16_t lhs_end_byte_offset = UINT16_C(0);
4592 bool overflow = false;
4593
4594#if zig_big_endian
4595 lhs_byte_offset = size - lhs_byte_offset;
4596 lhs_end_byte_offset = size - lhs_end_byte_offset;
4597#endif
4598
4599 while (lhs_byte_offset != lhs_end_byte_offset) {
4600 uint16_t rhs_byte_offset = UINT16_C(0);
4601 uint16_t end_byte_offset = sign_byte_offset;
4602 uint16_t res_byte_offset;
4603 uint16_t lhs_byte;
4604 uint8_t res_byte = UINT8_C(0);
4605 uint16_t mul_res = UINT16_C(0);
4606 uint8_t carry = UINT8_C(0);
4607
4608#if zig_little_endian
4609 lhs_byte_offset -= UINT16_C(1);
4610#else
4611 rhs_byte_offset = size - rhs_byte_offset;
4612 end_byte_offset = size - end_byte_offset;
4613#endif
4614
4615 lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill;
4616
4617#if zig_big_endian
4618 lhs_byte_offset += UINT16_C(1);
4619#endif
4620
4621 res_byte_offset = lhs_byte_offset;
4622
4623 while (res_byte_offset != end_byte_offset) {
4624 bool res_byte_initialized = res_byte_offset != lhs_byte_offset;
4625
4626#if zig_big_endian
4627 rhs_byte_offset -= UINT16_C(1);
4628 res_byte_offset -= UINT16_C(1);
4629#endif
4630
4631 if (res_byte_initialized) res_byte = res_bytes[res_byte_offset];
4632 carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8));
4633 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16(
4634 zig_shr_u16(mul_res, UINT8_C(8))
4635 ), UINT8_C(8));
4636 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4637 carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16(
4638 mul_res,
4639 UINT8_C(8)
4640 ), UINT8_C(8));
4641
4642#if zig_little_endian
4643 rhs_byte_offset += UINT16_C(1);
4644 res_byte_offset += UINT16_C(1);
4645#endif
4646 }
4647
4648 while (rhs_byte_offset != end_byte_offset) {
4649#if zig_big_endian
4650 rhs_byte_offset -= UINT16_C(1);
4651#endif
4652
4653 carry = zig_addo_u8(
4654 &res_byte,
4655 zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))),
4656 carry,
4657 UINT8_C(8)
4658 );
4659 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4660 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16(
4661 mul_res,
4662 UINT8_C(8)
4663 ), UINT8_C(8));
4664 overflow |= res_byte != UINT8_C(0);
4665
4666#if zig_little_endian
4667 rhs_byte_offset += UINT16_C(1);
4668#endif
4669 }
4670
4671 overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0);
4672 overflow |= carry != UINT8_C(0);
4673 }
4674
4675#if zig_little_endian
4676 sign_byte_offset -= UINT64_C(1);
4677#else
4678 sign_byte_offset = size - sign_byte_offset;
4679#endif
4680
4681 if (lhs_sign_fill != rhs_sign_fill) {
4682 uint16_t byte_offset = UINT16_C(0);
4683 uint16_t end_byte_offset = sign_byte_offset;
4684 uint8_t res_byte;
4685 int8_t signed_res_byte;
4686 uint8_t carry = UINT8_C(0);
4687
4688#if zig_big_endian
4689 byte_offset = size - byte_offset;
4690 end_byte_offset += UINT16_C(1);
4691#endif
4692
4693 while (byte_offset != end_byte_offset) {
4694#if zig_big_endian
4695 byte_offset -= UINT16_C(1);
4696#endif
4697
4698 carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8));
4699 carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8));
4700 carry += zig_subo_u8(
4701 &res_bytes[byte_offset],
4702 res_byte,
4703 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4704 UINT8_C(8)
4705 );
4706
4707#if zig_little_endian
4708 byte_offset += UINT16_C(1);
4709#endif
4710 }
4711
4712#if zig_big_endian
4713 byte_offset -= UINT16_C(1);
4714#endif
4715
4716 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4717 overflow |= signed_res_byte < INT8_C(0);
4718 overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8));
4719 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4720 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4721 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4722 UINT8_C(8)
4723 ), UINT8_C(8));
4724 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4725 } else if (lhs_sign_fill != UINT8_C(0)) {
4726 uint16_t byte_offset = UINT16_C(0);
4727 uint16_t end_byte_offset = sign_byte_offset;
4728 uint8_t res_byte;
4729 int8_t signed_res_byte;
4730 uint8_t carry = UINT8_C(1);
4731
4732#if zig_big_endian
4733 byte_offset = size - byte_offset;
4734 end_byte_offset += UINT16_C(1);
4735#endif
4736
4737 while (byte_offset != end_byte_offset) {
4738#if zig_big_endian
4739 byte_offset -= UINT16_C(1);
4740#endif
4741
4742 carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8));
4743 carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8));
4744 carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8));
4745
4746#if zig_little_endian
4747 byte_offset += UINT16_C(1);
4748#endif
4749 }
4750
4751#if zig_big_endian
4752 byte_offset -= UINT16_C(1);
4753#endif
4754
4755 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4756 overflow |= signed_res_byte < INT8_C(0);
4757 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4758 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4759 lhs_bytes[byte_offset],
4760 UINT8_C(8)
4761 ), UINT8_C(8));
4762 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4763 rhs_bytes[byte_offset],
4764 UINT8_C(8)
4765 ), UINT8_C(8));
4766 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4767 } else if (is_signed) {
4768 int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4769
4770 overflow |= signed_res_byte < INT8_C(0);
4771 }
4772
4773 {
4774 uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4775 uint8_t fill_byte = UINT8_C(0);
4776
4777 if (is_signed) {
4778 int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4779 int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits);
4780
4781 overflow |= sign_byte != truncated;
4782 res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
4783 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
4784 } else {
4785 uint8_t sign_byte = res_bytes[sign_byte_offset];
4786 uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits);
4787
4788 overflow |= sign_byte != truncated;
4789 res_bytes[sign_byte_offset] = truncated;
4790 }
4791
4792#if zig_little_endian
4793 sign_byte_offset += UINT16_C(1);
4794 memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset);
4795#else
4796 memset(&res_bytes[0], fill_byte, sign_byte_offset);
4797#endif
4798 }
4799
4800 return overflow;
4801}
4802
4803static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4804 if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4805}
4806
4807static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4808 (void)zig_mulo_big(res, lhs, rhs, is_signed, bits);
4809}
4810
4811static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4812 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits);
4813
4814 if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return;
4815 switch (sat_sign) {
4816 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4817 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4818 }
4819}
4820
4821static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4822 if (is_signed) {
4823 zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4824 __divei5(res, lhs, rhs, temp, bits);
4825 } else {
4826 zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4827 __udivei5(res, lhs, rhs, temp, bits);
4828 }
4829}
4830
4831static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4832 if (is_signed) {
4833 zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4834 __modei5(res, lhs, rhs, temp, bits);
4835 } else {
4836 zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4837 __umodei5(res, lhs, rhs, temp, bits);
4838 }
4839}
4840
4841static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4842 bool decrement = false;
4843
4844 if (is_signed) {
4845 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4846 decrement = zig_u32_bitCast_i32(zig_xor_i32(
4847 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4848 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4849 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32));
4850 }
4851 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4852 if (decrement) zig_decrement_big(res, is_signed, bits);
4853}
4854
4855static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4856 bool increment = false;
4857
4858 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4859 increment = zig_xor_i32(
4860 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4861 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4862 ) > INT32_C(0);
4863 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4864 if (increment) zig_increment_big(res, is_signed, bits);
4865}
4866
4867static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4868 bool fixup = false;
4869
4870 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4871 if (is_signed && zig_u32_bitCast_i32(zig_xor_i32(
4872 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4873 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4874 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits);
4875}
4876
4877static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4878 uint8_t *res_bytes = res;
4879 const uint8_t *lhs_bytes = lhs;
4880 uint16_t size = zig_int_bytes(bits);
4881 uint16_t res_byte_offset = UINT16_C(0);
4882 uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3));
4883 uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4884 uint8_t lhs_prev_byte;
4885 uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3));
4886
4887#if zig_big_endian
4888 res_byte_offset = size - res_byte_offset;
4889 lhs_byte_offset = size - lhs_byte_offset;
4890 end_byte_offset = size - end_byte_offset;
4891#endif
4892
4893 {
4894#if zig_big_endian
4895 lhs_byte_offset -= UINT16_C(1);
4896#endif
4897
4898 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4899
4900#if zig_little_endian
4901 lhs_byte_offset += UINT16_C(1);
4902#endif
4903 }
4904
4905 while (lhs_byte_offset != end_byte_offset) {
4906#if zig_big_endian
4907 res_byte_offset -= UINT16_C(1);
4908 lhs_byte_offset -= UINT16_C(1);
4909#endif
4910
4911 {
4912 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
4913
4914 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
4915 zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)),
4916 zig_u16_intCast_u8(lhs_prev_byte)
4917 ), byte_shift));
4918 lhs_prev_byte = lhs_byte;
4919 }
4920
4921#if zig_little_endian
4922 res_byte_offset += UINT16_C(1);
4923 lhs_byte_offset += UINT16_C(1);
4924#endif
4925 }
4926
4927 {
4928 uint8_t lhs_sign_fill = UINT8_C(0);
4929
4930#if zig_big_endian
4931 res_byte_offset -= UINT16_C(1);
4932#endif
4933
4934 if (is_signed) {
4935 int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8));
4936
4937 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
4938 lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
4939 } else {
4940 res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift);
4941 }
4942
4943#if zig_little_endian
4944 res_byte_offset += UINT16_C(1);
4945 memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset);
4946#else
4947 memset(&res_bytes[0], lhs_sign_fill, res_byte_offset);
4948#endif
4949 }
4950}
4951
4952static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4953 uint8_t *res_bytes = res;
4954 const uint8_t *lhs_bytes = lhs;
4955 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4956 uint16_t size = zig_int_bytes(bits);
4957 uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4958 uint16_t lhs_byte_offset = UINT16_C(0);
4959 uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3));
4960 uint8_t lhs_prev_byte = lhs_sign_fill;
4961 uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3));
4962 bool overflow = false;
4963
4964#if zig_little_endian
4965 lhs_byte_offset = size - lhs_byte_offset;
4966#else
4967 res_byte_offset = size - res_byte_offset;
4968 end_byte_offset = size - end_byte_offset;
4969#endif
4970
4971 while (lhs_byte_offset != end_byte_offset) {
4972#if zig_little_endian
4973 lhs_byte_offset -= UINT16_C(1);
4974#endif
4975
4976 overflow |= lhs_prev_byte != lhs_sign_fill;
4977 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4978
4979#if zig_big_endian
4980 lhs_byte_offset += UINT16_C(1);
4981#endif
4982 }
4983
4984#if zig_little_endian
4985 end_byte_offset = UINT16_C(0);
4986#else
4987 end_byte_offset = size;
4988#endif
4989
4990 {
4991 bool lhs_more_bytes = lhs_byte_offset != end_byte_offset;
4992
4993#if zig_little_endian
4994 if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1);
4995#endif
4996
4997 {
4998 uint8_t lhs_byte = UINT8_C(0);
4999
5000 if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset];
5001
5002 if (is_signed) {
5003 int16_t shifted = zig_shr_i16(zig_or_i16(
5004 zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5005 zig_i16_intCast_u8(lhs_byte)
5006 ), byte_shift);
5007 int8_t truncated = zig_i8_truncate_i16(
5008 shifted,
5009 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5010 );
5011 uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
5012
5013 overflow |= zig_i16_intCast_i8(truncated) != shifted;
5014#if zig_little_endian
5015 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5016 res_byte_offset -= UINT16_C(1);
5017#else
5018 memset(&res_bytes[0], fill, res_byte_offset);
5019#endif
5020 res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
5021 } else {
5022 uint16_t shifted = zig_shr_u16(zig_or_u16(
5023 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5024 zig_u16_intCast_u8(lhs_byte)
5025 ), byte_shift);
5026 uint8_t truncated = zig_u8_truncate_u16(
5027 shifted,
5028 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5029 );
5030
5031 overflow |= zig_u16_intCast_u8(truncated) != shifted;
5032#if zig_little_endian
5033 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5034 res_byte_offset -= UINT16_C(1);
5035#else
5036 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5037#endif
5038 res_bytes[res_byte_offset] = truncated;
5039 }
5040
5041 lhs_prev_byte = lhs_byte;
5042 }
5043
5044#if zig_big_endian
5045 res_byte_offset += UINT16_C(1);
5046 if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1);
5047#endif
5048 }
5049
5050 while (lhs_byte_offset != end_byte_offset) {
5051#if zig_little_endian
5052 res_byte_offset -= UINT16_C(1);
5053 lhs_byte_offset -= UINT16_C(1);
5054#endif
5055
5056 {
5057 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
5058
5059 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5060 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5061 zig_u16_intCast_u8(lhs_byte)
5062 ), byte_shift));
5063 lhs_prev_byte = lhs_byte;
5064 }
5065
5066#if zig_big_endian
5067 res_byte_offset += UINT16_C(1);
5068 lhs_byte_offset += UINT16_C(1);
5069#endif
5070 }
5071
5072 {
5073#if zig_little_endian
5074 res_byte_offset -= UINT16_C(1);
5075#endif
5076
5077 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(
5078 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5079 byte_shift
5080 ));
5081
5082#if zig_big_endian
5083 res_byte_offset += UINT16_C(1);
5084#endif
5085 }
5086
5087#if zig_little_endian
5088 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5089#else
5090 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5091#endif
5092
5093 return overflow;
5094}
5095
5096static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5097 if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits
5098}
5099
5100static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5101 (void)zig_shlo_big(res, lhs, rhs, is_signed, bits);
5102}
5103
5104#define zig_big_shls_builtin(w) \
5105 static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \
5106 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5107 uint##w##_t res; \
5108 const uint8_t *rhs_bytes = rhs; \
5109 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5110 !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5111 return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \
5112 } \
5113\
5114 static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \
5115 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5116 int##w##_t res; \
5117 const uint8_t *rhs_bytes = rhs; \
5118 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5119 !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5120 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
5121 lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \
5122 } \
5123\
5124 static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \
5125 const uint8_t *lhs_bytes = lhs; \
5126 if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \
5127 switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \
5128 case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \
5129 case INT32_C(0): return zig_minInt_big(res, false, bits); \
5130 case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \
5131 default: zig_unreachable(); \
5132 } \
5133 }
5134zig_big_shls_builtin(8)
5135zig_big_shls_builtin(16)
5136zig_big_shls_builtin(32)
5137zig_big_shls_builtin(64)
5138
5139static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5140 uint8_t *res_bytes = res;
5141 const uint8_t *arg_bytes = arg;
5142 uint16_t res_byte_offset = UINT16_C(0);
5143 uint16_t arg_byte_offset = bits / CHAR_BIT;
5144 uint16_t end_byte_offset = UINT16_C(1);
5145 uint16_t size = zig_int_bytes(bits);
5146
5147#if zig_big_endian
5148 res_byte_offset = size - res_byte_offset;
5149 arg_byte_offset = size - arg_byte_offset;
5150 end_byte_offset = size - end_byte_offset;
5151#endif
32425152
5153 while (arg_byte_offset != end_byte_offset) {
32435154#if zig_little_endian
3244 byte_offset += 8 / CHAR_BIT;
5155 arg_byte_offset -= UINT16_C(1);
5156#else
5157 res_byte_offset -= UINT16_C(1);
5158#endif
5159
5160 res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset];
5161
5162#if zig_little_endian
5163 res_byte_offset += UINT16_C(1);
5164#else
5165 arg_byte_offset += UINT16_C(1);
32455166#endif
32465167 }
32475168
3248 return overflow;
3249}
5169 {
5170#if zig_little_endian
5171 arg_byte_offset -= UINT16_C(1);
5172#else
5173 res_byte_offset -= UINT16_C(1);
5174#endif
32505175
3251static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3252 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);
3253}
5176 {
5177 uint8_t byte = arg_bytes[arg_byte_offset];
5178 uint8_t fill = is_signed
5179 ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8))
5180 : UINT8_C(0);
32545181
3255static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3256 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
3257}
5182 res_bytes[res_byte_offset] = byte;
32585183
3259zig_extern void __udivei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);
3260static inline void zig_div_trunc_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3261 if (!is_signed) {
3262 __udivei4(res, lhs, rhs, bits);
3263 return;
5184#if zig_little_endian
5185 res_byte_offset += UINT16_C(1);
5186 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5187#else
5188 memset(&res_bytes[0], fill, res_byte_offset);
5189#endif
5190 }
32645191 }
3265
3266 zig_trap();
32675192}
32685193
3269static inline void zig_div_floor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3270 if (!is_signed) {
3271 zig_div_trunc_big(res, lhs, rhs, is_signed, bits);
3272 return;
3273 }
5194static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5195 uint8_t *res_bytes = res;
5196 const uint8_t *arg_bytes = arg;
5197 uint16_t size = zig_int_bytes(bits);
5198 uint16_t res_byte_offset = UINT16_C(0);
5199 uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5200 uint16_t end_byte_offset = UINT16_C(0);
5201 uint8_t arg_prev_byte;
5202 uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3)));
32745203
3275 zig_trap();
3276}
5204#if zig_big_endian
5205 res_byte_offset = size - res_byte_offset;
5206 arg_byte_offset = size - arg_byte_offset;
5207 end_byte_offset = size - end_byte_offset;
5208#endif
32775209
3278static inline void zig_div_ceil_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3279 zig_trap();
3280}
5210 {
5211#if zig_little_endian
5212 arg_byte_offset -= UINT16_C(1);
5213#endif
32815214
3282zig_extern void __umodei4(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uintptr_t bits);
3283static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3284 if (!is_signed) {
3285 __umodei4(res, lhs, rhs, bits);
3286 return;
5215 arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
5216
5217#if zig_big_endian
5218 arg_byte_offset += UINT16_C(1);
5219#endif
32875220 }
32885221
3289 zig_trap();
3290}
5222 while (arg_byte_offset != end_byte_offset) {
5223#if zig_big_endian
5224 res_byte_offset -= UINT16_C(1);
5225#else
5226 arg_byte_offset -= UINT16_C(1);
5227#endif
32915228
3292static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3293 if (!is_signed) {
3294 zig_rem_big(res, lhs, rhs, is_signed, bits);
3295 return;
5229 {
5230 uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
5231
5232 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5233 zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)),
5234 zig_u16_intCast_u8(arg_prev_byte)
5235 ), byte_shift));
5236 arg_prev_byte = arg_byte;
5237 }
5238
5239#if zig_little_endian
5240 res_byte_offset += UINT16_C(1);
5241#else
5242 arg_byte_offset += UINT16_C(1);
5243#endif
32965244 }
32975245
3298 zig_trap();
5246 {
5247 uint8_t arg_sign_fill = UINT8_C(0);
5248
5249#if zig_big_endian
5250 res_byte_offset -= UINT16_C(1);
5251#endif
5252
5253 if (is_signed) {
5254 int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8));
5255
5256 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
5257 arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
5258 } else {
5259 res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift);
5260 }
5261
5262#if zig_little_endian
5263 res_byte_offset += UINT16_C(1);
5264 memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset);
5265#else
5266 memset(&res_bytes[0], arg_sign_fill, res_byte_offset);
5267#endif
5268 }
32995269}
33005270
3301static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) {
3302 const uint8_t *val_bytes = val;
5271static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) {
5272 const uint8_t *arg_bytes = arg;
33035273 uint16_t byte_offset = 0;
3304 uint16_t remaining_bytes = zig_int_bytes(bits);
3305 uint16_t skip_bits = remaining_bytes * 8 - bits;
3306 uint16_t total_lz = 0;
3307 uint16_t limb_lz;
5274 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5275 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5276 uint16_t total_pc = 0;
33085277 (void)is_signed;
33095278
3310#if zig_little_endian
3311 byte_offset = remaining_bytes;
5279#if zig_big_endian
5280 byte_offset = zig_int_bytes(bits);
33125281#endif
33135282
33145283 while (remaining_bytes >= 128 / CHAR_BIT) {
3315#if zig_little_endian
5284 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5285
5286#if zig_big_endian
33165287 byte_offset -= 128 / CHAR_BIT;
33175288#endif
33185289
33195290 {
3320 zig_u128 val_limb;
5291 zig_u128 arg_limb;
33215292
3322 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3323 limb_lz = zig_clz_u128(val_limb, 128 - skip_bits);
5293 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5294 total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
33245295 }
33255296
3326 total_lz += limb_lz;
3327 if (limb_lz < 128 - skip_bits) return total_lz;
3328 skip_bits = 0;
33295297 remaining_bytes -= 128 / CHAR_BIT;
33305298
3331#if zig_big_endian
5299#if zig_little_endian
33325300 byte_offset += 128 / CHAR_BIT;
33335301#endif
33345302 }
33355303
33365304 while (remaining_bytes >= 64 / CHAR_BIT) {
3337#if zig_little_endian
5305 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5306
5307#if zig_big_endian
33385308 byte_offset -= 64 / CHAR_BIT;
33395309#endif
33405310
33415311 {
3342 uint64_t val_limb;
5312 uint64_t arg_limb;
33435313
3344 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3345 limb_lz = zig_clz_u64(val_limb, 64 - skip_bits);
5314 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5315 total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
33465316 }
33475317
3348 total_lz += limb_lz;
3349 if (limb_lz < 64 - skip_bits) return total_lz;
3350 skip_bits = 0;
33515318 remaining_bytes -= 64 / CHAR_BIT;
33525319
3353#if zig_big_endian
5320#if zig_little_endian
33545321 byte_offset += 64 / CHAR_BIT;
33555322#endif
33565323 }
33575324
33585325 while (remaining_bytes >= 32 / CHAR_BIT) {
3359#if zig_little_endian
5326 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5327
5328#if zig_big_endian
33605329 byte_offset -= 32 / CHAR_BIT;
33615330#endif
33625331
33635332 {
3364 uint32_t val_limb;
5333 uint32_t arg_limb;
33655334
3366 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3367 limb_lz = zig_clz_u32(val_limb, 32 - skip_bits);
5335 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5336 total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
33685337 }
33695338
3370 total_lz += limb_lz;
3371 if (limb_lz < 32 - skip_bits) return total_lz;
3372 skip_bits = 0;
33735339 remaining_bytes -= 32 / CHAR_BIT;
33745340
3375#if zig_big_endian
5341#if zig_little_endian
33765342 byte_offset += 32 / CHAR_BIT;
33775343#endif
33785344 }
33795345
33805346 while (remaining_bytes >= 16 / CHAR_BIT) {
3381#if zig_little_endian
5347 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5348
5349#if zig_big_endian
33825350 byte_offset -= 16 / CHAR_BIT;
33835351#endif
33845352
33855353 {
3386 uint16_t val_limb;
5354 uint16_t arg_limb;
33875355
3388 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3389 limb_lz = zig_clz_u16(val_limb, 16 - skip_bits);
5356 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5357 total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
33905358 }
33915359
3392 total_lz += limb_lz;
3393 if (limb_lz < 16 - skip_bits) return total_lz;
3394 skip_bits = 0;
33955360 remaining_bytes -= 16 / CHAR_BIT;
33965361
3397#if zig_big_endian
5362#if zig_little_endian
33985363 byte_offset += 16 / CHAR_BIT;
33995364#endif
34005365 }
34015366
34025367 while (remaining_bytes >= 8 / CHAR_BIT) {
3403#if zig_little_endian
5368 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5369
5370#if zig_big_endian
34045371 byte_offset -= 8 / CHAR_BIT;
34055372#endif
34065373
34075374 {
3408 uint8_t val_limb;
5375 uint8_t arg_limb;
34095376
3410 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3411 limb_lz = zig_clz_u8(val_limb, 8 - skip_bits);
5377 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5378 total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
34125379 }
34135380
3414 total_lz += limb_lz;
3415 if (limb_lz < 8 - skip_bits) return total_lz;
3416 skip_bits = 0;
34175381 remaining_bytes -= 8 / CHAR_BIT;
34185382
3419#if zig_big_endian
5383#if zig_little_endian
34205384 byte_offset += 8 / CHAR_BIT;
34215385#endif
34225386 }
34235387
3424 return total_lz;
5388 return total_pc;
34255389}
34265390
3427static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) {
3428 const uint8_t *val_bytes = val;
3429 uint16_t byte_offset = 0;
3430 uint16_t remaining_bytes = zig_int_bytes(bits);
3431 uint16_t total_tz = 0;
5391static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) {
5392 const uint8_t *arg_bytes = arg;
5393 uint16_t byte_offset = UINT16_C(0);
5394 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5395 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5396 uint16_t total_tz = UINT16_C(0);
34325397 uint16_t limb_tz;
34335398 (void)is_signed;
34345399
34355400#if zig_big_endian
3436 byte_offset = remaining_bytes;
5401 byte_offset = zig_int_bytes(bits);
34375402#endif
34385403
34395404 while (remaining_bytes >= 128 / CHAR_BIT) {
5405 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5406
34405407#if zig_big_endian
34415408 byte_offset -= 128 / CHAR_BIT;
34425409#endif
34435410
34445411 {
3445 zig_u128 val_limb;
5412 zig_u128 arg_limb;
34465413
3447 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3448 limb_tz = zig_ctz_u128(val_limb, 128);
5414 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5415 limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
34495416 }
34505417
34515418 total_tz += limb_tz;
3452 if (limb_tz < 128) return total_tz;
5419 if (limb_tz < limb_bits) return total_tz;
34535420 remaining_bytes -= 128 / CHAR_BIT;
34545421
34555422#if zig_little_endian
......@@ -3458,19 +5425,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
34585425 }
34595426
34605427 while (remaining_bytes >= 64 / CHAR_BIT) {
5428 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5429
34615430#if zig_big_endian
34625431 byte_offset -= 64 / CHAR_BIT;
34635432#endif
34645433
34655434 {
3466 uint64_t val_limb;
5435 uint64_t arg_limb;
34675436
3468 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3469 limb_tz = zig_ctz_u64(val_limb, 64);
5437 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5438 limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
34705439 }
34715440
34725441 total_tz += limb_tz;
3473 if (limb_tz < 64) return total_tz;
5442 if (limb_tz < limb_bits) return total_tz;
34745443 remaining_bytes -= 64 / CHAR_BIT;
34755444
34765445#if zig_little_endian
......@@ -3479,19 +5448,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
34795448 }
34805449
34815450 while (remaining_bytes >= 32 / CHAR_BIT) {
5451 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5452
34825453#if zig_big_endian
34835454 byte_offset -= 32 / CHAR_BIT;
34845455#endif
34855456
34865457 {
3487 uint32_t val_limb;
5458 uint32_t arg_limb;
34885459
3489 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3490 limb_tz = zig_ctz_u32(val_limb, 32);
5460 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5461 limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
34915462 }
34925463
34935464 total_tz += limb_tz;
3494 if (limb_tz < 32) return total_tz;
5465 if (limb_tz < limb_bits) return total_tz;
34955466 remaining_bytes -= 32 / CHAR_BIT;
34965467
34975468#if zig_little_endian
......@@ -3500,19 +5471,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
35005471 }
35015472
35025473 while (remaining_bytes >= 16 / CHAR_BIT) {
5474 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5475
35035476#if zig_big_endian
35045477 byte_offset -= 16 / CHAR_BIT;
35055478#endif
35065479
35075480 {
3508 uint16_t val_limb;
5481 uint16_t arg_limb;
35095482
3510 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3511 limb_tz = zig_ctz_u16(val_limb, 16);
5483 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5484 limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
35125485 }
35135486
35145487 total_tz += limb_tz;
3515 if (limb_tz < 16) return total_tz;
5488 if (limb_tz < limb_bits) return total_tz;
35165489 remaining_bytes -= 16 / CHAR_BIT;
35175490
35185491#if zig_little_endian
......@@ -3521,19 +5494,21 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
35215494 }
35225495
35235496 while (remaining_bytes >= 8 / CHAR_BIT) {
5497 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5498
35245499#if zig_big_endian
35255500 byte_offset -= 8 / CHAR_BIT;
35265501#endif
35275502
35285503 {
3529 uint8_t val_limb;
5504 uint8_t arg_limb;
35305505
3531 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3532 limb_tz = zig_ctz_u8(val_limb, 8);
5506 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5507 limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
35335508 }
35345509
35355510 total_tz += limb_tz;
3536 if (limb_tz < 8) return total_tz;
5511 if (limb_tz < limb_bits) return total_tz;
35375512 remaining_bytes -= 8 / CHAR_BIT;
35385513
35395514#if zig_little_endian
......@@ -3544,113 +5519,141 @@ static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bit
35445519 return total_tz;
35455520}
35465521
3547static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) {
3548 const uint8_t *val_bytes = val;
3549 uint16_t byte_offset = 0;
3550 uint16_t remaining_bytes = zig_int_bytes(bits);
3551 uint16_t total_pc = 0;
5522static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) {
5523 const uint8_t *arg_bytes = arg;
5524 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5525 uint16_t remaining_bytes = byte_offset;
5526 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5527 bool sign_limb = true;
5528 uint16_t total_lz = UINT16_C(0);
5529 uint16_t limb_lz;
35525530 (void)is_signed;
35535531
35545532#if zig_big_endian
3555 byte_offset = remaining_bytes;
5533 byte_offset = zig_int_bytes(bits) - remaining_bytes;
35565534#endif
35575535
35585536 while (remaining_bytes >= 128 / CHAR_BIT) {
3559#if zig_big_endian
5537 uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0));
5538
5539#if zig_little_endian
35605540 byte_offset -= 128 / CHAR_BIT;
35615541#endif
35625542
35635543 {
3564 zig_u128 val_limb;
5544 zig_u128 arg_limb;
35655545
3566 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3567 total_pc += zig_popcount_u128(val_limb, 128);
5546 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5547 limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
35685548 }
35695549
5550 total_lz += limb_lz;
5551 if (limb_lz < limb_bits) return total_lz;
5552 sign_limb = false;
35705553 remaining_bytes -= 128 / CHAR_BIT;
35715554
3572#if zig_little_endian
5555#if zig_big_endian
35735556 byte_offset += 128 / CHAR_BIT;
35745557#endif
35755558 }
35765559
35775560 while (remaining_bytes >= 64 / CHAR_BIT) {
3578#if zig_big_endian
5561 uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0));
5562
5563#if zig_little_endian
35795564 byte_offset -= 64 / CHAR_BIT;
35805565#endif
35815566
35825567 {
3583 uint64_t val_limb;
5568 uint64_t arg_limb;
35845569
3585 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3586 total_pc += zig_popcount_u64(val_limb, 64);
5570 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5571 limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
35875572 }
35885573
5574 total_lz += limb_lz;
5575 if (limb_lz < limb_bits) return total_lz;
5576 sign_limb = false;
35895577 remaining_bytes -= 64 / CHAR_BIT;
35905578
3591#if zig_little_endian
5579#if zig_big_endian
35925580 byte_offset += 64 / CHAR_BIT;
35935581#endif
35945582 }
35955583
35965584 while (remaining_bytes >= 32 / CHAR_BIT) {
3597#if zig_big_endian
5585 uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0));
5586
5587#if zig_little_endian
35985588 byte_offset -= 32 / CHAR_BIT;
35995589#endif
36005590
36015591 {
3602 uint32_t val_limb;
5592 uint32_t arg_limb;
36035593
3604 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3605 total_pc += zig_popcount_u32(val_limb, 32);
5594 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5595 limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
36065596 }
36075597
5598 total_lz += limb_lz;
5599 if (limb_lz < limb_bits) return total_lz;
5600 sign_limb = false;
36085601 remaining_bytes -= 32 / CHAR_BIT;
36095602
3610#if zig_little_endian
5603#if zig_big_endian
36115604 byte_offset += 32 / CHAR_BIT;
36125605#endif
36135606 }
36145607
36155608 while (remaining_bytes >= 16 / CHAR_BIT) {
3616#if zig_big_endian
5609 uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0));
5610
5611#if zig_little_endian
36175612 byte_offset -= 16 / CHAR_BIT;
36185613#endif
36195614
36205615 {
3621 uint16_t val_limb;
5616 uint16_t arg_limb;
36225617
3623 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3624 total_pc = zig_popcount_u16(val_limb, 16);
5618 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5619 limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
36255620 }
36265621
5622 total_lz += limb_lz;
5623 if (limb_lz < limb_bits) return total_lz;
5624 sign_limb = false;
36275625 remaining_bytes -= 16 / CHAR_BIT;
36285626
3629#if zig_little_endian
5627#if zig_big_endian
36305628 byte_offset += 16 / CHAR_BIT;
36315629#endif
36325630 }
36335631
36345632 while (remaining_bytes >= 8 / CHAR_BIT) {
3635#if zig_big_endian
5633 uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0));
5634
5635#if zig_little_endian
36365636 byte_offset -= 8 / CHAR_BIT;
36375637#endif
36385638
36395639 {
3640 uint8_t val_limb;
5640 uint8_t arg_limb;
36415641
3642 memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb));
3643 total_pc = zig_popcount_u8(val_limb, 8);
5642 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5643 limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
36445644 }
36455645
5646 total_lz += limb_lz;
5647 if (limb_lz < limb_bits) return total_lz;
5648 sign_limb = false;
36465649 remaining_bytes -= 8 / CHAR_BIT;
36475650
3648#if zig_little_endian
5651#if zig_big_endian
36495652 byte_offset += 8 / CHAR_BIT;
36505653#endif
36515654 }
36525655
3653 return total_pc;
5656 return total_lz;
36545657}
36555658
36565659/* ========================= Floating Point Support ========================= */
......@@ -3687,29 +5690,29 @@ long double __cdecl nanl(char const* input);
36875690#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
36885691#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
36895692#else
3690#define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr)
3691#define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr)
3692#define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr)
3693#define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr)
3694#define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr)
5693#define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr)
5694#define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr)
5695#define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr)
5696#define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr)
5697#define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr)
36955698#endif
36965699
36975700#define zig_has_f16 1
36985701#define zig_libc_name_f16(name) __##name##h
36995702#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
3700#if FLT_MANT_DIG == 11
5703#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11
37015704typedef float zig_f16;
37025705#define zig_make_f16(fp, repr) fp##f
3703#elif DBL_MANT_DIG == 11
5706#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11
37045707typedef double zig_f16;
37055708#define zig_make_f16(fp, repr) fp
3706#elif LDBL_MANT_DIG == 11
5709#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11
37075710typedef long double zig_f16;
37085711#define zig_make_f16(fp, repr) fp##l
3709#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
5712#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
37105713typedef _Float16 zig_f16;
37115714#define zig_make_f16(fp, repr) fp##f16
3712#elif defined(__SIZEOF_FP16__)
5715#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__)
37135716typedef __fp16 zig_f16;
37145717#define zig_make_f16(fp, repr) fp##f16
37155718#else
......@@ -3723,11 +5726,6 @@ typedef uint16_t zig_f16;
37235726#undef zig_init_special_f16
37245727#define zig_init_special_f16(sign, name, arg, repr) repr
37255728#endif
3726#if defined(zig_darwin) && defined(zig_x86)
3727typedef uint16_t zig_compiler_rt_f16;
3728#else
3729typedef zig_f16 zig_compiler_rt_f16;
3730#endif
37315729
37325730#define zig_has_f32 1
37335731#define zig_libc_name_f32(name) name##f
......@@ -3736,16 +5734,16 @@ typedef zig_f16 zig_compiler_rt_f16;
37365734#else
37375735#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)
37385736#endif
3739#if FLT_MANT_DIG == 24
5737#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24
37405738typedef float zig_f32;
37415739#define zig_make_f32(fp, repr) fp##f
3742#elif DBL_MANT_DIG == 24
5740#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24
37435741typedef double zig_f32;
37445742#define zig_make_f32(fp, repr) fp
3745#elif LDBL_MANT_DIG == 24
5743#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24
37465744typedef long double zig_f32;
37475745#define zig_make_f32(fp, repr) fp##l
3748#elif FLT32_MANT_DIG == 24
5746#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24
37495747typedef _Float32 zig_f32;
37505748#define zig_make_f32(fp, repr) fp##f32
37515749#else
......@@ -3768,19 +5766,19 @@ typedef uint32_t zig_f32;
37685766#else
37695767#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
37705768#endif
3771#if FLT_MANT_DIG == 53
5769#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53
37725770typedef float zig_f64;
37735771#define zig_make_f64(fp, repr) fp##f
3774#elif DBL_MANT_DIG == 53
5772#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53
37755773typedef double zig_f64;
37765774#define zig_make_f64(fp, repr) fp
3777#elif LDBL_MANT_DIG == 53
5775#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53
37785776typedef long double zig_f64;
37795777#define zig_make_f64(fp, repr) fp##l
3780#elif FLT64_MANT_DIG == 53
5778#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53
37815779typedef _Float64 zig_f64;
37825780#define zig_make_f64(fp, repr) fp##f64
3783#elif FLT32X_MANT_DIG == 53
5781#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53
37845782typedef _Float32x zig_f64;
37855783#define zig_make_f64(fp, repr) fp##f32x
37865784#else
......@@ -3798,7 +5796,14 @@ typedef uint64_t zig_f64;
37985796#define zig_has_f80 1
37995797#define zig_libc_name_f80(name) __##name##x
38005798#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
3801#if FLT_MANT_DIG == 64
5799#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI
5800#undef zig_has_f80
5801typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80;
5802#define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent }
5803#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5804#define zig_mantissa_repr_f80(arg) (arg).mantissa
5805#define zig_exponent_repr_f80(arg) (arg).exponent
5806#elif FLT_MANT_DIG == 64
38025807typedef float zig_f80;
38035808#define zig_make_f80(fp, repr) fp##f
38045809#elif DBL_MANT_DIG == 64
......@@ -3818,10 +5823,18 @@ typedef __float80 zig_f80;
38185823#define zig_make_f80(fp, repr) fp##l
38195824#else
38205825#undef zig_has_f80
3821#define zig_has_f80 0
3822#define zig_repr_f80 u128
38235826typedef zig_u128 zig_f80;
5827#define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa)
5828#define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa)
5829#define zig_mantissa_repr_f80(arg) zig_lo_u128(arg)
5830#define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg)
5831#endif
5832#ifndef zig_has_f80
5833#define zig_has_f80 0
38245834#define zig_make_f80(fp, repr) repr
5835#ifndef zig_make_repr_f80
5836#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5837#endif
38255838#undef zig_make_special_f80
38265839#define zig_make_special_f80(sign, name, arg, repr) repr
38275840#undef zig_init_special_f80
......@@ -3833,11 +5846,20 @@ typedef zig_u128 zig_f80;
38335846#else
38345847#define zig_f128_has_miscompilations 0
38355848#endif
3836
38375849#define zig_has_f128 1
38385850#define zig_libc_name_f128(name) name##f128
38395851#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3840#if !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
5852#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI
5853#undef zig_has_f128
5854#if zig_little_endian
5855typedef struct { uint64_t lo, hi; } zig_f128;
5856#else
5857typedef struct { uint64_t hi, lo; } zig_f128;
5858#endif
5859#define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo }
5860#define zig_lo_repr_f128(arg) (arg).lo
5861#define zig_hi_repr_f128(arg) (arg).hi
5862#elif !zig_f128_has_miscompilations && FLT_MANT_DIG == 113
38415863typedef float zig_f128;
38425864#define zig_make_f128(fp, repr) fp##f
38435865#elif !zig_f128_has_miscompilations && DBL_MANT_DIG == 113
......@@ -3859,27 +5881,38 @@ typedef __float128 zig_f128;
38595881#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)
38605882#else
38615883#undef zig_has_f128
3862#define zig_has_f128 0
3863#undef zig_make_special_f128
3864#undef zig_init_special_f128
3865#if defined(zig_darwin) || defined(zig_aarch64)
3866typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;
3867zig_basic_operator(zig_v2u64, xor_v2u64, ^)
3868#define zig_repr_f128 v2u64
3869typedef zig_v2u64 zig_f128;
3870#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }
3871#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128
3872#define zig_make_f128(fp, repr) zig_make_f128_##repr
3873#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3874#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3875#else
3876#define zig_repr_f128 u128
5884#if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC)
5885#if defined(zig_msvc) && !defined(__clang__)
5886#include <emmintrin.h>
5887typedef __m128i zig_f128;
5888#define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } }
5889#define zig_lo_repr_f128(arg) (arg).m128i_u64[0]
5890#define zig_hi_repr_f128(arg) (arg).m128i_u64[1]
5891#else
5892typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128;
5893#define zig_init_repr_f128(hi, lo) { lo, hi }
5894#define zig_lo_repr_f128(arg) (arg)[0]
5895#define zig_hi_repr_f128(arg) (arg)[1]
5896#endif
5897#else
38775898typedef zig_u128 zig_f128;
5899#define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo)
5900#define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo)
5901#define zig_lo_repr_f128(arg) zig_lo_u128(arg)
5902#define zig_hi_repr_f128(arg) zig_hi_u128(arg)
5903#endif
5904#endif
5905#ifndef zig_has_f128
5906#define zig_has_f128 0
38785907#define zig_make_f128(fp, repr) repr
5908#ifndef zig_make_repr_f128
5909#define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo)
5910#endif
5911#undef zig_make_special_f128
38795912#define zig_make_special_f128(sign, name, arg, repr) repr
5913#undef zig_init_special_f128
38805914#define zig_init_special_f128(sign, name, arg, repr) repr
38815915#endif
3882#endif
38835916
38845917#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)
38855918/* Emulate msvc abi on a gnu compiler */
......@@ -3892,84 +5925,141 @@ typedef zig_f128 zig_c_longdouble;
38925925typedef long double zig_c_longdouble;
38935926#endif
38945927
3895#define zig_bitCast_float(Type, ReprType) \
3896 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \
3897 zig_##Type result; \
3898 memcpy(&result, &repr, sizeof(result)); \
3899 return result; \
5928#if __AVR__
5929typedef signed char zig_FloatCompareResult;
5930#elif defined(zig_aarch64)
5931typedef signed int zig_FloatCompareResult;
5932#elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__
5933typedef signed long zig_FloatCompareResult;
5934#else
5935typedef signed long long zig_FloatCompareResult;
5936#endif
5937
5938#define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \
5939 static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \
5940 zig_f##w res; \
5941 memcpy(&res, &arg, sizeof(zig_f##w)); \
5942 return res; \
5943 } \
5944 static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \
5945 zig_f##w res; \
5946 memcpy(&res, &arg, sizeof(zig_f##w)); \
5947 return res; \
5948 } \
5949 static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \
5950 UnsignedReprType res; \
5951 memcpy(&res, &arg, sizeof(zig_f##w)); \
5952 return zig_u##iw##_truncate_u##iw(res, w); \
5953 } \
5954 static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \
5955 SignedReprType res; \
5956 memcpy(&res, &arg, sizeof(zig_f##w)); \
5957 return zig_i##iw##_truncate_i##iw(res, w); \
39005958 }
3901zig_bitCast_float(f16, uint16_t)
3902zig_bitCast_float(f32, uint32_t)
3903zig_bitCast_float(f64, uint64_t)
3904zig_bitCast_float(f80, zig_u128)
3905zig_bitCast_float(f128, zig_u128)
5959zig_bitCast_float(16, 16, uint16_t, int16_t)
5960zig_bitCast_float(32, 32, uint32_t, int32_t)
5961zig_bitCast_float(64, 64, uint64_t, int64_t)
5962#if zig_has_f80
5963zig_bitCast_float(80, 128, zig_u128, zig_i128)
5964#else
5965static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) {
5966 return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg));
5967}
5968static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) {
5969 return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg));
5970}
5971static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) {
5972 return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5973}
5974static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) {
5975 return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5976}
5977#endif
5978static inline zig_f80 zig_f80_bitCast_big(const void *arg) {
5979 return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80)));
5980}
5981static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) {
5982 if (res_is_signed) {
5983 zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits);
5984 } else {
5985 zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits);
5986 }
5987}
5988#if zig_has_f128
5989zig_bitCast_float(128, 128, zig_u128, zig_i128)
5990#else
5991static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) {
5992 return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg));
5993}
5994static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) {
5995 return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg));
5996}
5997static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) {
5998 return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5999}
6000static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) {
6001 return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
6002}
6003#endif
39066004
3907#define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \
3908 zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3909 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \
6005#define zig_convert_float_00(ResType, operation, ArgType, version) \
6006 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6007 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \
6008 return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6009 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg)
6010#define zig_convert_float_01(ResType, operation, ArgType, version) \
6011 zig_convert_float_00(ResType, operation, ArgType, version)
6012#define zig_convert_float_10(ResType, operation, ArgType, version) \
6013 zig_convert_float_00(ResType, operation, ArgType, version)
6014#define zig_convert_float_11(ResType, operation, ArgType, version) \
6015 return (ResType)arg
6016#define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \
39106017 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
39116018 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
3912 ResType res; \
3913 ExternResType extern_res; \
3914 ExternArgType extern_arg; \
3915 memcpy(&extern_arg, &arg, sizeof(extern_arg)); \
3916 extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3917 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \
3918 memcpy(&res, &extern_res, sizeof(res)); \
3919 return extern_res; \
3920 }
3921zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)
3922zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)
3923zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)
3924zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)
3925zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)
3926zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)
3927zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)
3928zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)
3929zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)
3930zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)
3931zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)
3932zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)
3933zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)
3934zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3935zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3936zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3937zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3938zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2)
3939
3940#ifdef __ARM_EABI__
3941
3942zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_d2f(zig_f64);
3943static inline zig_f32 zig_truncdfsf(zig_f64 arg) { return __aeabi_d2f(arg); }
3944
3945zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_f2d(zig_f32);
3946static inline zig_f64 zig_extendsfdf(zig_f32 arg) { return __aeabi_f2d(arg); }
3947
3948#else /* __ARM_EABI__ */
3949
3950zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3951zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3952
3953#endif /* __ARM_EABI__ */
3954
3955#define zig_float_negate_builtin_0(w, c, sb) \
3956 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb))
3957#define zig_float_negate_builtin_1(w, c, sb) -arg
3958#define zig_float_negate_builtin(w, c, sb) \
6019 zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \
6020 zig_has_##arg_when)(ResType, operation, ArgType, version); \
6021 }
6022
6023#define zig_convert_floats(SmallType, BigType) \
6024 zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \
6025 zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2)
6026zig_convert_floats(f16, f32)
6027zig_convert_floats(f16, f64)
6028zig_convert_floats(f16, f80)
6029zig_convert_floats(f16, f128)
6030zig_convert_floats(f32, f64)
6031zig_convert_floats(f32, f80)
6032zig_convert_floats(f32, f128)
6033zig_convert_floats(f64, f80)
6034zig_convert_floats(f64, f128)
6035zig_convert_floats(f80, f128)
6036
6037#define zig_float_negate_builtin_0(w, sb) \
6038 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb))
6039#define zig_float_negate_builtin_1(w, sb) -arg
6040#define zig_float_negate_builtin(w, sb) \
39596041 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3960 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \
6042 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \
39616043 }
3962zig_float_negate_builtin(16, , UINT16_C(1) << 15 )
3963zig_float_negate_builtin(32, , UINT32_C(1) << 31 )
3964zig_float_negate_builtin(64, , UINT64_C(1) << 63 )
3965zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))
3966zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
6044zig_float_negate_builtin(16, UINT16_C(1) << 15)
6045zig_float_negate_builtin(32, UINT32_C(1) << 31)
6046zig_float_negate_builtin(64, UINT64_C(1) << 63)
6047
6048#undef zig_float_negate_builtin_0
6049#define zig_float_negate_builtin_0(w, sb) \
6050 zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb))
6051zig_float_negate_builtin(80, UINT16_C(1) << 15)
6052
6053#undef zig_float_negate_builtin_0
6054#define zig_float_negate_builtin_0(w, sb) \
6055 zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg))
6056zig_float_negate_builtin(128, UINT64_C(1) << 63)
39676057
39686058#define zig_float_less_builtin_0(Type, operation) \
3969 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \
6059 zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \
39706060 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \
39716061 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
3972 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \
6062 return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \
39736063 }
39746064#define zig_float_less_builtin_1(Type, operation) \
39756065 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
......@@ -3994,13 +6084,52 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
39946084 return lhs operator rhs; \
39956085 }
39966086
6087#define zig_float_builtins(w) \
6088 zig_common_float_builtins(w) \
6089 zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \
6090 zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, )
39976091#define zig_common_float_builtins(w) \
3998 zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \
3999 zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \
4000 zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \
4001 zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \
4002 zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \
4003 zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \
6092 zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \
6093 zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \
6094 zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \
6095 zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \
6096 zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \
6097 zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \
6098 zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \
6099 zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \
6100 zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \
6101 zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \
6102\
6103 static inline void zig_expand_concat(zig_expand_concat(zig_fix, \
6104 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6105 zig_extern void zig_expand_concat(zig_expand_concat(__fix, \
6106 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6107 zig_expand_concat(zig_expand_concat(__fix, \
6108 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6109 } \
6110\
6111 static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \
6112 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6113 zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \
6114 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6115 zig_expand_concat(zig_expand_concat(__fixuns, \
6116 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6117 } \
6118\
6119 static inline zig_f##w zig_expand_concat(zig_floatei, \
6120 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6121 zig_extern zig_f##w zig_expand_concat(__floatei, \
6122 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6123 return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6124 } \
6125\
6126 static inline zig_f##w zig_expand_concat(zig_floatunei, \
6127 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6128 zig_extern zig_f##w zig_expand_concat(__floatunei, \
6129 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6130 return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6131 } \
6132\
40046133 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
40056134 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
40066135 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
......@@ -4031,82 +6160,48 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
40316160 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
40326161 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
40336162\
4034 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
6163 static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
40356164 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \
40366165 } \
40376166\
4038 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \
6167 static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \
40396168 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \
40406169 } \
40416170\
4042 static inline zig_f##w zig_div_ceil_f##w(zig_f##w lhs, zig_f##w rhs) { \
6171 static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \
40436172 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \
40446173 } \
40456174\
40466175 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
4047 return zig_sub_f##w(lhs, zig_mul_f##w(zig_div_floor_f##w(lhs, rhs), rhs)); \
6176 return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \
40486177 }
4049zig_common_float_builtins(16)
4050zig_common_float_builtins(32)
4051zig_common_float_builtins(64)
4052zig_common_float_builtins(80)
4053zig_common_float_builtins(128)
4054
4055#define zig_float_builtins(w) \
4056 zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \
4057 zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \
4058 zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \
4059 zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \
4060 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \
4061 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, )
40626178zig_float_builtins(16)
4063zig_float_builtins(80)
4064zig_float_builtins(128)
4065
4066#ifdef __ARM_EABI__
4067
4068zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_f2iz(zig_f32);
4069static inline int32_t zig_fixsfsi(zig_f32 arg) { return __aeabi_f2iz(arg); }
4070
4071zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_f2uiz(zig_f32);
4072static inline uint32_t zig_fixunssfsi(zig_f32 arg) { return __aeabi_f2uiz(arg); }
4073
4074zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_f2ulz(zig_f32);
4075static inline uint64_t zig_fixunssfdi(zig_f32 arg) { return __aeabi_f2ulz(arg); }
4076
4077zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_i2f(int32_t);
4078static inline zig_f32 zig_floatsisf(int32_t arg) { return __aeabi_i2f(arg); }
4079
4080zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ui2f(uint32_t);
4081static inline zig_f32 zig_floatunsisf(uint32_t arg) { return __aeabi_ui2f(arg); }
4082
4083zig_extern zig_callconv(pcs("aapcs")) zig_f32 __aeabi_ul2f(uint64_t);
4084static inline zig_f32 zig_floatundisf(uint64_t arg) { return __aeabi_ul2f(arg); }
4085
4086zig_extern zig_callconv(pcs("aapcs")) int32_t __aeabi_d2iz(zig_f64);
4087static inline int32_t zig_fixdfsi(zig_f64 arg) { return __aeabi_d2iz(arg); }
4088
4089zig_extern zig_callconv(pcs("aapcs")) uint32_t __aeabi_d2uiz(zig_f64);
4090static inline uint32_t zig_fixunsdfsi(zig_f64 arg) { return __aeabi_d2uiz(arg); }
4091
4092zig_extern zig_callconv(pcs("aapcs")) uint64_t __aeabi_d2ulz(zig_f64);
4093static inline uint64_t zig_fixunsdfdi(zig_f64 arg) { return __aeabi_d2ulz(arg); }
4094
4095zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_i2d(int32_t);
4096static inline zig_f64 zig_floatsidf(int32_t arg) { return __aeabi_i2d(arg); }
4097
4098zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ui2d(uint32_t);
4099static inline zig_f64 zig_floatunsidf(uint32_t arg) { return __aeabi_ui2d(arg); }
4100
4101zig_extern zig_callconv(pcs("aapcs")) zig_f64 __aeabi_ul2d(uint64_t);
4102static inline zig_f64 zig_floatundidf(uint64_t arg) { return __aeabi_ul2d(arg); }
4103
4104#else /* __ARM_EABI__ */
4105
41066179zig_float_builtins(32)
41076180zig_float_builtins(64)
4108
4109#endif /* __ARM_EABI__ */
6181zig_float_builtins(80)
6182#if defined(zig_x86_32)
6183zig_common_float_builtins(128)
6184static inline zig_f128 zig_floattitf(zig_i128 arg) {
6185 extern zig_f128 __floattitf(zig_f128 arg);
6186 return __floattitf(zig_f128_bitCast_i128(arg));
6187}
6188static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6189 extern zig_f128 __floatuntitf(zig_f128 arg);
6190 return __floatuntitf(zig_f128_bitCast_u128(arg));
6191}
6192#elif defined(zig_x86_64) && defined(zig_windows)
6193zig_common_float_builtins(128)
6194static inline zig_f128 zig_floattitf(zig_i128 arg) {
6195 extern zig_f128 __floattitf(zig_i128 arg);
6196 return __floattitf(arg);
6197}
6198static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6199 extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi);
6200 return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg));
6201}
6202#else
6203zig_float_builtins(128)
6204#endif
41106205
41116206/* ============================ Atomics Support ============================= */
41126207
......@@ -4410,19 +6505,19 @@ typedef int zig_memory_order;
44106505 } \
44116506 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
44126507 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
4413 } \
6508 } \
44146509 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \
44156510 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
44166511 } \
44176512 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \
4418 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6513 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
44196514 _ReadWriteBarrier(); \
4420 return val; \
6515 return value; \
44216516 } \
44226517 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \
4423 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6518 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
44246519 _ReadWriteBarrier(); \
4425 return val; \
6520 return value; \
44266521 }
44276522
44286523zig_msvc_atomics( u8, uint8_t, char, 8, 8)
......@@ -4465,14 +6560,14 @@ zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
44656560 zig_##Type result; \
44666561 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
44676562 _ReadWriteBarrier(); \
4468 memcpy(&result, &initial, sizeof(result)); \
6563 memcpy(&result, &initial, sizeof(result)); \
44696564 return result; \
44706565 } \
44716566 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \
44726567 zig_##Type result; \
44736568 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
44746569 _ReadWriteBarrier(); \
4475 memcpy(&result, &initial, sizeof(result)); \
6570 memcpy(&result, &initial, sizeof(result)); \
44766571 return result; \
44776572 }
44786573
......@@ -4502,9 +6597,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volat
45026597}
45036598
45046599static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {
4505 void* val = (void*)__iso_volatile_load32(obj);
6600 void* value = (void*)__iso_volatile_load32(obj);
45066601 _ReadWriteBarrier();
4507 return val;
6602 return value;
45086603}
45096604
45106605static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {
......@@ -4532,9 +6627,9 @@ static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volat
45326627}
45336628
45346629static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {
4535 void* val = (void*)__iso_volatile_load64(obj);
6630 void* value = (void*)__iso_volatile_load64(obj);
45366631 _ReadWriteBarrier();
4537 return val;
6632 return value;
45386633}
45396634
45406635static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {
src/codegen/c.zig+704-503
......@@ -164,7 +164,8 @@ const BlockData = struct {
164164
165165const LocalType = struct {
166166 type: Type,
167 alignment: Alignment,
167 alignment: Alignment = .none,
168 array_len: u2 = 1,
168169};
169170
170171const LocalIndex = u16;
......@@ -184,13 +185,11 @@ const ValueRenderLocation = enum {
184185 }
185186};
186187
187const BuiltinInfo = enum { none, bits };
188const BuiltinInfo = enum { none, bits, bits_none, big_temp_bits };
188189
189190const reserved_idents = std.StaticStringMap(void).initComptime(.{
190191 // C language
191 .{ "alignas", {
192 @setEvalBranchQuota(4000);
193 } },
192 .{ "alignas", {} },
194193 .{ "alignof", {} },
195194 .{ "asm", {} },
196195 .{ "atomic_bool", {} },
......@@ -302,7 +301,100 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
302301 // stddef.h
303302 .{ "offsetof", {} },
304303
304 // math.h (only symbols exported by compiler-rt)
305 .{ "ceil", {} },
306 .{ "ceilf", {} },
307 .{ "ceilf128", {} },
308 .{ "ceill", {} },
309 .{ "cos", {} },
310 .{ "cosf", {} },
311 .{ "cosf128", {} },
312 .{ "cosl", {} },
313 .{ "exp", {} },
314 .{ "exp2", {} },
315 .{ "exp2f", {} },
316 .{ "exp2f128", {} },
317 .{ "exp2l", {} },
318 .{ "expf", {} },
319 .{ "expf128", {} },
320 .{ "expl", {} },
321 .{ "fabs", {} },
322 .{ "fabsf", {} },
323 .{ "fabsf128", {} },
324 .{ "fabsl", {} },
325 .{ "floor", {} },
326 .{ "floorf", {} },
327 .{ "floorf128", {} },
328 .{ "floorl", {} },
329 .{ "fma", {} },
330 .{ "fmaf", {} },
331 .{ "fmaf128", {} },
332 .{ "fmal", {} },
333 .{ "fmax", {} },
334 .{ "fmaxf", {} },
335 .{ "fmaxf128", {} },
336 .{ "fmaxl", {} },
337 .{ "fmin", {} },
338 .{ "fminf", {} },
339 .{ "fminf128", {} },
340 .{ "fminl", {} },
341 .{ "fmod", {} },
342 .{ "fmodf", {} },
343 .{ "fmodf128", {} },
344 .{ "fmodl", {} },
345 .{ "log", {} },
346 .{ "log10", {} },
347 .{ "log10f", {} },
348 .{ "log10f128", {} },
349 .{ "log10l", {} },
350 .{ "log2", {} },
351 .{ "log2f", {} },
352 .{ "log2f128", {} },
353 .{ "log2l", {} },
354 .{ "logf", {} },
355 .{ "logf128", {} },
356 .{ "logl", {} },
357 .{ "round", {} },
358 .{ "roundf", {} },
359 .{ "roundf128", {} },
360 .{ "roundl", {} },
361 .{ "sin", {} },
362 .{ "sincos", {} },
363 .{ "sincosf", {} },
364 .{ "sincosf128", {} },
365 .{ "sincosl", {} },
366 .{ "sinf", {} },
367 .{ "sinf128", {} },
368 .{ "sinl", {} },
369 .{ "sqrt", {} },
370 .{ "sqrtf", {} },
371 .{ "sqrtf128", {} },
372 .{ "sqrtl", {} },
373 .{ "tan", {} },
374 .{ "tanf", {} },
375 .{ "tanf128", {} },
376 .{ "tanl", {} },
377 .{ "trunc", {} },
378 .{ "truncf", {} },
379 .{ "truncf128", {} },
380 .{ "truncl", {} },
381
305382 // windows.h
383 .{"DUMMYSTRUCTNAME"},
384 .{"DUMMYSTRUCTNAME2"},
385 .{"DUMMYSTRUCTNAME3"},
386 .{"DUMMYSTRUCTNAME4"},
387 .{"DUMMYSTRUCTNAME5"},
388 .{"DUMMYSTRUCTNAME6"},
389 .{"DUMMYUNIONNAME"},
390 .{"DUMMYUNIONNAME2"},
391 .{"DUMMYUNIONNAME3"},
392 .{"DUMMYUNIONNAME4"},
393 .{"DUMMYUNIONNAME5"},
394 .{"DUMMYUNIONNAME6"},
395 .{"DUMMYUNIONNAME7"},
396 .{"DUMMYUNIONNAME8"},
397 .{"DUMMYUNIONNAME9"},
306398 .{ "max", {} },
307399 .{ "min", {} },
308400});
......@@ -316,13 +408,6 @@ fn isReservedIdent(ident: []const u8) bool {
316408 }
317409 }
318410
319 // windows.h
320 if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or
321 mem.startsWith(u8, ident, "DUMMYUNIONNAME"))
322 {
323 return true;
324 }
325
326411 // CType
327412 if (mem.startsWith(u8, ident, "enum__") or
328413 mem.startsWith(u8, ident, "bitpack__") or
......@@ -469,10 +554,7 @@ pub const Function = struct {
469554 }
470555
471556 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
472 return f.allocAlignedLocal(inst, .{
473 .type = ty,
474 .alignment = .none,
475 });
557 return f.allocAlignedLocal(inst, .{ .type = ty });
476558 }
477559
478560 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should
......@@ -564,10 +646,6 @@ pub const Function = struct {
564646 return f.dg.renderType(w, ty);
565647 }
566648
567 fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
568 return f.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
569 }
570
571649 fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
572650 return f.dg.fmtIntLiteralDec(val, .other);
573651 }
......@@ -672,7 +750,9 @@ pub const DeclGen = struct {
672750 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
673751 const ptr_ty: Type = .fromInterned(uav.orig_ty);
674752 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
675 return dg.renderUndefValue(w, ptr_ty, location);
753 try w.writeByte('(');
754 try dg.renderOpvPointer(w, ptr_ty, location);
755 return w.writeByte(')');
676756 }
677757
678758 switch (ip.indexToKey(uav.val)) {
......@@ -737,8 +817,10 @@ pub const DeclGen = struct {
737817 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
738818 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type);
739819 const ptr_ty = try pt.navPtrType(owner_nav);
740 if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
741 return dg.renderUndefValue(w, ptr_ty, location);
820 if (nav_ty.zigTypeTag(zcu) != .@"opaque" and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
821 try w.writeByte('(');
822 try dg.renderOpvPointer(w, ptr_ty, location);
823 return w.writeByte(')');
742824 }
743825
744826 // We shouldn't cast C function pointers as this is UB (when you call
......@@ -758,6 +840,26 @@ pub const DeclGen = struct {
758840 if (need_cast) try w.writeByte(')');
759841 }
760842
843 fn renderOpvPointer(
844 dg: *DeclGen,
845 w: *Writer,
846 ptr_ty: Type,
847 location: ValueRenderLocation,
848 ) Error!void {
849 const zcu = dg.pt.zcu;
850 const target = zcu.getTarget();
851 try w.writeByte('(');
852 try dg.renderType(w, ptr_ty);
853 return w.print("){f}", .{fmtUnsignedIntLiteralSmall(
854 target,
855 .uintptr_t,
856 ptr_ty.ptrAlignment(zcu).forward(undefPattern(u64) >> @intCast(64 - target.ptrBitWidth())),
857 location == .static_initializer,
858 16,
859 .lower,
860 )});
861 }
862
761863 fn renderPointer(
762864 dg: *DeclGen,
763865 w: *Writer,
......@@ -959,9 +1061,6 @@ pub const DeclGen = struct {
9591061 const bits = ty.floatBits(target);
9601062 const f128_val = val.toFloat(f128, zcu);
9611063
962 // All unsigned ints matching float types are pre-allocated.
963 const repr_ty = pt.intType(.unsigned, bits) catch unreachable;
964
9651064 assert(bits <= 128);
9661065 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
9671066 var repr_val_big = BigInt.Mutable{
......@@ -971,29 +1070,27 @@ pub const DeclGen = struct {
9711070 };
9721071
9731072 switch (bits) {
1073 else => unreachable,
9741074 16 => repr_val_big.set(@as(u16, @bitCast(val.toFloat(f16, zcu)))),
9751075 32 => repr_val_big.set(@as(u32, @bitCast(val.toFloat(f32, zcu)))),
9761076 64 => repr_val_big.set(@as(u64, @bitCast(val.toFloat(f64, zcu)))),
9771077 80 => repr_val_big.set(@as(u80, @bitCast(val.toFloat(f80, zcu)))),
9781078 128 => repr_val_big.set(@as(u128, @bitCast(f128_val))),
979 else => unreachable,
9801079 }
9811080
982 var empty = true;
9831081 if (std.math.isFinite(f128_val)) {
9841082 try w.writeAll("zig_make_");
9851083 try dg.renderTypeForBuiltinFnName(w, ty);
9861084 try w.writeByte('(');
9871085 switch (bits) {
1086 else => unreachable,
9881087 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}),
9891088 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}),
9901089 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}),
9911090 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}),
9921091 128 => try w.print("{x}", .{f128_val}),
993 else => unreachable,
9941092 }
9951093 try w.writeAll(", ");
996 empty = false;
9971094 } else {
9981095 // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan
9991096 const operation = if (std.math.isNan(f128_val))
......@@ -1028,6 +1125,7 @@ pub const DeclGen = struct {
10281125 try w.writeAll(operation);
10291126 try w.writeAll(", ");
10301127 if (std.math.isNan(f128_val)) switch (bits) {
1128 else => unreachable,
10311129 // We only actually need to pass the significand, but it will get
10321130 // properly masked anyway, so just pass the whole value.
10331131 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),
......@@ -1035,16 +1133,23 @@ pub const DeclGen = struct {
10351133 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),
10361134 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),
10371135 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),
1038 else => unreachable,
10391136 };
10401137 try w.writeAll(", ");
1041 empty = false;
10421138 }
1043 try w.print("{f}", .{try dg.fmtIntLiteralHex(
1044 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1045 location,
1046 )});
1047 if (!empty) try w.writeByte(')');
1139 switch (bits) {
1140 else => unreachable,
1141 16, 32, 64 => {
1142 // All unsigned ints matching float types are pre-allocated.
1143 const repr_ty = pt.intType(.unsigned, bits) catch unreachable;
1144 try w.print("{f}", .{try dg.fmtIntLiteralHex(
1145 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1146 location,
1147 )});
1148 },
1149 80 => try F80Repr.write(@bitCast(val.toFloat(f80, zcu)), w, target, location == .static_initializer),
1150 128 => try F128Repr.write(@bitCast(f128_val), w, target, location == .static_initializer),
1151 }
1152 try w.writeByte(')');
10481153 },
10491154 .slice => |slice| {
10501155 if (!location.isInitializer()) {
......@@ -1319,22 +1424,29 @@ pub const DeclGen = struct {
13191424 .f128_type,
13201425 => {
13211426 const bits = ty.floatBits(target);
1322 // All unsigned ints matching float types are pre-allocated.
1323 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
13241427
13251428 try w.writeAll("zig_make_");
13261429 try dg.renderTypeForBuiltinFnName(w, ty);
13271430 try w.writeByte('(');
13281431 switch (bits) {
1329 16 => try w.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1330 32 => try w.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1331 64 => try w.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1332 80 => try w.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1333 128 => try w.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
13341432 else => unreachable,
1433 16 => try w.print("{x}", .{undefPattern(f16)}),
1434 32 => try w.print("{x}", .{undefPattern(f32)}),
1435 64 => try w.print("{x}", .{undefPattern(f64)}),
1436 80 => try w.print("{x}", .{undefPattern(f80)}),
1437 128 => try w.print("{x}", .{undefPattern(f128)}),
13351438 }
13361439 try w.writeAll(", ");
1337 try dg.renderUndefValue(w, repr_ty, .other);
1440 switch (bits) {
1441 else => unreachable,
1442 16, 32, 64 => {
1443 // All unsigned ints matching float types are pre-allocated.
1444 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
1445 try dg.renderUndefValue(w, repr_ty, .other);
1446 },
1447 80 => try undefPattern(F80Repr).write(w, target, location == .static_initializer),
1448 128 => try undefPattern(F128Repr).write(w, target, location == .static_initializer),
1449 }
13381450 return w.writeByte(')');
13391451 },
13401452 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),
......@@ -1726,136 +1838,6 @@ pub const DeclGen = struct {
17261838 try w.print("{f}", .{cty.fmtTypeName(zcu)});
17271839 }
17281840
1729 const IntCastContext = union(enum) {
1730 c_value: struct {
1731 f: *Function,
1732 value: CValue,
1733 v: Vectorize,
1734 },
1735 value: struct {
1736 value: Value,
1737 },
1738
1739 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: *Writer, location: ValueRenderLocation) !void {
1740 switch (self.*) {
1741 .c_value => |v| {
1742 try v.f.writeCValue(w, v.value, location);
1743 try v.v.elem(v.f, w);
1744 },
1745 .value => |v| try dg.renderValue(w, v.value, location),
1746 }
1747 }
1748 };
1749 fn intCastIsNoop(dg: *DeclGen, dest_ty: Type, src_ty: Type) bool {
1750 const pt = dg.pt;
1751 const zcu = pt.zcu;
1752 const dest_bits = dest_ty.bitSize(zcu);
1753 const dest_int_info = dest_ty.intInfo(pt.zcu);
1754
1755 const src_is_ptr = src_ty.isPtrAtRuntime(pt.zcu);
1756 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1757 .unsigned => .usize,
1758 .signed => .isize,
1759 } else src_ty;
1760
1761 const src_bits = src_eff_ty.bitSize(zcu);
1762 const src_int_info = if (src_eff_ty.isAbiInt(pt.zcu)) src_eff_ty.intInfo(pt.zcu) else null;
1763 if (dest_bits <= 64 and src_bits <= 64) {
1764 const needs_cast = src_int_info == null or
1765 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
1766 dest_int_info.signedness != src_int_info.?.signedness);
1767 return !needs_cast and !src_is_ptr;
1768 } else return false;
1769 }
1770 /// Renders a cast to an int type, from either an int or a pointer.
1771 ///
1772 /// Some platforms don't have 128 bit integers, so we need to use
1773 /// the zig_make_ and zig_lo_ macros in those cases.
1774 ///
1775 /// | Dest type bits | Src type | Result
1776 /// |------------------|------------------|---------------------------|
1777 /// | < 64 bit integer | pointer | (zig_<dest_ty>)(zig_<u|i>size)src
1778 /// | < 64 bit integer | < 64 bit integer | (zig_<dest_ty>)src
1779 /// | < 64 bit integer | > 64 bit integer | zig_lo(src)
1780 /// | > 64 bit integer | pointer | zig_make_<dest_ty>(0, (zig_<u|i>size)src)
1781 /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
1782 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
1783 fn renderIntCast(
1784 dg: *DeclGen,
1785 w: *Writer,
1786 dest_ty: Type,
1787 context: IntCastContext,
1788 src_ty: Type,
1789 location: ValueRenderLocation,
1790 ) !void {
1791 const pt = dg.pt;
1792 const zcu = pt.zcu;
1793 const dest_bits = dest_ty.bitSize(zcu);
1794 const dest_int_info = dest_ty.intInfo(zcu);
1795
1796 const src_is_ptr = src_ty.isPtrAtRuntime(zcu);
1797 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
1798 .unsigned => .usize,
1799 .signed => .isize,
1800 } else src_ty;
1801
1802 const src_bits = src_eff_ty.bitSize(zcu);
1803 const src_int_info = if (src_eff_ty.isAbiInt(zcu)) src_eff_ty.intInfo(zcu) else null;
1804 if (dest_bits <= 64 and src_bits <= 64) {
1805 const needs_cast = src_int_info == null or
1806 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
1807 dest_int_info.signedness != src_int_info.?.signedness);
1808
1809 if (needs_cast) {
1810 try w.writeByte('(');
1811 try dg.renderType(w, dest_ty);
1812 try w.writeByte(')');
1813 }
1814 if (src_is_ptr) {
1815 try w.writeByte('(');
1816 try dg.renderType(w, src_eff_ty);
1817 try w.writeByte(')');
1818 }
1819 try context.writeValue(dg, w, location);
1820 } else if (dest_bits <= 64 and src_bits > 64) {
1821 assert(!src_is_ptr);
1822 if (dest_bits < 64) {
1823 try w.writeByte('(');
1824 try dg.renderType(w, dest_ty);
1825 try w.writeByte(')');
1826 }
1827 try w.writeAll("zig_lo_");
1828 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1829 try w.writeByte('(');
1830 try context.writeValue(dg, w, .other);
1831 try w.writeByte(')');
1832 } else if (dest_bits > 64 and src_bits <= 64) {
1833 try w.writeAll("zig_make_");
1834 try dg.renderTypeForBuiltinFnName(w, dest_ty);
1835 try w.writeAll("(0, ");
1836 if (src_is_ptr) {
1837 try w.writeByte('(');
1838 try dg.renderType(w, src_eff_ty);
1839 try w.writeByte(')');
1840 }
1841 try context.writeValue(dg, w, .other);
1842 try w.writeByte(')');
1843 } else {
1844 assert(!src_is_ptr);
1845 try w.writeAll("zig_make_");
1846 try dg.renderTypeForBuiltinFnName(w, dest_ty);
1847 try w.writeAll("(zig_hi_");
1848 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1849 try w.writeByte('(');
1850 try context.writeValue(dg, w, .other);
1851 try w.writeAll("), zig_lo_");
1852 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
1853 try w.writeByte('(');
1854 try context.writeValue(dg, w, .other);
1855 try w.writeAll("))");
1856 }
1857 }
1858
18591841 /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type.
18601842 fn renderTypeAndName(
18611843 dg: *DeclGen,
......@@ -2000,6 +1982,7 @@ pub const DeclGen = struct {
20001982 switch (info) {
20011983 .none => if (!is_big) return,
20021984 .bits => {},
1985 .bits_none, .big_temp_bits => unreachable,
20031986 }
20041987
20051988 const int_info: std.lang.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{
......@@ -2056,6 +2039,72 @@ const CQualifiers = packed struct {
20562039 restrict: bool = false,
20572040};
20582041
2042pub fn genHeader(zcu: *Zcu, w: *Writer) !void {
2043 const gpa = zcu.comp.gpa;
2044
2045 var arena: std.heap.ArenaAllocator = .init(gpa);
2046 defer arena.deinit();
2047 var ctype_deps: CType.Dependencies = .empty;
2048 defer ctype_deps.deinit(gpa);
2049
2050 const target = zcu.getTarget();
2051 switch (target.abi) {
2052 .msvc, .itanium => try w.writeAll("#define ZIG_TARGET_ABI_MSVC\n"),
2053 else => {},
2054 }
2055 for ([_]u16{ 16, 32, 64, 80, 128 }) |bits| switch (std.zig.target.compilerRtFloatAbi(target, bits)) {
2056 .hard => {},
2057 .soft => try w.print("#define ZIG_TARGET_SOFT_COMPILER_RT_F{d}_ABI\n", .{bits}),
2058 };
2059 try w.print(
2060 \\#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}
2061 \\#include "zig.h"
2062 \\
2063 \\
2064 ,
2065 .{target.cMaxIntAlignment()},
2066 );
2067
2068 var basic_ty: Type = .fromInterned(.first_type);
2069 while (true) : ({
2070 basic_ty = .fromInterned(@fromBackingInt(@intCast(@backingInt(basic_ty.toIntern()) + 1)));
2071 if (basic_ty.toIntern() == InternPool.Index.last_type) break;
2072 }) {
2073 switch (basic_ty.toIntern()) {
2074 else => {},
2075 .anyframe_type,
2076 .adhoc_inferred_error_set_type,
2077 .generic_poison_type,
2078 => continue, // skip unsupported types
2079 }
2080 const basic_cty: CType = try .lower(basic_ty, &ctype_deps, arena.allocator(), zcu);
2081 switch (basic_cty) {
2082 .void => {}, // no layout to check
2083 .bool,
2084 .int,
2085 .float,
2086 => try CType.render_defs.writeStaticAssertTypeLayout(basic_ty, basic_cty, w, zcu),
2087 .@"fn",
2088 .@"enum",
2089 .bitpack,
2090 .@"struct",
2091 .union_auto,
2092 .union_extern,
2093 .slice,
2094 .opt,
2095 .arr,
2096 .vec,
2097 .errunion,
2098 .aligned,
2099 .bigint,
2100 .pointer,
2101 .array,
2102 .function,
2103 => {},
2104 }
2105 }
2106}
2107
20592108pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
20602109 for (zcu.global_assembly.values()) |asm_source| {
20612110 try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)});
......@@ -2070,16 +2119,16 @@ pub fn genErrDecls(
20702119 const ip = &zcu.intern_pool;
20712120
20722121 const names = ip.global_error_set.getNamesFromMainThread();
2073 // Don't generate an invalid empty enum if the global error set is empty!
2074 if (names.len > 0) {
2075 try w.writeAll("enum {\n");
2076 for (names, 1..) |name_nts, value| {
2077 try w.writeByte(' ');
2078 try renderErrorName(w, name_nts.toSlice(ip));
2079 try w.print(" = {d}u,\n", .{value});
2080 }
2081 try w.writeAll("};\n");
2122 // Don't generate an invalid empty enum/array if the global error set is empty!
2123 if (names.len == 0) return;
2124
2125 try w.writeAll("enum {\n");
2126 for (names, 1..) |name_nts, value| {
2127 try w.writeByte(' ');
2128 try renderErrorName(w, name_nts.toSlice(ip));
2129 try w.print(" = {d}u,\n", .{value});
20822130 }
2131 try w.writeAll("};\n");
20832132
20842133 for (names) |name_nts| {
20852134 const name = name_nts.toSlice(ip);
......@@ -2093,7 +2142,7 @@ pub fn genErrDecls(
20932142 "static {s} const zig_errorName[{d}] = {{",
20942143 .{ slice_const_u8_sentinel_0_type_name, names.len },
20952144 );
2096 if (names.len > 0) try w.writeByte('\n');
2145 try w.writeByte('\n');
20972146 for (names) |name_nts| {
20982147 const name = name_nts.toSlice(ip);
20992148 try w.print(
......@@ -2114,10 +2163,18 @@ pub fn genTagNameFn(
21142163 const ip = &zcu.intern_pool;
21152164 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());
21162165 assert(loaded_enum.field_names.len > 0);
2117 if (Type.fromInterned(loaded_enum.int_tag_type).bitSize(zcu) > 64) {
2118 @panic("TODO CBE: tagName for enum over 64 bits");
2166 switch (CType.classifyInt(enum_ty, zcu)) {
2167 .void => unreachable,
2168 .small => |int| switch (int) {
2169 else => {},
2170 .zig_u128, .zig_i128 => @panic("TODO CBE: tagName for 128-bit enums"),
2171 },
2172 .big => @panic("TODO CBE: tagName for bigint enums"),
21192173 }
21202174
2175 if (!zcu.comp.config.root_strip) try w.print("/* @tagName({f}) */\n", .{
2176 loaded_enum.name.fmt(ip),
2177 });
21212178 try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{
21222179 slice_const_u8_sentinel_0_type_name,
21232180 fmtIdentUnsolo(loaded_enum.name.toSlice(ip)),
......@@ -2291,6 +2348,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E
22912348 .{ .nav = nav_index },
22922349 );
22932350 try header_writer.writeAll(" {\n ");
2351 if (!f.dg.mod.strip) try header_writer.print("/* {f} */\n ", .{nav.fqn.fmt(ip)});
22942352
22952353 f.free_locals_map.clearRetainingCapacity();
22962354
......@@ -2346,6 +2404,7 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E
23462404 for (list.keys()) |local_index| {
23472405 const local = f.locals.items[local_index];
23482406 try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment);
2407 if (local.array_len != 1) try header_writer.print("[{d}]", .{local.array_len});
23492408 try header_writer.writeAll(";\n ");
23502409 }
23512410 }
......@@ -2461,7 +2520,12 @@ pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct {
24612520 try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none);
24622521 try w.writeAll(" = ");
24632522 try dg.renderValue(w, options.init_val, .static_initializer);
2464 try w.writeAll(";\n");
2523 try w.writeByte(';');
2524 if (dg.owner_nav.unwrap()) |nav_index| {
2525 const ip = &zcu.intern_pool;
2526 if (!dg.mod.strip) try w.print(" /* {f} */", .{ip.getNav(nav_index).fqn.fmt(ip)});
2527 }
2528 try w.writeByte('\n');
24652529}
24662530pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct {
24672531 name: CValue,
......@@ -2662,22 +2726,22 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
26622726 .mul => try airBinOp(f, inst, "*", "mul", .none),
26632727
26642728 .neg => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "neg", .none),
2665 .div_float => try airBinBuiltinCall(f, inst, "div", .none),
2729 .div_float => try airBinBuiltinCall(f, inst, "div", .big_temp_bits),
26662730
2667 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
2731 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "divTrunc", .big_temp_bits),
26682732 .rem => blk: {
26692733 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
26702734 const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(zcu);
26712735 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
26722736 // so we only check one.
26732737 break :blk if (lhs_scalar_ty.isInt(zcu))
2674 try airBinOp(f, inst, "%", "rem", .none)
2738 try airBinOp(f, inst, "%", "rem", .big_temp_bits)
26752739 else
26762740 try airBinBuiltinCall(f, inst, "fmod", .none);
26772741 },
2678 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none),
2679 .div_ceil => try airBinBuiltinCall(f, inst, "div_ceil", .none),
2680 .mod => try airBinBuiltinCall(f, inst, "mod", .none),
2742 .div_floor => try airBinBuiltinCall(f, inst, "divFloor", .big_temp_bits),
2743 .div_ceil => try airBinBuiltinCall(f, inst, "divCeil", .big_temp_bits),
2744 .mod => try airBinBuiltinCall(f, inst, "mod", .big_temp_bits),
26812745 .abs => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "abs", .none),
26822746
26832747 .add_wrap => try airBinBuiltinCall(f, inst, "addw", .bits),
......@@ -2687,7 +2751,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
26872751 .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits),
26882752 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits),
26892753 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits),
2690 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits),
2754 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits_none),
26912755
26922756 .sqrt => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sqrt", .none),
26932757 .sin => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].un_op, "sin", .none),
......@@ -2764,8 +2828,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
27642828 .int_from_error => try airNopCast(f, inst),
27652829 .union_from_enum => try airUnionFromEnum(f, inst),
27662830 .bit_cast => try airBitCast(f, inst),
2767 .int_cast => try airIntCast(f, inst),
2768 .trunc => try airTrunc(f, inst),
2831 .int_cast => try airIntCast(f, inst, "intCast", .none),
2832 .trunc => try airIntCast(f, inst, "truncate", .bits),
27692833 .load => try airLoad(f, inst),
27702834 .store => try airStore(f, inst, false),
27712835 .store_safe => try airStore(f, inst, true),
......@@ -2783,9 +2847,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
27832847 .get_union_tag => try airGetUnionTag(f, inst),
27842848 .clz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "clz", .bits),
27852849 .ctz => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "ctz", .bits),
2786 .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popcount", .bits),
2787 .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byte_swap", .bits),
2788 .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bit_reverse", .bits),
2850 .popcount => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "popCount", .bits),
2851 .byte_swap => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "byteSwap", .bits),
2852 .bit_reverse => try airUnBuiltinCall(f, inst, air_datas[@intFromEnum(inst)].ty_op.operand, "bitReverse", .bits),
27892853 .tag_name => try airTagName(f, inst),
27902854 .error_name => try airErrorName(f, inst),
27912855 .splat => try airSplat(f, inst),
......@@ -3124,7 +3188,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
31243188 const zcu = pt.zcu;
31253189 const inst_ty = f.typeOfIndex(inst);
31263190 const elem_ty = inst_ty.childType(zcu);
3127 if (!elem_ty.hasRuntimeBits(zcu)) return .{ .undef = inst_ty };
3191 if (!elem_ty.hasRuntimeBits(zcu)) {
3192 const w = &f.code.writer;
3193 const local = try f.allocLocal(inst, inst_ty);
3194 try f.writeCValue(w, local, .other);
3195 try w.writeAll(" = ");
3196 try f.dg.renderOpvPointer(w, inst_ty, .other);
3197 try w.writeByte(';');
3198 try f.newline();
3199 return local;
3200 }
31283201
31293202 const local = try f.allocLocalValue(.{
31303203 .type = elem_ty,
......@@ -3298,120 +3371,57 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
32983371 }
32993372}
33003373
3301fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3374fn airIntCast(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
33023375 const pt = f.dg.pt;
33033376 const zcu = pt.zcu;
33043377 const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op;
33053378
3306 const operand = try f.resolveInst(ty_op.operand);
3307 try reap(f, inst, &.{ty_op.operand});
3308
3309 const inst_ty = f.typeOfIndex(inst);
3379 const inst_ty = ty_op.ty.toType();
33103380 const inst_scalar_ty = inst_ty.scalarType(zcu);
33113381 const operand_ty = f.typeOf(ty_op.operand);
3312 const scalar_ty = operand_ty.scalarType(zcu);
3313
3314 // `intCastIsNoop` doesn't apply to vectors because every vector lowers to a different C struct.
3315 if (inst_ty.zigTypeTag(zcu) != .vector and f.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) {
3316 return f.moveCValue(inst, inst_ty, operand);
3317 }
3318
3319 const w = &f.code.writer;
3320 const local = try f.allocLocal(inst, inst_ty);
3321 const v = try Vectorize.start(f, inst, w, operand_ty);
3322 try f.writeCValue(w, local, .other);
3323 try v.elem(f, w);
3324 try w.writeAll(" = ");
3325 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .other);
3326 try w.writeByte(';');
3327 try f.newline();
3328 try v.end(f, inst, w);
3329 return local;
3330}
3331
3332fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3333 const pt = f.dg.pt;
3334 const zcu = pt.zcu;
3335 const ty_op = f.air.instructions.items(.data)[@backingInt(inst)].ty_op;
3382 const operand_scalar_ty = operand_ty.scalarType(zcu);
3383 const is_big = lowersToBigInt(operand_ty, zcu);
33363384
33373385 const operand = try f.resolveInst(ty_op.operand);
3338 try reap(f, inst, &.{ty_op.operand});
3339
3340 const inst_ty = f.typeOfIndex(inst);
3341 const inst_scalar_ty = inst_ty.scalarType(zcu);
3342 const dest_int_info = inst_scalar_ty.intInfo(zcu);
3343 const dest_bits = dest_int_info.bits;
3344 const dest_c_bits = toCIntBits(dest_bits) orelse
3345 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3346 const operand_ty = f.typeOf(ty_op.operand);
3347 const scalar_ty = operand_ty.scalarType(zcu);
3348 const scalar_int_info = scalar_ty.intInfo(zcu);
3386 if (!is_big) try reap(f, inst, &.{ty_op.operand});
33493387
3350 const need_cast = dest_c_bits < 64;
3351 const need_lo = scalar_int_info.bits > 64 and dest_bits <= 64;
3352 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
3353 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
3388 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
3389 const ref_arg = lowersToBigInt(operand_scalar_ty, zcu);
33543390
33553391 const w = &f.code.writer;
33563392 const local = try f.allocLocal(inst, inst_ty);
3393 if (is_big) try reap(f, inst, &.{ty_op.operand});
33573394 const v = try Vectorize.start(f, inst, w, operand_ty);
3358 try f.writeCValue(w, local, .other);
3359 try v.elem(f, w);
3360 try w.writeAll(" = ");
3361 if (need_cast) {
3362 try w.writeByte('(');
3363 try f.renderType(w, inst_scalar_ty);
3364 try w.writeByte(')');
3365 }
3366 if (need_lo) {
3367 try w.writeAll("zig_lo_");
3368 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3369 try w.writeByte('(');
3395 if (!ref_ret) {
3396 try f.writeCValue(w, local, .other);
3397 try v.elem(f, w);
3398 try w.writeAll(" = ");
33703399 }
3371 if (!need_mask) {
3372 try f.writeCValue(w, operand, .other);
3400 try w.writeAll("zig_");
3401 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
3402 try w.print("_{s}_", .{operation});
3403 try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty);
3404 try w.writeByte('(');
3405 if (ref_ret) {
3406 try w.writeByte('&');
3407 try f.writeCValue(w, local, .other);
33733408 try v.elem(f, w);
3374 } else switch (dest_int_info.signedness) {
3375 .unsigned => {
3376 try w.writeAll("zig_and_");
3377 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3378 try w.writeByte('(');
3379 try f.writeCValue(w, operand, .other);
3380 try v.elem(f, w);
3381 try w.print(", {f})", .{
3382 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
3383 });
3384 },
3385 .signed => {
3386 const c_bits = toCIntBits(scalar_int_info.bits) orelse
3387 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3388 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
3389
3390 try w.writeAll("zig_shr_");
3391 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3392 if (c_bits == 128) {
3393 try w.print("(zig_bitCast_i{d}(", .{c_bits});
3394 } else {
3395 try w.print("((int{d}_t)", .{c_bits});
3396 }
3397 try w.print("zig_shl_u{d}(", .{c_bits});
3398 if (c_bits == 128) {
3399 try w.print("zig_bitCast_u{d}(", .{c_bits});
3400 } else {
3401 try w.print("(uint{d}_t)", .{c_bits});
3402 }
3403 try f.writeCValue(w, operand, .other);
3404 try v.elem(f, w);
3405 if (c_bits == 128) try w.writeByte(')');
3406 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
3407 if (c_bits == 128) try w.writeByte(')');
3408 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
3409 },
3409 try w.writeAll(", ");
34103410 }
3411 if (need_lo) try w.writeByte(')');
3412 try w.writeByte(';');
3411 if (ref_arg) {
3412 try w.writeByte('&');
3413 switch (operand) {
3414 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
3415 else => try f.writeCValue(w, operand, .other),
3416 }
3417 } else try f.writeCValue(w, operand, .other);
3418 try v.elem(f, w);
3419 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, info);
3420 try f.dg.renderBuiltinInfo(w, operand_scalar_ty, .none);
3421 try w.writeAll(");");
34133422 try f.newline();
34143423 try v.end(f, inst, w);
3424
34153425 return local;
34163426}
34173427
......@@ -3525,39 +3535,46 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
35253535 const ty_pl = f.air.instructions.items(.data)[@backingInt(inst)].ty_pl;
35263536 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
35273537
3538 const lhs_ty = f.typeOf(bin_op.lhs);
3539 const rhs_ty = f.typeOf(bin_op.rhs);
3540 const is_big = lowersToBigInt(lhs_ty, zcu);
3541
35283542 const lhs = try f.resolveInst(bin_op.lhs);
35293543 const rhs = try f.resolveInst(bin_op.rhs);
3530 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3544 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
35313545
3532 const inst_ty = f.typeOfIndex(inst);
3533 const operand_ty = f.typeOf(bin_op.lhs);
3534 const scalar_ty = operand_ty.scalarType(zcu);
3546 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
3547 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
35353548
3536 const ref_arg = lowersToBigInt(scalar_ty, zcu);
3549 const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu);
3550 const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu);
35373551
35383552 const w = &f.code.writer;
3539 const local = try f.allocLocal(inst, inst_ty);
3540 const v = try Vectorize.start(f, inst, w, operand_ty);
3553 const local = try f.allocLocal(inst, f.typeOfIndex(inst));
3554 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3555 const v = try Vectorize.start(f, inst, w, lhs_ty);
35413556 try f.writeCValueMember(w, local, .{ .field = 1 });
35423557 try v.elem(f, w);
3543 try w.writeAll(" = zig_");
3558 try w.writeAll(" = ");
3559 try w.writeAll("zig_");
35443560 try w.writeAll(operation);
35453561 try w.writeAll("o_");
3546 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3562 try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty);
35473563 try w.writeByte('(');
35483564
35493565 // '&dest', possibly preceded by a cast
3550 switch (zcu.intern_pool.indexToKey(scalar_ty.toIntern())) {
3566 switch (zcu.intern_pool.indexToKey(lhs_scalar_ty.toIntern())) {
35513567 .int_type => {}, // we already have a '[u]intX_t *'
35523568 .simple_type => {
35533569 // '&dest' will be something like a 'uintptr_t *', which might be a different C type to
35543570 // the equivalent sized integer (e.g. 'uint64_t *'), so we need a cast. We don't need a
35553571 // cast on the *operands* because they are passed by value (except for big integers,
35563572 // where this issue doesn't exist because no "simple" int type needs bigint repr).
3557 try w.print("({s}int{d}_t *)", .{
3558 if (scalar_ty.isUnsignedInt(zcu)) "u" else "",
3559 scalar_ty.abiSize(zcu) * 8,
3560 });
3573 const inst_int_info = lhs_scalar_ty.intInfo(zcu);
3574 try w.print("({s}int{d}_t *)", .{ switch (inst_int_info.signedness) {
3575 .signed => "",
3576 .unsigned => "u",
3577 }, inst_int_info.bits });
35613578 },
35623579 else => unreachable,
35633580 }
......@@ -3566,14 +3583,24 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
35663583 try v.elem(f, w);
35673584
35683585 try w.writeAll(", ");
3569 if (ref_arg) try w.writeByte('&');
3570 try f.writeCValue(w, lhs, .other);
3586 if (ref_lhs) {
3587 try w.writeByte('&');
3588 switch (lhs) {
3589 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
3590 else => try f.writeCValue(w, lhs, .other),
3591 }
3592 } else try f.writeCValue(w, lhs, .other);
35713593 try v.elem(f, w);
35723594 try w.writeAll(", ");
3573 if (ref_arg) try w.writeByte('&');
3574 try f.writeCValue(w, rhs, .other);
3575 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
3576 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
3595 if (ref_rhs) {
3596 try w.writeByte('&');
3597 switch (rhs) {
3598 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
3599 else => try f.writeCValue(w, rhs, .other),
3600 }
3601 } else try f.writeCValue(w, rhs, .other);
3602 try v.elem(f, w);
3603 try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info);
35773604 try w.writeAll(");");
35783605 try f.newline();
35793606 try v.end(f, inst, w);
......@@ -3622,8 +3649,18 @@ fn airBinOp(
36223649 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
36233650 const operand_ty = f.typeOf(bin_op.lhs);
36243651 const scalar_ty = operand_ty.scalarType(zcu);
3625 if ((scalar_ty.isInt(zcu) and scalar_ty.bitSize(zcu) > 64) or scalar_ty.isRuntimeFloat())
3626 return try airBinBuiltinCall(f, inst, operation, info);
3652
3653 builtin: {
3654 if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) {
3655 .void => unreachable,
3656 .small => |int| switch (int) {
3657 else => break :builtin,
3658 .zig_u128, .zig_i128 => {},
3659 },
3660 .big => {},
3661 } else if (!scalar_ty.isRuntimeFloat()) break :builtin;
3662 return airBinBuiltinCall(f, inst, operation, info);
3663 }
36273664
36283665 const lhs = try f.resolveInst(bin_op.lhs);
36293666 const rhs = try f.resolveInst(bin_op.rhs);
......@@ -3662,19 +3699,21 @@ fn airCmpOp(
36623699 const lhs_ty = f.typeOf(data.lhs);
36633700 const scalar_ty = lhs_ty.scalarType(zcu);
36643701
3665 if (scalar_ty.isInt(zcu)) {
3666 const scalar_bits = scalar_ty.bitSize(zcu);
3667 if (scalar_bits > 64) return airCmpBuiltinCall(
3668 f,
3669 inst,
3670 data,
3671 operator,
3672 .cmp,
3673 if (scalar_bits > 128) .bits else .none,
3674 );
3702 builtin: {
3703 if (scalar_ty.isInt(zcu)) {
3704 switch (CType.classifyInt(scalar_ty, zcu)) {
3705 .void => unreachable,
3706 .small => |int| switch (int) {
3707 else => break :builtin,
3708 .zig_u128, .zig_i128 => {},
3709 },
3710 .big => {},
3711 }
3712 return airCmpBuiltinCall(f, inst, data, operator, .cmp, .none);
3713 }
3714 if (scalar_ty.isRuntimeFloat())
3715 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
36753716 }
3676 if (scalar_ty.isRuntimeFloat())
3677 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
36783717
36793718 const inst_ty = f.typeOfIndex(inst);
36803719 const lhs = try f.resolveInst(data.lhs);
......@@ -3716,21 +3755,23 @@ fn airEquality(
37163755 const pt = f.dg.pt;
37173756 const zcu = pt.zcu;
37183757 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
3719
37203758 const operand_ty = f.typeOf(bin_op.lhs);
3721 if (operand_ty.isAbiInt(zcu)) {
3722 const operand_bits = operand_ty.bitSize(zcu);
3723 if (operand_bits > 64) return airCmpBuiltinCall(
3724 f,
3725 inst,
3726 bin_op,
3727 operator,
3728 .cmp,
3729 if (operand_bits > 128) .bits else .none,
3730 );
3759
3760 builtin: {
3761 if (operand_ty.isAbiInt(zcu)) {
3762 switch (CType.classifyInt(operand_ty, zcu)) {
3763 .void => unreachable,
3764 .small => |int| switch (int) {
3765 else => break :builtin,
3766 .zig_u128, .zig_i128 => {},
3767 },
3768 .big => {},
3769 }
3770 return airCmpBuiltinCall(f, inst, bin_op, operator, .cmp, .none);
3771 }
3772 if (operand_ty.isRuntimeFloat())
3773 return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
37313774 }
3732 if (operand_ty.isRuntimeFloat())
3733 return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
37343775
37353776 const lhs = try f.resolveInst(bin_op.lhs);
37363777 const rhs = try f.resolveInst(bin_op.rhs);
......@@ -3809,7 +3850,7 @@ fn airCmpLteErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
38093850 try f.writeCValue(w, local, .other);
38103851 try w.writeAll(" = ");
38113852 try f.writeCValue(w, operand, .other);
3812 try w.writeAll(" < sizeof(zig_errorName) / sizeof(*zig_errorName);");
3853 try w.writeAll(" <= sizeof(zig_errorName) / sizeof(*zig_errorName);");
38133854 try f.newline();
38143855 return local;
38153856}
......@@ -3862,8 +3903,17 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
38623903 const inst_ty = f.typeOfIndex(inst);
38633904 const inst_scalar_ty = inst_ty.scalarType(zcu);
38643905
3865 if ((inst_scalar_ty.isInt(zcu) and inst_scalar_ty.bitSize(zcu) > 64) or inst_scalar_ty.isRuntimeFloat())
3866 return try airBinBuiltinCall(f, inst, operation, .none);
3906 builtin: {
3907 if (inst_scalar_ty.isInt(zcu)) switch (CType.classifyInt(inst_scalar_ty, zcu)) {
3908 .void => unreachable,
3909 .small => |int| switch (int) {
3910 else => break :builtin,
3911 .zig_u128, .zig_i128 => {},
3912 },
3913 .big => {},
3914 } else if (!inst_scalar_ty.isRuntimeFloat()) break :builtin;
3915 return airBinBuiltinCall(f, inst, operation, .none);
3916 }
38673917
38683918 const lhs = try f.resolveInst(bin_op.lhs);
38693919 const rhs = try f.resolveInst(bin_op.rhs);
......@@ -3979,10 +4029,7 @@ fn airCall(
39794029 try w.writeAll("(void)");
39804030 break :result .none;
39814031 } else {
3982 const local = try f.allocAlignedLocal(inst, .{
3983 .type = ret_ty,
3984 .alignment = .none,
3985 });
4032 const local = try f.allocAlignedLocal(inst, .{ .type = ret_ty });
39864033 try f.writeCValue(w, local, .other);
39874034 try w.writeAll(" = ");
39884035 break :result local;
......@@ -4058,16 +4105,7 @@ fn airCall(
40584105fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
40594106 const dbg_stmt = f.air.instructions.items(.data)[@backingInt(inst)].dbg_stmt;
40604107 const w = &f.code.writer;
4061 // TODO re-evaluate whether to emit these or not. If we naively emit
4062 // these directives, the output file will report bogus line numbers because
4063 // every newline after the #line directive adds one to the line.
4064 // We also don't print the filename yet, so the output is strictly unhelpful.
4065 // If we wanted to go this route, we would need to go all the way and not output
4066 // newlines until the next dbg_stmt occurs.
4067 // Perhaps an additional compilation option is in order?
4068 //try w.print("#line {d}", .{dbg_stmt.line + 1});
4069 //try f.newline();
4070 try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4108 try w.print("/* {d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
40714109 try f.newline();
40724110 return .none;
40734111}
......@@ -4433,12 +4471,12 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {
44334471 const operand_scalar_ty = operand_ty.scalarType(zcu);
44344472 const dest_scalar_ty = dest_ty.scalarType(zcu);
44354473
4436 // Some cases are handled with a simple cast:
4437 // * float -> float
4438 // * bool -> int
44394474 if ((operand_scalar_ty.isRuntimeFloat() and dest_scalar_ty.isRuntimeFloat()) or
44404475 (operand_scalar_ty.toIntern() == .bool_type and dest_scalar_ty.isAbiInt(zcu)))
44414476 {
4477 // Some cases are handled with a simple cast:
4478 // * float -> float
4479 // * bool -> int
44424480 try f.writeCValue(w, dest_local, .other);
44434481 try v.elem(f, w);
44444482 try w.writeAll(" = (");
......@@ -4458,85 +4496,44 @@ fn airBitCast(f: *Function, inst: Air.Inst.Index) Error!CValue {
44584496 try v.elem(f, w);
44594497 try w.writeAll(" != 0;");
44604498 try f.newline();
4461 } else if (dest_scalar_ty.isRuntimeFloat()) {
4462 // For int->float, just do a memcpy.
4463 assert(operand_scalar_ty.isAbiInt(zcu));
4464 try w.writeAll("memcpy(&");
4465 try f.writeCValue(w, dest_local, .other);
4466 try v.elem(f, w);
4467 try w.writeAll(", &");
4468 switch (operand) {
4469 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4470 else => try f.writeCValue(w, operand, .other),
4471 }
4472 try v.elem(f, w);
4473 try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))});
4474 try f.newline();
44754499 } else {
4476 // The only remaining possibility is that the result is an integer. We will need to use
4477 // `zig_wrap_*` to correct the "padding" bits after we populate the value bits.
4478 assert(dest_scalar_ty.isAbiInt(zcu));
44794500 assert(operand_scalar_ty.isRuntimeFloat() or operand_scalar_ty.isAbiInt(zcu));
4501 assert(dest_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isAbiInt(zcu));
44804502
4481 // memcpy the value...
4482 try w.writeAll("memcpy(&");
4483 try f.writeCValue(w, dest_local, .other);
4484 try v.elem(f, w);
4485 try w.writeAll(", &");
4486 switch (operand) {
4487 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4488 else => try f.writeCValue(w, operand, .other),
4503 const ref_ret = lowersToBigInt(dest_scalar_ty, zcu);
4504 const ref_arg = lowersToBigInt(operand_scalar_ty, zcu);
4505
4506 if (!ref_ret) {
4507 try f.writeCValue(w, dest_local, .other);
4508 try v.elem(f, w);
4509 try w.writeAll(" = ");
44894510 }
4511 try w.writeAll("zig_");
4512 try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty);
4513 try w.writeAll("_bitCast_");
4514 try f.dg.renderTypeForBuiltinFnName(w, operand_scalar_ty);
4515 try w.writeByte('(');
4516 if (ref_ret) {
4517 try w.writeByte('&');
4518 try f.writeCValue(w, dest_local, .other);
4519 try v.elem(f, w);
4520 try w.writeAll(", ");
4521 }
4522 if (ref_arg) {
4523 try w.writeByte('&');
4524 switch (operand) {
4525 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4526 else => try f.writeCValue(w, operand, .other),
4527 }
4528 } else try f.writeCValue(w, operand, .other);
44904529 try v.elem(f, w);
4491 try w.print(", {d});", .{@min(operand_scalar_ty.abiSize(zcu), dest_scalar_ty.abiSize(zcu))});
4530 try f.dg.renderBuiltinInfo(
4531 w,
4532 dest_scalar_ty,
4533 if (operand_scalar_ty.isRuntimeFloat() or dest_scalar_ty.isRuntimeFloat()) .none else .bits,
4534 );
4535 try w.writeAll(");");
44924536 try f.newline();
4493
4494 // ...and ensure padding bits have the correct value.
4495 switch (CType.classifyInt(dest_scalar_ty, zcu)) {
4496 .void => unreachable, // opv
4497 .small => {
4498 try f.writeCValue(w, dest_local, .other);
4499 try v.elem(f, w);
4500 try w.writeAll(" = zig_wrap_");
4501 try f.dg.renderTypeForBuiltinFnName(w, dest_scalar_ty);
4502 try w.writeByte('(');
4503 try f.writeCValue(w, dest_local, .other);
4504 try v.elem(f, w);
4505 try f.dg.renderBuiltinInfo(w, dest_scalar_ty, .bits);
4506 try w.writeAll(");");
4507 try f.newline();
4508 },
4509 .big => |big| {
4510 const dest_info = dest_scalar_ty.intInfo(zcu);
4511 const padding_index: u16 = switch (f.dg.mod.resolved_target.result.cpu.arch.endian()) {
4512 .little => big.limbs_len - 1,
4513 .big => 0,
4514 };
4515 const wrap_bits = ((dest_info.bits - 1) % big.limb_size.bits()) + 1;
4516 if (big.limb_size != .@"128" or dest_info.signedness == .unsigned) {
4517 try f.writeCValue(w, dest_local, .other);
4518 try v.elem(f, w);
4519 try w.print(".limbs[{d}] = zig_wrap_{c}{d}(", .{
4520 padding_index,
4521 signAbbrev(dest_info.signedness),
4522 big.limb_size.bits(),
4523 });
4524 try f.writeCValue(w, dest_local, .other);
4525 try v.elem(f, w);
4526 try w.print(".limbs[{d}], {d});", .{ padding_index, wrap_bits });
4527 } else {
4528 try f.writeCValue(w, dest_local, .other);
4529 try v.elem(f, w);
4530 try w.print(".limbs[{d}] = zig_bitCast_u128(zig_wrap_i128(zig_bitCast_i128(", .{
4531 padding_index,
4532 });
4533 try f.writeCValue(w, dest_local, .other);
4534 try v.elem(f, w);
4535 try w.print(".limbs[{d}]), {d}));", .{ padding_index, wrap_bits });
4536 try f.newline();
4537 }
4538 },
4539 }
45404537 }
45414538
45424539 try v.end(f, inst, w);
......@@ -4906,11 +4903,9 @@ fn lowerSwitchCmp(
49064903
49074904fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
49084905 const dg = f.dg;
4909 const target = &dg.mod.resolved_target.result;
49104906 return switch (constraint[0]) {
49114907 '{' => true,
4912 'i', 'r' => false,
4913 'I' => !target.cpu.arch.isArm(),
4908 'r', 'i', 'n', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' => false,
49144909 else => switch (value) {
49154910 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
49164911 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
......@@ -4937,10 +4932,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
49374932 const w = &f.code.writer;
49384933 const inst_ty = f.typeOfIndex(inst);
49394934 const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: {
4940 const inst_local = try f.allocLocalValue(.{
4941 .type = inst_ty,
4942 .alignment = .none,
4943 });
4935 const inst_local = try f.allocLocalValue(.{ .type = inst_ty });
49444936 if (f.wantSafety()) {
49454937 try f.writeCValue(w, inst_local, .other);
49464938 try w.writeAll(" = ");
......@@ -4967,10 +4959,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
49674959 if (is_reg) {
49684960 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);
49694961 try w.writeAll("register ");
4970 const output_local = try f.allocLocalValue(.{
4971 .type = output_ty,
4972 .alignment = .none,
4973 });
4962 const output_local = try f.allocLocalValue(.{ .type = output_ty });
49744963 try f.allocs.put(gpa, output_local.new_local, false);
49754964 try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none);
49764965 try w.writeAll(" __asm(\"");
......@@ -5000,10 +4989,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
50004989 if (asmInputNeedsLocal(f, constraint, input_val)) {
50014990 const input_ty = f.typeOf(input.operand);
50024991 if (is_reg) try w.writeAll("register ");
5003 const input_local = try f.allocLocalValue(.{
5004 .type = input_ty,
5005 .alignment = .none,
5006 });
4992 const input_local = try f.allocLocalValue(.{ .type = input_ty });
50074993 try f.allocs.put(gpa, input_local.new_local, false);
50084994 // Do not render the declaration as `const` qualified if we're generating an
50094995 // explicit `register` local, as GCC will ignore the constraint completely.
......@@ -5853,28 +5839,124 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
58535839 else
58545840 unreachable;
58555841
5842 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5843 const ref_operand = lowersToBigInt(scalar_ty, zcu);
5844
58565845 const w = &f.code.writer;
58575846 const local = try f.allocLocal(inst, inst_ty);
58585847 const v = try Vectorize.start(f, inst, w, operand_ty);
5859 try f.writeCValue(w, local, .other);
5860 try v.elem(f, w);
5861 try w.writeAll(" = ");
5848 if (ref_ret) {
5849 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5850 if (inst_int_info.bits <= 128) {
5851 try w.writeAll("zig_");
5852 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
5853 try w.print("_intCast_{c}{d}", .{
5854 @as(u8, switch (inst_int_info.signedness) {
5855 .signed => 'i',
5856 .unsigned => 'u',
5857 }),
5858 std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)),
5859 });
5860 try w.writeAll("(&");
5861 try f.writeCValue(w, local, .other);
5862 try v.elem(f, w);
5863 try w.writeAll(", ");
5864 }
5865 } else {
5866 try f.writeCValue(w, local, .other);
5867 try v.elem(f, w);
5868 try w.writeAll(" = ");
5869 }
58625870 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
5863 try w.writeAll("zig_wrap_");
5864 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
5865 try w.writeByte('(');
5871 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5872 if (inst_int_info.bits <= 128) try w.print("zig_{c}{d}_truncate_{[0]c}{[1]d}(", .{
5873 @as(u8, switch (inst_int_info.signedness) {
5874 .signed => 'i',
5875 .unsigned => 'u',
5876 }),
5877 std.math.ceilPowerOfTwoAssert(u16, @max(inst_int_info.bits, 32)),
5878 });
58665879 }
58675880 try w.writeAll("zig_");
58685881 try w.writeAll(operation);
58695882 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
58705883 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
58715884 try w.writeByte('(');
5872 try f.writeCValue(w, operand, .other);
5873 try v.elem(f, w);
5885 if (ref_ret) {
5886 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5887 if (inst_int_info.bits > 128) {
5888 try w.writeByte('&');
5889 try f.writeCValue(w, local, .other);
5890 try v.elem(f, w);
5891 try w.writeAll(", ");
5892 }
5893 }
5894 if (ref_operand) {
5895 const operand_int_info = scalar_ty.intInfo(zcu);
5896 if (operand_int_info.bits <= 128) {
5897 try w.print("zig_{c}{d}_intCast_", .{
5898 @as(u8, switch (operand_int_info.signedness) {
5899 .signed => 'i',
5900 .unsigned => 'u',
5901 }),
5902 std.math.ceilPowerOfTwoAssert(u16, @max(operand_int_info.bits, 32)),
5903 });
5904 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
5905 try w.writeAll("(&");
5906 switch (operand) {
5907 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
5908 else => try f.writeCValue(w, operand, .other),
5909 }
5910 try v.elem(f, w);
5911 try f.dg.renderBuiltinInfo(w, scalar_ty, .none);
5912 try w.writeByte(')');
5913 } else {
5914 try w.writeByte('&');
5915 switch (operand) {
5916 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
5917 else => try f.writeCValue(w, operand, .other),
5918 }
5919 try v.elem(f, w);
5920 try w.print(", {f}", .{fmtUnsignedIntLiteralSmall(
5921 target,
5922 .uint16_t,
5923 operand_int_info.bits,
5924 false,
5925 10,
5926 .lower,
5927 )});
5928 }
5929 } else {
5930 try f.writeCValue(w, operand, .other);
5931 try v.elem(f, w);
5932 }
5933 if (ref_ret) {
5934 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5935 if (inst_int_info.bits > 128) try w.print(", {f}", .{fmtUnsignedIntLiteralSmall(
5936 target,
5937 .uint16_t,
5938 inst_int_info.bits,
5939 false,
5940 10,
5941 .lower,
5942 )});
5943 }
58745944 try w.writeByte(')');
58755945 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
5876 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits);
5877 try w.writeByte(')');
5946 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5947 if (inst_int_info.bits <= 128) {
5948 try w.print(", {f}", .{
5949 try f.dg.fmtIntLiteralDec(try pt.intValue(.u8, inst_int_info.bits), .other),
5950 });
5951 try w.writeByte(')');
5952 }
5953 }
5954 if (ref_ret) {
5955 const inst_int_info = inst_scalar_ty.intInfo(zcu);
5956 if (inst_int_info.bits <= 128) {
5957 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .none);
5958 try w.writeByte(')');
5959 }
58785960 }
58795961 try w.writeByte(';');
58805962 try f.newline();
......@@ -5893,18 +5975,21 @@ fn airUnBuiltinCall(
58935975 const pt = f.dg.pt;
58945976 const zcu = pt.zcu;
58955977
5896 const operand = try f.resolveInst(operand_ref);
5897 try reap(f, inst, &.{operand_ref});
58985978 const inst_ty = f.typeOfIndex(inst);
58995979 const inst_scalar_ty = inst_ty.scalarType(zcu);
59005980 const operand_ty = f.typeOf(operand_ref);
59015981 const scalar_ty = operand_ty.scalarType(zcu);
5982 const is_big = lowersToBigInt(operand_ty, zcu);
5983
5984 const operand = try f.resolveInst(operand_ref);
5985 if (!is_big) try reap(f, inst, &.{operand_ref});
59025986
59035987 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
59045988 const ref_arg = lowersToBigInt(scalar_ty, zcu);
59055989
59065990 const w = &f.code.writer;
59075991 const local = try f.allocLocal(inst, inst_ty);
5992 if (is_big) try reap(f, inst, &.{operand_ref});
59085993 const v = try Vectorize.start(f, inst, w, operand_ty);
59095994 if (!ref_ret) {
59105995 try f.writeCValue(w, local, .other);
......@@ -5920,8 +6005,13 @@ fn airUnBuiltinCall(
59206005 try v.elem(f, w);
59216006 try w.writeAll(", ");
59226007 }
5923 if (ref_arg) try w.writeByte('&');
5924 try f.writeCValue(w, operand, .other);
6008 if (ref_arg) {
6009 try w.writeByte('&');
6010 switch (operand) {
6011 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6012 else => try f.writeCValue(w, operand, .other),
6013 }
6014 } else try f.writeCValue(w, operand, .other);
59256015 try v.elem(f, w);
59266016 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
59276017 try w.writeAll(");");
......@@ -5941,8 +6031,9 @@ fn airBinBuiltinCall(
59416031 const zcu = pt.zcu;
59426032 const bin_op = f.air.instructions.items(.data)[@backingInt(inst)].bin_op;
59436033
5944 const operand_ty = f.typeOf(bin_op.lhs);
5945 const is_big = lowersToBigInt(operand_ty, zcu);
6034 const lhs_ty = f.typeOf(bin_op.lhs);
6035 const rhs_ty = f.typeOf(bin_op.rhs);
6036 const is_big = lowersToBigInt(lhs_ty, zcu);
59466037
59476038 const lhs = try f.resolveInst(bin_op.lhs);
59486039 const rhs = try f.resolveInst(bin_op.rhs);
......@@ -5950,22 +6041,31 @@ fn airBinBuiltinCall(
59506041
59516042 const inst_ty = f.typeOfIndex(inst);
59526043 const inst_scalar_ty = inst_ty.scalarType(zcu);
5953 const scalar_ty = operand_ty.scalarType(zcu);
6044 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
6045 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
59546046
59556047 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5956 const ref_arg = lowersToBigInt(scalar_ty, zcu);
6048 const ref_lhs = lowersToBigInt(lhs_scalar_ty, zcu);
6049 const ref_rhs = lowersToBigInt(rhs_scalar_ty, zcu);
59576050
59586051 const w = &f.code.writer;
59596052 const local = try f.allocLocal(inst, inst_ty);
59606053 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
5961 const v = try Vectorize.start(f, inst, w, operand_ty);
6054 const v = try Vectorize.start(f, inst, w, lhs_ty);
59626055 if (!ref_ret) {
59636056 try f.writeCValue(w, local, .other);
59646057 try v.elem(f, w);
59656058 try w.writeAll(" = ");
59666059 }
59676060 try w.print("zig_{s}_", .{operation});
5968 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6061 try f.dg.renderTypeForBuiltinFnName(w, lhs_scalar_ty);
6062 switch (info) {
6063 .bits, .none, .big_temp_bits => {},
6064 .bits_none => {
6065 try w.writeByte('_');
6066 try f.dg.renderTypeForBuiltinFnName(w, rhs_scalar_ty);
6067 },
6068 }
59696069 try w.writeByte('(');
59706070 if (ref_ret) {
59716071 try w.writeByte('&');
......@@ -5973,15 +6073,45 @@ fn airBinBuiltinCall(
59736073 try v.elem(f, w);
59746074 try w.writeAll(", ");
59756075 }
5976 if (ref_arg) try w.writeByte('&');
5977 try f.writeCValue(w, lhs, .other);
6076 if (ref_lhs) {
6077 try w.writeByte('&');
6078 switch (lhs) {
6079 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
6080 else => try f.writeCValue(w, lhs, .other),
6081 }
6082 } else try f.writeCValue(w, lhs, .other);
59786083 try v.elem(f, w);
59796084 try w.writeAll(", ");
5980 if (ref_arg) try w.writeByte('&');
5981 try f.writeCValue(w, rhs, .other);
5982 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
5983 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
5984 try w.writeAll(");\n");
6085 if (ref_rhs) {
6086 try w.writeByte('&');
6087 switch (rhs) {
6088 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
6089 else => try f.writeCValue(w, rhs, .other),
6090 }
6091 } else try f.writeCValue(w, rhs, .other);
6092 try v.elem(f, w);
6093 try f.dg.renderBuiltinInfo(w, lhs_scalar_ty, info: switch (info) {
6094 .none => .none,
6095 .bits, .bits_none => .bits,
6096 .big_temp_bits => {
6097 if (lowersToBigInt(lhs_scalar_ty, zcu)) {
6098 const temp_local = try f.allocAlignedLocal(inst, .{
6099 .type = lhs_scalar_ty,
6100 .array_len = 2,
6101 });
6102 try w.writeAll(", &");
6103 try f.writeCValue(w, temp_local, .other);
6104 try freeLocal(f, inst, temp_local.new_local, null);
6105 }
6106 break :info .none;
6107 },
6108 });
6109 switch (info) {
6110 .none, .bits, .big_temp_bits => {},
6111 .bits_none => try f.dg.renderBuiltinInfo(w, rhs_scalar_ty, .none),
6112 }
6113 try w.writeAll(");");
6114 try f.newline();
59856115 try v.end(f, inst, w);
59866116
59876117 return local;
......@@ -6029,12 +6159,22 @@ fn airCmpBuiltinCall(
60296159 try v.elem(f, w);
60306160 try w.writeAll(", ");
60316161 }
6032 if (ref_arg) try w.writeByte('&');
6033 try f.writeCValue(w, lhs, .other);
6162 if (ref_arg) {
6163 try w.writeByte('&');
6164 switch (lhs) {
6165 .constant => |lhs_val| try f.dg.renderValueAsLvalue(w, lhs_val),
6166 else => try f.writeCValue(w, lhs, .other),
6167 }
6168 } else try f.writeCValue(w, lhs, .other);
60346169 try v.elem(f, w);
60356170 try w.writeAll(", ");
6036 if (ref_arg) try w.writeByte('&');
6037 try f.writeCValue(w, rhs, .other);
6171 if (ref_arg) {
6172 try w.writeByte('&');
6173 switch (rhs) {
6174 .constant => |rhs_val| try f.dg.renderValueAsLvalue(w, rhs_val),
6175 else => try f.writeCValue(w, rhs, .other),
6176 }
6177 } else try f.writeCValue(w, rhs, .other);
60386178 try v.elem(f, w);
60396179 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
60406180 try w.writeByte(')');
......@@ -6595,7 +6735,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
65956735 },
65966736 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
65976737 }
6598 try w.writeAll(";\n");
6738 try w.writeByte(';');
6739 try f.newline();
65996740 }
66006741
66016742 return local;
......@@ -6653,7 +6794,14 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
66536794 const operand_ty = f.typeOf(reduce.operand);
66546795 const w = &f.code.writer;
66556796
6656 const use_operator = scalar_ty.bitSize(zcu) <= 64;
6797 const use_operator, const is_big = if (scalar_ty.isInt(zcu)) switch (CType.classifyInt(scalar_ty, zcu)) {
6798 .void => unreachable,
6799 .small => |int| switch (int) {
6800 else => .{ true, false },
6801 .zig_u128, .zig_i128 => .{ false, false },
6802 },
6803 .big => .{ false, true },
6804 } else .{ false, false };
66576805 const op: union(enum) {
66586806 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
66596807 builtin: Func,
......@@ -6742,25 +6890,57 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67426890 try f.newline();
67436891
67446892 const v = try Vectorize.start(f, inst, w, operand_ty);
6745 try f.writeCValue(w, accum, .other);
67466893 switch (op) {
67476894 .builtin => |func| {
6748 try w.print(" = zig_{s}_", .{func.operation});
6895 const prev_accum = if (is_big) prev_accum: {
6896 const prev_accum = try f.allocLocal(inst, scalar_ty);
6897 try f.writeCValue(w, prev_accum, .other);
6898 try w.writeAll(" = ");
6899 try f.writeCValue(w, accum, .other);
6900 try w.writeByte(';');
6901 try f.newline();
6902 break :prev_accum prev_accum;
6903 } else prev_accum: {
6904 try f.writeCValue(w, accum, .other);
6905 try w.writeAll(" = ");
6906 break :prev_accum accum;
6907 };
6908 try w.print("zig_{s}_", .{func.operation});
67496909 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
67506910 try w.writeByte('(');
6751 try f.writeCValue(w, accum, .other);
6911 if (is_big) {
6912 try w.writeByte('&');
6913 switch (accum) {
6914 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6915 else => try f.writeCValue(w, accum, .other),
6916 }
6917 try w.writeAll(", &");
6918 switch (prev_accum) {
6919 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6920 else => try f.writeCValue(w, prev_accum, .other),
6921 }
6922 } else try f.writeCValue(w, prev_accum, .other);
67526923 try w.writeAll(", ");
6753 try f.writeCValue(w, operand, .other);
6924 if (is_big) {
6925 try w.writeByte('&');
6926 switch (operand) {
6927 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
6928 else => try f.writeCValue(w, operand, .other),
6929 }
6930 } else try f.writeCValue(w, operand, .other);
67546931 try v.elem(f, w);
67556932 try f.dg.renderBuiltinInfo(w, scalar_ty, func.info);
67566933 try w.writeByte(')');
6934 if (is_big) try freeLocal(f, inst, prev_accum.new_local, null);
67576935 },
67586936 .infix => |ass| {
6937 try f.writeCValue(w, accum, .other);
67596938 try w.writeAll(ass);
67606939 try f.writeCValue(w, operand, .other);
67616940 try v.elem(f, w);
67626941 },
67636942 .ternary => |cmp| {
6943 try f.writeCValue(w, accum, .other);
67646944 try w.writeAll(" = ");
67656945 try f.writeCValue(w, accum, .other);
67666946 try w.writeAll(cmp);
......@@ -7224,17 +7404,18 @@ fn signAbbrev(signedness: std.lang.Signedness) u8 {
72247404
72257405fn compilerRtAbbrev(ty: Type, zcu: *Zcu, target: *const std.Target) []const u8 {
72267406 return if (ty.isInt(zcu)) switch (ty.intInfo(zcu).bits) {
7407 0 => unreachable,
72277408 1...32 => "si",
72287409 33...64 => "di",
72297410 65...128 => "ti",
7230 else => unreachable,
7411 else => "ei",
72317412 } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) {
7413 else => unreachable,
72327414 16 => "hf",
72337415 32 => "sf",
72347416 64 => "df",
72357417 80 => "xf",
7236 128 => "tf",
7237 else => unreachable,
7418 128 => if (target.cpu.arch.isPowerPC()) "kf" else "tf",
72387419 } else unreachable;
72397420}
72407421
......@@ -7390,10 +7571,8 @@ fn fmtStringLiteral(str: []const u8, sentinel: ?u8) std.fmt.Alt(FormatStringCont
73907571 return .{ .data = .{ .str = str, .sentinel = sentinel } };
73917572}
73927573
7393fn undefPattern(comptime IntType: type) IntType {
7394 const int_info = @typeInfo(IntType).int;
7395 const UnsignedType = @Int(.unsigned, int_info.bits);
7396 return @bitCast(@as(UnsignedType, (1 << (int_info.bits | 1)) / 3));
7574fn undefPattern(comptime Result: type) Result {
7575 return @bitCast(@as(@Int(.unsigned, @bitSizeOf(Result)), (1 << (@bitSizeOf(Result) | 1)) / 3));
73977576}
73987577
73997578const FormatIntLiteralContext = struct {
......@@ -7580,11 +7759,9 @@ const FormatSignedIntLiteralSmall = struct {
75807759 case: std.fmt.Case,
75817760 pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void {
75827761 const bits = data.int_cty.bits(data.target);
7583 const max_int: i64 = @bitCast((@as(u64, 1) << @intCast(bits - 1)) - 1);
7584 const min_int: i64 = @bitCast(@as(u64, 1) << @intCast(bits - 1));
7585 if (data.val == max_int) {
7762 if (data.val == @as(i64, std.math.maxInt(i64)) >> @intCast(64 - bits)) {
75867763 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
7587 } else if (data.val == min_int) {
7764 } else if (data.val == @as(i64, std.math.minInt(i64)) >> @intCast(64 - bits)) {
75887765 return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)});
75897766 }
75907767 if (data.val < 0) try w.writeByte('-');
......@@ -7596,7 +7773,7 @@ const FormatSignedIntLiteralSmall = struct {
75967773 16 => try w.writeAll("0x"),
75977774 else => unreachable,
75987775 }
7599 // This `@abs` is safe thanks to the `min_int` case above.
7776 // This `@abs` is safe thanks to the min int check above.
76007777 try w.printInt(@abs(data.val), data.base, data.case, .{});
76017778 try w.writeAll(intLiteralSuffix(data.int_cty));
76027779 }
......@@ -7610,8 +7787,7 @@ const FormatUnsignedIntLiteralSmall = struct {
76107787 case: std.fmt.Case,
76117788 pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void {
76127789 const bits = data.int_cty.bits(data.target);
7613 const max_int: u64 = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits);
7614 if (data.val == max_int) {
7790 if (data.val == @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits)) {
76157791 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
76167792 }
76177793 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));
......@@ -7735,6 +7911,31 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 {
77357911 };
77367912}
77377913
7914const F80Repr = packed struct {
7915 mantissa: u64,
7916 exponent: u16,
7917
7918 fn write(repr: F80Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void {
7919 try w.print("zig_{s}_repr_f80({f}, {f})", .{
7920 if (is_global) "init" else "make",
7921 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.mantissa, is_global, 16, .lower),
7922 fmtUnsignedIntLiteralSmall(target, .uint16_t, repr.exponent, is_global, 16, .lower),
7923 });
7924 }
7925};
7926const F128Repr = packed struct {
7927 lo: u64,
7928 hi: u64,
7929
7930 fn write(repr: F128Repr, w: *Writer, target: *const std.Target, is_global: bool) Writer.Error!void {
7931 try w.print("zig_{s}_repr_f128({f}, {f})", .{
7932 if (is_global) "init" else "make",
7933 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.hi, is_global, 16, .lower),
7934 fmtUnsignedIntLiteralSmall(target, .uint64_t, repr.lo, is_global, 16, .lower),
7935 });
7936 }
7937};
7938
77387939const Materialize = struct {
77397940 local: CValue,
77407941
src/codegen/c/type/render_defs.zig+100-82
......@@ -21,16 +21,21 @@ pub fn defineAligned(
2121 if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {
2222 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});
2323 }
24 try w.print("{f}{f}{f}; /* align({d}) {f} */\n", .{
24 try w.print("{f}{f}{f};", .{
2525 cty.fmtDeclaratorPrefix(zcu),
2626 name_cty.fmtTypeName(zcu),
2727 cty.fmtDeclaratorSuffix(zcu),
28 });
29 if (!zcu.comp.config.root_strip) try w.print(" /* align({d}) {f} */", .{
2830 alignment.toByteUnits().?,
2931 ty.fmt(pt),
3032 });
33 try w.writeByte('\n');
3134}
3235/// Renders the definition of a big-int `struct`.
3336pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void {
37 const target = zcu.getTarget();
38 const bits = big.limb_size.bits() *| big.limbs_len;
3439 const name_cty: CType = .{ .bigint = .{
3540 .limb_size = big.limb_size,
3641 .limbs_len = big.limbs_len,
......@@ -41,12 +46,20 @@ pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error
4146 .elem_ty = &limb_cty,
4247 .nonstring = limb_cty.isStringElem(),
4348 } };
44 try w.print("{f} {{ {f}limbs{f}; }}; /* {d} bits */\n", .{
49 try w.print("{f} {{ {f}limbs{f}; }};", .{
4550 name_cty.fmtTypeName(zcu),
4651 array_cty.fmtDeclaratorPrefix(zcu),
4752 array_cty.fmtDeclaratorSuffix(zcu),
48 big.limb_size.bits() * @as(u17, big.limbs_len),
4953 });
54 if (!zcu.comp.config.root_strip) try w.print(" /* u{d}, i{d} */", .{ bits, bits });
55 try w.writeByte('\n');
56 try writeStaticAssertCTypeLayout(
57 name_cty,
58 std.zig.target.intByteSize(target, bits),
59 .fromByteUnits(std.zig.target.intAlignment(target, bits)),
60 w,
61 zcu,
62 );
5063}
5164
5265/// Renders a forward declaration of the `struct` which represents an error union whose payload type
......@@ -81,27 +94,28 @@ pub fn errunionDefineComplete(
8194 if (payload_ty.hasRuntimeBits(zcu)) {
8295 const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu);
8396 try w.print(
84 \\{f} {{ /* anyerror!{f} */
97 \\{f} {{
8598 \\ {f}payload{f};
8699 \\ {f}error{f};
87100 \\}};
88 \\
89101 , .{
90102 name_cty.fmtTypeName(zcu),
91 payload_ty.fmt(pt),
92103 payload_cty.fmtDeclaratorPrefix(zcu),
93104 payload_cty.fmtDeclaratorSuffix(zcu),
94105 error_cty.fmtDeclaratorPrefix(zcu),
95106 error_cty.fmtDeclaratorSuffix(zcu),
96107 });
97108 } else {
98 try w.print("{f} {{ {f}error{f}; }}; /* anyerror!{f} */\n", .{
109 try w.print("{f} {{ {f}error{f}; }};", .{
99110 name_cty.fmtTypeName(zcu),
100111 error_cty.fmtDeclaratorPrefix(zcu),
101112 error_cty.fmtDeclaratorSuffix(zcu),
102 payload_ty.fmt(pt),
103113 });
104114 }
115 if (!zcu.comp.config.root_strip) try w.print(" /* anyerror!{f} */", .{
116 payload_ty.fmt(pt),
117 });
118 try w.writeByte('\n');
105119}
106120
107121/// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that
......@@ -141,10 +155,13 @@ pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!vo
141155 },
142156 else => return,
143157 };
144 try w.print("typedef void {f}; /* {f} */\n", .{
158 try w.print("typedef void {f};", .{
145159 name_cty.fmtTypeName(zcu),
160 });
161 if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{
146162 ty.fmt(pt),
147163 });
164 try w.writeByte('\n');
148165}
149166
150167/// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the
......@@ -163,13 +180,13 @@ pub fn defineComplete(
163180
164181 ty.assertHasLayout(zcu);
165182
166 switch (ty.zigTypeTag(zcu)) {
183 const check_cty = check_cty: switch (ty.zigTypeTag(zcu)) {
167184 .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) {
168185 const name_cty: CType = .{ .@"fn" = ty };
169 try w.print("typedef void {f}; /* {f} */\n", .{
186 try w.print("typedef void {f};", .{
170187 name_cty.fmtTypeName(zcu),
171 ty.fmt(pt),
172188 });
189 break :check_cty null;
173190 } else {
174191 const ip = &zcu.intern_pool;
175192 const func_type = ip.indexToKey(ty.toIntern()).func_type;
......@@ -205,82 +222,82 @@ pub fn defineComplete(
205222 } else if (!any_params) {
206223 try w.writeAll("void");
207224 }
208 try w.print("){f}; /* {f} */\n", .{
225 try w.print("){f};", .{
209226 ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu),
210 ty.fmt(pt),
211227 });
228 break :check_cty null;
212229 },
213230 .@"enum" => {
214231 const name_cty: CType = .{ .@"enum" = ty };
215232 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);
216 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{
233 try w.print("typedef {f}{f}{f};", .{
217234 cty.fmtDeclaratorPrefix(zcu),
218235 name_cty.fmtTypeName(zcu),
219236 cty.fmtDeclaratorSuffix(zcu),
220 ty.fmt(pt),
221237 });
238 break :check_cty null;
222239 },
223 .@"struct" => if (ty.isTuple(zcu)) {
224 try defineTuple(ty, deps, arena, w, pt);
225 } else switch (ty.containerLayout(zcu)) {
226 .auto, .@"extern" => try defineStruct(ty, deps, arena, w, pt),
240 .@"struct" => if (ty.isTuple(zcu))
241 if (ty.hasRuntimeBits(zcu)) try defineTuple(ty, deps, arena, w, pt) else return
242 else switch (ty.containerLayout(zcu)) {
243 .auto, .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineStruct(ty, deps, arena, w, pt) else return,
227244 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
228245 },
229246 .@"union" => switch (ty.containerLayout(zcu)) {
230 .auto => try defineUnionAuto(ty, deps, arena, w, pt),
231 .@"extern" => try defineUnionExtern(ty, deps, arena, w, pt),
247 .auto => if (ty.hasRuntimeBits(zcu)) try defineUnionAuto(ty, deps, arena, w, pt) else return,
248 .@"extern" => if (ty.hasRuntimeBits(zcu)) try defineUnionExtern(ty, deps, arena, w, pt) else return,
232249 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
233250 },
234251 .pointer => if (ty.isSlice(zcu)) {
235252 const name_cty: CType = .{ .slice = ty };
236253 const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu);
237254 try w.print(
238 \\{f} {{ /* {f} */
255 \\{f} {{
239256 \\ {f}ptr{f};
240257 \\ size_t len;
241258 \\}};
242 \\
243259 , .{
244260 name_cty.fmtTypeName(zcu),
245 ty.fmt(pt),
246261 ptr_cty.fmtDeclaratorPrefix(zcu),
247262 ptr_cty.fmtDeclaratorSuffix(zcu),
248263 });
249 // Don't bother with `writeStaticAssertLayout`---there's not really any way we could mess
250 // slices up, and they're all obviously the same layout.
251 },
264 break :check_cty switch (ty.toIntern()) {
265 .slice_const_u8_sentinel_0_type => name_cty,
266 else => null,
267 };
268 } else return,
252269 .optional => switch (CType.classifyOptional(ty, zcu)) {
253270 .error_set,
254271 .ptr_like,
255272 .slice_like,
256273 .npv_payload,
257 => {},
274 => return,
258275
259276 .opv_payload => {
260277 const name_cty: CType = .{ .opt = ty };
261 try w.print("{f} {{ bool is_null; }}; /* {f} */\n", .{
278 try w.print("{f} {{ bool is_null; }};", .{
262279 name_cty.fmtTypeName(zcu),
263 ty.fmt(pt),
264280 });
265 try writeStaticAssertLayout(ty, name_cty, w, zcu);
281 break :check_cty switch (ty.toIntern()) {
282 .optional_noreturn_type => name_cty,
283 else => null,
284 };
266285 },
267286
268287 .@"struct" => {
269288 const name_cty: CType = .{ .opt = ty };
270289 const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu);
271290 try w.print(
272 \\{f} {{ /* {f} */
291 \\{f} {{
273292 \\ {f}payload{f};
274293 \\ bool is_null;
275294 \\}};
276 \\
277295 , .{
278296 name_cty.fmtTypeName(zcu),
279 ty.fmt(pt),
280297 payload_cty.fmtDeclaratorPrefix(zcu),
281298 payload_cty.fmtDeclaratorSuffix(zcu),
282299 });
283 try writeStaticAssertLayout(ty, name_cty, w, zcu);
300 break :check_cty name_cty;
284301 },
285302 },
286303 .array => if (ty.hasRuntimeBits(zcu)) {
......@@ -295,14 +312,13 @@ pub fn defineComplete(
295312 break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu);
296313 },
297314 } };
298 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{
315 try w.print("{f} {{ {f}array{f}; }};", .{
299316 name_cty.fmtTypeName(zcu),
300317 array_cty.fmtDeclaratorPrefix(zcu),
301318 array_cty.fmtDeclaratorSuffix(zcu),
302 ty.fmt(pt),
303319 });
304 try writeStaticAssertLayout(ty, name_cty, w, zcu);
305 },
320 break :check_cty name_cty;
321 } else return,
306322 .vector => if (ty.hasRuntimeBits(zcu)) {
307323 const name_cty: CType = .{ .vec = ty };
308324 const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu);
......@@ -311,16 +327,20 @@ pub fn defineComplete(
311327 .elem_ty = &elem_cty,
312328 .nonstring = elem_cty.isStringElem(),
313329 } };
314 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{
330 try w.print("{f} {{ {f}array{f}; }};", .{
315331 name_cty.fmtTypeName(zcu),
316332 array_cty.fmtDeclaratorPrefix(zcu),
317333 array_cty.fmtDeclaratorSuffix(zcu),
318 ty.fmt(pt),
319334 });
320 try writeStaticAssertLayout(ty, name_cty, w, zcu);
321 },
322 else => {},
323 }
335 break :check_cty name_cty;
336 } else return,
337 else => return,
338 };
339 if (!zcu.comp.config.root_strip) try w.print(" /* {f} */", .{
340 ty.fmt(pt),
341 });
342 try w.writeByte('\n');
343 if (check_cty) |cty| try writeStaticAssertTypeLayout(ty, cty, w, zcu);
324344}
325345fn defineBitpack(
326346 ty: Type,
......@@ -328,16 +348,16 @@ fn defineBitpack(
328348 arena: Allocator,
329349 w: *Writer,
330350 pt: Zcu.PerThread,
331) (Allocator.Error || Writer.Error)!void {
351) (Allocator.Error || Writer.Error)!?CType {
332352 const zcu = pt.zcu;
333353 const name_cty: CType = .{ .bitpack = ty };
334354 const cty: CType = try .lower(ty.backingIntType(zcu), deps, arena, zcu);
335 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{
355 try w.print("typedef {f}{f}{f};", .{
336356 cty.fmtDeclaratorPrefix(zcu),
337357 name_cty.fmtTypeName(zcu),
338358 cty.fmtDeclaratorSuffix(zcu),
339 ty.fmt(pt),
340359 });
360 return null;
341361}
342362fn defineTuple(
343363 ty: Type,
......@@ -345,9 +365,8 @@ fn defineTuple(
345365 arena: Allocator,
346366 w: *Writer,
347367 pt: Zcu.PerThread,
348) (Allocator.Error || Writer.Error)!void {
368) (Allocator.Error || Writer.Error)!CType {
349369 const zcu = pt.zcu;
350 if (!ty.hasRuntimeBits(zcu)) return;
351370 const ip = &zcu.intern_pool;
352371 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
353372
......@@ -367,9 +386,8 @@ fn defineTuple(
367386 } else true;
368387
369388 const name_cty: CType = .{ .@"struct" = ty };
370 try w.print("{f} {{ /* {f} */\n", .{
389 try w.print("{f} {{\n", .{
371390 name_cty.fmtTypeName(zcu),
372 ty.fmt(pt),
373391 });
374392 var zig_offset: u64 = 0;
375393 var c_offset: u64 = 0;
......@@ -403,9 +421,8 @@ fn defineTuple(
403421 zig_offset += field_size;
404422 c_offset += field_size;
405423 }
406 try w.writeAll("};\n");
407
408 try writeStaticAssertLayout(ty, name_cty, w, zcu);
424 try w.writeAll("};");
425 return name_cty;
409426}
410427fn defineStruct(
411428 ty: Type,
......@@ -413,9 +430,8 @@ fn defineStruct(
413430 arena: Allocator,
414431 w: *Writer,
415432 pt: Zcu.PerThread,
416) (Allocator.Error || Writer.Error)!void {
433) (Allocator.Error || Writer.Error)!CType {
417434 const zcu = pt.zcu;
418 if (!ty.hasRuntimeBits(zcu)) return;
419435 const ip = &zcu.intern_pool;
420436
421437 const struct_type = ip.loadStructType(ty.toIntern());
......@@ -457,9 +473,8 @@ fn defineStruct(
457473
458474 if (pack) try w.writeAll("zig_packed(");
459475 const name_cty: CType = .{ .@"struct" = ty };
460 try w.print("{f} {{ /* {f} */\n", .{
476 try w.print("{f} {{\n", .{
461477 name_cty.fmtTypeName(zcu),
462 ty.fmt(pt),
463478 });
464479 var it = struct_type.iterateRuntimeOrder(ip);
465480 var offset: u64 = 0;
......@@ -497,9 +512,8 @@ fn defineStruct(
497512 assert(struct_type.alignment.forward(offset) == struct_type.size);
498513 try w.writeByte('}');
499514 if (pack) try w.writeByte(')');
500 try w.writeAll(";\n");
501
502 try writeStaticAssertLayout(ty, name_cty, w, zcu);
515 try w.writeByte(';');
516 return name_cty;
503517}
504518fn defineUnionAuto(
505519 ty: Type,
......@@ -507,9 +521,8 @@ fn defineUnionAuto(
507521 arena: Allocator,
508522 w: *Writer,
509523 pt: Zcu.PerThread,
510) (Allocator.Error || Writer.Error)!void {
524) (Allocator.Error || Writer.Error)!CType {
511525 const zcu = pt.zcu;
512 if (!ty.hasRuntimeBits(zcu)) return;
513526 const ip = &zcu.intern_pool;
514527
515528 const union_type = ip.loadUnionType(ty.toIntern());
......@@ -553,9 +566,8 @@ fn defineUnionAuto(
553566 const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu);
554567
555568 const name_cty: CType = .{ .union_auto = ty };
556 try w.print("{f} {{ /* {f} */\n", .{
569 try w.print("{f} {{\n", .{
557570 name_cty.fmtTypeName(zcu),
558 ty.fmt(pt),
559571 });
560572 if (payload_has_bits) {
561573 try w.writeByte(' ');
......@@ -587,9 +599,8 @@ fn defineUnionAuto(
587599 tag_cty.fmtDeclaratorSuffix(zcu),
588600 });
589601 }
590 try w.writeAll("};\n");
591
592 try writeStaticAssertLayout(ty, name_cty, w, zcu);
602 try w.writeAll("};");
603 return name_cty;
593604}
594605fn defineUnionExtern(
595606 ty: Type,
......@@ -597,9 +608,8 @@ fn defineUnionExtern(
597608 arena: Allocator,
598609 w: *Writer,
599610 pt: Zcu.PerThread,
600) (Allocator.Error || Writer.Error)!void {
611) (Allocator.Error || Writer.Error)!CType {
601612 const zcu = pt.zcu;
602 if (!ty.hasRuntimeBits(zcu)) return;
603613 const ip = &zcu.intern_pool;
604614
605615 const union_type = ip.loadUnionType(ty.toIntern());
......@@ -636,9 +646,8 @@ fn defineUnionExtern(
636646 if (pack) try w.writeAll("zig_packed(");
637647
638648 const name_cty: CType = .{ .union_extern = ty };
639 try w.print("{f} {{ /* {f} */\n", .{
649 try w.print("{f} {{\n", .{
640650 name_cty.fmtTypeName(zcu),
641 ty.fmt(pt),
642651 });
643652
644653 for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| {
......@@ -659,9 +668,8 @@ fn defineUnionExtern(
659668 }
660669 try w.writeByte('}');
661670 if (pack) try w.writeByte(')');
662 try w.writeAll(";\n");
663
664 try writeStaticAssertLayout(ty, name_cty, w, zcu);
671 try w.writeByte(';');
672 return name_cty;
665673}
666674
667675/// Writes an annotation which, placed before a struct/union field declaration with field type `ty`,
......@@ -680,19 +688,29 @@ fn writeFieldAlign(
680688}
681689
682690/// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`.
683fn writeStaticAssertLayout(
691pub fn writeStaticAssertTypeLayout(
684692 ty: Type,
685693 cty: CType,
686694 w: *Writer,
687695 zcu: *const Zcu,
696) Writer.Error!void {
697 try writeStaticAssertCTypeLayout(cty, ty.abiSize(zcu), ty.abiAlignment(zcu), w, zcu);
698}
699
700/// Emits static assertions that the size and alignment of `cty` match the provided values.
701pub fn writeStaticAssertCTypeLayout(
702 cty: CType,
703 expected_size: u64,
704 expected_alignment: Alignment,
705 w: *Writer,
706 zcu: *const Zcu,
688707) Writer.Error!void {
689708 try w.print(
690 \\zig_static_assert(sizeof ({f}) == {d}, "incorrect size");
691 \\zig_static_assert(_Alignof ({f}) == {d}, "incorrect alignment");
709 \\zig_static_assert(sizeof({f}) == {d} && zig_alignOf({f}) == {d}, "abi mismatch");
692710 \\
693711 , .{
694 cty.fmtTypeName(zcu), ty.abiSize(zcu),
695 cty.fmtTypeName(zcu), ty.abiAlignment(zcu).toByteUnits().?,
712 cty.fmtTypeName(zcu), expected_size,
713 cty.fmtTypeName(zcu), expected_alignment.toByteUnits().?,
696714 });
697715}
698716
src/link.zig+1-1
......@@ -1238,7 +1238,7 @@ pub const File = struct {
12381238 }
12391239
12401240 switch (base.tag) {
1241 inline .elf2, .coff2, .wasm => |tag| {
1241 inline .elf2, .coff2, .wasm, .c => |tag| {
12421242 dev.check(tag.devFeature());
12431243 try @as(*tag.Type(), @fieldParentPtr("base", base)).prelink(base.comp.link_prog_node);
12441244 },
src/link/C.zig+25-24
......@@ -43,6 +43,8 @@ type_dependencies: std.ArrayList(link.ConstPool.Index),
4343/// one array.
4444align_dependency_masks: std.ArrayList(u64),
4545
46/// Emitted at the top of the file. This can be cached since it only depends on the target.
47header: String,
4648/// All NAVs, regardless of whether they are functions or simple constants, are put in this map.
4749navs: std.array_hash_map.Auto(InternPool.Nav.Index, RenderedDecl),
4850/// All UAVs which may be referenced are in this map. The UAV alignment is not included in the
......@@ -404,9 +406,8 @@ pub fn createEmpty(
404406 emit: Path,
405407 options: link.File.OpenOptions,
406408) !*C {
409 assert(comp.root_mod.resolved_target.result.ofmt == .c);
407410 const io = comp.io;
408 const target = &comp.root_mod.resolved_target.result;
409 assert(target.ofmt == .c);
410411 const optimize_mode = comp.root_mod.optimize_mode;
411412 const use_lld = build_options.have_llvm and comp.config.use_lld;
412413 const use_llvm = comp.config.use_llvm;
......@@ -422,9 +423,8 @@ pub fn createEmpty(
422423 });
423424 errdefer file.close(io);
424425
425 const c_file = try arena.create(C);
426
427 c_file.* = .{
426 const c = try arena.create(C);
427 c.* = .{
428428 .base = .{
429429 .tag = .c,
430430 .comp = comp,
......@@ -439,6 +439,7 @@ pub fn createEmpty(
439439 .string_bytes = .empty,
440440 .type_dependencies = .empty,
441441 .align_dependency_masks = .empty,
442 .header = .empty,
442443 .navs = .empty,
443444 .uavs = .empty,
444445 .type_pool = .empty,
......@@ -447,8 +448,7 @@ pub fn createEmpty(
447448 .exported_navs = .empty,
448449 .exported_uavs = .empty,
449450 };
450
451 return c_file;
451 return c;
452452}
453453
454454pub fn deinit(c: *C) void {
......@@ -469,6 +469,21 @@ pub fn deinit(c: *C) void {
469469 c.exported_uavs.deinit(gpa);
470470}
471471
472pub fn prelink(c: *C, prog_node: std.Progress.Node) !void {
473 const comp = c.base.comp;
474
475 const sub_prog_node = prog_node.start("Generate Header", 0);
476 defer sub_prog_node.end();
477
478 var header_aw: std.Io.Writer.Allocating = .init(comp.gpa);
479 defer header_aw.deinit();
480 codegen.genHeader(comp.zcu.?, &header_aw.writer) catch |err| switch (err) {
481 error.WriteFailed => return error.OutOfMemory,
482 else => |e| return e,
483 };
484 c.header = try c.addString(&.{header_aw.written()});
485}
486
472487pub fn updateContainerType(
473488 c: *C,
474489 pt: Zcu.PerThread,
......@@ -727,7 +742,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
727742 const io = comp.io;
728743 const zcu = c.base.comp.zcu.?;
729744 const ip = &zcu.intern_pool;
730 const target = zcu.getTarget();
731745 const active = zcu.activate(tid);
732746 defer active.deactivate();
733747 const pt = active.pt;
......@@ -943,7 +957,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
943957 // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin
944958 // to build the output buffer. Our strategy is to emit the C source in this order:
945959 //
946 // * ABI defines and `#include "zig.h"`
960 // * Header
947961 // * Big-int type definitions
948962 // * Other CType definitions (traversing the dependency graph to sort topologically)
949963 // * Global assembly
......@@ -968,7 +982,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
968982
969983 // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers!
970984
971 try f.all_buffers.ensureUnusedCapacity(gpa, 3 + // ABI defines and `#include "zig.h"`
985 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + // Header
972986 1 + // Big-int type definitions
973987 need_types.count() + // `RenderedType.fwd_decl` (worst-case)
974988 need_types.count() + // `RenderedType.definition`
......@@ -984,20 +998,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
984998 need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>")
985999 need_navs.count() * 2); // NAV definitions ("static ", "<definition body>")
9861000
987 // ABI defines and `#include "zig.h"`
988 switch (target.abi) {
989 .msvc, .itanium => f.appendBufAssumeCapacity("#define ZIG_TARGET_ABI_MSVC\n"),
990 else => {},
991 }
992 f.appendBufAssumeCapacity(try std.fmt.allocPrint(
993 arena,
994 "#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n",
995 .{target.cMaxIntAlignment()},
996 ));
997 f.appendBufAssumeCapacity(
998 \\#include "zig.h"
999 \\
1000 );
1001 f.appendBufAssumeCapacity(c.header.get(c));
10011002
10021003 // Big-int type definitions
10031004 var bigint_aw: std.Io.Writer.Allocating = .init(gpa);
test/behavior/abs.zig-2
......@@ -144,7 +144,6 @@ test "@abs big int <= 128 bits" {
144144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146146 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
147 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
148147
149148 try comptime testAbsSignedBigInt();
150149 try testAbsSignedBigInt();
......@@ -256,7 +255,6 @@ fn testAbsFloats(comptime T: type) !void {
256255
257256test "@abs int vectors" {
258257 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
259 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
260258 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
261259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
262260 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/align.zig-2
......@@ -547,7 +547,6 @@ test "sub-aligned pointer field access" {
547547}
548548
549549test "alignment of zero-bit types is respected" {
550 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
551550 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
552551 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
553552 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
......@@ -582,7 +581,6 @@ test "zero-bit fields in extern struct pad fields appropriately" {
582581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
583582 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
584583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
585 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
586584
587585 const S = extern struct {
588586 x: u8,
test/behavior/basic.zig-1
......@@ -800,7 +800,6 @@ test "extern variable with non-pointer opaque type" {
800800 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
801801 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
802802 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
803 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
804803 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
805804
806805 @export(&var_to_export, .{ .name = "opaque_extern_var" });
test/behavior/bit_shifting.zig-1
......@@ -147,7 +147,6 @@ test "Saturating Shift Left where lhs is of a computed type" {
147147
148148test "Saturating Shift Left" {
149149 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
150 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
151150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
152151 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
153152 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/bitcast.zig+1-6
......@@ -210,7 +210,6 @@ test "triple level result location with bitcast sandwich passed as tuple element
210210
211211test "@bitCast packed struct of floats" {
212212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
214213 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
215214 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
216215 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -247,7 +246,6 @@ test "@bitCast packed struct of floats" {
247246
248247test "comptime @bitCast packed struct to int and back" {
249248 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
250 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
251249 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
252250 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
253251 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -283,7 +281,6 @@ test "comptime @bitCast packed struct to int and back" {
283281test "bitcast vector to integer and back" {
284282 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
285283 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
287284 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
288285 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
289286
......@@ -329,10 +326,10 @@ fn bitCastWrapper128(x: f128) u128 {
329326}
330327test "bitcast nan float does not modify signaling bit" {
331328 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
333329 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
334330 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
335331 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
332 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
336333
337334 const snan_u16: u16 = 0x7D00;
338335 const snan_u32: u32 = 0x7FA00000;
......@@ -383,7 +380,6 @@ test "bitcast nan float does not modify signaling bit" {
383380test "@bitCast of packed struct of bools all true" {
384381 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
385382 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
386 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
387383 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
388384 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
389385
......@@ -404,7 +400,6 @@ test "@bitCast of packed struct of bools all true" {
404400test "@bitCast of packed struct of bools all false" {
405401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
406402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
407 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
408403 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
409404
410405 const P = packed struct {
test/behavior/cast.zig+1-10
......@@ -134,7 +134,6 @@ test "@intFromFloat > 128 bits" {
134134 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
135135 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
136136 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
137 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
138137
139138 try testIntFromFloat(f16, 1024, u140, 1024);
140139 try testIntFromFloat(f16, -1024, i140, -1024);
......@@ -160,7 +159,6 @@ test "@floatFromInt > 128 bits" {
160159 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
161160 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
162161 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
163 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
164162
165163 try testFloatFromInt(u140, 1024, f16, 1024);
166164 try testFloatFromInt(i140, -1024, f16, -1024);
......@@ -182,7 +180,6 @@ test "@floatFromInt(f80)" {
182180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
183181 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184182 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
185 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
186183 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
187184
188185 const S = struct {
......@@ -281,6 +278,7 @@ test "type coercion from int to float" {
281278test "@intFromFloat" {
282279 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
283280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
281
284282 try testIntFromFloats();
285283 try comptime testIntFromFloats();
286284}
......@@ -1473,11 +1471,6 @@ fn foobar(func: PFN_void) !void {
14731471test "cast function with an opaque parameter" {
14741472 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
14751473
1476 if (builtin.zig_backend == .stage2_c) {
1477 // https://github.com/ziglang/zig/issues/16845
1478 return error.SkipZigTest;
1479 }
1480
14811474 const Container = struct {
14821475 const Ctx = opaque {};
14831476 ctx: *Ctx,
......@@ -1724,7 +1717,6 @@ test "cast f16 to wider types" {
17241717 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17251718 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
17261719 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1727 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
17281720 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
17291721 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag == .macos) return error.SkipZigTest;
17301722
......@@ -1831,7 +1823,6 @@ test "pointer to empty struct literal to mutable slice" {
18311823
18321824test "coerce between pointers of compatible differently-named floats" {
18331825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1834 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest;
18351826 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
18361827 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18371828 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/cast_int.zig-1
......@@ -168,7 +168,6 @@ test "@intCast <= 64 bits" {
168168
169169test "@intCast > 128 bits" {
170170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
171 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
172171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
173172
174173 try testIntCast(u8, 123, u140, 123);
test/behavior/eval.zig-1
......@@ -513,7 +513,6 @@ test "runtime 128 bit integer division" {
513513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
514514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
515515 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
516 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
517516 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
518517
519518 var a: u128 = 152313999999999991610955792383;
test/behavior/extern.zig-1
......@@ -3,7 +3,6 @@ const std = @import("std");
33const expect = std.testing.expect;
44
55test "anyopaque extern symbol" {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
76 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
87 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
98
test/behavior/field_parent_ptr.zig-2
......@@ -586,7 +586,6 @@ test "@fieldParentPtr extern struct last zero-bit field" {
586586}
587587
588588test "@fieldParentPtr unaligned packed struct" {
589 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
590589 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
591590 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
592591 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -725,7 +724,6 @@ test "@fieldParentPtr unaligned packed struct" {
725724}
726725
727726test "@fieldParentPtr aligned packed struct" {
728 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
729727 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
730728 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
731729 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/floatop.zig-8
......@@ -142,7 +142,6 @@ test "cmp f64" {
142142
143143test "cmp f128" {
144144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
146145 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
147146 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
148147
......@@ -152,7 +151,6 @@ test "cmp f128" {
152151
153152test "cmp f80/c_longdouble" {
154153 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
156154 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
157155 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
158156
......@@ -253,7 +251,6 @@ test "vector cmp f64" {
253251test "vector cmp f128" {
254252 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
255253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
257254 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
258255 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
259256 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .powerpc64le) return error.SkipZigTest;
......@@ -1055,7 +1052,6 @@ test "@abs f32/f64" {
10551052
10561053test "@abs f80/f128/c_longdouble" {
10571054 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1058 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
10591055 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10601056 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
10611057 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -1173,7 +1169,6 @@ test "@floor f32/f64" {
11731169
11741170test "@floor f80/f128/c_longdouble" {
11751171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1176 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
11771172 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11781173 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11791174 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -1262,7 +1257,6 @@ test "@ceil f32/f64" {
12621257
12631258test "@ceil f80/f128/c_longdouble" {
12641259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1265 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
12661260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12671261 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
12681262 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -1282,7 +1276,6 @@ test "@ceil f80/f128/c_longdouble" {
12821276
12831277test "@ceil f80 maxInt(u64)" {
12841278 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1285 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
12861279 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12871280 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
12881281 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -1369,7 +1362,6 @@ test "@trunc f32/f64" {
13691362
13701363test "@trunc f80/f128/c_longdouble" {
13711364 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1372 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
13731365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
13741366 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13751367 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/fn.zig-1
......@@ -147,7 +147,6 @@ fn fnWithUnreachable() noreturn {
147147
148148test "extern struct with stdcallcc fn pointer" {
149149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
150 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .x86) return error.SkipZigTest;
151150 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
152151
153152 const S = extern struct {
test/behavior/math.zig-29
......@@ -873,7 +873,6 @@ test "umax wrapped squaring" {
873873test "128-bit multiplication" {
874874 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
875875 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
876 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
877876 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
878877
879878 {
......@@ -968,7 +967,6 @@ test "@addWithOverflow > 128 bits" {
968967 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
969968 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
970969 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
971 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
972970
973971 try testAddWithOverflow(u129, 4, 105, 109, 0);
974972 try testAddWithOverflow(u129, 1000, 100, 1100, 0);
......@@ -1136,7 +1134,6 @@ test "Multiply unwrap error * immediate" {
11361134
11371135test "@mulWithOverflow bitsize 128 bits" {
11381136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1139 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
11401137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11411138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11421139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1163,7 +1160,6 @@ test "@mulWithOverflow bitsize 128 bits" {
11631160
11641161test "@mulWithOverflow > 128 bits" {
11651162 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1166 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
11671163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11681164
11691165 try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0);
......@@ -1193,7 +1189,6 @@ test "@mulWithOverflow > 128 bits" {
11931189
11941190test "@mulWithOverflow bitsize 256 bits" {
11951191 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1196 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
11971192 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11981193 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11991194
......@@ -1298,7 +1293,6 @@ test "@subWithOverflow > 128 bits" {
12981293 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12991294 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13001295 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1301 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
13021296
13031297 try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1);
13041298 try testSubWithOverflow(u129, 1000, 100, 900, 0);
......@@ -1389,7 +1383,6 @@ test "@shlWithOverflow > 64 bits" {
13891383
13901384test "@shlWithOverflow > 128 bits" {
13911385 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1392 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
13931386 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13941387
13951388 try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0);
......@@ -1419,7 +1412,6 @@ fn testAnd(comptime T: type, a: T, b: T, expected: T) !void {
14191412
14201413test "and > 128 bits" {
14211414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1422 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14231415
14241416 try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88);
14251417 try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100);
......@@ -1448,7 +1440,6 @@ fn testOr(comptime T: type, a: T, b: T, expected: T) !void {
14481440
14491441test "or > 128 bits" {
14501442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1451 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14521443
14531444 try testOr(u140, 0, 1 << 139, 1 << 139);
14541445 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);
......@@ -1477,7 +1468,6 @@ fn testXor(comptime T: type, a: T, b: T, expected: T) !void {
14771468
14781469test "xor > 128 bits" {
14791470 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1480 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
14811471
14821472 try testXor(u140, 0, maxInt(u140), maxInt(u140));
14831473 try testXor(u140, 1 << 139, 1 << 139, 0);
......@@ -1506,7 +1496,6 @@ fn testNot(comptime T: type, a: T, expected: T) !void {
15061496
15071497test "not > 128 bits" {
15081498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1509 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15101499
15111500 try testNot(u140, 0, maxInt(u140));
15121501 try testNot(u140, maxInt(u140), 0);
......@@ -1535,7 +1524,6 @@ fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
15351524
15361525test "shl > 128 bits" {
15371526 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1538 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15391527
15401528 try testShl(u140, 1 << 5, 10, 1 << 15);
15411529 try testShl(u140, 3, 138, (1 << 139) | (1 << 138));
......@@ -1564,7 +1552,6 @@ fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
15641552
15651553test "shr > 128 bits" {
15661554 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1567 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15681555
15691556 try testShr(u140, 1 << 139, 39, 1 << 100);
15701557 try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1);
......@@ -1593,7 +1580,6 @@ fn testClz(comptime T: type, a: T, expected: u16) !void {
15931580
15941581test "@clz > 128 bits" {
15951582 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1596 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
15971583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
15981584
15991585 try testClz(u140, 0, 140);
......@@ -1623,7 +1609,6 @@ fn testCtz(comptime T: type, a: T, expected: u16) !void {
16231609
16241610test "@ctz > 128 bits" {
16251611 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1626 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16271612 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16281613
16291614 try testCtz(u140, 0, 140);
......@@ -1653,7 +1638,6 @@ fn testPopCount(comptime T: type, a: T, expected: u16) !void {
16531638
16541639test "@popCount > 128 bits" {
16551640 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1656 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16571641 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16581642
16591643 try testPopCount(u140, 0, 0);
......@@ -1683,7 +1667,6 @@ fn testBitReverse(comptime T: type, a: T, expected: T) !void {
16831667
16841668test "@bitReverse > 128 bits" {
16851669 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1686 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16871670 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16881671
16891672 try testBitReverse(u140, 1 << 139, 1);
......@@ -1713,7 +1696,6 @@ fn testByteSwap(comptime T: type, a: T, expected: T) !void {
17131696
17141697test "@byteSwap > 128 bits" {
17151698 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1716 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
17171699 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17181700
17191701 try testByteSwap(u144, 1 << 136, 1);
......@@ -1743,7 +1725,6 @@ fn testMax(comptime T: type, a: T, b: T, expected: T) !void {
17431725
17441726test "@max > 128 bits" {
17451727 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1746 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
17471728 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17481729
17491730 try testMax(u140, 0, maxInt(u140), maxInt(u140));
......@@ -1773,7 +1754,6 @@ fn testMin(comptime T: type, a: T, b: T, expected: T) !void {
17731754
17741755test "@min > 128 bits" {
17751756 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1776 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
17771757 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17781758
17791759 try testMin(u140, 0, maxInt(u140), 0);
......@@ -1803,7 +1783,6 @@ fn testAbs(comptime T: type, a: T, expected: anytype) !void {
18031783
18041784test "@abs > 128 bits" {
18051785 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1806 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18071786
18081787 try testAbs(u140, 0, 0);
18091788 try testAbs(u140, 1 << 139, 1 << 139);
......@@ -1827,7 +1806,6 @@ fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void {
18271806
18281807test "@rem > 128 bits" {
18291808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1830 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18311809 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18321810
18331811 try testRem(u140, 0, maxInt(u140), 0);
......@@ -1855,7 +1833,6 @@ fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void {
18551833
18561834test "@mod > 128 bits" {
18571835 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1858 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18591836 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18601837
18611838 try testMod(u140, 0, maxInt(u140), 0);
......@@ -1883,7 +1860,6 @@ fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !vo
18831860
18841861test "@divFloor > 128 bits" {
18851862 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1886 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
18871863 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18881864
18891865 try testDivFloor(u140, 0, maxInt(u140), 0);
......@@ -1912,7 +1888,6 @@ fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !voi
19121888
19131889test "@divCeil > 128 bits" {
19141890 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1915 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
19161891 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19171892
19181893 try testDivCeil(u140, 0, maxInt(u140), 0);
......@@ -1941,7 +1916,6 @@ fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !vo
19411916
19421917test "@divTrunc > 128 bits" {
19431918 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1944 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
19451919 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
19461920
19471921 try testDivTrunc(u140, 0, maxInt(u140), 0);
......@@ -2166,7 +2140,6 @@ test "remainder division" {
21662140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21672141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
21682142 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2169 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
21702143 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
21712144
21722145 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
......@@ -2315,7 +2288,6 @@ test "@round f80" {
23152288 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23162289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23172290 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2318 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
23192291 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23202292
23212293 try testRound(f80, 12.0);
......@@ -2326,7 +2298,6 @@ test "@round f128" {
23262298 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
23272299 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
23282300 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2329 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
23302301 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
23312302
23322303 try testRound(f128, 12.0);
test/behavior/maximum_minimum.zig-1
......@@ -115,7 +115,6 @@ test "@min/max for floats" {
115115 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
116116 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
117117 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
118 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
119118 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
120119
121120 const S = struct {
test/behavior/muladd.zig-4
......@@ -49,7 +49,6 @@ test "@mulAdd f80" {
4949 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
5050 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5151 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
5352 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5453
5554 try comptime testMulAdd80();
......@@ -68,7 +67,6 @@ test "@mulAdd f128" {
6867 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6968 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7069 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
7270 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7371
7472 try comptime testMulAdd128();
......@@ -169,7 +167,6 @@ test "vector f80" {
169167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
170168 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
171169 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
172 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
173170 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
174171
175172 try comptime vector80();
......@@ -194,7 +191,6 @@ test "vector f128" {
194191 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
195192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
196193 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
197 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
198194 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
199195
200196 try comptime vector128();
test/behavior/packed-struct.zig-4
......@@ -404,7 +404,6 @@ test "nested packed struct field pointers" {
404404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
405405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
406406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
407 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access
408407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
409408 const S2 = packed struct {
410409 base: u8,
......@@ -579,7 +578,6 @@ test "packed struct fields modification" {
579578}
580579
581580test "nested packed struct field access test" {
582 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
583581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
584582 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
585583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -733,7 +731,6 @@ test "nested packed struct at non-zero offset 2" {
733731 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
734732 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
735733 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
736 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
737734 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
738735
739736 const S = struct {
......@@ -1171,7 +1168,6 @@ test "packed struct equality" {
11711168
11721169test "packed struct equality ignores padding bits" {
11731170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1174 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
11751171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11761172
11771173 const S = packed struct { b: bool };
test/behavior/pointers.zig+1-1
......@@ -275,7 +275,7 @@ test "compare equality of optional and non-optional pointer" {
275275}
276276
277277test "allowzero pointer and slice" {
278 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
278 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
279279 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
280280 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
281281 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/saturating_arithmetic.zig-7
......@@ -144,7 +144,6 @@ test "saturating multiplication <= 32 bits" {
144144 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
145145 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
146146 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
147 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
148147 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
149148
150149 try testSatMul(u8, 0, maxInt(u8), 0);
......@@ -238,7 +237,6 @@ test "saturating multiplication" {
238237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
239238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
240239 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
241 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
242240 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
243241
244242 const S = struct {
......@@ -313,7 +311,6 @@ test "saturating shift-left" {
313311
314312test "saturating shift-left large rhs" {
315313 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
316 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
317314 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
318315 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
319316 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
......@@ -361,7 +358,6 @@ test "saturating shl uses the LHS type" {
361358
362359test "sat add > 128 bits" {
363360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
364 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
365361 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
366362
367363 try testSatAdd(u140, 0, 0, 0);
......@@ -377,7 +373,6 @@ test "sat add > 128 bits" {
377373
378374test "sat sub > 128 bits" {
379375 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
380 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
381376 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
382377
383378 try testSatSub(u140, 0, 1, 0);
......@@ -393,7 +388,6 @@ test "sat sub > 128 bits" {
393388
394389test "sat mul > 128 bits" {
395390 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
396 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
397391 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
398392
399393 try testSatMul(u140, 0, maxInt(u140), 0);
......@@ -409,7 +403,6 @@ test "sat mul > 128 bits" {
409403
410404test "sat shl > 128 bits" {
411405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
412 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
413406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
414407
415408 try testSatShl(u140, 0, u8, 17, 0);
test/behavior/struct.zig+2-6
......@@ -535,7 +535,6 @@ test "zero-bit field in packed struct" {
535535test "packed struct with non-ABI-aligned field" {
536536 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
537537 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
538 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
539538 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
540539 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
541540 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -792,7 +791,6 @@ test "non-packed struct with u128 entry in union" {
792791 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
793792 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
794793 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
795 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
796794 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
797795
798796 const U = union(enum) {
......@@ -1539,7 +1537,6 @@ test "instantiate struct with comptime field" {
15391537}
15401538
15411539test "struct field pointer has correct alignment" {
1542 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
15431540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15441541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15451542 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -1569,7 +1566,6 @@ test "struct field pointer has correct alignment" {
15691566}
15701567
15711568test "extern struct field pointer has correct alignment" {
1572 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
15731569 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
15741570 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15751571 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -2007,7 +2003,6 @@ test "initiate global variable with runtime value" {
20072003}
20082004
20092005test "struct containing optional pointer to array of @This()" {
2010 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
20112006 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
20122007
20132008 const S = struct {
......@@ -2266,7 +2261,8 @@ test "struct contains aligned pointer to itself through type decl" {
22662261
22672262test "struct contains underaligned field with overaligned pointer to itself" {
22682263 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2269 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2264 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
2265
22702266 const S = struct {
22712267 ptr: *align(8) @This() align(1),
22722268 };
test/behavior/switch_loop.zig+1-2
......@@ -223,7 +223,6 @@ test "unanalyzed continue with operand" {
223223
224224test "switch loop on larger than pointer integer" {
225225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
226 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
227226 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
228227
229228 var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined;
......@@ -268,7 +267,7 @@ test "switch loop on non-exhaustive enum" {
268267
269268test "switch loop with discarded tag capture" {
270269 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
271 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
270
272271 const S = struct {
273272 const U = union(enum) {
274273 a: u32,
test/behavior/truncate.zig-1
......@@ -49,7 +49,6 @@ fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void {
4949
5050test "@truncate > 128 bits" {
5151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
5352 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
5453
5554 try testTruncate(u140, 0, u128, 0);
test/behavior/union.zig-6
......@@ -1437,7 +1437,6 @@ test "coerce enum literal to union in result loc" {
14371437}
14381438
14391439test "defined-layout union field pointer has correct alignment" {
1440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14411440 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14421441 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14431442 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -1472,7 +1471,6 @@ test "defined-layout union field pointer has correct alignment" {
14721471}
14731472
14741473test "undefined-layout union field pointer has correct alignment" {
1475 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14761474 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14771475 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14781476 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -1758,8 +1756,6 @@ test "reinterpret packed union" {
17581756 };
17591757
17601758 try comptime S.doTheTest();
1761
1762 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
17631759 try S.doTheTest();
17641760}
17651761
......@@ -1800,8 +1796,6 @@ test "reinterpret packed union inside packed struct" {
18001796 };
18011797
18021798 try comptime S.doTheTest();
1803
1804 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
18051799 try S.doTheTest();
18061800}
18071801
test/behavior/vector.zig-5
......@@ -128,7 +128,6 @@ test "vector float operators" {
128128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
129129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
130130 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
131 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
132131
133132 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
134133 // Triggers an assertion with LLVM 18:
......@@ -736,7 +735,6 @@ test "vector reduce operation" {
736735 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
737736 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
738737 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
739 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
740738 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
741739 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/195562
742740
......@@ -1437,7 +1435,6 @@ test "store packed vector element" {
14371435 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
14381436 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14391437 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14411438 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14421439
14431440 var v = @Vector(4, u1){ 1, 1, 1, 1 };
......@@ -1469,7 +1466,6 @@ test "store vector with memset" {
14691466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14701467 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14711468 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1472 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
14731469 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14741470
14751471 var a: [5]@Vector(2, i1) = undefined;
......@@ -1610,7 +1606,6 @@ test "bitcast vector to array of smaller vectors" {
16101606 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
16111607 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
16121608 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1613 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
16141609
16151610 const u8x32 = @Vector(32, u8);
16161611 const u8x64 = @Vector(64, u8);
test/standalone/build.zig-1
......@@ -39,7 +39,6 @@ pub fn build(b: *std.Build) void {
3939 "../../tools/gen_parser_oracle.zig",
4040 "../../tools/gen_spirv_spec.zig",
4141 "../../tools/gen_stubs.zig",
42 "../../tools/generate_c_size_and_align_checks.zig",
4342 "../../tools/generate_JSONTestSuite.zig",
4443 "../../tools/generate_linux_syscalls.zig",
4544 "../../tools/process_headers.zig",
test/tests.zig+54-10
......@@ -274,6 +274,15 @@ const module_test_targets = blk: {
274274 },
275275 .link_libc = true,
276276 },
277 .{
278 .target = .{
279 .cpu_arch = .arm,
280 .os_tag = .linux,
281 .abi = .musleabi,
282 .ofmt = .c,
283 },
284 .link_libc = true,
285 },
277286 .{
278287 .target = .{
279288 .cpu_arch = .arm,
......@@ -292,6 +301,15 @@ const module_test_targets = blk: {
292301 },
293302 .link_libc = true,
294303 },
304 .{
305 .target = .{
306 .cpu_arch = .arm,
307 .os_tag = .linux,
308 .abi = .musleabihf,
309 .ofmt = .c,
310 },
311 .link_libc = true,
312 },
295313 .{
296314 .target = .{
297315 .cpu_arch = .arm,
......@@ -341,6 +359,15 @@ const module_test_targets = blk: {
341359 },
342360 .link_libc = true,
343361 },
362 .{
363 .target = .{
364 .cpu_arch = .armeb,
365 .os_tag = .linux,
366 .abi = .musleabi,
367 .ofmt = .c,
368 },
369 .link_libc = true,
370 },
344371 // Crashes in weird ways when applying relocations.
345372 // .{
346373 // .target = .{
......@@ -360,6 +387,15 @@ const module_test_targets = blk: {
360387 },
361388 .link_libc = true,
362389 },
390 .{
391 .target = .{
392 .cpu_arch = .armeb,
393 .os_tag = .linux,
394 .abi = .musleabihf,
395 .ofmt = .c,
396 },
397 .link_libc = true,
398 },
363399 // Crashes in weird ways when applying relocations.
364400 // .{
365401 // .target = .{
......@@ -1107,6 +1143,15 @@ const module_test_targets = blk: {
11071143 },
11081144 .link_libc = true,
11091145 },
1146 .{
1147 .target = .{
1148 .cpu_arch = .x86,
1149 .os_tag = .linux,
1150 .abi = .musl,
1151 .ofmt = .c,
1152 },
1153 .link_libc = true,
1154 },
11101155 .{
11111156 .target = .{
11121157 .cpu_arch = .x86,
......@@ -1645,6 +1690,15 @@ const module_test_targets = blk: {
16451690 },
16461691 .link_libc = true,
16471692 },
1693 .{
1694 .target = .{
1695 .cpu_arch = .x86,
1696 .os_tag = .windows,
1697 .abi = .gnu,
1698 .ofmt = .c,
1699 },
1700 .link_libc = true,
1701 },
16481702
16491703 .{
16501704 .target = .{
......@@ -2782,16 +2836,6 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
27822836
27832837 const target = &resolved_target.result;
27842838
2785 if (target.cpu.arch == .s390x and target.ofmt == .c) {
2786 // https://codeberg.org/ziglang/zig/issues/35523
2787 continue;
2788 }
2789
2790 if (target.cpu.arch == .riscv64 and target.ofmt == .c) {
2791 // https://codeberg.org/ziglang/zig/issues/30930
2792 continue;
2793 }
2794
27952839 if (std.mem.eql(u8, options.name, "libc")) {
27962840 // The libc API tests obviously need to link libc. So for test
27972841 // target entries where we wouldn't link libc by default, skip the
tools/generate_c_size_and_align_checks.zig deleted-62
......@@ -1,62 +0,0 @@
1//! Usage: zig run tools/generate_c_size_and_align_checks.zig -- [target_triple]
2//! e.g. zig run tools/generate_c_size_and_align_checks.zig -- x86_64-linux-gnu
3//!
4//! Prints _Static_asserts for the size and alignment of all the basic built-in C
5//! types. The output can be run through a compiler for the specified target to
6//! verify that Zig's values are the same as those used by a C compiler for the
7//! target.
8
9const std = @import("std");
10const Io = std.Io;
11
12fn cName(ty: std.Target.CType) []const u8 {
13 return switch (ty) {
14 .char => "char",
15 .short => "short",
16 .ushort => "unsigned short",
17 .int => "int",
18 .uint => "unsigned int",
19 .long => "long",
20 .ulong => "unsigned long",
21 .longlong => "long long",
22 .ulonglong => "unsigned long long",
23 .float => "float",
24 .double => "double",
25 .longdouble => "long double",
26 };
27}
28
29var general_purpose_allocator: std.heap.DebugAllocator(.{}) = .init;
30
31pub fn main(init: std.process.Init) !void {
32 const args = try init.minimal.args.toSlice(init.arena.allocator());
33 const io = init.io;
34
35 if (args.len != 2) {
36 std.debug.print("Usage: {s} [target_triple]\n", .{args[0]});
37 std.process.exit(1);
38 }
39
40 const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] });
41 const target = try std.zig.system.resolveTargetQuery(io, query);
42
43 var buffer: [2000]u8 = undefined;
44 var stdout_writer = Io.File.stdout().writerStreaming(io, &buffer);
45 const w = &stdout_writer.interface;
46 inline for (@typeInfo(std.Target.CType).@"enum".field_values) |field_value| {
47 const c_type: std.Target.CType = @fromBackingInt(@intCast(field_value));
48 try w.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{
49 cName(c_type),
50 target.cTypeByteSize(c_type),
51 });
52 try w.print("_Static_assert(_Alignof({0s}) == {1d}, \"_Alignof({0s}) == {1d}\");\n", .{
53 cName(c_type),
54 target.cTypeAlignment(c_type),
55 });
56 try w.print("_Static_assert(__alignof({0s}) == {1d}, \"__alignof({0s}) == {1d}\");\n\n", .{
57 cName(c_type),
58 target.cTypePreferredAlignment(c_type),
59 });
60 }
61 try w.flush();
62}