authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-08 23:13:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
log1336619979cfd5145c042ba7e2c6d0fbafc53574
tree5938526017ccaf8441cd524c7dd13319622dcef9
parent81664f17d5ec4382057bc3d2c8774d8804791a04

x86_64: fix field_ptr nonsense


3 files changed, 14 insertions(+), 62 deletions(-)

src/arch/x86_64/CodeGen.zig+14-57
...@@ -5257,64 +5257,24 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -5257,64 +5257,24 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
52575257
5258fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {5258fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
5259 const ptr_field_ty = self.air.typeOfIndex(inst);5259 const ptr_field_ty = self.air.typeOfIndex(inst);
5260 const mcv = try self.resolveInst(operand);
5261 const ptr_container_ty = self.air.typeOf(operand);5260 const ptr_container_ty = self.air.typeOf(operand);
5262 const container_ty = ptr_container_ty.childType();5261 const container_ty = ptr_container_ty.childType();
5263 const field_offset = switch (container_ty.containerLayout()) {5262 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
5264 .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*)),5263 .Auto, .Extern => container_ty.structFieldOffset(index, self.target.*),
5265 .Packed => if (container_ty.zigTypeTag() == .Struct and5264 .Packed => if (container_ty.zigTypeTag() == .Struct and
5266 ptr_field_ty.ptrInfo().data.host_size == 0)5265 ptr_field_ty.ptrInfo().data.host_size == 0)
5267 container_ty.packedStructFieldByteOffset(index, self.target.*)5266 container_ty.packedStructFieldByteOffset(index, self.target.*)
5268 else5267 else
5269 0,5268 0,
5270 };5269 });
5271
5272 const result: MCValue = result: {
5273 switch (mcv) {
5274 .load_frame, .lea_tlv, .load_tlv => {
5275 const offset_reg = try self.copyToTmpRegister(Type.usize, .{
5276 .immediate = field_offset,
5277 });
5278 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
5279 defer self.register_manager.unlockReg(offset_reg_lock);
5280
5281 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, Type.usize, switch (mcv) {
5282 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
5283 else => mcv,
5284 });
5285 try self.genBinOpMir(.{ ._, .add }, Type.usize, dst_mcv, .{ .register = offset_reg });
5286 break :result dst_mcv;
5287 },
5288 .indirect => |reg_off| break :result .{ .indirect = .{
5289 .reg = reg_off.reg,
5290 .off = reg_off.off + @intCast(i32, field_offset),
5291 } },
5292 .lea_frame => |frame_addr| break :result .{ .lea_frame = .{
5293 .index = frame_addr.index,
5294 .off = frame_addr.off + @intCast(i32, field_offset),
5295 } },
5296 .register, .register_offset => {
5297 const src_reg = mcv.getReg().?;
5298 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
5299 defer self.register_manager.unlockReg(src_lock);
53005270
5301 const dst_mcv: MCValue = if (self.reuseOperand(inst, operand, 0, mcv))5271 const src_mcv = try self.resolveInst(operand);
5302 mcv5272 const dst_mcv = if (switch (src_mcv) {
5303 else5273 .immediate, .lea_frame => true,
5304 .{ .register = try self.copyToTmpRegister(ptr_field_ty, mcv) };5274 .register, .register_offset => self.reuseOperand(inst, operand, 0, src_mcv),
5305 break :result .{ .register_offset = .{5275 else => false,
5306 .reg = dst_mcv.getReg().?,5276 }) src_mcv else try self.copyToRegisterWithInstTracking(inst, ptr_field_ty, src_mcv);
5307 .off = switch (dst_mcv) {5277 return dst_mcv.offset(field_offset);
5308 .register => 0,
5309 .register_offset => |reg_off| reg_off.off,
5310 else => unreachable,
5311 } + @intCast(i32, field_offset),
5312 } };
5313 },
5314 else => return self.fail("TODO implement fieldPtr for {}", .{mcv}),
5315 }
5316 };
5317 return result;
5318}5278}
53195279
5320fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {5280fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
...@@ -6717,7 +6677,6 @@ fn genBinOpMir(...@@ -6717,7 +6677,6 @@ fn genBinOpMir(
6717 .dead,6677 .dead,
6718 .undef,6678 .undef,
6719 .immediate,6679 .immediate,
6720 .register_offset,
6721 .eflags,6680 .eflags,
6722 .register_overflow,6681 .register_overflow,
6723 .lea_direct,6682 .lea_direct,
...@@ -6726,7 +6685,9 @@ fn genBinOpMir(...@@ -6726,7 +6685,9 @@ fn genBinOpMir(
6726 .lea_frame,6685 .lea_frame,
6727 .reserved_frame,6686 .reserved_frame,
6728 => unreachable, // unmodifiable destination6687 => unreachable, // unmodifiable destination
6729 .register => |dst_reg| {6688 .register, .register_offset => {
6689 assert(dst_mcv.isRegister());
6690 const dst_reg = dst_mcv.getReg().?;
6730 const dst_alias = registerAlias(dst_reg, abi_size);6691 const dst_alias = registerAlias(dst_reg, abi_size);
6731 switch (src_mcv) {6692 switch (src_mcv) {
6732 .none,6693 .none,
...@@ -8625,11 +8586,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {...@@ -8625,11 +8586,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
8625}8586}
86268587
8627fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {8588fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
8628 const src_lock = switch (src_mcv) {8589 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
8629 .register => |reg| self.register_manager.lockReg(reg),
8630 .register_overflow => |ro| self.register_manager.lockReg(ro.reg),
8631 else => null,
8632 };
8633 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);8590 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
86348591
8635 switch (dst_mcv) {8592 switch (dst_mcv) {
test/behavior/field_parent_ptr.zig-4
...@@ -11,7 +11,6 @@ test "@fieldParentPtr non-first field" {...@@ -11,7 +11,6 @@ test "@fieldParentPtr non-first field" {
11}11}
1212
13test "@fieldParentPtr first field" {13test "@fieldParentPtr first field" {
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
16 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;16 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
...@@ -51,7 +50,6 @@ fn testParentFieldPtrFirst(a: *const bool) !void {...@@ -51,7 +50,6 @@ fn testParentFieldPtrFirst(a: *const bool) !void {
51}50}
5251
53test "@fieldParentPtr untagged union" {52test "@fieldParentPtr untagged union" {
54 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
55 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;53 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
56 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -79,7 +77,6 @@ fn testFieldParentPtrUnion(c: *const i32) !void {...@@ -79,7 +77,6 @@ fn testFieldParentPtrUnion(c: *const i32) !void {
79}77}
8078
81test "@fieldParentPtr tagged union" {79test "@fieldParentPtr tagged union" {
82 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;80 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
84 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO81 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
85 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO82 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
...@@ -107,7 +104,6 @@ fn testFieldParentPtrTaggedUnion(c: *const i32) !void {...@@ -107,7 +104,6 @@ fn testFieldParentPtrTaggedUnion(c: *const i32) !void {
107}104}
108105
109test "@fieldParentPtr extern union" {106test "@fieldParentPtr extern union" {
110 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
111 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO109 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/union.zig-1
...@@ -1164,7 +1164,6 @@ test "union enum type gets a separate scope" {...@@ -1164,7 +1164,6 @@ test "union enum type gets a separate scope" {
1164}1164}
11651165
1166test "global variable struct contains union initialized to non-most-aligned field" {1166test "global variable struct contains union initialized to non-most-aligned field" {
1167 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1167 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1169 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1168 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1169 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO