arm.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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. #[naked]
  5. #[cfg_attr(not(test), no_mangle)]
  6. pub unsafe fn __aeabi_uidivmod() {
  7. asm!("push {lr}
  8. sub sp, sp, #4
  9. mov r2, sp
  10. bl __udivmodsi4
  11. ldr r1, [sp]
  12. add sp, sp, #4
  13. pop {pc}");
  14. intrinsics::unreachable();
  15. }
  16. #[naked]
  17. #[cfg_attr(not(test), no_mangle)]
  18. pub unsafe fn __aeabi_uldivmod() {
  19. asm!("push {r4, lr}
  20. sub sp, sp, #16
  21. add r4, sp, #8
  22. str r4, [sp]
  23. bl __udivmoddi4
  24. ldr r2, [sp, #8]
  25. ldr r3, [sp, #12]
  26. add sp, sp, #16
  27. pop {r4, pc}");
  28. intrinsics::unreachable();
  29. }
  30. #[naked]
  31. #[cfg_attr(not(test), no_mangle)]
  32. pub unsafe fn __aeabi_idivmod() {
  33. asm!("push {r0, r1, r4, lr}
  34. bl __divsi3
  35. pop {r1, r2}
  36. muls r2, r2, r0
  37. subs r1, r1, r2
  38. pop {r4, pc}");
  39. intrinsics::unreachable();
  40. }
  41. #[naked]
  42. #[cfg_attr(not(test), no_mangle)]
  43. pub unsafe fn __aeabi_ldivmod() {
  44. asm!("push {r4, lr}
  45. sub sp, sp, #16
  46. add r4, sp, #8
  47. str r4, [sp]
  48. bl __divmoddi4
  49. ldr r2, [sp, #8]
  50. ldr r3, [sp, #12]
  51. add sp, sp, #16
  52. pop {r4, pc}");
  53. intrinsics::unreachable();
  54. }
  55. // TODO: These two functions should be defined as aliases
  56. #[cfg_attr(not(test), no_mangle)]
  57. pub extern "C" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
  58. ::udiv::__udivsi3(a, b)
  59. }
  60. #[cfg_attr(not(test), no_mangle)]
  61. pub extern "C" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
  62. ::sdiv::__divsi3(a, b)
  63. }
  64. extern "C" {
  65. fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
  66. fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
  67. fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8;
  68. }
  69. // FIXME: The `*4` and `*8` variants should be defined as aliases.
  70. #[cfg_attr(not(test), no_mangle)]
  71. pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
  72. memcpy(dest, src, n);
  73. }
  74. #[cfg_attr(not(test), no_mangle)]
  75. pub unsafe extern "C" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) {
  76. memcpy(dest, src, n);
  77. }
  78. #[cfg_attr(not(test), no_mangle)]
  79. pub unsafe extern "C" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
  80. memcpy(dest, src, n);
  81. }
  82. #[cfg_attr(not(test), no_mangle)]
  83. pub unsafe extern "C" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
  84. memmove(dest, src, n);
  85. }
  86. #[cfg_attr(not(test), no_mangle)]
  87. pub unsafe extern "C" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
  88. memmove(dest, src, n);
  89. }
  90. #[cfg_attr(not(test), no_mangle)]
  91. pub unsafe extern "C" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
  92. memmove(dest, src, n);
  93. }
  94. // Note the different argument order
  95. #[cfg_attr(not(test), no_mangle)]
  96. pub unsafe extern "C" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
  97. memset(dest, c, n);
  98. }
  99. #[cfg_attr(not(test), no_mangle)]
  100. pub unsafe extern "C" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) {
  101. memset(dest, c, n);
  102. }
  103. #[cfg_attr(not(test), no_mangle)]
  104. pub unsafe extern "C" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
  105. memset(dest, c, n);
  106. }
  107. #[cfg_attr(not(test), no_mangle)]
  108. pub unsafe extern "C" fn __aeabi_memclr(dest: *mut u8, n: usize) {
  109. memset(dest, 0, n);
  110. }
  111. #[cfg_attr(not(test), no_mangle)]
  112. pub unsafe extern "C" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
  113. memset(dest, 0, n);
  114. }
  115. #[cfg_attr(not(test), no_mangle)]
  116. pub unsafe extern "C" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
  117. memset(dest, 0, n);
  118. }