Skip to content

Commit 451ac96

Browse files
committed
Fix some more stuff
1 parent 71b84cf commit 451ac96

File tree

5 files changed

+120
-25
lines changed

5 files changed

+120
-25
lines changed

example/mini_core.rs

+28
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ unsafe impl Copy for u8 {}
4444
unsafe impl Copy for u16 {}
4545
unsafe impl Copy for u32 {}
4646
unsafe impl Copy for u64 {}
47+
unsafe impl Copy for u128 {}
4748
unsafe impl Copy for usize {}
4849
unsafe impl Copy for i8 {}
4950
unsafe impl Copy for i16 {}
5051
unsafe impl Copy for i32 {}
52+
unsafe impl Copy for i128 {}
5153
unsafe impl Copy for isize {}
5254
unsafe impl Copy for char {}
5355
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
@@ -144,6 +146,14 @@ impl Add for u128 {
144146
}
145147
}
146148

149+
impl Add for i128 {
150+
type Output = Self;
151+
152+
fn add(self, rhs: Self) -> Self {
153+
self + rhs
154+
}
155+
}
156+
147157
#[lang = "sub"]
148158
pub trait Sub<RHS = Self> {
149159
type Output;
@@ -244,6 +254,15 @@ impl PartialEq for i32 {
244254
}
245255
}
246256

257+
impl PartialEq for i128 {
258+
fn eq(&self, other: &i128) -> bool {
259+
(*self) == (*other)
260+
}
261+
fn ne(&self, other: &i128) -> bool {
262+
(*self) != (*other)
263+
}
264+
}
265+
247266
impl PartialEq for isize {
248267
fn eq(&self, other: &isize) -> bool {
249268
(*self) == (*other)
@@ -278,6 +297,14 @@ pub trait Neg {
278297
fn neg(self) -> Self::Output;
279298
}
280299

300+
impl Neg for i128 {
301+
type Output = i128;
302+
303+
fn neg(self) -> i128 {
304+
-self
305+
}
306+
}
307+
281308
impl Neg for isize {
282309
type Output = isize;
283310

@@ -398,6 +425,7 @@ pub mod intrinsics {
398425
pub fn needs_drop<T>() -> bool;
399426
pub fn bitreverse<T>(x: T) -> T;
400427
pub fn bswap<T>(x: T) -> T;
428+
pub fn unchecked_div<T>(lhs: T, rhs: T) -> T;
401429
}
402430
}
403431

example/mini_core_hello_world.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,22 @@ impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsiz
117117
fn take_f32(_f: f32) {}
118118
fn take_unique(_u: Unique<()>) {}
119119

120-
fn main() {
120+
fn checked_div_i128(lhs: i128, rhs: i128) -> Option<i128> {
121+
if rhs == 0 || (lhs == -170141183460469231731687303715884105728 && rhs == -1) {
122+
None
123+
} else {
124+
Some(unsafe { intrinsics::unchecked_div(lhs, rhs) })
125+
}
126+
}
121127

128+
fn checked_div_u128(lhs: u128, rhs: u128) -> Option<u128> {
129+
match rhs {
130+
0 => None,
131+
rhs => Some(unsafe { intrinsics::unchecked_div(lhs, rhs) })
132+
}
133+
}
134+
135+
fn main() {
136+
checked_div_i128(0i128, 2i128);
137+
checked_div_u128(0u128, 2u128);
122138
}

src/base.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,28 @@ fn trans_stmt<'a, 'tcx: 'a>(
357357
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
358358
fx.bcx.ins().bint(types::I8, res)
359359
}
360-
ty::Uint(_) | ty::Int(_) => fx.bcx.ins().bnot(val),
360+
ty::Uint(_) | ty::Int(_) => {
361+
if fx.bcx.func.dfg.value_type(val) == types::I128 {
362+
let (a, b) = fx.bcx.ins().isplit(val);
363+
let a = fx.bcx.ins().bnot(a);
364+
let b = fx.bcx.ins().bnot(b);
365+
fx.bcx.ins().iconcat(a, b)
366+
} else {
367+
fx.bcx.ins().bnot(val)
368+
}
369+
}
361370
_ => unimplemented!("un op Not for {:?}", layout.ty),
362371
}
363372
}
364373
UnOp::Neg => match layout.ty.sty {
365374
ty::Int(_) => {
366375
let clif_ty = fx.clif_type(layout.ty).unwrap();
367-
let zero = fx.bcx.ins().iconst(clif_ty, 0);
368-
fx.bcx.ins().isub(zero, val)
376+
if clif_ty == types::I128 {
377+
crate::trap::trap_unreachable_ret_value(fx, layout, "i128 neg is not yet supported").load_scalar(fx)
378+
} else {
379+
let zero = fx.bcx.ins().iconst(clif_ty, 0);
380+
fx.bcx.ins().isub(zero, val)
381+
}
369382
}
370383
ty::Float(_) => fx.bcx.ins().fneg(val),
371384
_ => unimplemented!("un op Neg for {:?}", layout.ty),

src/common.rs

+35-19
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,42 @@ pub fn clif_intcast<'a, 'tcx: 'a>(
8282
if from == to {
8383
return val;
8484
}
85-
if to == types::I128 {
86-
let wider = if signed {
87-
fx.bcx.ins().sextend(types::I64, val)
88-
} else {
89-
fx.bcx.ins().uextend(types::I64, val)
90-
};
91-
let zero = fx.bcx.ins().iconst(types::I64, 0);
92-
return fx.bcx.ins().iconcat(wider, zero);
93-
}
94-
if to.wider_or_equal(from) {
95-
if signed {
96-
fx.bcx.ins().sextend(to, val)
97-
} else {
98-
fx.bcx.ins().uextend(to, val)
85+
match (from, to) {
86+
// equal
87+
(_, _) if from == to => val,
88+
89+
// extend
90+
(_, types::I128) => {
91+
let wider = if from == types::I64 {
92+
val
93+
} else if signed {
94+
fx.bcx.ins().sextend(types::I64, val)
95+
} else {
96+
fx.bcx.ins().uextend(types::I64, val)
97+
};
98+
let zero = fx.bcx.ins().iconst(types::I64, 0);
99+
fx.bcx.ins().iconcat(wider, zero)
100+
}
101+
(_, _) if to.wider_or_equal(from) => {
102+
if signed {
103+
fx.bcx.ins().sextend(to, val)
104+
} else {
105+
fx.bcx.ins().uextend(to, val)
106+
}
107+
}
108+
109+
// reduce
110+
(types::I128, _) => {
111+
let (lsb, _msb) = fx.bcx.ins().isplit(val);
112+
if to == types::I64 {
113+
lsb
114+
} else {
115+
fx.bcx.ins().ireduce(to, lsb)
116+
}
117+
}
118+
(_, _) => {
119+
fx.bcx.ins().ireduce(to, val)
99120
}
100-
} else if from == types::I128 {
101-
let (lsb, _msb) = fx.bcx.ins().isplit(val);
102-
fx.bcx.ins().ireduce(to, lsb)
103-
} else {
104-
fx.bcx.ins().ireduce(to, val)
105121
}
106122
}
107123

src/intrinsics.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,33 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
390390
fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count);
391391
};
392392
ctlz | ctlz_nonzero, <T> (v arg) {
393-
let res = CValue::by_val(fx.bcx.ins().clz(arg), fx.layout_of(T));
393+
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
394+
// FIXME verify this algorithm is correct
395+
let (lsb, msb) = fx.bcx.ins().isplit(arg);
396+
let lsb_lz = fx.bcx.ins().clz(lsb);
397+
let msb_lz = fx.bcx.ins().clz(msb);
398+
let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64);
399+
let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64);
400+
fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz)
401+
} else {
402+
fx.bcx.ins().clz(arg)
403+
};
404+
let res = CValue::by_val(res, fx.layout_of(T));
394405
ret.write_cvalue(fx, res);
395406
};
396407
cttz | cttz_nonzero, <T> (v arg) {
397-
let res = CValue::by_val(fx.bcx.ins().ctz(arg), fx.layout_of(T));
408+
let res = if T == fx.tcx.types.u128 || T == fx.tcx.types.i128 {
409+
// FIXME verify this algorithm is correct
410+
let (lsb, msb) = fx.bcx.ins().isplit(arg);
411+
let lsb_tz = fx.bcx.ins().ctz(lsb);
412+
let msb_tz = fx.bcx.ins().ctz(msb);
413+
let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64);
414+
let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
415+
fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz)
416+
} else {
417+
fx.bcx.ins().ctz(arg)
418+
};
419+
let res = CValue::by_val(res, fx.layout_of(T));
398420
ret.write_cvalue(fx, res);
399421
};
400422
ctpop, <T> (v arg) {

0 commit comments

Comments
 (0)