1
1
//@run-pass
2
- //@ignore-endian-big behavior of simd_select_bitmask is endian-specific
3
2
#![ feature( repr_simd, intrinsics) ]
4
3
5
4
extern "rust-intrinsic" {
@@ -17,36 +16,139 @@ fn main() {
17
16
let i: u8 = simd_bitmask ( v) ;
18
17
let a: [ u8 ; 1 ] = simd_bitmask ( v) ;
19
18
20
- assert_eq ! ( i, 0b0101 ) ;
21
- assert_eq ! ( a, [ 0b0101 ] ) ;
19
+ if cfg ! ( target_endian = "little" ) {
20
+ assert_eq ! ( i, 0b0101 ) ;
21
+ assert_eq ! ( a, [ 0b0101 ] ) ;
22
+ } else {
23
+ assert_eq ! ( i, 0b1010 ) ;
24
+ assert_eq ! ( a, [ 0b1010 ] ) ;
25
+ }
22
26
23
27
let v = Simd :: < i8 , 16 > ( [ 0 , 0 , -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , 0 , -1 , 0 ] ) ;
24
28
let i: u16 = simd_bitmask ( v) ;
25
29
let a: [ u8 ; 2 ] = simd_bitmask ( v) ;
26
30
27
- assert_eq ! ( i, 0b0101000000001100 ) ;
28
- assert_eq ! ( a, [ 0b1100 , 0b01010000 ] ) ;
31
+ if cfg ! ( target_endian = "little" ) {
32
+ assert_eq ! ( i, 0b0101000000001100 ) ;
33
+ assert_eq ! ( a, [ 0b00001100 , 0b01010000 ] ) ;
34
+ } else {
35
+ assert_eq ! ( i, 0b0011000000001010 ) ;
36
+ assert_eq ! ( a, [ 0b00110000 , 0b00001010 ] ) ;
37
+ }
29
38
}
30
39
31
40
unsafe {
32
- let a = Simd :: < i32 , 8 > ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
33
- let b = Simd :: < i32 , 8 > ( [ 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ) ;
34
- let e = [ 0 , 9 , 2 , 11 , 12 , 13 , 14 , 15 ] ;
41
+ let a = Simd :: < i32 , 4 > ( [ 0 , 1 , 2 , 3 ] ) ;
42
+ let b = Simd :: < i32 , 4 > ( [ 8 , 9 , 10 , 11 ] ) ;
43
+ let e = [ 0 , 9 , 2 , 11 ] ;
35
44
36
- let r = simd_select_bitmask ( 0b0101u8 , a, b) ;
45
+ let mask = if cfg ! ( target_endian = "little" ) { 0b0101u8 } else { 0b1010u8 } ;
46
+ let r = simd_select_bitmask ( mask, a, b) ;
37
47
assert_eq ! ( r. 0 , e) ;
38
48
39
- let r = simd_select_bitmask ( [ 0b0101u8 ] , a, b) ;
49
+ let mask = if cfg ! ( target_endian = "little" ) { [ 0b0101u8 ] } else { [ 0b1010u8 ] } ;
50
+ let r = simd_select_bitmask ( mask, a, b) ;
40
51
assert_eq ! ( r. 0 , e) ;
41
52
42
53
let a = Simd :: < i32 , 16 > ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ] ) ;
43
54
let b = Simd :: < i32 , 16 > ( [ 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ] ) ;
44
55
let e = [ 16 , 17 , 2 , 3 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 12 , 29 , 14 , 31 ] ;
45
56
46
- let r = simd_select_bitmask ( 0b0101000000001100u16 , a, b) ;
57
+ let mask = if cfg ! ( target_endian = "little" ) {
58
+ 0b0101000000001100u16
59
+ } else {
60
+ 0b0011000000001010u16
61
+ } ;
62
+ let r = simd_select_bitmask ( mask, a, b) ;
47
63
assert_eq ! ( r. 0 , e) ;
48
64
49
- let r = simd_select_bitmask ( [ 0b1100u8 , 0b01010000u8 ] , a, b) ;
65
+ let mask = if cfg ! ( target_endian = "little" ) {
66
+ [ 0b00001100u8 , 0b01010000u8 ]
67
+ } else {
68
+ [ 0b00110000u8 , 0b00001010u8 ]
69
+ } ;
70
+ let r = simd_select_bitmask ( mask, a, b) ;
50
71
assert_eq ! ( r. 0 , e) ;
51
72
}
73
+
74
+ non_pow2 ( ) ;
75
+ }
76
+
77
+ fn non_pow2 ( ) {
78
+ // Non-power-of-2 multi-byte mask.
79
+ #[ repr( simd, packed) ]
80
+ #[ allow( non_camel_case_types) ]
81
+ #[ derive( Copy , Clone , Debug , PartialEq ) ]
82
+ struct i32x10 ( [ i32 ; 10 ] ) ;
83
+ impl i32x10 {
84
+ fn splat ( x : i32 ) -> Self {
85
+ Self ( [ x; 10 ] )
86
+ }
87
+ }
88
+ unsafe {
89
+ let mask = i32x10 ( [ !0 , !0 , 0 , !0 , 0 , 0 , !0 , 0 , !0 , 0 ] ) ;
90
+ let mask_bits = if cfg ! ( target_endian = "little" ) { 0b0101001011 } else { 0b1101001010 } ;
91
+ let mask_bytes =
92
+ if cfg ! ( target_endian = "little" ) { [ 0b01001011 , 0b01 ] } else { [ 0b11 , 0b01001010 ] } ;
93
+
94
+ let bitmask1: u16 = simd_bitmask ( mask) ;
95
+ let bitmask2: [ u8 ; 2 ] = simd_bitmask ( mask) ;
96
+ assert_eq ! ( bitmask1, mask_bits) ;
97
+ assert_eq ! ( bitmask2, mask_bytes) ;
98
+
99
+ let selected1 = simd_select_bitmask :: < u16 , _ > (
100
+ mask_bits,
101
+ i32x10:: splat ( !0 ) , // yes
102
+ i32x10:: splat ( 0 ) , // no
103
+ ) ;
104
+ let selected2 = simd_select_bitmask :: < [ u8 ; 2 ] , _ > (
105
+ mask_bytes,
106
+ i32x10:: splat ( !0 ) , // yes
107
+ i32x10:: splat ( 0 ) , // no
108
+ ) ;
109
+ assert_eq ! ( selected1, mask) ;
110
+ assert_eq ! ( selected2, mask) ;
111
+ }
112
+
113
+ // Test for a mask where the next multiple of 8 is not a power of two.
114
+ #[ repr( simd, packed) ]
115
+ #[ allow( non_camel_case_types) ]
116
+ #[ derive( Copy , Clone , Debug , PartialEq ) ]
117
+ struct i32x20 ( [ i32 ; 20 ] ) ;
118
+ impl i32x20 {
119
+ fn splat ( x : i32 ) -> Self {
120
+ Self ( [ x; 20 ] )
121
+ }
122
+ }
123
+ unsafe {
124
+ let mask = i32x20 ( [ !0 , !0 , 0 , !0 , 0 , 0 , !0 , 0 , !0 , 0 , 0 , 0 , 0 , !0 , !0 , !0 , !0 , !0 , !0 , !0 ] ) ;
125
+ let mask_bits = if cfg ! ( target_endian = "little" ) {
126
+ 0b11111110000101001011
127
+ } else {
128
+ 0b11010010100001111111
129
+ } ;
130
+ let mask_bytes = if cfg ! ( target_endian = "little" ) {
131
+ [ 0b01001011 , 0b11100001 , 0b1111 ]
132
+ } else {
133
+ [ 0b1101 , 0b00101000 , 0b01111111 ]
134
+ } ;
135
+
136
+ let bitmask1: u32 = simd_bitmask ( mask) ;
137
+ let bitmask2: [ u8 ; 3 ] = simd_bitmask ( mask) ;
138
+ assert_eq ! ( bitmask1, mask_bits) ;
139
+ assert_eq ! ( bitmask2, mask_bytes) ;
140
+
141
+ let selected1 = simd_select_bitmask :: < u32 , _ > (
142
+ mask_bits,
143
+ i32x20:: splat ( !0 ) , // yes
144
+ i32x20:: splat ( 0 ) , // no
145
+ ) ;
146
+ let selected2 = simd_select_bitmask :: < [ u8 ; 3 ] , _ > (
147
+ mask_bytes,
148
+ i32x20:: splat ( !0 ) , // yes
149
+ i32x20:: splat ( 0 ) , // no
150
+ ) ;
151
+ assert_eq ! ( selected1, mask) ;
152
+ assert_eq ! ( selected2, mask) ;
153
+ }
52
154
}
0 commit comments