@@ -16,6 +16,14 @@ const WORD_COPY_THRESHOLD: usize = if 2 * WORD_SIZE > 16 {
16
16
16
17
17
} ;
18
18
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
+
19
27
#[ inline( always) ]
20
28
pub unsafe fn copy_forward ( mut dest : * mut u8 , mut src : * const u8 , mut n : usize ) {
21
29
#[ inline( always) ]
@@ -41,6 +49,7 @@ pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, mut n: usize)
41
49
}
42
50
}
43
51
52
+ #[ cfg( not( feature = "mem-unaligned" ) ) ]
44
53
#[ inline( always) ]
45
54
unsafe fn copy_forward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
46
55
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)
69
78
}
70
79
}
71
80
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
+
72
95
if n >= WORD_COPY_THRESHOLD {
73
96
// Align dest
74
97
// 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) {
119
142
}
120
143
}
121
144
145
+ #[ cfg( not( feature = "mem-unaligned" ) ) ]
122
146
#[ inline( always) ]
123
147
unsafe fn copy_backward_misaligned_words ( dest : * mut u8 , src : * const u8 , n : usize ) {
124
148
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) {
147
171
}
148
172
}
149
173
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
+
150
188
let mut dest = dest. add ( n) ;
151
189
let mut src = src. add ( n) ;
152
190
0 commit comments