summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/insn.c
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2017-01-09 20:28:29 +0300
committerWill Deacon <will.deacon@arm.com>2017-01-10 20:11:23 +0300
commit8c2dcbd2c4443bad0b4242fb62baa47b260b8f79 (patch)
tree0ff1e138c7fdcccdc0ac75e44636f9252bd5df4a /arch/arm64/kernel/insn.c
parentc9ee0f98662a6e358b5f2969755c938ce9c3a63a (diff)
downloadlinux-8c2dcbd2c4443bad0b4242fb62baa47b260b8f79.tar.xz
arm64: Add helper to decode register from instruction
Add a helper to extract the register field from a given instruction. Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/insn.c')
-rw-r--r--arch/arm64/kernel/insn.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 94b62c1fa4df..1f44cf8c73e6 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -417,6 +417,35 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
return insn;
}
+u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
+ u32 insn)
+{
+ int shift;
+
+ switch (type) {
+ case AARCH64_INSN_REGTYPE_RT:
+ case AARCH64_INSN_REGTYPE_RD:
+ shift = 0;
+ break;
+ case AARCH64_INSN_REGTYPE_RN:
+ shift = 5;
+ break;
+ case AARCH64_INSN_REGTYPE_RT2:
+ case AARCH64_INSN_REGTYPE_RA:
+ shift = 10;
+ break;
+ case AARCH64_INSN_REGTYPE_RM:
+ shift = 16;
+ break;
+ default:
+ pr_err("%s: unknown register type encoding %d\n", __func__,
+ type);
+ return 0;
+ }
+
+ return (insn >> shift) & GENMASK(4, 0);
+}
+
static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
u32 insn,
enum aarch64_insn_register reg)