| ... | @@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2089 | defer self.register_manager.unlockReg(src_lock); | 2089 | defer self.register_manager.unlockReg(src_lock); |
| 2090 | | 2090 | |
| 2091 | const dst_ty = self.air.typeOfIndex(inst); | 2091 | const dst_ty = self.air.typeOfIndex(inst); |
| 2092 | const dst_reg = try self.register_manager.allocReg(inst, gp); | 2092 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2093 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 2093 | src_reg |
| 2094 | defer self.register_manager.unlockReg(dst_lock); | 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 | const eu_ty = src_ty.childType(); | 2099 | const eu_ty = src_ty.childType(); |
| 2097 | const pl_ty = eu_ty.errorUnionPayload(); | 2100 | const pl_ty = eu_ty.errorUnionPayload(); |
| ... | @@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 2133 | if (self.liveness.isUnused(inst)) break :result .dead; | 2136 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2134 | | 2137 | |
| 2135 | const dst_ty = self.air.typeOfIndex(inst); | 2138 | const dst_ty = self.air.typeOfIndex(inst); |
| 2136 | const dst_reg = try self.register_manager.allocReg(inst, gp); | 2139 | const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) |
| 2137 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 2140 | src_reg |
| 2138 | defer self.register_manager.unlockReg(dst_lock); | 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 | const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); | 2146 | const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*)); |
| 2141 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); | 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,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 2309 | | 2315 | |
| 2310 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { | 2316 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2311 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2317 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2312 | const result: MCValue = if (self.liveness.isUnused(inst)) | 2318 | const result: MCValue = result: { |
| 2313 | .dead | 2319 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2314 | else | 2320 | |
| 2315 | return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch}); | 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 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2349 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2317 | } | 2350 | } |
| 2318 | | 2351 | |
| 2319 | fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { | 2352 | fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2320 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 2353 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2321 | const result: MCValue = if (self.liveness.isUnused(inst)) | 2354 | const result: MCValue = result: { |
| 2322 | .dead | 2355 | if (self.liveness.isUnused(inst)) break :result .dead; |
| 2323 | else | 2356 | |
| 2324 | return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch}); | 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 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 2365 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2326 | } | 2366 | } |
| 2327 | | 2367 | |