#ifndef caller_save_h #define caller_save_h namespace as { //-------------------------------------------------------------------- // class caller_save //-------------------------------------------------------------------- class caller_save // SystemV AMD64 ABI { public: enum when {first = 0, next}; caller_save() noexcept = default; when __attribute__((naked,noinline,returns_twice)) get() noexcept { asm volatile("mov (%%rsp),%%rax \n" "mov %%rax,%0 \n" "lea 8(%%rsp),%%rax \n" "mov %%rax,%1 \n" "mov %%rbp,%2 \n" "mov %%rbx,%3 \n" "mov %%r12,%4 \n" "mov %%r13,%5 \n" "mov %%r14,%6 \n" "mov %%r15,%7 \n" "xor %%rax,%%rax \n" "ret \n" :"=m"(rip), "=m"(rsp), "=m"(rbp), "=m"(rbx), "=m"(r12), "=m"(r13), "=m"(r14), "=m"(r15) : :"rax","memory"); } void __attribute__((naked,noinline,noreturn)) set(when ret = next) const noexcept { asm volatile("mov %1,%%rsp \n" "mov %2,%%rbp \n" "mov %3,%%rbx \n" "mov %4,%%r12 \n" "mov %5,%%r13 \n" "mov %6,%%r14 \n" "mov %7,%%r15 \n" "jmp *%0 \n" : :"m"(rip), "m"(rsp), "m"(rbp), "m"(rbx), "m"(r12), "m"(r13), "m"(r14), "m"(r15), "a"(ret)); } private: void *rip, *rsp, *rbp, *rbx, *r12, *r13, *r14, *r15; // SystemV AMD64 ABI }; // caller_save //-------------------------------------------------------------------- } // namespace as #endif // caller_save_h