diff --git a/lib/compiler_rt/udivmodei4.zig b/lib/compiler_rt/udivmodei4.zig index ff37a0cd272f..5552ed9026fb 100644 --- a/lib/compiler_rt/udivmodei4.zig +++ b/lib/compiler_rt/udivmodei4.zig @@ -4,7 +4,7 @@ const common = @import("common.zig"); const shr = std.math.shr; const shl = std.math.shl; -const max_limbs = std.math.divCeil(usize, 65535, 32) catch unreachable; // max supported type is u65535 +const max_limbs: usize = std.math.divCeilAssert(comptime_int, 65535, 32); // max supported type is u65535 comptime { @export(__udivei4, .{ .name = "__udivei4", .linkage = common.linkage, .visibility = common.visibility }); diff --git a/lib/std/crypto/aes_gcm.zig b/lib/std/crypto/aes_gcm.zig index 1715636bed4c..4bff4b3d3e10 100644 --- a/lib/std/crypto/aes_gcm.zig +++ b/lib/std/crypto/aes_gcm.zig @@ -36,7 +36,7 @@ fn AesGcm(comptime Aes: anytype) type { mem.writeIntBig(u32, j[nonce_length..][0..4], 1); aes.encrypt(&t, &j); - const block_count = (math.divCeil(usize, ad.len, Ghash.block_length) catch unreachable) + (math.divCeil(usize, c.len, Ghash.block_length) catch unreachable) + 1; + const block_count = math.divCeilAssert(usize, ad.len, Ghash.block_length) + math.divCeilAssert(usize, c.len, Ghash.block_length) + 1; var mac = Ghash.initForBlockCount(&h, block_count); mac.update(ad); mac.pad(); @@ -78,7 +78,7 @@ fn AesGcm(comptime Aes: anytype) type { mem.writeIntBig(u32, j[nonce_length..][0..4], 1); aes.encrypt(&t, &j); - const block_count = (math.divCeil(usize, ad.len, Ghash.block_length) catch unreachable) + (math.divCeil(usize, c.len, Ghash.block_length) catch unreachable) + 1; + const block_count = math.divCeilAssert(usize, ad.len, Ghash.block_length) + math.divCeilAssert(usize, c.len, Ghash.block_length) + 1; var mac = Ghash.initForBlockCount(&h, block_count); mac.update(ad); mac.pad(); diff --git a/lib/std/crypto/ascon.zig b/lib/std/crypto/ascon.zig index 8aa0b109f21e..8f2b4fede9eb 100644 --- a/lib/std/crypto/ascon.zig +++ b/lib/std/crypto/ascon.zig @@ -147,7 +147,8 @@ pub fn State(comptime endian: builtin.Endian) type { /// Set the words storing the bytes of a given range to zero. pub fn clear(self: *Self, from: usize, to: usize) void { - @memset(self.st[from / 8 .. (to + 7) / 8], 0); + const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1); + @memset(self.st[from / 8 .. @intCast(std.math.divCeilAssert(UsizePlusOne, to, 8))], 0); } /// Clear the entire state, disabling compiler optimizations. diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig index e00a3741da76..4fc7c0da4641 100644 --- a/lib/std/crypto/ff.zig +++ b/lib/std/crypto/ff.zig @@ -64,12 +64,12 @@ pub fn Uint(comptime max_bits: comptime_int) type { return struct { const Self = @This(); - const max_limbs_count = math.divCeil(usize, max_bits, t_bits) catch unreachable; + const max_limbs_count: usize = math.divCeilAssert(comptime_int, max_bits, t_bits); const Limbs = BoundedArray(Limb, max_limbs_count); limbs: Limbs, /// Number of bytes required to serialize an integer. - pub const encoded_bytes = math.divCeil(usize, max_bits, 8) catch unreachable; + pub const encoded_bytes: usize = math.divCeilAssert(comptime_int, max_bits, 8); // Returns the number of active limbs. fn limbs_count(self: Self) usize { @@ -788,9 +788,12 @@ pub fn Modulus(comptime max_bits: comptime_int) type { /// Returns x^e (mod m), assuming that the exponent is public. /// The function remains constant time with respect to `x`. pub fn powPublic(self: Self, x: Fe, e: Fe) NullExponentError!Fe { - var e_normalized = Fe{ .v = e.v.normalize() }; - var buf_: [Fe.encoded_bytes]u8 = undefined; - var buf = buf_[0 .. math.divCeil(usize, e_normalized.v.limbs_count() * t_bits, 8) catch unreachable]; + const e_normalized: Fe = .{ .v = e.v.normalize() }; + var buf: []u8 = buf: { + var buf_: [Fe.encoded_bytes]u8 = undefined; + const buf_end: usize = math.divCeilAssert(usize, e_normalized.v.limbs_count() * t_bits, 8); + break :buf buf_[0..buf_end]; + }; e_normalized.toBytes(buf, .Little) catch unreachable; const leading = @clz(e_normalized.v.limbs.get(e_normalized.v.limbs_count() - carry_bits)); buf = buf[0 .. buf.len - leading / 8]; diff --git a/lib/std/crypto/pbkdf2.zig b/lib/std/crypto/pbkdf2.zig index 2e0318369b83..e5e9ffb47b6b 100644 --- a/lib/std/crypto/pbkdf2.zig +++ b/lib/std/crypto/pbkdf2.zig @@ -74,7 +74,7 @@ pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, com // block // - const blocks_count = @as(u32, @intCast(std.math.divCeil(usize, dk_len, h_len) catch unreachable)); + const blocks_count: u32 = @intCast(std.math.divCeilAssert(usize, dk_len, h_len)); var r = dk_len % h_len; if (r == 0) { r = h_len; diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig index c9741c00a214..275cccb60c15 100644 --- a/lib/std/hash/auto_hash.zig +++ b/lib/std/hash/auto_hash.zig @@ -103,7 +103,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void { } else { // Take only the part containing the key value, the remaining // bytes are undefined and must not be hashed! - const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable; + const byte_size: usize = comptime std.math.divCeilAssert(comptime_int, @bitSizeOf(Key), 8); @call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key)[0..byte_size] }); } }, diff --git a/lib/std/io/Reader.zig b/lib/std/io/Reader.zig index 4a03eb0b5466..858d2e6c5bfd 100644 --- a/lib/std/io/Reader.zig +++ b/lib/std/io/Reader.zig @@ -278,28 +278,28 @@ pub fn readBoundedBytes(self: Self, comptime num_bytes: usize) anyerror!std.Boun /// Reads a native-endian integer pub fn readIntNative(self: Self, comptime T: type) anyerror!T { - const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))); + const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)); return mem.readIntNative(T, &bytes); } /// Reads a foreign-endian integer pub fn readIntForeign(self: Self, comptime T: type) anyerror!T { - const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))); + const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)); return mem.readIntForeign(T, &bytes); } pub fn readIntLittle(self: Self, comptime T: type) anyerror!T { - const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))); + const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)); return mem.readIntLittle(T, &bytes); } pub fn readIntBig(self: Self, comptime T: type) anyerror!T { - const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))); + const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)); return mem.readIntBig(T, &bytes); } pub fn readInt(self: Self, comptime T: type, endian: std.builtin.Endian) anyerror!T { - const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))); + const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)); return mem.readInt(T, &bytes, endian); } diff --git a/lib/std/io/writer.zig b/lib/std/io/writer.zig index 41dcf9b6e73c..4ebed83eef9f 100644 --- a/lib/std/io/writer.zig +++ b/lib/std/io/writer.zig @@ -47,33 +47,38 @@ pub fn Writer( /// Write a native-endian integer. pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void { - var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined; - mem.writeIntNative(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value); + const ByteAlignedT = std.math.ByteAlignedInt(T); + var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined; + mem.writeIntNative(ByteAlignedT, &bytes, value); return self.writeAll(&bytes); } /// Write a foreign-endian integer. pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void { - var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined; - mem.writeIntForeign(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value); + const ByteAlignedT = std.math.ByteAlignedInt(T); + var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined; + mem.writeIntForeign(ByteAlignedT, &bytes, value); return self.writeAll(&bytes); } pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void { - var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined; - mem.writeIntLittle(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value); + const ByteAlignedT = std.math.ByteAlignedInt(T); + var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined; + mem.writeIntLittle(ByteAlignedT, &bytes, value); return self.writeAll(&bytes); } pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void { - var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined; - mem.writeIntBig(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value); + const ByteAlignedT = std.math.ByteAlignedInt(T); + var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined; + mem.writeIntBig(ByteAlignedT, &bytes, value); return self.writeAll(&bytes); } pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { - var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined; - mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); + const ByteAlignedT = std.math.ByteAlignedInt(T); + var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined; + mem.writeInt(ByteAlignedT, &bytes, value, endian); return self.writeAll(&bytes); } diff --git a/lib/std/math.zig b/lib/std/math.zig index f110efa0afc7..126b5f806bf6 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -828,6 +828,12 @@ pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T { } } +/// Divide numerator by denominator, rounding toward positive +/// infinity. Asserts that the value fits and denominator is not zero. +pub fn divCeilAssert(comptime T: type, numerator: T, denominator: T) T { + return divCeil(T, numerator, denominator) catch unreachable; +} + test "divCeil" { if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; @@ -1040,9 +1046,8 @@ test isPowerOfTwo { /// Aligns the given integer type bit width to a width divisible by 8. pub fn ByteAlignedInt(comptime T: type) type { const info = @typeInfo(T).Int; - const bits = (info.bits + 7) / 8 * 8; - const extended_type = std.meta.Int(info.signedness, bits); - return extended_type; + const bytes_aligned: u14 = divCeilAssert(comptime_int, info.bits, 8); + return std.meta.Int(info.signedness, bytes_aligned * 8); } test "ByteAlignedInt" { diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index a761151e7b5e..110d89554808 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -75,7 +75,7 @@ pub fn calcSqrtLimbsBufferLen(a_bit_count: usize) usize { // Compute the number of limbs required to store a 2s-complement number of `bit_count` bits. pub fn calcTwosCompLimbCount(bit_count: usize) usize { - return std.math.divCeil(usize, bit_count, @bitSizeOf(Limb)) catch unreachable; + return math.divCeilAssert(usize, bit_count, limb_bits); } /// a + b * c + *carry, sets carry to the overflow bits @@ -1910,14 +1910,16 @@ pub const Mutable = struct { // Check whether the input is negative var positive = true; if (signedness == .signed) { - const total_bits = bit_offset + bit_count; - var last_byte = switch (endian) { - .Little => ((total_bits + 7) / 8) - 1, - .Big => buffer.len - ((total_bits + 7) / 8), - }; + const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1); + + const total_bits: usize = bit_offset + bit_count; + const last_byte_pos: usize = @intCast(switch (endian) { + .Little => math.divCeilAssert(UsizePlusOne, total_bits, 8) - 1, + .Big => @as(UsizePlusOne, buffer.len) - math.divCeilAssert(UsizePlusOne, total_bits, 8), + }); - const sign_bit = @as(u8, 1) << @as(u3, @intCast((total_bits - 1) % 8)); - positive = ((buffer[last_byte] & sign_bit) == 0); + const sign_bit = @as(u8, 1) << @intCast((total_bits - 1) % 8); + positive = ((buffer[last_byte_pos] & sign_bit) == 0); } // Copy all complete limbs diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 4e2d5a805f69..df7727ae7b82 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1781,7 +1781,7 @@ test "readIntBig and readIntLittle" { /// accepts any integer bit width. /// This function stores in native endian, which means it is implemented as a simple /// memory store. -pub fn writeIntNative(comptime T: type, buf: *[@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8, value: T) void { +pub fn writeIntNative(comptime T: type, buf: *[math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)]u8, value: T) void { @as(*align(1) T, @ptrCast(buf)).* = value; } diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig index cff9eb8cf15b..2bbc81957e29 100644 --- a/lib/std/packed_int_array.zig +++ b/lib/std/packed_int_array.zig @@ -8,6 +8,7 @@ const debug = std.debug; const testing = std.testing; const native_endian = builtin.target.cpu.arch.endian(); const Endian = std.builtin.Endian; +const divCeilAssert = std.math.divCeilAssert; /// Provides a set of functions for reading and writing packed integers from a /// slice of bytes. @@ -26,24 +27,23 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type { // of the memory. const int_bits = @bitSizeOf(Int); + // We bitcast the desired Int type to an unsigned version of itself + // to avoid issues with shifting signed ints. + const UnInt = std.meta.Int(.unsigned, int_bits); + // In the best case, this is the number of bytes we need to touch // to read or write a value, as bits. - const min_io_bits = ((int_bits + 7) / 8) * 8; + const min_io_bits = @bitSizeOf(std.math.ByteAlignedInt(UnInt)); // In the worst case, this is the number of bytes we need to touch // to read or write a value, as bits. To calculate for int_bits > 1, // set aside 2 bits to touch the first and last bytes, then divide // by 8 to see how many bytes can be filled up in between. const max_io_bits = switch (int_bits) { - 0 => 0, - 1 => 8, + 0, 1 => min_io_bits, else => ((int_bits - 2) / 8 + 2) * 8, }; - // We bitcast the desired Int type to an unsigned version of itself - // to avoid issues with shifting signed ints. - const UnInt = std.meta.Int(.unsigned, int_bits); - // The maximum container int type const MinIo = std.meta.Int(.unsigned, min_io_bits); @@ -147,10 +147,12 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type { pub fn slice(bytes: []u8, bit_offset: u3, start: usize, end: usize) PackedIntSliceEndian(Int, endian) { debug.assert(end >= start); + const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1); + const length = end - start; const bit_index = (start * int_bits) + bit_offset; const start_byte = bit_index / 8; - const end_byte = (bit_index + (length * int_bits) + 7) / 8; + const end_byte: usize = @intCast(divCeilAssert(UsizePlusOne, bit_index + (length * int_bits), 8)); const new_bytes = bytes[start_byte..end_byte]; if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0); @@ -196,7 +198,7 @@ pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type { pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptime int_count: usize) type { const int_bits = @bitSizeOf(Int); const total_bits = int_bits * int_count; - const total_bytes = (total_bits + 7) / 8; + const total_bytes: usize = divCeilAssert(comptime_int, total_bits, 8); const Io = PackedIntIo(Int, endian); @@ -293,7 +295,8 @@ pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: Endian) type { /// of `Int`s. pub fn bytesRequired(int_count: usize) usize { const total_bits = int_bits * int_count; - const total_bytes = (total_bits + 7) / 8; + const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1); + const total_bytes: usize = @intCast(divCeilAssert(UsizePlusOne, total_bits, 8)); return total_bytes; } @@ -362,7 +365,7 @@ test "PackedIntArray" { const I = std.meta.Int(sign, bits); const PackedArray = PackedIntArray(I, int_count); - const expected_bytes = ((bits * int_count) + 7) / 8; + const expected_bytes: usize = divCeilAssert(comptime_int, bits * int_count, 8); try testing.expect(@sizeOf(PackedArray) == expected_bytes); var data = @as(PackedArray, undefined); @@ -419,7 +422,7 @@ test "PackedIntSlice" { const max_bits = 256; const int_count = 19; const total_bits = max_bits * int_count; - const total_bytes = (total_bits + 7) / 8; + const total_bytes: usize = divCeilAssert(comptime_int, total_bits, 8); var buffer: [total_bytes]u8 = undefined; @@ -476,7 +479,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" { var packed_slice = packed_array.slice(2, 5); try testing.expect(packed_slice.len == 3); const ps_bit_count = (bits * packed_slice.len) + packed_slice.bit_offset; - const ps_expected_bytes = (ps_bit_count + 7) / 8; + const ps_expected_bytes: usize = divCeilAssert(comptime_int, ps_bit_count, 8); try testing.expect(packed_slice.bytes.len == ps_expected_bytes); try testing.expect(packed_slice.get(0) == 2 % limit); try testing.expect(packed_slice.get(1) == 3 % limit); @@ -491,7 +494,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" { const packed_slice_two = packed_slice.slice(0, 3); try testing.expect(packed_slice_two.len == 3); const ps2_bit_count = (bits * packed_slice_two.len) + packed_slice_two.bit_offset; - const ps2_expected_bytes = (ps2_bit_count + 7) / 8; + const ps2_expected_bytes: usize = divCeilAssert(comptime_int, ps2_bit_count, 8); try testing.expect(packed_slice_two.bytes.len == ps2_expected_bytes); try testing.expect(packed_slice_two.get(1) == 7 % limit); try testing.expect(packed_slice_two.get(2) == 4 % limit); @@ -500,7 +503,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" { const packed_slice_three = packed_slice_two.slice(1, 2); try testing.expect(packed_slice_three.len == 1); const ps3_bit_count = (bits * packed_slice_three.len) + packed_slice_three.bit_offset; - const ps3_expected_bytes = (ps3_bit_count + 7) / 8; + const ps3_expected_bytes: usize = divCeilAssert(comptime_int, ps3_bit_count, 8); try testing.expect(packed_slice_three.bytes.len == ps3_expected_bytes); try testing.expect(packed_slice_three.get(0) == 7 % limit); @@ -513,7 +516,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" { const packed_slice_edge = packed_array.slice(8, 16); try testing.expect(packed_slice_edge.len == 8); const pse_bit_count = (bits * packed_slice_edge.len) + packed_slice_edge.bit_offset; - const pse_expected_bytes = (pse_bit_count + 7) / 8; + const pse_expected_bytes: usize = divCeilAssert(comptime_int, pse_bit_count, 8); try testing.expect(packed_slice_edge.bytes.len == pse_expected_bytes); try testing.expect(packed_slice_edge.bit_offset == 0); } diff --git a/lib/std/target.zig b/lib/std/target.zig index 7296b304347e..c22f517a93c1 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -2,6 +2,7 @@ const std = @import("std.zig"); const builtin = @import("builtin"); const mem = std.mem; const Version = std.SemanticVersion; +const divCeilAssert = std.math.divCeilAssert; pub const Target = struct { cpu: Cpu, @@ -704,9 +705,9 @@ pub const Target = struct { pub const Set = struct { ints: [usize_count]usize, - pub const needed_bit_count = 288; - pub const byte_count = (needed_bit_count + 7) / 8; - pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize); + pub const needed_bit_count = 36 * 8; // 288 + pub const byte_count: usize = divCeilAssert(comptime_int, needed_bit_count, 8); + pub const usize_count: usize = divCeilAssert(comptime_int, byte_count, @sizeOf(usize)); pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize))); pub const ShiftInt = std.math.Log2Int(usize); @@ -2390,8 +2391,9 @@ pub const Target = struct { } // Next-power-of-two-aligned, up to a maximum. + const c_type_byte_aligned_size: u16 = @intCast(divCeilAssert(u17, c_type_bit_size(target, c_type), 8)); return @min( - std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8), + std.math.ceilPowerOfTwoAssert(u16, c_type_byte_aligned_size), switch (target.cpu.arch) { .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) { .netbsd => switch (target.abi) { @@ -2530,8 +2532,9 @@ pub const Target = struct { } // Next-power-of-two-aligned, up to a maximum. + const c_type_byte_aligned_size: u16 = @intCast(divCeilAssert(u17, c_type_bit_size(target, c_type), 8)); return @min( - std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8), + std.math.ceilPowerOfTwoAssert(u16, c_type_byte_aligned_size), switch (target.cpu.arch) { .msp430 => @as(u16, 2),