Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7875 Discussions

inline assembler, register of function return value...


in some of our code (C++ interpreter) we have inline assembler code to to be able to call vararg functions (assembler needed to pass the varargs in the correct registers). According to the gcc asm docs the return value of a function call are always returned in the rax register. This holds also for Intel icc, except when the function returns a C++ object. In that case, I found by looking in the debugger, that Intel icc returns the object reference in rdi. Is this an icc particularity or is this documented behavior. Here a snip of out code:

__asm__ __volatile__("movq %0, %%rax \n\t"
"movq %%rax, 144(%%rsp)" :: "m" (u[18].lval) : "%rax");
__asm__ __volatile__("movq %0, %%rax \n\t"
"movq %%rax, 152(%%rsp)" :: "m" (u[19].lval) : "%rax");
__asm__ __volatile__("movq %0, %%r10" :: "m" (fptr) : "%r10");
__asm__ __volatile__("movl $8, %eax"); // number of used xmm registers
__asm__ __volatile__("call *%r10");
__asm__ __volatile__("movq %%rax, %0" : "=m" (u[0].lval) :: "memory"); // get return value
__asm__ __volatile__("addq %0, %%rsp" :: "i" ((umax+2)*8));
TString* pobj;
TString xobj = *(TString*) u[0].lval;
pobj = new TString(xobj);
result7->obj.i = (long) ((void*) pobj);
result7->ref = result7->obj.i;
return(result7) ;

where this line works for g++ and icc when the return value is a pointer or basic type:

__asm__ __volatile__("movq %%rax, %0" : "=m" (u[0].lval) :: "memory"); // get return value

but not when, like in the above case, the function returns on object, and it has to be like:

__asm__ __volatile__("movq %%rdi, %0" : "=m" (u[0].lval) :: "memory"); // get return value

for icc (g++ is always rax).

Is this an icc bug or feature?

Cheers, Fons.

0 Kudos
1 Reply
Black Belt


Write a dummy function in C++that takes example arguments of type and number, and returns the type that you wish for your ASM routine. Then compile this file with the option switch that creates an assembler source file (omit the binary code and line numbers. Then examine how the arguments go into and come out of the listing. Follow this in your program.

Note, you will need to consult a reference as to which registers (r?x as well as xmm? etc) that are temporary and which require preservation.

Note, the register usage is different between x32 and x64.

Jim Dempsey
0 Kudos