8
8
9
9
#![ allow( non_camel_case_types) ]
10
10
11
+ use crate :: core_arch:: powerpc:: * ;
11
12
use crate :: intrinsics:: simd:: * ;
12
13
13
14
#[ cfg( test) ]
@@ -36,6 +37,16 @@ types! {
36
37
// pub struct vector_unsigned___int128 = i128x1;
37
38
}
38
39
40
+ #[ allow( improper_ctypes) ]
41
+ extern "C" {
42
+ #[ link_name = "llvm.ppc.altivec.vperm" ]
43
+ fn vperm (
44
+ a : vector_signed_int ,
45
+ b : vector_signed_int ,
46
+ c : vector_unsigned_char ,
47
+ ) -> vector_signed_int ;
48
+ }
49
+
39
50
mod sealed {
40
51
use super :: * ;
41
52
use crate :: core_arch:: simd:: * ;
@@ -80,6 +91,73 @@ mod sealed {
80
91
vec_xxpermdi ! { vector_signed_long }
81
92
vec_xxpermdi ! { vector_bool_long }
82
93
vec_xxpermdi ! { vector_double }
94
+
95
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
96
+ pub trait VectorMergeEo {
97
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
98
+ unsafe fn vec_mergee ( self , b : Self ) -> Self ;
99
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
100
+ unsafe fn vec_mergeo ( self , b : Self ) -> Self ;
101
+ }
102
+
103
+ #[ inline]
104
+ #[ target_feature( enable = "altivec" ) ]
105
+ #[ cfg_attr(
106
+ all( test, target_endian = "little" , target_feature = "power8-vector" ) ,
107
+ assert_instr( vmrgow)
108
+ ) ]
109
+ #[ cfg_attr(
110
+ all( test, target_endian = "big" , target_feature = "power8-vector" ) ,
111
+ assert_instr( vmrgew)
112
+ ) ]
113
+ unsafe fn mergee ( a : vector_signed_int , b : vector_signed_int ) -> vector_signed_int {
114
+ let p = transmute ( u8x16:: new (
115
+ 0x00 , 0x01 , 0x02 , 0x03 , 0x10 , 0x11 , 0x12 , 0x13 , 0x08 , 0x09 , 0x0A , 0x0B , 0x18 , 0x19 ,
116
+ 0x1A , 0x1B ,
117
+ ) ) ;
118
+ vec_perm ( a, b, p)
119
+ }
120
+
121
+ #[ inline]
122
+ #[ target_feature( enable = "altivec" ) ]
123
+ #[ cfg_attr(
124
+ all( test, target_endian = "little" , target_feature = "power8-vector" ) ,
125
+ assert_instr( vmrgew)
126
+ ) ]
127
+ #[ cfg_attr(
128
+ all( test, target_endian = "big" , target_feature = "power8-vector" ) ,
129
+ assert_instr( vmrgow)
130
+ ) ]
131
+ unsafe fn mergeo ( a : vector_signed_int , b : vector_signed_int ) -> vector_signed_int {
132
+ let p = transmute ( u8x16:: new (
133
+ 0x04 , 0x05 , 0x06 , 0x07 , 0x14 , 0x15 , 0x16 , 0x17 , 0x0C , 0x0D , 0x0E , 0x0F , 0x1C , 0x1D ,
134
+ 0x1E , 0x1F ,
135
+ ) ) ;
136
+ vec_perm ( a, b, p)
137
+ }
138
+
139
+ macro_rules! vec_mergeeo {
140
+ { $impl: ident, $even: ident, $odd: ident } => {
141
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
142
+ impl VectorMergeEo for $impl {
143
+ #[ inline]
144
+ #[ target_feature( enable = "altivec" ) ]
145
+ unsafe fn vec_mergee( self , b: Self ) -> Self {
146
+ transmute( mergee( transmute( self ) , transmute( b) ) )
147
+ }
148
+ #[ inline]
149
+ #[ target_feature( enable = "altivec" ) ]
150
+ unsafe fn vec_mergeo( self , b: Self ) -> Self {
151
+ transmute( mergeo( transmute( self ) , transmute( b) ) )
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ vec_mergeeo ! { vector_signed_int, mergee, mergeo }
158
+ vec_mergeeo ! { vector_unsigned_int, mergee, mergeo }
159
+ vec_mergeeo ! { vector_bool_int, mergee, mergeo }
160
+ vec_mergeeo ! { vector_float, mergee, mergeo }
83
161
}
84
162
85
163
/// Vector permute.
@@ -95,6 +173,42 @@ where
95
173
a. vec_xxpermdi ( b, DM as u8 )
96
174
}
97
175
176
+ /// Vector Merge Even
177
+ ///
178
+ /// ## Purpose
179
+ /// Merges the even-numbered values from two vectors.
180
+ ///
181
+ /// ## Result value
182
+ /// The even-numbered elements of a are stored into the even-numbered elements of r.
183
+ /// The even-numbered elements of b are stored into the odd-numbered elements of r.
184
+ #[ inline]
185
+ #[ target_feature( enable = "altivec" ) ]
186
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
187
+ pub unsafe fn vec_mergee < T > ( a : T , b : T ) -> T
188
+ where
189
+ T : sealed:: VectorMergeEo ,
190
+ {
191
+ a. vec_mergee ( b)
192
+ }
193
+
194
+ /// Vector Merge Odd
195
+ ///
196
+ /// ## Purpose
197
+ /// Merges the odd-numbered values from two vectors.
198
+ ///
199
+ /// ## Result value
200
+ /// The odd-numbered elements of a are stored into the even-numbered elements of r.
201
+ /// The odd-numbered elements of b are stored into the odd-numbered elements of r.
202
+ #[ inline]
203
+ #[ target_feature( enable = "altivec" ) ]
204
+ #[ unstable( feature = "stdarch_powerpc" , issue = "111145" ) ]
205
+ pub unsafe fn vec_mergeo < T > ( a : T , b : T ) -> T
206
+ where
207
+ T : sealed:: VectorMergeEo ,
208
+ {
209
+ a. vec_mergeo ( b)
210
+ }
211
+
98
212
#[ cfg( test) ]
99
213
mod tests {
100
214
#[ cfg( target_arch = "powerpc" ) ]
0 commit comments