Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  arch/arm/include/asm/opcodes.h
0004  */
0005 
0006 #ifndef __ASM_ARM_OPCODES_H
0007 #define __ASM_ARM_OPCODES_H
0008 
0009 #ifndef __ASSEMBLY__
0010 #include <linux/linkage.h>
0011 extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
0012 #endif
0013 
0014 #define ARM_OPCODE_CONDTEST_FAIL   0
0015 #define ARM_OPCODE_CONDTEST_PASS   1
0016 #define ARM_OPCODE_CONDTEST_UNCOND 2
0017 
0018 
0019 /*
0020  * Assembler opcode byteswap helpers.
0021  * These are only intended for use by this header: don't use them directly,
0022  * because they will be suboptimal in most cases.
0023  */
0024 #define ___asm_opcode_swab32(x) (   \
0025       (((x) << 24) & 0xFF000000)    \
0026     | (((x) <<  8) & 0x00FF0000)    \
0027     | (((x) >>  8) & 0x0000FF00)    \
0028     | (((x) >> 24) & 0x000000FF)    \
0029 )
0030 #define ___asm_opcode_swab16(x) (   \
0031       (((x) << 8) & 0xFF00)     \
0032     | (((x) >> 8) & 0x00FF)     \
0033 )
0034 #define ___asm_opcode_swahb32(x) (  \
0035       (((x) << 8) & 0xFF00FF00) \
0036     | (((x) >> 8) & 0x00FF00FF) \
0037 )
0038 #define ___asm_opcode_swahw32(x) (  \
0039       (((x) << 16) & 0xFFFF0000)    \
0040     | (((x) >> 16) & 0x0000FFFF)    \
0041 )
0042 #define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF)
0043 #define ___asm_opcode_identity16(x) ((x) & 0xFFFF)
0044 
0045 
0046 /*
0047  * Opcode byteswap helpers
0048  *
0049  * These macros help with converting instructions between a canonical integer
0050  * format and in-memory representation, in an endianness-agnostic manner.
0051  *
0052  * __mem_to_opcode_*() convert from in-memory representation to canonical form.
0053  * __opcode_to_mem_*() convert from canonical form to in-memory representation.
0054  *
0055  *
0056  * Canonical instruction representation:
0057  *
0058  *  ARM:        0xKKLLMMNN
0059  *  Thumb 16-bit:   0x0000KKLL, where KK < 0xE8
0060  *  Thumb 32-bit:   0xKKLLMMNN, where KK >= 0xE8
0061  *
0062  * There is no way to distinguish an ARM instruction in canonical representation
0063  * from a Thumb instruction (just as these cannot be distinguished in memory).
0064  * Where this distinction is important, it needs to be tracked separately.
0065  *
0066  * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
0067  * represent any valid Thumb-2 instruction.  For this range,
0068  * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
0069  *
0070  * The ___asm variants are intended only for use by this header, in situations
0071  * involving inline assembler.  For .S files, the normal __opcode_*() macros
0072  * should do the right thing.
0073  */
0074 #ifdef __ASSEMBLY__
0075 
0076 #define ___opcode_swab32(x) ___asm_opcode_swab32(x)
0077 #define ___opcode_swab16(x) ___asm_opcode_swab16(x)
0078 #define ___opcode_swahb32(x) ___asm_opcode_swahb32(x)
0079 #define ___opcode_swahw32(x) ___asm_opcode_swahw32(x)
0080 #define ___opcode_identity32(x) ___asm_opcode_identity32(x)
0081 #define ___opcode_identity16(x) ___asm_opcode_identity16(x)
0082 
0083 #else /* ! __ASSEMBLY__ */
0084 
0085 #include <linux/types.h>
0086 #include <linux/swab.h>
0087 
0088 #define ___opcode_swab32(x) swab32(x)
0089 #define ___opcode_swab16(x) swab16(x)
0090 #define ___opcode_swahb32(x) swahb32(x)
0091 #define ___opcode_swahw32(x) swahw32(x)
0092 #define ___opcode_identity32(x) ((u32)(x))
0093 #define ___opcode_identity16(x) ((u16)(x))
0094 
0095 #endif /* ! __ASSEMBLY__ */
0096 
0097 
0098 #ifdef CONFIG_CPU_ENDIAN_BE8
0099 
0100 #define __opcode_to_mem_arm(x) ___opcode_swab32(x)
0101 #define __opcode_to_mem_thumb16(x) ___opcode_swab16(x)
0102 #define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x)
0103 #define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x)
0104 #define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x)
0105 #define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x)
0106 
0107 #else /* ! CONFIG_CPU_ENDIAN_BE8 */
0108 
0109 #define __opcode_to_mem_arm(x) ___opcode_identity32(x)
0110 #define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
0111 #define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
0112 #define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
0113 #ifdef CONFIG_CPU_ENDIAN_BE32
0114 #ifndef __ASSEMBLY__
0115 /*
0116  * On BE32 systems, using 32-bit accesses to store Thumb instructions will not
0117  * work in all cases, due to alignment constraints.  For now, a correct
0118  * version is not provided for BE32, but the prototype needs to be there
0119  * to compile patch.c.
0120  */
0121 extern __u32 __opcode_to_mem_thumb32(__u32);
0122 #endif
0123 #else
0124 #define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
0125 #define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
0126 #endif
0127 
0128 #endif /* ! CONFIG_CPU_ENDIAN_BE8 */
0129 
0130 #define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
0131 #define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
0132 #ifndef CONFIG_CPU_ENDIAN_BE32
0133 #define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
0134 #endif
0135 
0136 /* Operations specific to Thumb opcodes */
0137 
0138 /* Instruction size checks: */
0139 #define __opcode_is_thumb32(x) (        \
0140        ((x) & 0xF8000000) == 0xE8000000 \
0141     || ((x) & 0xF0000000) == 0xF0000000 \
0142 )
0143 #define __opcode_is_thumb16(x) (                    \
0144        ((x) & 0xFFFF0000) == 0                  \
0145     && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000)  \
0146 )
0147 
0148 /* Operations to construct or split 32-bit Thumb instructions: */
0149 #define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16))
0150 #define __opcode_thumb32_second(x) (___opcode_identity16(x))
0151 #define __opcode_thumb32_compose(first, second) (           \
0152       (___opcode_identity32(___opcode_identity16(first)) << 16) \
0153     | ___opcode_identity32(___opcode_identity16(second))        \
0154 )
0155 #define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16))
0156 #define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x))
0157 #define ___asm_opcode_thumb32_compose(first, second) (              \
0158       (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \
0159     | ___asm_opcode_identity32(___asm_opcode_identity16(second))        \
0160 )
0161 
0162 /*
0163  * Opcode injection helpers
0164  *
0165  * In rare cases it is necessary to assemble an opcode which the
0166  * assembler does not support directly, or which would normally be
0167  * rejected because of the CFLAGS or AFLAGS used to build the affected
0168  * file.
0169  *
0170  * Before using these macros, consider carefully whether it is feasible
0171  * instead to change the build flags for your file, or whether it really
0172  * makes sense to support old assembler versions when building that
0173  * particular kernel feature.
0174  *
0175  * The macros defined here should only be used where there is no viable
0176  * alternative.
0177  *
0178  *
0179  * __inst_arm(x): emit the specified ARM opcode
0180  * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
0181  * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
0182  *
0183  * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
0184  *  16-bit Thumb opcode, depending on whether an ARM or Thumb-2
0185  *  kernel is being built
0186  *
0187  * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
0188  *  32-bit Thumb opcode, depending on whether an ARM or Thumb-2
0189  *  kernel is being built
0190  *
0191  *
0192  * Note that using these macros directly is poor practice.  Instead, you
0193  * should use them to define human-readable wrapper macros to encode the
0194  * instructions that you care about.  In code which might run on ARMv7 or
0195  * above, you can usually use the __inst_arm_thumb{16,32} macros to
0196  * specify the ARM and Thumb alternatives at the same time.  This ensures
0197  * that the correct opcode gets emitted depending on the instruction set
0198  * used for the kernel build.
0199  *
0200  * Look at opcodes-virt.h for an example of how to use these macros.
0201  */
0202 #include <linux/stringify.h>
0203 
0204 #define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
0205 #define __inst_thumb32(x) ___inst_thumb32(              \
0206     ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)),   \
0207     ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x))   \
0208 )
0209 #define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
0210 
0211 #ifdef CONFIG_THUMB2_KERNEL
0212 #define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
0213     __inst_thumb16(thumb_opcode)
0214 #define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
0215     __inst_thumb32(thumb_opcode)
0216 #else
0217 #define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
0218 #define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
0219 #endif
0220 
0221 /* Helpers for the helpers.  Don't use these directly. */
0222 #ifdef __ASSEMBLY__
0223 #define ___inst_arm(x) .long x
0224 #define ___inst_thumb16(x) .short x
0225 #define ___inst_thumb32(first, second) .short first, second
0226 #else
0227 #define ___inst_arm(x) ".long " __stringify(x) "\n\t"
0228 #define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
0229 #define ___inst_thumb32(first, second) \
0230     ".short " __stringify(first) ", " __stringify(second) "\n\t"
0231 #endif
0232 
0233 #endif /* __ASM_ARM_OPCODES_H */