This is a follow up to What is "=qm" in extended assembler.
When using RDRAND
, it sets (or unsets) the Carry Flag (CF
):
char rc;
unsigned int val;
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
);
// 1 = success, 0 = underflow
if(rc) {
// use val
...
}
Are the FLAGS
and EFLAGS
registers considered part of condition control so that it conveys the proper information to the compiler? Should the above be written as:
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
:
: "cc"
);
Or is the use of "cc"
spurious?
I know its harmless to use if unneeded. From Extended ASM:
If your assembler instruction can alter the condition code register, add ‘cc’ to the list of clobbered registers. GCC on some machines represents the condition codes as a specific hardware register; ‘cc’ serves to name this register. On other machines, the condition code is handled differently, and specifying ‘cc’ has no effect. But it is valid no matter what the machine.
If its spurious, what architectures does it apply to? (I presume ARM and the CPSR
register, but I could be mistaken).
According to the manual, yes - cc
is clobbered. RDRAND
also sets OF, SF, ZF, AF, PF <- 0.
In practice, gcc assumes that an __asm__
block always clobbers the [E|R]FLAGS
condition code register for x86. I don't have the reference, but you can see this assumption in places like the longlong.h
header used in various GNU packages.
It is, as you say, harmless if not used. For that reason, you might as well include it, since it still provides semantic intent, or commentary at worst. Also consider that Clang and ICC implement GCC asm syntax, and they would be conforming to the documentation if they honoured the "cc"
clobber, rather than presume it - even though this is unlikely.