@@ -32,28 +32,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
32
32
33
33
assert_eq ! ( dest_len, op_len) ;
34
34
35
- #[ derive( Copy , Clone ) ]
36
- enum HostFloatOp {
37
- Ceil ,
38
- Floor ,
39
- Round ,
40
- Trunc ,
41
- Sqrt ,
42
- }
43
35
#[ derive( Copy , Clone ) ]
44
36
enum Op {
45
37
MirOp ( mir:: UnOp ) ,
46
38
Abs ,
47
- HostOp ( HostFloatOp ) ,
39
+ Sqrt ,
40
+ Round ( rustc_apfloat:: Round ) ,
48
41
}
49
42
let which = match intrinsic_name {
50
43
"neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
51
44
"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 ) ,
57
50
_ => unreachable ! ( ) ,
58
51
} ;
59
52
@@ -73,36 +66,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
73
66
FloatTy :: F64 => Scalar :: from_f64 ( op. to_f64 ( ) ?. abs ( ) ) ,
74
67
}
75
68
}
76
- Op :: HostOp ( host_op ) => {
69
+ Op :: Sqrt => {
77
70
let ty:: Float ( float_ty) = op. layout . ty . kind ( ) else {
78
71
span_bug ! ( this. cur_span( ) , "{} operand is not a float" , intrinsic_name)
79
72
} ;
80
73
// FIXME using host floats
81
74
match float_ty {
82
75
FloatTy :: F32 => {
83
76
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 ( ) ;
91
78
Scalar :: from_u32 ( res. to_bits ( ) )
92
79
}
93
80
FloatTy :: F64 => {
94
81
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 ( ) ;
102
83
Scalar :: from_u64 ( res. to_bits ( ) )
103
84
}
104
85
}
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
+ }
106
103
}
107
104
} ;
108
105
this. write_scalar ( val, & dest) ?;
0 commit comments