3
3
//! and miri.
4
4
5
5
use rustc_hir:: def_id:: DefId ;
6
- use rustc_middle:: mir:: {
7
- self ,
8
- interpret:: { Allocation , ConstAllocation , GlobalId , InterpResult , PointerArithmetic , Scalar } ,
9
- BinOp , ConstValue , NonDivergingIntrinsic ,
10
- } ;
11
6
use rustc_middle:: ty;
12
7
use rustc_middle:: ty:: layout:: { LayoutOf as _, ValidityRequirement } ;
13
8
use rustc_middle:: ty:: GenericArgsRef ;
14
9
use rustc_middle:: ty:: { Ty , TyCtxt } ;
10
+ use rustc_middle:: {
11
+ mir:: {
12
+ self ,
13
+ interpret:: {
14
+ Allocation , ConstAllocation , GlobalId , InterpResult , PointerArithmetic , Scalar ,
15
+ } ,
16
+ BinOp , ConstValue , NonDivergingIntrinsic ,
17
+ } ,
18
+ ty:: layout:: TyAndLayout ,
19
+ } ;
15
20
use rustc_span:: symbol:: { sym, Symbol } ;
16
- use rustc_target:: abi:: { Abi , Primitive , Size } ;
21
+ use rustc_target:: abi:: Size ;
17
22
18
23
use super :: {
19
24
util:: ensure_monomorphic_enough, CheckInAllocMsg , ImmTy , InterpCx , Machine , OpTy , PlaceTy ,
@@ -22,23 +27,6 @@ use super::{
22
27
23
28
use crate :: fluent_generated as fluent;
24
29
25
- fn numeric_intrinsic < Prov > ( name : Symbol , bits : u128 , kind : Primitive ) -> Scalar < Prov > {
26
- let size = match kind {
27
- Primitive :: Int ( integer, _) => integer. size ( ) ,
28
- _ => bug ! ( "invalid `{}` argument: {:?}" , name, bits) ,
29
- } ;
30
- let extra = 128 - u128:: from ( size. bits ( ) ) ;
31
- let bits_out = match name {
32
- sym:: ctpop => u128:: from ( bits. count_ones ( ) ) ,
33
- sym:: ctlz => u128:: from ( bits. leading_zeros ( ) ) - extra,
34
- sym:: cttz => u128:: from ( ( bits << extra) . trailing_zeros ( ) ) - extra,
35
- sym:: bswap => ( bits << extra) . swap_bytes ( ) ,
36
- sym:: bitreverse => ( bits << extra) . reverse_bits ( ) ,
37
- _ => bug ! ( "not a numeric intrinsic: {}" , name) ,
38
- } ;
39
- Scalar :: from_uint ( bits_out, size)
40
- }
41
-
42
30
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
43
31
pub ( crate ) fn alloc_type_name < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> ConstAllocation < ' tcx > {
44
32
let path = crate :: util:: type_name ( tcx, ty) ;
@@ -179,30 +167,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
179
167
| sym:: bswap
180
168
| sym:: bitreverse => {
181
169
let ty = instance_args. type_at ( 0 ) ;
182
- let layout_of = self . layout_of ( ty) ?;
170
+ let layout = self . layout_of ( ty) ?;
183
171
let val = self . read_scalar ( & args[ 0 ] ) ?;
184
- let bits = val. to_bits ( layout_of. size ) ?;
185
- let kind = match layout_of. abi {
186
- Abi :: Scalar ( scalar) => scalar. primitive ( ) ,
187
- _ => span_bug ! (
188
- self . cur_span( ) ,
189
- "{} called on invalid type {:?}" ,
190
- intrinsic_name,
191
- ty
192
- ) ,
193
- } ;
194
- let ( nonzero, actual_intrinsic_name) = match intrinsic_name {
195
- sym:: cttz_nonzero => ( true , sym:: cttz) ,
196
- sym:: ctlz_nonzero => ( true , sym:: ctlz) ,
197
- other => ( false , other) ,
198
- } ;
199
- if nonzero && bits == 0 {
200
- throw_ub_custom ! (
201
- fluent:: const_eval_call_nonzero_intrinsic,
202
- name = intrinsic_name,
203
- ) ;
204
- }
205
- let out_val = numeric_intrinsic ( actual_intrinsic_name, bits, kind) ;
172
+ let out_val = self . numeric_intrinsic ( intrinsic_name, val, layout) ?;
206
173
self . write_scalar ( out_val, dest) ?;
207
174
}
208
175
sym:: saturating_add | sym:: saturating_sub => {
@@ -493,6 +460,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
493
460
}
494
461
}
495
462
463
+ pub fn numeric_intrinsic (
464
+ & self ,
465
+ name : Symbol ,
466
+ val : Scalar < M :: Provenance > ,
467
+ layout : TyAndLayout < ' tcx > ,
468
+ ) -> InterpResult < ' tcx , Scalar < M :: Provenance > > {
469
+ assert ! ( layout. ty. is_integral( ) , "invalid type for numeric intrinsic: {}" , layout. ty) ;
470
+ let bits = val. to_bits ( layout. size ) ?;
471
+ let extra = 128 - u128:: from ( layout. size . bits ( ) ) ;
472
+ let bits_out = match name {
473
+ sym:: ctpop => u128:: from ( bits. count_ones ( ) ) ,
474
+ sym:: ctlz_nonzero | sym:: cttz_nonzero if bits == 0 => {
475
+ throw_ub_custom ! ( fluent:: const_eval_call_nonzero_intrinsic, name = name, ) ;
476
+ }
477
+ sym:: ctlz | sym:: ctlz_nonzero => u128:: from ( bits. leading_zeros ( ) ) - extra,
478
+ sym:: cttz | sym:: cttz_nonzero => u128:: from ( ( bits << extra) . trailing_zeros ( ) ) - extra,
479
+ sym:: bswap => ( bits << extra) . swap_bytes ( ) ,
480
+ sym:: bitreverse => ( bits << extra) . reverse_bits ( ) ,
481
+ _ => bug ! ( "not a numeric intrinsic: {}" , name) ,
482
+ } ;
483
+ Ok ( Scalar :: from_uint ( bits_out, layout. size ) )
484
+ }
485
+
496
486
pub fn exact_div (
497
487
& mut self ,
498
488
a : & ImmTy < ' tcx , M :: Provenance > ,
0 commit comments