| ... | @@ -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 { |
| 5257 | | 5257 | |
| 5258 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 5258 | fn 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 and | 5264 | .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 | else | 5267 | 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); | | |
| 5300 | | 5270 | |
| 5301 | const dst_mcv: MCValue = if (self.reuseOperand(inst, operand, 0, mcv)) | 5271 | const src_mcv = try self.resolveInst(operand); |
| 5302 | mcv | 5272 | const dst_mcv = if (switch (src_mcv) { |
| 5303 | else | 5273 | .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 | } |
| 5319 | | 5279 | |
| 5320 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 5280 | fn 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 destination | 6687 | => 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 | } |
| 8626 | | 8587 | |
| 8627 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 8588 | fn 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); |
| 8634 | | 8591 | |
| 8635 | switch (dst_mcv) { | 8592 | switch (dst_mcv) { |