Fix some more stuff

This commit is contained in:
bjorn3 2019-06-29 16:43:20 +02:00
parent 79f4c3d002
commit 45de0336a5
5 changed files with 121 additions and 26 deletions

View File

@ -44,10 +44,12 @@ unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for u128 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for i128 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
@ -152,6 +154,14 @@ impl Add for u128 {
}
}
impl Add for i128 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
self + rhs
}
}
#[lang = "sub"]
pub trait Sub<RHS = Self> {
type Output;
@ -276,6 +286,15 @@ impl PartialEq for i32 {
}
}
impl PartialEq for i128 {
fn eq(&self, other: &i128) -> bool {
(*self) == (*other)
}
fn ne(&self, other: &i128) -> bool {
(*self) != (*other)
}
}
impl PartialEq for isize {
fn eq(&self, other: &isize) -> bool {
(*self) == (*other)
@ -322,6 +341,14 @@ impl Neg for i16 {
type Output = i16;
fn neg(self) -> i16 {
self
}
}
impl Neg for i128 {
type Output = i128;
fn neg(self) -> i128 {
-self
}
}
@ -446,6 +473,7 @@ pub mod intrinsics {
pub fn needs_drop<T>() -> bool;
pub fn bitreverse<T>(x: T) -> T;
pub fn bswap<T>(x: T) -> T;
pub fn unchecked_div<T>(lhs: T, rhs: T) -> T;
}
}

View File

@ -117,6 +117,22 @@ impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsiz
fn take_f32(_f: f32) {}
fn take_unique(_u: Unique<()>) {}
fn main() {
fn checked_div_i128(lhs: i128, rhs: i128) -> Option<i128> {
if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) {
None
} else {
Some(unsafe { intrinsics::unchecked_div(lhs, rhs) })
}
}
fn checked_div_u128(lhs: u128, rhs: u128) -> Option<u128> {
match rhs {
0 => None,
rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) })
}
}
fn main() {
checked_div_i128(0i128, 2i128);
checked_div_u128(0u128, 2u128);
}

View File

@ -357,15 +357,28 @@ fn trans_stmt<'a, 'tcx: 'a>(
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
fx.bcx.ins().bint(types::I8, res)
}
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val),
ty::Uint(_) | ty::Int(_) => {
if fx.bcx.func.dfg.value_type(val) == types::I128 {
let (a, b) = fx.bcx.ins().isplit(val);
let a = fx.bcx.ins().bnot(a);
let b = fx.bcx.ins().bnot(b);
fx.bcx.ins().iconcat(a, b)
} else {
fx.bcx.ins().bnot(val)
}
}
_ => unimplemented!("un op Not for {:?}", layout.ty),
}
}
UnOp::Neg => match layout.ty.sty {
ty::Int(_) => {
let clif_ty = fx.clif_type(layout.ty).unwrap();
let zero = fx.bcx.ins().iconst(clif_ty, 0);
fx.bcx.ins().isub(zero, val)
if clif_ty == types::I128 {
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)
}
}
ty::Float(_) => fx.bcx.ins().fneg(val),
_ => unimplemented!("un op Neg for {:?}", layout.ty),

View File

@ -82,26 +82,42 @@ pub fn clif_intcast<'a, 'tcx: 'a>(
if from == to {
return val;
}
if to == types::I128 {
let wider = if signed {
fx.bcx.ins().sextend(types::I64, val)
} else {
fx.bcx.ins().uextend(types::I64, val)
};
let zero = fx.bcx.ins().iconst(types::I64, 0);
return fx.bcx.ins().iconcat(wider, zero);
}
if to.wider_or_equal(from) {
if signed {
fx.bcx.ins().sextend(to, val)
} else {
fx.bcx.ins().uextend(to, val)
match (from, to) {
// equal
(_, _) if from == to => val,
// extend
(_, types::I128) => {
let wider = if from == types::I64 {
val
} else if signed {
fx.bcx.ins().sextend(types::I64, val)
} else {
fx.bcx.ins().uextend(types::I64, val)
};
let zero = fx.bcx.ins().iconst(types::I64, 0);
fx.bcx.ins().iconcat(wider, zero)
}
(_, _) if to.wider_or_equal(from) => {
if signed {
fx.bcx.ins().sextend(to, val)
} else {
fx.bcx.ins().uextend(to, val)
}
}
// reduce
(types::I128, _) => {
let (lsb, _msb) = fx.bcx.ins().isplit(val);
if to == types::I64 {
lsb
} else {
fx.bcx.ins().ireduce(to, lsb)
}
}
(_, _) => {
fx.bcx.ins().ireduce(to, val)
}
} else if from == types::I128 {
let (lsb, _msb) = fx.bcx.ins().isplit(val);
fx.bcx.ins().ireduce(to, lsb)
} else {
fx.bcx.ins().ireduce(to, val)
}
}

View File

@ -390,11 +390,33 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count);
};
ctlz | ctlz_nonzero, <T> (v arg) {
let res = CValue::by_val(fx.bcx.ins().clz(arg), fx.layout_of(T));
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
// FIXME verify this algorithm is correct
let (lsb, msb) = fx.bcx.ins().isplit(arg);
let lsb_lz = fx.bcx.ins().clz(lsb);
let msb_lz = fx.bcx.ins().clz(msb);
let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64);
let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64);
fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz)
} else {
fx.bcx.ins().clz(arg)
};
let res = CValue::by_val(res, fx.layout_of(T));
ret.write_cvalue(fx, res);
};
cttz | cttz_nonzero, <T> (v arg) {
let res = CValue::by_val(fx.bcx.ins().ctz(arg), fx.layout_of(T));
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
// FIXME verify this algorithm is correct
let (lsb, msb) = fx.bcx.ins().isplit(arg);
let lsb_tz = fx.bcx.ins().ctz(lsb);
let msb_tz = fx.bcx.ins().ctz(msb);
let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64);
let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz)
} else {
fx.bcx.ins().ctz(arg)
};
let res = CValue::by_val(res, fx.layout_of(T));
ret.write_cvalue(fx, res);
};
ctpop, <T> (v arg) {