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);
// 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) {
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) {