]> git.lizzy.rs Git - rust.git/blob - src/cast.rs
Fix simd_cast
[rust.git] / src / cast.rs
1 use crate::prelude::*;
2
3 pub fn clif_intcast<'a, 'tcx: 'a>(
4     fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
5     val: Value,
6     to: Type,
7     signed: bool,
8 ) -> Value {
9     let from = fx.bcx.func.dfg.value_type(val);
10     match (from, to) {
11         // equal
12         (_, _) if from == to => val,
13
14         // extend
15         (_, types::I128) => {
16             let wider = if from == types::I64 {
17                 val
18             } else if signed {
19                 fx.bcx.ins().sextend(types::I64, val)
20             } else {
21                 fx.bcx.ins().uextend(types::I64, val)
22             };
23             let zero = fx.bcx.ins().iconst(types::I64, 0);
24             fx.bcx.ins().iconcat(wider, zero)
25         }
26         (_, _) if to.wider_or_equal(from) => {
27             if signed {
28                 fx.bcx.ins().sextend(to, val)
29             } else {
30                 fx.bcx.ins().uextend(to, val)
31             }
32         }
33
34         // reduce
35         (types::I128, _) => {
36             let (lsb, _msb) = fx.bcx.ins().isplit(val);
37             if to == types::I64 {
38                 lsb
39             } else {
40                 fx.bcx.ins().ireduce(to, lsb)
41             }
42         }
43         (_, _) => {
44             fx.bcx.ins().ireduce(to, val)
45         }
46     }
47 }
48
49 pub fn clif_int_or_float_cast(
50     fx: &mut FunctionCx<'_, '_, impl Backend>,
51     from: Value,
52     to_ty: Type,
53     signed: bool,
54 ) -> Value {
55     let from_ty = fx.bcx.func.dfg.value_type(from);
56
57     if from_ty.is_int() && to_ty.is_int() {
58         // int-like -> int-like
59         clif_intcast(
60             fx,
61             from,
62             to_ty,
63             signed,
64         )
65     } else if from_ty.is_int() && to_ty.is_float() {
66         // int-like -> float
67         if signed {
68             fx.bcx.ins().fcvt_from_sint(to_ty, from)
69         } else {
70             fx.bcx.ins().fcvt_from_uint(to_ty, from)
71         }
72     } else if from_ty.is_float() && to_ty.is_int() {
73         // float -> int-like
74         if signed {
75             fx.bcx.ins().fcvt_to_sint_sat(to_ty, from)
76         } else {
77             fx.bcx.ins().fcvt_to_uint_sat(to_ty, from)
78         }
79     } else if from_ty.is_float() && to_ty.is_float() {
80         // float -> float
81         match (from_ty, to_ty) {
82             (types::F32, types::F64) => {
83                 fx.bcx.ins().fpromote(types::F64, from)
84             }
85             (types::F64, types::F32) => {
86                 fx.bcx.ins().fdemote(types::F32, from)
87             }
88             _ => from,
89         }
90     } else {
91         unreachable!("cast value from {:?} to {:?}", from_ty, to_ty);
92     }
93 }