backend progress

The x86_64 backend now compiles and, with `-fstrip`, kinda works!
This commit is contained in:
Matthew Lugg 2026-01-22 16:30:15 +00:00
parent 372b3c33c1
commit f0a9ed38af
No known key found for this signature in database
GPG key ID: 3F5B7DCCBF4AF02E
6 changed files with 145 additions and 146 deletions

View file

@ -4150,6 +4150,13 @@ pub const Index = enum(u32) {
const extra = ip.getLocalShared(slice.tid).extra.acquire();
return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
}
/// If `slice` is empty (`slice.len == 0`), returns `.none`.
/// Otherwise, asserts that `index < slice.len`, and returns the value at `index`.
pub fn getOrNone(slice: Slice, ip: *const InternPool, index: usize) Index {
if (slice.len == 0) return .none;
return slice.get(ip)[index];
}
};
/// Used for a map of `Index` values to the index within a list of `Index` values.
@ -5981,6 +5988,13 @@ pub const Alignment = enum(u6) {
const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
return @ptrCast(bytes[0..slice.len]);
}
/// If `slice` is empty (`slice.len == 0`), returns `.none`.
/// Otherwise, asserts that `index < slice.len`, and returns the value at `index`.
pub fn getOrNone(slice: Slice, ip: *const InternPool, index: usize) Alignment {
if (slice.len == 0) return .none;
return slice.get(ip)[index];
}
};
pub fn toRelaxedCompareUnits(a: Alignment) u8 {

View file

@ -4097,6 +4097,7 @@ pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!
}
// TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`.
// MLUGG TODO: that's done, move it!
pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment {
const zcu = pt.zcu;
const ty: Type, const alignment = switch (zcu.intern_pool.getNav(nav_index).status) {

View file

@ -377,7 +377,7 @@ pub fn generateSymbol(
.payload => 0,
};
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
if (!payload_ty.hasRuntimeBits(zcu)) {
try w.writeInt(u16, err_val, endian);
return;
}
@ -610,7 +610,7 @@ pub fn generateSymbol(
.auto, .@"extern" => {
const struct_begin = w.end;
const field_types = struct_type.field_types.get(ip);
const offsets = struct_type.offsets.get(ip);
const offsets = struct_type.field_offsets.get(ip);
var it = struct_type.iterateRuntimeOrder(ip);
while (it.next()) |field_index| {
@ -635,13 +635,11 @@ pub fn generateSymbol(
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
}
const size = struct_type.sizeUnordered(ip);
const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?;
assert(struct_type.alignment.check(struct_type.size));
const padding = math.cast(
usize,
std.mem.alignForward(u64, size, @max(alignment, 1)) - (w.end - struct_begin),
) orelse return error.Overflow;
const padding = math.cast(usize, struct_type.size - (w.end - struct_begin)) orelse {
return error.Overflow;
};
if (padding > 0) try w.splatByteAll(0, padding);
},
}
@ -1060,51 +1058,38 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
switch (ty.zigTypeTag(zcu)) {
.void => return .none,
.bool => return .{ .immediate = @intFromBool(val.toBool()) },
.pointer => switch (ty.ptrSize(zcu)) {
.slice => {},
else => switch (val.toIntern()) {
.null_value => {
return .{ .immediate = 0 };
},
else => switch (ip.indexToKey(val.toIntern())) {
.int => {
return .{ .immediate = val.toUnsignedInt(zcu) };
},
.ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
.nav => |nav| {
if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
1 => 0xaa,
2 => 0xaaaa,
4 => 0xaaaaaaaa,
8 => 0xaaaaaaaaaaaaaaaa,
else => unreachable,
};
return .{ .immediate = imm };
}
.one, .many, .c => {
const elem_ty = ty.childType(zcu);
const ptr = ip.indexToKey(val.toIntern()).ptr;
if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
switch (ptr.base_addr) {
.int => unreachable, // handled above
if (ty.castPtrToFn(zcu)) |fn_ty| {
if (zcu.typeToFunc(fn_ty).?.is_generic) {
return .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? };
}
} else if (ty.zigTypeTag(zcu) == .pointer) {
const elem_ty = ty.childType(zcu);
if (!elem_ty.hasRuntimeBits(zcu)) {
return .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? };
}
}
return .{ .lea_nav = nav };
},
.uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).hasRuntimeBits(zcu))
return .{ .lea_uav = uav }
else
return .{ .immediate = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu)
.forward(@intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() | 1)) / 3)) },
else => {},
.nav => |nav| if (elem_ty.isFnOrHasRuntimeBits(zcu)) {
return .{ .lea_nav = nav };
} else {
// Create the 0xaa bit pattern...
const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
// ...but align the pointer
const alignment = pt.navAlignment(nav);
return .{ .immediate = alignment.forward(undef_ptr_bits) };
},
.uav => |uav| if (elem_ty.isFnOrHasRuntimeBits(zcu)) {
return .{ .lea_uav = uav };
} else {
// Create the 0xaa bit pattern...
const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
// ...but align the pointer
const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
return .{ .immediate = alignment.forward(undef_ptr_bits) };
},
else => {},
},
}
},
},
.int => {
@ -1117,9 +1102,6 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
return .{ .immediate = unsigned };
}
},
.bool => {
return .{ .immediate = @intFromBool(val.toBool()) };
},
.optional => {
if (ty.isPtrLikeOptional(zcu)) {
return lowerValue(
@ -1147,7 +1129,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
.error_union => {
const err_type = ty.errorUnionSet(zcu);
const payload_type = ty.errorUnionPayload(zcu);
if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
if (!payload_type.hasRuntimeBits(zcu)) {
// We use the error type directly as the type.
const err_int_ty = try pt.errorIntType();
switch (ip.indexToKey(val.toIntern()).error_union.val) {
@ -1187,10 +1169,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
}
pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
if (!payload_ty.hasRuntimeBits(zcu)) return 0;
const payload_align = payload_ty.abiAlignment(zcu);
const error_align = Type.anyerror.abiAlignment(zcu);
if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBits(zcu)) {
return 0;
} else {
return payload_align.forward(Type.anyerror.abiSize(zcu));
@ -1198,10 +1180,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
}
pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
if (!payload_ty.hasRuntimeBits(zcu)) return 0;
const payload_align = payload_ty.abiAlignment(zcu);
const error_align = Type.anyerror.abiAlignment(zcu);
if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBits(zcu)) {
return error_align.forward(payload_ty.abiSize(zcu));
} else {
return 0;

View file

@ -43261,7 +43261,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
try ops[0].toSlicePtr(cg);
var res: [1]Temp = undefined;
if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBits(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
.patterns = &.{
.{ .src = .{ .to_gpr, .simm32, .none } },
},
@ -43375,7 +43375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
try ops[0].toSlicePtr(cg);
var res: [1]Temp = undefined;
if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBits(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
.patterns = &.{
.{ .src = .{ .to_gpr, .simm32, .none } },
},
@ -103699,7 +103699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.optional_payload => {
const ty_op = air_datas[@intFromEnum(inst)].ty_op;
var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
const pl = if (!hack_around_sema_opv_bugs or ty_op.ty.toType().hasRuntimeBitsIgnoreComptime(zcu))
const pl = if (!hack_around_sema_opv_bugs or ty_op.ty.toType().hasRuntimeBits(zcu))
try ops[0].read(ty_op.ty.toType(), .{}, cg)
else
try cg.tempInit(ty_op.ty.toType(), .none);
@ -103745,7 +103745,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const eu_pl_ty = ty_op.ty.toType();
const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu));
var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
const pl = if (!hack_around_sema_opv_bugs or eu_pl_ty.hasRuntimeBitsIgnoreComptime(zcu))
const pl = if (!hack_around_sema_opv_bugs or eu_pl_ty.hasRuntimeBits(zcu))
try ops[0].read(eu_pl_ty, .{ .disp = eu_pl_off }, cg)
else
try cg.tempInit(eu_pl_ty, .none);
@ -103864,7 +103864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.@"packed" => unreachable,
};
var ops = try cg.tempsFromOperands(inst, .{struct_field.struct_operand});
var res = if (!hack_around_sema_opv_bugs or field_ty.hasRuntimeBitsIgnoreComptime(zcu))
var res = if (!hack_around_sema_opv_bugs or field_ty.hasRuntimeBits(zcu))
try ops[0].read(field_ty, .{ .disp = field_off }, cg)
else
try cg.tempInit(field_ty, .none);
@ -104125,7 +104125,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
try ops[0].toSlicePtr(cg);
var res: [1]Temp = undefined;
if (!hack_around_sema_opv_bugs or res_ty.hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
if (!hack_around_sema_opv_bugs or res_ty.hasRuntimeBits(zcu)) cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
.dst_constraints = .{ .{ .int = .byte }, .any },
.patterns = &.{
.{ .src = .{ .to_gpr, .simm32, .none } },
@ -171422,10 +171422,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.auto, .@"extern" => {
for (elems, 0..) |elem_ref, field_index| {
const elem_dies = bt.feed();
if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
if (!hack_around_sema_opv_bugs or Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]).hasRuntimeBitsIgnoreComptime(zcu)) {
if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
if (!hack_around_sema_opv_bugs or Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]).hasRuntimeBits(zcu)) {
var elem = try cg.tempFromOperand(elem_ref, elem_dies);
try res.write(&elem, .{ .disp = @intCast(loaded_struct.offsets.get(ip)[field_index]) }, cg);
try res.write(&elem, .{ .disp = @intCast(loaded_struct.field_offsets.get(ip)[field_index]) }, cg);
try elem.die(cg);
try cg.resetTemps(reset_index);
}
@ -171441,7 +171441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const elem_dies = bt.feed();
if (tuple_type.values.get(ip)[field_index] != .none) continue;
const field_type = Type.fromInterned(tuple_type.types.get(ip)[field_index]);
if (!hack_around_sema_opv_bugs or field_type.hasRuntimeBitsIgnoreComptime(zcu)) {
if (!hack_around_sema_opv_bugs or field_type.hasRuntimeBits(zcu)) {
elem_disp = @intCast(field_type.abiAlignment(zcu).forward(elem_disp));
var elem = try cg.tempFromOperand(elem_ref, elem_dies);
try res.write(&elem, .{ .disp = elem_disp }, cg);
@ -173756,7 +173756,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
var data_off: i32 = 0;
const reset_index = cg.next_temp_index;
const tag_names = ip.loadEnumType(lazy_sym.ty).names;
const tag_names = ip.loadEnumType(lazy_sym.ty).field_names;
for (0..tag_names.len) |tag_index| {
var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {
else => unreachable,
@ -174334,7 +174334,7 @@ fn genUnwrapErrUnionPayloadMir(
const payload_ty = err_union_ty.errorUnionPayload(zcu);
const result: MCValue = result: {
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
switch (err_union) {
@ -174450,7 +174450,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE
const pt = self.pt;
const zcu = pt.zcu;
const dst_ty = ptr_ty.childType(zcu);
if (!dst_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
if (!dst_ty.hasRuntimeBits(zcu)) return;
switch (ptr_mcv) {
.none,
.unreach,
@ -174503,7 +174503,7 @@ fn store(
const pt = self.pt;
const zcu = pt.zcu;
const src_ty = ptr_ty.childType(zcu);
if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
if (!src_ty.hasRuntimeBits(zcu)) return;
switch (ptr_mcv) {
.none,
.unreach,
@ -176615,7 +176615,7 @@ fn lowerSwitchBr(
break :condition_index condition_index;
};
try cg.spillEflagsIfOccupied();
if (min.?.orderAgainstZero(zcu).compare(.neq)) try cg.genBinOpMir(
if (Value.compareHetero(min.?, .neq, .zero_comptime_int, zcu)) try cg.genBinOpMir(
.{ ._, .sub },
condition_ty,
condition_index,
@ -176957,7 +176957,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {
const unsigned_condition_ty = try self.pt.intType(.unsigned, self.intInfo(condition_ty).?.bits);
const condition_mcv = block_tracking.short;
try self.spillEflagsIfOccupied();
if (table.min.orderAgainstZero(self.pt.zcu).compare(.neq)) try self.genBinOpMir(
if (Value.compareHetero(table.min, .neq, .zero_comptime_int, self.pt.zcu)) try self.genBinOpMir(
.{ ._, .sub },
condition_ty,
condition_mcv,
@ -177054,8 +177054,7 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void {
const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
const block_ty = self.typeOfIndex(br.block_inst);
const block_unused =
!block_ty.hasRuntimeBitsIgnoreComptime(zcu) or self.liveness.isUnused(br.block_inst);
const block_unused = !block_ty.hasRuntimeBits(zcu) or self.liveness.isUnused(br.block_inst);
const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
const block_data = self.blocks.getPtr(br.block_inst).?;
const first_br = block_data.relocs.items.len == 0;
@ -180986,7 +180985,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {
const ty = self.typeOf(ref);
// If the type has no codegen bits, no need to store it.
if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
if (!ty.hasRuntimeBits(zcu)) return .none;
const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {
break :mcv self.inst_tracking.getPtr(inst).?.short;
@ -181105,7 +181104,7 @@ fn resolveCallingConventionValues(
// Return values
if (ret_ty.isNoReturn(zcu)) {
result.return_value = .init(.unreach);
} else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
} else if (!ret_ty.hasRuntimeBits(zcu)) {
// TODO: is this even possible for C calling convention?
result.return_value = .init(.none);
} else {
@ -181182,7 +181181,7 @@ fn resolveCallingConventionValues(
// Input params
params: for (param_types, result.args) |ty, *arg| {
assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
assert(ty.hasRuntimeBits(zcu));
result.air_arg_count += 1;
switch (cc) {
.x86_64_sysv => {},
@ -181327,7 +181326,7 @@ fn resolveCallingConventionValues(
// Return values
result.return_value = if (ret_ty.isNoReturn(zcu))
.init(.unreach)
else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu))
else if (!ret_ty.hasRuntimeBits(zcu))
.init(.none)
else return_value: {
const ret_gpr = abi.getCAbiIntReturnRegs(cc);
@ -181357,7 +181356,7 @@ fn resolveCallingConventionValues(
// Input params
for (param_types, result.args) |param_ty, *arg| {
if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
if (!param_ty.hasRuntimeBits(zcu)) {
arg.* = .none;
continue;
}
@ -181721,7 +181720,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
.one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
.slice => null,
},
.opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBitsIgnoreComptime(zcu))
.opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBits(zcu))
.{ .signedness = .unsigned, .bits = 1 }
else switch (ip.indexToKey(opt_child)) {
.ptr_type => |ptr_type| switch (ptr_type.flags.size) {
@ -181734,7 +181733,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
else => null,
},
.error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type)
.hasRuntimeBitsIgnoreComptime(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null,
.hasRuntimeBits(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null,
.simple_type => |simple_type| return switch (simple_type) {
.bool => .{ .signedness = .unsigned, .bits = 1 },
.anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
@ -181767,14 +181766,17 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
const loaded_struct = ip.loadStructType(ty_index);
switch (loaded_struct.layout) {
.auto, .@"extern" => return null,
.@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip),
.@"packed" => ty_index = loaded_struct.packed_backing_int_type,
}
},
.union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) {
.auto, .@"extern" => null,
.@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) },
.union_type => {
const loaded_union = ip.loadUnionType(ty_index);
switch (loaded_union.layout) {
.auto, .@"extern" => return null,
.@"packed" => ty_index = loaded_union.packed_backing_int_type,
}
},
.enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty,
.enum_type => ty_index = ip.loadEnumType(ty_index).int_tag_type,
.error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
else => return null,
};

View file

@ -339,7 +339,7 @@ fn classifySystemVStruct(
var field_it = loaded_struct.iterateRuntimeOrder(ip);
while (field_it.next()) |field_index| {
const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
const field_align = loaded_struct.fieldAlign(ip, field_index);
const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index);
byte_offset = std.mem.alignForward(
u64,
byte_offset,
@ -355,7 +355,7 @@ fn classifySystemVStruct(
.@"packed" => {},
}
} else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
switch (field_loaded_union.flagsUnordered(ip).layout) {
switch (field_loaded_union.layout) {
.auto => unreachable,
.@"extern" => {
byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target);
@ -369,11 +369,11 @@ fn classifySystemVStruct(
result_class.* = result_class.combineSystemV(field_class);
byte_offset += field_ty.abiSize(zcu);
}
const final_byte_offset = starting_byte_offset + loaded_struct.sizeUnordered(ip);
const final_byte_offset = starting_byte_offset + loaded_struct.size;
std.debug.assert(final_byte_offset == std.mem.alignForward(
u64,
byte_offset,
loaded_struct.flagsUnordered(ip).alignment.toByteUnits().?,
loaded_struct.alignment.toByteUnits().?,
));
return final_byte_offset;
}
@ -398,7 +398,7 @@ fn classifySystemVUnion(
.@"packed" => {},
}
} else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
switch (field_loaded_union.flagsUnordered(ip).layout) {
switch (field_loaded_union.layout) {
.auto => unreachable,
.@"extern" => {
_ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target);
@ -411,7 +411,7 @@ fn classifySystemVUnion(
for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
result_class.* = result_class.combineSystemV(field_class);
}
return starting_byte_offset + loaded_union.sizeUnordered(ip);
return starting_byte_offset + loaded_union.size;
}
pub const zigcc = struct {

View file

@ -2243,8 +2243,8 @@ pub const WipNav = struct {
const zcu = wip_nav.pt.zcu;
const ip = &zcu.intern_pool;
var big_int_space: Value.BigIntSpace = undefined;
try wip_nav.bigIntConstValue(abbrev_code, .fromInterned(loaded_enum.tag_ty), if (loaded_enum.values.len > 0)
Value.fromInterned(loaded_enum.values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)
try wip_nav.bigIntConstValue(abbrev_code, .fromInterned(loaded_enum.int_tag_type), if (loaded_enum.field_values.len > 0)
Value.fromInterned(loaded_enum.field_values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)
else
std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
}
@ -3164,8 +3164,8 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
try diw.writeUleb128(nav_val.toType().abiSize(zcu));
try diw.writeUleb128(nav_val.toType().abiAlignment(zcu).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
const field_init = loaded_struct.fieldInit(ip, field_index);
const is_comptime = loaded_struct.field_is_comptime_bits.get(ip, field_index);
const field_init = loaded_struct.field_defaults.getOrNone(ip, field_index);
assert(!(is_comptime and field_init == .none));
const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
const has_runtime_bits, const has_comptime_state = switch (field_init) {
@ -3191,11 +3191,11 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
.struct_field
else
.struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
try wip_nav.refType(field_type);
if (!is_comptime) {
try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_struct.field_offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
field_type.abiAlignment(zcu).toByteUnits().?);
}
if (has_comptime_state)
@ -3212,11 +3212,11 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
.generic_decl = .generic_decl_const,
.decl_instance = .decl_instance_packed_struct,
}, &nav, inst_info.file, &decl);
try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
try wip_nav.refType(.fromInterned(loaded_struct.packed_backing_int_type));
var field_bit_offset: u16 = 0;
for (0..loaded_struct.field_types.len) |field_index| {
try wip_nav.abbrevCode(.packed_struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(field_bit_offset);
@ -3246,7 +3246,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
}
wip_nav.entry = nav_gop.value_ptr.*;
const diw = &wip_nav.debug_info.writer;
try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{
try wip_nav.declCommon(if (loaded_enum.field_names.len > 0) .{
.decl = .decl_enum,
.generic_decl = .generic_decl_const,
.decl_instance = .decl_instance_enum,
@ -3255,16 +3255,16 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
.generic_decl = .generic_decl_const,
.decl_instance = .decl_instance_empty_enum,
}, &nav, inst_info.file, &decl);
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
for (0..loaded_enum.names.len) |field_index| {
try wip_nav.refType(.fromInterned(loaded_enum.int_tag_type));
for (0..loaded_enum.field_names.len) |field_index| {
try wip_nav.enumConstValue(loaded_enum, .{
.sdata = .signed_enum_field,
.udata = .unsigned_enum_field,
.block = .big_enum_field,
}, field_index);
try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
}
if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
if (loaded_enum.field_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
break :tag .done;
},
.union_type => tag: {
@ -3293,8 +3293,8 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
const union_layout = Type.getUnionLayout(loaded_union, zcu);
try diw.writeUleb128(union_layout.abi_size);
try diw.writeUleb128(union_layout.abi_align.toByteUnits().?);
const loaded_tag = loaded_union.loadTagType(ip);
if (loaded_union.hasTag(ip)) {
const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
if (loaded_union.runtime_tag != .none) {
try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
@ -3305,7 +3305,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
{
try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("tag");
try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty));
try wip_nav.refType(.fromInterned(loaded_union.enum_tag_type));
try diw.writeUleb128(union_layout.tagOffset());
for (0..loaded_union.field_types.len) |field_index| {
@ -3316,11 +3316,11 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
}, field_index);
{
try wip_nav.abbrevCode(.struct_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(union_layout.payloadOffset());
try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
}
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
@ -3329,10 +3329,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
} else for (0..loaded_union.field_types.len) |field_index| {
try wip_nav.abbrevCode(.untagged_union_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
}
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
@ -3877,18 +3877,18 @@ fn updateLazyType(
},
.enum_type => {
const loaded_enum = ip.loadEnumType(type_index);
try wip_nav.abbrevCode(if (loaded_enum.names.len == 0) .generated_empty_enum_type else .generated_enum_type);
try wip_nav.abbrevCode(if (loaded_enum.field_names.len == 0) .generated_empty_enum_type else .generated_enum_type);
try wip_nav.strp(name);
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
for (0..loaded_enum.names.len) |field_index| {
try wip_nav.refType(.fromInterned(loaded_enum.int_tag_type));
for (0..loaded_enum.field_names.len) |field_index| {
try wip_nav.enumConstValue(loaded_enum, .{
.sdata = .signed_enum_field,
.udata = .unsigned_enum_field,
.block = .big_enum_field,
}, field_index);
try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
}
if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
if (loaded_enum.field_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
},
.func_type => |func_type| {
const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
@ -4349,7 +4349,7 @@ fn updateLazyValue(
const loaded_struct_type = ip.loadStructType(aggregate.ty);
assert(loaded_struct_type.layout == .auto);
for (0..loaded_struct_type.field_types.len) |field_index| {
if (loaded_struct_type.fieldIsComptime(ip, field_index)) continue;
if (loaded_struct_type.field_is_comptime_bits.get(ip, field_index)) continue;
const field_type: Type = .fromInterned(loaded_struct_type.field_types.get(ip)[field_index]);
const has_runtime_bits = field_type.hasRuntimeBits(zcu);
const has_comptime_state = field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null;
@ -4359,7 +4359,7 @@ fn updateLazyValue(
.comptime_value_field_runtime_bits
else
continue);
try wip_nav.strp(loaded_struct_type.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct_type.field_names.get(ip)[field_index].toSlice(ip));
const field_value: Value = .fromInterned(switch (aggregate.storage) {
.bytes => unreachable,
.elems => |elems| elems[field_index],
@ -4427,10 +4427,10 @@ fn updateLazyValue(
try wip_nav.refType(.fromInterned(un.ty));
field: {
const loaded_union_type = ip.loadUnionType(un.ty);
assert(loaded_union_type.flagsUnordered(ip).layout == .auto);
assert(loaded_union_type.layout == .auto);
const field_index = zcu.unionTagFieldIndex(loaded_union_type, Value.fromInterned(un.tag)).?;
const field_ty: Type = .fromInterned(loaded_union_type.field_types.get(ip)[field_index]);
const field_name = loaded_union_type.loadTagType(ip).names.get(ip)[field_index];
const field_name = ip.loadEnumType(loaded_union_type.enum_tag_type).field_names.get(ip)[field_index];
const has_runtime_bits = field_ty.hasRuntimeBits(zcu);
const has_comptime_state = field_ty.comptimeOnly(zcu) and try field_ty.onePossibleValue(pt) == null;
try wip_nav.abbrevCode(if (has_comptime_state)
@ -4521,8 +4521,8 @@ fn updateContainerTypeWriterError(
try diw.writeUleb128(ty.abiSize(zcu));
try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
const field_init = loaded_struct.fieldInit(ip, field_index);
const is_comptime = loaded_struct.field_is_comptime_bits.get(ip, field_index);
const field_init = loaded_struct.field_defaults.getOrNone(ip, field_index);
assert(!(is_comptime and field_init == .none));
const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
const has_runtime_bits, const has_comptime_state = switch (field_init) {
@ -4548,11 +4548,11 @@ fn updateContainerTypeWriterError(
.struct_field
else
.struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
try wip_nav.refType(field_type);
if (!is_comptime) {
try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_struct.field_offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
field_type.abiAlignment(zcu).toByteUnits().?);
}
if (has_comptime_state)
@ -4628,8 +4628,8 @@ fn updateContainerTypeWriterError(
try diw.writeUleb128(ty.abiSize(zcu));
try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
for (0..loaded_struct.field_types.len) |field_index| {
const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
const field_init = loaded_struct.fieldInit(ip, field_index);
const is_comptime = loaded_struct.field_is_comptime_bits.get(ip, field_index);
const field_init = loaded_struct.field_defaults.getOrNone(ip, field_index);
assert(!(is_comptime and field_init == .none));
const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
const has_runtime_bits, const has_comptime_state = switch (field_init) {
@ -4655,11 +4655,11 @@ fn updateContainerTypeWriterError(
.struct_field
else
.struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
try wip_nav.refType(field_type);
if (!is_comptime) {
try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_struct.field_offsets.get(ip)[field_index]);
try diw.writeUleb128(loaded_struct.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
field_type.abiAlignment(zcu).toByteUnits().?);
}
if (has_comptime_state)
@ -4674,11 +4674,11 @@ fn updateContainerTypeWriterError(
try wip_nav.abbrevCode(if (loaded_struct.field_types.len > 0) .packed_struct_type else .empty_packed_struct_type);
try diw.writeUleb128(file_gop.index);
try wip_nav.strp(name);
try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
try wip_nav.refType(.fromInterned(loaded_struct.packed_backing_int_type));
var field_bit_offset: u16 = 0;
for (0..loaded_struct.field_types.len) |field_index| {
try wip_nav.abbrevCode(.packed_struct_field);
try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(field_bit_offset);
@ -4690,19 +4690,19 @@ fn updateContainerTypeWriterError(
},
.enum_type => {
const loaded_enum = ip.loadEnumType(type_index);
try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
try wip_nav.abbrevCode(if (loaded_enum.field_names.len > 0) .enum_type else .empty_enum_type);
try diw.writeUleb128(file_gop.index);
try wip_nav.strp(name);
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
for (0..loaded_enum.names.len) |field_index| {
try wip_nav.refType(.fromInterned(loaded_enum.int_tag_type));
for (0..loaded_enum.field_names.len) |field_index| {
try wip_nav.enumConstValue(loaded_enum, .{
.sdata = .signed_enum_field,
.udata = .unsigned_enum_field,
.block = .big_enum_field,
}, field_index);
try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
}
if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
if (loaded_enum.field_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
},
.union_type => {
const loaded_union = ip.loadUnionType(type_index);
@ -4712,8 +4712,8 @@ fn updateContainerTypeWriterError(
const union_layout = Type.getUnionLayout(loaded_union, zcu);
try diw.writeUleb128(union_layout.abi_size);
try diw.writeUleb128(union_layout.abi_align.toByteUnits().?);
const loaded_tag = loaded_union.loadTagType(ip);
if (loaded_union.hasTag(ip)) {
const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
if (loaded_union.runtime_tag != .none) {
try wip_nav.abbrevCode(.tagged_union);
try wip_nav.infoSectionOffset(
.debug_info,
@ -4724,7 +4724,7 @@ fn updateContainerTypeWriterError(
{
try wip_nav.abbrevCode(.generated_field);
try wip_nav.strp("tag");
try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty));
try wip_nav.refType(.fromInterned(loaded_union.enum_tag_type));
try diw.writeUleb128(union_layout.tagOffset());
for (0..loaded_union.field_types.len) |field_index| {
@ -4735,11 +4735,11 @@ fn updateContainerTypeWriterError(
}, field_index);
{
try wip_nav.abbrevCode(.struct_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(union_layout.payloadOffset());
try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
}
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
@ -4748,10 +4748,10 @@ fn updateContainerTypeWriterError(
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
} else for (0..loaded_union.field_types.len) |field_index| {
try wip_nav.abbrevCode(.untagged_union_field);
try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
try wip_nav.refType(field_type);
try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
}
if (loaded_union.field_types.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));