authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-03 07:12:01-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-16 20:47:30-05:00
log870443f7fabefa753a1653a275172a4a04fe8c34
treec16170384d482ad6910e11e161e497d2fd88377a
parent094ac8c3dc7945c8452931aed28d6e0b3e26769b

x86_64: implement passing undefined as a call arg with the new cc


1 files changed, 34 insertions(+), 33 deletions(-)

src/arch/x86_64/CodeGen.zig+34-33
......@@ -4004,10 +4004,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
40044004 } });
40054005 try slot.moveTo(inst, cg);
40064006 },
4007 .call => try cg.airCall(inst, .auto),
4008 .call_always_tail => try cg.airCall(inst, .always_tail),
4009 .call_never_tail => try cg.airCall(inst, .never_tail),
4010 .call_never_inline => try cg.airCall(inst, .never_inline),
4007 .call => try cg.airCall(inst, .auto, .{ .safety = true }),
4008 .call_always_tail => try cg.airCall(inst, .always_tail, .{ .safety = true }),
4009 .call_never_tail => try cg.airCall(inst, .never_tail, .{ .safety = true }),
4010 .call_never_inline => try cg.airCall(inst, .never_inline, .{ .safety = true }),
40114011
40124012 .clz => |air_tag| if (use_old) try cg.airClz(inst) else {
40134013 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
......@@ -10136,7 +10136,7 @@ fn airFptrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
1013610136 floatCompilerRtAbiName(src_bits),
1013710137 floatCompilerRtAbiName(dst_bits),
1013810138 }) catch unreachable,
10139 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }});
10139 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
1014010140 }
1014110141
1014210142 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -10240,7 +10240,7 @@ fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void {
1024010240 floatCompilerRtAbiName(src_bits),
1024110241 floatCompilerRtAbiName(dst_bits),
1024210242 }) catch unreachable,
10243 } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }});
10243 } }, &.{src_scalar_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
1024410244 }
1024510245
1024610246 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
......@@ -10969,6 +10969,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
1096910969 } },
1097010970 &.{ src_ty, src_ty },
1097110971 &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } },
10972 .{},
1097210973 );
1097310974 break :result if (signed) switch (tag) {
1097410975 .div_floor => {
......@@ -10998,6 +10999,7 @@ fn airMulDivBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
1099810999 } },
1099911000 &.{ src_ty, src_ty },
1100011001 &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } },
11002 .{},
1100111003 );
1100211004 try self.asmRegisterMemory(
1100311005 .{ ._, .sub },
......@@ -11247,7 +11249,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
1124711249 .{ .air_ref = bin_op.lhs },
1124811250 .{ .air_ref = bin_op.rhs },
1124911251 overflow.address(),
11250 });
11252 }, .{});
1125111253 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_mcv.register_pair);
1125211254 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
1125311255
......@@ -11748,7 +11750,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
1174811750 .{ .air_ref = bin_op.lhs },
1174911751 .{ .air_ref = bin_op.rhs },
1175011752 overflow.address(),
11751 });
11753 }, .{});
1175211754
1175311755 const dst_mcv = try self.allocRegOrMem(inst, false);
1175411756 try self.genSetMem(
......@@ -14413,7 +14415,7 @@ fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: RoundMode)
1441314415 },
1441414416 floatLibcAbiSuffix(ty),
1441514417 }) catch unreachable,
14416 } }, &.{ty}, &.{src_mcv});
14418 } }, &.{ty}, &.{src_mcv}, .{});
1441714419}
1441814420
1441914421fn genRound(self: *CodeGen, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void {
......@@ -14684,7 +14686,7 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {
1468414686 floatLibcAbiPrefix(ty),
1468514687 floatLibcAbiSuffix(ty),
1468614688 }) catch unreachable,
14687 } }, &.{ty}, &.{.{ .air_ref = un_op }});
14689 } }, &.{ty}, &.{.{ .air_ref = un_op }}, .{});
1468814690 }
1468914691 },
1469014692 else => {},
......@@ -14850,7 +14852,7 @@ fn airUnaryMath(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1485014852 },
1485114853 floatLibcAbiSuffix(ty),
1485214854 }) catch unreachable,
14853 } }, &.{ty}, &.{.{ .air_ref = un_op }});
14855 } }, &.{ty}, &.{.{ .air_ref = un_op }}, .{});
1485414856 return self.finishAir(inst, result, .{ un_op, .none, .none });
1485514857}
1485614858
......@@ -16689,7 +16691,7 @@ fn genMulDivBinOp(
1668916691 lhs_mcv.address(),
1669016692 rhs_mcv.address(),
1669116693 .{ .immediate = src_info.bits },
16692 });
16694 }, .{});
1669316695 return dst_mcv;
1669416696 },
1669516697 },
......@@ -16913,7 +16915,7 @@ fn genBinOp(
1691316915 .return_type = lhs_ty.toIntern(),
1691416916 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
1691516917 .callee = callee,
16916 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } });
16918 } }, &.{ lhs_ty, rhs_ty }, &.{ .{ .air_ref = lhs_air }, .{ .air_ref = rhs_air } }, .{});
1691716919 return switch (air_tag) {
1691816920 .mod => result: {
1691916921 const adjusted: MCValue = if (type_needs_libcall) adjusted: {
......@@ -16927,7 +16929,7 @@ fn genBinOp(
1692716929 .callee = std.fmt.bufPrint(&add_callee_buf, "__add{c}f3", .{
1692816930 floatCompilerRtAbiName(float_bits),
1692916931 }) catch unreachable,
16930 } }, &.{ lhs_ty, rhs_ty }, &.{ result, .{ .air_ref = rhs_air } });
16932 } }, &.{ lhs_ty, rhs_ty }, &.{ result, .{ .air_ref = rhs_air } }, .{});
1693116933 } else switch (float_bits) {
1693216934 16, 32, 64 => adjusted: {
1693316935 const dst_reg = switch (result) {
......@@ -17026,7 +17028,7 @@ fn genBinOp(
1702617028 .return_type = lhs_ty.toIntern(),
1702717029 .param_types = &.{ lhs_ty.toIntern(), rhs_ty.toIntern() },
1702817030 .callee = callee,
17029 } }, &.{ lhs_ty, rhs_ty }, &.{ adjusted, .{ .air_ref = rhs_air } });
17031 } }, &.{ lhs_ty, rhs_ty }, &.{ adjusted, .{ .air_ref = rhs_air } }, .{});
1703017032 },
1703117033 .div_trunc, .div_floor => try self.genRoundLibcall(lhs_ty, result, .{
1703217034 .mode = switch (air_tag) {
......@@ -19305,7 +19307,7 @@ fn airFrameAddress(self: *CodeGen, inst: Air.Inst.Index) !void {
1930519307 return self.finishAir(inst, dst_mcv, .{ .none, .none, .none });
1930619308}
1930719309
19308fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
19310fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier, opts: CopyOptions) !void {
1930919311 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});
1931019312
1931119313 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
......@@ -19329,7 +19331,7 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
1932919331 defer allocator.free(arg_vals);
1933019332 for (arg_vals, arg_refs) |*arg_val, arg_ref| arg_val.* = .{ .air_ref = arg_ref };
1933119333
19332 const ret = try self.genCall(.{ .air = pl_op.operand }, arg_tys, arg_vals);
19334 const ret = try self.genCall(.{ .air = pl_op.operand }, arg_tys, arg_vals, opts);
1933319335
1933419336 var bt = self.liveness.iterateBigTomb(inst);
1933519337 try self.feed(&bt, pl_op.operand);
......@@ -19347,7 +19349,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
1934719349 lib: ?[]const u8 = null,
1934819350 callee: []const u8,
1934919351 },
19350}, arg_types: []const Type, args: []const MCValue) !MCValue {
19352}, arg_types: []const Type, args: []const MCValue, opts: CopyOptions) !MCValue {
1935119353 const pt = self.pt;
1935219354 const zcu = pt.zcu;
1935319355 const ip = &zcu.intern_pool;
......@@ -19431,12 +19433,12 @@ fn genCall(self: *CodeGen, info: union(enum) {
1943119433 },
1943219434 .indirect => |reg_off| {
1943319435 frame_index.* = try self.allocFrameIndex(.initType(arg_ty, zcu));
19434 try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, .{});
19436 try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg, opts);
1943519437 try self.register_manager.getReg(reg_off.reg, null);
1943619438 try reg_locks.append(self.register_manager.lockReg(reg_off.reg));
1943719439 },
1943819440 .load_frame => {
19439 try self.genCopy(arg_ty, dst_arg, src_arg, .{});
19441 try self.genCopy(arg_ty, dst_arg, src_arg, opts);
1944019442 try self.freeValue(src_arg);
1944119443 },
1944219444 .elementwise_regs_then_frame => |regs_frame_addr| {
......@@ -19513,22 +19515,20 @@ fn genCall(self: *CodeGen, info: union(enum) {
1951319515 switch (dst_arg) {
1951419516 .none, .load_frame => {},
1951519517 .register => |dst_reg| switch (fn_info.cc) {
19516 else => try self.genSetReg(
19517 registerAlias(dst_reg, @intCast(arg_ty.abiSize(zcu))),
19518 arg_ty,
19519 src_arg,
19520 .{},
19521 ),
19518 else => try self.genSetReg(registerAlias(
19519 dst_reg,
19520 @intCast(arg_ty.abiSize(zcu)),
19521 ), arg_ty, src_arg, opts),
1952219522 .x86_64_sysv, .x86_64_win => {
1952319523 const promoted_ty = self.promoteInt(arg_ty);
1952419524 const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(zcu));
1952519525 const dst_alias = registerAlias(dst_reg, promoted_abi_size);
19526 try self.genSetReg(dst_alias, promoted_ty, src_arg, .{});
19526 try self.genSetReg(dst_alias, promoted_ty, src_arg, opts);
1952719527 if (promoted_ty.toIntern() != arg_ty.toIntern())
1952819528 try self.truncateRegister(arg_ty, dst_alias);
1952919529 },
1953019530 },
19531 .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, .{}),
19531 .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg, opts),
1953219532 .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{
1953319533 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
1953419534 }, .{}),
......@@ -19756,7 +19756,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
1975619756 },
1975719757 floatCompilerRtAbiName(float_bits),
1975819758 }) catch unreachable,
19759 } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } });
19759 } }, &.{ ty, ty }, &.{ .{ .air_ref = bin_op.lhs }, .{ .air_ref = bin_op.rhs } }, .{});
1976019760 try self.genBinOpMir(.{ ._, .@"test" }, .i32, ret, ret);
1976119761 break :result switch (op) {
1976219762 .eq => .e,
......@@ -22305,6 +22305,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
2230522305 }, opts),
2230622306 inline .register_pair, .register_triple, .register_quadruple => |dst_regs, dst_tag| {
2230722307 const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = src_info: switch (src_mcv) {
22308 .undef, .memory, .indirect, .load_frame => null,
2230822309 .register => |src_reg| switch (dst_regs[0].class()) {
2230922310 .general_purpose => switch (src_reg.class()) {
2231022311 else => unreachable,
......@@ -22344,7 +22345,6 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
2234422345 }
2234522346 return;
2234622347 },
22347 .memory, .indirect, .load_frame => null,
2234822348 .load_symbol, .load_direct, .load_got, .load_tlv => {
2234922349 const src_addr_reg =
2235022350 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
......@@ -22375,6 +22375,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
2237522375 if (is_hazard) hazard_count += 1;
2237622376 if (is_hazard != emit_hazard) continue;
2237722377 try self.genSetReg(dst_reg, dst_ty, switch (src_mcv) {
22378 .undef => if (opts.safety and part_i > 0) .{ .register = dst_regs[0] } else .undef,
2237822379 dst_tag => |src_regs| .{ .register = src_regs[part_i] },
2237922380 .memory, .indirect, .load_frame => src_mcv.address().offset(part_disp).deref(),
2238022381 .load_symbol, .load_direct, .load_got, .load_tlv => .{ .indirect = .{
......@@ -23410,7 +23411,7 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {
2341023411 intCompilerRtAbiName(src_bits),
2341123412 floatCompilerRtAbiName(dst_bits),
2341223413 }) catch unreachable,
23413 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }});
23414 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
2341423415 }
2341523416
2341623417 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -23490,7 +23491,7 @@ fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void {
2349023491 floatCompilerRtAbiName(src_bits),
2349123492 intCompilerRtAbiName(dst_bits),
2349223493 }) catch unreachable,
23493 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }});
23494 } }, &.{src_ty}, &.{.{ .air_ref = ty_op.operand }}, .{});
2349423495 }
2349523496
2349623497 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -26230,7 +26231,7 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {
2623026231 }) catch unreachable,
2623126232 } }, &.{ ty, ty, ty }, &.{
2623226233 .{ .air_ref = extra.lhs }, .{ .air_ref = extra.rhs }, .{ .air_ref = pl_op.operand },
26233 });
26234 }, .{});
2623426235 }
2623526236
2623626237 var mcvs: [3]MCValue = undefined;