@@ -95074,7 +95074,7 @@ fn moveStrategy(cg: *CodeGen, ty: Type, class: Register.Class, aligned: bool) !M
95074
95074
.mmx => {},
95075
95075
.sse => switch (ty.zigTypeTag(zcu)) {
95076
95076
else => {
95077
- const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, cg.target.* , .other), .none);
95077
+ const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, cg.target, .other), .none);
95078
95078
assert(std.mem.indexOfNone(abi.Class, classes, &.{
95079
95079
.integer, .sse, .sseup, .memory, .float, .float_combine,
95080
95080
}) == null);
@@ -99706,7 +99706,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void {
99706
99706
const overflow_arg_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 8 } };
99707
99707
const reg_save_area: MCValue = .{ .indirect = .{ .reg = ptr_arg_list_reg, .off = 16 } };
99708
99708
99709
- const classes = std.mem.sliceTo(&abi.classifySystemV(promote_ty, zcu, self.target.* , .arg), .none);
99709
+ const classes = std.mem.sliceTo(&abi.classifySystemV(promote_ty, zcu, self.target, .arg), .none);
99710
99710
switch (classes[0]) {
99711
99711
.integer => {
99712
99712
assert(classes.len == 1);
@@ -100051,7 +100051,7 @@ fn resolveCallingConventionValues(
100051
100051
var ret_tracking_i: usize = 0;
100052
100052
100053
100053
const classes = switch (cc) {
100054
- .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, self.target.* , .ret), .none),
100054
+ .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, self.target, .ret), .none),
100055
100055
.x86_64_win => &.{abi.classifyWindows(ret_ty, zcu)},
100056
100056
else => unreachable,
100057
100057
};
@@ -100140,7 +100140,7 @@ fn resolveCallingConventionValues(
100140
100140
var arg_mcv_i: usize = 0;
100141
100141
100142
100142
const classes = switch (cc) {
100143
- .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.* , .arg), .none),
100143
+ .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target, .arg), .none),
100144
100144
.x86_64_win => &.{abi.classifyWindows(ty, zcu)},
100145
100145
else => unreachable,
100146
100146
};
@@ -100444,7 +100444,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty
100444
100444
error.DivisionByZero => unreachable,
100445
100445
error.UnexpectedRemainder => {},
100446
100446
};
100447
- const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.* , .other), .none);
100447
+ const classes = std.mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target, .other), .none);
100448
100448
if (classes.len == parts_len) for (&parts, classes, 0..) |*part, class, part_i| {
100449
100449
part.* = switch (class) {
100450
100450
.integer => if (part_i < parts_len - 1)
@@ -101443,19 +101443,19 @@ const Temp = struct {
101443
101443
.disp = opts.disp,
101444
101444
}),
101445
101445
),
101446
- .register => |val_reg| try dst.writeRegs (opts.disp, val_ty, &.{ registerAlias(
101446
+ .register => |val_reg| try dst.writeReg (opts.disp, val_ty, registerAlias(
101447
101447
val_reg,
101448
101448
@intCast(val_ty.abiSize(cg.pt.zcu)),
101449
- )} , cg),
101449
+ ), cg),
101450
101450
inline .register_pair,
101451
101451
.register_triple,
101452
101452
.register_quadruple,
101453
101453
=> |val_regs| try dst.writeRegs(opts.disp, val_ty, &val_regs, cg),
101454
101454
.register_offset => |val_reg_off| switch (val_reg_off.off) {
101455
- 0 => try dst.writeRegs (opts.disp, val_ty, &.{ registerAlias(
101455
+ 0 => try dst.writeReg (opts.disp, val_ty, registerAlias(
101456
101456
val_reg_off.reg,
101457
101457
@intCast(val_ty.abiSize(cg.pt.zcu)),
101458
- )} , cg),
101458
+ ), cg),
101459
101459
else => continue :val_to_gpr,
101460
101460
},
101461
101461
.register_overflow => |val_reg_ov| {
@@ -101473,7 +101473,7 @@ const Temp = struct {
101473
101473
else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }),
101474
101474
});
101475
101475
const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu));
101476
- try dst.writeRegs (opts.disp, first_ty, &.{ registerAlias(val_reg_ov.reg, first_size)} , cg);
101476
+ try dst.writeReg (opts.disp, first_ty, registerAlias(val_reg_ov.reg, first_size), cg);
101477
101477
try cg.asmSetccMemory(
101478
101478
val_reg_ov.eflags,
101479
101479
try dst.tracking(cg).short.mem(cg, .{
@@ -101564,17 +101564,79 @@ const Temp = struct {
101564
101564
}));
101565
101565
}
101566
101566
101567
+ fn writeReg(dst: Temp, disp: i32, src_ty: Type, src_reg: Register, cg: *CodeGen) InnerError!void {
101568
+ const src_abi_size: u31 = @intCast(src_ty.abiSize(cg.pt.zcu));
101569
+ const src_rc = src_reg.class();
101570
+ if (src_rc == .x87 or std.math.isPowerOfTwo(src_abi_size)) {
101571
+ const strat = try cg.moveStrategy(src_ty, src_rc, false);
101572
+ try strat.write(cg, try dst.tracking(cg).short.mem(cg, .{
101573
+ .size = .fromBitSize(@min(8 * src_abi_size, src_reg.bitSize())),
101574
+ .disp = disp,
101575
+ }), registerAlias(src_reg, src_abi_size));
101576
+ } else {
101577
+ const frame_size = std.math.ceilPowerOfTwoAssert(u32, src_abi_size);
101578
+ const frame_index = try cg.allocFrameIndex(.init(.{
101579
+ .size = frame_size,
101580
+ .alignment = .fromNonzeroByteUnits(frame_size),
101581
+ }));
101582
+ const strat = try cg.moveStrategy(src_ty, src_rc, true);
101583
+ try strat.write(cg, .{
101584
+ .base = .{ .frame = frame_index },
101585
+ .mod = .{ .rm = .{ .size = .fromSize(frame_size) } },
101586
+ }, registerAlias(src_reg, frame_size));
101587
+ var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address());
101588
+ try dst_ptr.toOffset(disp, cg);
101589
+ var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } });
101590
+ var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size });
101591
+ try dst_ptr.memcpy(&src_ptr, &len, cg);
101592
+ try dst_ptr.die(cg);
101593
+ try src_ptr.die(cg);
101594
+ try len.die(cg);
101595
+ }
101596
+ }
101597
+
101567
101598
fn writeRegs(dst: Temp, disp: i32, src_ty: Type, src_regs: []const Register, cg: *CodeGen) InnerError!void {
101599
+ const zcu = cg.pt.zcu;
101600
+ const classes = std.mem.sliceTo(&abi.classifySystemV(src_ty, zcu, cg.target, .other), .none);
101601
+ var next_class_index: u4 = 0;
101568
101602
var part_disp = disp;
101569
- var src_abi_size: u32 = @intCast( src_ty.abiSize(cg.pt. zcu) );
101603
+ var remaining_abi_size = src_ty.abiSize(zcu);
101570
101604
for (src_regs) |src_reg| {
101571
- const src_rc = src_reg.class();
101572
- const part_bit_size = @min(8 * src_abi_size, src_reg.bitSize());
101573
- const part_size = @divExact(part_bit_size, 8);
101574
- if (src_rc == .x87 or std.math.isPowerOfTwo(part_size)) {
101575
- const strat = try cg.moveStrategy(src_ty, src_rc, false);
101605
+ const class_index = next_class_index;
101606
+ const class = classes[class_index];
101607
+ next_class_index = @intCast(switch (class) {
101608
+ .integer, .memory, .float, .float_combine => class_index + 1,
101609
+ .sse => std.mem.indexOfNonePos(abi.Class, classes, class_index + 1, &.{.sseup}) orelse classes.len,
101610
+ .x87 => std.mem.indexOfNonePos(abi.Class, classes, class_index + 1, &.{.x87up}) orelse classes.len,
101611
+ .sseup, .x87up, .complex_x87, .none, .win_i128, .integer_per_element => unreachable,
101612
+ });
101613
+ const part_size = switch (class) {
101614
+ .integer, .sse, .memory => @min(8 * @as(u7, next_class_index - class_index), remaining_abi_size),
101615
+ .x87 => 16,
101616
+ .float => 4,
101617
+ .float_combine => 8,
101618
+ .sseup, .x87up, .complex_x87, .none, .win_i128, .integer_per_element => unreachable,
101619
+ };
101620
+ const part_ty: Type = switch (class) {
101621
+ .integer => .u64,
101622
+ .sse => switch (part_size) {
101623
+ else => unreachable,
101624
+ 8 => .f64,
101625
+ 16 => .vector_2_f64,
101626
+ 32 => .vector_4_f64,
101627
+ },
101628
+ .x87 => .f80,
101629
+ .float => .f32,
101630
+ .float_combine => .vector_2_f32,
101631
+ .sseup, .x87up, .complex_x87, .memory, .none, .win_i128, .integer_per_element => unreachable,
101632
+ };
101633
+ if (class == .x87 or std.math.isPowerOfTwo(part_size)) {
101634
+ const strat = try cg.moveStrategy(part_ty, src_reg.class(), false);
101576
101635
try strat.write(cg, try dst.tracking(cg).short.mem(cg, .{
101577
- .size = .fromBitSize(part_bit_size),
101636
+ .size = switch (class) {
101637
+ else => .fromSize(part_size),
101638
+ .x87 => .tbyte,
101639
+ },
101578
101640
.disp = part_disp,
101579
101641
}), registerAlias(src_reg, part_size));
101580
101642
} else {
@@ -101583,23 +101645,24 @@ const Temp = struct {
101583
101645
.size = frame_size,
101584
101646
.alignment = .fromNonzeroByteUnits(frame_size),
101585
101647
}));
101586
- const strat = try cg.moveStrategy(src_ty, src_rc , true);
101648
+ const strat = try cg.moveStrategy(part_ty, src_reg.class() , true);
101587
101649
try strat.write(cg, .{
101588
101650
.base = .{ .frame = frame_index },
101589
101651
.mod = .{ .rm = .{ .size = .fromSize(frame_size) } },
101590
101652
}, registerAlias(src_reg, frame_size));
101591
101653
var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address());
101592
101654
try dst_ptr.toOffset(part_disp, cg);
101593
101655
var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } });
101594
- var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size });
101656
+ var len = try cg.tempInit(.usize, .{ .immediate = part_size });
101595
101657
try dst_ptr.memcpy(&src_ptr, &len, cg);
101596
101658
try dst_ptr.die(cg);
101597
101659
try src_ptr.die(cg);
101598
101660
try len.die(cg);
101599
101661
}
101600
101662
part_disp += part_size;
101601
- src_abi_size -= part_size;
101663
+ remaining_abi_size -= part_size;
101602
101664
}
101665
+ assert(next_class_index == classes.len);
101603
101666
}
101604
101667
101605
101668
fn memcpy(dst: *Temp, src: *Temp, len: *Temp, cg: *CodeGen) InnerError!void {
0 commit comments