@@ -103,12 +103,12 @@ impl_imm_lane_id! {
103103 struct ImmLaneIdx32 ( x 32 ) ;
104104}
105105
106- trait IntoLane {
107- type Lane : Lane < Item = Self , LaneIdx = Self :: LaneIdx > ;
106+ trait IntoLanes {
107+ type Lanes : Lanes < Item = Self , LaneIdx = Self :: LaneIdx > ;
108108 type LaneIdx ;
109109}
110110
111- trait Lane {
111+ trait Lanes {
112112 type Item ;
113113 type LaneIdx ;
114114
@@ -136,12 +136,12 @@ macro_rules! impl_lanes_for {
136136 #[ repr( transparent) ]
137137 struct $name( [ $ty; $n] ) ;
138138
139- impl IntoLane for $ty {
140- type Lane = $name;
139+ impl IntoLanes for $ty {
140+ type Lanes = $name;
141141 type LaneIdx = <[ ( ) ; $n] as IntoLaneIdx >:: LaneIdx ;
142142 }
143143
144- impl Lane for $name {
144+ impl Lanes for $name {
145145 type Item = $ty;
146146 type LaneIdx = <[ ( ) ; $n] as IntoLaneIdx >:: LaneIdx ;
147147
@@ -211,18 +211,18 @@ impl_lanes_for! {
211211 struct F64x2 ( [ f64 ; 2 ] ) ;
212212}
213213
214- trait LanewiseWidening : Lane {
215- type Narrow : Lane ;
214+ trait LanewiseWidening : Lanes {
215+ type Narrow : Lanes ;
216216
217217 fn lanewise_widening_unary (
218218 value : Self :: Narrow ,
219- f : impl Fn ( <Self :: Narrow as Lane >:: Item , <Self :: Narrow as Lane >:: Item ) -> Self :: Item ,
219+ f : impl Fn ( <Self :: Narrow as Lanes >:: Item , <Self :: Narrow as Lanes >:: Item ) -> Self :: Item ,
220220 ) -> Self ;
221221
222222 fn lanewise_widening_binary (
223223 lhs : Self :: Narrow ,
224224 rhs : Self :: Narrow ,
225- f : impl Fn ( [ <Self :: Narrow as Lane >:: Item ; 2 ] , [ <Self :: Narrow as Lane >:: Item ; 2 ] ) -> Self :: Item ,
225+ f : impl Fn ( [ <Self :: Narrow as Lanes >:: Item ; 2 ] , [ <Self :: Narrow as Lanes >:: Item ; 2 ] ) -> Self :: Item ,
226226 ) -> Self ;
227227}
228228
@@ -231,7 +231,7 @@ impl LanewiseWidening for I64x2 {
231231
232232 fn lanewise_widening_unary (
233233 value : Self :: Narrow ,
234- f : impl Fn ( <Self :: Narrow as Lane >:: Item , <Self :: Narrow as Lane >:: Item ) -> Self :: Item ,
234+ f : impl Fn ( <Self :: Narrow as Lanes >:: Item , <Self :: Narrow as Lanes >:: Item ) -> Self :: Item ,
235235 ) -> Self {
236236 let a = value. 0 ;
237237 #[ rustfmt:: skip]
@@ -245,7 +245,7 @@ impl LanewiseWidening for I64x2 {
245245 fn lanewise_widening_binary (
246246 lhs : Self :: Narrow ,
247247 rhs : Self :: Narrow ,
248- f : impl Fn ( [ <Self :: Narrow as Lane >:: Item ; 2 ] , [ <Self :: Narrow as Lane >:: Item ; 2 ] ) -> Self :: Item ,
248+ f : impl Fn ( [ <Self :: Narrow as Lanes >:: Item ; 2 ] , [ <Self :: Narrow as Lanes >:: Item ; 2 ] ) -> Self :: Item ,
249249 ) -> Self {
250250 let a = lhs. 0 ;
251251 let b = rhs. 0 ;
@@ -263,7 +263,7 @@ impl LanewiseWidening for I32x4 {
263263
264264 fn lanewise_widening_unary (
265265 value : Self :: Narrow ,
266- f : impl Fn ( <Self :: Narrow as Lane >:: Item , <Self :: Narrow as Lane >:: Item ) -> Self :: Item ,
266+ f : impl Fn ( <Self :: Narrow as Lanes >:: Item , <Self :: Narrow as Lanes >:: Item ) -> Self :: Item ,
267267 ) -> Self {
268268 let a = value. 0 ;
269269 #[ rustfmt:: skip]
@@ -279,7 +279,7 @@ impl LanewiseWidening for I32x4 {
279279 fn lanewise_widening_binary (
280280 lhs : Self :: Narrow ,
281281 rhs : Self :: Narrow ,
282- f : impl Fn ( [ <Self :: Narrow as Lane >:: Item ; 2 ] , [ <Self :: Narrow as Lane >:: Item ; 2 ] ) -> Self :: Item ,
282+ f : impl Fn ( [ <Self :: Narrow as Lanes >:: Item ; 2 ] , [ <Self :: Narrow as Lanes >:: Item ; 2 ] ) -> Self :: Item ,
283283 ) -> Self {
284284 let a = lhs. 0 ;
285285 let b = rhs. 0 ;
@@ -299,7 +299,7 @@ impl LanewiseWidening for I16x8 {
299299
300300 fn lanewise_widening_unary (
301301 value : Self :: Narrow ,
302- f : impl Fn ( <Self :: Narrow as Lane >:: Item , <Self :: Narrow as Lane >:: Item ) -> Self :: Item ,
302+ f : impl Fn ( <Self :: Narrow as Lanes >:: Item , <Self :: Narrow as Lanes >:: Item ) -> Self :: Item ,
303303 ) -> Self {
304304 let a = value. 0 ;
305305 #[ rustfmt:: skip]
@@ -319,7 +319,7 @@ impl LanewiseWidening for I16x8 {
319319 fn lanewise_widening_binary (
320320 lhs : Self :: Narrow ,
321321 rhs : Self :: Narrow ,
322- f : impl Fn ( [ <Self :: Narrow as Lane >:: Item ; 2 ] , [ <Self :: Narrow as Lane >:: Item ; 2 ] ) -> Self :: Item ,
322+ f : impl Fn ( [ <Self :: Narrow as Lanes >:: Item ; 2 ] , [ <Self :: Narrow as Lanes >:: Item ; 2 ] ) -> Self :: Item ,
323323 ) -> Self {
324324 let a = lhs. 0 ;
325325 let b = rhs. 0 ;
@@ -338,18 +338,18 @@ impl LanewiseWidening for I16x8 {
338338 }
339339}
340340
341- trait LanewiseNarrowing : Lane {
342- type Wide : Lane ;
341+ trait LanewiseNarrowing : Lanes {
342+ type Wide : Lanes ;
343343
344344 fn lanewise_narrowing_unary (
345345 value : Self :: Wide ,
346- f : impl Fn ( <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
346+ f : impl Fn ( <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
347347 ) -> Self ;
348348
349349 fn lanewise_narrowing_binary (
350350 lhs : Self :: Wide ,
351351 rhs : Self :: Wide ,
352- f : impl Fn ( <Self :: Wide as Lane >:: Item , <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
352+ f : impl Fn ( <Self :: Wide as Lanes >:: Item , <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
353353 ) -> Self ;
354354}
355355
@@ -358,7 +358,7 @@ impl LanewiseNarrowing for I32x4 {
358358
359359 fn lanewise_narrowing_unary (
360360 value : Self :: Wide ,
361- f : impl Fn ( <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
361+ f : impl Fn ( <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
362362 ) -> Self {
363363 let w = value. 0 ;
364364 let [ a0, a1] = f ( w[ 0 ] ) ;
@@ -369,7 +369,7 @@ impl LanewiseNarrowing for I32x4 {
369369 fn lanewise_narrowing_binary (
370370 lhs : Self :: Wide ,
371371 rhs : Self :: Wide ,
372- f : impl Fn ( <Self :: Wide as Lane >:: Item , <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
372+ f : impl Fn ( <Self :: Wide as Lanes >:: Item , <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
373373 ) -> Self {
374374 let lhs = lhs. 0 ;
375375 let rhs = rhs. 0 ;
@@ -384,7 +384,7 @@ impl LanewiseNarrowing for I16x8 {
384384
385385 fn lanewise_narrowing_unary (
386386 value : Self :: Wide ,
387- f : impl Fn ( <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
387+ f : impl Fn ( <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
388388 ) -> Self {
389389 let w = value. 0 ;
390390 let [ a0, a1] = f ( w[ 0 ] ) ;
@@ -397,7 +397,7 @@ impl LanewiseNarrowing for I16x8 {
397397 fn lanewise_narrowing_binary (
398398 lhs : Self :: Wide ,
399399 rhs : Self :: Wide ,
400- f : impl Fn ( <Self :: Wide as Lane >:: Item , <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
400+ f : impl Fn ( <Self :: Wide as Lanes >:: Item , <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
401401 ) -> Self {
402402 let lhs = lhs. 0 ;
403403 let rhs = rhs. 0 ;
@@ -414,7 +414,7 @@ impl LanewiseNarrowing for I8x16 {
414414
415415 fn lanewise_narrowing_unary (
416416 value : Self :: Wide ,
417- f : impl Fn ( <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
417+ f : impl Fn ( <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
418418 ) -> Self {
419419 let w = value. 0 ;
420420 let [ a0, a1] = f ( w[ 0 ] ) ;
@@ -433,7 +433,7 @@ impl LanewiseNarrowing for I8x16 {
433433 fn lanewise_narrowing_binary (
434434 lhs : Self :: Wide ,
435435 rhs : Self :: Wide ,
436- f : impl Fn ( <Self :: Wide as Lane >:: Item , <Self :: Wide as Lane >:: Item ) -> [ Self :: Item ; 2 ] ,
436+ f : impl Fn ( <Self :: Wide as Lanes >:: Item , <Self :: Wide as Lanes >:: Item ) -> [ Self :: Item ; 2 ] ,
437437 ) -> Self {
438438 let lhs = lhs. 0 ;
439439 let rhs = rhs. 0 ;
@@ -452,75 +452,128 @@ impl LanewiseNarrowing for I8x16 {
452452}
453453
454454impl V128 {
455- fn splat < T : IntoLane > ( value : T ) -> Self {
456- <<T as IntoLane >:: Lane >:: splat ( value) . into_v128 ( )
455+ fn splat < T : IntoLanes > ( value : T ) -> Self {
456+ <<T as IntoLanes >:: Lanes >:: splat ( value) . into_v128 ( )
457457 }
458458
459- fn extract_lane < T : IntoLane > ( self , lane : <T as IntoLane >:: LaneIdx ) -> T {
460- <<T as IntoLane >:: Lane >:: from_v128 ( self ) . extract_lane ( lane)
459+ fn extract_lane < T : IntoLanes > ( self , lane : <T as IntoLanes >:: LaneIdx ) -> T {
460+ <<T as IntoLanes >:: Lanes >:: from_v128 ( self ) . extract_lane ( lane)
461461 }
462462
463- fn replace_lane < T : IntoLane > ( self , lane : <T as IntoLane >:: LaneIdx , item : T ) -> Self {
464- <<T as IntoLane >:: Lane >:: from_v128 ( self )
463+ fn replace_lane < T : IntoLanes > ( self , lane : <T as IntoLanes >:: LaneIdx , item : T ) -> Self {
464+ <<T as IntoLanes >:: Lanes >:: from_v128 ( self )
465465 . replace_lane ( lane, item)
466466 . into_v128 ( )
467467 }
468468
469- fn lanewise_unary < T : IntoLane > ( v128 : Self , f : impl Fn ( T ) -> T ) -> Self {
470- <<T as IntoLane >:: Lane >:: from_v128 ( v128)
469+ fn lanewise_unary < T : IntoLanes > ( v128 : Self , f : impl Fn ( T ) -> T ) -> Self {
470+ <<T as IntoLanes >:: Lanes >:: from_v128 ( v128)
471471 . lanewise_unary ( f)
472472 . into_v128 ( )
473473 }
474474
475- fn lanewise_binary < T : IntoLane > ( lhs : Self , rhs : Self , f : impl Fn ( T , T ) -> T ) -> Self {
476- let lhs = <<T as IntoLane >:: Lane >:: from_v128 ( lhs) ;
477- let rhs = <<T as IntoLane >:: Lane >:: from_v128 ( rhs) ;
475+ fn lanewise_binary < T : IntoLanes > ( lhs : Self , rhs : Self , f : impl Fn ( T , T ) -> T ) -> Self {
476+ let lhs = <<T as IntoLanes >:: Lanes >:: from_v128 ( lhs) ;
477+ let rhs = <<T as IntoLanes >:: Lanes >:: from_v128 ( rhs) ;
478478 lhs. lanewise_binary ( rhs, f) . into_v128 ( )
479479 }
480480
481- fn lanewise_comparison < T : IntoLane > ( lhs : Self , rhs : Self , f : impl Fn ( T , T ) -> bool ) -> Self {
482- let lhs = <<T as IntoLane >:: Lane >:: from_v128 ( lhs) ;
483- let rhs = <<T as IntoLane >:: Lane >:: from_v128 ( rhs) ;
481+ fn lanewise_comparison < T : IntoLanes > ( lhs : Self , rhs : Self , f : impl Fn ( T , T ) -> bool ) -> Self {
482+ let lhs = <<T as IntoLanes >:: Lanes >:: from_v128 ( lhs) ;
483+ let rhs = <<T as IntoLanes >:: Lanes >:: from_v128 ( rhs) ;
484484 lhs. lanewise_comparison ( rhs, f) . into_v128 ( )
485485 }
486486
487487 fn lanewise_widening_unary < T : LanewiseWidening > (
488488 self ,
489- f : impl Fn ( <T :: Narrow as Lane >:: Item , <T :: Narrow as Lane >:: Item ) -> T :: Item ,
489+ f : impl Fn ( <T :: Narrow as Lanes >:: Item , <T :: Narrow as Lanes >:: Item ) -> T :: Item ,
490490 ) -> Self {
491- T :: lanewise_widening_unary ( <T :: Narrow as Lane >:: from_v128 ( self ) , f) . into_v128 ( )
491+ T :: lanewise_widening_unary ( <T :: Narrow as Lanes >:: from_v128 ( self ) , f) . into_v128 ( )
492492 }
493493
494494 fn lanewise_widening_binary < T : LanewiseWidening > (
495495 self ,
496496 rhs : Self ,
497- f : impl Fn ( [ <T :: Narrow as Lane >:: Item ; 2 ] , [ <T :: Narrow as Lane >:: Item ; 2 ] ) -> T :: Item ,
497+ f : impl Fn ( [ <T :: Narrow as Lanes >:: Item ; 2 ] , [ <T :: Narrow as Lanes >:: Item ; 2 ] ) -> T :: Item ,
498498 ) -> Self {
499499 T :: lanewise_widening_binary (
500- <T :: Narrow as Lane >:: from_v128 ( self ) ,
501- <T :: Narrow as Lane >:: from_v128 ( rhs) ,
500+ <T :: Narrow as Lanes >:: from_v128 ( self ) ,
501+ <T :: Narrow as Lanes >:: from_v128 ( rhs) ,
502502 f,
503503 )
504504 . into_v128 ( )
505505 }
506506
507507 fn lanewise_narrowing_unary < T : LanewiseNarrowing > (
508508 self ,
509- f : impl Fn ( <T :: Wide as Lane >:: Item ) -> [ T :: Item ; 2 ] ,
509+ f : impl Fn ( <T :: Wide as Lanes >:: Item ) -> [ T :: Item ; 2 ] ,
510510 ) -> Self {
511- T :: lanewise_narrowing_unary ( <T :: Wide as Lane >:: from_v128 ( self ) , f) . into_v128 ( )
511+ T :: lanewise_narrowing_unary ( <T :: Wide as Lanes >:: from_v128 ( self ) , f) . into_v128 ( )
512512 }
513513
514514 fn lanewise_narrowing_binary < T : LanewiseNarrowing > (
515515 self ,
516516 rhs : Self ,
517- f : impl Fn ( <T :: Wide as Lane >:: Item , <T :: Wide as Lane >:: Item ) -> [ T :: Item ; 2 ] ,
517+ f : impl Fn ( <T :: Wide as Lanes >:: Item , <T :: Wide as Lanes >:: Item ) -> [ T :: Item ; 2 ] ,
518518 ) -> Self {
519519 T :: lanewise_narrowing_binary (
520- <T :: Wide as Lane >:: from_v128 ( self ) ,
521- <T :: Wide as Lane >:: from_v128 ( rhs) ,
520+ <T :: Wide as Lanes >:: from_v128 ( self ) ,
521+ <T :: Wide as Lanes >:: from_v128 ( rhs) ,
522522 f,
523523 )
524524 . into_v128 ( )
525525 }
526+
527+ pub fn i32x4_splat ( value : i32 ) -> Self {
528+ Self :: splat ( value)
529+ }
530+
531+ pub fn i32x4_extract_lane ( self , lane : ImmLaneIdx4 ) -> i32 {
532+ self . extract_lane ( lane)
533+ }
534+
535+ pub fn i8x16_extract_lane_s ( self , lane : ImmLaneIdx16 ) -> i32 {
536+ self . extract_lane :: < i8 > ( lane) . into ( )
537+ }
538+
539+ pub fn i8x16_extract_lane_u ( self , lane : ImmLaneIdx16 ) -> i32 {
540+ ( self . extract_lane :: < i8 > ( lane) as u8 ) . into ( )
541+ }
542+
543+ pub fn i32x4_replace_lane ( self , lane : ImmLaneIdx4 , item : i32 ) -> Self {
544+ self . replace_lane ( lane, item)
545+ }
546+
547+ pub fn i32x4_add ( lhs : Self , rhs : Self ) -> Self {
548+ Self :: lanewise_binary ( lhs, rhs, i32:: wrapping_add)
549+ }
550+
551+ pub fn i8x16_add ( lhs : Self , rhs : Self ) -> Self {
552+ Self :: lanewise_binary ( lhs, rhs, i8:: wrapping_add)
553+ }
554+
555+ pub fn i32x4_lt_s ( lhs : Self , rhs : Self ) -> Self {
556+ Self :: lanewise_comparison ( lhs, rhs, wasm:: i32_lt_s)
557+ }
558+
559+ pub fn i32x4_neg ( self ) -> Self {
560+ Self :: lanewise_unary ( self , |x : i32 | -x)
561+ }
562+
563+ pub fn i32x4_dot_i16x8_s ( self , rhs : Self ) -> Self {
564+ fn dot ( a : [ i16 ; 2 ] , b : [ i16 ; 2 ] ) -> i32 {
565+ let dot0 = i32:: from ( a[ 0 ] ) . wrapping_mul ( i32:: from ( b[ 0 ] ) ) ;
566+ let dot1 = i32:: from ( a[ 1 ] ) . wrapping_mul ( i32:: from ( b[ 1 ] ) ) ;
567+ dot0. wrapping_add ( dot1)
568+ }
569+ Self :: lanewise_widening_binary :: < I32x4 > ( self , rhs, dot)
570+ }
571+ }
572+
573+ #[ test]
574+ fn it_works ( ) {
575+ let v0 = V128 :: splat ( 16383_i16 ) ;
576+ let v1 = V128 :: splat ( 16384_i16 ) ;
577+ let result = v0. i32x4_dot_i16x8_s ( v1) ;
578+ assert_eq ! ( result, V128 :: splat( 536838144_i32 ) ) ;
526579}
0 commit comments