@@ -270,6 +270,32 @@ macro_rules! s_t_l {
270
270
} ;
271
271
}
272
272
273
+ macro_rules! t_t_l {
274
+ ( i32 ) => {
275
+ vector_signed_int
276
+ } ;
277
+ ( i16 ) => {
278
+ vector_signed_short
279
+ } ;
280
+ ( i8 ) => {
281
+ vector_signed_char
282
+ } ;
283
+
284
+ ( u32 ) => {
285
+ vector_unsigned_int
286
+ } ;
287
+ ( u16 ) => {
288
+ vector_unsigned_short
289
+ } ;
290
+ ( u8 ) => {
291
+ vector_unsigned_char
292
+ } ;
293
+
294
+ ( f32 ) => {
295
+ vector_float
296
+ } ;
297
+ }
298
+
273
299
macro_rules! impl_from {
274
300
( $s: ident) => {
275
301
impl From <$s> for s_t_l!( $s) {
@@ -412,6 +438,52 @@ mod sealed {
412
438
}
413
439
}
414
440
441
+ #[ inline( always) ]
442
+ unsafe fn load ( off : i32 , p : * const i8 ) -> u32x4 {
443
+ let addr = p. offset ( off as isize ) ;
444
+
445
+ * ( addr as * const u32x4 )
446
+ }
447
+
448
+ pub trait VectorLd {
449
+ type Result ;
450
+ unsafe fn vec_ld ( self , off : i32 ) -> Self :: Result ;
451
+ }
452
+
453
+ macro_rules! impl_vec_ld {
454
+ ( $fun: ident $ty: ident [ $instr: ident] ) => {
455
+ #[ inline]
456
+ #[ target_feature( enable = "altivec" ) ]
457
+ #[ cfg_attr( test, assert_instr( $instr) ) ]
458
+ pub unsafe fn $fun( off: i32 , p: * const $ty) -> t_t_l!( $ty) {
459
+ transmute( load( off, p as * const i8 ) )
460
+ }
461
+
462
+ impl VectorLd for * const $ty {
463
+ type Result = t_t_l!( $ty) ;
464
+ #[ inline]
465
+ #[ target_feature( enable = "altivec" ) ]
466
+ unsafe fn vec_ld( self , off: i32 ) -> Self :: Result {
467
+ $fun( off, self )
468
+ }
469
+ }
470
+ } ;
471
+ ( $fun: ident $ty: ident) => {
472
+ impl_vec_ld! { $fun $ty [ lvx] }
473
+ } ;
474
+ }
475
+
476
+ impl_vec_ld ! { vec_ld_u8 u8 }
477
+ impl_vec_ld ! { vec_ld_i8 i8 }
478
+
479
+ impl_vec_ld ! { vec_ld_u16 u16 }
480
+ impl_vec_ld ! { vec_ld_i16 i16 }
481
+
482
+ impl_vec_ld ! { vec_ld_u32 u32 }
483
+ impl_vec_ld ! { vec_ld_i32 i32 }
484
+
485
+ impl_vec_ld ! { vec_ld_f32 f32 }
486
+
415
487
test_impl ! { vec_floor( a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
416
488
417
489
test_impl ! { vec_vexptefp( a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1376,6 +1448,16 @@ mod sealed {
1376
1448
vector_mladd ! { vector_signed_short, vector_signed_short, vector_signed_short }
1377
1449
}
1378
1450
1451
+ /// Vector ld.
1452
+ #[ inline]
1453
+ #[ target_feature( enable = "altivec" ) ]
1454
+ pub unsafe fn vec_ld < T > ( off : i32 , p : T ) -> <T as sealed:: VectorLd >:: Result
1455
+ where
1456
+ T : sealed:: VectorLd ,
1457
+ {
1458
+ p. vec_ld ( off)
1459
+ }
1460
+
1379
1461
/// Vector floor.
1380
1462
#[ inline]
1381
1463
#[ target_feature( enable = "altivec" ) ]
@@ -1812,6 +1894,23 @@ mod tests {
1812
1894
}
1813
1895
}
1814
1896
1897
+ #[ simd_test( enable = "altivec" ) ]
1898
+ unsafe fn test_vec_ld ( ) {
1899
+ let pat = [
1900
+ u8x16:: new ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) ,
1901
+ u8x16:: new ( 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 )
1902
+ ] ;
1903
+
1904
+ for off in 0 ..16 {
1905
+ let v: u8x16 = transmute ( vec_ld ( 0 , ( pat. as_ptr ( ) as * const u8 ) . offset ( off) ) ) ;
1906
+ assert_eq ! ( v, u8x16:: new( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) ) ;
1907
+ }
1908
+ for off in 16 ..32 {
1909
+ let v: u8x16 = transmute ( vec_ld ( 0 , ( pat. as_ptr ( ) as * const u8 ) . offset ( off) ) ) ;
1910
+ assert_eq ! ( v, u8x16:: new( 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ) ) ;
1911
+ }
1912
+ }
1913
+
1815
1914
test_vec_1 ! { test_vec_floor, vec_floor, f32x4,
1816
1915
[ 1.1 , 1.9 , -0.5 , -0.9 ] ,
1817
1916
[ 1.0 , 1.0 , -1.0 , -1.0 ]
0 commit comments