xref: /linux/arch/openrisc/include/asm/jump_label.h (revision 742adaa16db994ba1748465b95548e2f28aa18ca)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2025 Chen Miao
4  *
5  * Based on arch/arm/include/asm/jump_label.h
6  */
7 #ifndef __ASM_OPENRISC_JUMP_LABEL_H
8 #define __ASM_OPENRISC_JUMP_LABEL_H
9 
10 #ifndef __ASSEMBLER__
11 
12 #include <linux/types.h>
13 #include <asm/insn-def.h>
14 
15 #define HAVE_JUMP_LABEL_BATCH
16 
17 #define JUMP_LABEL_NOP_SIZE OPENRISC_INSN_SIZE
18 
19 /**
20  * JUMP_TABLE_ENTRY - Create a jump table entry
21  * @key: Jump key identifier (typically a symbol address)
22  * @label: Target label address
23  *
24  * This macro creates a jump table entry in the dedicated kernel section (__jump_table).
25  * Each entry contains the following information:
26  * 		Offset from current instruction to jump instruction (1b - .)
27  * 		Offset from current instruction to target label (label - .)
28  * 		Offset from current instruction to key identifier (key - .)
29  */
30 #define JUMP_TABLE_ENTRY(key, label)			\
31 	".pushsection	__jump_table, \"aw\"	\n\t"	\
32 	".align 	4 			\n\t"	\
33 	".long 		1b - ., " label " - .	\n\t"	\
34 	".long 		" key " - . 		\n\t"	\
35 	".popsection				\n\t"
36 
37 #define ARCH_STATIC_BRANCH_ASM(key, label)		\
38 	".align		4			\n\t"	\
39 	"1: l.nop				\n\t"	\
40 	"    l.nop				\n\t"	\
41 	JUMP_TABLE_ENTRY(key, label)
42 
arch_static_branch(struct static_key * const key,const bool branch)43 static __always_inline bool arch_static_branch(struct static_key *const key,
44 					       const bool branch)
45 {
46 	asm goto (ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]")
47 		  ::"i"(&((char *)key)[branch])::l_yes);
48 
49 	return false;
50 l_yes:
51 	return true;
52 }
53 
54 #define ARCH_STATIC_BRANCH_JUMP_ASM(key, label)		\
55 	".align		4			\n\t"	\
56 	"1: l.j	" label "			\n\t"	\
57 	"    l.nop				\n\t"	\
58 	JUMP_TABLE_ENTRY(key, label)
59 
60 static __always_inline bool
arch_static_branch_jump(struct static_key * const key,const bool branch)61 arch_static_branch_jump(struct static_key *const key, const bool branch)
62 {
63 	asm goto (ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[l_yes]")
64 		  ::"i"(&((char *)key)[branch])::l_yes);
65 
66 	return false;
67 l_yes:
68 	return true;
69 }
70 
71 #endif /* __ASSEMBLER__ */
72 #endif /* __ASM_OPENRISC_JUMP_LABEL_H */
73