xref: /linux/arch/loongarch/include/asm/jump_label.h (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2023 Loongson Technology Corporation Limited
4  *
5  * Based on arch/arm64/include/asm/jump_label.h
6  */
7 #ifndef __ASM_JUMP_LABEL_H
8 #define __ASM_JUMP_LABEL_H
9 
10 #ifndef __ASSEMBLER__
11 
12 #include <linux/types.h>
13 #include <linux/stringify.h>
14 #include <asm/asm.h>
15 
16 #define HAVE_JUMP_LABEL_BATCH
17 
18 #define JUMP_LABEL_NOP_SIZE	4
19 
20 #ifdef CONFIG_32BIT
21 #define JUMP_LABEL_TYPE		".long "
22 #else
23 #define JUMP_LABEL_TYPE		".quad "
24 #endif
25 
26 /* This macro is also expanded on the Rust side. */
27 #define JUMP_TABLE_ENTRY(key, label)			\
28 	 ".pushsection	__jump_table, \"aw\"	\n\t"	\
29 	 ".align	" __stringify(PTRLOG) "	\n\t"	\
30 	 ".long		1b - ., " label " - .	\n\t"	\
31 	 JUMP_LABEL_TYPE  key " - .		\n\t"	\
32 	 ".popsection				\n\t"
33 
34 #define ARCH_STATIC_BRANCH_ASM(key, label)		\
35 	"1:	nop				\n\t"	\
36 	JUMP_TABLE_ENTRY(key, label)
37 
38 static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
39 {
40 	asm goto(
41 		ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]")
42 		:  :  "i"(&((char *)key)[branch]) :  : l_yes);
43 
44 	return false;
45 
46 l_yes:
47 	return true;
48 }
49 
50 static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch)
51 {
52 	asm goto(
53 		"1:	b	%l[l_yes]	\n\t"
54 		JUMP_TABLE_ENTRY("%0", "%l[l_yes]")
55 		:  :  "i"(&((char *)key)[branch]) :  : l_yes);
56 
57 	return false;
58 
59 l_yes:
60 	return true;
61 }
62 
63 #endif  /* __ASSEMBLER__ */
64 #endif	/* __ASM_JUMP_LABEL_H */
65