@@ -33,6 +33,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3333 | "round"
3434 | "trunc"
3535 | "fsqrt"
36+ | "fsin"
37+ | "fcos"
38+ | "fexp"
39+ | "fexp2"
40+ | "flog"
41+ | "flog2"
42+ | "flog10"
3643 | "ctlz"
3744 | "cttz"
3845 | "bswap"
@@ -45,17 +52,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4552 assert_eq ! ( dest_len, op_len) ;
4653
4754 #[ derive( Copy , Clone ) ]
48- enum Op {
55+ enum Op < ' a > {
4956 MirOp ( mir:: UnOp ) ,
5057 Abs ,
51- Sqrt ,
5258 Round ( rustc_apfloat:: Round ) ,
5359 Numeric ( Symbol ) ,
60+ HostOp ( & ' a str ) ,
5461 }
5562 let which = match intrinsic_name {
5663 "neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
5764 "fabs" => Op :: Abs ,
58- "fsqrt" => Op :: Sqrt ,
5965 "ceil" => Op :: Round ( rustc_apfloat:: Round :: TowardPositive ) ,
6066 "floor" => Op :: Round ( rustc_apfloat:: Round :: TowardNegative ) ,
6167 "round" => Op :: Round ( rustc_apfloat:: Round :: NearestTiesToAway ) ,
@@ -64,7 +70,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
6470 "cttz" => Op :: Numeric ( sym:: cttz) ,
6571 "bswap" => Op :: Numeric ( sym:: bswap) ,
6672 "bitreverse" => Op :: Numeric ( sym:: bitreverse) ,
67- _ => unreachable ! ( ) ,
73+ _ => Op :: HostOp ( intrinsic_name ) ,
6874 } ;
6975
7076 for i in 0 ..dest_len {
@@ -89,7 +95,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8995 FloatTy :: F128 => unimplemented ! ( "f16_f128" ) ,
9096 }
9197 }
92- Op :: Sqrt => {
98+ Op :: HostOp ( host_op ) => {
9399 let ty:: Float ( float_ty) = op. layout . ty . kind ( ) else {
94100 span_bug ! ( this. cur_span( ) , "{} operand is not a float" , intrinsic_name)
95101 } ;
@@ -98,13 +104,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
98104 FloatTy :: F16 => unimplemented ! ( "f16_f128" ) ,
99105 FloatTy :: F32 => {
100106 let f = op. to_scalar ( ) . to_f32 ( ) ?;
101- let res = f. to_host ( ) . sqrt ( ) . to_soft ( ) ;
107+ let f_host = f. to_host ( ) ;
108+ let res = match host_op {
109+ "fsqrt" => f_host. sqrt ( ) ,
110+ "fsin" => f_host. sin ( ) ,
111+ "fcos" => f_host. cos ( ) ,
112+ "fexp" => f_host. exp ( ) ,
113+ "fexp2" => f_host. exp2 ( ) ,
114+ "flog" => f_host. ln ( ) ,
115+ "flog2" => f_host. log2 ( ) ,
116+ "flog10" => f_host. log10 ( ) ,
117+ _ => bug ! ( ) ,
118+ } ;
119+ let res = res. to_soft ( ) ;
102120 let res = this. adjust_nan ( res, & [ f] ) ;
103121 Scalar :: from ( res)
104122 }
105123 FloatTy :: F64 => {
106124 let f = op. to_scalar ( ) . to_f64 ( ) ?;
107- let res = f. to_host ( ) . sqrt ( ) . to_soft ( ) ;
125+ let f_host = f. to_host ( ) ;
126+ let res = match host_op {
127+ "fsqrt" => f_host. sqrt ( ) ,
128+ "fsin" => f_host. sin ( ) ,
129+ "fcos" => f_host. cos ( ) ,
130+ "fexp" => f_host. exp ( ) ,
131+ "fexp2" => f_host. exp2 ( ) ,
132+ "flog" => f_host. ln ( ) ,
133+ "flog2" => f_host. log2 ( ) ,
134+ "flog10" => f_host. log10 ( ) ,
135+ _ => bug ! ( ) ,
136+ } ;
137+ let res = res. to_soft ( ) ;
108138 let res = this. adjust_nan ( res, & [ f] ) ;
109139 Scalar :: from ( res)
110140 }
0 commit comments