authorgravatar for xtex@astrafall.orgxtex <xtex@astrafall.org> 2026-09-30 19:51:59+08:00
committergravatar for xtex@astrafall.orgxtex <xtex@astrafall.org> 2026-10-01 08:39:15+08:00
logbfaaeab734e6cef3cd2a1186e14a19ba8481ec6e
treee666248bb6a99bb3b632b429199879cefc9c6d86
parente2d0773388ae25b3a55787968a5a652efdae07ea
signature Signed by SSH key SHA256:IEYEjkZlkUTr5U9GiDAmZU/4eZus2t2RsxusyhQqwao

loongarch: support unordered load/store atomicity


1 files changed, 84 insertions(+), 28 deletions(-)

src/codegen/loongarch/Select.zig+84-28
...@@ -983,7 +983,14 @@ pub const Value = struct {...@@ -983,7 +983,14 @@ pub const Value = struct {
983 while (part_it.next()) |part_vi| {983 while (part_it.next()) |part_vi| {
984 const part_offset, const part_size = part_vi.positionInParent(isel);984 const part_offset, const part_size = part_vi.positionInParent(isel);
985 const part_mat = try part_vi.mat(isel, .{});985 const part_mat = try part_vi.mat(isel, .{});
986 try isel.moveLoc(def_loc, part_offset, part_mat.loc(), 0, part_size, .preserved);986 try isel.moveLoc(
987 def_loc,
988 part_offset,
989 part_mat.loc(),
990 0,
991 part_size,
992 .{ .dst_prot = .preserved },
993 );
987 try part_mat.finish(isel);994 try part_mat.finish(isel);
988 if (reextend_parts)995 if (reextend_parts)
989 try part_vi.reextend(isel, def_ext);996 try part_vi.reextend(isel, def_ext);
...@@ -1003,7 +1010,7 @@ pub const Value = struct {...@@ -1003,7 +1010,7 @@ pub const Value = struct {
1003 const def_loc = def_vi.takeLocationMarkWritten(isel) orelse return;1010 const def_loc = def_vi.takeLocationMarkWritten(isel) orelse return;
1004 const def_offset, const def_size = def_vi.positionInParent(isel);1011 const def_offset, const def_size = def_vi.positionInParent(isel);
1005 const parent_mat = try parent_vi.mat(isel, .{});1012 const parent_mat = try parent_vi.mat(isel, .{});
1006 try isel.moveLoc(def_loc, 0, parent_mat.loc(), def_offset, def_size, .none);1013 try isel.moveLoc(def_loc, 0, parent_mat.loc(), def_offset, def_size, .{});
1007 try parent_mat.finish(isel);1014 try parent_mat.finish(isel);
1008 }1015 }
10091016
...@@ -1115,7 +1122,7 @@ pub const Value = struct {...@@ -1115,7 +1122,7 @@ pub const Value = struct {
1115 .{ .stack_slot = .{ .base = base_reg, .offset = 0 } },1122 .{ .stack_slot = .{ .base = base_reg, .offset = 0 } },
1116 offset,1123 offset,
1117 vi.size(isel),1124 vi.size(isel),
1118 .none,1125 .{ .atomic = opts.atomic },
1119 );1126 );
1120 return true;1127 return true;
1121 }1128 }
...@@ -1167,7 +1174,7 @@ pub const Value = struct {...@@ -1167,7 +1174,7 @@ pub const Value = struct {
1167 const src_loc = src_mat.loc();1174 const src_loc = src_mat.loc();
1168 if (!std.meta.eql(loc, src_loc)) {1175 if (!std.meta.eql(loc, src_loc)) {
1169 loc.markRegWritten(isel);1176 loc.markRegWritten(isel);
1170 try isel.moveLoc(loc, 0, src_mat.loc(), 0, copy_size, .none);1177 try isel.moveLoc(loc, 0, src_mat.loc(), 0, copy_size, .{});
1171 }1178 }
1172 try src_mat.finish(isel);1179 try src_mat.finish(isel);
1173 }1180 }
...@@ -1271,7 +1278,14 @@ pub const Value = struct {...@@ -1271,7 +1278,14 @@ pub const Value = struct {
1271 _ = try isel.fillReg(src_reg);1278 _ = try isel.fillReg(src_reg);
1272 }1279 }
1273 // TODO: replace reextending def_part_vi to .zero_ext with moveLoc .wipe when applicable1280 // TODO: replace reextending def_part_vi to .zero_ext with moveLoc .wipe when applicable
1274 try isel.moveLoc(def_part_loc, dst_offset, src_loc, src_offset, mat_size, .preserved);1281 try isel.moveLoc(
1282 def_part_loc,
1283 dst_offset,
1284 src_loc,
1285 src_offset,
1286 mat_size,
1287 .{ .dst_prot = .preserved },
1288 );
1275 }1289 }
1276 }1290 }
1277 if (maybe_def_addr_mat) |def_addr_mat| try def_addr_mat.finish(isel);1291 if (maybe_def_addr_mat) |def_addr_mat| try def_addr_mat.finish(isel);
...@@ -1279,6 +1293,8 @@ pub const Value = struct {...@@ -1279,6 +1293,8 @@ pub const Value = struct {
12791293
1280 const MemoryAccessOptions = struct {1294 const MemoryAccessOptions = struct {
1281 @"volatile": bool = false,1295 @"volatile": bool = false,
1296 // Atomicity. This is unrelated to ordering and visibility.
1297 atomic: bool = false,
1282 };1298 };
12831299
1284 const MatOptions = struct {1300 const MatOptions = struct {
...@@ -1478,7 +1494,6 @@ pub const Value = struct {...@@ -1478,7 +1494,6 @@ pub const Value = struct {
1478 opts: MemoryAccessOptions,1494 opts: MemoryAccessOptions,
1479 ) !void {1495 ) !void {
1480 wip_mir_log.debug(" | # store {f} -> [${t}, #{d}]", .{ vi, base_reg, offset });1496 wip_mir_log.debug(" | # store {f} -> [${t}, #{d}]", .{ vi, base_reg, offset });
1481 _ = opts;
14821497
1483 const hint_stack: Indirect = if (std.math.cast(@FieldType(Indirect, "offset"), offset)) |stack_off|1498 const hint_stack: Indirect = if (std.math.cast(@FieldType(Indirect, "offset"), offset)) |stack_off|
1484 .{ .base = base_reg, .offset = stack_off }1499 .{ .base = base_reg, .offset = stack_off }
...@@ -1491,7 +1506,7 @@ pub const Value = struct {...@@ -1491,7 +1506,7 @@ pub const Value = struct {
1491 value_mat.loc(),1506 value_mat.loc(),
1492 0,1507 0,
1493 vi.size(isel),1508 vi.size(isel),
1494 .none,1509 .{ .atomic = opts.atomic },
1495 );1510 );
1496 try value_mat.finish(isel);1511 try value_mat.finish(isel);
1497 }1512 }
...@@ -1543,7 +1558,7 @@ pub const Value = struct {...@@ -1543,7 +1558,7 @@ pub const Value = struct {
1543 .size = @intCast(part_size),1558 .size = @intCast(part_size),
1544 .extension = part_vi.extension(isel),1559 .extension = part_vi.extension(isel),
1545 });1560 });
1546 try isel.moveLoc(.{ .register = part_ra }, 0, value_mat.loc(), 0, part_size, .none);1561 try isel.moveLoc(.{ .register = part_ra }, 0, value_mat.loc(), 0, part_size, .{});
1547 try value_mat.finish(isel);1562 try value_mat.finish(isel);
1548 }1563 }
15491564
...@@ -1558,7 +1573,7 @@ pub const Value = struct {...@@ -1558,7 +1573,7 @@ pub const Value = struct {
1558 .size = @intCast(part_size),1573 .size = @intCast(part_size),
1559 .extension = part_vi.extension(isel),1574 .extension = part_vi.extension(isel),
1560 });1575 });
1561 try isel.moveLoc(.{ .stack_slot = layout_part_stack }, 0, value_mat.loc(), 0, part_size, .none);1576 try isel.moveLoc(.{ .stack_slot = layout_part_stack }, 0, value_mat.loc(), 0, part_size, .{});
1562 try value_mat.finish(isel);1577 try value_mat.finish(isel);
1563 }1578 }
1564 }1579 }
...@@ -1569,7 +1584,7 @@ pub const Value = struct {...@@ -1569,7 +1584,7 @@ pub const Value = struct {
1569 if (src_loc.asRegister()) |src_reg| _ = try isel.fillReg(src_reg);1584 if (src_loc.asRegister()) |src_reg| _ = try isel.fillReg(src_reg);
1570 tracking_log.debug("{f} -> {f} (move to)", .{ vi, src_loc });1585 tracking_log.debug("{f} -> {f} (move to)", .{ vi, src_loc });
1571 if (vi.takeLocationMarkWritten(isel)) |dst_loc|1586 if (vi.takeLocationMarkWritten(isel)) |dst_loc|
1572 try isel.moveLoc(dst_loc, 0, src_loc, 0, vi.size(isel), .none);1587 try isel.moveLoc(dst_loc, 0, src_loc, 0, vi.size(isel), .{});
1573 if (vi.isSmall(isel)) {1588 if (vi.isSmall(isel)) {
1574 vi.setSmallLocation(isel, src_loc);1589 vi.setSmallLocation(isel, src_loc);
1575 if (src_loc.asRegister()) |src_reg| {1590 if (src_loc.asRegister()) |src_reg| {
...@@ -2130,7 +2145,7 @@ pub const Value = struct {...@@ -2130,7 +2145,7 @@ pub const Value = struct {
2130 vi_loc,2145 vi_loc,
2131 mat.offset,2146 mat.offset,
2132 mat.size,2147 mat.size,
2133 .preserved,2148 .{ .dst_prot = .preserved },
2134 );2149 );
2135 if (maybe_loc_reg) |loc_reg| {2150 if (maybe_loc_reg) |loc_reg| {
2136 const loc_live = isel.live_registers.getPtr(loc_reg);2151 const loc_live = isel.live_registers.getPtr(loc_reg);
...@@ -2190,7 +2205,7 @@ pub const Value = struct {...@@ -2190,7 +2205,7 @@ pub const Value = struct {
2190 .{ .stack_slot = .{ .base = addr_mat.reg(), .offset = 0 } },2205 .{ .stack_slot = .{ .base = addr_mat.reg(), .offset = 0 } },
2191 offset_from_root + mat.offset,2206 offset_from_root + mat.offset,
2192 mat.size,2207 mat.size,
2193 .none,2208 .{},
2194 );2209 );
2195 try addr_mat.finish(isel);2210 try addr_mat.finish(isel);
2196 },2211 },
...@@ -3415,7 +3430,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void...@@ -3415,7 +3430,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void
3415 output_loc,3430 output_loc,
3416 0,3431 0,
3417 output_vi.value.size(isel),3432 output_vi.value.size(isel),
3418 .none,3433 .{},
3419 );3434 );
3420 }3435 }
3421 break :output_reg output_reg;3436 break :output_reg output_reg;
...@@ -3544,7 +3559,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void...@@ -3544,7 +3559,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void
3544 const dst_loc: Value.Location = .{ .register = input_ra };3559 const dst_loc: Value.Location = .{ .register = input_ra };
3545 if (!std.meta.eql(input_val_loc, dst_loc)) {3560 if (!std.meta.eql(input_val_loc, dst_loc)) {
3546 dst_loc.markRegWritten(isel);3561 dst_loc.markRegWritten(isel);
3547 try isel.moveLoc(dst_loc, 0, input_val_loc, 0, input_ra.mod.byteSize(isel.target), .none);3562 try isel.moveLoc(dst_loc, 0, input_val_loc, 0, input_ra.mod.byteSize(isel.target), .{});
3548 }3563 }
3549 try input_val_mat.finish(isel);3564 try input_val_mat.finish(isel);
3550 },3565 },
...@@ -3962,6 +3977,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void...@@ -3962,6 +3977,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void
3962 const ptr_mat = try ptr_vi.matReg(isel);3977 const ptr_mat = try ptr_vi.matReg(isel);
3963 try src_vi.matStore(isel, ptr_mat.reg(), 0, .{3978 try src_vi.matStore(isel, ptr_mat.reg(), 0, .{
3964 .@"volatile" = ptr_info.flags.is_volatile,3979 .@"volatile" = ptr_info.flags.is_volatile,
3980 .atomic = (air_tag == .atomic_store_unordered),
3965 });3981 });
3966 try ptr_mat.finish(isel);3982 try ptr_mat.finish(isel);
3967 },3983 },
...@@ -3986,6 +4002,29 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void...@@ -3986,6 +4002,29 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void
3986 try ptr_mat.finish(isel);4002 try ptr_mat.finish(isel);
3987 }4003 }
3988 },4004 },
4005 .atomic_load => {
4006 const atomic_load = air.data(air.inst_index).atomic_load;
4007 const ptr_ty = isel.air.typeOf(atomic_load.ptr, ip);
4008 const ptr_info = ptr_ty.ptrInfo(zcu);
4009 if (ptr_info.packed_offset.host_size > 0) return isel.fail("packed atomic load", .{});
4010
4011 if (ptr_info.flags.is_volatile)
4012 _ = try isel.use(air.inst_index.toRef());
4013 if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| {
4014 defer dst_vi.value.deref(isel);
4015
4016 const ptr_vi = try isel.use(atomic_load.ptr);
4017 const ptr_mat = try ptr_vi.matIntRegZeroExt(isel);
4018 _ = try dst_vi.value.defLoad(isel, ptr_mat.reg(), 0, .{
4019 .@"volatile" = ptr_info.flags.is_volatile,
4020 .atomic = true,
4021 });
4022 try ptr_mat.finish(isel);
4023
4024 if (atomic_load.order != .unordered)
4025 try isel.failUnimplemented("ordered atomic load", .{});
4026 }
4027 },
3989 .int_cast => if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| {4028 .int_cast => if (isel.live_values.fetchRemove(air.inst_index)) |dst_vi| {
3990 defer dst_vi.value.deref(isel);4029 defer dst_vi.value.deref(isel);
39914030
...@@ -6206,6 +6245,11 @@ fn elemPtr(...@@ -6206,6 +6245,11 @@ fn elemPtr(
6206 try index_mat.finish(isel);6245 try index_mat.finish(isel);
6207}6246}
62086247
6248const MoveLocOptions = struct {
6249 dst_prot: DestProtection = .none,
6250 atomic: bool = false,
6251};
6252
6209fn moveLoc(6253fn moveLoc(
6210 isel: *Select,6254 isel: *Select,
6211 dst_loc: Value.Location,6255 dst_loc: Value.Location,
...@@ -6213,22 +6257,23 @@ fn moveLoc(...@@ -6213,22 +6257,23 @@ fn moveLoc(
6213 src_loc: Value.Location,6257 src_loc: Value.Location,
6214 src_off: u64,6258 src_off: u64,
6215 size: u64,6259 size: u64,
6216 dst_prot: DestProtection,6260 opts: MoveLocOptions,
6217) !void {6261) !void {
6218 if (dst_loc.isUnallocated()) return;6262 if (dst_loc.isUnallocated()) return;
6219 if (std.meta.eql(dst_loc, src_loc) and dst_off == src_off) return;6263 if (std.meta.eql(dst_loc, src_loc) and dst_off == src_off) return;
6220 if (size == 0) return;6264 if (size == 0) return;
6221 assert(!src_loc.isUnallocated());6265 assert(!src_loc.isUnallocated());
6222 wip_mir_log.debug(" | # move {f}[{d}] <- {f}[{d}], {d}B, dst prot={t}", .{6266 wip_mir_log.debug(" | # move {f}[{d}] <- {f}[{d}], {d}B, dst prot={t}, atomic={}", .{
6223 dst_loc,6267 dst_loc,
6224 dst_off,6268 dst_off,
6225 src_loc,6269 src_loc,
6226 src_off,6270 src_off,
6227 size,6271 size,
6228 dst_prot,6272 opts.dst_prot,
6273 opts.atomic,
6229 });6274 });
62306275
6231 const dst_lock: RegLock = if (dst_prot != .preserved) .empty else dst_loc.tryLock(isel);6276 const dst_lock: RegLock = if (opts.dst_prot != .preserved) .empty else dst_loc.tryLock(isel);
6232 defer dst_lock.unlock(isel);6277 defer dst_lock.unlock(isel);
6233 const src_lock = src_loc.tryLock(isel);6278 const src_lock = src_loc.tryLock(isel);
6234 defer src_lock.unlock(isel);6279 defer src_lock.unlock(isel);
...@@ -6241,7 +6286,7 @@ fn moveLoc(...@@ -6241,7 +6286,7 @@ fn moveLoc(
6241 src_ra,6286 src_ra,
6242 @intCast(src_off * 8),6287 @intCast(src_off * 8),
6243 @intCast(size * 8),6288 @intCast(size * 8),
6244 dst_prot,6289 opts.dst_prot,
6245 ),6290 ),
6246 .stack_slot => |src_stack| {6291 .stack_slot => |src_stack| {
6247 const tmp_reg = if (dst_ra.mod == .integer and dst_off == 0)6292 const tmp_reg = if (dst_ra.mod == .integer and dst_off == 0)
...@@ -6255,7 +6300,7 @@ fn moveLoc(...@@ -6255,7 +6300,7 @@ fn moveLoc(
6255 .{ .reg = tmp_reg, .mod = .integer },6300 .{ .reg = tmp_reg, .mod = .integer },
6256 0,6301 0,
6257 @intCast(size * 8),6302 @intCast(size * 8),
6258 dst_prot,6303 opts.dst_prot,
6259 );6304 );
6260 try isel.loadReg(6305 try isel.loadReg(
6261 tmp_reg,6306 tmp_reg,
...@@ -6267,6 +6312,8 @@ fn moveLoc(...@@ -6267,6 +6312,8 @@ fn moveLoc(
6267 },6312 },
6268 },6313 },
6269 .stack_slot => |dst_stack| {6314 .stack_slot => |dst_stack| {
6315 if (size > isel.gprSize() and opts.atomic)
6316 return isel.fail("Memory store of {d} bytes cannot be atomic", .{size});
6270 if (size > isel.gprSize()) {6317 if (size > isel.gprSize()) {
6271 // large memory copies, src must be stack_slot6318 // large memory copies, src must be stack_slot
6272 const src_stack = src_loc.stack_slot;6319 const src_stack = src_loc.stack_slot;
...@@ -6294,7 +6341,7 @@ fn moveLoc(...@@ -6294,7 +6341,7 @@ fn moveLoc(
6294 if (gen_low_to_high) {6341 if (gen_low_to_high) {
6295 var off: u64 = 0;6342 var off: u64 = 0;
6296 for (0..@intCast(steps)) |_| {6343 for (0..@intCast(steps)) |_| {
6297 try isel.moveLoc(dst_loc, dst_off + off, src_loc, src_off + off, gpr_size, dst_prot);6344 try isel.moveLoc(dst_loc, dst_off + off, src_loc, src_off + off, gpr_size, opts);
6298 off += gpr_size;6345 off += gpr_size;
6299 }6346 }
6300 }6347 }
...@@ -6302,7 +6349,7 @@ fn moveLoc(...@@ -6302,7 +6349,7 @@ fn moveLoc(
6302 var off: u64 = steps * gpr_size;6349 var off: u64 = steps * gpr_size;
6303 for (0..@intCast(steps)) |_| {6350 for (0..@intCast(steps)) |_| {
6304 off -= gpr_size;6351 off -= gpr_size;
6305 try isel.moveLoc(dst_loc, dst_off + off, src_loc, src_off + off, gpr_size, dst_prot);6352 try isel.moveLoc(dst_loc, dst_off + off, src_loc, src_off + off, gpr_size, opts);
6306 }6353 }
6307 }6354 }
63086355
...@@ -6313,7 +6360,9 @@ fn moveLoc(...@@ -6313,7 +6360,9 @@ fn moveLoc(
6313 // If size is not direct mem op size and !kill_dst, old values have to6360 // If size is not direct mem op size and !kill_dst, old values have to
6314 // be loaded first.6361 // be loaded first.
6315 const memop_size = memOpSizeFitting(size);6362 const memop_size = memOpSizeFitting(size);
6316 const need_load = memop_size != size;6363 const need_load = memop_size != size and opts.dst_prot != .none;
6364 if (opts.atomic and need_load)
6365 return isel.fail("Memory store of {d} bytes cannot be atomic without killing other bytes", .{size});
6317 const tmp_reg, const tmp_allocated = tmp_reg: {6366 const tmp_reg, const tmp_allocated = tmp_reg: {
6318 if (src_off == 0 and !need_load) {6367 if (src_off == 0 and !need_load) {
6319 switch (src_loc) {6368 switch (src_loc) {
...@@ -6335,7 +6384,7 @@ fn moveLoc(...@@ -6335,7 +6384,7 @@ fn moveLoc(
6335 src_loc,6384 src_loc,
6336 src_off,6385 src_off,
6337 size,6386 size,
6338 if (need_load) .preserved else .none,6387 opts,
6339 );6388 );
6340 if (need_load)6389 if (need_load)
6341 try isel.loadReg(tmp_reg, memop_size, .unsigned, dst_stack.base, dst_stack_off);6390 try isel.loadReg(tmp_reg, memop_size, .unsigned, dst_stack.base, dst_stack_off);
...@@ -6463,7 +6512,7 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini...@@ -6463,7 +6512,7 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini
6463 const rd = dst_ra.reg;6512 const rd = dst_ra.reg;
6464 defer if (use_tmp_reg) isel.freeReg(rd);6513 defer if (use_tmp_reg) isel.freeReg(rd);
64656514
6466 if (use_tmp_reg) try isel.moveLoc(dst, 0, .{ .register = dst_ra }, 0, isel.gprSize(), .none);6515 if (use_tmp_reg) try isel.moveLoc(dst, 0, .{ .register = dst_ra }, 0, isel.gprSize(), .{});
6467 return switch (ptr.base_addr) {6516 return switch (ptr.base_addr) {
6468 .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) {6517 .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) {
6469 // TODO code model6518 // TODO code model
...@@ -6724,7 +6773,14 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini...@@ -6724,7 +6773,14 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini
6724 ),6773 ),
6725 };6774 };
67266775
6727 try isel.moveLoc(dst, part_offset, .{ .register = tmp_ra }, 0, part_size, .preserved);6776 try isel.moveLoc(
6777 dst,
6778 part_offset,
6779 .{ .register = tmp_ra },
6780 0,
6781 part_size,
6782 .{ .dst_prot = .preserved },
6783 );
6728 try isel.moveIntImm(tmp_reg, @bitCast(part_value));6784 try isel.moveIntImm(tmp_reg, @bitCast(part_value));
67296785
6730 if (part_offset == 0) break else part_offset -= gpr_size;6786 if (part_offset == 0) break else part_offset -= gpr_size;
...@@ -6755,7 +6811,7 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini...@@ -6755,7 +6811,7 @@ fn moveConstant(isel: *Select, dst: Value.Location, init_constant: Constant, ini
6755 .{ .stack_slot = .{ .base = tmp_reg, .offset = 0 } },6811 .{ .stack_slot = .{ .base = tmp_reg, .offset = 0 } },
6756 offset,6812 offset,
6757 size,6813 size,
6758 .none,6814 .{},
6759 );6815 );
67606816
6761 // load constant pointer6817 // load constant pointer
...@@ -7237,7 +7293,7 @@ const call = struct {...@@ -7237,7 +7293,7 @@ const call = struct {
7237 .{ .register = .{ .mod = .integer, .reg = tmp_reg } },7293 .{ .register = .{ .mod = .integer, .reg = tmp_reg } },
7238 0,7294 0,
7239 isel.gprSize(),7295 isel.gprSize(),
7240 .preserved,7296 .{ .dst_prot = .preserved },
7241 );7297 );
7242 } else unreachable;7298 } else unreachable;
7243 }7299 }