]> git.neil.brown.name Git - history.git/commitdiff
ia64: Fix __delay() even more: it's just not safe to inline the delay-
authorDavid Mosberger <davidm@tiger.hpl.hp.com>
Wed, 15 Oct 2003 07:07:23 +0000 (00:07 -0700)
committerDavid Mosberger <davidm@tiger.hpl.hp.com>
Wed, 15 Oct 2003 07:07:23 +0000 (00:07 -0700)
loop because, e.g., the compiler might decide to unroll the
loop when passed a constant, etc.

arch/ia64/kernel/head.S
include/asm-ia64/delay.h

index 23a1864d16bbceb904650f5cb4fbd19cef2931cc..db5f71d05bb521afc239ecdf70338880543a768b 100644 (file)
@@ -797,6 +797,25 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
        br.ret.sptk.many rp
 END(ia64_switch_mode_virt)
 
+GLOBAL_ENTRY(ia64_delay_loop)
+       .prologue
+{      nop 0                   // work around GAS unwind info generation bug...
+       .save ar.lc,r2
+       mov r2=ar.lc
+       .body
+       ;;
+       mov ar.lc=r32
+}
+       ;;
+       // force loop to be 32-byte aligned (GAS bug means we cannot use .align
+       // inside function body without corrupting unwind info).
+{      nop 0 }
+1:     br.cloop.sptk.few 1b
+       ;;
+       mov ar.lc=r2
+       br.ret.sptk.many rp
+END(ia64_delay_loop)
+
 #ifdef CONFIG_IA64_BRL_EMU
 
 /*
index 8cc00a25d17ab93e11a98e726fb8d7435d791fa2..1b9df23a5641c7961ea21973a088ded0d7744b5f 100644 (file)
@@ -67,14 +67,15 @@ ia64_get_itc (void)
        return result;
 }
 
+extern void ia64_delay_loop (unsigned long loops);
+
 static __inline__ void
 __delay (unsigned long loops)
 {
-       if (loops < 1)
+       if (unlikely(loops < 1))
                return;
 
-       while (loops--)
-               barrier();
+       ia64_delay_loop (loops - 1);
 }
 
 static __inline__ void