X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=include%2Fasm-powerpc%2Fbug.h;h=f6fa39474846457f9960c6072f0a43aff16dc5ac;hb=refs%2Fheads%2Fvserver;hp=99817a802ca4e4d7c6a6784b3be2d39620018aa0;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h index 99817a802..f6fa39474 100644 --- a/include/asm-powerpc/bug.h +++ b/include/asm-powerpc/bug.h @@ -11,60 +11,109 @@ #define BUG_OPCODE .long 0x00b00b00 /* For asm */ #define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */ -#ifndef __ASSEMBLY__ +#ifdef CONFIG_BUG -struct bug_entry { - unsigned long bug_addr; - long line; - const char *file; - const char *function; -}; +#ifdef __ASSEMBLY__ +#ifdef CONFIG_DEBUG_BUGVERBOSE +.macro EMIT_BUG_ENTRY addr,file,line,flags + .section __bug_table,"a" +5001: PPC_LONG \addr, 5002f + .short \line, \flags + .org 5001b+BUG_ENTRY_SIZE + .previous + .section .rodata,"a" +5002: .asciz "\file" + .previous +.endm +#else + .macro EMIT_BUG_ENTRY addr,file,line,flags + .section __bug_table,"a" +5001: PPC_LONG \addr + .short \flags + .org 5001b+BUG_ENTRY_SIZE + .previous +.endm +#endif /* verbose */ -struct bug_entry *find_bug(unsigned long bugaddr); +#else /* !__ASSEMBLY__ */ +/* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and + sizeof(struct bug_entry), respectively */ +#ifdef CONFIG_DEBUG_BUGVERBOSE +#define _EMIT_BUG_ENTRY \ + ".section __bug_table,\"a\"\n" \ + "2:\t" PPC_LONG "1b, %0\n" \ + "\t.short %1, %2\n" \ + ".org 2b+%3\n" \ + ".previous\n" +#else +#define _EMIT_BUG_ENTRY \ + ".section __bug_table,\"a\"\n" \ + "2:\t" PPC_LONG "1b\n" \ + "\t.short %2\n" \ + ".org 2b+%3\n" \ + ".previous\n" +#endif /* - * If this bit is set in the line number it means that the trap - * is for WARN_ON rather than BUG or BUG_ON. + * BUG_ON() and WARN_ON() do their best to cooperate with compile-time + * optimisations. However depending on the complexity of the condition + * some compiler versions may not produce optimal results. */ -#define BUG_WARNING_TRAP 0x1000000 - -#ifdef CONFIG_BUG -#define BUG() do { \ - __asm__ __volatile__( \ - "1: twi 31,0,0\n" \ - ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%0,%1,%2\n" \ - ".previous" \ - : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ +#define BUG() do { \ + __asm__ __volatile__( \ + "1: twi 31,0,0\n" \ + _EMIT_BUG_ENTRY \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (0), "i" (sizeof(struct bug_entry))); \ + for(;;) ; \ } while (0) #define BUG_ON(x) do { \ - __asm__ __volatile__( \ - "1: "PPC_TLNEI" %0,0\n" \ - ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ - ".previous" \ - : : "r" ((long)(x)), "i" (__LINE__), \ - "i" (__FILE__), "i" (__FUNCTION__)); \ + if (__builtin_constant_p(x)) { \ + if (x) \ + BUG(); \ + } else { \ + __asm__ __volatile__( \ + "1: "PPC_TLNEI" %4,0\n" \ + _EMIT_BUG_ENTRY \ + : : "i" (__FILE__), "i" (__LINE__), "i" (0), \ + "i" (sizeof(struct bug_entry)), \ + "r" ((long)(x))); \ + } \ } while (0) -#define WARN_ON(x) do { \ +#define __WARN() do { \ __asm__ __volatile__( \ - "1: "PPC_TLNEI" %0,0\n" \ - ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ - ".previous" \ - : : "r" ((long)(x)), \ - "i" (__LINE__ + BUG_WARNING_TRAP), \ - "i" (__FILE__), "i" (__FUNCTION__)); \ + "1: twi 31,0,0\n" \ + _EMIT_BUG_ENTRY \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (BUGFLAG_WARNING), \ + "i" (sizeof(struct bug_entry))); \ } while (0) +#define WARN_ON(x) ({ \ + typeof(x) __ret_warn_on = (x); \ + if (__builtin_constant_p(__ret_warn_on)) { \ + if (__ret_warn_on) \ + __WARN(); \ + } else { \ + __asm__ __volatile__( \ + "1: "PPC_TLNEI" %4,0\n" \ + _EMIT_BUG_ENTRY \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (BUGFLAG_WARNING), \ + "i" (sizeof(struct bug_entry)), \ + "r" (__ret_warn_on)); \ + } \ + unlikely(__ret_warn_on); \ +}) + #define HAVE_ARCH_BUG #define HAVE_ARCH_BUG_ON #define HAVE_ARCH_WARN_ON -#endif /* CONFIG_BUG */ #endif /* __ASSEMBLY __ */ +#endif /* CONFIG_BUG */ #include