162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_ARM_INSN_H
362306a36Sopenharmony_ci#define __ASM_ARM_INSN_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/*
862306a36Sopenharmony_ci * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
962306a36Sopenharmony_ci * appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
1062306a36Sopenharmony_ci * which should be sufficient for the core kernel as well as modules loaded
1162306a36Sopenharmony_ci * into the module region. (Not supported by LLD before release 14)
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#define LOAD_SYM_ARMV6(reg, sym)					\
1462306a36Sopenharmony_ci	"	.globl	" #sym "				\n\t"	\
1562306a36Sopenharmony_ci	"	.reloc	10f, R_ARM_ALU_PC_G0_NC, " #sym "	\n\t"	\
1662306a36Sopenharmony_ci	"	.reloc	11f, R_ARM_ALU_PC_G1_NC, " #sym "	\n\t"	\
1762306a36Sopenharmony_ci	"	.reloc	12f, R_ARM_LDR_PC_G2, " #sym "		\n\t"	\
1862306a36Sopenharmony_ci	"10:	sub	" #reg ", pc, #8			\n\t"	\
1962306a36Sopenharmony_ci	"11:	sub	" #reg ", " #reg ", #4			\n\t"	\
2062306a36Sopenharmony_ci	"12:	ldr	" #reg ", [" #reg ", #0]		\n\t"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic inline unsigned long
2362306a36Sopenharmony_ciarm_gen_nop(void)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci#ifdef CONFIG_THUMB2_KERNEL
2662306a36Sopenharmony_ci	return 0xf3af8000; /* nop.w */
2762306a36Sopenharmony_ci#else
2862306a36Sopenharmony_ci	return 0xe1a00000; /* mov r0, r0 */
2962306a36Sopenharmony_ci#endif
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciunsigned long
3362306a36Sopenharmony_ci__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic inline unsigned long
3662306a36Sopenharmony_ciarm_gen_branch(unsigned long pc, unsigned long addr)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	return __arm_gen_branch(pc, addr, false, true);
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic inline unsigned long
4262306a36Sopenharmony_ciarm_gen_branch_link(unsigned long pc, unsigned long addr, bool warn)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	return __arm_gen_branch(pc, addr, true, warn);
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#endif
48