1
1
use rustc_apfloat:: { Float , Round } ;
2
2
use rustc_middle:: ty:: layout:: { HasParamEnv , LayoutOf } ;
3
3
use rustc_middle:: { mir, ty, ty:: FloatTy } ;
4
+ use rustc_span:: { sym, Symbol } ;
4
5
use rustc_target:: abi:: { Endian , HasDataLayout } ;
5
6
6
7
use crate :: * ;
@@ -25,7 +26,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
25
26
| "floor"
26
27
| "round"
27
28
| "trunc"
28
- | "fsqrt" => {
29
+ | "fsqrt"
30
+ | "ctlz"
31
+ | "cttz"
32
+ => {
29
33
let [ op] = check_arg_count ( args) ?;
30
34
let ( op, op_len) = this. operand_to_simd ( op) ?;
31
35
let ( dest, dest_len) = this. place_to_simd ( dest) ?;
@@ -38,6 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
38
42
Abs ,
39
43
Sqrt ,
40
44
Round ( rustc_apfloat:: Round ) ,
45
+ Numeric ( Symbol ) ,
41
46
}
42
47
let which = match intrinsic_name {
43
48
"neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
@@ -47,6 +52,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
47
52
"floor" => Op :: Round ( rustc_apfloat:: Round :: TowardNegative ) ,
48
53
"round" => Op :: Round ( rustc_apfloat:: Round :: NearestTiesToAway ) ,
49
54
"trunc" => Op :: Round ( rustc_apfloat:: Round :: TowardZero ) ,
55
+ "ctlz" => Op :: Numeric ( sym:: ctlz) ,
56
+ "cttz" => Op :: Numeric ( sym:: cttz) ,
50
57
_ => unreachable ! ( ) ,
51
58
} ;
52
59
@@ -101,6 +108,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
101
108
}
102
109
}
103
110
}
111
+ Op :: Numeric ( name) => {
112
+ assert ! ( op. layout. ty. is_integral( ) ) ;
113
+ let size = op. layout . size ;
114
+ let bits = op. to_scalar ( ) . to_bits ( size) . unwrap ( ) ;
115
+ let extra = 128u128 . checked_sub ( u128:: from ( size. bits ( ) ) ) . unwrap ( ) ;
116
+ let bits_out = match name {
117
+ sym:: ctlz => u128:: from ( bits. leading_zeros ( ) ) . checked_sub ( extra) . unwrap ( ) ,
118
+ sym:: cttz => u128:: from ( ( bits << extra) . trailing_zeros ( ) ) . checked_sub ( extra) . unwrap ( ) ,
119
+ _ => unreachable ! ( ) ,
120
+ } ;
121
+ Scalar :: from_uint ( bits_out, size)
122
+ }
104
123
} ;
105
124
this. write_scalar ( val, & dest) ?;
106
125
}
@@ -126,7 +145,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
126
145
| "fmin"
127
146
| "saturating_add"
128
147
| "saturating_sub"
129
- | "arith_offset" => {
148
+ | "arith_offset"
149
+ => {
130
150
use mir:: BinOp ;
131
151
132
152
let [ left, right] = check_arg_count ( args) ?;
0 commit comments