|
4 | 4 |
|
5 | 5 | use std::assert_matches::assert_matches;
|
6 | 6 |
|
| 7 | +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; |
7 | 8 | use rustc_hir::def_id::DefId;
|
8 | 9 | use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
|
9 | 10 | use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement};
|
@@ -438,6 +439,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
438 | 439 | self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?;
|
439 | 440 | }
|
440 | 441 |
|
| 442 | + sym::minnumf16 => self.float_min_intrinsic::<Half>(args, dest)?, |
| 443 | + sym::minnumf32 => self.float_min_intrinsic::<Single>(args, dest)?, |
| 444 | + sym::minnumf64 => self.float_min_intrinsic::<Double>(args, dest)?, |
| 445 | + sym::minnumf128 => self.float_min_intrinsic::<Quad>(args, dest)?, |
| 446 | + |
| 447 | + sym::maxnumf16 => self.float_max_intrinsic::<Half>(args, dest)?, |
| 448 | + sym::maxnumf32 => self.float_max_intrinsic::<Single>(args, dest)?, |
| 449 | + sym::maxnumf64 => self.float_max_intrinsic::<Double>(args, dest)?, |
| 450 | + sym::maxnumf128 => self.float_max_intrinsic::<Quad>(args, dest)?, |
| 451 | + |
| 452 | + sym::copysignf16 => self.float_copysign_intrinsic::<Half>(args, dest)?, |
| 453 | + sym::copysignf32 => self.float_copysign_intrinsic::<Single>(args, dest)?, |
| 454 | + sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?, |
| 455 | + sym::copysignf128 => self.float_copysign_intrinsic::<Quad>(args, dest)?, |
| 456 | + |
| 457 | + sym::fabsf16 => self.float_abs_intrinsic::<Half>(args, dest)?, |
| 458 | + sym::fabsf32 => self.float_abs_intrinsic::<Single>(args, dest)?, |
| 459 | + sym::fabsf64 => self.float_abs_intrinsic::<Double>(args, dest)?, |
| 460 | + sym::fabsf128 => self.float_abs_intrinsic::<Quad>(args, dest)?, |
| 461 | + |
441 | 462 | // Unsupported intrinsic: skip the return_to_block below.
|
442 | 463 | _ => return interp_ok(false),
|
443 | 464 | }
|
@@ -697,4 +718,63 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
697 | 718 | let rhs_bytes = get_bytes(self, rhs)?;
|
698 | 719 | interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
|
699 | 720 | }
|
| 721 | + |
| 722 | + fn float_min_intrinsic<F>( |
| 723 | + &mut self, |
| 724 | + args: &[OpTy<'tcx, M::Provenance>], |
| 725 | + dest: &MPlaceTy<'tcx, M::Provenance>, |
| 726 | + ) -> InterpResult<'tcx, ()> |
| 727 | + where |
| 728 | + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, |
| 729 | + { |
| 730 | + let a: F = self.read_scalar(&args[0])?.to_float()?; |
| 731 | + let b: F = self.read_scalar(&args[1])?.to_float()?; |
| 732 | + let res = self.adjust_nan(a.min(b), &[a, b]); |
| 733 | + self.write_scalar(res, dest)?; |
| 734 | + interp_ok(()) |
| 735 | + } |
| 736 | + |
| 737 | + fn float_max_intrinsic<F>( |
| 738 | + &mut self, |
| 739 | + args: &[OpTy<'tcx, M::Provenance>], |
| 740 | + dest: &MPlaceTy<'tcx, M::Provenance>, |
| 741 | + ) -> InterpResult<'tcx, ()> |
| 742 | + where |
| 743 | + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, |
| 744 | + { |
| 745 | + let a: F = self.read_scalar(&args[0])?.to_float()?; |
| 746 | + let b: F = self.read_scalar(&args[1])?.to_float()?; |
| 747 | + let res = self.adjust_nan(a.max(b), &[a, b]); |
| 748 | + self.write_scalar(res, dest)?; |
| 749 | + interp_ok(()) |
| 750 | + } |
| 751 | + |
| 752 | + fn float_copysign_intrinsic<F>( |
| 753 | + &mut self, |
| 754 | + args: &[OpTy<'tcx, M::Provenance>], |
| 755 | + dest: &MPlaceTy<'tcx, M::Provenance>, |
| 756 | + ) -> InterpResult<'tcx, ()> |
| 757 | + where |
| 758 | + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, |
| 759 | + { |
| 760 | + let a: F = self.read_scalar(&args[0])?.to_float()?; |
| 761 | + let b: F = self.read_scalar(&args[1])?.to_float()?; |
| 762 | + // bitwise, no NaN adjustments |
| 763 | + self.write_scalar(a.copy_sign(b), dest)?; |
| 764 | + interp_ok(()) |
| 765 | + } |
| 766 | + |
| 767 | + fn float_abs_intrinsic<F>( |
| 768 | + &mut self, |
| 769 | + args: &[OpTy<'tcx, M::Provenance>], |
| 770 | + dest: &MPlaceTy<'tcx, M::Provenance>, |
| 771 | + ) -> InterpResult<'tcx, ()> |
| 772 | + where |
| 773 | + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, |
| 774 | + { |
| 775 | + let x: F = self.read_scalar(&args[0])?.to_float()?; |
| 776 | + // bitwise, no NaN adjustments |
| 777 | + self.write_scalar(x.abs(), dest)?; |
| 778 | + interp_ok(()) |
| 779 | + } |
700 | 780 | }
|
0 commit comments