diff options
author | Glauber Costa <gcosta@redhat.com> | 2008-06-24 10:21:25 -0300 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 08:52:04 +0200 |
commit | 7e58818d32c18197602d1869b22cfda99efd05fe (patch) | |
tree | 2ecdee4abda69dad3aefb25c04a81d43081ba01b /arch | |
parent | a76febe975997b933b7285b6e20bb0a21c09d453 (diff) | |
download | blackbird-op-linux-7e58818d32c18197602d1869b22cfda99efd05fe.tar.gz blackbird-op-linux-7e58818d32c18197602d1869b22cfda99efd05fe.zip |
x86: explicitly use edx in const delay function.
For x86_64, we can't just use %0, as it would
generate a mul against rdx, which is not really what we
want (note the ">> 32" in x86_64 version).
Using a u64 variable with a shift in i386 generates bad code,
so the solution is to explicitly use %%edx in inline assembly
for both.
Signed-off-by: Glauber Costa <gcosta@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/lib/delay_32.c | 2 | ||||
-rw-r--r-- | arch/x86/lib/delay_64.c | 11 |
2 files changed, 10 insertions, 3 deletions
diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c index bf6de05445ba..0b659a320b1e 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay_32.c @@ -114,7 +114,7 @@ inline void __const_udelay(unsigned long xloops) int d0; xloops *= 4; - __asm__("mull %0" + __asm__("mull %%edx" :"=d" (xloops), "=&a" (d0) :"1" (xloops), "0" (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c index d0326d07c845..ff3dfecdb6f9 100644 --- a/arch/x86/lib/delay_64.c +++ b/arch/x86/lib/delay_64.c @@ -103,9 +103,16 @@ EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { - __delay(((xloops * HZ * - cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1); + int d0; + xloops *= 4; + __asm__("mull %%edx" + :"=d" (xloops), "=&a" (d0) + :"1" (xloops), "0" + (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); + + __delay(++xloops); } + EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) |