diff options
author | Jiang Liu <liuj97@gmail.com> | 2014-01-07 22:17:10 +0800 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-01-08 15:21:29 +0000 |
commit | c84fced8d990dd86c523233d38b4685a52a4fc3f (patch) | |
tree | 436b20c25726810b4701e23928f786e550a60d1e /arch/arm64/kernel/insn.c | |
parent | ae16480785de1da84f21d1698f304a52f9790c49 (diff) | |
download | linux-stable-c84fced8d990dd86c523233d38b4685a52a4fc3f.tar.gz linux-stable-c84fced8d990dd86c523233d38b4685a52a4fc3f.tar.bz2 linux-stable-c84fced8d990dd86c523233d38b4685a52a4fc3f.zip |
arm64: move encode_insn_immediate() from module.c to insn.c
Function encode_insn_immediate() will be used by other instruction
manipulate related functions, so move it into insn.c and rename it
as aarch64_insn_encode_immediate().
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/insn.c')
-rw-r--r-- | arch/arm64/kernel/insn.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index b9dac57e580a..7df08075fc7a 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -208,3 +208,57 @@ int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt) return aarch64_insn_patch_text_sync(addrs, insns, cnt); } + +u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, + u32 insn, u64 imm) +{ + u32 immlo, immhi, lomask, himask, mask; + int shift; + + switch (type) { + case AARCH64_INSN_IMM_ADR: + lomask = 0x3; + himask = 0x7ffff; + immlo = imm & lomask; + imm >>= 2; + immhi = imm & himask; + imm = (immlo << 24) | (immhi); + mask = (lomask << 24) | (himask); + shift = 5; + break; + case AARCH64_INSN_IMM_26: + mask = BIT(26) - 1; + shift = 0; + break; + case AARCH64_INSN_IMM_19: + mask = BIT(19) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_16: + mask = BIT(16) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_14: + mask = BIT(14) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_12: + mask = BIT(12) - 1; + shift = 10; + break; + case AARCH64_INSN_IMM_9: + mask = BIT(9) - 1; + shift = 12; + break; + default: + pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n", + type); + return 0; + } + + /* Update the immediate field. */ + insn &= ~(mask << shift); + insn |= (imm & mask) << shift; + + return insn; +} |