xref: /openbmc/linux/arch/sh/include/asm/bug.h (revision b6dcefde)
1 #ifndef __ASM_SH_BUG_H
2 #define __ASM_SH_BUG_H
3 
4 #define TRAPA_BUG_OPCODE	0xc33e	/* trapa #0x3e */
5 #define BUGFLAG_UNWINDER	(1 << 1)
6 
7 #ifdef CONFIG_GENERIC_BUG
8 #define HAVE_ARCH_BUG
9 #define HAVE_ARCH_WARN_ON
10 
11 /**
12  * _EMIT_BUG_ENTRY
13  * %1 - __FILE__
14  * %2 - __LINE__
15  * %3 - trap type
16  * %4 - sizeof(struct bug_entry)
17  *
18  * The trapa opcode itself sits in %0.
19  * The %O notation is used to avoid # generation.
20  *
21  * The offending file and line are encoded in the __bug_table section.
22  */
23 #ifdef CONFIG_DEBUG_BUGVERBOSE
24 #define _EMIT_BUG_ENTRY				\
25 	"\t.pushsection __bug_table,\"a\"\n"	\
26 	"2:\t.long 1b, %O1\n"			\
27 	"\t.short %O2, %O3\n"			\
28 	"\t.org 2b+%O4\n"			\
29 	"\t.popsection\n"
30 #else
31 #define _EMIT_BUG_ENTRY				\
32 	"\t.pushsection __bug_table,\"a\"\n"	\
33 	"2:\t.long 1b\n"			\
34 	"\t.short %O3\n"			\
35 	"\t.org 2b+%O4\n"			\
36 	"\t.popsection\n"
37 #endif
38 
39 #define BUG()						\
40 do {							\
41 	__asm__ __volatile__ (				\
42 		"1:\t.short %O0\n"			\
43 		_EMIT_BUG_ENTRY				\
44 		 :					\
45 		 : "n" (TRAPA_BUG_OPCODE),		\
46 		   "i" (__FILE__),			\
47 		   "i" (__LINE__), "i" (0),		\
48 		   "i" (sizeof(struct bug_entry)));	\
49 } while (0)
50 
51 #define __WARN()					\
52 do {							\
53 	__asm__ __volatile__ (				\
54 		"1:\t.short %O0\n"			\
55 		 _EMIT_BUG_ENTRY			\
56 		 :					\
57 		 : "n" (TRAPA_BUG_OPCODE),		\
58 		   "i" (__FILE__),			\
59 		   "i" (__LINE__),			\
60 		   "i" (BUGFLAG_WARNING),		\
61 		   "i" (sizeof(struct bug_entry)));	\
62 } while (0)
63 
64 #define WARN_ON(x) ({						\
65 	int __ret_warn_on = !!(x);				\
66 	if (__builtin_constant_p(__ret_warn_on)) {		\
67 		if (__ret_warn_on)				\
68 			__WARN();				\
69 	} else {						\
70 		if (unlikely(__ret_warn_on))			\
71 			__WARN();				\
72 	}							\
73 	unlikely(__ret_warn_on);				\
74 })
75 
76 #define UNWINDER_BUG()					\
77 do {							\
78 	__asm__ __volatile__ (				\
79 		"1:\t.short %O0\n"			\
80 		_EMIT_BUG_ENTRY				\
81 		 :					\
82 		 : "n" (TRAPA_BUG_OPCODE),		\
83 		   "i" (__FILE__),			\
84 		   "i" (__LINE__),			\
85 		   "i" (BUGFLAG_UNWINDER),		\
86 		   "i" (sizeof(struct bug_entry)));	\
87 } while (0)
88 
89 #define UNWINDER_BUG_ON(x) ({					\
90 	int __ret_unwinder_on = !!(x);				\
91 	if (__builtin_constant_p(__ret_unwinder_on)) {		\
92 		if (__ret_unwinder_on)				\
93 			UNWINDER_BUG();				\
94 	} else {						\
95 		if (unlikely(__ret_unwinder_on))		\
96 			UNWINDER_BUG();				\
97 	}							\
98 	unlikely(__ret_unwinder_on);				\
99 })
100 
101 #else
102 
103 #define UNWINDER_BUG	BUG
104 #define UNWINDER_BUG_ON	BUG_ON
105 
106 #endif /* CONFIG_GENERIC_BUG */
107 
108 #include <asm-generic/bug.h>
109 
110 #endif /* __ASM_SH_BUG_H */
111