@@ -53,6 +53,14 @@ types! {
5353extern "C" {
5454 #[ link_name = "llvm.ppc.altivec.lvx" ]
5555 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+
5664 #[ link_name = "llvm.ppc.altivec.vperm" ]
5765 fn vperm (
5866 a : vector_signed_int ,
@@ -440,6 +448,43 @@ mod sealed {
440448
441449 impl_vec_ld ! { vec_ld_f32 f32 }
442450
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+
443488 test_impl ! { vec_floor( a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
444489
445490 test_impl ! { vec_vexptefp( a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1918,6 +1963,16 @@ where
19181963 p. vec_ld ( off)
19191964}
19201965
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+
19211976/// Vector floor.
19221977#[ inline]
19231978#[ target_feature( enable = "altivec" ) ]
@@ -2650,6 +2705,27 @@ mod tests {
26502705 }
26512706 }
26522707
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+
26532729 test_vec_1 ! { test_vec_floor, vec_floor, f32x4,
26542730 [ 1.1 , 1.9 , -0.5 , -0.9 ] ,
26552731 [ 1.0 , 1.0 , -1.0 , -1.0 ]
0 commit comments