mmarkk@mmarkk-desktop:~/src/vmdetect$ gcc --version gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1 ---------------------------------------------- #include <sys/types.h> #include <stdio.h> int main (void) { size_t ecx; asm ("cpuid": "=c" (ecx): "a" (0x1):"eax","ebx","edx"); printf ("Suspected %s machine!\n", (ecx >> 31) ? "virtual" : "real"); return 0; } mmarkk@mmarkk-desktop:~/src/vmdetect$ gcc 1main.c 1main.c: In function ‘main’: 1main.c:7: error: can't find a register in class ‘AREG’ while reloading ‘asm’ 1main.c:7: error: ‘asm’ operand has impossible constraints ------------------------------------------------ #include <sys/types.h> #include <stdio.h> int main (void) { size_t ecx, dontneed; asm ("cpuid": "=c" (ecx),"=a"(dontneed): "a" (0x1):"ebx","edx"); printf ("Suspected %s machine!\n", (ecx >> 31) ? "virtual" : "real"); return 0; } works OK. How to correctly say compiler about clobbering eax register ?
You can use cpuid.h. BTW: Please ask questions about using gcc in gcc-help@ or elsewhere. Not a bug.
To answer the exact question, yes, using a dummy variable as output (perhaps with "1" instead of "a" for the matching input) is the right fix.
Thanks alot, but I think it is bug in gcc inline assembler. I think I wrote correct asm() line. I know about cpuid.h I listed this instruction just as example.
You can't at the same time force something into aregs and clobber them.
Well, how to say that to compiler: This instruction receives input in register eax, but after executing it, eax value will be corrupted. I don't need this new value, but compiler should not think that eax is preserved.
(In reply to comment #5) > Well, how to say that to compiler: > > This instruction receives input in register eax, but after executing it, eax > value will be corrupted. I don't need this new value, but compiler should not > think that eax is preserved. > Just make eax both input and output.
> Just make eax both input and output. it's not optimal. gcc will try to preserve new eax value. So it will not use eax register in next instructions. If eax is really need, it will save it in esi, edi or so on - it's redundant.
(In reply to comment #7) > > Just make eax both input and output. > it's not optimal. gcc will try to preserve new eax value. So it will not use > eax register in next instructions. If eax is really need, it will save it in > esi, edi or so on - it's redundant. Not if you make the output unused by not using it.
> Not if you make the output unused by not using it. I do not understand why gcc distinguish between 'specifying register as output' and 'specifying as clobbering'. I always considered, that 'clobber list' specify list of items which may be changed *AFTER* the end of instruction(s). So I do not understand why adding eax in clobber list will break compilation. I found some posts where people create size_t dummy; and specify this variable as output. insted of just specifying this register in clobber-list. Why not to fix bug I have reported? Maybe convert to feature?
Because the way the constraints are implemented inside GCC, an input constraint cannot overlap with a clobber. As input constraint can stay in the same register across the inline-asm so it does not make sense to have it as a clobber. Use an output register that says it clobbers that register.
Suppose this: volatile int x; asm("something"::"a" (1)) x=1; the compiler may think that "something" do not modify eax. So next assignment may use eax ( mov eax, x ). So, "it does not make sense to have it as a clobber" is not correct. does not it ? ----------------- And the second, "Because the way the constraints are implemented inside GCC, an input constraint cannot overlap with a clobber." - It definitely the bug.
> the compiler may think that "something" do not modify eax. So next assignment > may use eax ( mov eax, x ). So, "it does not make sense to have it as a > clobber" is not correct. does not it ? Andrew was saying that it doesn't make sense to consider input operands as clobbered by an inline asm, generically. > And the second, "Because the way the constraints are implemented inside GCC, > an input constraint cannot overlap with a clobber." - It definitely the bug. No, it isn't, it's clearly stated in the manual: "You may not write a clobber description in a way that overlaps with an input or output operand."
Andrew Pinski said: > Use an output register that says it clobbers that register. This indeed works for normal inline assembler, but it doesn't work for asm goto which currently doesn't have outputs. maybe the Bug should be reopened for newer versions of GCC?
(In reply to Eric Botcazou from comment #12) > > the compiler may think that "something" do not modify eax. So next assignment > > may use eax ( mov eax, x ). So, "it does not make sense to have it as a > > clobber" is not correct. does not it ? > > Andrew was saying that it doesn't make sense to consider input operands as > clobbered by an inline asm, generically. How about allowing an ampersand in the input list? Just like early clobber in output list, in input list it may mean "late clobber" - that is, clobbered after the argument is taken. Then you won't contradict with any doc and will avoid any logical inconsistency. This makes a lot of sense for things like "rep; movsl" where you'd need 3 dummy values...
Btw, clang seems to allow same regs in input and clobber list.