mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-18 03:25:55 +00:00
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.
This commit is contained in:
parent
b5d29a8c58
commit
6129921529
27
src/base.rs
27
src/base.rs
@ -313,33 +313,26 @@ fn trans_stmt<'tcx>(
|
|||||||
ty::Bool => {
|
ty::Bool => {
|
||||||
let val = fx.bcx.ins().uextend(types::I32, val); // WORKAROUND for CraneStation/cranelift#466
|
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);
|
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),
|
_ => unimplemented!("un op Not for {:?}", layout.ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnOp::Neg => match layout.ty.kind {
|
UnOp::Neg => match layout.ty.kind {
|
||||||
ty::Int(_) => {
|
ty::Int(_) => {
|
||||||
let clif_ty = fx.clif_type(layout.ty).unwrap();
|
let zero = CValue::const_val(fx, layout.ty, 0);
|
||||||
if clif_ty == types::I128 {
|
crate::num::trans_int_binop(fx, BinOp::Sub, zero, operand)
|
||||||
// FIXME implement it
|
}
|
||||||
crate::trap::trap_unreachable_ret_value(
|
ty::Float(_) => {
|
||||||
fx,
|
CValue::by_val(fx.bcx.ins().fneg(val), layout)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::Float(_) => fx.bcx.ins().fneg(val),
|
|
||||||
_ => unimplemented!("un op Neg for {:?}", layout.ty),
|
_ => 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) => {
|
Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), operand, ty) => {
|
||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
|
@ -98,7 +98,7 @@ pub fn maybe_codegen<'tcx>(
|
|||||||
// Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit
|
// Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit
|
||||||
// integer into its lsb and msb.
|
// integer into its lsb and msb.
|
||||||
// https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217
|
// 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 (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val);
|
||||||
let all_zeros = fx.bcx.ins().iconst(types::I64, 0);
|
let all_zeros = fx.bcx.ins().iconst(types::I64, 0);
|
||||||
let val = match (bin_op, is_signed) {
|
let val = match (bin_op, is_signed) {
|
||||||
|
@ -700,11 +700,29 @@ pub fn codegen_intrinsic_call<'tcx>(
|
|||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
};
|
};
|
||||||
ctpop, <T> (v arg) {
|
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);
|
ret.write_cvalue(fx, res);
|
||||||
};
|
};
|
||||||
bitreverse, <T> (v arg) {
|
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);
|
ret.write_cvalue(fx, res);
|
||||||
};
|
};
|
||||||
bswap, <T> (v arg) {
|
bswap, <T> (v arg) {
|
||||||
|
Loading…
Reference in New Issue
Block a user