| ... | ... | @@ -10175,37 +10175,38 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 10175 | 10175 | if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned; |
| 10176 | 10176 | const src_signedness = |
| 10177 | 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 | 10180 | const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*)); |
| 10179 | 10181 | const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*)); |
| 10180 | | const dst_limbs_len = math.divCeil(u16, bit_size, 64) catch unreachable; |
| 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); |
| 10182 | if (abi_size * 8 <= bit_size) break :result dst_mcv; |
| 10200 | 10183 | |
| 10201 | | try self.truncateRegister(high_ty, high_reg); |
| 10202 | | if (!dst_mcv.isRegister()) try self.genCopy( |
| 10184 | const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable; |
| 10185 | const high_reg = if (dst_mcv.isRegister()) |
| 10186 | dst_mcv.getReg().? |
| 10187 | else |
| 10188 | try self.copyToTmpRegister( |
| 10203 | 10189 | Type.usize, |
| 10204 | 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 | 10210 | break :result dst_mcv; |
| 10210 | 10211 | }; |
| 10211 | 10212 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |