]> git.proxmox.com Git - rustc.git/blob - vendor/packed_simd/src/api/swap_bytes.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / vendor / packed_simd / src / api / swap_bytes.rs
1 //! Horizontal swap bytes
2
3 macro_rules! impl_swap_bytes {
4 ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
5 impl $id {
6 /// Reverses the byte order of the vector.
7 #[inline]
8 pub fn swap_bytes(self) -> Self {
9 super::codegen::swap_bytes::SwapBytes::swap_bytes(self)
10 }
11
12 /// Converts self to little endian from the target's endianness.
13 ///
14 /// On little endian this is a no-op. On big endian the bytes are
15 /// swapped.
16 #[inline]
17 pub fn to_le(self) -> Self {
18 #[cfg(target_endian = "little")]
19 {
20 self
21 }
22 #[cfg(not(target_endian = "little"))]
23 {
24 self.swap_bytes()
25 }
26 }
27
28 /// Converts self to big endian from the target's endianness.
29 ///
30 /// On big endian this is a no-op. On little endian the bytes are
31 /// swapped.
32 #[inline]
33 pub fn to_be(self) -> Self {
34 #[cfg(target_endian = "big")]
35 {
36 self
37 }
38 #[cfg(not(target_endian = "big"))]
39 {
40 self.swap_bytes()
41 }
42 }
43
44 /// Converts a vector from little endian to the target's endianness.
45 ///
46 /// On little endian this is a no-op. On big endian the bytes are
47 /// swapped.
48 #[inline]
49 pub fn from_le(x: Self) -> Self {
50 #[cfg(target_endian = "little")]
51 {
52 x
53 }
54 #[cfg(not(target_endian = "little"))]
55 {
56 x.swap_bytes()
57 }
58 }
59
60 /// Converts a vector from big endian to the target's endianness.
61 ///
62 /// On big endian this is a no-op. On little endian the bytes are
63 /// swapped.
64 #[inline]
65 pub fn from_be(x: Self) -> Self {
66 #[cfg(target_endian = "big")]
67 {
68 x
69 }
70 #[cfg(not(target_endian = "big"))]
71 {
72 x.swap_bytes()
73 }
74 }
75 }
76
77 test_if! {
78 $test_tt:
79 paste::item_with_macros! {
80 pub mod [<$id _swap_bytes>] {
81 use super::*;
82
83 const BYTES: [u8; 64] = [
84 0, 1, 2, 3, 4, 5, 6, 7,
85 8, 9, 10, 11, 12, 13, 14, 15,
86 16, 17, 18, 19, 20, 21, 22, 23,
87 24, 25, 26, 27, 28, 29, 30, 31,
88 32, 33, 34, 35, 36, 37, 38, 39,
89 40, 41, 42, 43, 44, 45, 46, 47,
90 48, 49, 50, 51, 52, 53, 54, 55,
91 56, 57, 58, 59, 60, 61, 62, 63,
92 ];
93
94 macro_rules! swap {
95 ($func: ident) => {{
96 // catch possible future >512 vectors
97 assert!(mem::size_of::<$id>() <= 64);
98
99 let mut actual = BYTES;
100 let elems: &mut [$elem_ty] = unsafe {
101 slice::from_raw_parts_mut(
102 actual.as_mut_ptr() as *mut $elem_ty,
103 $id::lanes(),
104 )
105 };
106
107 let vec = $id::from_slice_unaligned(elems);
108 $id::$func(vec).write_to_slice_unaligned(elems);
109
110 actual
111 }};
112 }
113
114 macro_rules! test_swap {
115 ($func: ident) => {{
116 let actual = swap!($func);
117 let expected =
118 BYTES.iter().rev()
119 .skip(64 - crate::mem::size_of::<$id>());
120 assert!(actual.iter().zip(expected)
121 .all(|(x, y)| x == y));
122 }};
123 }
124
125 macro_rules! test_no_swap {
126 ($func: ident) => {{
127 let actual = swap!($func);
128 let expected = BYTES.iter()
129 .take(mem::size_of::<$id>());
130
131 assert!(actual.iter().zip(expected)
132 .all(|(x, y)| x == y));
133 }};
134 }
135
136 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
137 fn swap_bytes() {
138 test_swap!(swap_bytes);
139 }
140
141 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
142 fn to_le() {
143 #[cfg(target_endian = "little")]
144 {
145 test_no_swap!(to_le);
146 }
147 #[cfg(not(target_endian = "little"))]
148 {
149 test_swap!(to_le);
150 }
151 }
152
153 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
154 fn to_be() {
155 #[cfg(target_endian = "big")]
156 {
157 test_no_swap!(to_be);
158 }
159 #[cfg(not(target_endian = "big"))]
160 {
161 test_swap!(to_be);
162 }
163 }
164
165 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
166 fn from_le() {
167 #[cfg(target_endian = "little")]
168 {
169 test_no_swap!(from_le);
170 }
171 #[cfg(not(target_endian = "little"))]
172 {
173 test_swap!(from_le);
174 }
175 }
176
177 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
178 fn from_be() {
179 #[cfg(target_endian = "big")]
180 {
181 test_no_swap!(from_be);
182 }
183 #[cfg(not(target_endian = "big"))]
184 {
185 test_swap!(from_be);
186 }
187 }
188 }
189 }
190 }
191 };
192 }