authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-18 01:24:17-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-21 10:55:41-04:00
log9358a7528f74cfa8b45f98e83749b8e695d9a941
tree2a777eb95a639beb0c515ee7fb7021fa77c3c7ae
parentb403ca0aabb4529949b48e68f1392afc31098a98

x86_64: fix crashes


4 files changed, 40 insertions(+), 20 deletions(-)

src/arch/x86_64/CodeGen.zig+38-17
...@@ -3798,11 +3798,13 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3798,11 +3798,13 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
3798}3798}
37993799
3800fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {3800fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3801 const mod = self.bin_file.options.module.?;
3801 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3802 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3802 const result: MCValue = result: {3803 const result: MCValue = result: {
3803 const pl_ty = self.typeOfIndex(inst);3804 const pl_ty = self.typeOfIndex(inst);
3804 const opt_mcv = try self.resolveInst(ty_op.operand);3805 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
38053806
3807 const opt_mcv = try self.resolveInst(ty_op.operand);
3806 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {3808 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
3807 switch (opt_mcv) {3809 switch (opt_mcv) {
3808 .register => |reg| try self.truncateRegister(pl_ty, reg),3810 .register => |reg| try self.truncateRegister(pl_ty, reg),
...@@ -11521,10 +11523,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -11521,10 +11523,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
11521 .undef => {},11523 .undef => {},
11522 .immediate => |imm| switch (abi_size) {11524 .immediate => |imm| switch (abi_size) {
11523 1, 2, 4 => {11525 1, 2, 4 => {
11524 const immediate = if (ty.isSignedInt(mod))11526 const immediate = switch (if (ty.isAbiInt(mod))
11525 Immediate.s(@truncate(@as(i64, @bitCast(imm))))11527 ty.intInfo(mod).signedness
11526 else11528 else
11527 Immediate.u(@as(u32, @intCast(imm)));11529 .unsigned) {
11530 .signed => Immediate.s(@truncate(@as(i64, @bitCast(imm)))),
11531 .unsigned => Immediate.u(@as(u32, @intCast(imm))),
11532 };
11528 try self.asmMemoryImmediate(11533 try self.asmMemoryImmediate(
11529 .{ ._, .mov },11534 .{ ._, .mov },
11530 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }),11535 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base, .disp = disp }),
...@@ -11586,19 +11591,35 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -11586,19 +11591,35 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
11586 .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) },11591 .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) },
11587 ), registerAlias(src_reg, part_size));11592 ), registerAlias(src_reg, part_size));
11588 },11593 },
11589 .register_overflow => |ro| {11594 .register_overflow => |ro| switch (ty.zigTypeTag(mod)) {
11590 try self.genSetMem(11595 .Struct => {
11591 base,11596 try self.genSetMem(
11592 disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),11597 base,
11593 ty.structFieldType(0, mod),11598 disp + @as(i32, @intCast(ty.structFieldOffset(0, mod))),
11594 .{ .register = ro.reg },11599 ty.structFieldType(0, mod),
11595 );11600 .{ .register = ro.reg },
11596 try self.genSetMem(11601 );
11597 base,11602 try self.genSetMem(
11598 disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))),11603 base,
11599 ty.structFieldType(1, mod),11604 disp + @as(i32, @intCast(ty.structFieldOffset(1, mod))),
11600 .{ .eflags = ro.eflags },11605 ty.structFieldType(1, mod),
11601 );11606 .{ .eflags = ro.eflags },
11607 );
11608 },
11609 .Optional => {
11610 assert(!ty.optionalReprIsPayload(mod));
11611 const child_ty = ty.optionalChild(mod);
11612 try self.genSetMem(base, disp, child_ty, .{ .register = ro.reg });
11613 try self.genSetMem(
11614 base,
11615 disp + @as(i32, @intCast(child_ty.abiSize(mod))),
11616 Type.bool,
11617 .{ .eflags = ro.eflags },
11618 );
11619 },
11620 else => return self.fail("TODO implement genSetMem for {s} of {}", .{
11621 @tagName(src_mcv), ty.fmt(mod),
11622 }),
11602 },11623 },
11603 .register_offset,11624 .register_offset,
11604 .memory,11625 .memory,
test/behavior/basic.zig+1-1
...@@ -745,12 +745,12 @@ test "auto created variables have correct alignment" {...@@ -745,12 +745,12 @@ test "auto created variables have correct alignment" {
745745
746test "extern variable with non-pointer opaque type" {746test "extern variable with non-pointer opaque type" {
747 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO747 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
748 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
749 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO748 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
750 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO749 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
751 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO750 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
752 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO751 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
753 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;752 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
753 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
754754
755 @export(var_to_export, .{ .name = "opaque_extern_var" });755 @export(var_to_export, .{ .name = "opaque_extern_var" });
756 try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42);756 try expect(@as(*align(1) u32, @ptrCast(&opaque_extern_var)).* == 42);
test/behavior/cast.zig-1
...@@ -2383,7 +2383,6 @@ test "numeric coercions with undefined" {...@@ -2383,7 +2383,6 @@ test "numeric coercions with undefined" {
23832383
2384test "15-bit int to float" {2384test "15-bit int to float" {
2385 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;2385 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
2386 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
23872386
2388 var a: u15 = 42;2387 var a: u15 = 42;
2389 var b: f32 = @floatFromInt(a);2388 var b: f32 = @floatFromInt(a);
test/behavior/fn.zig+1-1
...@@ -425,8 +425,8 @@ test "implicit cast function to function ptr" {...@@ -425,8 +425,8 @@ test "implicit cast function to function ptr" {
425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO425 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
427 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO427 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
428 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
429 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;428 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
429 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
430430
431 const S1 = struct {431 const S1 = struct {
432 export fn someFunctionThatReturnsAValue() c_int {432 export fn someFunctionThatReturnsAValue() c_int {