@@ -16,6 +16,14 @@ const WORD_COPY_THRESHOLD: usize = if 2 * WORD_SIZE > 16 {
1616 16
1717} ;
1818
19+ #[ cfg( feature = "mem-unaligned" ) ]
20+ unsafe fn read_usize_unaligned ( x : * const usize ) -> usize {
21+ // Do not use `core::ptr::read_unaligned` here, since it calls `copy_nonoverlapping` which
22+ // is translated to memcpy in LLVM.
23+ let x_read = ( x as * const [ u8 ; core:: mem:: size_of :: < usize > ( ) ] ) . read ( ) ;
24+ core:: mem:: transmute ( x_read)
25+ }
26+
1927#[ inline( always) ]
2028pub unsafe fn copy_forward ( mut dest : * mut u8 , mut src : * const u8 , mut n : usize ) {
2129 #[ inline( always) ]
@@ -41,6 +49,7 @@ pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, mut n: usize)
4149 }
4250 }
4351
52+ #[ cfg( not( feature = "mem-unaligned" ) ) ]
4453 #[ inline( always) ]
4554 unsafe fn copy_forward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
4655 let mut dest_usize = dest as * mut usize ;
@@ -69,6 +78,20 @@ pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, mut n: usize)
6978 }
7079 }
7180
81+ #[ cfg( feature = "mem-unaligned" ) ]
82+ #[ inline( always) ]
83+ unsafe fn copy_forward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
84+ let mut dest_usize = dest as * mut usize ;
85+ let mut src_usize = src as * mut usize ;
86+ let dest_end = dest. add ( n) as * mut usize ;
87+
88+ while dest_usize < dest_end {
89+ * dest_usize = read_usize_unaligned ( src_usize) ;
90+ dest_usize = dest_usize. add ( 1 ) ;
91+ src_usize = src_usize. add ( 1 ) ;
92+ }
93+ }
94+
7295 if n >= WORD_COPY_THRESHOLD {
7396 // Align dest
7497 // Because of n >= 2 * WORD_SIZE, dst_misalignment < n
@@ -119,6 +142,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, mut n: usize) {
119142 }
120143 }
121144
145+ #[ cfg( not( feature = "mem-unaligned" ) ) ]
122146 #[ inline( always) ]
123147 unsafe fn copy_backward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
124148 let mut dest_usize = dest as * mut usize ;
@@ -147,6 +171,20 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, mut n: usize) {
147171 }
148172 }
149173
174+ #[ cfg( feature = "mem-unaligned" ) ]
175+ #[ inline( always) ]
176+ unsafe fn copy_backward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
177+ let mut dest_usize = dest as * mut usize ;
178+ let mut src_usize = src as * mut usize ;
179+ let dest_start = dest. sub ( n) as * mut usize ;
180+
181+ while dest_start < dest_usize {
182+ dest_usize = dest_usize. sub ( 1 ) ;
183+ src_usize = src_usize. sub ( 1 ) ;
184+ * dest_usize = read_usize_unaligned ( src_usize as * const u8 ) ;
185+ }
186+ }
187+
150188 let mut dest = dest. add ( n) ;
151189 let mut src = src. add ( n) ;
152190
0 commit comments