diff options
| -rw-r--r-- | 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 f57e417cab95..f7937e1c46bf 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); | |||
| 156 | | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ | 156 | | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ |
| 157 | ) | 157 | ) |
| 158 | 158 | ||
| 159 | /* | ||
| 160 | * Opcode injection helpers | ||
| 161 | * | ||
| 162 | * In rare cases it is necessary to assemble an opcode which the | ||
| 163 | * assembler does not support directly, or which would normally be | ||
| 164 | * rejected because of the CFLAGS or AFLAGS used to build the affected | ||
| 165 | * file. | ||
| 166 | * | ||
| 167 | * Before using these macros, consider carefully whether it is feasible | ||
| 168 | * instead to change the build flags for your file, or whether it really | ||
| 169 | * makes sense to support old assembler versions when building that | ||
| 170 | * particular kernel feature. | ||
| 171 | * | ||
| 172 | * The macros defined here should only be used where there is no viable | ||
| 173 | * alternative. | ||
| 174 | * | ||
| 175 | * | ||
| 176 | * __inst_arm(x): emit the specified ARM opcode | ||
| 177 | * __inst_thumb16(x): emit the specified 16-bit Thumb opcode | ||
| 178 | * __inst_thumb32(x): emit the specified 32-bit Thumb opcode | ||
| 179 | * | ||
| 180 | * __inst_arm_thumb16(arm, thumb): emit either the specified arm or | ||
| 181 | * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 | ||
| 182 | * kernel is being built | ||
| 183 | * | ||
| 184 | * __inst_arm_thumb32(arm, thumb): emit either the specified arm or | ||
| 185 | * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 | ||
| 186 | * kernel is being built | ||
| 187 | * | ||
| 188 | * | ||
| 189 | * Note that using these macros directly is poor practice. Instead, you | ||
| 190 | * should use them to define human-readable wrapper macros to encode the | ||
| 191 | * instructions that you care about. In code which might run on ARMv7 or | ||
| 192 | * above, you can usually use the __inst_arm_thumb{16,32} macros to | ||
| 193 | * specify the ARM and Thumb alternatives at the same time. This ensures | ||
| 194 | * that the correct opcode gets emitted depending on the instruction set | ||
| 195 | * used for the kernel build. | ||
| 196 | */ | ||
| 197 | #include <linux/stringify.h> | ||
| 198 | |||
| 199 | #define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) | ||
| 200 | #define __inst_thumb32(x) ___inst_thumb32( \ | ||
| 201 | ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ | ||
| 202 | ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ | ||
| 203 | ) | ||
| 204 | #define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) | ||
| 205 | |||
| 206 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 207 | #define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ | ||
| 208 | __inst_thumb16(thumb_opcode) | ||
| 209 | #define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ | ||
| 210 | __inst_thumb32(thumb_opcode) | ||
| 211 | #else | ||
| 212 | #define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) | ||
| 213 | #define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) | ||
| 214 | #endif | ||
| 215 | |||
| 216 | /* Helpers for the helpers. Don't use these directly. */ | ||
| 217 | #ifdef __ASSEMBLY__ | ||
| 218 | #define ___inst_arm(x) .long x | ||
| 219 | #define ___inst_thumb16(x) .short x | ||
| 220 | #define ___inst_thumb32(first, second) .short first, second | ||
| 221 | #else | ||
| 222 | #define ___inst_arm(x) ".long " __stringify(x) "\n\t" | ||
| 223 | #define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" | ||
| 224 | #define ___inst_thumb32(first, second) \ | ||
| 225 | ".short " __stringify(first) ", " __stringify(second) "\n\t" | ||
| 226 | #endif | ||
| 227 | |||
| 159 | #endif /* __ASM_ARM_OPCODES_H */ | 228 | #endif /* __ASM_ARM_OPCODES_H */ |
