[PATCH 3/4] ARM: opcodes: Add helpers for emitting custom opcodes
Nicolas Pitre
nicolas.pitre at linaro.org
Thu Mar 15 13:54:22 EDT 2012
On Thu, 15 Mar 2012, Dave Martin wrote:
> This patch adds some __inst_() macros for injecting custom opcodes
> in assembler (both inline and in .S files). They should make it
> easier and cleaner to get things right in little-/big-
> endian/ARM/Thumb-2 kernels without a lot of #ifdefs.
>
> Signed-off-by: Dave Martin <dave.martin at linaro.org>
Acked-by: Nicolas Pitre <nico at linaro.org>
> ---
> arch/arm/include/asm/opcodes.h | 69 ++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 69 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
> index 32730a8..50ef0be 100644
> --- a/arch/arm/include/asm/opcodes.h
> +++ b/arch/arm/include/asm/opcodes.h
> @@ -156,4 +156,73 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
> | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \
> )
>
> +/*
> + * Opcode injection helpers
> + *
> + * In rare cases it is necessary to assemble an opcode which the
> + * assembler does not support directly, or which would normally be
> + * rejected because of the CFLAGS or AFLAGS used to build the affected
> + * file.
> + *
> + * Before using these macros, consider carefully whether it is feasible
> + * instead to change the build flags for your file, or whether it really
> + * makes sense to support old assembler versions when building that
> + * particular kernel feature.
> + *
> + * The macros defined here should only be used where there is no viable
> + * alternative.
> + *
> + *
> + * __inst_arm(x): emit the specified ARM opcode
> + * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
> + * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
> + *
> + * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
> + * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2
> + * kernel is being built
> + *
> + * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
> + * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2
> + * kernel is being built
> + *
> + *
> + * Note that using these macros directly is poor practice. Instead, you
> + * should use them to define human-readable wrapper macros to encode the
> + * instructions that you care about. In code which might run on ARMv7 or
> + * above, you can usually use the __inst_arm_thumb{16,32} macros to
> + * specify the ARM and Thumb alternatives at the same time. This ensures
> + * that the correct opcode gets emitted depending on the instruction set
> + * used for the kernel build.
> + */
> +#include <linux/stringify.h>
> +
> +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
> +#define __inst_thumb32(x) ___inst_thumb32( \
> + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \
> + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \
> +)
> +#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
> +
> +#ifdef CONFIG_THUMB2_KERNEL
> +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
> + __inst_thumb16(thumb_opcode)
> +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
> + __inst_thumb32(thumb_opcode)
> +#else
> +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
> +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
> +#endif
> +
> +/* Helpers for the helpers. Don't use these directly. */
> +#ifdef __ASSEMBLY__
> +#define ___inst_arm(x) .long x
> +#define ___inst_thumb16(x) .short x
> +#define ___inst_thumb32(first, second) .short first, second
> +#else
> +#define ___inst_arm(x) ".long " __stringify(x) "\n\t"
> +#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
> +#define ___inst_thumb32(first, second) \
> + ".short " __stringify(first) ", " __stringify(second) "\n\t"
> +#endif
> +
> #endif /* __ASM_ARM_OPCODES_H */
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
More information about the linux-arm-kernel
mailing list