]> git.lizzy.rs Git - rust.git/commitdiff
More 128bit support
authorbjorn3 <bjorn3@users.noreply.github.com>
Sun, 6 Oct 2019 13:51:43 +0000 (15:51 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Sun, 6 Oct 2019 13:51:43 +0000 (15:51 +0200)
* UnOp::Neg
* ctpop
* bitreverse

Also replaces `if let Some(64u128) = ...` with `if ... = Some(u64u128)`
to be able to compile cg_clif using cg_clif, as cranelift_frontend::Switch
doesn't support i128 yet.

src/base.rs
src/codegen_i128.rs
src/intrinsics.rs

index 96f3b783d91701166ca5bfff6719d64bf5e1079c..1a78f33ae7363f250a1eaf32f9654c4874ef036a 100644 (file)
@@ -313,33 +313,26 @@ fn trans_stmt<'tcx>(
                                 ty::Bool => {
                                     let val = fx.bcx.ins().uextend(types::I32, val); // WORKAROUND for CraneStation/cranelift#466
                                     let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
-                                    fx.bcx.ins().bint(types::I8, res)
+                                    CValue::by_val(fx.bcx.ins().bint(types::I8, res), layout)
+                                }
+                                ty::Uint(_) | ty::Int(_) => {
+                                    CValue::by_val(fx.bcx.ins().bnot(val), layout)
                                 }
-                                ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val),
                                 _ => unimplemented!("un op Not for {:?}", layout.ty),
                             }
                         }
                         UnOp::Neg => match layout.ty.kind {
                             ty::Int(_) => {
-                                let clif_ty = fx.clif_type(layout.ty).unwrap();
-                                if clif_ty == types::I128 {
-                                    // FIXME implement it
-                                    crate::trap::trap_unreachable_ret_value(
-                                        fx,
-                                        layout,
-                                        "i128 neg is not yet supported",
-                                    )
-                                    .load_scalar(fx)
-                                } else {
-                                    let zero = fx.bcx.ins().iconst(clif_ty, 0);
-                                    fx.bcx.ins().isub(zero, val)
-                                }
+                                let zero = CValue::const_val(fx, layout.ty, 0);
+                                crate::num::trans_int_binop(fx, BinOp::Sub, zero, operand)
+                            }
+                            ty::Float(_) => {
+                                CValue::by_val(fx.bcx.ins().fneg(val), layout)
                             }
-                            ty::Float(_) => fx.bcx.ins().fneg(val),
                             _ => unimplemented!("un op Neg for {:?}", layout.ty),
                         },
                     };
-                    lval.write_cvalue(fx, CValue::by_val(res, layout));
+                    lval.write_cvalue(fx, res);
                 }
                 Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), operand, ty) => {
                     let layout = fx.layout_of(ty);
index 6653b4e2d91f558fb389ce98e0a4d05e2986da15..be0ed1668f8595f85a4a99fe8e39dcf1693598e9 100644 (file)
@@ -98,7 +98,7 @@ pub fn maybe_codegen<'tcx>(
             // Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit
             // integer into its lsb and msb.
             // https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217
-            if let Some(64) = resolve_value_imm(fx.bcx.func, rhs_val) {
+            if  resolve_value_imm(fx.bcx.func, rhs_val) == Some(64) {
                 let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val);
                 let all_zeros = fx.bcx.ins().iconst(types::I64, 0);
                 let val = match (bin_op, is_signed) {
index 44aa2151a75410722ee4bf069a72b2f994ac6e6e..0910b878890cb569194238f104047080ab265e3f 100644 (file)
@@ -700,11 +700,29 @@ pub fn codegen_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, res);
         };
         ctpop, <T> (v arg) {
-            let res = CValue::by_val(fx.bcx.ins().popcnt(arg), fx.layout_of(T));
+            let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
+                let (lo, hi) = fx.bcx.ins().isplit(arg);
+                let lo_popcnt = fx.bcx.ins().popcnt(lo);
+                let hi_popcnt = fx.bcx.ins().popcnt(hi);
+                let popcnt = fx.bcx.ins().iadd(lo_popcnt, hi_popcnt);
+                crate::cast::clif_intcast(fx, popcnt, types::I128, false)
+            } else {
+                fx.bcx.ins().popcnt(arg)
+            };
+            let res = CValue::by_val(res, fx.layout_of(T));
             ret.write_cvalue(fx, res);
         };
         bitreverse, <T> (v arg) {
-            let res = CValue::by_val(fx.bcx.ins().bitrev(arg), fx.layout_of(T));
+            let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
+                let (lo, hi) = fx.bcx.ins().isplit(arg);
+                let lo_bitrev = fx.bcx.ins().bitrev(lo);
+                let hi_bitrev = fx.bcx.ins().bitrev(hi);
+                let bitrev = fx.bcx.ins().iconcat(hi_bitrev, lo_bitrev);
+                crate::cast::clif_intcast(fx, bitrev, types::I128, false)
+            } else {
+                fx.bcx.ins().bitrev(arg)
+            };
+            let res = CValue::by_val(res, fx.layout_of(T));
             ret.write_cvalue(fx, res);
         };
         bswap, <T> (v arg) {