Skip to content

Commit 56fda23

Browse files
authored
Merge pull request #21 from antoyo/fix-oper-128bits
Fix oper 128bits
2 parents d7d84d3 + af70373 commit 56fda23

File tree

2 files changed

+91
-72
lines changed

2 files changed

+91
-72
lines changed

gcc-test-backend/src/main.rs

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#![feature(const_option)]
22

3-
use std::num::{NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize};
4-
53
fn main() {
64
/*test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN);
75
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => {*/
@@ -156,67 +154,86 @@ fn main() {
156154
println!();
157155
*/
158156

159-
assert_eq!(NonZeroU8::new(1).unwrap().trailing_zeros(), 0);
160-
assert_eq!(NonZeroI8::new(1).unwrap().trailing_zeros(), 0);
161-
assert_eq!(NonZeroU16::new(1).unwrap().trailing_zeros(), 0);
162-
assert_eq!(NonZeroI16::new(1).unwrap().trailing_zeros(), 0);
163-
assert_eq!(NonZeroU32::new(1).unwrap().trailing_zeros(), 0);
164-
assert_eq!(NonZeroI32::new(1).unwrap().trailing_zeros(), 0);
165-
assert_eq!(NonZeroU64::new(1).unwrap().trailing_zeros(), 0);
166-
assert_eq!(NonZeroI64::new(1).unwrap().trailing_zeros(), 0);
167-
assert_eq!(NonZeroU128::new(1).unwrap().trailing_zeros(), 0);
168-
assert_eq!(NonZeroI128::new(1).unwrap().trailing_zeros(), 0);
169-
assert_eq!(NonZeroUsize::new(1).unwrap().trailing_zeros(), 0);
170-
assert_eq!(NonZeroIsize::new(1).unwrap().trailing_zeros(), 0);
171-
172-
assert_eq!(NonZeroU8::new(1 << 2).unwrap().trailing_zeros(), 2);
173-
assert_eq!(NonZeroI8::new(1 << 2).unwrap().trailing_zeros(), 2);
174-
assert_eq!(NonZeroU16::new(1 << 2).unwrap().trailing_zeros(), 2);
175-
assert_eq!(NonZeroI16::new(1 << 2).unwrap().trailing_zeros(), 2);
176-
assert_eq!(NonZeroU32::new(1 << 2).unwrap().trailing_zeros(), 2);
177-
assert_eq!(NonZeroI32::new(1 << 2).unwrap().trailing_zeros(), 2);
178-
assert_eq!(NonZeroU64::new(1 << 2).unwrap().trailing_zeros(), 2);
179-
assert_eq!(NonZeroI64::new(1 << 2).unwrap().trailing_zeros(), 2);
180-
assert_eq!(NonZeroU128::new(1 << 2).unwrap().trailing_zeros(), 2);
181-
assert_eq!(NonZeroI128::new(1 << 2).unwrap().trailing_zeros(), 2);
182-
assert_eq!(NonZeroUsize::new(1 << 2).unwrap().trailing_zeros(), 2);
183-
assert_eq!(NonZeroIsize::new(1 << 2).unwrap().trailing_zeros(), 2);
184-
185-
assert_eq!(NonZeroU8::new(1 << 7).unwrap().trailing_zeros(), 7);
186-
assert_eq!(NonZeroI8::new(1 << 7).unwrap().trailing_zeros(), 7);
187-
assert_eq!(NonZeroU16::new(1 << 15).unwrap().trailing_zeros(), 15);
188-
assert_eq!(NonZeroI16::new(1 << 15).unwrap().trailing_zeros(), 15);
189-
assert_eq!(NonZeroU32::new(1 << 31).unwrap().trailing_zeros(), 31);
190-
assert_eq!(NonZeroI32::new(1 << 31).unwrap().trailing_zeros(), 31);
191-
assert_eq!(NonZeroU64::new(1 << 63).unwrap().trailing_zeros(), 63);
192-
assert_eq!(NonZeroI64::new(1 << 63).unwrap().trailing_zeros(), 63);
193-
assert_eq!(NonZeroU128::new(1 << 127).unwrap().trailing_zeros(), 127);
194-
assert_eq!(NonZeroI128::new(1 << 127).unwrap().trailing_zeros(), 127);
157+
/*let mut r = 2 as i128;
158+
assert_eq!(r.pow(2), 4 as i128);
159+
assert_eq!(r.pow(0), 1 as i128);
160+
assert_eq!(r.wrapping_pow(2), 4 as i128);
161+
assert_eq!(r.wrapping_pow(0), 1 as i128);
162+
assert_eq!(r.checked_pow(2), Some(4 as i128));
163+
assert_eq!(r.checked_pow(0), Some(1 as i128));
164+
assert_eq!(r.overflowing_pow(2), (4 as i128, false));
165+
assert_eq!(r.overflowing_pow(0), (1 as i128, false));
166+
assert_eq!(r.saturating_pow(2), 4 as i128);
167+
assert_eq!(r.saturating_pow(0), 1 as i128);
168+
169+
r = i128::MAX;
170+
// use `^` to represent .pow() with no overflow.
171+
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
172+
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
173+
// thussaturating_pow the overflowing result is exactly 1.
174+
assert_eq!(r.wrapping_pow(2), 1 as i128);
175+
assert_eq!(r.checked_pow(2), None);
176+
assert_eq!(r.overflowing_pow(2), (1 as i128, true));
177+
assert_eq!(r.saturating_pow(2), i128::MAX);
178+
//test for negative exponent.
179+
r = -2 as i128;
180+
assert_eq!(r.pow(2), 4 as i128);
181+
assert_eq!(r.pow(3), -8 as i128);
182+
assert_eq!(r.pow(0), 1 as i128);
183+
assert_eq!(r.wrapping_pow(2), 4 as i128);
184+
assert_eq!(r.wrapping_pow(3), -8 as i128);
185+
assert_eq!(r.wrapping_pow(0), 1 as i128);
186+
assert_eq!(r.checked_pow(2), Some(4 as i128));
187+
assert_eq!(r.checked_pow(3), Some(-8 as i128));
188+
assert_eq!(r.checked_pow(0), Some(1 as i128));
189+
assert_eq!(r.overflowing_pow(2), (4 as i128, false));
190+
assert_eq!(r.overflowing_pow(3), (-8 as i128, false));
191+
assert_eq!(r.overflowing_pow(0), (1 as i128, false));
192+
assert_eq!(r.saturating_pow(2), 4 as i128);
193+
assert_eq!(r.saturating_pow(3), -8 as i128);
194+
assert_eq!(r.saturating_pow(0), 1 as i128);*/
195+
196+
{
197+
const A: u128 = 0b0101100;
198+
const B: u128 = 0b0100001;
199+
const C: u128 = 0b1111001;
200+
201+
const _0: u128 = 0;
202+
const _1: u128 = !0;
203+
204+
assert_eq!(A.reverse_bits().reverse_bits(), A);
205+
assert_eq!(B.reverse_bits().reverse_bits(), B);
206+
assert_eq!(C.reverse_bits().reverse_bits(), C);
207+
208+
// Swapping these should make no difference
209+
assert_eq!(_0.reverse_bits(), _0);
210+
assert_eq!(_1.reverse_bits(), _1);
211+
}
195212

196-
assert_eq!(
197-
NonZeroUsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
198-
usize::BITS - 1
199-
);
200-
assert_eq!(
201-
NonZeroIsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
202-
usize::BITS - 1
203-
);
213+
const _0: i128 = 0;
214+
const _1: i128 = !0;
215+
216+
use std::i128::MAX;
217+
218+
let a: i128 = 0b0101_1111;
219+
assert_eq!(a.trailing_ones(), 5);
220+
assert_eq!((!a).leading_ones(), i128::BITS - 7);
221+
222+
assert_eq!(a.reverse_bits().leading_ones(), 5);
223+
224+
assert_eq!(_1.leading_ones(), i128::BITS);
225+
assert_eq!(_1.trailing_ones(), i128::BITS);
204226

205-
const TRAILING_ZEROS: u32 = NonZeroU16::new(1 << 2).unwrap().trailing_zeros();
206-
assert_eq!(TRAILING_ZEROS, 2);
227+
assert_eq!((_1 << 1).trailing_ones(), 0);
228+
assert_eq!(MAX.leading_ones(), 0);
207229

208-
const A: u128 = 0b0101100;
209-
const B: u128 = 0b0100001;
210-
const C: u128 = 0b1111001;
230+
assert_eq!((_1 << 1).leading_ones(), i128::BITS - 1);
231+
assert_eq!(MAX.trailing_ones(), i128::BITS - 1);
211232

212-
const _0: u128 = 0;
213-
const _1: u128 = !0;
233+
assert_eq!(_0.leading_ones(), 0);
234+
assert_eq!(_0.trailing_ones(), 0);
214235

215-
assert_eq!(u128::from_be(A.to_be()), A);
216-
assert_eq!(u128::from_be(B.to_be()), B);
217-
assert_eq!(u128::from_be(C.to_be()), C);
218-
assert_eq!(u128::from_be(_0), _0);
219-
assert_eq!(u128::from_be(_1), _1);
220-
assert_eq!(_0.to_be(), _0);
221-
assert_eq!(_1.to_be(), _1);
236+
let x: i128 = 0b0010_1100;
237+
assert_eq!(x.leading_ones(), 0);
238+
assert_eq!(x.trailing_ones(), 0);
222239
}

src/intrinsic.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -677,14 +677,14 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
677677
64 => {
678678
// First step.
679679
let left = self.shl(value, context.new_rvalue_from_long(typ, 32));
680-
let right = self.lshr(left, context.new_rvalue_from_long(typ, 32));
680+
let right = self.lshr(value, context.new_rvalue_from_long(typ, 32));
681681
let step1 = self.or(left, right);
682682

683683
// Second step.
684684
let left = self.and(step1, context.new_rvalue_from_long(typ, 0x0001FFFF0001FFFF));
685685
let left = self.shl(left, context.new_rvalue_from_long(typ, 15));
686686
let right = self.and(step1, context.new_rvalue_from_long(typ, 0xFFFE0000FFFE0000u64 as i64)); // TODO: transmute the number instead?
687-
let right = self.shl(right, context.new_rvalue_from_long(typ, 17));
687+
let right = self.lshr(right, context.new_rvalue_from_long(typ, 17));
688688
let step2 = self.or(left, right);
689689

690690
// Third step.
@@ -717,8 +717,18 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
717717
step5
718718
},
719719
128 => {
720-
// TODO
721-
value
720+
// TODO: find a more efficient implementation?
721+
let sixty_four = self.context.new_rvalue_from_long(typ, 64);
722+
let high = self.context.new_cast(None, value >> sixty_four, self.u64_type);
723+
let low = self.context.new_cast(None, value, self.u64_type);
724+
725+
let reversed_high = self.bit_reverse(64, high);
726+
let reversed_low = self.bit_reverse(64, low);
727+
728+
let new_low = self.context.new_cast(None, reversed_high, typ);
729+
let new_high = self.context.new_cast(None, reversed_low, typ) << sixty_four;
730+
731+
new_low | new_high
722732
},
723733
_ => {
724734
panic!("cannot bit reverse with width = {}", width);
@@ -1006,14 +1016,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
10061016
let then_block = func.new_block("then");
10071017
let after_block = func.new_block("after");
10081018

1009-
let width =
1010-
// TODO: support 128-bit integers.
1011-
if width == 128 {
1012-
64
1013-
}
1014-
else {
1015-
width
1016-
};
10171019
let unsigned_type = self.context.new_int_type(width as i32 / 8, false);
10181020
let shifted = self.context.new_cast(None, lhs, unsigned_type) >> self.context.new_rvalue_from_int(unsigned_type, width as i32 - 1);
10191021
let uint_max = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, unsigned_type,

0 commit comments

Comments
 (0)