#pragma once
|
|
|
|
#include <cstdint>
|
|
|
|
#define no_inline_decl(a) [[gnu::noinline]] a
|
|
|
|
namespace gp{
|
|
namespace specifics {
|
|
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;
|
|
}
|
|
};
|
|
}
|
|
}
|