rustix/backend/linux_raw/
reg.rs1#![allow(unsafe_code)]
14
15use super::c;
16use super::fd::RawFd;
17use core::marker::PhantomData;
18use core::ops::Range;
19
20pub(super) trait ToAsm: private::Sealed {
21 #[must_use]
29 unsafe fn to_asm(self) -> *mut Opaque;
30}
31
32pub(super) trait FromAsm: private::Sealed {
33 #[must_use]
41 unsafe fn from_asm(raw: *mut Opaque) -> Self;
42}
43
44#[repr(transparent)]
48#[allow(dead_code)]
49pub(super) struct Opaque(c::c_void);
50
51pub(super) struct A0(());
53pub(super) struct A1(());
54pub(super) struct A2(());
55pub(super) struct A3(());
56pub(super) struct A4(());
57pub(super) struct A5(());
58#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))]
59pub(super) struct A6(());
60#[cfg(target_arch = "x86")]
61pub(super) struct SocketArg;
62
63pub(super) trait ArgNumber: private::Sealed {}
64impl ArgNumber for A0 {}
65impl ArgNumber for A1 {}
66impl ArgNumber for A2 {}
67impl ArgNumber for A3 {}
68impl ArgNumber for A4 {}
69impl ArgNumber for A5 {}
70#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))]
71impl ArgNumber for A6 {}
72#[cfg(target_arch = "x86")]
73impl ArgNumber for SocketArg {}
74
75pub(super) struct R0(());
77
78pub(super) trait RetNumber: private::Sealed {}
79impl RetNumber for R0 {}
80
81#[repr(transparent)]
88#[must_use]
89pub(super) struct ArgReg<'a, Num: ArgNumber> {
90 raw: *mut Opaque,
91 _phantom: PhantomData<(&'a (), Num)>,
92}
93
94impl<'a, Num: ArgNumber> ToAsm for ArgReg<'a, Num> {
95 #[inline]
96 unsafe fn to_asm(self) -> *mut Opaque {
97 self.raw
98 }
99}
100
101#[repr(transparent)]
107#[must_use]
108pub(super) struct RetReg<Num: RetNumber> {
109 raw: *mut Opaque,
110 _phantom: PhantomData<Num>,
111}
112
113impl<Num: RetNumber> RetReg<Num> {
114 #[inline]
115 pub(super) fn decode_usize(self) -> usize {
116 debug_assert!(!(-4095..0).contains(&(self.raw as isize)));
117 self.raw as usize
118 }
119
120 #[inline]
121 pub(super) fn decode_raw_fd(self) -> RawFd {
122 let bits = self.decode_usize();
123 let raw_fd = bits as RawFd;
124
125 debug_assert_eq!(raw_fd as usize, bits);
127
128 raw_fd
129 }
130
131 #[inline]
132 pub(super) fn decode_c_int(self) -> c::c_int {
133 let bits = self.decode_usize();
134 let c_int_ = bits as c::c_int;
135
136 debug_assert_eq!(c_int_ as usize, bits);
138
139 c_int_
140 }
141
142 #[inline]
143 pub(super) fn decode_c_uint(self) -> c::c_uint {
144 let bits = self.decode_usize();
145 let c_uint_ = bits as c::c_uint;
146
147 debug_assert_eq!(c_uint_ as usize, bits);
149
150 c_uint_
151 }
152
153 #[inline]
154 pub(super) fn decode_void_star(self) -> *mut c::c_void {
155 self.raw.cast()
156 }
157
158 #[cfg(target_pointer_width = "64")]
159 #[inline]
160 pub(super) fn decode_u64(self) -> u64 {
161 self.decode_usize() as u64
162 }
163
164 #[inline]
165 pub(super) fn decode_void(self) {
166 let ignore = self.decode_usize();
167 debug_assert_eq!(ignore, 0);
168 }
169
170 #[inline]
171 pub(super) fn decode_error_code(self) -> u16 {
172 let bits = self.raw as usize;
173
174 debug_assert!((-4095..0).contains(&(bits as isize)));
177
178 bits as u16
179 }
180
181 #[inline]
182 pub(super) fn is_nonzero(&self) -> bool {
183 !self.raw.is_null()
184 }
185
186 #[inline]
187 pub(super) fn is_negative(&self) -> bool {
188 (self.raw as isize) < 0
189 }
190
191 #[inline]
192 pub(super) fn is_in_range(&self, range: Range<isize>) -> bool {
193 range.contains(&(self.raw as isize))
194 }
195}
196
197impl<Num: RetNumber> FromAsm for RetReg<Num> {
198 #[inline]
199 unsafe fn from_asm(raw: *mut Opaque) -> Self {
200 Self {
201 raw,
202 _phantom: PhantomData,
203 }
204 }
205}
206
207#[repr(transparent)]
208pub(super) struct SyscallNumber<'a> {
209 pub(super) nr: usize,
210 _phantom: PhantomData<&'a ()>,
211}
212
213impl<'a> ToAsm for SyscallNumber<'a> {
214 #[inline]
215 unsafe fn to_asm(self) -> *mut Opaque {
216 self.nr as usize as *mut Opaque
217 }
218}
219
220#[inline]
222pub(super) fn raw_arg<'a, Num: ArgNumber>(raw: *mut Opaque) -> ArgReg<'a, Num> {
223 ArgReg {
224 raw,
225 _phantom: PhantomData,
226 }
227}
228
229#[inline]
231pub(super) const fn nr<'a>(nr: u32) -> SyscallNumber<'a> {
232 SyscallNumber {
233 nr: nr as usize,
234 _phantom: PhantomData,
235 }
236}
237
238mod private {
242 pub trait Sealed {}
243
244 impl<'a, Num: super::ArgNumber> Sealed for super::ArgReg<'a, Num> {}
246 impl<Num: super::RetNumber> Sealed for super::RetReg<Num> {}
247 impl<'a> Sealed for super::SyscallNumber<'a> {}
248 impl Sealed for super::A0 {}
249 impl Sealed for super::A1 {}
250 impl Sealed for super::A2 {}
251 impl Sealed for super::A3 {}
252 impl Sealed for super::A4 {}
253 impl Sealed for super::A5 {}
254 #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))]
255 impl Sealed for super::A6 {}
256 #[cfg(target_arch = "x86")]
257 impl Sealed for super::SocketArg {}
258 impl Sealed for super::R0 {}
259}