xref: /linux/arch/arm64/include/asm/jump_label.h (revision 40de53fd002c6ba087a623722915e8006ed68a02)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2013 Huawei Ltd.
4  * Author: Jiang Liu <liuj97@gmail.com>
5  *
6  * Based on arch/arm/include/asm/jump_label.h
7  */
8 #ifndef __ASM_JUMP_LABEL_H
9 #define __ASM_JUMP_LABEL_H
10 
11 #ifndef __ASSEMBLY__
12 
13 #include <linux/types.h>
14 #include <asm/insn.h>
15 
16 #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
17 
18 /*
19  * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
20  * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
21  */
22 static __always_inline bool arch_static_branch(struct static_key * const key,
23 					       const bool branch)
24 {
25 	asm goto(
26 		"1:	nop					\n\t"
27 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
28 		 "	.align		3			\n\t"
29 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
30 		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
31 		 "	.popsection				\n\t"
32 		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
33 
34 	return false;
35 l_yes:
36 	return true;
37 }
38 
39 static __always_inline bool arch_static_branch_jump(struct static_key * const key,
40 						    const bool branch)
41 {
42 	asm goto(
43 		"1:	b		%l[l_yes]		\n\t"
44 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
45 		 "	.align		3			\n\t"
46 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
47 		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
48 		 "	.popsection				\n\t"
49 		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
50 
51 	return false;
52 l_yes:
53 	return true;
54 }
55 
56 #endif  /* __ASSEMBLY__ */
57 #endif	/* __ASM_JUMP_LABEL_H */
58