Skip to content

Commit 1b6ab01

Browse files
committed
Implement and fix rotate intrinsic
1 parent 5e9e74c commit 1b6ab01

File tree

3 files changed

+70
-64
lines changed

3 files changed

+70
-64
lines changed

gcc-test-backend/src/main.rs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,54 @@
1-
#![feature(is_sorted)]
2-
31
fn main() {
4-
let b: u16 = 42;
5-
assert_eq!(b, 42);
6-
let empty: [i32; 0] = [];
7-
8-
assert!([1, 2, 2, 9].is_sorted());
9-
assert!(![1, 3, 2].is_sorted());
10-
assert!([42].is_sorted());
11-
assert!(empty.is_sorted());
12-
assert!(![0.0, 1.0, f32::NAN].is_sorted());
13-
assert!([-2, -1, 0, 3].is_sorted());
14-
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
15-
assert!(!["c", "bb", "aaa"].is_sorted());
16-
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
2+
const A: i8 = 0b0101100;
3+
const B: i8 = 0b0100001;
4+
const C: i8 = 0b1111001;
5+
6+
const _0: i8 = 0;
7+
const _1: i8 = !0;
8+
9+
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
10+
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
11+
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
12+
13+
/*fn rotate_left(x: u32, mut n: u32) -> u32 {
14+
//(x << n) | (x >> (-(n as i32) & 31))
15+
//println!("{}", 0 << 32);
16+
let second_shift = 32 - (n % 32);
17+
n %= 32;
18+
(x << n) | (x >> second_shift)
19+
}
20+
21+
fn irotate_left(x: i32, mut n: u32) -> i32 {
22+
let x = x as u32;
23+
let second_shift = 32 - (n % 32);
24+
n %= 32;
25+
((x << n) | (x >> second_shift)) as i32
26+
}
27+
28+
assert_eq!(rotate_left(2, 48), 131072);
29+
assert_eq!(irotate_left(2, 48), 131072);
30+
assert_eq!(irotate_left(-2, 48), -65537);
31+
assert_eq!(irotate_left(_1, 124), _1);*/
32+
33+
/*const _2: u32 = 0;
34+
assert_eq!(rotate_left(_2, 16), _2);
35+
assert_eq!(rotate_left(_2, 32), _2);
36+
assert_eq!(_2.rotate_left(32), _2);*/
37+
38+
// Rotating these should make no difference
39+
//
40+
// We test using 124 bits because to ensure that overlong bit shifts do
41+
// not cause undefined behaviour. See #10183.
42+
assert_eq!(_0.rotate_left(124), _0);
43+
println!("{:b}", _1);
44+
assert_eq!(_1.rotate_left(124), _1);
45+
46+
// Rotating by 0 should have no effect
47+
assert_eq!(A.rotate_left(0), A);
48+
assert_eq!(B.rotate_left(0), B);
49+
assert_eq!(C.rotate_left(0), C);
50+
// Rotating by a multiple of word size should also have no effect
51+
assert_eq!(A.rotate_left(128), A);
52+
assert_eq!(B.rotate_left(128), B);
53+
assert_eq!(C.rotate_left(128), C);
1754
}

patches/0022-core-Disable-not-compiling-tests.patch

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,46 +39,6 @@ index a35897e..f0bf645 100644
3939

4040
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
4141
match decode(v).1 {
42-
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
43-
index 0475aeb..9558198 100644
44-
--- a/library/core/tests/num/int_macros.rs
45-
+++ b/library/core/tests/num/int_macros.rs
46-
@@ -88,6 +88,7 @@ mod tests {
47-
assert_eq!(x.trailing_ones(), 0);
48-
}
49-
50-
+ /*
51-
#[test]
52-
fn test_rotate() {
53-
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
54-
@@ -112,6 +113,7 @@ mod tests {
55-
assert_eq!(B.rotate_left(128), B);
56-
assert_eq!(C.rotate_left(128), C);
57-
}
58-
+ */
59-
60-
#[test]
61-
fn test_swap_bytes() {
62-
diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
63-
index 04ed14f..a6e372e 100644
64-
--- a/library/core/tests/num/uint_macros.rs
65-
+++ b/library/core/tests/num/uint_macros.rs
66-
@@ -52,6 +52,7 @@ mod tests {
67-
assert_eq!(x.trailing_ones(), 0);
68-
}
69-
70-
+ /*
71-
#[test]
72-
fn test_rotate() {
73-
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
74-
@@ -76,6 +77,7 @@ mod tests {
75-
assert_eq!(B.rotate_left(128), B);
76-
assert_eq!(C.rotate_left(128), C);
77-
}
78-
+ */
79-
80-
#[test]
81-
fn test_swap_bytes() {
8242
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
8343
index 6609bc3..241b497 100644
8444
--- a/library/core/tests/slice.rs

src/intrinsic.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
296296
self.rotate_left(val, raw_shift, width)
297297
}
298298
else {
299-
// TODO: implement now to enable more tests.
300-
match width {
301-
8 => unimplemented!(),
302-
16 => unimplemented!(),
303-
32 => unimplemented!(),
304-
64 => unimplemented!(),
305-
_ => unimplemented!("rotate for integer of size {}", width),
306-
}
299+
self.rotate_right(val, raw_shift, width)
307300
}
308301
},
309302
sym::saturating_add => {
@@ -935,13 +928,29 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
935928

936929
// Algorithm from: https://blog.regehr.org/archives/1063
937930
fn rotate_left(&mut self, value: RValue<'gcc>, shift: RValue<'gcc>, width: u64) -> RValue<'gcc> {
931+
let max = self.context.new_rvalue_from_long(shift.get_type(), width as i64);
932+
let shift = shift % max;
938933
let lhs = self.shl(value, shift);
939934
let result_and =
940935
self.and(
941936
self.context.new_unary_op(None, UnaryOp::Minus, shift.get_type(), shift),
942937
self.context.new_rvalue_from_long(shift.get_type(), width as i64 - 1),
943938
);
944-
let rhs = self.lshr(shift, result_and);
939+
let rhs = self.lshr(value, result_and);
940+
self.or(lhs, rhs)
941+
}
942+
943+
// Algorithm from: https://blog.regehr.org/archives/1063
944+
fn rotate_right(&mut self, value: RValue<'gcc>, shift: RValue<'gcc>, width: u64) -> RValue<'gcc> {
945+
let max = self.context.new_rvalue_from_long(shift.get_type(), width as i64);
946+
let shift = shift % max;
947+
let lhs = self.lshr(value, shift);
948+
let result_and =
949+
self.and(
950+
self.context.new_unary_op(None, UnaryOp::Minus, shift.get_type(), shift),
951+
self.context.new_rvalue_from_long(shift.get_type(), width as i64 - 1),
952+
);
953+
let rhs = self.shl(value, result_and);
945954
self.or(lhs, rhs)
946955
}
947956

0 commit comments

Comments
 (0)