#pragma once #include "gp/containers/buffer.hpp" #include #define no_inline_decl(a) a __attribute__((noinline)) namespace gp{ namespace specifics { struct platform_data { platform_data() = default; platform_data(gp::buffer stack_str) : stack_ptr((stack_str.end()-16).data) , base_ptr(stack_ptr) {} 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)) { volatile void* volatile tmp = static_cast(stack_ptr) - sizeof(void*); *static_cast(tmp) = location; __asm__ __volatile__( "movq %1, %%rsp\n" "movq %2, %%rbp\n" "movq %3, %%rbx\n" "movq %4, %%r12\n" "movq %5, %%r13\n" "movq %6, %%r14\n" "movq %7, %%r15\n" "popq %0\n" : "+r"(location) : "m"(tmp) , "m"(base_ptr) , "m"(rbx) , "m"(r12) , "m"(r13) , "m"(r14) , "m"(r15) : "memory" ); return location; } }; } }