[RFC PATCH 03/16] arm64/insn: always inline aarch64_insn_decode_register()
Ada Couprie Diaz
ada.coupriediaz at arm.com
Tue Sep 23 10:48:50 PDT 2025
As it is always called with an explicit register type, we can
check for its validity at compile time and remove the runtime error print.
This makes `aarch64_insn_decode_register()` self-contained and safe
for inlining and usage from patching callbacks.
Signed-off-by: Ada Couprie Diaz <ada.coupriediaz at arm.com>
---
arch/arm64/include/asm/insn.h | 32 ++++++++++++++++++++++++++++++--
arch/arm64/lib/insn.c | 29 -----------------------------
2 files changed, 30 insertions(+), 31 deletions(-)
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 18c7811774d3..f6bce1a62dda 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -7,6 +7,7 @@
*/
#ifndef __ASM_INSN_H
#define __ASM_INSN_H
+#include <linux/bits.h>
#include <linux/build_bug.h>
#include <linux/types.h>
@@ -558,8 +559,35 @@ enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn);
u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
u32 insn, u64 imm);
-u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
- u32 insn);
+static __always_inline u32 aarch64_insn_decode_register(
+ enum aarch64_insn_register_type type, u32 insn)
+{
+ compiletime_assert(type >= AARCH64_INSN_REGTYPE_RT &&
+ type <= AARCH64_INSN_REGTYPE_RS, "unknown register type encoding");
+ 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:
+ case AARCH64_INSN_REGTYPE_RS:
+ shift = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ return (insn >> shift) & GENMASK(4, 0);
+}
u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
enum aarch64_insn_branch_type type);
u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index 4e298baddc2e..0fac78e542cf 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -144,35 +144,6 @@ 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)
--
2.43.0
More information about the linux-arm-kernel
mailing list