11use rustc_apfloat:: { Float , Round } ;
22use rustc_middle:: ty:: layout:: { HasParamEnv , LayoutOf } ;
33use rustc_middle:: { mir, ty, ty:: FloatTy } ;
4+ use rustc_span:: { sym, Symbol } ;
45use rustc_target:: abi:: { Endian , HasDataLayout } ;
56
67use crate :: * ;
@@ -25,7 +26,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2526 | "floor"
2627 | "round"
2728 | "trunc"
28- | "fsqrt" => {
29+ | "fsqrt"
30+ | "ctlz"
31+ | "cttz"
32+ => {
2933 let [ op] = check_arg_count ( args) ?;
3034 let ( op, op_len) = this. operand_to_simd ( op) ?;
3135 let ( dest, dest_len) = this. place_to_simd ( dest) ?;
@@ -38,6 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3842 Abs ,
3943 Sqrt ,
4044 Round ( rustc_apfloat:: Round ) ,
45+ Numeric ( Symbol ) ,
4146 }
4247 let which = match intrinsic_name {
4348 "neg" => Op :: MirOp ( mir:: UnOp :: Neg ) ,
@@ -47,6 +52,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4752 "floor" => Op :: Round ( rustc_apfloat:: Round :: TowardNegative ) ,
4853 "round" => Op :: Round ( rustc_apfloat:: Round :: NearestTiesToAway ) ,
4954 "trunc" => Op :: Round ( rustc_apfloat:: Round :: TowardZero ) ,
55+ "ctlz" => Op :: Numeric ( sym:: ctlz) ,
56+ "cttz" => Op :: Numeric ( sym:: cttz) ,
5057 _ => unreachable ! ( ) ,
5158 } ;
5259
@@ -101,6 +108,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
101108 }
102109 }
103110 }
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+ }
104123 } ;
105124 this. write_scalar ( val, & dest) ?;
106125 }
@@ -126,7 +145,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
126145 | "fmin"
127146 | "saturating_add"
128147 | "saturating_sub"
129- | "arith_offset" => {
148+ | "arith_offset"
149+ => {
130150 use mir:: BinOp ;
131151
132152 let [ left, right] = check_arg_count ( args) ?;
0 commit comments