@@ -146,10 +146,146 @@ mod sealed {
146146 #[ inline]
147147 #[ target_feature( enable = "vector" ) ]
148148 unsafe fn vec_add ( self , other : Self ) -> Self :: Result {
149- simd_add ( self , other)
149+ va_float ( self , other)
150150 }
151151 }
152152 }
153+
154+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
155+ pub trait VectorSub < Other > {
156+ type Result ;
157+ unsafe fn vec_sub ( self , other : Other ) -> Self :: Result ;
158+ }
159+
160+ macro_rules! impl_sub {
161+ ( $name: ident, $a: ty, $instr: ident) => {
162+ impl_sub!( $name, $a, $a, $a, $instr) ;
163+ } ;
164+ ( $name: ident, $a: ty, $b: ty, $c: ty, $instr: ident) => {
165+ #[ inline]
166+ #[ target_feature( enable = "vector" ) ]
167+ #[ cfg_attr( test, assert_instr( $instr) ) ]
168+ pub unsafe fn $name( a: $a, b: $b) -> $c {
169+ transmute( simd_sub( transmute( a) , b) )
170+ }
171+
172+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
173+ impl VectorSub <$b> for $a {
174+ type Result = $c;
175+
176+ #[ inline]
177+ #[ target_feature( enable = "vector" ) ]
178+ unsafe fn vec_sub( self , other: $b) -> Self :: Result {
179+ $name( self , other)
180+ }
181+ }
182+ } ;
183+ }
184+
185+ #[ rustfmt:: skip]
186+ mod impl_sub {
187+ use super :: * ;
188+
189+ impl_sub ! ( vs_sc, vector_signed_char, vsb) ;
190+ impl_sub ! ( vs_uc, vector_unsigned_char, vsb) ;
191+ impl_sub ! ( vs_sh, vector_signed_short, vsh) ;
192+ impl_sub ! ( vs_uh, vector_unsigned_short, vsh) ;
193+ impl_sub ! ( vs_sf, vector_signed_int, vsf) ;
194+ impl_sub ! ( vs_uf, vector_unsigned_int, vsf) ;
195+ impl_sub ! ( vs_sg, vector_signed_long_long, vsg) ;
196+ impl_sub ! ( vs_ug, vector_unsigned_long_long, vsg) ;
197+
198+ impl_sub ! ( vs_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vsb) ;
199+ impl_sub ! ( vs_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vsb) ;
200+ impl_sub ! ( vs_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vsh) ;
201+ impl_sub ! ( vs_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vsh) ;
202+ impl_sub ! ( vs_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vsf) ;
203+ impl_sub ! ( vs_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vsf) ;
204+ impl_sub ! ( vs_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vsg) ;
205+ impl_sub ! ( vs_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vsg) ;
206+
207+ impl_sub ! ( vs_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vsb) ;
208+ impl_sub ! ( vs_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vsb) ;
209+ impl_sub ! ( vs_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vsh) ;
210+ impl_sub ! ( vs_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vsh) ;
211+ impl_sub ! ( vs_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vsf) ;
212+ impl_sub ! ( vs_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vsf) ;
213+ impl_sub ! ( vs_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vsg) ;
214+ impl_sub ! ( vs_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vsg) ;
215+
216+ impl_sub ! ( vs_double, vector_double, vfsdb) ;
217+
218+ #[ inline]
219+ #[ target_feature( enable = "vector" ) ]
220+ // FIXME: "vfssb" is part of vector enhancements 1, add a test for it when possible
221+ // #[cfg_attr(test, assert_instr(vfasb))]
222+ pub unsafe fn vs_float ( a : vector_float , b : vector_float ) -> vector_float {
223+ transmute ( simd_sub ( a, b) )
224+ }
225+
226+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
227+ impl VectorSub < Self > for vector_float {
228+ type Result = Self ;
229+
230+ #[ inline]
231+ #[ target_feature( enable = "vector" ) ]
232+ unsafe fn vec_sub ( self , other : Self ) -> Self :: Result {
233+ vs_float ( self , other)
234+ }
235+ }
236+ }
237+
238+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
239+ pub trait VectorMul {
240+ unsafe fn vec_mul ( self , b : Self ) -> Self ;
241+ }
242+
243+ macro_rules! impl_mul {
244+ ( $name: ident, $a: ty, std_simd) => {
245+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
246+ impl VectorMul for $a {
247+ #[ inline]
248+ #[ target_feature( enable = "vector" ) ]
249+ unsafe fn vec_mul( self , other: Self ) -> Self {
250+ transmute( simd_mul( transmute( self ) , other) )
251+ }
252+ }
253+ } ;
254+ ( $name: ident, $a: ty, $instr: ident) => {
255+ #[ inline]
256+ #[ target_feature( enable = "vector" ) ]
257+ #[ cfg_attr( test, assert_instr( $instr) ) ]
258+ pub unsafe fn $name( a: $a, b: $a) -> $a {
259+ transmute( simd_mul( transmute( a) , b) )
260+ }
261+
262+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
263+ impl VectorMul for $a {
264+ #[ inline]
265+ #[ target_feature( enable = "vector" ) ]
266+ unsafe fn vec_mul( self , other: Self ) -> Self {
267+ $name( self , other)
268+ }
269+ }
270+ } ;
271+ }
272+
273+ #[ rustfmt:: skip]
274+ mod impl_mul {
275+ use super :: * ;
276+
277+ impl_mul ! ( vml_sc, vector_signed_char, vmlb) ;
278+ impl_mul ! ( vml_uc, vector_unsigned_char, vmlb) ;
279+ impl_mul ! ( vml_sh, vector_signed_short, vmlhw) ;
280+ impl_mul ! ( vml_uh, vector_unsigned_short, vmlhw) ;
281+ impl_mul ! ( vml_sf, vector_signed_int, vmlf) ;
282+ impl_mul ! ( vml_uf, vector_unsigned_int, vmlf) ;
283+ impl_mul ! ( vml_sg, vector_signed_long_long, std_simd) ;
284+ impl_mul ! ( vml_ug, vector_unsigned_long_long, std_simd) ;
285+
286+ impl_mul ! ( vml_float, vector_float, std_simd) ;
287+ impl_mul ! ( vml_double, vector_double, vfmdb) ;
288+ }
153289}
154290
155291/// Vector pointwise addition.
@@ -163,6 +299,34 @@ where
163299 a. vec_add ( b)
164300}
165301
302+ /// Vector pointwise subtraction.
303+ #[ inline]
304+ #[ target_feature( enable = "vector" ) ]
305+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
306+ pub unsafe fn vec_sub < T , U > ( a : T , b : U ) -> <T as sealed:: VectorSub < U > >:: Result
307+ where
308+ T : sealed:: VectorSub < U > ,
309+ {
310+ a. vec_sub ( b)
311+ }
312+
313+ /// Vector Multiply
314+ ///
315+ /// ## Purpose
316+ /// Compute the products of corresponding elements of two vectors.
317+ ///
318+ /// ## Result value
319+ /// Each element of r receives the product of the corresponding elements of a and b.
320+ #[ inline]
321+ #[ target_feature( enable = "vector" ) ]
322+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
323+ pub unsafe fn vec_mul < T > ( a : T , b : T ) -> T
324+ where
325+ T : sealed:: VectorMul ,
326+ {
327+ a. vec_mul ( b)
328+ }
329+
166330#[ cfg( test) ]
167331mod tests {
168332 use super :: * ;
@@ -172,6 +336,33 @@ mod tests {
172336 use crate :: core_arch:: simd:: * ;
173337 use stdarch_test:: simd_test;
174338
339+ macro_rules! test_vec_2 {
340+ { $name: ident, $fn: ident, $ty: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , [ $( $d: expr) ,+] } => {
341+ test_vec_2! { $name, $fn, $ty -> $ty, [ $( $a) ,+] , [ $( $b) ,+] , [ $( $d) ,+] }
342+ } ;
343+ { $name: ident, $fn: ident, $ty: ident -> $ty_out: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , [ $( $d: expr) ,+] } => {
344+ #[ simd_test( enable = "vector" ) ]
345+ unsafe fn $name( ) {
346+ let a: s_t_l!( $ty) = transmute( $ty:: new( $( $a) ,+) ) ;
347+ let b: s_t_l!( $ty) = transmute( $ty:: new( $( $b) ,+) ) ;
348+
349+ let d = $ty_out:: new( $( $d) ,+) ;
350+ let r : $ty_out = transmute( $fn( a, b) ) ;
351+ assert_eq!( d, r) ;
352+ }
353+ } ;
354+ { $name: ident, $fn: ident, $ty: ident -> $ty_out: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , $d: expr } => {
355+ #[ simd_test( enable = "vector" ) ]
356+ unsafe fn $name( ) {
357+ let a: s_t_l!( $ty) = transmute( $ty:: new( $( $a) ,+) ) ;
358+ let b: s_t_l!( $ty) = transmute( $ty:: new( $( $b) ,+) ) ;
359+
360+ let r : $ty_out = transmute( $fn( a, b) ) ;
361+ assert_eq!( $d, r) ;
362+ }
363+ }
364+ }
365+
175366 #[ simd_test( enable = "vector" ) ]
176367 unsafe fn vec_add_i32x4_i32x4 ( ) {
177368 let x = i32x4:: new ( 1 , 2 , 3 , 4 ) ;
@@ -181,4 +372,116 @@ mod tests {
181372 let z = vec_add ( x, y) ;
182373 assert_eq ! ( i32x4:: splat( 5 ) , transmute( z) ) ;
183374 }
375+
376+ macro_rules! test_vec_sub {
377+ { $name: ident, $ty: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , [ $( $d: expr) ,+] } => {
378+ test_vec_2! { $name, vec_sub, $ty, [ $( $a) ,+] , [ $( $b) ,+] , [ $( $d) ,+] }
379+ }
380+ }
381+
382+ test_vec_sub ! { test_vec_sub_f32x4, f32x4,
383+ [ -1.0 , 0.0 , 1.0 , 2.0 ] ,
384+ [ 2.0 , 1.0 , -1.0 , -2.0 ] ,
385+ [ -3.0 , -1.0 , 2.0 , 4.0 ] }
386+
387+ test_vec_sub ! { test_vec_sub_f64x2, f64x2,
388+ [ -1.0 , 0.0 ] ,
389+ [ 2.0 , 1.0 ] ,
390+ [ -3.0 , -1.0 ] }
391+
392+ test_vec_sub ! { test_vec_sub_i64x2, i64x2,
393+ [ -1 , 0 ] ,
394+ [ 2 , 1 ] ,
395+ [ -3 , -1 ] }
396+
397+ test_vec_sub ! { test_vec_sub_u64x2, u64x2,
398+ [ 0 , 1 ] ,
399+ [ 1 , 0 ] ,
400+ [ u64 :: MAX , 1 ] }
401+
402+ test_vec_sub ! { test_vec_sub_i32x4, i32x4,
403+ [ -1 , 0 , 1 , 2 ] ,
404+ [ 2 , 1 , -1 , -2 ] ,
405+ [ -3 , -1 , 2 , 4 ] }
406+
407+ test_vec_sub ! { test_vec_sub_u32x4, u32x4,
408+ [ 0 , 0 , 1 , 2 ] ,
409+ [ 2 , 1 , 0 , 0 ] ,
410+ [ 4294967294 , 4294967295 , 1 , 2 ] }
411+
412+ test_vec_sub ! { test_vec_sub_i16x8, i16x8,
413+ [ -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 ] ,
414+ [ 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 ] ,
415+ [ -3 , -1 , 2 , 4 , -3 , -1 , 2 , 4 ] }
416+
417+ test_vec_sub ! { test_vec_sub_u16x8, u16x8,
418+ [ 0 , 0 , 1 , 2 , 0 , 0 , 1 , 2 ] ,
419+ [ 2 , 1 , 0 , 0 , 2 , 1 , 0 , 0 ] ,
420+ [ 65534 , 65535 , 1 , 2 , 65534 , 65535 , 1 , 2 ] }
421+
422+ test_vec_sub ! { test_vec_sub_i8x16, i8x16,
423+ [ -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 ] ,
424+ [ 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 ] ,
425+ [ -3 , -1 , 2 , 4 , -3 , -1 , 2 , 4 , -3 , -1 , 2 , 4 , -3 , -1 , 2 , 4 ] }
426+
427+ test_vec_sub ! { test_vec_sub_u8x16, u8x16,
428+ [ 0 , 0 , 1 , 2 , 0 , 0 , 1 , 2 , 0 , 0 , 1 , 2 , 0 , 0 , 1 , 2 ] ,
429+ [ 2 , 1 , 0 , 0 , 2 , 1 , 0 , 0 , 2 , 1 , 0 , 0 , 2 , 1 , 0 , 0 ] ,
430+ [ 254 , 255 , 1 , 2 , 254 , 255 , 1 , 2 , 254 , 255 , 1 , 2 , 254 , 255 , 1 , 2 ] }
431+
432+ macro_rules! test_vec_mul {
433+ { $name: ident, $ty: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , [ $( $d: expr) ,+] } => {
434+ test_vec_2! { $name, vec_mul, $ty, [ $( $a) ,+] , [ $( $b) ,+] , [ $( $d) ,+] }
435+ }
436+ }
437+
438+ test_vec_mul ! { test_vec_mul_f32x4, f32x4,
439+ [ -1.0 , 0.0 , 1.0 , 2.0 ] ,
440+ [ 2.0 , 1.0 , -1.0 , -2.0 ] ,
441+ [ -2.0 , 0.0 , -1.0 , -4.0 ] }
442+
443+ test_vec_mul ! { test_vec_mul_f64x2, f64x2,
444+ [ -1.0 , 0.0 ] ,
445+ [ 2.0 , 1.0 ] ,
446+ [ -2.0 , 0.0 ] }
447+
448+ test_vec_mul ! { test_vec_mul_i64x2, i64x2,
449+ [ i64 :: MAX , -4 ] ,
450+ [ 2 , 3 ] ,
451+ [ i64 :: MAX . wrapping_mul( 2 ) , -12 ] }
452+
453+ test_vec_mul ! { test_vec_mul_u64x2, u64x2,
454+ [ u64 :: MAX , 4 ] ,
455+ [ 2 , 3 ] ,
456+ [ u64 :: MAX . wrapping_mul( 2 ) , 12 ] }
457+
458+ test_vec_mul ! { test_vec_mul_i32x4, i32x4,
459+ [ -1 , 0 , 1 , 2 ] ,
460+ [ 2 , 1 , -1 , -2 ] ,
461+ [ -2 , 0 , -1 , -4 ] }
462+
463+ test_vec_mul ! { test_vec_mul_u32x4, u32x4,
464+ [ 0 , u32 :: MAX - 1 , 1 , 2 ] ,
465+ [ 5 , 6 , 7 , 8 ] ,
466+ [ 0 , 4294967284 , 7 , 16 ] }
467+
468+ test_vec_mul ! { test_vec_mul_i16x8, i16x8,
469+ [ -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 ] ,
470+ [ 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 ] ,
471+ [ -2 , 0 , -1 , -4 , -2 , 0 , -1 , -4 ] }
472+
473+ test_vec_mul ! { test_vec_mul_u16x8, u16x8,
474+ [ 0 , u16 :: MAX - 1 , 1 , 2 , 3 , 4 , 5 , 6 ] ,
475+ [ 5 , 6 , 7 , 8 , 9 , 8 , 7 , 6 ] ,
476+ [ 0 , 65524 , 7 , 16 , 27 , 32 , 35 , 36 ] }
477+
478+ test_vec_mul ! { test_vec_mul_i8x16, i8x16,
479+ [ -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 , -1 , 0 , 1 , 2 ] ,
480+ [ 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 , 2 , 1 , -1 , -2 ] ,
481+ [ -2 , 0 , -1 , -4 , -2 , 0 , -1 , -4 , -2 , 0 , -1 , -4 , -2 , 0 , -1 , -4 ] }
482+
483+ test_vec_mul ! { test_vec_mul_u8x16, u8x16,
484+ [ 0 , u8 :: MAX - 1 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 8 , 7 , 6 , 5 , 4 ] ,
485+ [ 5 , 6 , 7 , 8 , 9 , 8 , 7 , 6 , 5 , 4 , 0 , u8 :: MAX , 1 , 2 , 3 , 4 ] ,
486+ [ 0 , 244 , 7 , 16 , 27 , 32 , 35 , 36 , 35 , 32 , 0 , 248 , 7 , 12 , 15 , 16 ] }
184487}
0 commit comments