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 {
52575257
52585258fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
52595259 const ptr_field_ty = self.air.typeOfIndex(inst);
5260 const mcv = try self.resolveInst(operand);
52615260 const ptr_container_ty = self.air.typeOf(operand);
52625261 const container_ty = ptr_container_ty.childType();
5263 const field_offset = switch (container_ty.containerLayout()) {
5264 .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*)),
5262 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
5263 .Auto, .Extern => container_ty.structFieldOffset(index, self.target.*),
52655264 .Packed => if (container_ty.zigTypeTag() == .Struct and
52665265 ptr_field_ty.ptrInfo().data.host_size == 0)
52675266 container_ty.packedStructFieldByteOffset(index, self.target.*)
52685267 else
52695268 0,
5270 };
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);
5269 });
53005270
5301 const dst_mcv: MCValue = if (self.reuseOperand(inst, operand, 0, mcv))
5302 mcv
5303 else
5304 .{ .register = try self.copyToTmpRegister(ptr_field_ty, mcv) };
5305 break :result .{ .register_offset = .{
5306 .reg = dst_mcv.getReg().?,
5307 .off = switch (dst_mcv) {
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;
5271 const src_mcv = try self.resolveInst(operand);
5272 const dst_mcv = if (switch (src_mcv) {
5273 .immediate, .lea_frame => true,
5274 .register, .register_offset => self.reuseOperand(inst, operand, 0, src_mcv),
5275 else => false,
5276 }) src_mcv else try self.copyToRegisterWithInstTracking(inst, ptr_field_ty, src_mcv);
5277 return dst_mcv.offset(field_offset);
53185278}
53195279
53205280fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
......@@ -6717,7 +6677,6 @@ fn genBinOpMir(
67176677 .dead,
67186678 .undef,
67196679 .immediate,
6720 .register_offset,
67216680 .eflags,
67226681 .register_overflow,
67236682 .lea_direct,
......@@ -6726,7 +6685,9 @@ fn genBinOpMir(
67266685 .lea_frame,
67276686 .reserved_frame,
67286687 => unreachable, // unmodifiable destination
6729 .register => |dst_reg| {
6688 .register, .register_offset => {
6689 assert(dst_mcv.isRegister());
6690 const dst_reg = dst_mcv.getReg().?;
67306691 const dst_alias = registerAlias(dst_reg, abi_size);
67316692 switch (src_mcv) {
67326693 .none,
......@@ -8625,11 +8586,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag {
86258586}
86268587
86278588fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
8628 const src_lock = switch (src_mcv) {
8629 .register => |reg| self.register_manager.lockReg(reg),
8630 .register_overflow => |ro| self.register_manager.lockReg(ro.reg),
8631 else => null,
8632 };
8589 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
86338590 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
86348591
86358592 switch (dst_mcv) {
test/behavior/field_parent_ptr.zig-4
......@@ -11,7 +11,6 @@ test "@fieldParentPtr non-first field" {
1111}
1212
1313test "@fieldParentPtr first field" {
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1514 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1615 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1716 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
......@@ -51,7 +50,6 @@ fn testParentFieldPtrFirst(a: *const bool) !void {
5150}
5251
5352test "@fieldParentPtr untagged union" {
54 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
5553 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5654 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5755 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -79,7 +77,6 @@ fn testFieldParentPtrUnion(c: *const i32) !void {
7977}
8078
8179test "@fieldParentPtr tagged union" {
82 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
8380 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8481 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8582 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
......@@ -107,7 +104,6 @@ fn testFieldParentPtrTaggedUnion(c: *const i32) !void {
107104}
108105
109106test "@fieldParentPtr extern union" {
110 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
111107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
112108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
113109 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" {
11641164}
11651165
11661166test "global variable struct contains union initialized to non-most-aligned field" {
1167 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11681167 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11691168 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11701169 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO