arm.rs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. use core::intrinsics;
  2. // NOTE This function and the ones below are implemented using assembly because they using a custom
  3. // calling convention which can't be implemented using a normal Rust function.
  4. // NOTE The only difference between the iOS and non-iOS versions of those functions is that the iOS
  5. // versions use 3 leading underscores in the names of called functions instead of 2.
  6. #[cfg(not(any(target_os = "ios", target_env = "msvc")))]
  7. #[naked]
  8. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  9. pub unsafe fn __aeabi_uidivmod() {
  10. asm!("push {lr}
  11. sub sp, sp, #4
  12. mov r2, sp
  13. bl __udivmodsi4
  14. ldr r1, [sp]
  15. add sp, sp, #4
  16. pop {pc}" ::: "memory" : "volatile");
  17. intrinsics::unreachable();
  18. }
  19. #[cfg(target_os = "ios")]
  20. #[naked]
  21. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  22. pub unsafe fn __aeabi_uidivmod() {
  23. asm!("push {lr}
  24. sub sp, sp, #4
  25. mov r2, sp
  26. bl ___udivmodsi4
  27. ldr r1, [sp]
  28. add sp, sp, #4
  29. pop {pc}" ::: "memory" : "volatile");
  30. intrinsics::unreachable();
  31. }
  32. #[cfg(not(target_os = "ios"))]
  33. #[naked]
  34. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  35. pub unsafe fn __aeabi_uldivmod() {
  36. asm!("push {r4, lr}
  37. sub sp, sp, #16
  38. add r4, sp, #8
  39. str r4, [sp]
  40. bl __udivmoddi4
  41. ldr r2, [sp, #8]
  42. ldr r3, [sp, #12]
  43. add sp, sp, #16
  44. pop {r4, pc}" ::: "memory" : "volatile");
  45. intrinsics::unreachable();
  46. }
  47. #[cfg(target_os = "ios")]
  48. #[naked]
  49. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  50. pub unsafe fn __aeabi_uldivmod() {
  51. asm!("push {r4, lr}
  52. sub sp, sp, #16
  53. add r4, sp, #8
  54. str r4, [sp]
  55. bl ___udivmoddi4
  56. ldr r2, [sp, #8]
  57. ldr r3, [sp, #12]
  58. add sp, sp, #16
  59. pop {r4, pc}" ::: "memory" : "volatile");
  60. intrinsics::unreachable();
  61. }
  62. #[cfg(not(target_os = "ios"))]
  63. #[naked]
  64. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  65. pub unsafe fn __aeabi_idivmod() {
  66. asm!("push {r0, r1, r4, lr}
  67. bl __aeabi_idiv
  68. pop {r1, r2}
  69. muls r2, r2, r0
  70. subs r1, r1, r2
  71. pop {r4, pc}" ::: "memory" : "volatile");
  72. intrinsics::unreachable();
  73. }
  74. #[cfg(target_os = "ios")]
  75. #[naked]
  76. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  77. pub unsafe fn __aeabi_idivmod() {
  78. asm!("push {r0, r1, r4, lr}
  79. bl ___aeabi_idiv
  80. pop {r1, r2}
  81. muls r2, r2, r0
  82. subs r1, r1, r2
  83. pop {r4, pc}" ::: "memory" : "volatile");
  84. intrinsics::unreachable();
  85. }
  86. #[cfg(not(target_os = "ios"))]
  87. #[naked]
  88. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  89. pub unsafe fn __aeabi_ldivmod() {
  90. asm!("push {r4, lr}
  91. sub sp, sp, #16
  92. add r4, sp, #8
  93. str r4, [sp]
  94. bl __divmoddi4
  95. ldr r2, [sp, #8]
  96. ldr r3, [sp, #12]
  97. add sp, sp, #16
  98. pop {r4, pc}" ::: "memory" : "volatile");
  99. intrinsics::unreachable();
  100. }
  101. #[cfg(target_os = "ios")]
  102. #[naked]
  103. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  104. pub unsafe fn __aeabi_ldivmod() {
  105. asm!("push {r4, lr}
  106. sub sp, sp, #16
  107. add r4, sp, #8
  108. str r4, [sp]
  109. bl ___divmoddi4
  110. ldr r2, [sp, #8]
  111. ldr r3, [sp, #12]
  112. add sp, sp, #16
  113. pop {r4, pc}" ::: "memory" : "volatile");
  114. intrinsics::unreachable();
  115. }
  116. // FIXME: The `*4` and `*8` variants should be defined as aliases.
  117. #[cfg(not(target_os = "ios"))]
  118. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  119. #[cfg_attr(thumb, linkage = "weak")]
  120. pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
  121. ::mem::memcpy(dest, src, n);
  122. }
  123. #[cfg(not(target_os = "ios"))]
  124. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  125. #[cfg_attr(thumb, linkage = "weak")]
  126. pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, mut n: usize) {
  127. use core::ptr;
  128. let mut dest = dest as *mut u32;
  129. let mut src = src as *mut u32;
  130. while n >= 4 {
  131. ptr::write(dest, ptr::read(src));
  132. dest = dest.offset(1);
  133. src = src.offset(1);
  134. n -= 4;
  135. }
  136. __aeabi_memcpy(dest as *mut u8, src as *const u8, n);
  137. }
  138. #[cfg(not(target_os = "ios"))]
  139. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  140. #[cfg_attr(thumb, linkage = "weak")]
  141. pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
  142. __aeabi_memcpy4(dest, src, n);
  143. }
  144. #[cfg(not(target_os = "ios"))]
  145. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  146. #[cfg_attr(thumb, linkage = "weak")]
  147. pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
  148. ::mem::memmove(dest, src, n);
  149. }
  150. #[cfg(not(target_os = "ios"))]
  151. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  152. #[cfg_attr(thumb, linkage = "weak")]
  153. pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
  154. __aeabi_memmove(dest, src, n);
  155. }
  156. #[cfg(not(target_os = "ios"))]
  157. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  158. #[cfg_attr(thumb, linkage = "weak")]
  159. pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
  160. __aeabi_memmove(dest, src, n);
  161. }
  162. #[cfg(not(target_os = "ios"))]
  163. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  164. #[cfg_attr(thumb, linkage = "weak")]
  165. pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
  166. // Note the different argument order
  167. ::mem::memset(dest, c, n);
  168. }
  169. #[cfg(not(target_os = "ios"))]
  170. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  171. #[cfg_attr(thumb, linkage = "weak")]
  172. pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, mut n: usize, c: i32) {
  173. use core::ptr;
  174. let mut dest = dest as *mut u32;
  175. let byte = (c as u32) & 0xff;
  176. let c = (byte << 24) | (byte << 16) | (byte << 8) | byte;
  177. while n >= 4 {
  178. ptr::write(dest, c);
  179. dest = dest.offset(1);
  180. n -= 4;
  181. }
  182. __aeabi_memset(dest as *mut u8, n, byte as i32);
  183. }
  184. #[cfg(not(target_os = "ios"))]
  185. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  186. #[cfg_attr(thumb, linkage = "weak")]
  187. pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
  188. __aeabi_memset4(dest, n, c);
  189. }
  190. #[cfg(not(target_os = "ios"))]
  191. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  192. #[cfg_attr(thumb, linkage = "weak")]
  193. pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) {
  194. __aeabi_memset(dest, n, 0);
  195. }
  196. #[cfg(not(target_os = "ios"))]
  197. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  198. #[cfg_attr(thumb, linkage = "weak")]
  199. pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
  200. __aeabi_memset4(dest, n, 0);
  201. }
  202. #[cfg(not(target_os = "ios"))]
  203. #[cfg_attr(not(feature = "mangled-names"), no_mangle)]
  204. #[cfg_attr(thumb, linkage = "weak")]
  205. pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
  206. __aeabi_memset4(dest, n, 0);
  207. }