as_callfunc_x64_gcc.cpp does not compile correctly.
The following output is produced using "angelscript/projects/gnuc macosx/makefile": mkdir obj c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_atomic.o -c ../../source/as_atomic.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_builder.o -c ../../source/as_builder.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_bytecode.o -c ../../source/as_bytecode.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc.o -c ../../source/as_callfunc.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_arm.o -c ../../source/as_callfunc_arm.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_mips.o -c ../../source/as_callfunc_mips.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_ppc.o -c ../../source/as_callfunc_ppc.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_ppc_64.o -c ../../source/as_callfunc_ppc_64.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_sh4.o -c ../../source/as_callfunc_sh4.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_x86.o -c ../../source/as_callfunc_x86.cpp c++ -g -Wall -fPIC -arch i386 -arch x86_64 -o obj/as_callfunc_x64_gcc.o -c ../../source/as_callfunc_x64_gcc.cpp /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:170:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:173:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:176:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:179:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:182:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:185:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:188:suffix or operands invalid for `movq' /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccQb3SXj.s:191:suffix or operands invalid for `movq' lipo: can't open input file: /var/folders/iG/iGgRv-pOHVq8lMdjYzTz0E+++TI/-Tmp-//ccDlZLXb.out (No such file or directory) make: *** [obj/as_callfunc_x64_gcc.o] Error 1
Which seems to correspond to the following lines in as_callfunc_x64_gcc.cpp POP_LONG( "%xmm7" ); POP_LONG( "%xmm6" ); POP_LONG( "%xmm5" ); POP_LONG( "%xmm4" ); POP_LONG( "%xmm3" ); POP_LONG( "%xmm2" ); POP_LONG( "%xmm1" ); POP_LONG( "%xmm0" );
Moving from a general purpose register to an xmm register doesn't seem to be supported, only xmm to xmm, memory to xmm and xmm to memory. According to this
I'm by no means an assembly programmer but wouldn't it be possible to just use movq using the stack pointer to reference memory and then pop into rax after the move? Maybe something like this? #define POP_LONG( reg ) \ __asm__ __volatile__ ( \ "add %%rsp, 8\n" \ "movq (%%rsp), %" reg \ : \ : \ : reg \ )
I wish I could test this, but I don't have a 64bit mac.
Anyway the problem is most likely caused by the latest changes in the file. Can you help me determine which revision from the svn was the latest to still work?
Hmm. That version of the file is very old and is no longer compatible with the current library code. Version 640 was the one that introduced the new assembly code, and it was contributed by a Mac developer that couldn't compile the previous version.
I think the problem you're having is because of a difference in the compiler version that you use. I think it is necessary to write the assembly code slightly differently depending on the version of the compiler.
Which xcode version are you using, and which version of gcc is it using (it should hopefully appear in the build logs)?
This will print out: xmm0 contents cafebabefeedface So clearly all 64 bits are being moved into the xmmcontents variable.
According to the disassembly it seems that the correct instruction to move a qword from a general purpose register into an xmm register is not movq but movd.
This C code gives the same stdout printout as the above nasm code:#include <stdio.h>
Can you try the following code for the POP_LONG macro? It seems GNUC is doing some weirdness in order to keep backward compatibility. I suspect this has been changed for newer versions of GNUC, so I'll differentiate with the code for your version.
// While movq really should be used to move from general // purpose register to xmm register, GNUC accepts movd for // backward compatibility. // http ://gcc.gnu.org/bugzilla/show_bug.cgi?id=43215 #if __GNUC__ <= 4 && __GNUC_MINOR__ <= 2 #define POP_LONG( reg ) \ __asm__ __volatile__ ( \ "popq %%rax\n" \ "movd %%rax, %" reg \ : \ : \ : "%rax", reg \ ) #else #define POP_LONG( reg ) \ __asm__ __volatile__ ( \ "popq %%rax\n" \ "movq %%rax, %" reg \ : \ : \ : "%rax", reg \ ) #endif
This POP_LONG macro works for the xmm registers but fails for the general purpose ones. It seems that for general purpose -> xmm register the correct opcode is movd but for a general purpose -> general purpose register the correct opcode is movq. I was reading the Intel opcode reference yesterday and the movq that does gp -> xmm is filed with movd but it's name is still given as movq.Clear as mud.
I think it is a bug in the version of GNUC that you're using that makes the movq not work with the xmm registers. This bug was fixed in a later version of GNUC, which is why others are able to compile the code just fine. According to the article I linked to they left the movd instruction for xmm registers for backwards compatibility, so it should be working even on the newer versions of GNUC.
Can you try kainjow's solution with two different versions of the POP_LONG macro, and then update the X64_CallFunction to use the right version with the right register?