General Purpose library for Freestanding C++ and POSIX systems
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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