(&mut self, val: SpirvValue, sign: SpirvValue)
| 35 | |
| 36 | impl Builder<'_, '_> { |
| 37 | pub fn copysign(&mut self, val: SpirvValue, sign: SpirvValue) -> SpirvValue { |
| 38 | let width = match self.lookup_type(val.ty) { |
| 39 | SpirvType::Float(width) => width, |
| 40 | other => bug!( |
| 41 | "copysign must have float argument, not {}", |
| 42 | other.debug(val.ty, self) |
| 43 | ), |
| 44 | }; |
| 45 | let int_ty = SpirvType::Integer(width, false).def(self.span(), self); |
| 46 | let (mask_sign, mask_value) = match width { |
| 47 | 32 => ( |
| 48 | self.constant_u32(self.span(), 1 << 31), |
| 49 | self.constant_u32(self.span(), u32::max_value() >> 1), |
| 50 | ), |
| 51 | 64 => ( |
| 52 | self.constant_u64(self.span(), 1 << 63), |
| 53 | self.constant_u64(self.span(), u64::max_value() >> 1), |
| 54 | ), |
| 55 | _ => bug!("copysign must have width 32 or 64, not {}", width), |
| 56 | }; |
| 57 | let val_bits = self.bitcast(val, int_ty); |
| 58 | let sign_bits = self.bitcast(sign, int_ty); |
| 59 | let val_masked = self.and(val_bits, mask_value); |
| 60 | let sign_masked = self.and(sign_bits, mask_sign); |
| 61 | let result_bits = self.or(val_masked, sign_masked); |
| 62 | self.bitcast(result_bits, val.ty) |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> { |
no test coverage detected