]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/interpret/mod.rs
0c921f66198eb88d7538e9c0fdc1d56cb5700bd6
[rust.git] / src / librustc_mir / interpret / mod.rs
1 //! An interpreter for MIR used in CTFE and by miri
2
3 mod cast;
4 mod const_eval;
5 mod eval_context;
6 mod place;
7 mod machine;
8 mod memory;
9 mod operator;
10 mod step;
11 mod terminator;
12 mod traits;
13
14 pub use self::eval_context::{EvalContext, Frame, StackPopCleanup,
15                              TyAndPacked, ValTy};
16
17 pub use self::place::{Place, PlaceExtra};
18
19 pub use self::memory::{Memory, MemoryKind, HasMemory};
20
21 pub use self::const_eval::{
22     eval_promoted,
23     mk_borrowck_eval_cx,
24     mk_eval_cx,
25     CompileTimeEvaluator,
26     const_value_to_allocation_provider,
27     const_eval_provider,
28     const_val_field,
29     const_variant_index,
30     value_to_const_value,
31 };
32
33 pub use self::machine::Machine;
34
35 pub use self::memory::{write_target_uint, write_target_int, read_target_uint};
36
37 use rustc::mir::interpret::{EvalResult, EvalErrorKind};
38 use rustc::ty::{Ty, TyCtxt, ParamEnv};
39
40 pub fn sign_extend<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
41     let param_env = ParamEnv::empty();
42     let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
43     let size = layout.size.bits();
44     assert!(layout.abi.is_signed());
45     // sign extend
46     let shift = 128 - size;
47     // shift the unsigned value to the left
48     // and back to the right as signed (essentially fills with FF on the left)
49     Ok((((value << shift) as i128) >> shift) as u128)
50 }
51
52 pub fn truncate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
53     let param_env = ParamEnv::empty();
54     let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
55     let size = layout.size.bits();
56     let shift = 128 - size;
57     // truncate (shift left to drop out leftover values, shift right to fill with zeroes)
58     Ok((value << shift) >> shift)
59 }