Re: cpuid_eax damages registers (2.4.7pre7)

From: Kai Germaschewski (kai@tp1.ruhr-uni-bochum.de)
Date: Wed Jul 18 2001 - 15:43:44 EST


On Wed, 18 Jul 2001, Linus Torvalds wrote:

> Can you try to do the following in the cpuid_xxx() functions:
> - remove the dummy reads (ie leave just the one register in the asm that
> we're actually interested in)
> - add explicit clobbers for the other registers

I looked into this a little to improve my knowledge on inline asm. Anyway,
I found one ugly work-around, i.e. using a makro instead of the inline
function plus a local eax_in variable, but your idea seems way nicer and
works as well.

Generated code looks okay now (using kgcc aka egcs-2.91.66):

    2002: 31 c0 xor %eax,%eax
    2004: 0f a2 cpuid
    2006: 89 46 08 mov %eax,0x8(%esi)
    2009: 5b pop %ebx
    200a: 5e pop %esi
    200b: c3 ret

Patch follows:

--Kai

diff -ur linux-2.4.7-pre7/include/asm-i386/processor.h linux-2.4.7-pre7.work/include/asm-i386/processor.h
--- linux-2.4.7-pre7/include/asm-i386/processor.h Wed Jul 18 21:49:47 2001
+++ linux-2.4.7-pre7.work/include/asm-i386/processor.h Wed Jul 18 22:38:20 2001
@@ -134,38 +134,42 @@
  */
 extern inline unsigned int cpuid_eax(unsigned int op)
 {
- unsigned int eax, ebx, ecx, edx;
+ unsigned int eax;
 
         __asm__("cpuid"
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
- : "a" (op));
+ : "=a" (eax)
+ : "a" (op)
+ : "ebx", "ecx", "edx");
         return eax;
 }
 extern inline unsigned int cpuid_ebx(unsigned int op)
 {
- unsigned int eax, ebx, ecx, edx;
+ unsigned int ebx;
 
         __asm__("cpuid"
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
- : "a" (op));
+ : "=b" (ebx)
+ : "a" (op)
+ : "eax", "ecx", "edx");
         return ebx;
 }
 extern inline unsigned int cpuid_ecx(unsigned int op)
 {
- unsigned int eax, ebx, ecx, edx;
+ unsigned int ecx;
 
         __asm__("cpuid"
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
- : "a" (op));
+ : "=c" (ecx)
+ : "a" (op)
+ : "eax", "ebx", "edx");
         return ecx;
 }
 extern inline unsigned int cpuid_edx(unsigned int op)
 {
- unsigned int eax, ebx, ecx, edx;
+ unsigned int edx;
 
         __asm__("cpuid"
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
- : "a" (op));
+ : "=d" (edx)
+ : "a" (op)
+ : "eax", "ebx", "ecx");
         return edx;
 }
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jul 23 2001 - 21:00:11 EST