| @ -1,9 +1,58 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cstdint> | |||||
| #define no_inline_decl(a) [[gnu::noinline]] a | |||||
| namespace gp{ | namespace gp{ | ||||
| namespace specifics { | namespace specifics { | ||||
| struct platform_data { | struct platform_data { | ||||
| uint64_t rbx, r12, r13, r14, r15; | |||||
| void* stack_ptr; | |||||
| void* base_ptr; | |||||
| void pull() __attribute__((always_inline)) | |||||
| { | |||||
| __asm__ __volatile__( | |||||
| "movq %%rsp, %0\n" | |||||
| "movq %%rbp, %1\n" | |||||
| "movq %%rbx, %2\n" | |||||
| "movq %%r12, %3\n" | |||||
| "movq %%r13, %4\n" | |||||
| "movq %%r14, %5\n" | |||||
| "movq %%r15, %6\n" | |||||
| : "=m"(stack_ptr) | |||||
| , "=m"(base_ptr) | |||||
| , "=m"(rbx) | |||||
| , "=m"(r12) | |||||
| , "=m"(r13) | |||||
| , "=m"(r14) | |||||
| , "=m"(r15)); | |||||
| } | |||||
| void* push(void* location) __attribute__((always_inline)) | |||||
| { | |||||
| void* tmp = static_cast<char*>(stack_ptr) - sizeof(void*); | |||||
| *static_cast<void**>(tmp) = location; | |||||
| __asm__ __volatile__( | |||||
| "movq %1, %%rsp\n" | |||||
| "movq %2, %%rbp\n" | |||||
| "movq %3, %%r12\n" | |||||
| "movq %4, %%r13\n" | |||||
| "movq %5, %%r14\n" | |||||
| "movq %6, %%r15\n" | |||||
| "popq %0\n" | |||||
| : "+r"(location) | |||||
| : "m"(tmp) | |||||
| , "m"(base_ptr) | |||||
| , "m"(r12) | |||||
| , "m"(r13) | |||||
| , "m"(r14) | |||||
| , "m"(r15) | |||||
| : "memory"); | |||||
| return location; | |||||
| } | |||||
| }; | }; | ||||
| } | } | ||||
| } | } | ||||