1
1
//! Implements integer rotates.
2
2
#![ allow( unused) ]
3
3
4
+ /// Trait used for overloading rotates
5
+ pub trait Rotate < T > {
6
+ /// Shifts the bits of each lane to the left by the specified amount in
7
+ /// the corresponding lane of `n`, wrapping the truncated bits to
8
+ /// the end of the resulting integer.
9
+ ///
10
+ /// Please note this isn't the same operation as `<<`!. Also note it
11
+ /// isn't equivalent to `slice::rotate_left`, it doesn't move the vector's
12
+ /// lanes around. (that can be implemented with vector shuffles).
13
+ fn rotate_left ( self , n : T ) -> Self ;
14
+
15
+ /// Shifts the bits of each lane to the right by the specified amount in
16
+ /// the corresponding lane of `n`, wrapping the truncated bits to
17
+ /// the beginning of the resulting integer.
18
+ ///
19
+ /// Please note this isn't the same operation as `>>`!. Also note it
20
+ /// isn't similar to `slice::rotate_right`, it doesn't move the vector's
21
+ /// lanes around. (that can be implemented with vector shuffles).
22
+ fn rotate_right ( self , n : T ) -> Self ;
23
+ }
24
+
4
25
macro_rules! impl_vector_rotates {
5
26
( $id: ident, $elem_ty: ident) => {
6
- impl $id {
7
- /// Shifts the bits of each lane to the left by the specified amount in
8
- /// the corresponding lane of `n`, wrapping the truncated bits to
9
- /// the end of the resulting integer.
10
- ///
11
- /// Please note this isn't the same operation as `<<`!. Also note it
12
- /// isn't equivalent to `slice::rotate_left` (that can be implemented
13
- /// with vector shuffles).
27
+ impl super :: api:: Rotate <$id> for $id {
14
28
#[ inline]
15
- pub fn rotate_left( self , n: $id) -> $id {
29
+ fn rotate_left( self , n: $id) -> $id {
16
30
const LANE_WIDTH : $elem_ty = :: mem:: size_of:: <$elem_ty>( ) as $elem_ty * 8 ;
17
31
// Protect against undefined behavior for over-long bit shifts
18
32
let n = n % LANE_WIDTH ;
19
33
( self << n) | ( self >> ( ( LANE_WIDTH - n) % LANE_WIDTH ) )
20
34
}
21
35
22
- /// Shifts the bits of each lane to the right by the specified amount in
23
- /// the corresponding lane of `n`, wrapping the truncated bits to
24
- /// the beginning of the resulting integer.
25
- ///
26
- /// Please note this isn't the same operation as `>>`!. Also note it
27
- /// isn't similar to `slice::rotate_right`, it doesn't move the vector's
28
- /// lanes around. (that can be implemented with vector shuffles).
29
36
#[ inline]
30
- pub fn rotate_right( self , n: $id) -> $id {
37
+ fn rotate_right( self , n: $id) -> $id {
31
38
const LANE_WIDTH : $elem_ty = :: mem:: size_of:: <$elem_ty>( ) as $elem_ty * 8 ;
32
39
// Protect against undefined behavior for over-long bit shifts
33
40
let n = n % LANE_WIDTH ;
34
41
( self >> n) | ( self << ( ( LANE_WIDTH - n) % LANE_WIDTH ) )
35
42
}
36
43
}
44
+
45
+ impl super :: api:: Rotate <$elem_ty> for $id {
46
+ #[ inline]
47
+ fn rotate_left( self , n: $elem_ty) -> $id {
48
+ self . rotate_left( $id:: splat( n) )
49
+ }
50
+
51
+
52
+ #[ inline]
53
+ fn rotate_right( self , n: $elem_ty) -> $id {
54
+ self . rotate_right( $id:: splat( n) )
55
+ }
56
+ }
37
57
} ;
38
58
}
39
59
@@ -43,6 +63,7 @@ macro_rules! test_vector_rotate_ops {
43
63
#[ test]
44
64
fn rotate_ops( ) {
45
65
use coresimd:: simd:: $id;
66
+ use coresimd:: simd:: Rotate ; ;
46
67
use std:: mem;
47
68
let z = $id:: splat( 0 as $elem_ty) ;
48
69
let o = $id:: splat( 1 as $elem_ty) ;
0 commit comments