aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-02-01 04:42:22 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-03-24 05:38:51 -0400
commitf5f5195487affe53f90d99cba4aee73a20cae565 (patch)
tree3c2f539c086a42f2056b3979be29de15022438da /arch/arm/include/asm
parenta9d6d15131b0519363b0c94734ee80955c411093 (diff)
ARM: 7311/1: Add generic instruction opcode manipulation helpers
This patch adds some endianness-agnostic helpers to convert machine instructions between canonical integer form and in-memory representation. A canonical integer form for representing instructions is also formalised here. Signed-off-by: Dave Martin <dave.martin@linaro.org> Acked-by: Nicolas Pitre <nico@linaro.org> Tested-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r--arch/arm/include/asm/opcodes.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
index c0efdd60966f..19c48deda70f 100644
--- a/arch/arm/include/asm/opcodes.h
+++ b/arch/arm/include/asm/opcodes.h
@@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
17#define ARM_OPCODE_CONDTEST_PASS 1 17#define ARM_OPCODE_CONDTEST_PASS 1
18#define ARM_OPCODE_CONDTEST_UNCOND 2 18#define ARM_OPCODE_CONDTEST_UNCOND 2
19 19
20
21/*
22 * Opcode byteswap helpers
23 *
24 * These macros help with converting instructions between a canonical integer
25 * format and in-memory representation, in an endianness-agnostic manner.
26 *
27 * __mem_to_opcode_*() convert from in-memory representation to canonical form.
28 * __opcode_to_mem_*() convert from canonical form to in-memory representation.
29 *
30 *
31 * Canonical instruction representation:
32 *
33 * ARM: 0xKKLLMMNN
34 * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8
35 * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8
36 *
37 * There is no way to distinguish an ARM instruction in canonical representation
38 * from a Thumb instruction (just as these cannot be distinguished in memory).
39 * Where this distinction is important, it needs to be tracked separately.
40 *
41 * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
42 * represent any valid Thumb-2 instruction. For this range,
43 * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
44 */
45
46#ifndef __ASSEMBLY__
47
48#include <linux/types.h>
49#include <linux/swab.h>
50
51#ifdef CONFIG_CPU_ENDIAN_BE8
52#define __opcode_to_mem_arm(x) swab32(x)
53#define __opcode_to_mem_thumb16(x) swab16(x)
54#define __opcode_to_mem_thumb32(x) swahb32(x)
55#else
56#define __opcode_to_mem_arm(x) ((u32)(x))
57#define __opcode_to_mem_thumb16(x) ((u16)(x))
58#define __opcode_to_mem_thumb32(x) swahw32(x)
59#endif
60
61#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
62#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
63#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
64
65/* Operations specific to Thumb opcodes */
66
67/* Instruction size checks: */
68#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL)
69#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL)
70
71/* Operations to construct or split 32-bit Thumb instructions: */
72#define __opcode_thumb32_first(x) ((u16)((x) >> 16))
73#define __opcode_thumb32_second(x) ((u16)(x))
74#define __opcode_thumb32_compose(first, second) \
75 (((u32)(u16)(first) << 16) | (u32)(u16)(second))
76
77#endif /* __ASSEMBLY__ */
78
20#endif /* __ASM_ARM_OPCODES_H */ 79#endif /* __ASM_ARM_OPCODES_H */