@@ -166,20 +166,58 @@ macro_rules! define_common_ops {
166
166
unsafe { simd_mul( self , other) }
167
167
}
168
168
}
169
- ) +
170
- }
171
- }
172
169
173
- macro_rules! define_float_ops {
174
- ( $( $ty: ident) ,+) => {
175
- $(
176
170
impl :: std:: ops:: Div for $ty {
177
171
type Output = Self ;
178
172
#[ inline( always) ]
179
173
fn div( self , other: Self ) -> Self {
180
174
unsafe { simd_div( self , other) }
181
175
}
182
176
}
177
+
178
+ impl :: std:: ops:: Rem for $ty {
179
+ type Output = Self ;
180
+ #[ inline( always) ]
181
+ fn rem( self , other: Self ) -> Self {
182
+ unsafe { simd_rem( self , other) }
183
+ }
184
+ }
185
+
186
+ impl :: std:: ops:: AddAssign for $ty {
187
+ #[ inline( always) ]
188
+ fn add_assign( & mut self , other: Self ) {
189
+ * self = * self + other;
190
+ }
191
+ }
192
+
193
+ impl :: std:: ops:: SubAssign for $ty {
194
+ #[ inline( always) ]
195
+ fn sub_assign( & mut self , other: Self ) {
196
+ * self = * self - other;
197
+ }
198
+ }
199
+
200
+ impl :: std:: ops:: MulAssign for $ty {
201
+ #[ inline( always) ]
202
+ fn mul_assign( & mut self , other: Self ) {
203
+ * self = * self * other;
204
+ }
205
+ }
206
+
207
+ impl :: std:: ops:: DivAssign for $ty {
208
+ #[ inline( always) ]
209
+ fn div_assign( & mut self , other: Self ) {
210
+ * self = * self / other;
211
+ }
212
+ }
213
+
214
+ impl :: std:: ops:: RemAssign for $ty {
215
+ #[ inline( always) ]
216
+ fn rem_assign( & mut self , other: Self ) {
217
+ * self = * self % other;
218
+ }
219
+ }
220
+
183
221
) +
184
222
}
185
223
}
@@ -201,13 +239,63 @@ macro_rules! define_shifts {
201
239
unsafe { simd_shr( self , $ty:: splat( other as $elem) ) }
202
240
}
203
241
}
242
+
243
+ impl :: std:: ops:: ShlAssign <$by> for $ty {
244
+ #[ inline( always) ]
245
+ fn shl_assign( & mut self , other: $by) {
246
+ * self = * self << other;
247
+ }
248
+ }
249
+ impl :: std:: ops:: ShrAssign <$by> for $ty {
250
+ #[ inline( always) ]
251
+ fn shr_assign( & mut self , other: $by) {
252
+ * self = * self >> other;
253
+ }
254
+ }
255
+
204
256
) +
205
257
}
206
258
}
207
259
260
+ macro_rules! define_float_ops {
261
+ ( $( $ty: ident) ,+) => {
262
+ $(
263
+ impl :: std:: ops:: Neg for $ty {
264
+ type Output = Self ;
265
+ #[ inline( always) ]
266
+ fn neg( self ) -> Self {
267
+ Self :: splat( -1.0 ) * self
268
+ }
269
+ }
270
+ ) +
271
+ } ;
272
+ }
273
+
274
+ macro_rules! define_signed_integer_ops {
275
+ ( $( $ty: ident) ,+) => {
276
+ $(
277
+ impl :: std:: ops:: Neg for $ty {
278
+ type Output = Self ;
279
+ #[ inline( always) ]
280
+ fn neg( self ) -> Self {
281
+ Self :: splat( -1 ) * self
282
+ }
283
+ }
284
+ ) +
285
+ } ;
286
+ }
287
+
208
288
macro_rules! define_integer_ops {
209
289
( $( ( $ty: ident, $elem: ident) ) ,+) => {
210
290
$(
291
+ impl :: std:: ops:: Not for $ty {
292
+ type Output = Self ;
293
+ #[ inline( always) ]
294
+ fn not( self ) -> Self {
295
+ $ty:: splat( !0 ) ^ self
296
+ }
297
+ }
298
+
211
299
impl :: std:: ops:: BitAnd for $ty {
212
300
type Output = Self ;
213
301
#[ inline( always) ]
@@ -229,13 +317,25 @@ macro_rules! define_integer_ops {
229
317
unsafe { simd_xor( self , other) }
230
318
}
231
319
}
232
- impl :: std:: ops:: Not for $ty {
233
- type Output = Self ;
320
+ impl :: std:: ops:: BitAndAssign for $ty {
234
321
#[ inline( always) ]
235
- fn not( self ) -> Self {
236
- $ty:: splat( !0 ) ^ self
322
+ fn bitand_assign( & mut self , other: Self ) {
323
+ * self = * self & other;
324
+ }
325
+ }
326
+ impl :: std:: ops:: BitOrAssign for $ty {
327
+ #[ inline( always) ]
328
+ fn bitor_assign( & mut self , other: Self ) {
329
+ * self = * self | other;
330
+ }
331
+ }
332
+ impl :: std:: ops:: BitXorAssign for $ty {
333
+ #[ inline( always) ]
334
+ fn bitxor_assign( & mut self , other: Self ) {
335
+ * self = * self ^ other;
237
336
}
238
337
}
338
+
239
339
define_shifts!(
240
340
$ty, $elem,
241
341
u8 , u16 , u32 , u64 , usize ,
@@ -321,3 +421,186 @@ mod tests {
321
421
assert ! ( cfg_feature_enabled!( "sse" ) ) ;
322
422
}
323
423
}
424
+
425
+
426
+ #[ cfg( test) ]
427
+ #[ macro_export]
428
+ macro_rules! test_arithmetic_ {
429
+ ( $tn: ident, $zero: expr, $one: expr, $two: expr, $four: expr) => {
430
+ {
431
+ let z = $tn:: splat( $zero) ;
432
+ let o = $tn:: splat( $one) ;
433
+ let t = $tn:: splat( $two) ;
434
+ let f = $tn:: splat( $four) ;
435
+
436
+ // add
437
+ assert_eq!( z + z, z) ;
438
+ assert_eq!( o + z, o) ;
439
+ assert_eq!( t + z, t) ;
440
+ assert_eq!( t + t, f) ;
441
+ // sub
442
+ assert_eq!( z - z, z) ;
443
+ assert_eq!( o - z, o) ;
444
+ assert_eq!( t - z, t) ;
445
+ assert_eq!( f - t, t) ;
446
+ assert_eq!( f - o - o, t) ;
447
+ // mul
448
+ assert_eq!( z * z, z) ;
449
+ assert_eq!( z * o, z) ;
450
+ assert_eq!( z * t, z) ;
451
+ assert_eq!( o * t, t) ;
452
+ assert_eq!( t * t, f) ;
453
+ // div
454
+ assert_eq!( z / o, z) ;
455
+ assert_eq!( t / o, t) ;
456
+ assert_eq!( f / o, f) ;
457
+ assert_eq!( t / t, o) ;
458
+ assert_eq!( f / t, t) ;
459
+ // rem
460
+ assert_eq!( o % o, z) ;
461
+ assert_eq!( f % t, z) ;
462
+
463
+ {
464
+ let mut v = z;
465
+ assert_eq!( v, z) ;
466
+ v += o; // add_assign
467
+ assert_eq!( v, o) ;
468
+ v -= o; // sub_assign
469
+ assert_eq!( v, z) ;
470
+ v = t;
471
+ v *= o; // mul_assign
472
+ assert_eq!( v, t) ;
473
+ v *= t;
474
+ assert_eq!( v, f) ;
475
+ v /= o; // div_assign
476
+ assert_eq!( v, f) ;
477
+ v /= t;
478
+ assert_eq!( v, t) ;
479
+ v %= t; // rem_assign
480
+ assert_eq!( v, z) ;
481
+ }
482
+ }
483
+ } ;
484
+ }
485
+
486
+ #[ cfg( test) ]
487
+ #[ macro_export]
488
+ macro_rules! test_neg_ {
489
+ ( $tn: ident, $zero: expr, $one: expr, $two: expr, $four: expr) => {
490
+ {
491
+ let z = $tn:: splat( $zero) ;
492
+ let o = $tn:: splat( $one) ;
493
+ let t = $tn:: splat( $two) ;
494
+ let f = $tn:: splat( $four) ;
495
+
496
+ let nz = $tn:: splat( -$zero) ;
497
+ let no = $tn:: splat( -$one) ;
498
+ let nt = $tn:: splat( -$two) ;
499
+ let nf = $tn:: splat( -$four) ;
500
+
501
+ assert_eq!( -z, nz) ;
502
+ assert_eq!( -o, no) ;
503
+ assert_eq!( -t, nt) ;
504
+ assert_eq!( -f, nf) ;
505
+ }
506
+ } ;
507
+ }
508
+
509
+ #[ cfg( test) ]
510
+ #[ macro_export]
511
+ macro_rules! test_bit_arithmetic_ {
512
+ ( $tn: ident) => {
513
+ {
514
+ let z = $tn:: splat( 0 ) ;
515
+ let o = $tn:: splat( 1 ) ;
516
+ let t = $tn:: splat( 2 ) ;
517
+ let f = $tn:: splat( 4 ) ;
518
+ let m = $tn:: splat( !z. extract( 0 ) ) ;
519
+
520
+ // shr
521
+ assert_eq!( o >> 1 , z) ;
522
+ assert_eq!( t >> 1 , o) ;
523
+ assert_eq!( f >> 1 , t) ;
524
+ // shl
525
+ assert_eq!( o << 1 , t) ;
526
+ assert_eq!( o << 2 , f) ;
527
+ assert_eq!( t << 1 , f) ;
528
+ // bitand
529
+ assert_eq!( o & o, o) ;
530
+ assert_eq!( t & t, t) ;
531
+ assert_eq!( t & o, z) ;
532
+ // bitor
533
+ assert_eq!( o | o, o) ;
534
+ assert_eq!( t | t, t) ;
535
+ assert_eq!( z | o, o) ;
536
+ // bitxor
537
+ assert_eq!( o ^ o, z) ;
538
+ assert_eq!( t ^ t, z) ;
539
+ assert_eq!( z ^ o, o) ;
540
+ // not
541
+ assert_eq!( !z, m) ;
542
+ assert_eq!( !m, z) ;
543
+
544
+ { // shr_assign
545
+ let mut v = o;
546
+ v >>= 1 ;
547
+ assert_eq!( v, z) ;
548
+ }
549
+ { // shl_assign
550
+ let mut v = o;
551
+ v <<= 1 ;
552
+ assert_eq!( v, t) ;
553
+ }
554
+ { // and_assign
555
+ let mut v = o;
556
+ v &= t;
557
+ assert_eq!( v, z) ;
558
+ }
559
+ { // or_assign
560
+ let mut v = z;
561
+ v |= o;
562
+ assert_eq!( v, o) ;
563
+ }
564
+ { // xor_assign
565
+ let mut v = z;
566
+ v ^= o;
567
+ assert_eq!( v, o) ;
568
+ }
569
+ }
570
+ } ;
571
+ }
572
+
573
+
574
+ #[ cfg( test) ]
575
+ #[ macro_export]
576
+ macro_rules! test_ops_si {
577
+ ( $( $tn: ident) ,+) => {
578
+ $(
579
+ test_arithmetic_!( $tn, 0 , 1 , 2 , 4 ) ;
580
+ test_neg_!( $tn, 0 , 1 , 2 , 4 ) ;
581
+ test_bit_arithmetic_!( $tn) ;
582
+ ) +
583
+ } ;
584
+ }
585
+
586
+ #[ cfg( test) ]
587
+ #[ macro_export]
588
+ macro_rules! test_ops_ui {
589
+ ( $( $tn: ident) ,+) => {
590
+ $(
591
+ test_arithmetic_!( $tn, 0 , 1 , 2 , 4 ) ;
592
+ test_bit_arithmetic_!( $tn) ;
593
+ ) +
594
+ } ;
595
+ }
596
+
597
+ #[ cfg( test) ]
598
+ #[ macro_export]
599
+ macro_rules! test_ops_f {
600
+ ( $( $tn: ident) ,+) => {
601
+ $(
602
+ test_arithmetic_!( $tn, 0. , 1. , 2. , 4. ) ;
603
+ test_neg_!( $tn, 0. , 1. , 2. , 4. ) ;
604
+ ) +
605
+ } ;
606
+ }
0 commit comments