Skip to content

Commit 93a15e6

Browse files
committed
Fix cast from u64 to i128
1 parent d5bf570 commit 93a15e6

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

gcc-test-backend/src/main.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,46 @@ fn main() {
214214
assert_eq!(r.saturating_pow(2), 4 as i128);
215215
assert_eq!(r.saturating_pow(3), -8 as i128);
216216
assert_eq!(r.saturating_pow(0), 1 as i128);*/
217+
218+
fn max64() -> i128 {
219+
18446744073709551615_u64 as i128
220+
221+
/*println!("{}", u64::MAX);
222+
u64::MAX as i128*/
223+
}
224+
225+
println!("1. {}", max64());
226+
227+
/*use std::convert::TryFrom;
228+
229+
fn try_from(u: i128) -> Option<u64> {
230+
let min = u64::MIN as i128;
231+
let max = u64::MAX as i128;
232+
/*println!("{} < {} == {}", u, min, u < min);
233+
println!("{} > {} == {}", u, max, u > max);*/
234+
if u < min || u > max {
235+
None
236+
} else {
237+
Some(u as u64)
238+
}
239+
}
240+
241+
let max = <i128>::MAX;
242+
let min = <i128>::MIN;
243+
let zero: i128 = 0;
244+
let t_max = <u64>::MAX;
245+
let t_min = <u64>::MIN;
246+
assert!(<u64 as TryFrom<i128>>::try_from(max).is_err());
247+
assert!(<u64 as TryFrom<i128>>::try_from(min).is_err());
248+
println!("{:?}", try_from(zero));
249+
println!("{:?}", <u64 as TryFrom<i128>>::try_from(zero));
250+
assert_eq!(<u64 as TryFrom<i128>>::try_from(zero).unwrap(), zero as u64);
251+
assert_eq!(
252+
<u64 as TryFrom<i128>>::try_from(t_max as i128).unwrap(),
253+
t_max as u64
254+
);
255+
assert_eq!(
256+
<u64 as TryFrom<i128>>::try_from(t_min as i128).unwrap(),
257+
t_min as u64
258+
);*/
217259
}

src/common.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,20 +128,28 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
128128
}
129129

130130
fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
131-
let num64: Result<u64, _> = num.try_into();
131+
println!("Num: {:?}", num);
132+
let num64: Result<i64, _> = num.try_into();
132133
if let Ok(num) = num64 {
134+
println!("1");
133135
// FIXME: workaround for a bug where libgccjit is expecting a constant.
134136
// The operations >> 64 and | low are making the normal case a non-constant.
135137
return self.context.new_rvalue_from_long(typ, num as i64);
136138
}
137139

138-
// FIXME: use a new function new_rvalue_from_unsigned_long()?
139-
let low = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
140-
let high = self.context.new_rvalue_from_long(typ, (num >> 64) as u64 as i64);
140+
if num >> 64 != 0 {
141+
println!("2");
142+
// FIXME: use a new function new_rvalue_from_unsigned_long()?
143+
let low = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
144+
let high = self.context.new_rvalue_from_long(typ, (num >> 64) as u64 as i64);
141145

142-
let sixty_four = self.context.new_rvalue_from_long(typ, 64);
143-
144-
(high << sixty_four) | self.context.new_cast(None, low, typ)
146+
let sixty_four = self.context.new_rvalue_from_long(typ, 64);
147+
(high << sixty_four) | self.context.new_cast(None, low, typ)
148+
}
149+
else {
150+
println!("3");
151+
self.context.new_rvalue_from_long(typ, num as u64 as i64)
152+
}
145153

146154
/*unsafe {
147155
let words = [u as u64, (u >> 64) as u64];

0 commit comments

Comments
 (0)