From: VMware, Inc <> Date: Thu, 2 Aug 2012 05:29:55 +0000 (-0700) Subject: Fix asm constraint for Set/Test/ClearBitVector X-Git-Tag: 2012.10.14-874563~82 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5c4e42d19fc85c8bb33d4bc9c178988c468618fd;p=thirdparty%2Fopen-vm-tools.git Fix asm constraint for Set/Test/ClearBitVector Compiling this assembly with gcc-4.4.3 in i686 results in a compilation error stating that %dil is not a valid register. GCC experts state that the compiler is correct and the problem is in the assembly constraints: https://bugzilla.redhat.com/show_bug.cgi?id=625263 (Summary for uninitiated: %dil is the low 8 bits of %edi, which is addressible in x86_64 but NOT in ia32) Slightly more detail: the setc instruction takes an 8-bit operand. Which means any register chosen must also be an 8-bit register (ia32: al, bl, cl, dl). The 'q' constraint means "any register addressible with the -l suffix", which is the correct constraint. At Jim's suggetion, I'm also adding 'Q' (ia32: ah, bh, ch, dh). Note that in x86_64, 'q' covers all registers, so 'q' vs. 'r' does not hurt x86_64. I also note that bts specifically alters CF (and we are indeed using setc to read it!), but "cc" is not on the clobber list. It was present on the clobber list of all the other assembly fragments, so I suspect this was an oversight. Why didn't we see this before? - These BitTest funcs tend to be used only in VMX - The only VMX that builds with gcc-4.4.3 today is ESX's, which ix x86_64 - The Linux Workstation vmx32 uses gcc-4.1.2 - (I'm experimenting with bumping Workstation Linux's gcc) There are no correctness concerns; if constraints were wrong, the code would fail to compile entirely due to incorrect register selection. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/include/vm_basic_asm.h b/open-vm-tools/lib/include/vm_basic_asm.h index 180bd157a..881a13c28 100644 --- a/open-vm-tools/lib/include/vm_basic_asm.h +++ b/open-vm-tools/lib/include/vm_basic_asm.h @@ -1086,7 +1086,7 @@ TestBit32(const uint32 *var, uint32 index) __asm__ ( "bt %[index], %[var] \n" "setc %[bit]" - : [bit] "=rm" (bit) + : [bit] "=qQm" (bit) : [index] "rI" (index), [var] "r" (*var) : "cc" ); @@ -1104,7 +1104,7 @@ TestBit64(const uint64 *var, uint64 index) __asm__ ( "bt %[index], %[var] \n" "setc %[bit]" - : [bit] "=rm" (bit) + : [bit] "=qQm" (bit) : [index] "rJ" (index), [var] "r" (*var) : "cc" ); @@ -1137,9 +1137,9 @@ SetBitVector(void *var, int32 index) __asm__ ( "bts %2, %1;" "setc %0" - : "=rm" (bit), "+m" (*(volatile uint32 *)var) + : "=qQm" (bit), "+m" (*(volatile uint32 *)var) : "rI" (index) - : "memory" + : "memory", "cc" ); return bit; #elif defined(_MSC_VER) @@ -1157,7 +1157,7 @@ ClearBitVector(void *var, int32 index) __asm__ ( "btr %2, %1;" "setc %0" - : "=rm" (bit), "+m" (*(volatile uint32 *)var) + : "=qQm" (bit), "+m" (*(volatile uint32 *)var) : "rI" (index) : "cc" ); @@ -1177,7 +1177,7 @@ ComplementBitVector(void *var, int32 index) __asm__ ( "btc %2, %1;" "setc %0" - : "=rm" (bit), "+m" (*(volatile uint32 *)var) + : "=qQm" (bit), "+m" (*(volatile uint32 *)var) : "rI" (index) : "cc" ); @@ -1197,7 +1197,7 @@ TestBitVector(const void *var, int32 index) __asm__ ( "bt %2, %1;" "setc %0" - : "=rm" (bit) + : "=qQm" (bit) : "m" (*(const uint32 *)var), "rI" (index) : "cc" );