core/stdarch/crates/core_arch/src/powerpc64/
vsx.rs

1//! PowerPC Vector Scalar eXtensions (VSX) intrinsics.
2//!
3//! The references are: [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA
4//! NVlink)] and [POWER ISA v3.0B (for POWER9)].
5//!
6//! [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA NVlink)]: https://ibm.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u
7//! [POWER ISA v3.0B (for POWER9)]: https://ibm.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv
8
9#![allow(non_camel_case_types)]
10
11use crate::core_arch::powerpc::macros::*;
12use crate::core_arch::powerpc::*;
13
14#[cfg(test)]
15use stdarch_test::assert_instr;
16
17use crate::mem::transmute;
18
19#[allow(improper_ctypes)]
20extern "C" {
21    #[link_name = "llvm.ppc.vsx.lxvl"]
22    fn lxvl(a: *const u8, l: usize) -> vector_signed_int;
23
24    #[link_name = "llvm.ppc.vsx.stxvl"]
25    fn stxvl(v: vector_signed_int, a: *mut u8, l: usize);
26}
27
28mod sealed {
29    use super::*;
30
31    #[inline]
32    #[target_feature(enable = "power9-vector")]
33    #[cfg_attr(test, assert_instr(lxvl))]
34    unsafe fn vec_lxvl(p: *const u8, l: usize) -> vector_signed_int {
35        lxvl(p, l << 56)
36    }
37
38    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
39    pub trait VectorXloads {
40        type Result;
41        unsafe fn vec_xl_len(self, l: usize) -> Self::Result;
42    }
43
44    macro_rules! impl_vsx_loads {
45        ($ty:ident) => {
46            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
47            impl VectorXloads for *const $ty {
48                type Result = t_t_l!($ty);
49                #[inline]
50                #[target_feature(enable = "power9-vector")]
51                unsafe fn vec_xl_len(self, l: usize) -> Self::Result {
52                    transmute(vec_lxvl(self as *const u8, l))
53                }
54            }
55        };
56    }
57
58    impl_vsx_loads! { i8 }
59    impl_vsx_loads! { u8 }
60    impl_vsx_loads! { i16 }
61    impl_vsx_loads! { u16 }
62    impl_vsx_loads! { i32 }
63    impl_vsx_loads! { u32 }
64    impl_vsx_loads! { f32 }
65
66    #[inline]
67    #[target_feature(enable = "power9-vector")]
68    #[cfg_attr(test, assert_instr(stxvl))]
69    unsafe fn vec_stxvl(v: vector_signed_int, a: *mut u8, l: usize) {
70        stxvl(v, a, l << 56);
71    }
72
73    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
74    pub trait VectorXstores {
75        type Out;
76        unsafe fn vec_xst_len(self, p: Self::Out, l: usize);
77    }
78
79    macro_rules! impl_stores {
80        ($ty:ident) => {
81            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
82            impl VectorXstores for t_t_l!($ty) {
83                type Out = *mut $ty;
84                #[inline]
85                #[target_feature(enable = "power9-vector")]
86                unsafe fn vec_xst_len(self, a: Self::Out, l: usize) {
87                    stxvl(transmute(self), a as *mut u8, l)
88                }
89            }
90        };
91    }
92
93    impl_stores! { i8 }
94    impl_stores! { u8 }
95    impl_stores! { i16 }
96    impl_stores! { u16 }
97    impl_stores! { i32 }
98    impl_stores! { u32 }
99    impl_stores! { f32 }
100}
101
102/// Vector Load with Length
103///
104/// ## Purpose
105/// Loads a vector of a specified byte length.
106///
107/// ## Result value
108/// Loads the number of bytes specified by b from the address specified in a.
109/// Initializes elements in order from the byte stream (as defined by the endianness of the
110/// target). Any bytes of elements that cannot be initialized from the number of loaded bytes have
111/// a zero value.
112///
113/// Between 0 and 16 bytes, inclusive, will be loaded. The length is specified by the
114/// least-significant byte of b, as min (b mod 256, 16). The behavior is undefined if the length
115/// argument is outside of the range 0–255, or if it is not a multiple of the vector element size.
116///
117/// ## Notes
118/// vec_xl_len should not be used to load from cache-inhibited memory.
119#[inline]
120#[target_feature(enable = "power9-vector")]
121#[unstable(feature = "stdarch_powerpc", issue = "111145")]
122pub unsafe fn vec_xl_len<T>(p: T, len: usize) -> <T as sealed::VectorXloads>::Result
123where
124    T: sealed::VectorXloads,
125{
126    p.vec_xl_len(len)
127}
128
129/// Vector Store with Length
130///
131/// ## Purpose
132///
133/// Stores a vector of a specified byte length.
134///
135/// ## Operation
136///
137/// Stores the number of bytes specified by c of the vector a to the address specified
138/// in b. The bytes are obtained starting from the lowest-numbered byte of the lowest-numbered
139/// element (as defined by the endianness of the target). All bytes of an element are accessed
140/// before proceeding to the next higher element.
141///
142/// Between 0 and 16 bytes, inclusive, will be stored. The length is specified by the
143/// least-significant byte of c, as min (c mod 256, 16). The behavior is undefined if the length
144/// argument is outside of the range 0–255, or if it is not a multiple of the vector element size.
145///
146/// ## Notes
147/// vec_xst_len should not be used to store to cache-inhibited memory.
148#[inline]
149#[target_feature(enable = "power9-vector")]
150#[unstable(feature = "stdarch_powerpc", issue = "111145")]
151pub unsafe fn vec_xst_len<T>(v: T, a: <T as sealed::VectorXstores>::Out, l: usize)
152where
153    T: sealed::VectorXstores,
154{
155    v.vec_xst_len(a, l)
156}