authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-04-06 10:14:34+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-11 05:22:00-04:00
loged9aa8f259d452cb344064ee412fc5af18877d55
treebc25fc044efda559430e3ea7d715936b179b37cf
parent0132be7bf3fd02cfb8c31ffdeaddae918a76b295

compiler: Move int size/alignment functions to std.Target and std.zig.target.

This allows using them in e.g. compiler-rt.

5 files changed, 108 insertions(+), 109 deletions(-)

lib/std/Target.zig+62
......@@ -3273,6 +3273,68 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 {
32733273 );
32743274}
32753275
3276pub fn cMaxIntAlignment(target: std.Target) u16 {
3277 return switch (target.cpu.arch) {
3278 .avr => 1,
3279
3280 .msp430 => 2,
3281
3282 .xcore,
3283 .propeller,
3284 => 4,
3285
3286 .amdgcn,
3287 .arm,
3288 .armeb,
3289 .thumb,
3290 .thumbeb,
3291 .lanai,
3292 .hexagon,
3293 .mips,
3294 .mipsel,
3295 .powerpc,
3296 .powerpcle,
3297 .riscv32,
3298 .s390x,
3299 => 8,
3300
3301 // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
3302 .aarch64,
3303 .aarch64_be,
3304 .bpfel,
3305 .bpfeb,
3306 .mips64,
3307 .mips64el,
3308 .nvptx,
3309 .nvptx64,
3310 .powerpc64,
3311 .powerpc64le,
3312 .riscv64,
3313 .sparc,
3314 .sparc64,
3315 .wasm32,
3316 .wasm64,
3317 .x86,
3318 .x86_64,
3319 => 16,
3320
3321 // Below this comment are unverified but based on the fact that C requires
3322 // int128_t to be 16 bytes aligned, it's a safe default.
3323 .arc,
3324 .csky,
3325 .kalimba,
3326 .loongarch32,
3327 .loongarch64,
3328 .m68k,
3329 .spirv,
3330 .spirv32,
3331 .spirv64,
3332 .ve,
3333 .xtensa,
3334 => 16,
3335 };
3336}
3337
32763338pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
32773339 return switch (target.cpu.arch) {
32783340 .x86_64 => switch (target.os.tag) {
lib/std/zig/target.zig+32
......@@ -352,6 +352,38 @@ fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
352352 }
353353}
354354
355pub fn intByteSize(target: std.Target, bits: u16) u19 {
356 return std.mem.alignForward(u19, @intCast((@as(u17, bits) + 7) / 8), intAlignment(target, bits));
357}
358
359pub fn intAlignment(target: std.Target, bits: u16) u16 {
360 return switch (target.cpu.arch) {
361 .x86 => switch (bits) {
362 0 => 0,
363 1...8 => 1,
364 9...16 => 2,
365 17...32 => 4,
366 33...64 => switch (target.os.tag) {
367 .uefi, .windows => 8,
368 else => 4,
369 },
370 else => 16,
371 },
372 .x86_64 => switch (bits) {
373 0 => 0,
374 1...8 => 1,
375 9...16 => 2,
376 17...32 => 4,
377 33...64 => 8,
378 else => 16,
379 },
380 else => return @min(
381 std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
382 target.cMaxIntAlignment(),
383 ),
384 };
385}
386
355387const std = @import("std");
356388const assert = std.debug.assert;
357389const Allocator = std.mem.Allocator;
src/Type.zig+7-101
......@@ -968,7 +968,7 @@ pub fn abiAlignmentInner(
968968 else => switch (ip.indexToKey(ty.toIntern())) {
969969 .int_type => |int_type| {
970970 if (int_type.bits == 0) return .{ .scalar = .@"1" };
971 return .{ .scalar = intAbiAlignment(int_type.bits, target) };
971 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)) };
972972 },
973973 .ptr_type, .anyframe_type => {
974974 return .{ .scalar = ptrAbiAlignment(target) };
......@@ -1021,7 +1021,7 @@ pub fn abiAlignmentInner(
10211021 .error_set_type, .inferred_error_set_type => {
10221022 const bits = zcu.errorSetBits();
10231023 if (bits == 0) return .{ .scalar = .@"1" };
1024 return .{ .scalar = intAbiAlignment(bits, target) };
1024 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
10251025 },
10261026
10271027 // represents machine code; not a pointer
......@@ -1034,7 +1034,7 @@ pub fn abiAlignmentInner(
10341034
10351035 .usize,
10361036 .isize,
1037 => return .{ .scalar = intAbiAlignment(target.ptrBitWidth(), target) },
1037 => return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())) },
10381038
10391039 .c_char => return .{ .scalar = cTypeAlign(target, .char) },
10401040 .c_short => return .{ .scalar = cTypeAlign(target, .short) },
......@@ -1065,7 +1065,7 @@ pub fn abiAlignmentInner(
10651065 .anyerror, .adhoc_inferred_error_set => {
10661066 const bits = zcu.errorSetBits();
10671067 if (bits == 0) return .{ .scalar = .@"1" };
1068 return .{ .scalar = intAbiAlignment(bits, target) };
1068 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
10691069 },
10701070
10711071 .void,
......@@ -1297,7 +1297,7 @@ pub fn abiSizeInner(
12971297 else => switch (ip.indexToKey(ty.toIntern())) {
12981298 .int_type => |int_type| {
12991299 if (int_type.bits == 0) return .{ .scalar = 0 };
1300 return .{ .scalar = intAbiSize(int_type.bits, target) };
1300 return .{ .scalar = std.zig.target.intByteSize(target, int_type.bits) };
13011301 },
13021302 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
13031303 .slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
......@@ -1359,7 +1359,7 @@ pub fn abiSizeInner(
13591359 .error_set_type, .inferred_error_set_type => {
13601360 const bits = zcu.errorSetBits();
13611361 if (bits == 0) return .{ .scalar = 0 };
1362 return .{ .scalar = intAbiSize(bits, target) };
1362 return .{ .scalar = std.zig.target.intByteSize(target, bits) };
13631363 },
13641364
13651365 .error_union_type => |error_union_type| {
......@@ -1452,7 +1452,7 @@ pub fn abiSizeInner(
14521452 .anyerror, .adhoc_inferred_error_set => {
14531453 const bits = zcu.errorSetBits();
14541454 if (bits == 0) return .{ .scalar = 0 };
1455 return .{ .scalar = intAbiSize(bits, target) };
1455 return .{ .scalar = std.zig.target.intByteSize(target, bits) };
14561456 },
14571457
14581458 .noreturn => unreachable,
......@@ -1606,100 +1606,6 @@ pub fn ptrAbiAlignment(target: Target) Alignment {
16061606 return Alignment.fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
16071607}
16081608
1609pub fn intAbiSize(bits: u16, target: Target) u64 {
1610 return intAbiAlignment(bits, target).forward(@as(u16, @intCast((@as(u17, bits) + 7) / 8)));
1611}
1612
1613pub fn intAbiAlignment(bits: u16, target: Target) Alignment {
1614 return switch (target.cpu.arch) {
1615 .x86 => switch (bits) {
1616 0 => .none,
1617 1...8 => .@"1",
1618 9...16 => .@"2",
1619 17...32 => .@"4",
1620 33...64 => switch (target.os.tag) {
1621 .uefi, .windows => .@"8",
1622 else => .@"4",
1623 },
1624 else => .@"16",
1625 },
1626 .x86_64 => switch (bits) {
1627 0 => .none,
1628 1...8 => .@"1",
1629 9...16 => .@"2",
1630 17...32 => .@"4",
1631 33...64 => .@"8",
1632 else => .@"16",
1633 },
1634 else => return Alignment.fromByteUnits(@min(
1635 std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
1636 maxIntAlignment(target),
1637 )),
1638 };
1639}
1640
1641pub fn maxIntAlignment(target: std.Target) u16 {
1642 return switch (target.cpu.arch) {
1643 .avr => 1,
1644
1645 .msp430 => 2,
1646
1647 .xcore,
1648 .propeller,
1649 => 4,
1650
1651 .amdgcn,
1652 .arm,
1653 .armeb,
1654 .thumb,
1655 .thumbeb,
1656 .lanai,
1657 .hexagon,
1658 .mips,
1659 .mipsel,
1660 .powerpc,
1661 .powerpcle,
1662 .riscv32,
1663 .s390x,
1664 => 8,
1665
1666 // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
1667 .aarch64,
1668 .aarch64_be,
1669 .bpfel,
1670 .bpfeb,
1671 .mips64,
1672 .mips64el,
1673 .nvptx,
1674 .nvptx64,
1675 .powerpc64,
1676 .powerpc64le,
1677 .riscv64,
1678 .sparc,
1679 .sparc64,
1680 .wasm32,
1681 .wasm64,
1682 .x86,
1683 .x86_64,
1684 => 16,
1685
1686 // Below this comment are unverified but based on the fact that C requires
1687 // int128_t to be 16 bytes aligned, it's a safe default.
1688 .arc,
1689 .csky,
1690 .kalimba,
1691 .loongarch32,
1692 .loongarch64,
1693 .m68k,
1694 .spirv,
1695 .spirv32,
1696 .spirv64,
1697 .ve,
1698 .xtensa,
1699 => 16,
1700 };
1701}
1702
17031609pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
17041610 return bitSizeInner(ty, .normal, zcu, {}) catch unreachable;
17051611}
src/codegen/c/Type.zig+6-7
......@@ -1319,10 +1319,9 @@ pub const Pool = struct {
13191319 },
13201320 else => {
13211321 const target = &mod.resolved_target.result;
1322 const abi_align = Type.intAbiAlignment(int_info.bits, target.*);
1323 const abi_align_bytes = abi_align.toByteUnits().?;
1322 const abi_align_bytes = std.zig.target.intAlignment(target.*, int_info.bits);
13241323 const array_ctype = try pool.getArray(allocator, .{
1325 .len = @divExact(Type.intAbiSize(int_info.bits, target.*), abi_align_bytes),
1324 .len = @divExact(std.zig.target.intByteSize(target.*, int_info.bits), abi_align_bytes),
13261325 .elem_ctype = try pool.fromIntInfo(allocator, .{
13271326 .signedness = .unsigned,
13281327 .bits = @intCast(abi_align_bytes * 8),
......@@ -1333,7 +1332,7 @@ pub const Pool = struct {
13331332 .{
13341333 .name = .{ .index = .array },
13351334 .ctype = array_ctype,
1336 .alignas = AlignAs.fromAbiAlignment(abi_align),
1335 .alignas = AlignAs.fromAbiAlignment(.fromByteUnits(abi_align_bytes)),
13371336 },
13381337 };
13391338 return pool.fromFields(allocator, .@"struct", &fields, kind);
......@@ -1437,7 +1436,7 @@ pub const Pool = struct {
14371436 .name = .{ .index = .len },
14381437 .ctype = .usize,
14391438 .alignas = AlignAs.fromAbiAlignment(
1440 Type.intAbiAlignment(target.ptrBitWidth(), target.*),
1439 .fromByteUnits(std.zig.target.intAlignment(target.*, target.ptrBitWidth())),
14411440 ),
14421441 },
14431442 };
......@@ -1937,7 +1936,7 @@ pub const Pool = struct {
19371936 .name = .{ .index = .len },
19381937 .ctype = .usize,
19391938 .alignas = AlignAs.fromAbiAlignment(
1940 Type.intAbiAlignment(target.ptrBitWidth(), target.*),
1939 .fromByteUnits(std.zig.target.intAlignment(target.*, target.ptrBitWidth())),
19411940 ),
19421941 },
19431942 };
......@@ -2057,7 +2056,7 @@ pub const Pool = struct {
20572056 .name = .{ .index = .@"error" },
20582057 .ctype = error_set_ctype,
20592058 .alignas = AlignAs.fromAbiAlignment(
2060 Type.intAbiAlignment(error_set_bits, target.*),
2059 .fromByteUnits(std.zig.target.intAlignment(target.*, error_set_bits)),
20612060 ),
20622061 },
20632062 .{
src/link/C.zig+1-1
......@@ -396,7 +396,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
396396 else => {},
397397 }
398398 try writer.print("#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", .{
399 Type.maxIntAlignment(target),
399 target.cMaxIntAlignment(),
400400 });
401401 return defines;
402402}