I have this function:
#include <cstdint>
using ::std::intptr_t;
struct syscall_param {
syscall_param(intptr_t v) : value(v) { }
syscall_param(void *v) : value(reinterpret_cast<::std::intptr_t>(v)) { }
intptr_t value;
};
inline intptr_t do_syscall(syscall_param const &callnum,
syscall_param const &p1,
syscall_param const &p2,
syscall_param const &p3,
syscall_param const &p4,
syscall_param const &p5,
syscall_param const &p6)
{
intptr_t retval;
asm volatile (
"movq %5, %%r10\n\t"
"movq %6, %%r8\n\t"
"movq %7, %%r9\n\t"
"syscall\n\t"
:"=a"(retval)
:"a"(callnum.value), "D"(p1.value), "S"(p2.value), "d"(p3.value), "g"(p4.value), "g"(p5.value), "g"(p6.value)
:"%rcx", "%r11", "%r10", "%r8", "%r9"
);
return retval;
}
I would really like to get rid of the movq instructions by using contraints. While I can use constraints to get things into the rax, edi, esi, and rdx registers, there don't seem to be any constraints that let me get things into the r10, r8, and r9 registers. It seems like there ought to be a constrain that would allow me to get things into an arbitrary r# register. Am I missing something? Is there a better way to do what I want?