@@ -61,6 +61,9 @@ extern "C" {
61
61
#[ link_name = "llvm.ppc.altivec.lvewx" ]
62
62
fn lvewx ( p : * const i8 ) -> vector_signed_int ;
63
63
64
+ #[ link_name = "llvm.ppc.altivec.lvxl" ]
65
+ fn lvxl ( p : * const i8 ) -> vector_unsigned_int ;
66
+
64
67
#[ link_name = "llvm.ppc.altivec.vperm" ]
65
68
fn vperm (
66
69
a : vector_signed_int ,
@@ -403,50 +406,56 @@ mod sealed {
403
406
}
404
407
}
405
408
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
-
412
409
pub trait VectorLd {
413
410
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 ;
415
413
}
416
414
417
415
macro_rules! impl_vec_ld {
418
- ( $fun: ident $ty : ident [ $instr : ident] ) => {
416
+ ( $fun: ident $fun_lru : ident $ty : ident) => {
419
417
#[ inline]
420
418
#[ 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) )
424
431
}
425
432
426
433
impl VectorLd for * const $ty {
427
434
type Result = t_t_l!( $ty) ;
428
435
#[ inline]
429
436
#[ 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 {
431
443
$fun( off, self )
432
444
}
433
445
}
434
446
} ;
435
- ( $fun: ident $ty: ident) => {
436
- impl_vec_ld! { $fun $ty [ lvx] }
437
- } ;
438
447
}
439
448
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 }
442
451
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 }
445
454
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 }
448
457
449
- impl_vec_ld ! { vec_ld_f32 f32 }
458
+ impl_vec_ld ! { vec_ld_f32 vec_ldl_f32 f32 }
450
459
451
460
pub trait VectorLde {
452
461
type Result ;
@@ -1953,16 +1962,26 @@ mod sealed {
1953
1962
impl_vec_trait ! { [ VectorNor vec_nor] 2 ( vec_vnorub, vec_vnorsb, vec_vnoruh, vec_vnorsh, vec_vnoruw, vec_vnorsw) }
1954
1963
}
1955
1964
1956
- /// Vector ld .
1965
+ /// Vector Load Indexed .
1957
1966
#[ inline]
1958
1967
#[ 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
1960
1969
where
1961
1970
T : sealed:: VectorLd ,
1962
1971
{
1963
1972
p. vec_ld ( off)
1964
1973
}
1965
1974
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
+
1966
1985
/// Vector Load Element Indexed.
1967
1986
#[ inline]
1968
1987
#[ target_feature( enable = "altivec" ) ]
@@ -2705,6 +2724,31 @@ mod tests {
2705
2724
}
2706
2725
}
2707
2726
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
+
2708
2752
#[ simd_test( enable = "altivec" ) ]
2709
2753
unsafe fn test_vec_lde ( ) {
2710
2754
let pat = [ u8x16:: new (
0 commit comments