mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
x86_64: fix switch multi-prongs and mul/div flags clobber
This commit is contained in:
parent
5e7f3d5daa
commit
db88b41472
@ -2435,6 +2435,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} };
|
||||
const src_ty = Type.initPayload(&src_pl.base);
|
||||
|
||||
try self.spillEflagsIfOccupied();
|
||||
try self.spillRegisters(&.{ .rax, .rdx });
|
||||
const lhs = try self.resolveInst(bin_op.lhs);
|
||||
const rhs = try self.resolveInst(bin_op.rhs);
|
||||
@ -7236,15 +7237,16 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
var relocs = try self.gpa.alloc(u32, items.len);
|
||||
defer self.gpa.free(relocs);
|
||||
|
||||
for (items, relocs) |item, *reloc| {
|
||||
try self.spillEflagsIfOccupied();
|
||||
try self.spillEflagsIfOccupied();
|
||||
for (items, relocs, 0..) |item, *reloc, i| {
|
||||
const item_mcv = try self.resolveInst(item);
|
||||
try self.genBinOpMir(.cmp, condition_ty, condition, item_mcv);
|
||||
reloc.* = try self.asmJccReloc(undefined, .ne);
|
||||
reloc.* = try self.asmJccReloc(undefined, if (i < relocs.len - 1) .e else .ne);
|
||||
}
|
||||
|
||||
for (liveness.deaths[case_i]) |operand| self.processDeath(operand);
|
||||
|
||||
for (relocs[0 .. relocs.len - 1]) |reloc| try self.performReloc(reloc);
|
||||
try self.genBody(case_body);
|
||||
try self.restoreState(state, &.{}, .{
|
||||
.emit_instructions = false,
|
||||
@ -7253,7 +7255,7 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
.close_scope = true,
|
||||
});
|
||||
|
||||
for (relocs) |reloc| try self.performReloc(reloc);
|
||||
try self.performReloc(relocs[relocs.len - 1]);
|
||||
}
|
||||
|
||||
if (switch_br.data.else_body_len > 0) {
|
||||
|
||||
@ -94,7 +94,6 @@ test "inline else error" {
|
||||
|
||||
test "inline else enum" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const E2 = enum(u8) { a = 2, b = 3, c = 4, d = 5 };
|
||||
|
||||
@ -88,7 +88,6 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {
|
||||
const SwitchStatementFoo = enum { A, B, C, D };
|
||||
|
||||
test "switch with multiple expressions" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const x = switch (returnsFive()) {
|
||||
@ -275,7 +274,6 @@ fn testSwitchEnumPtrCapture() !void {
|
||||
}
|
||||
|
||||
test "switch handles all cases of number" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchHandleAllCases();
|
||||
@ -455,7 +453,6 @@ test "else prong of switch on error set excludes other cases" {
|
||||
}
|
||||
|
||||
test "switch prongs with error set cases make a new error set type for capture value" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
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" {
|
||||
test "switch prongs with cases with identical payload types" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const Union = union(enum) {
|
||||
|
||||
@ -1288,7 +1288,6 @@ test "return an extern union from C calling convention" {
|
||||
test "noreturn field in union" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = union(enum) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user