General Purpose library for Freestanding C++ and POSIX systems
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

72 行
1.5 KiB

  1. #pragma once
  2. #include "gp/containers/buffer.hpp"
  3. #include <cstdint>
  4. #define no_inline_decl(a) a __attribute__((noinline))
  5. namespace gp{
  6. namespace system {
  7. namespace specifics {
  8. struct platform_data {
  9. platform_data() = default;
  10. platform_data(gp::buffer<char> stack_str)
  11. : stack_ptr((stack_str.end()-16).data)
  12. , base_ptr(stack_ptr)
  13. {}
  14. uint64_t rbx, r12, r13, r14, r15;
  15. void* stack_ptr;
  16. void* base_ptr;
  17. void pull() __attribute__((always_inline))
  18. {
  19. __asm__ __volatile__(
  20. "movq %%rsp, %0\n"
  21. "movq %%rbp, %1\n"
  22. "movq %%rbx, %2\n"
  23. "movq %%r12, %3\n"
  24. "movq %%r13, %4\n"
  25. "movq %%r14, %5\n"
  26. "movq %%r15, %6\n"
  27. : "=m"(stack_ptr)
  28. , "=m"(base_ptr)
  29. , "=m"(rbx)
  30. , "=m"(r12)
  31. , "=m"(r13)
  32. , "=m"(r14)
  33. , "=m"(r15)
  34. );
  35. }
  36. void* push(void* location) __attribute__((always_inline))
  37. {
  38. volatile void* volatile tmp = static_cast<char*>(stack_ptr) - sizeof(void*);
  39. *static_cast<volatile void* volatile * volatile>(tmp) = location;
  40. __asm__ __volatile__(
  41. "movq %1, %%rsp\n"
  42. "movq %2, %%rbp\n"
  43. "movq %3, %%rbx\n"
  44. "movq %4, %%r12\n"
  45. "movq %5, %%r13\n"
  46. "movq %6, %%r14\n"
  47. "movq %7, %%r15\n"
  48. "popq %0\n"
  49. : "+r"(location)
  50. : "m"(tmp)
  51. , "m"(base_ptr)
  52. , "m"(rbx)
  53. , "m"(r12)
  54. , "m"(r13)
  55. , "m"(r14)
  56. , "m"(r15)
  57. : "memory"
  58. );
  59. return location;
  60. }
  61. };
  62. }
  63. }
  64. }