@@ -61,6 +61,9 @@ extern "C" {
6161 #[ link_name = "llvm.ppc.altivec.lvewx" ]
6262 fn lvewx ( p : * const i8 ) -> vector_signed_int ;
6363
64+ #[ link_name = "llvm.ppc.altivec.lvxl" ]
65+ fn lvxl ( p : * const i8 ) -> vector_unsigned_int ;
66+
6467 #[ link_name = "llvm.ppc.altivec.vperm" ]
6568 fn vperm (
6669 a : vector_signed_int ,
@@ -403,50 +406,56 @@ mod sealed {
403406 }
404407 }
405408
406- #[ inline( always) ]
407- unsafe fn load ( off : i32 , p : * const i8 ) -> u32x4 {
408- let addr = p. offset ( off as isize ) ;
409- transmute ( lvx ( addr) )
410- }
411-
412409 pub trait VectorLd {
413410 type Result ;
414- unsafe fn vec_ld ( self , off : i32 ) -> Self :: Result ;
411+ unsafe fn vec_ld ( self , off : isize ) -> Self :: Result ;
412+ unsafe fn vec_ldl ( self , off : isize ) -> Self :: Result ;
415413 }
416414
417415 macro_rules! impl_vec_ld {
418- ( $fun: ident $ty : ident [ $instr : ident] ) => {
416+ ( $fun: ident $fun_lru : ident $ty : ident) => {
419417 #[ inline]
420418 #[ target_feature( enable = "altivec" ) ]
421- #[ cfg_attr( test, assert_instr( $instr) ) ]
422- pub unsafe fn $fun( off: i32 , p: * const $ty) -> t_t_l!( $ty) {
423- transmute( load( off, p as * const i8 ) )
419+ #[ cfg_attr( test, assert_instr( lvx) ) ]
420+ pub unsafe fn $fun( off: isize , p: * const $ty) -> t_t_l!( $ty) {
421+ let addr = ( p as * const i8 ) . offset( off) ;
422+ transmute( lvx( addr) )
423+ }
424+
425+ #[ inline]
426+ #[ target_feature( enable = "altivec" ) ]
427+ #[ cfg_attr( test, assert_instr( lvxl) ) ]
428+ pub unsafe fn $fun_lru( off: i32 , p: * const $ty) -> t_t_l!( $ty) {
429+ let addr = ( p as * const i8 ) . offset( off as isize ) ;
430+ transmute( lvxl( addr) )
424431 }
425432
426433 impl VectorLd for * const $ty {
427434 type Result = t_t_l!( $ty) ;
428435 #[ inline]
429436 #[ target_feature( enable = "altivec" ) ]
430- unsafe fn vec_ld( self , off: i32 ) -> Self :: Result {
437+ unsafe fn vec_ld( self , off: isize ) -> Self :: Result {
438+ $fun( off, self )
439+ }
440+ #[ inline]
441+ #[ target_feature( enable = "altivec" ) ]
442+ unsafe fn vec_ldl( self , off: isize ) -> Self :: Result {
431443 $fun( off, self )
432444 }
433445 }
434446 } ;
435- ( $fun: ident $ty: ident) => {
436- impl_vec_ld! { $fun $ty [ lvx] }
437- } ;
438447 }
439448
440- impl_vec_ld ! { vec_ld_u8 u8 }
441- impl_vec_ld ! { vec_ld_i8 i8 }
449+ impl_vec_ld ! { vec_ld_u8 vec_ldl_u8 u8 }
450+ impl_vec_ld ! { vec_ld_i8 vec_ldl_i8 i8 }
442451
443- impl_vec_ld ! { vec_ld_u16 u16 }
444- impl_vec_ld ! { vec_ld_i16 i16 }
452+ impl_vec_ld ! { vec_ld_u16 vec_ldl_u16 u16 }
453+ impl_vec_ld ! { vec_ld_i16 vec_ldl_i16 i16 }
445454
446- impl_vec_ld ! { vec_ld_u32 u32 }
447- impl_vec_ld ! { vec_ld_i32 i32 }
455+ impl_vec_ld ! { vec_ld_u32 vec_ldl_u32 u32 }
456+ impl_vec_ld ! { vec_ld_i32 vec_ldl_i32 i32 }
448457
449- impl_vec_ld ! { vec_ld_f32 f32 }
458+ impl_vec_ld ! { vec_ld_f32 vec_ldl_f32 f32 }
450459
451460 pub trait VectorLde {
452461 type Result ;
@@ -1953,16 +1962,26 @@ mod sealed {
19531962 impl_vec_trait ! { [ VectorNor vec_nor] 2 ( vec_vnorub, vec_vnorsb, vec_vnoruh, vec_vnorsh, vec_vnoruw, vec_vnorsw) }
19541963}
19551964
1956- /// Vector ld .
1965+ /// Vector Load Indexed .
19571966#[ inline]
19581967#[ target_feature( enable = "altivec" ) ]
1959- pub unsafe fn vec_ld < T > ( off : i32 , p : T ) -> <T as sealed:: VectorLd >:: Result
1968+ pub unsafe fn vec_ld < T > ( off : isize , p : T ) -> <T as sealed:: VectorLd >:: Result
19601969where
19611970 T : sealed:: VectorLd ,
19621971{
19631972 p. vec_ld ( off)
19641973}
19651974
1975+ /// Vector Load Indexed Least Recently Used.
1976+ #[ inline]
1977+ #[ target_feature( enable = "altivec" ) ]
1978+ pub unsafe fn vec_ldl < T > ( off : isize , p : T ) -> <T as sealed:: VectorLd >:: Result
1979+ where
1980+ T : sealed:: VectorLd ,
1981+ {
1982+ p. vec_ldl ( off)
1983+ }
1984+
19661985/// Vector Load Element Indexed.
19671986#[ inline]
19681987#[ target_feature( enable = "altivec" ) ]
@@ -2705,6 +2724,31 @@ mod tests {
27052724 }
27062725 }
27072726
2727+ #[ simd_test( enable = "altivec" ) ]
2728+ unsafe fn test_vec_ldl ( ) {
2729+ let pat = [
2730+ u8x16:: new ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) ,
2731+ u8x16:: new (
2732+ 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ,
2733+ ) ,
2734+ ] ;
2735+
2736+ for off in 0 ..16 {
2737+ let v: u8x16 = transmute ( vec_ldl ( 0 , ( pat. as_ptr ( ) as * const u8 ) . offset ( off) ) ) ;
2738+ assert_eq ! (
2739+ v,
2740+ u8x16:: new( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 )
2741+ ) ;
2742+ }
2743+ for off in 16 ..32 {
2744+ let v: u8x16 = transmute ( vec_ldl ( 0 , ( pat. as_ptr ( ) as * const u8 ) . offset ( off) ) ) ;
2745+ assert_eq ! (
2746+ v,
2747+ u8x16:: new( 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 )
2748+ ) ;
2749+ }
2750+ }
2751+
27082752 #[ simd_test( enable = "altivec" ) ]
27092753 unsafe fn test_vec_lde ( ) {
27102754 let pat = [ u8x16:: new (
0 commit comments