| ... | ... | @@ -5257,64 +5257,24 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 5257 | 5257 | |
| 5258 | 5258 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 5259 | 5259 | const ptr_field_ty = self.air.typeOfIndex(inst); |
| 5260 | | const mcv = try self.resolveInst(operand); |
| 5261 | 5260 | const ptr_container_ty = self.air.typeOf(operand); |
| 5262 | 5261 | 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.*), |
| 5265 | 5264 | .Packed => if (container_ty.zigTypeTag() == .Struct and |
| 5266 | 5265 | ptr_field_ty.ptrInfo().data.host_size == 0) |
| 5267 | 5266 | container_ty.packedStructFieldByteOffset(index, self.target.*) |
| 5268 | 5267 | else |
| 5269 | 5268 | 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 | }); |
| 5300 | 5270 | |
| 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); |
| 5318 | 5278 | } |
| 5319 | 5279 | |
| 5320 | 5280 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -6717,7 +6677,6 @@ fn genBinOpMir( |
| 6717 | 6677 | .dead, |
| 6718 | 6678 | .undef, |
| 6719 | 6679 | .immediate, |
| 6720 | | .register_offset, |
| 6721 | 6680 | .eflags, |
| 6722 | 6681 | .register_overflow, |
| 6723 | 6682 | .lea_direct, |
| ... | ... | @@ -6726,7 +6685,9 @@ fn genBinOpMir( |
| 6726 | 6685 | .lea_frame, |
| 6727 | 6686 | .reserved_frame, |
| 6728 | 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 | 6691 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 6731 | 6692 | switch (src_mcv) { |
| 6732 | 6693 | .none, |
| ... | ... | @@ -8625,11 +8586,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { |
| 8625 | 8586 | } |
| 8626 | 8587 | |
| 8627 | 8588 | fn 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; |
| 8633 | 8590 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 8634 | 8591 | |
| 8635 | 8592 | switch (dst_mcv) { |