- summary: Compiler can place its code between onsecutive inline asm --> Compiler can place its code between consecutive inline asm
In v0.6.1 it is assumed that compiler can not place anything between consecutive inline assembler statements. This is wrong and causes for example Intel compiler to emit errors. For example consider the following test (rediced from SIMD/SIMD.cpp):
static bool haveSSE = false;
static bool haveSSE2 = false;
static bool AutoDetectPerformed = false;
void AutoDetect() {
try {
__asm__ volatile (".intel_syntax noprefix\n");
__asm__ volatile ("xorps xmm0" "," "xmm0\n");
__asm__ volatile (".att_syntax\n");
haveSSE = true;
} catch(...) {
haveSSE = false;
}
try {
__asm__ volatile (".intel_syntax noprefix\n");
__asm__ volatile ("xorpd xmm0" "," "xmm0\n");
__asm__ volatile (".att_syntax\n");
haveSSE2 = true;
} catch(...) {
haveSSE2 = false;
}
AutoDetectPerformed = true;
}
bool IsSSEEnabled() {
if(!AutoDetectPerformed)
AutoDetect();
return haveSSE;
}
Intel compiler can produce this error:
> icc -c a.cpp
/tmp/icc7q24kmas_.s: Assembler messages:
/tmp/icc7q24kmas_.s:67: Error: no such instruction: `movl $1,%ebx'
The problem is in the following .s file part (that shows that compiler generated "movl $1, %ebx" is placed after ".intel_syntax noprefix" and that causes problems):
# Begin ASM
.intel_syntax noprefix
# End ASM #36.3
movl $1, %ebx #36.3
# Begin ASM
xorps xmm0,xmm0
# End ASM #36.3
# Begin ASM
.att_syntax
# End ASM #36.3
P.S. In http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Extended-Asm.html we can read this:
Note that even a volatile asm instruction can be moved in ways that appear insignificant to the compiler, such as across jump instructions. You can't expect a sequence of volatile asm instructions to remain perfectly consecutive. If you want consecutive output, use a single asm. Also, GCC will perform some optimizations across a volatile asm instruction; GCC does not "forget everything" when it encounters a volatile asm instruction the way some other compilers do.