@@ -5,6 +5,10 @@ type c_int = i16;
55#[ cfg( not( target_pointer_width = "16" ) ) ]
66type c_int = i32 ;
77
8+ use core:: intrinsics:: { atomic_load_unordered, atomic_store_unordered, unchecked_div} ;
9+ use core:: mem;
10+ use core:: ops:: { BitOr , Shl } ;
11+
812#[ cfg_attr( all( feature = "mem" , not( feature = "mangled-names" ) ) , no_mangle) ]
913pub unsafe extern "C" fn memcpy ( dest : * mut u8 , src : * const u8 , n : usize ) -> * mut u8 {
1014 let mut i = 0 ;
@@ -58,3 +62,105 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
5862 }
5963 0
6064}
65+
66+ fn memcpy_element_unordered_atomic < T : Copy > ( dest : * mut T , src : * const T , bytes : usize ) {
67+ unsafe {
68+ let n = unchecked_div ( bytes, mem:: size_of :: < T > ( ) ) ;
69+ let mut i = 0 ;
70+ while i < n {
71+ atomic_store_unordered ( dest. add ( i) , atomic_load_unordered ( src. add ( i) ) ) ;
72+ i += 1 ;
73+ }
74+ }
75+ }
76+
77+ fn memmove_element_unordered_atomic < T : Copy > ( dest : * mut T , src : * const T , bytes : usize ) {
78+ unsafe {
79+ let n = unchecked_div ( bytes, mem:: size_of :: < T > ( ) ) ;
80+ if src < dest as * const T {
81+ // copy from end
82+ let mut i = n;
83+ while i != 0 {
84+ i -= 1 ;
85+ atomic_store_unordered ( dest. add ( i) , atomic_load_unordered ( src. add ( i) ) ) ;
86+ }
87+ } else {
88+ // copy from beginning
89+ let mut i = 0 ;
90+ while i < n {
91+ atomic_store_unordered ( dest. add ( i) , atomic_load_unordered ( src. add ( i) ) ) ;
92+ i += 1 ;
93+ }
94+ }
95+ }
96+ }
97+
98+ fn memset_element_unordered_atomic < T > ( s : * mut T , c : u8 , bytes : usize )
99+ where
100+ T : Copy + From < u8 > + Shl < u32 , Output = T > + BitOr < T , Output = T > ,
101+ {
102+ unsafe {
103+ let n = unchecked_div ( bytes, mem:: size_of :: < T > ( ) ) ;
104+ let mut x = T :: from ( c) ;
105+ let mut i = 1 ;
106+ while i < mem:: size_of :: < T > ( ) {
107+ x = x << 8 | T :: from ( c) ;
108+ i += 1 ;
109+ }
110+ let mut i = 0 ;
111+ while i < n {
112+ atomic_store_unordered ( s. add ( i) , x) ;
113+ i += 1 ;
114+ }
115+ }
116+ }
117+
118+ intrinsics ! {
119+ pub extern "C" fn __llvm_memcpy_element_unordered_atomic_1( dest: * mut u8 , src: * const u8 , bytes: usize ) -> ( ) {
120+ memcpy_element_unordered_atomic( dest, src, bytes) ;
121+ }
122+ pub extern "C" fn __llvm_memcpy_element_unordered_atomic_2( dest: * mut u16 , src: * const u16 , bytes: usize ) -> ( ) {
123+ memcpy_element_unordered_atomic( dest, src, bytes) ;
124+ }
125+ pub extern "C" fn __llvm_memcpy_element_unordered_atomic_4( dest: * mut u32 , src: * const u32 , bytes: usize ) -> ( ) {
126+ memcpy_element_unordered_atomic( dest, src, bytes) ;
127+ }
128+ pub extern "C" fn __llvm_memcpy_element_unordered_atomic_8( dest: * mut u64 , src: * const u64 , bytes: usize ) -> ( ) {
129+ memcpy_element_unordered_atomic( dest, src, bytes) ;
130+ }
131+ pub extern "C" fn __llvm_memcpy_element_unordered_atomic_16( dest: * mut u128 , src: * const u128 , bytes: usize ) -> ( ) {
132+ memcpy_element_unordered_atomic( dest, src, bytes) ;
133+ }
134+
135+ pub extern "C" fn __llvm_memmove_element_unordered_atomic_1( dest: * mut u8 , src: * const u8 , bytes: usize ) -> ( ) {
136+ memmove_element_unordered_atomic( dest, src, bytes) ;
137+ }
138+ pub extern "C" fn __llvm_memmove_element_unordered_atomic_2( dest: * mut u16 , src: * const u16 , bytes: usize ) -> ( ) {
139+ memmove_element_unordered_atomic( dest, src, bytes) ;
140+ }
141+ pub extern "C" fn __llvm_memmove_element_unordered_atomic_4( dest: * mut u32 , src: * const u32 , bytes: usize ) -> ( ) {
142+ memmove_element_unordered_atomic( dest, src, bytes) ;
143+ }
144+ pub extern "C" fn __llvm_memmove_element_unordered_atomic_8( dest: * mut u64 , src: * const u64 , bytes: usize ) -> ( ) {
145+ memmove_element_unordered_atomic( dest, src, bytes) ;
146+ }
147+ pub extern "C" fn __llvm_memmove_element_unordered_atomic_16( dest: * mut u128 , src: * const u128 , bytes: usize ) -> ( ) {
148+ memmove_element_unordered_atomic( dest, src, bytes) ;
149+ }
150+
151+ pub extern "C" fn __llvm_memset_element_unordered_atomic_1( s: * mut u8 , c: u8 , bytes: usize ) -> ( ) {
152+ memset_element_unordered_atomic( s, c, bytes) ;
153+ }
154+ pub extern "C" fn __llvm_memset_element_unordered_atomic_2( s: * mut u16 , c: u8 , bytes: usize ) -> ( ) {
155+ memset_element_unordered_atomic( s, c, bytes) ;
156+ }
157+ pub extern "C" fn __llvm_memset_element_unordered_atomic_4( s: * mut u32 , c: u8 , bytes: usize ) -> ( ) {
158+ memset_element_unordered_atomic( s, c, bytes) ;
159+ }
160+ pub extern "C" fn __llvm_memset_element_unordered_atomic_8( s: * mut u64 , c: u8 , bytes: usize ) -> ( ) {
161+ memset_element_unordered_atomic( s, c, bytes) ;
162+ }
163+ pub extern "C" fn __llvm_memset_element_unordered_atomic_16( s: * mut u128 , c: u8 , bytes: usize ) -> ( ) {
164+ memset_element_unordered_atomic( s, c, bytes) ;
165+ }
166+ }
0 commit comments