| ... | ... | @@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2089 | 2089 | defer self.register_manager.unlockReg(src_lock); |
| 2090 | 2090 | |
| 2091 | 2091 | const dst_ty = self.air.typeOfIndex(inst); |
| 2092 | | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| 2093 | | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 2094 | | defer self.register_manager.unlockReg(dst_lock); |
| 2092 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2093 | src_reg |
| 2094 | else |
| 2095 | try self.register_manager.allocReg(inst, gp); |
| 2096 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 2097 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 2095 | 2098 | |
| 2096 | 2099 | const eu_ty = src_ty.childType(); |
| 2097 | 2100 | const pl_ty = eu_ty.errorUnionPayload(); |
| ... | ... | @@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 2133 | 2136 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2134 | 2137 | |
| 2135 | 2138 | const dst_ty = self.air.typeOfIndex(inst); |
| 2136 | | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| 2137 | | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 2138 | | defer self.register_manager.unlockReg(dst_lock); |
| 2139 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2140 | src_reg |
| 2141 | else |
| 2142 | try self.register_manager.allocReg(inst, gp); |
| 2143 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 2144 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 2139 | 2145 | |
| 2140 | 2146 | const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); |
| 2141 | 2147 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| ... | ... | @@ -2309,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 2309 | 2315 | |
| 2310 | 2316 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2311 | 2317 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2312 | | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 2313 | | .dead |
| 2314 | | else |
| 2315 | | return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}); |
| 2318 | const result: MCValue = result: { |
| 2319 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2320 | |
| 2321 | const src_ty = self.air.typeOf(ty_op.operand); |
| 2322 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 2323 | const src_reg = switch (src_mcv) { |
| 2324 | .register => |reg| reg, |
| 2325 | else => try self.copyToTmpRegister(src_ty, src_mcv), |
| 2326 | }; |
| 2327 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 2328 | defer self.register_manager.unlockReg(src_lock); |
| 2329 | |
| 2330 | const dst_ty = self.air.typeOfIndex(inst); |
| 2331 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2332 | src_reg |
| 2333 | else |
| 2334 | try self.register_manager.allocReg(inst, gp); |
| 2335 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 2336 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 2337 | |
| 2338 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| 2339 | try self.asmRegisterMemory( |
| 2340 | .lea, |
| 2341 | registerAlias(dst_reg, dst_abi_size), |
| 2342 | Memory.sib(.qword, .{ |
| 2343 | .base = src_reg, |
| 2344 | .disp = @divExact(self.target.cpu.arch.ptrBitWidth(), 8), |
| 2345 | }), |
| 2346 | ); |
| 2347 | break :result .{ .register = dst_reg }; |
| 2348 | }; |
| 2316 | 2349 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2317 | 2350 | } |
| 2318 | 2351 | |
| 2319 | 2352 | fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2320 | 2353 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2321 | | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 2322 | | .dead |
| 2323 | | else |
| 2324 | | return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}); |
| 2354 | const result: MCValue = result: { |
| 2355 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2356 | |
| 2357 | const dst_ty = self.air.typeOfIndex(inst); |
| 2358 | const opt_mcv = try self.resolveInst(ty_op.operand); |
| 2359 | |
| 2360 | break :result if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) |
| 2361 | opt_mcv |
| 2362 | else |
| 2363 | try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv); |
| 2364 | }; |
| 2325 | 2365 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2326 | 2366 | } |
| 2327 | 2367 | |