| ... | @@ -10175,37 +10175,38 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10175,37 +10175,38 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 10175 | if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned; | 10175 | if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned; |
| 10176 | const src_signedness = | 10176 | const src_signedness = |
| 10177 | if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned; | 10177 | if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned; |
| | 10178 | if (dst_signedness == src_signedness) break :result dst_mcv; |
| | 10179 | |
| 10178 | const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*)); | 10180 | const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*)); |
| 10179 | const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*)); | 10181 | const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*)); |
| 10180 | const dst_limbs_len = math.divCeil(u16, bit_size, 64) catch unreachable; | 10182 | if (abi_size * 8 <= bit_size) break :result dst_mcv; |
| 10181 | if (dst_signedness != src_signedness and abi_size * 8 > bit_size) { | | |
| 10182 | const high_reg = if (dst_mcv.isRegister()) | | |
| 10183 | dst_mcv.getReg().? | | |
| 10184 | else | | |
| 10185 | try self.copyToTmpRegister( | | |
| 10186 | Type.usize, | | |
| 10187 | dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(), | | |
| 10188 | ); | | |
| 10189 | const high_lock = self.register_manager.lockReg(high_reg); | | |
| 10190 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 10191 | | | |
| 10192 | var high_pl = Type.Payload.Bits{ | | |
| 10193 | .base = .{ .tag = switch (dst_signedness) { | | |
| 10194 | .signed => .int_signed, | | |
| 10195 | .unsigned => .int_unsigned, | | |
| 10196 | } }, | | |
| 10197 | .data = bit_size % 64, | | |
| 10198 | }; | | |
| 10199 | const high_ty = Type.initPayload(&high_pl.base); | | |
| 10200 | | 10183 | |
| 10201 | try self.truncateRegister(high_ty, high_reg); | 10184 | const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable; |
| 10202 | if (!dst_mcv.isRegister()) try self.genCopy( | 10185 | const high_reg = if (dst_mcv.isRegister()) |
| | 10186 | dst_mcv.getReg().? |
| | 10187 | else |
| | 10188 | try self.copyToTmpRegister( |
| 10203 | Type.usize, | 10189 | Type.usize, |
| 10204 | dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(), | 10190 | dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(), |
| 10205 | .{ .register = high_reg }, | | |
| 10206 | ); | 10191 | ); |
| 10207 | } | 10192 | const high_lock = self.register_manager.lockReg(high_reg); |
| | 10193 | defer if (high_lock) |lock| self.register_manager.unlockReg(lock); |
| | 10194 | |
| | 10195 | var high_pl = Type.Payload.Bits{ |
| | 10196 | .base = .{ .tag = switch (dst_signedness) { |
| | 10197 | .signed => .int_signed, |
| | 10198 | .unsigned => .int_unsigned, |
| | 10199 | } }, |
| | 10200 | .data = bit_size % 64, |
| | 10201 | }; |
| | 10202 | const high_ty = Type.initPayload(&high_pl.base); |
| 10208 | | 10203 | |
| | 10204 | try self.truncateRegister(high_ty, high_reg); |
| | 10205 | if (!dst_mcv.isRegister()) try self.genCopy( |
| | 10206 | Type.usize, |
| | 10207 | dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(), |
| | 10208 | .{ .register = high_reg }, |
| | 10209 | ); |
| 10209 | break :result dst_mcv; | 10210 | break :result dst_mcv; |
| 10210 | }; | 10211 | }; |
| 10211 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 10212 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |