@@ -33,6 +33,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
33
33
| "round"
34
34
| "trunc"
35
35
| "fsqrt"
36
+ | "fsin"
37
+ | "fcos"
38
+ | "fexp"
39
+ | "fexp2"
40
+ | "flog"
41
+ | "flog2"
42
+ | "flog10"
36
43
| "ctlz"
37
44
| "cttz"
38
45
| "bswap"
@@ -45,17 +52,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
45
52
assert_eq ! ( dest_len, op_len) ;
46
53
47
54
#[ derive( Copy , Clone ) ]
48
- enum Op {
55
+ enum Op < ' a > {
49
56
MirOp ( mir:: UnOp ) ,
50
57
Abs ,
51
- Sqrt ,
52
58
Round ( rustc_apfloat:: Round ) ,
53
59
Numeric ( Symbol ) ,
60
+ HostOp ( & ' a str ) ,
54
61
}
55
62
let which = match intrinsic_name {
56
63
"neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
57
64
"fabs" => Op :: Abs ,
58
- "fsqrt" => Op :: Sqrt ,
59
65
"ceil" => Op :: Round ( rustc_apfloat:: Round :: TowardPositive ) ,
60
66
"floor" => Op :: Round ( rustc_apfloat:: Round :: TowardNegative ) ,
61
67
"round" => Op :: Round ( rustc_apfloat:: Round :: NearestTiesToAway ) ,
@@ -64,7 +70,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
64
70
"cttz" => Op :: Numeric ( sym:: cttz) ,
65
71
"bswap" => Op :: Numeric ( sym:: bswap) ,
66
72
"bitreverse" => Op :: Numeric ( sym:: bitreverse) ,
67
- _ => unreachable ! ( ) ,
73
+ _ => Op :: HostOp ( intrinsic_name ) ,
68
74
} ;
69
75
70
76
for i in 0 ..dest_len {
@@ -89,7 +95,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
89
95
FloatTy :: F128 => unimplemented ! ( "f16_f128" ) ,
90
96
}
91
97
}
92
- Op :: Sqrt => {
98
+ Op :: HostOp ( host_op ) => {
93
99
let ty:: Float ( float_ty) = op. layout . ty . kind ( ) else {
94
100
span_bug ! ( this. cur_span( ) , "{} operand is not a float" , intrinsic_name)
95
101
} ;
@@ -98,13 +104,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
98
104
FloatTy :: F16 => unimplemented ! ( "f16_f128" ) ,
99
105
FloatTy :: F32 => {
100
106
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 ( ) ;
102
120
let res = this. adjust_nan ( res, & [ f] ) ;
103
121
Scalar :: from ( res)
104
122
}
105
123
FloatTy :: F64 => {
106
124
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 ( ) ;
108
138
let res = this. adjust_nan ( res, & [ f] ) ;
109
139
Scalar :: from ( res)
110
140
}
0 commit comments