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?
memoryclobber because it appears you could be passing addresses through registers rather than memory constraints."memory"in the clobber list, e.g. How to specify register constraints on the Intel x86_64 register r8 to r15 in GCC inline assembly?. Docs for "memory" clobber: gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html. See also How can I indicate that the memory *pointed* to by an inline ASM argument may be used? for why this is a problem.