x86_64.rs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #![allow(unused_imports)]
  2. use core::intrinsics;
  3. // NOTE These functions are implemented using assembly because they using a custom
  4. // calling convention which can't be implemented using a normal Rust function
  5. // NOTE These functions are never mangled as they are not tested against compiler-rt
  6. // and mangling ___chkstk would break the `jmp ___chkstk` instruction in __alloca
  7. #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))]
  8. #[naked]
  9. #[no_mangle]
  10. pub unsafe fn ___chkstk_ms() {
  11. asm!("
  12. push %rcx
  13. push %rax
  14. cmp $$0x1000,%rax
  15. lea 24(%rsp),%rcx
  16. jb 1f
  17. 2:
  18. sub $$0x1000,%rcx
  19. test %rcx,(%rcx)
  20. sub $$0x1000,%rax
  21. cmp $$0x1000,%rax
  22. ja 2b
  23. 1:
  24. sub %rax,%rcx
  25. test %rcx,(%rcx)
  26. pop %rax
  27. pop %rcx
  28. ret" ::: "memory" : "volatile");
  29. intrinsics::unreachable();
  30. }
  31. #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))]
  32. #[naked]
  33. #[no_mangle]
  34. pub unsafe fn __alloca() {
  35. asm!("mov %rcx,%rax // x64 _alloca is a normal function with parameter in rcx
  36. jmp ___chkstk // Jump to ___chkstk since fallthrough may be unreliable"
  37. ::: "memory" : "volatile");
  38. intrinsics::unreachable();
  39. }
  40. #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))]
  41. #[naked]
  42. #[no_mangle]
  43. pub unsafe fn ___chkstk() {
  44. asm!(
  45. "
  46. push %rcx
  47. cmp $$0x1000,%rax
  48. lea 16(%rsp),%rcx // rsp before calling this routine -> rcx
  49. jb 1f
  50. 2:
  51. sub $$0x1000,%rcx
  52. test %rcx,(%rcx)
  53. sub $$0x1000,%rax
  54. cmp $$0x1000,%rax
  55. ja 2b
  56. 1:
  57. sub %rax,%rcx
  58. test %rcx,(%rcx)
  59. lea 8(%rsp),%rax // load pointer to the return address into rax
  60. mov %rcx,%rsp // install the new top of stack pointer into rsp
  61. mov -8(%rax),%rcx // restore rcx
  62. push (%rax) // push return address onto the stack
  63. sub %rsp,%rax // restore the original value in rax
  64. ret"
  65. ::: "memory" : "volatile"
  66. );
  67. intrinsics::unreachable();
  68. }