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