xref: /linux/tools/testing/selftests/bpf/libarena/include/bpf_may_goto.h (revision 8c1e1c33fe5ad867bc0b6ba121911d70e7881d88)
1*8c1e1c33SEmil Tsalapatis #pragma once
2*8c1e1c33SEmil Tsalapatis 
3*8c1e1c33SEmil Tsalapatis /*
4*8c1e1c33SEmil Tsalapatis  * Note that cond_break can only be portably used in the body of a breakable
5*8c1e1c33SEmil Tsalapatis  * construct, whereas can_loop can be used anywhere.
6*8c1e1c33SEmil Tsalapatis  */
7*8c1e1c33SEmil Tsalapatis #ifdef __BPF_FEATURE_MAY_GOTO
8*8c1e1c33SEmil Tsalapatis #define can_loop					\
9*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
10*8c1e1c33SEmil Tsalapatis 	bool ret = true;				\
11*8c1e1c33SEmil Tsalapatis 	asm volatile goto("may_goto %l[l_break]"	\
12*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
13*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
14*8c1e1c33SEmil Tsalapatis 	l_break: ret = false;				\
15*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
16*8c1e1c33SEmil Tsalapatis 	ret;						\
17*8c1e1c33SEmil Tsalapatis 	})
18*8c1e1c33SEmil Tsalapatis 
19*8c1e1c33SEmil Tsalapatis #define __cond_break(expr)				\
20*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
21*8c1e1c33SEmil Tsalapatis 	asm volatile goto("may_goto %l[l_break]"	\
22*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
23*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
24*8c1e1c33SEmil Tsalapatis 	l_break: expr;					\
25*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
26*8c1e1c33SEmil Tsalapatis 	})
27*8c1e1c33SEmil Tsalapatis #else
28*8c1e1c33SEmil Tsalapatis #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
29*8c1e1c33SEmil Tsalapatis #define can_loop					\
30*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
31*8c1e1c33SEmil Tsalapatis 	bool ret = true;				\
32*8c1e1c33SEmil Tsalapatis 	asm volatile goto("1:.byte 0xe5;		\
33*8c1e1c33SEmil Tsalapatis 		      .byte 0;				\
34*8c1e1c33SEmil Tsalapatis 		      .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;	\
35*8c1e1c33SEmil Tsalapatis 		      .short 0"				\
36*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
37*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
38*8c1e1c33SEmil Tsalapatis 	l_break: ret = false;				\
39*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
40*8c1e1c33SEmil Tsalapatis 	ret;						\
41*8c1e1c33SEmil Tsalapatis 	})
42*8c1e1c33SEmil Tsalapatis 
43*8c1e1c33SEmil Tsalapatis #define __cond_break(expr)				\
44*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
45*8c1e1c33SEmil Tsalapatis 	asm volatile goto("1:.byte 0xe5;		\
46*8c1e1c33SEmil Tsalapatis 		      .byte 0;				\
47*8c1e1c33SEmil Tsalapatis 		      .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;	\
48*8c1e1c33SEmil Tsalapatis 		      .short 0"				\
49*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
50*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
51*8c1e1c33SEmil Tsalapatis 	l_break: expr;					\
52*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
53*8c1e1c33SEmil Tsalapatis 	})
54*8c1e1c33SEmil Tsalapatis #else
55*8c1e1c33SEmil Tsalapatis #define can_loop					\
56*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
57*8c1e1c33SEmil Tsalapatis 	bool ret = true;				\
58*8c1e1c33SEmil Tsalapatis 	asm volatile goto("1:.byte 0xe5;		\
59*8c1e1c33SEmil Tsalapatis 		      .byte 0;				\
60*8c1e1c33SEmil Tsalapatis 		      .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;	\
61*8c1e1c33SEmil Tsalapatis 		      .short 0"				\
62*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
63*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
64*8c1e1c33SEmil Tsalapatis 	l_break: ret = false;				\
65*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
66*8c1e1c33SEmil Tsalapatis 	ret;						\
67*8c1e1c33SEmil Tsalapatis 	})
68*8c1e1c33SEmil Tsalapatis 
69*8c1e1c33SEmil Tsalapatis #define __cond_break(expr)				\
70*8c1e1c33SEmil Tsalapatis 	({ __label__ l_break, l_continue;		\
71*8c1e1c33SEmil Tsalapatis 	asm volatile goto("1:.byte 0xe5;		\
72*8c1e1c33SEmil Tsalapatis 		      .byte 0;				\
73*8c1e1c33SEmil Tsalapatis 		      .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;	\
74*8c1e1c33SEmil Tsalapatis 		      .short 0"				\
75*8c1e1c33SEmil Tsalapatis 		      :::: l_break);			\
76*8c1e1c33SEmil Tsalapatis 	goto l_continue;				\
77*8c1e1c33SEmil Tsalapatis 	l_break: expr;					\
78*8c1e1c33SEmil Tsalapatis 	l_continue:;					\
79*8c1e1c33SEmil Tsalapatis 	})
80*8c1e1c33SEmil Tsalapatis #endif
81*8c1e1c33SEmil Tsalapatis #endif
82*8c1e1c33SEmil Tsalapatis 
83*8c1e1c33SEmil Tsalapatis #define cond_break __cond_break(break)
84*8c1e1c33SEmil Tsalapatis #define cond_break_label(label) __cond_break(goto label)
85