| ... | @@ -2457,7 +2457,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2457,7 +2457,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2457 | .load => try cg.airLoad(inst), | 2457 | .load => try cg.airLoad(inst), |
| 2458 | .store => try cg.airStore(inst, false), | 2458 | .store => try cg.airStore(inst, false), |
| 2459 | .store_safe => try cg.airStore(inst, true), | 2459 | .store_safe => try cg.airStore(inst, true), |
| 2460 | .struct_field_val => try cg.airStructFieldVal(inst), | | |
| 2461 | .float_from_int => try cg.airFloatFromInt(inst), | 2460 | .float_from_int => try cg.airFloatFromInt(inst), |
| 2462 | .int_from_float => try cg.airIntFromFloat(inst), | 2461 | .int_from_float => try cg.airIntFromFloat(inst), |
| 2463 | .cmpxchg_strong => try cg.airCmpxchg(inst), | 2462 | .cmpxchg_strong => try cg.airCmpxchg(inst), |
| ... | @@ -9723,11 +9722,32 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9723,11 +9722,32 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9723 | ), cg); | 9722 | ), cg); |
| 9724 | try ops[0].moveTo(inst, cg); | 9723 | try ops[0].moveTo(inst, cg); |
| 9725 | }, | 9724 | }, |
| | 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 | }, |
| 9726 | .set_union_tag => if (use_old) try cg.airSetUnionTag(inst) else { | 9745 | .set_union_tag => if (use_old) try cg.airSetUnionTag(inst) else { |
| 9727 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; | 9746 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 9728 | const union_ty = cg.typeOf(bin_op.lhs).childType(zcu); | 9747 | const union_ty = cg.typeOf(bin_op.lhs).childType(zcu); |
| 9729 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 9748 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 9730 | const union_layout = union_ty.unionGetLayout(zcu); | 9749 | const union_layout = union_ty.unionGetLayout(zcu); |
| | 9750 | // hack around Sema OPV bugs |
| 9731 | if (union_layout.tag_size > 0) try ops[0].store(@intCast(union_layout.tagOffset()), &ops[1], cg); | 9751 | if (union_layout.tag_size > 0) try ops[0].store(@intCast(union_layout.tagOffset()), &ops[1], cg); |
| 9732 | for (ops) |op| try op.die(cg); | 9752 | for (ops) |op| try op.die(cg); |
| 9733 | }, | 9753 | }, |
| ... | @@ -9857,6 +9877,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9857,6 +9877,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9857 | } }, | 9877 | } }, |
| 9858 | } }) catch |err| switch (err) { | 9878 | } }) catch |err| switch (err) { |
| 9859 | error.SelectFailed => switch (res_ty.abiSize(zcu)) { | 9879 | error.SelectFailed => switch (res_ty.abiSize(zcu)) { |
| | 9880 | // hack around Sema OPV bugs |
| 9860 | 0 => res[0] = try cg.tempInit(res_ty, .none), | 9881 | 0 => res[0] = try cg.tempInit(res_ty, .none), |
| 9861 | else => |elem_size| { | 9882 | else => |elem_size| { |
| 9862 | while (true) for (&ops) |*op| { | 9883 | while (true) for (&ops) |*op| { |
| ... | @@ -9917,6 +9938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -9917,6 +9938,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9917 | const dst_ty = ty_pl.ty.toType(); | 9938 | const dst_ty = ty_pl.ty.toType(); |
| 9918 | if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: { | 9939 | if (dst_ty.ptrInfo(zcu).flags.vector_index == .none) zero_offset: { |
| 9919 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); | 9940 | const elem_size = dst_ty.childType(zcu).abiSize(zcu); |
| | 9941 | // hack around Sema OPV bugs |
| 9920 | if (elem_size == 0) break :zero_offset; | 9942 | if (elem_size == 0) break :zero_offset; |
| 9921 | while (true) for (&ops) |*op| { | 9943 | while (true) for (&ops) |*op| { |
| 9922 | if (try op.toRegClass(true, .general_purpose, cg)) break; | 9944 | 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 | ... | @@ -15804,7 +15826,7 @@ fn fieldOffset(self: *CodeGen, ptr_agg_ty: Type, ptr_field_ty: Type, field_index |
| 15804 | return switch (agg_ty.containerLayout(zcu)) { | 15826 | return switch (agg_ty.containerLayout(zcu)) { |
| 15805 | .auto, .@"extern" => @intCast(agg_ty.structFieldOffset(field_index, zcu)), | 15827 | .auto, .@"extern" => @intCast(agg_ty.structFieldOffset(field_index, zcu)), |
| 15806 | .@"packed" => @divExact(@as(i32, ptr_agg_ty.ptrInfo(zcu).packed_offset.bit_offset) + | 15828 | .@"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) - |
| 15808 | ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8), | 15830 | ptr_field_ty.ptrInfo(zcu).packed_offset.bit_offset, 8), |
| 15809 | }; | 15831 | }; |
| 15810 | } | 15832 | } |
| ... | @@ -15828,8 +15850,8 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -15828,8 +15850,8 @@ fn airStructFieldVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15828 | const src_mcv = try self.resolveInst(operand); | 15850 | const src_mcv = try self.resolveInst(operand); |
| 15829 | const field_off: u32 = switch (container_ty.containerLayout(zcu)) { | 15851 | const field_off: u32 = switch (container_ty.containerLayout(zcu)) { |
| 15830 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8), | 15852 | .auto, .@"extern" => @intCast(container_ty.structFieldOffset(extra.field_index, zcu) * 8), |
| 15831 | .@"packed" => if (zcu.typeToStruct(container_ty)) |struct_obj| | 15853 | .@"packed" => if (zcu.typeToStruct(container_ty)) |loaded_struct| |
| 15832 | pt.structPackedFieldBitOffset(struct_obj, extra.field_index) | 15854 | pt.structPackedFieldBitOffset(loaded_struct, extra.field_index) |
| 15833 | else | 15855 | else |
| 15834 | 0, | 15856 | 0, |
| 15835 | }; | 15857 | }; |
| ... | @@ -26448,7 +26470,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -26448,7 +26470,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 26448 | .@"struct" => { | 26470 | .@"struct" => { |
| 26449 | const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu)); | 26471 | const frame_index = try self.allocFrameIndex(.initSpill(result_ty, zcu)); |
| 26450 | if (result_ty.containerLayout(zcu) == .@"packed") { | 26472 | 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()); |
| 26452 | try self.genInlineMemset( | 26474 | try self.genInlineMemset( |
| 26453 | .{ .lea_frame = .{ .index = frame_index } }, | 26475 | .{ .lea_frame = .{ .index = frame_index } }, |
| 26454 | .{ .immediate = 0 }, | 26476 | .{ .immediate = 0 }, |
| ... | @@ -26469,7 +26491,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -26469,7 +26491,7 @@ fn airAggregateInit(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 26469 | } | 26491 | } |
| 26470 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); | 26492 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(zcu)); |
| 26471 | const elem_abi_bits = elem_abi_size * 8; | 26493 | 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); |
| 26473 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); | 26495 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| 26474 | const elem_bit_off = elem_off % elem_abi_bits; | 26496 | const elem_bit_off = elem_off % elem_abi_bits; |
| 26475 | const elem_mcv = try self.resolveInst(elem); | 26497 | const elem_mcv = try self.resolveInst(elem); |
| ... | @@ -26651,9 +26673,9 @@ fn airUnionInit(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -26651,9 +26673,9 @@ fn airUnionInit(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 26651 | | 26673 | |
| 26652 | const dst_mcv = try self.allocRegOrMem(inst, false); | 26674 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 26653 | | 26675 | |
| 26654 | const union_obj = zcu.typeToUnion(union_ty).?; | 26676 | const loaded_union = zcu.typeToUnion(union_ty).?; |
| 26655 | const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 26677 | const field_name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 26656 | const tag_ty: Type = .fromInterned(union_obj.enum_tag_ty); | 26678 | const tag_ty: Type = .fromInterned(loaded_union.enum_tag_ty); |
| 26657 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; | 26679 | const field_index = tag_ty.enumFieldIndex(field_name, zcu).?; |
| 26658 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); | 26680 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); |
| 26659 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); | 26681 | const tag_int_val = try tag_val.intFromEnum(tag_ty, pt); |
| ... | @@ -28393,17 +28415,43 @@ const Temp = struct { | ... | @@ -28393,17 +28415,43 @@ const Temp = struct { |
| 28393 | } | 28415 | } |
| 28394 | | 28416 | |
| 28395 | fn read(src: *Temp, disp: i32, val_ty: Type, cg: *CodeGen) !Temp { | 28417 | 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); |
| 28397 | while (try src.toBase(cg)) {} | 28419 | while (try src.toBase(cg)) {} |
| 28398 | const val_mcv = val.tracking(cg).short; | 28420 | val_to_gpr: while (true) : (while (try val.toRegClass(false, .general_purpose, cg)) {}) { |
| 28399 | switch (val_mcv) { | 28421 | const val_mcv = val.tracking(cg).short; |
| 28400 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 28422 | switch (val_mcv) { |
| 28401 | .register => |val_reg| try src.readReg(disp, val_ty, registerAlias( | 28423 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 28402 | val_reg, | 28424 | .register => |val_reg| try src.readReg(disp, val_ty, registerAlias( |
| 28403 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 28425 | val_reg, |
| 28404 | ), cg), | 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; |
| 28405 | } | 28454 | } |
| 28406 | return val; | | |
| 28407 | } | 28455 | } |
| 28408 | | 28456 | |
| 28409 | fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { | 28457 | fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { |
| ... | @@ -28466,7 +28514,7 @@ const Temp = struct { | ... | @@ -28466,7 +28514,7 @@ const Temp = struct { |
| 28466 | try len.die(cg); | 28514 | try len.die(cg); |
| 28467 | }, | 28515 | }, |
| 28468 | } | 28516 | } |
| 28469 | break; | 28517 | return; |
| 28470 | } | 28518 | } |
| 28471 | } | 28519 | } |
| 28472 | | 28520 | |