@@ -146,10 +146,146 @@ mod sealed {
146
146
#[ inline]
147
147
#[ target_feature( enable = "vector" ) ]
148
148
unsafe fn vec_add ( self , other : Self ) -> Self :: Result {
149
- simd_add ( self , other)
149
+ va_float ( self , other)
150
150
}
151
151
}
152
152
}
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
+ }
153
289
}
154
290
155
291
/// Vector pointwise addition.
@@ -163,6 +299,34 @@ where
163
299
a. vec_add ( b)
164
300
}
165
301
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
+
166
330
#[ cfg( test) ]
167
331
mod tests {
168
332
use super :: * ;
@@ -172,6 +336,33 @@ mod tests {
172
336
use crate :: core_arch:: simd:: * ;
173
337
use stdarch_test:: simd_test;
174
338
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
+
175
366
#[ simd_test( enable = "vector" ) ]
176
367
unsafe fn vec_add_i32x4_i32x4 ( ) {
177
368
let x = i32x4:: new ( 1 , 2 , 3 , 4 ) ;
@@ -181,4 +372,116 @@ mod tests {
181
372
let z = vec_add ( x, y) ;
182
373
assert_eq ! ( i32x4:: splat( 5 ) , transmute( z) ) ;
183
374
}
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 ] }
184
487
}
0 commit comments