@@ -76,90 +76,200 @@ intrinsics! {
7676 ) ;
7777 }
7878
79- // FIXME: The `*4` and `*8` variants should be defined as aliases.
79+ // FIXME(arm) : The `*4` and `*8` variants should be defined as aliases.
8080
81+ /// `memcpy` provided with the `aapcs` ABI.
82+ ///
83+ /// # Safety
84+ ///
85+ /// Usual `memcpy` requirements apply.
8186 #[ cfg( not( target_vendor = "apple" ) ) ]
82- pub unsafe extern "aapcs" fn __aeabi_memcpy( dest: * mut u8 , src: * const u8 , n: usize ) {
83- crate :: mem:: memcpy( dest, src, n) ;
87+ pub unsafe extern "aapcs" fn __aeabi_memcpy( dst: * mut u8 , src: * const u8 , n: usize ) {
88+ // SAFETY: memcpy preconditions apply.
89+ unsafe { crate :: mem:: memcpy( dst, src, n) } ;
8490 }
8591
92+ /// `memcpy` for 4-byte alignment.
93+ ///
94+ /// # Safety
95+ ///
96+ /// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
97+ /// four bytes.
8698 #[ cfg( not( target_vendor = "apple" ) ) ]
87- pub unsafe extern "aapcs" fn __aeabi_memcpy4( dest : * mut u8 , src: * const u8 , n: usize ) {
99+ pub unsafe extern "aapcs" fn __aeabi_memcpy4( dst : * mut u8 , src: * const u8 , n: usize ) {
88100 // We are guaranteed 4-alignment, so accessing at u32 is okay.
89- let mut dest = dest as * mut u32 ;
90- let mut src = src as * mut u32 ;
101+ let mut dst = dst. cast:: <u32 >( ) ;
102+ let mut src = src. cast:: <u32 >( ) ;
103+ debug_assert!( dst. is_aligned( ) ) ;
104+ debug_assert!( src. is_aligned( ) ) ;
91105 let mut n = n;
92106
93107 while n >= 4 {
94- * dest = * src;
95- dest = dest. offset( 1 ) ;
96- src = src. offset( 1 ) ;
108+ // SAFETY: `dst` and `src` are both valid for at least 4 bytes, from
109+ // `memcpy` preconditions and the loop guard.
110+ unsafe { * dst = * src } ;
111+
112+ // TODO
113+ unsafe {
114+ dst = dst. offset( 1 ) ;
115+ src = src. offset( 1 ) ;
116+ }
117+
97118 n -= 4 ;
98119 }
99120
100- __aeabi_memcpy( dest as * mut u8 , src as * const u8 , n) ;
121+ // SAFETY: `dst` and `src` will still be valid for `n` bytes
122+ unsafe { __aeabi_memcpy( dst. cast:: <u8 >( ) , src. cast:: <u8 >( ) , n) } ;
101123 }
102124
125+ /// `memcpy` for 8-byte alignment.
126+ ///
127+ /// # Safety
128+ ///
129+ /// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
130+ /// eight bytes.
103131 #[ cfg( not( target_vendor = "apple" ) ) ]
104- pub unsafe extern "aapcs" fn __aeabi_memcpy8( dest: * mut u8 , src: * const u8 , n: usize ) {
105- __aeabi_memcpy4( dest, src, n) ;
132+ pub unsafe extern "aapcs" fn __aeabi_memcpy8( dst: * mut u8 , src: * const u8 , n: usize ) {
133+ debug_assert!( dst. addr( ) & 7 == 0 ) ;
134+ debug_assert!( src. addr( ) & 7 == 0 ) ;
135+
136+ // SAFETY: memcpy preconditions apply, less strict alignment.
137+ unsafe { __aeabi_memcpy4( dst, src, n) } ;
106138 }
107139
140+ /// `memmove` provided with the `aapcs` ABI.
141+ ///
142+ /// # Safety
143+ ///
144+ /// Usual `memmove` requirements apply.
108145 #[ cfg( not( target_vendor = "apple" ) ) ]
109- pub unsafe extern "aapcs" fn __aeabi_memmove( dest: * mut u8 , src: * const u8 , n: usize ) {
110- crate :: mem:: memmove( dest, src, n) ;
146+ pub unsafe extern "aapcs" fn __aeabi_memmove( dst: * mut u8 , src: * const u8 , n: usize ) {
147+ // SAFETY: memmove preconditions apply.
148+ unsafe { crate :: mem:: memmove( dst, src, n) } ;
111149 }
112150
151+ /// `memmove` for 4-byte alignment.
152+ ///
153+ /// # Safety
154+ ///
155+ /// Usual `memmove` requirements apply. Additionally, `dest` and `src` must be aligned to
156+ /// four bytes.
113157 #[ cfg( not( any( target_vendor = "apple" , target_env = "msvc" ) ) ) ]
114- pub unsafe extern "aapcs" fn __aeabi_memmove4( dest: * mut u8 , src: * const u8 , n: usize ) {
115- __aeabi_memmove( dest, src, n) ;
158+ pub unsafe extern "aapcs" fn __aeabi_memmove4( dst: * mut u8 , src: * const u8 , n: usize ) {
159+ debug_assert!( dst. addr( ) & 3 == 0 ) ;
160+ debug_assert!( src. addr( ) & 3 == 0 ) ;
161+
162+ // SAFETY: same preconditions, less strict aligment.
163+ unsafe { __aeabi_memmove( dst, src, n) } ;
116164 }
117165
166+ /// `memmove` for 8-byte alignment.
167+ ///
168+ /// # Safety
169+ ///
170+ /// Usual `memmove` requirements apply. Additionally, `dst` and `src` must be aligned to
171+ /// eight bytes.
118172 #[ cfg( not( any( target_vendor = "apple" , target_env = "msvc" ) ) ) ]
119- pub unsafe extern "aapcs" fn __aeabi_memmove8( dest: * mut u8 , src: * const u8 , n: usize ) {
120- __aeabi_memmove( dest, src, n) ;
173+ pub unsafe extern "aapcs" fn __aeabi_memmove8( dst: * mut u8 , src: * const u8 , n: usize ) {
174+ debug_assert!( dst. addr( ) & 7 == 0 ) ;
175+ debug_assert!( src. addr( ) & 7 == 0 ) ;
176+
177+ // SAFETY: memmove preconditions apply, less strict alignment.
178+ unsafe { __aeabi_memmove( dst, src, n) } ;
121179 }
122180
181+ /// `memset` provided with the `aapcs` ABI.
182+ ///
183+ /// # Safety
184+ ///
185+ /// Usual `memset` requirements apply.
123186 #[ cfg( not( target_vendor = "apple" ) ) ]
124- pub unsafe extern "aapcs" fn __aeabi_memset( dest : * mut u8 , n: usize , c: i32 ) {
187+ pub unsafe extern "aapcs" fn __aeabi_memset( dst : * mut u8 , n: usize , c: i32 ) {
125188 // Note the different argument order
126- crate :: mem:: memset( dest, c, n) ;
189+ // SAFETY: memset preconditions apply.
190+ unsafe { crate :: mem:: memset( dst, c, n) } ;
127191 }
128192
193+ /// `memset` for 4-byte alignment.
194+ ///
195+ /// # Safety
196+ ///
197+ /// Usual `memset` requirements apply. Additionally, `dest` and `src` must be aligned to
198+ /// four bytes.
129199 #[ cfg( not( target_vendor = "apple" ) ) ]
130- pub unsafe extern "aapcs" fn __aeabi_memset4( dest: * mut u8 , n: usize , c: i32 ) {
131- let mut dest = dest as * mut u32 ;
200+ pub unsafe extern "aapcs" fn __aeabi_memset4( dst: * mut u8 , n: usize , c: i32 ) {
201+ let mut dst = dst. cast:: <u32 >( ) ;
202+ debug_assert!( dst. is_aligned( ) ) ;
132203 let mut n = n;
133204
134205 let byte = ( c as u32 ) & 0xff ;
135206 let c = ( byte << 24 ) | ( byte << 16 ) | ( byte << 8 ) | byte;
136207
137208 while n >= 4 {
138- * dest = c;
139- dest = dest. offset( 1 ) ;
209+ // SAFETY: `dst` is valid for at least 4 bytes, from `memset` preconditions and
210+ // the loop guard.
211+ unsafe { * dst = c } ;
212+ // TODO
213+ unsafe {
214+ dst = dst. offset( 1 ) ;
215+ }
140216 n -= 4 ;
141217 }
142218
143- __aeabi_memset( dest as * mut u8 , n, byte as i32 ) ;
219+ // SAFETY: `dst` will still be valid for `n` bytes
220+ unsafe { __aeabi_memset( dst. cast:: <u8 >( ) , n, byte as i32 ) } ;
144221 }
145222
223+ /// `memset` for 8-byte alignment.
224+ ///
225+ /// # Safety
226+ ///
227+ /// Usual `memset` requirements apply. Additionally, `dst` and `src` must be aligned to
228+ /// eight bytes.
146229 #[ cfg( not( target_vendor = "apple" ) ) ]
147- pub unsafe extern "aapcs" fn __aeabi_memset8( dest: * mut u8 , n: usize , c: i32 ) {
148- __aeabi_memset4( dest, n, c) ;
230+ pub unsafe extern "aapcs" fn __aeabi_memset8( dst: * mut u8 , n: usize , c: i32 ) {
231+ debug_assert!( dst. addr( ) & 7 == 0 ) ;
232+
233+ // SAFETY: memset preconditions apply, less strict alignment.
234+ unsafe { __aeabi_memset4( dst, n, c) } ;
149235 }
150236
237+ /// `memclr` provided with the `aapcs` ABI.
238+ ///
239+ /// # Safety
240+ ///
241+ /// Usual `memclr` requirements apply.
151242 #[ cfg( not( target_vendor = "apple" ) ) ]
152- pub unsafe extern "aapcs" fn __aeabi_memclr( dest: * mut u8 , n: usize ) {
153- __aeabi_memset( dest, n, 0 ) ;
243+ pub unsafe extern "aapcs" fn __aeabi_memclr( dst: * mut u8 , n: usize ) {
244+ // SAFETY: memclr preconditions apply, less strict alignment.
245+ unsafe { __aeabi_memset( dst, n, 0 ) } ;
154246 }
155247
248+ /// `memclr` for 4-byte alignment.
249+ ///
250+ /// # Safety
251+ ///
252+ /// Usual `memclr` requirements apply. Additionally, `dest` and `src` must be aligned to
253+ /// four bytes.
156254 #[ cfg( not( any( target_vendor = "apple" , target_env = "msvc" ) ) ) ]
157- pub unsafe extern "aapcs" fn __aeabi_memclr4( dest: * mut u8 , n: usize ) {
158- __aeabi_memset4( dest, n, 0 ) ;
255+ pub unsafe extern "aapcs" fn __aeabi_memclr4( dst: * mut u8 , n: usize ) {
256+ debug_assert!( dst. addr( ) & 3 == 0 ) ;
257+
258+ // SAFETY: memclr preconditions apply, less strict alignment.
259+ unsafe { __aeabi_memset4( dst, n, 0 ) } ;
159260 }
160261
262+ /// `memclr` for 8-byte alignment.
263+ ///
264+ /// # Safety
265+ ///
266+ /// Usual `memclr` requirements apply. Additionally, `dst` and `src` must be aligned to
267+ /// eight bytes.
161268 #[ cfg( not( any( target_vendor = "apple" , target_env = "msvc" ) ) ) ]
162- pub unsafe extern "aapcs" fn __aeabi_memclr8( dest: * mut u8 , n: usize ) {
163- __aeabi_memset4( dest, n, 0 ) ;
269+ pub unsafe extern "aapcs" fn __aeabi_memclr8( dst: * mut u8 , n: usize ) {
270+ debug_assert!( dst. addr( ) & 7 == 0 ) ;
271+
272+ // SAFETY: memclr preconditions apply, less strict alignment.
273+ unsafe { __aeabi_memset4( dst, n, 0 ) } ;
164274 }
165275}
0 commit comments