Skip to content

Commit 6129921

Browse files
committed
More 128bit support
* 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.
1 parent b5d29a8 commit 6129921

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

src/base.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -313,33 +313,26 @@ fn trans_stmt<'tcx>(
313313
ty::Bool => {
314314
let val = fx.bcx.ins().uextend(types::I32, val); // WORKAROUND for CraneStation/cranelift#466
315315
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
316-
fx.bcx.ins().bint(types::I8, res)
316+
CValue::by_val(fx.bcx.ins().bint(types::I8, res), layout)
317+
}
318+
ty::Uint(_) | ty::Int(_) => {
319+
CValue::by_val(fx.bcx.ins().bnot(val), layout)
317320
}
318-
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val),
319321
_ => unimplemented!("un op Not for {:?}", layout.ty),
320322
}
321323
}
322324
UnOp::Neg => match layout.ty.kind {
323325
ty::Int(_) => {
324-
let clif_ty = fx.clif_type(layout.ty).unwrap();
325-
if clif_ty == types::I128 {
326-
// FIXME implement it
327-
crate::trap::trap_unreachable_ret_value(
328-
fx,
329-
layout,
330-
"i128 neg is not yet supported",
331-
)
332-
.load_scalar(fx)
333-
} else {
334-
let zero = fx.bcx.ins().iconst(clif_ty, 0);
335-
fx.bcx.ins().isub(zero, val)
336-
}
326+
let zero = CValue::const_val(fx, layout.ty, 0);
327+
crate::num::trans_int_binop(fx, BinOp::Sub, zero, operand)
328+
}
329+
ty::Float(_) => {
330+
CValue::by_val(fx.bcx.ins().fneg(val), layout)
337331
}
338-
ty::Float(_) => fx.bcx.ins().fneg(val),
339332
_ => unimplemented!("un op Neg for {:?}", layout.ty),
340333
},
341334
};
342-
lval.write_cvalue(fx, CValue::by_val(res, layout));
335+
lval.write_cvalue(fx, res);
343336
}
344337
Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), operand, ty) => {
345338
let layout = fx.layout_of(ty);

src/codegen_i128.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn maybe_codegen<'tcx>(
9898
// Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit
9999
// integer into its lsb and msb.
100100
// https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217
101-
if let Some(64) = resolve_value_imm(fx.bcx.func, rhs_val) {
101+
if resolve_value_imm(fx.bcx.func, rhs_val) == Some(64) {
102102
let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val);
103103
let all_zeros = fx.bcx.ins().iconst(types::I64, 0);
104104
let val = match (bin_op, is_signed) {

src/intrinsics.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,29 @@ pub fn codegen_intrinsic_call<'tcx>(
700700
ret.write_cvalue(fx, res);
701701
};
702702
ctpop, <T> (v arg) {
703-
let res = CValue::by_val(fx.bcx.ins().popcnt(arg), fx.layout_of(T));
703+
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
704+
let (lo, hi) = fx.bcx.ins().isplit(arg);
705+
let lo_popcnt = fx.bcx.ins().popcnt(lo);
706+
let hi_popcnt = fx.bcx.ins().popcnt(hi);
707+
let popcnt = fx.bcx.ins().iadd(lo_popcnt, hi_popcnt);
708+
crate::cast::clif_intcast(fx, popcnt, types::I128, false)
709+
} else {
710+
fx.bcx.ins().popcnt(arg)
711+
};
712+
let res = CValue::by_val(res, fx.layout_of(T));
704713
ret.write_cvalue(fx, res);
705714
};
706715
bitreverse, <T> (v arg) {
707-
let res = CValue::by_val(fx.bcx.ins().bitrev(arg), fx.layout_of(T));
716+
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
717+
let (lo, hi) = fx.bcx.ins().isplit(arg);
718+
let lo_bitrev = fx.bcx.ins().bitrev(lo);
719+
let hi_bitrev = fx.bcx.ins().bitrev(hi);
720+
let bitrev = fx.bcx.ins().iconcat(hi_bitrev, lo_bitrev);
721+
crate::cast::clif_intcast(fx, bitrev, types::I128, false)
722+
} else {
723+
fx.bcx.ins().bitrev(arg)
724+
};
725+
let res = CValue::by_val(res, fx.layout_of(T));
708726
ret.write_cvalue(fx, res);
709727
};
710728
bswap, <T> (v arg) {

0 commit comments

Comments
 (0)