Commit ed9aa8f259
Changed files (5)
lib
std
lib/std/zig/target.zig
@@ -352,6 +352,38 @@ fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
}
}
+pub fn intByteSize(target: std.Target, bits: u16) u19 {
+ return std.mem.alignForward(u19, @intCast((@as(u17, bits) + 7) / 8), intAlignment(target, bits));
+}
+
+pub fn intAlignment(target: std.Target, bits: u16) u16 {
+ return switch (target.cpu.arch) {
+ .x86 => switch (bits) {
+ 0 => 0,
+ 1...8 => 1,
+ 9...16 => 2,
+ 17...32 => 4,
+ 33...64 => switch (target.os.tag) {
+ .uefi, .windows => 8,
+ else => 4,
+ },
+ else => 16,
+ },
+ .x86_64 => switch (bits) {
+ 0 => 0,
+ 1...8 => 1,
+ 9...16 => 2,
+ 17...32 => 4,
+ 33...64 => 8,
+ else => 16,
+ },
+ else => return @min(
+ std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
+ target.cMaxIntAlignment(),
+ ),
+ };
+}
+
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
lib/std/Target.zig
@@ -3273,6 +3273,68 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 {
);
}
+pub fn cMaxIntAlignment(target: std.Target) u16 {
+ return switch (target.cpu.arch) {
+ .avr => 1,
+
+ .msp430 => 2,
+
+ .xcore,
+ .propeller,
+ => 4,
+
+ .amdgcn,
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ .lanai,
+ .hexagon,
+ .mips,
+ .mipsel,
+ .powerpc,
+ .powerpcle,
+ .riscv32,
+ .s390x,
+ => 8,
+
+ // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
+ .aarch64,
+ .aarch64_be,
+ .bpfel,
+ .bpfeb,
+ .mips64,
+ .mips64el,
+ .nvptx,
+ .nvptx64,
+ .powerpc64,
+ .powerpc64le,
+ .riscv64,
+ .sparc,
+ .sparc64,
+ .wasm32,
+ .wasm64,
+ .x86,
+ .x86_64,
+ => 16,
+
+ // Below this comment are unverified but based on the fact that C requires
+ // int128_t to be 16 bytes aligned, it's a safe default.
+ .arc,
+ .csky,
+ .kalimba,
+ .loongarch32,
+ .loongarch64,
+ .m68k,
+ .spirv,
+ .spirv32,
+ .spirv64,
+ .ve,
+ .xtensa,
+ => 16,
+ };
+}
+
pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention {
return switch (target.cpu.arch) {
.x86_64 => switch (target.os.tag) {
src/codegen/c/Type.zig
@@ -1319,10 +1319,9 @@ pub const Pool = struct {
},
else => {
const target = &mod.resolved_target.result;
- const abi_align = Type.intAbiAlignment(int_info.bits, target.*);
- const abi_align_bytes = abi_align.toByteUnits().?;
+ const abi_align_bytes = std.zig.target.intAlignment(target.*, int_info.bits);
const array_ctype = try pool.getArray(allocator, .{
- .len = @divExact(Type.intAbiSize(int_info.bits, target.*), abi_align_bytes),
+ .len = @divExact(std.zig.target.intByteSize(target.*, int_info.bits), abi_align_bytes),
.elem_ctype = try pool.fromIntInfo(allocator, .{
.signedness = .unsigned,
.bits = @intCast(abi_align_bytes * 8),
@@ -1333,7 +1332,7 @@ pub const Pool = struct {
.{
.name = .{ .index = .array },
.ctype = array_ctype,
- .alignas = AlignAs.fromAbiAlignment(abi_align),
+ .alignas = AlignAs.fromAbiAlignment(.fromByteUnits(abi_align_bytes)),
},
};
return pool.fromFields(allocator, .@"struct", &fields, kind);
@@ -1437,7 +1436,7 @@ pub const Pool = struct {
.name = .{ .index = .len },
.ctype = .usize,
.alignas = AlignAs.fromAbiAlignment(
- Type.intAbiAlignment(target.ptrBitWidth(), target.*),
+ .fromByteUnits(std.zig.target.intAlignment(target.*, target.ptrBitWidth())),
),
},
};
@@ -1937,7 +1936,7 @@ pub const Pool = struct {
.name = .{ .index = .len },
.ctype = .usize,
.alignas = AlignAs.fromAbiAlignment(
- Type.intAbiAlignment(target.ptrBitWidth(), target.*),
+ .fromByteUnits(std.zig.target.intAlignment(target.*, target.ptrBitWidth())),
),
},
};
@@ -2057,7 +2056,7 @@ pub const Pool = struct {
.name = .{ .index = .@"error" },
.ctype = error_set_ctype,
.alignas = AlignAs.fromAbiAlignment(
- Type.intAbiAlignment(error_set_bits, target.*),
+ .fromByteUnits(std.zig.target.intAlignment(target.*, error_set_bits)),
),
},
.{
src/link/C.zig
@@ -396,7 +396,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
else => {},
}
try writer.print("#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", .{
- Type.maxIntAlignment(target),
+ target.cMaxIntAlignment(),
});
return defines;
}
src/Type.zig
@@ -968,7 +968,7 @@ pub fn abiAlignmentInner(
else => switch (ip.indexToKey(ty.toIntern())) {
.int_type => |int_type| {
if (int_type.bits == 0) return .{ .scalar = .@"1" };
- return .{ .scalar = intAbiAlignment(int_type.bits, target) };
+ return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)) };
},
.ptr_type, .anyframe_type => {
return .{ .scalar = ptrAbiAlignment(target) };
@@ -1021,7 +1021,7 @@ pub fn abiAlignmentInner(
.error_set_type, .inferred_error_set_type => {
const bits = zcu.errorSetBits();
if (bits == 0) return .{ .scalar = .@"1" };
- return .{ .scalar = intAbiAlignment(bits, target) };
+ return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
},
// represents machine code; not a pointer
@@ -1034,7 +1034,7 @@ pub fn abiAlignmentInner(
.usize,
.isize,
- => return .{ .scalar = intAbiAlignment(target.ptrBitWidth(), target) },
+ => return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())) },
.c_char => return .{ .scalar = cTypeAlign(target, .char) },
.c_short => return .{ .scalar = cTypeAlign(target, .short) },
@@ -1065,7 +1065,7 @@ pub fn abiAlignmentInner(
.anyerror, .adhoc_inferred_error_set => {
const bits = zcu.errorSetBits();
if (bits == 0) return .{ .scalar = .@"1" };
- return .{ .scalar = intAbiAlignment(bits, target) };
+ return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
},
.void,
@@ -1297,7 +1297,7 @@ pub fn abiSizeInner(
else => switch (ip.indexToKey(ty.toIntern())) {
.int_type => |int_type| {
if (int_type.bits == 0) return .{ .scalar = 0 };
- return .{ .scalar = intAbiSize(int_type.bits, target) };
+ return .{ .scalar = std.zig.target.intByteSize(target, int_type.bits) };
},
.ptr_type => |ptr_type| switch (ptr_type.flags.size) {
.slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
@@ -1359,7 +1359,7 @@ pub fn abiSizeInner(
.error_set_type, .inferred_error_set_type => {
const bits = zcu.errorSetBits();
if (bits == 0) return .{ .scalar = 0 };
- return .{ .scalar = intAbiSize(bits, target) };
+ return .{ .scalar = std.zig.target.intByteSize(target, bits) };
},
.error_union_type => |error_union_type| {
@@ -1452,7 +1452,7 @@ pub fn abiSizeInner(
.anyerror, .adhoc_inferred_error_set => {
const bits = zcu.errorSetBits();
if (bits == 0) return .{ .scalar = 0 };
- return .{ .scalar = intAbiSize(bits, target) };
+ return .{ .scalar = std.zig.target.intByteSize(target, bits) };
},
.noreturn => unreachable,
@@ -1606,100 +1606,6 @@ pub fn ptrAbiAlignment(target: Target) Alignment {
return Alignment.fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
}
-pub fn intAbiSize(bits: u16, target: Target) u64 {
- return intAbiAlignment(bits, target).forward(@as(u16, @intCast((@as(u17, bits) + 7) / 8)));
-}
-
-pub fn intAbiAlignment(bits: u16, target: Target) Alignment {
- return switch (target.cpu.arch) {
- .x86 => switch (bits) {
- 0 => .none,
- 1...8 => .@"1",
- 9...16 => .@"2",
- 17...32 => .@"4",
- 33...64 => switch (target.os.tag) {
- .uefi, .windows => .@"8",
- else => .@"4",
- },
- else => .@"16",
- },
- .x86_64 => switch (bits) {
- 0 => .none,
- 1...8 => .@"1",
- 9...16 => .@"2",
- 17...32 => .@"4",
- 33...64 => .@"8",
- else => .@"16",
- },
- else => return Alignment.fromByteUnits(@min(
- std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
- maxIntAlignment(target),
- )),
- };
-}
-
-pub fn maxIntAlignment(target: std.Target) u16 {
- return switch (target.cpu.arch) {
- .avr => 1,
-
- .msp430 => 2,
-
- .xcore,
- .propeller,
- => 4,
-
- .amdgcn,
- .arm,
- .armeb,
- .thumb,
- .thumbeb,
- .lanai,
- .hexagon,
- .mips,
- .mipsel,
- .powerpc,
- .powerpcle,
- .riscv32,
- .s390x,
- => 8,
-
- // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
- .aarch64,
- .aarch64_be,
- .bpfel,
- .bpfeb,
- .mips64,
- .mips64el,
- .nvptx,
- .nvptx64,
- .powerpc64,
- .powerpc64le,
- .riscv64,
- .sparc,
- .sparc64,
- .wasm32,
- .wasm64,
- .x86,
- .x86_64,
- => 16,
-
- // Below this comment are unverified but based on the fact that C requires
- // int128_t to be 16 bytes aligned, it's a safe default.
- .arc,
- .csky,
- .kalimba,
- .loongarch32,
- .loongarch64,
- .m68k,
- .spirv,
- .spirv32,
- .spirv64,
- .ve,
- .xtensa,
- => 16,
- };
-}
-
pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
return bitSizeInner(ty, .normal, zcu, {}) catch unreachable;
}