@@ -2457,7 +2457,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24572457 .load => try cg.airLoad(inst),
24582458 .store => try cg.airStore(inst, false),
24592459 .store_safe => try cg.airStore(inst, true),
2460- .struct_field_val => try cg.airStructFieldVal(inst),
24612460 .float_from_int => try cg.airFloatFromInt(inst),
24622461 .int_from_float => try cg.airIntFromFloat(inst),
24632462 .cmpxchg_strong => try cg.airCmpxchg(inst),
@@ -9723,11 +9722,32 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
97239722 ), cg);
97249723 try ops[0].moveTo(inst, cg);
97259724 },
9725+ .struct_field_val => if (use_old) try cg.airStructFieldVal(inst) else fallback: {
9726+ const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
9727+ const extra = cg.air.extraData(Air.StructField, ty_pl.payload).data;
9728+ const agg_ty = cg.typeOf(extra.struct_operand);
9729+ const field_ty = ty_pl.ty.toType();
9730+ const field_off: u31 = switch (agg_ty.containerLayout(zcu)) {
9731+ .auto, .@"extern" => @intCast(agg_ty.structFieldOffset(extra.field_index, zcu)),
9732+ .@"packed" => break :fallback try cg.airStructFieldVal(inst),
9733+ };
9734+ if (field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
9735+ var ops = try cg.tempsFromOperands(inst, .{extra.struct_operand});
9736+ var res = try ops[0].read(field_off, field_ty, cg);
9737+ for (ops) |op| if (op.index != res.index) try op.die(cg);
9738+ try res.moveTo(inst, cg);
9739+ } else {
9740+ // hack around Sema OPV bugs
9741+ const res = try cg.tempInit(field_ty, .none);
9742+ try res.moveTo(inst, cg);
9743+ }
9744+ },
97269745 .set_union_tag => if (use_old) try cg.airSetUnionTag(inst) else {
97279746 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
97289747 const union_ty = cg.typeOf(bin_op.lhs).childType(zcu);
97299748 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
97309749 const union_layout = union_ty.unionGetLayout(zcu);
9750+ // hack around Sema OPV bugs
97319751 if (union_layout.tag_size > 0) try ops[0].store(@intCast(union_layout.tagOffset()), &ops[1], cg);
97329752 for (ops) |op| try op.die(cg);
97339753 },
@@ -9857,6 +9877,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
98579877 } },
98589878 } }) catch |err| switch (err) {
98599879 error.SelectFailed => switch (res_ty.abiSize(zcu)) {
9880+ // hack around Sema OPV bugs
98609881 0 => res[0] = try cg.tempInit(res_ty, .none),
98619882 else => |elem_size| {
98629883 while (true) for (&ops) |*op| {
@@ -9917,6 +9938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
99179938 const dst_ty = ty_pl.ty.toType();
99189939 if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: {
99199940 const elem_size = dst_ty.childType(zcu).abiSize(zcu);
9941+ // hack around Sema OPV bugs
99209942 if (elem_size == 0) break :zero_offset;
99219943 while (true) for (&ops) |*op| {
99229944 if (try op.toRegClass(true, .general_purpose, cg)) break;
@@ -15804,7 +15826,7 @@ fn fieldOffset(self: *CodeGen, ptr_agg_ty: Type, ptr_field_ty: Type, field_index
1580415826 return switch (agg_ty.containerLayout(zcu)) {
1580515827 .auto, .@"extern" => @intCast(agg_ty.structFieldOffset(field_index, zcu)),
1580615828 .@"packed" => @divExact(@as(i32, ptr_agg_ty.ptrInfo(zcu).packed_offset.bit_offset) +
15807- (if (zcu.typeToStruct(agg_ty)) |struct_obj | pt.structPackedFieldBitOffset(struct_obj , field_index) else 0) -
15829+ (if (zcu.typeToStruct(agg_ty)) |loaded_struct | pt.structPackedFieldBitOffset(loaded_struct , field_index) else 0) -
1580815830 ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8),
1580915831 };
1581015832}
@@ -15828,8 +15850,8 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void {
1582815850 const src_mcv = try self.resolveInst(operand);
1582915851 const field_off: u32 = switch (container_ty.containerLayout(zcu)) {
1583015852 .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8),
15831- .@"packed" => if (zcu.typeToStruct(container_ty)) |struct_obj |
15832- pt.structPackedFieldBitOffset(struct_obj , extra.field_index)
15853+ .@"packed" => if (zcu.typeToStruct(container_ty)) |loaded_struct |
15854+ pt.structPackedFieldBitOffset(loaded_struct , extra.field_index)
1583315855 else
1583415856 0,
1583515857 };
@@ -26448,7 +26470,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {
2644826470 .@"struct" => {
2644926471 const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu));
2645026472 if (result_ty.containerLayout(zcu) == .@"packed") {
26451- const struct_obj = zcu.typeToStruct (result_ty).? ;
26473+ const loaded_struct = zcu.intern_pool.loadStructType (result_ty.toIntern()) ;
2645226474 try self.genInlineMemset(
2645326475 .{ .lea_frame = .{ .index = frame_index } },
2645426476 .{ .immediate = 0 },
@@ -26469,7 +26491,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void {
2646926491 }
2647026492 const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu));
2647126493 const elem_abi_bits = elem_abi_size * 8;
26472- const elem_off = pt.structPackedFieldBitOffset(struct_obj , elem_i);
26494+ const elem_off = pt.structPackedFieldBitOffset(loaded_struct , elem_i);
2647326495 const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size);
2647426496 const elem_bit_off = elem_off % elem_abi_bits;
2647526497 const elem_mcv = try self.resolveInst(elem);
@@ -26651,9 +26673,9 @@ fn airUnionInit(self: *CodeGen, inst: Air.Inst.Index) !void {
2665126673
2665226674 const dst_mcv = try self.allocRegOrMem(inst, false);
2665326675
26654- const union_obj = zcu.typeToUnion(union_ty).?;
26655- const field_name = union_obj .loadTagType(ip).names.get(ip)[extra.field_index];
26656- const tag_ty: Type = .fromInterned(union_obj .enum_tag_ty);
26676+ const loaded_union = zcu.typeToUnion(union_ty).?;
26677+ const field_name = loaded_union .loadTagType(ip).names.get(ip)[extra.field_index];
26678+ const tag_ty: Type = .fromInterned(loaded_union .enum_tag_ty);
2665726679 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
2665826680 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
2665926681 const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
@@ -28393,17 +28415,43 @@ const Temp = struct {
2839328415 }
2839428416
2839528417 fn read(src: *Temp, disp: i32, val_ty: Type, cg: *CodeGen) !Temp {
28396- const val = try cg.tempAlloc(val_ty);
28418+ var val = try cg.tempAlloc(val_ty);
2839728419 while (try src.toBase(cg)) {}
28398- const val_mcv = val.tracking(cg).short;
28399- switch (val_mcv) {
28400- else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
28401- .register => |val_reg| try src.readReg(disp, val_ty, registerAlias(
28402- val_reg,
28403- @intCast(val_ty.abiSize(cg.pt.zcu)),
28404- ), cg),
28420+ val_to_gpr: while (true) : (while (try val.toRegClass(false, .general_purpose, cg)) {}) {
28421+ const val_mcv = val.tracking(cg).short;
28422+ switch (val_mcv) {
28423+ else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
28424+ .register => |val_reg| try src.readReg(disp, val_ty, registerAlias(
28425+ val_reg,
28426+ @intCast(val_ty.abiSize(cg.pt.zcu)),
28427+ ), cg),
28428+ inline .register_pair, .register_triple, .register_quadruple => |val_regs| {
28429+ var part_disp = disp;
28430+ for (val_regs) |val_reg| {
28431+ try src.readReg(disp, val_ty, val_reg, cg);
28432+ part_disp += @divExact(val_reg.bitSize(), 8);
28433+ }
28434+ },
28435+ .register_offset => |val_reg_off| switch (val_reg_off.off) {
28436+ 0 => try src.readReg(disp, val_ty, registerAlias(
28437+ val_reg_off.reg,
28438+ @intCast(val_ty.abiSize(cg.pt.zcu)),
28439+ ), cg),
28440+ else => continue :val_to_gpr,
28441+ },
28442+ .lea_frame, .lea_symbol => continue :val_to_gpr,
28443+ .memory, .indirect, .load_frame, .load_symbol => {
28444+ var val_ptr = try cg.tempInit(.usize, val_mcv.address());
28445+ var src_ptr = try cg.tempInit(.usize, src.tracking(cg).short.address().offset(disp));
28446+ var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });
28447+ try val_ptr.memcpy(&src_ptr, &len, cg);
28448+ try val_ptr.die(cg);
28449+ try src_ptr.die(cg);
28450+ try len.die(cg);
28451+ },
28452+ }
28453+ return val;
2840528454 }
28406- return val;
2840728455 }
2840828456
2840928457 fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void {
@@ -28466,7 +28514,7 @@ const Temp = struct {
2846628514 try len.die(cg);
2846728515 },
2846828516 }
28469- break ;
28517+ return ;
2847028518 }
2847128519 }
2847228520
0 commit comments