authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 16:58:55-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-01 19:22:53-04:00
logdb88b414722e698a392ec65a3ef46730341aea25
tree9915a092d16f85355a27265a7d31637631217d1a
parent5e7f3d5daaea1e6f5e835648ffd085797b667824

x86_64: fix switch multi-prongs and mul/div flags clobber


4 files changed, 6 insertions(+), 10 deletions(-)

src/arch/x86_64/CodeGen.zig+6-4
...@@ -2435,6 +2435,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2435,6 +2435,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2435 } };2435 } };
2436 const src_ty = Type.initPayload(&src_pl.base);2436 const src_ty = Type.initPayload(&src_pl.base);
24372437
2438 try self.spillEflagsIfOccupied();
2438 try self.spillRegisters(&.{ .rax, .rdx });2439 try self.spillRegisters(&.{ .rax, .rdx });
2439 const lhs = try self.resolveInst(bin_op.lhs);2440 const lhs = try self.resolveInst(bin_op.lhs);
2440 const rhs = try self.resolveInst(bin_op.rhs);2441 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -7236,15 +7237,16 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -7236,15 +7237,16 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
7236 var relocs = try self.gpa.alloc(u32, items.len);7237 var relocs = try self.gpa.alloc(u32, items.len);
7237 defer self.gpa.free(relocs);7238 defer self.gpa.free(relocs);
72387239
7239 for (items, relocs) |item, *reloc| {7240 try self.spillEflagsIfOccupied();
7240 try self.spillEflagsIfOccupied();7241 for (items, relocs, 0..) |item, *reloc, i| {
7241 const item_mcv = try self.resolveInst(item);7242 const item_mcv = try self.resolveInst(item);
7242 try self.genBinOpMir(.cmp, condition_ty, condition, item_mcv);7243 try self.genBinOpMir(.cmp, condition_ty, condition, item_mcv);
7243 reloc.* = try self.asmJccReloc(undefined, .ne);7244 reloc.* = try self.asmJccReloc(undefined, if (i < relocs.len - 1) .e else .ne);
7244 }7245 }
72457246
7246 for (liveness.deaths[case_i]) |operand| self.processDeath(operand);7247 for (liveness.deaths[case_i]) |operand| self.processDeath(operand);
72477248
7249 for (relocs[0 .. relocs.len - 1]) |reloc| try self.performReloc(reloc);
7248 try self.genBody(case_body);7250 try self.genBody(case_body);
7249 try self.restoreState(state, &.{}, .{7251 try self.restoreState(state, &.{}, .{
7250 .emit_instructions = false,7252 .emit_instructions = false,
...@@ -7253,7 +7255,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -7253,7 +7255,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
7253 .close_scope = true,7255 .close_scope = true,
7254 });7256 });
72557257
7256 for (relocs) |reloc| try self.performReloc(reloc);7258 try self.performReloc(relocs[relocs.len - 1]);
7257 }7259 }
72587260
7259 if (switch_br.data.else_body_len > 0) {7261 if (switch_br.data.else_body_len > 0) {
test/behavior/inline_switch.zig-1
...@@ -94,7 +94,6 @@ test "inline else error" {...@@ -94,7 +94,6 @@ test "inline else error" {
9494
95test "inline else enum" {95test "inline else enum" {
96 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO96 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
97 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
98 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO97 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9998
100 const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };99 const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };
test/behavior/switch.zig-4
...@@ -88,7 +88,6 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {...@@ -88,7 +88,6 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {
88const SwitchStatementFoo = enum { A, B, C, D };88const SwitchStatementFoo = enum { A, B, C, D };
8989
90test "switch with multiple expressions" {90test "switch with multiple expressions" {
91 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO91 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9392
94 const x = switch (returnsFive()) {93 const x = switch (returnsFive()) {
...@@ -275,7 +274,6 @@ fn testSwitchEnumPtrCapture() !void {...@@ -275,7 +274,6 @@ fn testSwitchEnumPtrCapture() !void {
275}274}
276275
277test "switch handles all cases of number" {276test "switch handles all cases of number" {
278 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
279 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO277 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
280278
281 try testSwitchHandleAllCases();279 try testSwitchHandleAllCases();
...@@ -455,7 +453,6 @@ test "else prong of switch on error set excludes other cases" {...@@ -455,7 +453,6 @@ test "else prong of switch on error set excludes other cases" {
455}453}
456454
457test "switch prongs with error set cases make a new error set type for capture value" {455test "switch prongs with error set cases make a new error set type for capture value" {
458 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
459 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO456 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
460 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
461 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO458 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -532,7 +529,6 @@ test "switch with null and T peer types and inferred result location type" {...@@ -532,7 +529,6 @@ test "switch with null and T peer types and inferred result location type" {
532test "switch prongs with cases with identical payload types" {529test "switch prongs with cases with identical payload types" {
533 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO530 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
534 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO531 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
535 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
536 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO532 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
537533
538 const Union = union(enum) {534 const Union = union(enum) {
test/behavior/union.zig-1
...@@ -1288,7 +1288,6 @@ test "return an extern union from C calling convention" {...@@ -1288,7 +1288,6 @@ test "return an extern union from C calling convention" {
1288test "noreturn field in union" {1288test "noreturn field in union" {
1289 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1289 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1291 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1292 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12931292
1294 const U = union(enum) {1293 const U = union(enum) {