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 */ |