authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-26 18:41:29-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-07-26 18:41:29-07:00
logde39c5f67ffec18b9a5aa51e84dbf5f04ce013bc
tree8f34a4d8425c6acf69de936e3100ab77e9528bbb
parenta51cdf3b24c25959ee55a38428dc0da42a8be81c
parent3194a4d22b755393296a4db4c85d7b54ea83e96d
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24587 from jacobly0/x86_64

x86_64: fix some bugs

2 files changed, 40 insertions(+), 21 deletions(-)

src/arch/x86_64/CodeGen.zig+30-21
......@@ -1103,11 +1103,7 @@ const FormatAirData = struct {
11031103 inst: Air.Inst.Index,
11041104};
11051105fn formatAir(data: FormatAirData, w: *std.io.Writer) Writer.Error!void {
1106 // not acceptable implementation because it ignores `w`:
1107 //data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness);
1108 _ = data;
1109 _ = w;
1110 @panic("TODO: unimplemented");
1106 data.self.air.writeInst(w, data.inst, data.self.pt, data.self.liveness);
11111107}
11121108fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(FormatAirData, formatAir) {
11131109 return .{ .data = .{ .self = self, .inst = inst } };
......@@ -179300,10 +179296,13 @@ fn lowerSwitchBr(
179300179296 } else undefined;
179301179297 const table_start: u31 = @intCast(cg.mir_table.items.len);
179302179298 {
179303 const condition_index_reg = if (condition_index.isRegister())
179304 condition_index.getReg().?
179305 else
179306 try cg.copyToTmpRegister(.usize, condition_index);
179299 const condition_index_reg = condition_index_reg: {
179300 if (condition_index.isRegister()) {
179301 const condition_index_reg = condition_index.getReg().?;
179302 if (condition_index_reg.isClass(.general_purpose)) break :condition_index_reg condition_index_reg;
179303 }
179304 break :condition_index_reg try cg.copyToTmpRegister(.usize, condition_index);
179305 };
179307179306 const condition_index_lock = cg.register_manager.lockReg(condition_index_reg);
179308179307 defer if (condition_index_lock) |lock| cg.register_manager.unlockReg(lock);
179309179308 try cg.truncateRegister(condition_ty, condition_index_reg);
......@@ -191921,18 +191920,15 @@ const Select = struct {
191921191920 error.InvalidInstruction => {
191922191921 const fixes = @tagName(mir_tag[0]);
191923191922 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;
191924 return s.cg.fail(
191925 "invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'",
191926 .{
191927 fixes[0..fixes_blank],
191928 @tagName(mir_tag[1]),
191929 fixes[fixes_blank + 1 ..],
191930 @tagName(mir_ops[0]),
191931 @tagName(mir_ops[1]),
191932 @tagName(mir_ops[2]),
191933 @tagName(mir_ops[3]),
191934 },
191935 );
191923 return s.cg.fail("invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", .{
191924 fixes[0..fixes_blank],
191925 @tagName(mir_tag[1]),
191926 fixes[fixes_blank + 1 ..],
191927 @tagName(mir_ops[0]),
191928 @tagName(mir_ops[1]),
191929 @tagName(mir_ops[2]),
191930 @tagName(mir_ops[3]),
191931 });
191936191932 },
191937191933 else => |e| return e,
191938191934 };
......@@ -194424,6 +194420,18 @@ fn select(
194424194420 while (true) for (pattern.src[0..src_temps.len], src_temps) |src_pattern, *src_temp| {
194425194421 if (try src_pattern.convert(src_temp, cg)) break;
194426194422 } else break;
194423 var src_locks: [s_src_temps.len][2]?RegisterLock = @splat(@splat(null));
194424 for (src_locks[0..src_temps.len], src_temps) |*locks, src_temp| {
194425 const regs: [2]Register = switch (src_temp.tracking(cg).short) {
194426 else => continue,
194427 .register => |reg| .{ reg, .none },
194428 .register_pair => |regs| regs,
194429 };
194430 for (regs, locks) |reg, *lock| {
194431 if (reg == .none) continue;
194432 lock.* = cg.register_manager.lockRegIndex(RegisterManager.indexOfRegIntoTracked(reg) orelse continue);
194433 }
194434 }
194427194435 @memcpy(s_src_temps[0..src_temps.len], src_temps);
194428194436 std.mem.swap(Temp, &s_src_temps[pattern.commute[0]], &s_src_temps[pattern.commute[1]]);
194429194437
......@@ -194442,6 +194450,7 @@ fn select(
194442194450 }
194443194451 assert(s.top == 0);
194444194452
194453 for (src_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194445194454 for (tmp_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194446194455 for (dst_locks) |locks| for (locks) |lock| if (lock) |reg| cg.register_manager.unlockReg(reg);
194447194456 caller_preserved: {
test/behavior/switch.zig+10
......@@ -1072,3 +1072,13 @@ test "switch on a signed value smaller than the smallest prong value" {
10721072 else => {},
10731073 }
10741074}
1075
1076test "switch on 8-bit mod result" {
1077 var x: u8 = undefined;
1078 x = 16;
1079 switch (x % 4) {
1080 0 => {},
1081 1, 2, 3 => return error.TestFailed,
1082 else => unreachable,
1083 }
1084}