diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index f7a217159e34060f6e5373e73e3a0808307df518..8677b40b95f6df2972819665005bf53c78182d25 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -674,11 +674,12 @@ pub const DataLayout = struct { }, } else first[first.len..]; const bit_width = std.fmt.parseInt(PointerSpec.BitWidth, field_it.next().?, 10) catch unreachable; - const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable); - const pref_align: Alignment = if (field_it.next()) |pref_align| - .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable) - else - abi_align; + const abi_align: Alignment = .fromByteUnits( + @divExact(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable, 8), + ); + const pref_align: Alignment = if (field_it.next()) |pref_align| .fromByteUnits( + @divExact(std.fmt.parseInt(u64, pref_align, 10) catch unreachable, 8), + ) else abi_align; const index_bit_width = if (field_it.next()) |index_bit_width| std.fmt.parseInt(PointerSpec.BitWidth, index_bit_width, 10) catch unreachable else @@ -708,11 +709,12 @@ pub const DataLayout = struct { } var field_it = std.mem.splitScalar(u8, spec[1..], ':'); const bit_width = std.fmt.parseInt(PrimitiveSpec.BitWidth, field_it.first(), 10) catch unreachable; - const abi_align: Alignment = .fromByteUnits(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable); - const pref_align: Alignment = if (field_it.next()) |pref_align| - .fromByteUnits(std.fmt.parseInt(u64, pref_align, 10) catch unreachable) - else - abi_align; + const abi_align: Alignment = .fromByteUnits( + @divExact(std.fmt.parseInt(u64, field_it.next().?, 10) catch unreachable, 8), + ); + const pref_align: Alignment = if (field_it.next()) |pref_align| .fromByteUnits( + @divExact(std.fmt.parseInt(u64, pref_align, 10) catch unreachable, 8), + ) else abi_align; assert(field_it.peek() == null); const specs = switch (kind) { else => unreachable, @@ -720,7 +722,10 @@ pub const DataLayout = struct { 'f' => &float_specs, 'v' => &vector_specs, }; - try specs.put(gpa, .{ .bit_width = bit_width, .abi_align = abi_align, .pref_align = pref_align }, {}); + const primitive_spec: PrimitiveSpec = + .{ .bit_width = bit_width, .abi_align = abi_align, .pref_align = pref_align }; + const gop = try specs.getOrPut(gpa, primitive_spec); + gop.key_ptr.* = primitive_spec; }, 'n' => { var field_it = std.mem.splitScalar(u8, spec[1..], ':'); @@ -784,45 +789,52 @@ pub const DataLayout = struct { data_layout.pointer_specs.deinit(gpa); } - pub fn getIntegerSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec { + pub fn getIntegerSpec(data_layout: *const DataLayout, bit_width: Type.Size) PrimitiveSpec { const specs = data_layout.int_specs.keys(); return specs[ @min(std.sort.lowerBound(PrimitiveSpec, specs, bit_width, struct { - fn order(ctx: PrimitiveSpec.BitWidth, spec: PrimitiveSpec) std.math.Order { - return std.math.order(ctx, spec.bit_width); + fn order(ctx: Type.Size, spec: PrimitiveSpec) std.math.Order { + return std.math.order(ctx.fixed, spec.bit_width); } }.order), specs.len - 1) ]; } - pub fn getFloatSpec(data_layout: *const DataLayout, bit_width: PrimitiveSpec.BitWidth) PrimitiveSpec { + pub fn getFloatSpec(data_layout: *const DataLayout, bit_width: Type.Size) PrimitiveSpec { + const fixed_bit_width: PrimitiveSpec.BitWidth = @intCast(bit_width.fixed); if (data_layout.float_specs.getEntry(.{ - .bit_width = bit_width, + .bit_width = fixed_bit_width, .abi_align = .default, .pref_align = .default, })) |entry| return entry.key_ptr.*; const default_align: Alignment = .fromByteUnits( - std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, bit_width / 8), + std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, @divExact(fixed_bit_width, 8)), ); - return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align }; + return .{ + .bit_width = fixed_bit_width, + .abi_align = default_align, + .pref_align = default_align, + }; } - pub fn getVectorSpec( - data_layout: *const DataLayout, - bit_width: PrimitiveSpec.BitWidth, - store_size: Type.Size, - ) PrimitiveSpec { - if (data_layout.float_specs.getEntry(.{ - .bit_width = bit_width, + pub fn getVectorSpec(data_layout: *const DataLayout, bit_width: Type.Size) PrimitiveSpec { + const known_min_bit_width: PrimitiveSpec.BitWidth = @intCast(switch (bit_width) { + .fixed, .scalable => |known_min| known_min, + }); + if (data_layout.vector_specs.getEntry(.{ + .bit_width = known_min_bit_width, .abi_align = .default, .pref_align = .default, })) |entry| return entry.key_ptr.*; - const default_align: Alignment = .fromByteUnits( - std.math.ceilPowerOfTwoAssert(PrimitiveSpec.BitWidth, switch (store_size) { - .fixed, .scalable => |known_min| known_min, - }), - ); - return .{ .bit_width = bit_width, .abi_align = default_align, .pref_align = default_align }; + const default_align: Alignment = .fromByteUnits(std.math.ceilPowerOfTwoAssert( + PrimitiveSpec.BitWidth, + std.mem.alignForward(PrimitiveSpec.BitWidth, known_min_bit_width, 8), + )); + return .{ + .bit_width = known_min_bit_width, + .abi_align = default_align, + .pref_align = default_align, + }; } pub fn getPointerSpec(data_layout: *const DataLayout, addr_space: AddrSpace) PointerSpec { @@ -1699,6 +1711,22 @@ pub const Type = enum(u32) { .pointer => .{ .fixed = builder.data_layout.getPointerSpec(@fromBackingInt(@intCast(item.data))).bit_width, }, + .vector, .scalable_vector => { + const extra = builder.typeExtraData(Type.Vector, item.data); + const min_bits = extra.len * extra.child.bits(builder).fixed; + return switch (item.tag) { + else => unreachable, + .vector => .{ .fixed = min_bits }, + .scalable_vector => .{ .scalable = min_bits }, + }; + }, + }; + } + + pub fn storeSize(ty: Type, builder: *const Builder) Size { + return switch (ty.bits(builder)) { + .fixed => |fixed| .{ .fixed = @divCeil(fixed, 8) }, + .scalable => |known_min| .{ .scalable = @divCeil(known_min, 8) }, }; } @@ -1716,7 +1744,7 @@ pub const Type = enum(u32) { }; }, .half, .bfloat, .float, .double, .ppc_fp128, .fp128, .x86_fp80 => { - const spec = builder.data_layout.getFloatSpec(@intCast(ty.bits(builder).fixed)); + const spec = builder.data_layout.getFloatSpec(ty.bits(builder)); return switch (kind) { .abi => spec.abi_align, .pref => spec.pref_align, @@ -1725,7 +1753,7 @@ pub const Type = enum(u32) { .x86_amx => return comptime .fromByteUnits(64), }, .integer => { - const spec = builder.data_layout.getIntegerSpec(@intCast(item.data)); + const spec = builder.data_layout.getIntegerSpec(.{ .fixed = item.data }); return switch (kind) { .abi => spec.abi_align, .pref => spec.pref_align, @@ -1738,6 +1766,13 @@ pub const Type = enum(u32) { .pref => spec.flags.pref_align, }; }, + .vector, .scalable_vector => { + const spec = builder.data_layout.getVectorSpec(ty.bits(builder)); + return switch (kind) { + .abi => spec.abi_align, + .pref => spec.pref_align, + }; + }, } } }; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index a8adfba6fc0c39da8db4226231dfd50387a123ec..74e9b24127e9ec94cf4c7868be535d85c1b273f4 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2484,7 +2484,7 @@ pub const Object = struct { .memory_access => {}, .in_memory => { const zig_align = std.zig.target.intAlignment(target, bits); - const llvm_align = o.builder.data_layout.getIntegerSpec(llvm_bit_width).abi_align; + const llvm_align = o.builder.data_layout.getIntegerSpec(.{ .fixed = llvm_bit_width }).abi_align; if (zig_align < llvm_align.toByteUnits().?) return o.builder.arrayType(abi_size, .i8); }, } diff --git a/src/dev.zig b/src/dev.zig index 6472f65f518bcc909f72ce3863c72dd0c6a2c4fc..b9e448ef7e53668bfac8044f6dfd3cabf6ead9bd 100644 --- a/src/dev.zig +++ b/src/dev.zig @@ -32,6 +32,14 @@ pub const Env = enum { /// - `zig build-* -ofmt=c` cbe, + /// - sema + /// - zig build-* -fincremental -fllvm -flld --listen=-` + llvm, + + /// - sema + /// - `zig build-* -fincremental -fno-llvm -fno-lld -target loongarch(32/64)-linux --listen=-` + @"loongarch-linux", + /// - sema /// - `zig build-* -fincremental -fno-llvm -fno-lld -target powerpc(64)(le)-linux --listen=-` @"powerpc-linux", @@ -44,6 +52,10 @@ pub const Env = enum { /// - `zig build-* -fno-llvm -fno-lld -target spirv(32/64)-* --listen=-` spirv, + /// - sema + /// - `zig build-* -fno-llvm -fno-lld -target spork8-* --listen=-` + spork8, + /// - sema /// - `zig build-* -fno-llvm -fno-lld -target wasm32-* --listen=-` wasm, @@ -56,14 +68,6 @@ pub const Env = enum { /// - `zig build-* -fincremental -fno-llvm -fno-lld -target x86_64-windows --listen=-` @"x86_64-windows", - /// - sema - /// - `zig build-* -fincremental -fno-llvm -fno-lld -target loongarch(32/64)-linux --listen=-` - @"loongarch-linux", - - /// - sema - /// - `zig build-* -fno-llvm -fno-lld -target spork8-* --listen=-` - spork8, - pub inline fn supports(comptime dev_env: Env, comptime feature: Feature) bool { return switch (dev_env) { .full => true, @@ -186,6 +190,24 @@ pub const Env = enum { => true, else => Env.sema.supports(feature), }, + .llvm => switch (feature) { + .stdio_listen, + .incremental, + .legalize, + .llvm_backend, + .lld_linker, + => true, + else => Env.sema.supports(feature), + }, + .@"loongarch-linux" => switch (feature) { + .stdio_listen, + .incremental, + .legalize, + .loongarch_backend, + .elf2_linker, + => true, + else => Env.sema.supports(feature), + }, .@"powerpc-linux" => switch (feature) { .stdio_listen, .incremental, @@ -207,6 +229,15 @@ pub const Env = enum { => true, else => Env.sema.supports(feature), }, + .spork8 => switch (feature) { + .stdio_listen, + .incremental, + .legalize, + .spork8_backend, + .spork8_linker, + => true, + else => Env.sema.supports(feature), + }, .wasm => switch (feature) { .incremental, .legalize, @@ -235,24 +266,6 @@ pub const Env = enum { => true, else => Env.sema.supports(feature), }, - .@"loongarch-linux" => switch (feature) { - .stdio_listen, - .incremental, - .legalize, - .loongarch_backend, - .elf2_linker, - => true, - else => Env.sema.supports(feature), - }, - .spork8 => switch (feature) { - .stdio_listen, - .incremental, - .legalize, - .spork8_backend, - .spork8_linker, - => true, - else => Env.sema.supports(feature), - }, }; }