@@ -53,6 +53,14 @@ types! {
53
53
extern "C" {
54
54
#[ link_name = "llvm.ppc.altivec.lvx" ]
55
55
fn lvx ( p : * const i8 ) -> vector_unsigned_int ;
56
+
57
+ #[ link_name = "llvm.ppc.altivec.lvebx" ]
58
+ fn lvebx ( p : * const i8 ) -> vector_signed_char ;
59
+ #[ link_name = "llvm.ppc.altivec.lvehx" ]
60
+ fn lvehx ( p : * const i8 ) -> vector_signed_short ;
61
+ #[ link_name = "llvm.ppc.altivec.lvewx" ]
62
+ fn lvewx ( p : * const i8 ) -> vector_signed_int ;
63
+
56
64
#[ link_name = "llvm.ppc.altivec.vperm" ]
57
65
fn vperm (
58
66
a : vector_signed_int ,
@@ -440,6 +448,43 @@ mod sealed {
440
448
441
449
impl_vec_ld ! { vec_ld_f32 f32 }
442
450
451
+ pub trait VectorLde {
452
+ type Result ;
453
+ unsafe fn vec_lde ( self , a : isize ) -> Self :: Result ;
454
+ }
455
+
456
+ macro_rules! impl_vec_lde {
457
+ ( $fun: ident $instr: ident $ty: ident) => {
458
+ #[ inline]
459
+ #[ target_feature( enable = "altivec" ) ]
460
+ #[ cfg_attr( test, assert_instr( $instr) ) ]
461
+ pub unsafe fn $fun( a: isize , b: * const $ty) -> t_t_l!( $ty) {
462
+ let addr = ( b as * const i8 ) . offset( a) ;
463
+ transmute( $instr( addr) )
464
+ }
465
+
466
+ impl VectorLde for * const $ty {
467
+ type Result = t_t_l!( $ty) ;
468
+ #[ inline]
469
+ #[ target_feature( enable = "altivec" ) ]
470
+ unsafe fn vec_lde( self , a: isize ) -> Self :: Result {
471
+ $fun( a, self )
472
+ }
473
+ }
474
+ } ;
475
+ }
476
+
477
+ impl_vec_lde ! { vec_lde_u8 lvebx u8 }
478
+ impl_vec_lde ! { vec_lde_i8 lvebx i8 }
479
+
480
+ impl_vec_lde ! { vec_lde_u16 lvehx u16 }
481
+ impl_vec_lde ! { vec_lde_i16 lvehx i16 }
482
+
483
+ impl_vec_lde ! { vec_lde_u32 lvewx u32 }
484
+ impl_vec_lde ! { vec_lde_i32 lvewx i32 }
485
+
486
+ impl_vec_lde ! { vec_lde_f32 lvewx f32 }
487
+
443
488
test_impl ! { vec_floor( a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
444
489
445
490
test_impl ! { vec_vexptefp( a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1918,6 +1963,16 @@ where
1918
1963
p. vec_ld ( off)
1919
1964
}
1920
1965
1966
+ /// Vector Load Element Indexed.
1967
+ #[ inline]
1968
+ #[ target_feature( enable = "altivec" ) ]
1969
+ pub unsafe fn vec_lde < T > ( off : isize , p : T ) -> <T as sealed:: VectorLde >:: Result
1970
+ where
1971
+ T : sealed:: VectorLde ,
1972
+ {
1973
+ p. vec_lde ( off)
1974
+ }
1975
+
1921
1976
/// Vector floor.
1922
1977
#[ inline]
1923
1978
#[ target_feature( enable = "altivec" ) ]
@@ -2650,6 +2705,27 @@ mod tests {
2650
2705
}
2651
2706
}
2652
2707
2708
+ #[ simd_test( enable = "altivec" ) ]
2709
+ unsafe fn test_vec_lde ( ) {
2710
+ let pat = [ u8x16:: new (
2711
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ,
2712
+ ) ] ;
2713
+ for off in 0 ..16 {
2714
+ let v: u8x16 = transmute ( vec_lde ( off, pat. as_ptr ( ) as * const u8 ) ) ;
2715
+ assert_eq ! ( off as u8 , v. extract( off as _) ) ;
2716
+ }
2717
+ let pat = [ u16x8:: new ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ] ;
2718
+ for off in 0 ..8 {
2719
+ let v: u16x8 = transmute ( vec_lde ( off * 2 , pat. as_ptr ( ) as * const u8 ) ) ;
2720
+ assert_eq ! ( off as u16 , v. extract( off as _) ) ;
2721
+ }
2722
+ let pat = [ u32x4:: new ( 0 , 1 , 2 , 3 ) ] ;
2723
+ for off in 0 ..4 {
2724
+ let v: u32x4 = transmute ( vec_lde ( off * 4 , pat. as_ptr ( ) as * const u8 ) ) ;
2725
+ assert_eq ! ( off as u32 , v. extract( off as _) ) ;
2726
+ }
2727
+ }
2728
+
2653
2729
test_vec_1 ! { test_vec_floor, vec_floor, f32x4,
2654
2730
[ 1.1 , 1.9 , -0.5 , -0.9 ] ,
2655
2731
[ 1.0 , 1.0 , -1.0 , -1.0 ]
0 commit comments