@@ -32,28 +32,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3232
3333 assert_eq ! ( dest_len, op_len) ;
3434
35- #[ derive( Copy , Clone ) ]
36- enum HostFloatOp {
37- Ceil ,
38- Floor ,
39- Round ,
40- Trunc ,
41- Sqrt ,
42- }
4335 #[ derive( Copy , Clone ) ]
4436 enum Op {
4537 MirOp ( mir:: UnOp ) ,
4638 Abs ,
47- HostOp ( HostFloatOp ) ,
39+ Sqrt ,
40+ Round ( rustc_apfloat:: Round ) ,
4841 }
4942 let which = match intrinsic_name {
5043 "neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
5144 "fabs" => Op :: Abs ,
52- "ceil " => Op :: HostOp ( HostFloatOp :: Ceil ) ,
53- "floor " => Op :: HostOp ( HostFloatOp :: Floor ) ,
54- "round " => Op :: HostOp ( HostFloatOp :: Round ) ,
55- "trunc " => Op :: HostOp ( HostFloatOp :: Trunc ) ,
56- "fsqrt " => Op :: HostOp ( HostFloatOp :: Sqrt ) ,
45+ "fsqrt " => Op :: Sqrt ,
46+ "ceil " => Op :: Round ( rustc_apfloat :: Round :: TowardPositive ) ,
47+ "floor " => Op :: Round ( rustc_apfloat :: Round :: TowardNegative ) ,
48+ "round " => Op :: Round ( rustc_apfloat :: Round :: NearestTiesToAway ) ,
49+ "trunc " => Op :: Round ( rustc_apfloat :: Round :: TowardZero ) ,
5750 _ => unreachable ! ( ) ,
5851 } ;
5952
@@ -73,36 +66,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7366 FloatTy :: F64 => Scalar :: from_f64 ( op. to_f64 ( ) ?. abs ( ) ) ,
7467 }
7568 }
76- Op :: HostOp ( host_op ) => {
69+ Op :: Sqrt => {
7770 let ty:: Float ( float_ty) = op. layout . ty . kind ( ) else {
7871 span_bug ! ( this. cur_span( ) , "{} operand is not a float" , intrinsic_name)
7972 } ;
8073 // FIXME using host floats
8174 match float_ty {
8275 FloatTy :: F32 => {
8376 let f = f32:: from_bits ( op. to_scalar ( ) . to_u32 ( ) ?) ;
84- let res = match host_op {
85- HostFloatOp :: Ceil => f. ceil ( ) ,
86- HostFloatOp :: Floor => f. floor ( ) ,
87- HostFloatOp :: Round => f. round ( ) ,
88- HostFloatOp :: Trunc => f. trunc ( ) ,
89- HostFloatOp :: Sqrt => f. sqrt ( ) ,
90- } ;
77+ let res = f. sqrt ( ) ;
9178 Scalar :: from_u32 ( res. to_bits ( ) )
9279 }
9380 FloatTy :: F64 => {
9481 let f = f64:: from_bits ( op. to_scalar ( ) . to_u64 ( ) ?) ;
95- let res = match host_op {
96- HostFloatOp :: Ceil => f. ceil ( ) ,
97- HostFloatOp :: Floor => f. floor ( ) ,
98- HostFloatOp :: Round => f. round ( ) ,
99- HostFloatOp :: Trunc => f. trunc ( ) ,
100- HostFloatOp :: Sqrt => f. sqrt ( ) ,
101- } ;
82+ let res = f. sqrt ( ) ;
10283 Scalar :: from_u64 ( res. to_bits ( ) )
10384 }
10485 }
105-
86+ }
87+ Op :: Round ( rounding) => {
88+ let ty:: Float ( float_ty) = op. layout . ty . kind ( ) else {
89+ span_bug ! ( this. cur_span( ) , "{} operand is not a float" , intrinsic_name)
90+ } ;
91+ match float_ty {
92+ FloatTy :: F32 => {
93+ let f = op. to_scalar ( ) . to_f32 ( ) ?;
94+ let res = f. round_to_integral ( rounding) . value ;
95+ Scalar :: from_f32 ( res)
96+ }
97+ FloatTy :: F64 => {
98+ let f = op. to_scalar ( ) . to_f64 ( ) ?;
99+ let res = f. round_to_integral ( rounding) . value ;
100+ Scalar :: from_f64 ( res)
101+ }
102+ }
106103 }
107104 } ;
108105 this. write_scalar ( val, & dest) ?;
0 commit comments