1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 20c9030deSLeif Lindholm /* 30c9030deSLeif Lindholm * arch/arm/include/asm/opcodes.h 40c9030deSLeif Lindholm */ 50c9030deSLeif Lindholm 60c9030deSLeif Lindholm #ifndef __ASM_ARM_OPCODES_H 70c9030deSLeif Lindholm #define __ASM_ARM_OPCODES_H 80c9030deSLeif Lindholm 90c9030deSLeif Lindholm #ifndef __ASSEMBLY__ 106d63f646SWill Deacon #include <linux/linkage.h> 110c9030deSLeif Lindholm extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); 120c9030deSLeif Lindholm #endif 130c9030deSLeif Lindholm 140c9030deSLeif Lindholm #define ARM_OPCODE_CONDTEST_FAIL 0 150c9030deSLeif Lindholm #define ARM_OPCODE_CONDTEST_PASS 1 160c9030deSLeif Lindholm #define ARM_OPCODE_CONDTEST_UNCOND 2 170c9030deSLeif Lindholm 18f5f51954SDave Martin 19f5f51954SDave Martin /* 200ce3de23SDave Martin * Assembler opcode byteswap helpers. 210ce3de23SDave Martin * These are only intended for use by this header: don't use them directly, 220ce3de23SDave Martin * because they will be suboptimal in most cases. 230ce3de23SDave Martin */ 240ce3de23SDave Martin #define ___asm_opcode_swab32(x) ( \ 250ce3de23SDave Martin (((x) << 24) & 0xFF000000) \ 260ce3de23SDave Martin | (((x) << 8) & 0x00FF0000) \ 270ce3de23SDave Martin | (((x) >> 8) & 0x0000FF00) \ 280ce3de23SDave Martin | (((x) >> 24) & 0x000000FF) \ 290ce3de23SDave Martin ) 300ce3de23SDave Martin #define ___asm_opcode_swab16(x) ( \ 310ce3de23SDave Martin (((x) << 8) & 0xFF00) \ 320ce3de23SDave Martin | (((x) >> 8) & 0x00FF) \ 330ce3de23SDave Martin ) 340ce3de23SDave Martin #define ___asm_opcode_swahb32(x) ( \ 350ce3de23SDave Martin (((x) << 8) & 0xFF00FF00) \ 360ce3de23SDave Martin | (((x) >> 8) & 0x00FF00FF) \ 370ce3de23SDave Martin ) 380ce3de23SDave Martin #define ___asm_opcode_swahw32(x) ( \ 390ce3de23SDave Martin (((x) << 16) & 0xFFFF0000) \ 400ce3de23SDave Martin | (((x) >> 16) & 0x0000FFFF) \ 410ce3de23SDave Martin ) 420ce3de23SDave Martin #define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) 430ce3de23SDave Martin #define ___asm_opcode_identity16(x) ((x) & 0xFFFF) 440ce3de23SDave Martin 450ce3de23SDave Martin 460ce3de23SDave Martin /* 47f5f51954SDave Martin * Opcode byteswap helpers 48f5f51954SDave Martin * 49f5f51954SDave Martin * These macros help with converting instructions between a canonical integer 50f5f51954SDave Martin * format and in-memory representation, in an endianness-agnostic manner. 51f5f51954SDave Martin * 52f5f51954SDave Martin * __mem_to_opcode_*() convert from in-memory representation to canonical form. 53f5f51954SDave Martin * __opcode_to_mem_*() convert from canonical form to in-memory representation. 54f5f51954SDave Martin * 55f5f51954SDave Martin * 56f5f51954SDave Martin * Canonical instruction representation: 57f5f51954SDave Martin * 58f5f51954SDave Martin * ARM: 0xKKLLMMNN 59f5f51954SDave Martin * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8 60f5f51954SDave Martin * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8 61f5f51954SDave Martin * 62f5f51954SDave Martin * There is no way to distinguish an ARM instruction in canonical representation 63f5f51954SDave Martin * from a Thumb instruction (just as these cannot be distinguished in memory). 64f5f51954SDave Martin * Where this distinction is important, it needs to be tracked separately. 65f5f51954SDave Martin * 66f5f51954SDave Martin * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not 67f5f51954SDave Martin * represent any valid Thumb-2 instruction. For this range, 68f5f51954SDave Martin * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. 690ce3de23SDave Martin * 700ce3de23SDave Martin * The ___asm variants are intended only for use by this header, in situations 710ce3de23SDave Martin * involving inline assembler. For .S files, the normal __opcode_*() macros 720ce3de23SDave Martin * should do the right thing. 73f5f51954SDave Martin */ 740ce3de23SDave Martin #ifdef __ASSEMBLY__ 75f5f51954SDave Martin 760ce3de23SDave Martin #define ___opcode_swab32(x) ___asm_opcode_swab32(x) 770ce3de23SDave Martin #define ___opcode_swab16(x) ___asm_opcode_swab16(x) 780ce3de23SDave Martin #define ___opcode_swahb32(x) ___asm_opcode_swahb32(x) 790ce3de23SDave Martin #define ___opcode_swahw32(x) ___asm_opcode_swahw32(x) 800ce3de23SDave Martin #define ___opcode_identity32(x) ___asm_opcode_identity32(x) 810ce3de23SDave Martin #define ___opcode_identity16(x) ___asm_opcode_identity16(x) 820ce3de23SDave Martin 830ce3de23SDave Martin #else /* ! __ASSEMBLY__ */ 84f5f51954SDave Martin 85f5f51954SDave Martin #include <linux/types.h> 86f5f51954SDave Martin #include <linux/swab.h> 87f5f51954SDave Martin 880ce3de23SDave Martin #define ___opcode_swab32(x) swab32(x) 890ce3de23SDave Martin #define ___opcode_swab16(x) swab16(x) 900ce3de23SDave Martin #define ___opcode_swahb32(x) swahb32(x) 910ce3de23SDave Martin #define ___opcode_swahw32(x) swahw32(x) 920ce3de23SDave Martin #define ___opcode_identity32(x) ((u32)(x)) 930ce3de23SDave Martin #define ___opcode_identity16(x) ((u16)(x)) 940ce3de23SDave Martin 950ce3de23SDave Martin #endif /* ! __ASSEMBLY__ */ 960ce3de23SDave Martin 970ce3de23SDave Martin 98f5f51954SDave Martin #ifdef CONFIG_CPU_ENDIAN_BE8 9957b9da32SDave Martin 1000ce3de23SDave Martin #define __opcode_to_mem_arm(x) ___opcode_swab32(x) 1010ce3de23SDave Martin #define __opcode_to_mem_thumb16(x) ___opcode_swab16(x) 1020ce3de23SDave Martin #define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x) 1030ce3de23SDave Martin #define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x) 1040ce3de23SDave Martin #define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x) 1050ce3de23SDave Martin #define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x) 10657b9da32SDave Martin 10757b9da32SDave Martin #else /* ! CONFIG_CPU_ENDIAN_BE8 */ 10857b9da32SDave Martin 1090ce3de23SDave Martin #define __opcode_to_mem_arm(x) ___opcode_identity32(x) 1100ce3de23SDave Martin #define __opcode_to_mem_thumb16(x) ___opcode_identity16(x) 1110ce3de23SDave Martin #define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) 1120ce3de23SDave Martin #define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x) 113*ae3d6978SArnd Bergmann #ifdef CONFIG_CPU_ENDIAN_BE32 114*ae3d6978SArnd Bergmann #ifndef __ASSEMBLY__ 11557b9da32SDave Martin /* 11657b9da32SDave Martin * On BE32 systems, using 32-bit accesses to store Thumb instructions will not 11757b9da32SDave Martin * work in all cases, due to alignment constraints. For now, a correct 118*ae3d6978SArnd Bergmann * version is not provided for BE32, but the prototype needs to be there 119*ae3d6978SArnd Bergmann * to compile patch.c. 12057b9da32SDave Martin */ 121*ae3d6978SArnd Bergmann extern __u32 __opcode_to_mem_thumb32(__u32); 122*ae3d6978SArnd Bergmann #endif 123*ae3d6978SArnd Bergmann #else 1240ce3de23SDave Martin #define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x) 1250ce3de23SDave Martin #define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x) 126f5f51954SDave Martin #endif 127f5f51954SDave Martin 12857b9da32SDave Martin #endif /* ! CONFIG_CPU_ENDIAN_BE8 */ 12957b9da32SDave Martin 130f5f51954SDave Martin #define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) 131f5f51954SDave Martin #define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) 13257b9da32SDave Martin #ifndef CONFIG_CPU_ENDIAN_BE32 133f5f51954SDave Martin #define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) 13457b9da32SDave Martin #endif 135f5f51954SDave Martin 136f5f51954SDave Martin /* Operations specific to Thumb opcodes */ 137f5f51954SDave Martin 138f5f51954SDave Martin /* Instruction size checks: */ 1390ce3de23SDave Martin #define __opcode_is_thumb32(x) ( \ 1400ce3de23SDave Martin ((x) & 0xF8000000) == 0xE8000000 \ 1410ce3de23SDave Martin || ((x) & 0xF0000000) == 0xF0000000 \ 1420ce3de23SDave Martin ) 1430ce3de23SDave Martin #define __opcode_is_thumb16(x) ( \ 1440ce3de23SDave Martin ((x) & 0xFFFF0000) == 0 \ 1450ce3de23SDave Martin && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \ 1460ce3de23SDave Martin ) 147f5f51954SDave Martin 148f5f51954SDave Martin /* Operations to construct or split 32-bit Thumb instructions: */ 1490ce3de23SDave Martin #define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16)) 1500ce3de23SDave Martin #define __opcode_thumb32_second(x) (___opcode_identity16(x)) 1510ce3de23SDave Martin #define __opcode_thumb32_compose(first, second) ( \ 1520ce3de23SDave Martin (___opcode_identity32(___opcode_identity16(first)) << 16) \ 1530ce3de23SDave Martin | ___opcode_identity32(___opcode_identity16(second)) \ 1540ce3de23SDave Martin ) 1550ce3de23SDave Martin #define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16)) 1560ce3de23SDave Martin #define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x)) 1570ce3de23SDave Martin #define ___asm_opcode_thumb32_compose(first, second) ( \ 1580ce3de23SDave Martin (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \ 1590ce3de23SDave Martin | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ 1600ce3de23SDave Martin ) 161f5f51954SDave Martin 162a61a41a0SDave Martin /* 163a61a41a0SDave Martin * Opcode injection helpers 164a61a41a0SDave Martin * 165a61a41a0SDave Martin * In rare cases it is necessary to assemble an opcode which the 166a61a41a0SDave Martin * assembler does not support directly, or which would normally be 167a61a41a0SDave Martin * rejected because of the CFLAGS or AFLAGS used to build the affected 168a61a41a0SDave Martin * file. 169a61a41a0SDave Martin * 170a61a41a0SDave Martin * Before using these macros, consider carefully whether it is feasible 171a61a41a0SDave Martin * instead to change the build flags for your file, or whether it really 172a61a41a0SDave Martin * makes sense to support old assembler versions when building that 173a61a41a0SDave Martin * particular kernel feature. 174a61a41a0SDave Martin * 175a61a41a0SDave Martin * The macros defined here should only be used where there is no viable 176a61a41a0SDave Martin * alternative. 177a61a41a0SDave Martin * 178a61a41a0SDave Martin * 179a61a41a0SDave Martin * __inst_arm(x): emit the specified ARM opcode 180a61a41a0SDave Martin * __inst_thumb16(x): emit the specified 16-bit Thumb opcode 181a61a41a0SDave Martin * __inst_thumb32(x): emit the specified 32-bit Thumb opcode 182a61a41a0SDave Martin * 183a61a41a0SDave Martin * __inst_arm_thumb16(arm, thumb): emit either the specified arm or 184a61a41a0SDave Martin * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 185a61a41a0SDave Martin * kernel is being built 186a61a41a0SDave Martin * 187a61a41a0SDave Martin * __inst_arm_thumb32(arm, thumb): emit either the specified arm or 188a61a41a0SDave Martin * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 189a61a41a0SDave Martin * kernel is being built 190a61a41a0SDave Martin * 191a61a41a0SDave Martin * 192a61a41a0SDave Martin * Note that using these macros directly is poor practice. Instead, you 193a61a41a0SDave Martin * should use them to define human-readable wrapper macros to encode the 194a61a41a0SDave Martin * instructions that you care about. In code which might run on ARMv7 or 195a61a41a0SDave Martin * above, you can usually use the __inst_arm_thumb{16,32} macros to 196a61a41a0SDave Martin * specify the ARM and Thumb alternatives at the same time. This ensures 197a61a41a0SDave Martin * that the correct opcode gets emitted depending on the instruction set 198a61a41a0SDave Martin * used for the kernel build. 199508514edSDave Martin * 200508514edSDave Martin * Look at opcodes-virt.h for an example of how to use these macros. 201a61a41a0SDave Martin */ 202a61a41a0SDave Martin #include <linux/stringify.h> 203a61a41a0SDave Martin 204a61a41a0SDave Martin #define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) 205a61a41a0SDave Martin #define __inst_thumb32(x) ___inst_thumb32( \ 206a61a41a0SDave Martin ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ 207a61a41a0SDave Martin ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ 208a61a41a0SDave Martin ) 209a61a41a0SDave Martin #define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) 210a61a41a0SDave Martin 211a61a41a0SDave Martin #ifdef CONFIG_THUMB2_KERNEL 212a61a41a0SDave Martin #define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ 213a61a41a0SDave Martin __inst_thumb16(thumb_opcode) 214a61a41a0SDave Martin #define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ 215a61a41a0SDave Martin __inst_thumb32(thumb_opcode) 216a61a41a0SDave Martin #else 217a61a41a0SDave Martin #define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) 218a61a41a0SDave Martin #define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) 219a61a41a0SDave Martin #endif 220a61a41a0SDave Martin 221a61a41a0SDave Martin /* Helpers for the helpers. Don't use these directly. */ 222a61a41a0SDave Martin #ifdef __ASSEMBLY__ 223a61a41a0SDave Martin #define ___inst_arm(x) .long x 224a61a41a0SDave Martin #define ___inst_thumb16(x) .short x 225a61a41a0SDave Martin #define ___inst_thumb32(first, second) .short first, second 226a61a41a0SDave Martin #else 227a61a41a0SDave Martin #define ___inst_arm(x) ".long " __stringify(x) "\n\t" 228a61a41a0SDave Martin #define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" 229a61a41a0SDave Martin #define ___inst_thumb32(first, second) \ 230a61a41a0SDave Martin ".short " __stringify(first) ", " __stringify(second) "\n\t" 231a61a41a0SDave Martin #endif 232a61a41a0SDave Martin 2330c9030deSLeif Lindholm #endif /* __ASM_ARM_OPCODES_H */ 234