|
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::{LayoutOfas _,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 | _ => returninterp_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 | +fnfloat_min_intrinsic<F>( |
| 723 | +&mutself, |
| 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 | +fnfloat_max_intrinsic<F>( |
| 738 | +&mutself, |
| 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 | +fnfloat_copysign_intrinsic<F>( |
| 753 | +&mutself, |
| 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 | +fnfloat_abs_intrinsic<F>( |
| 768 | +&mutself, |
| 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