18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (c) 2010 Cavium Networks, Inc.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#ifndef _ASM_MIPS_JUMP_LABEL_H
98c2ecf20Sopenharmony_ci#define _ASM_MIPS_JUMP_LABEL_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <asm/isa-rev.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define JUMP_LABEL_NOP_SIZE 4
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
198c2ecf20Sopenharmony_ci#define WORD_INSN ".dword"
208c2ecf20Sopenharmony_ci#else
218c2ecf20Sopenharmony_ci#define WORD_INSN ".word"
228c2ecf20Sopenharmony_ci#endif
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_MICROMIPS
258c2ecf20Sopenharmony_ci# define B_INSN "b32"
268c2ecf20Sopenharmony_ci# define J_INSN "j32"
278c2ecf20Sopenharmony_ci#elif MIPS_ISA_REV >= 6
288c2ecf20Sopenharmony_ci# define B_INSN "bc"
298c2ecf20Sopenharmony_ci# define J_INSN "bc"
308c2ecf20Sopenharmony_ci#else
318c2ecf20Sopenharmony_ci# define B_INSN "b"
328c2ecf20Sopenharmony_ci# define J_INSN "j"
338c2ecf20Sopenharmony_ci#endif
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic __always_inline bool arch_static_branch(struct static_key *key, bool branch)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	asm_volatile_goto("1:\t" B_INSN " 2f\n\t"
388c2ecf20Sopenharmony_ci		"2:\t.insn\n\t"
398c2ecf20Sopenharmony_ci		".pushsection __jump_table,  \"aw\"\n\t"
408c2ecf20Sopenharmony_ci		WORD_INSN " 1b, %l[l_yes], %0\n\t"
418c2ecf20Sopenharmony_ci		".popsection\n\t"
428c2ecf20Sopenharmony_ci		: :  "i" (&((char *)key)[branch]) : : l_yes);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	return false;
458c2ecf20Sopenharmony_cil_yes:
468c2ecf20Sopenharmony_ci	return true;
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	asm_volatile_goto("1:\t" J_INSN " %l[l_yes]\n\t"
528c2ecf20Sopenharmony_ci		".pushsection __jump_table,  \"aw\"\n\t"
538c2ecf20Sopenharmony_ci		WORD_INSN " 1b, %l[l_yes], %0\n\t"
548c2ecf20Sopenharmony_ci		".popsection\n\t"
558c2ecf20Sopenharmony_ci		: :  "i" (&((char *)key)[branch]) : : l_yes);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	return false;
588c2ecf20Sopenharmony_cil_yes:
598c2ecf20Sopenharmony_ci	return true;
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
638c2ecf20Sopenharmony_citypedef u64 jump_label_t;
648c2ecf20Sopenharmony_ci#else
658c2ecf20Sopenharmony_citypedef u32 jump_label_t;
668c2ecf20Sopenharmony_ci#endif
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistruct jump_entry {
698c2ecf20Sopenharmony_ci	jump_label_t code;
708c2ecf20Sopenharmony_ci	jump_label_t target;
718c2ecf20Sopenharmony_ci	jump_label_t key;
728c2ecf20Sopenharmony_ci};
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#endif  /* __ASSEMBLY__ */
758c2ecf20Sopenharmony_ci#endif /* _ASM_MIPS_JUMP_LABEL_H */
76