Fix some more stuff
This commit is contained in:
parent
79f4c3d002
commit
45de0336a5
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
19
src/base.rs
19
src/base.rs
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user