The current helpers only cover single and pair load/stores.
Introduce new helpers to cover exclusive, load acquire, store release
and the LSE atomics, as they both load and store.
To gather all of them in one call : introduce `aarch64_insn_is_load()`,
`aarch64_insn_is_store()`, and `aarch64_insn_is_ldst()` helpers which
check if the instruction is a load, store or either.
Signed-off-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
---
Note: I made the LSE atomics part of the is_{load,store} helpers
as they are used as such by `aarch64_insn_encode_ldst_size()`,
but it could make sense to not have them in the helpers and just
call them together where neeeded.
---
arch/arm64/include/asm/insn.h | 53 +++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 4ba4d5c50137..44435eede1f3 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -520,6 +520,23 @@ static __always_inline bool aarch64_insn_is_barrier(u32 insn)
aarch64_insn_is_pssbb(insn);
}
+#ifdef CONFIG_ARM64_LSE_ATOMICS
+static __always_inline bool aarch64_insn_is_lse_atomic(u32 insn)
+{
+ return aarch64_insn_is_ldadd(insn) ||
+ aarch64_insn_is_ldclr(insn) ||
+ aarch64_insn_is_ldeor(insn) ||
+ aarch64_insn_is_ldset(insn) ||
+ aarch64_insn_is_swp(insn) ||
+ aarch64_insn_is_cas(insn);
+}
+#else /* CONFIG_ARM64_LSE_ATOMICS */
+static __always_inline bool aarch64_insn_is_lse_atomic(u32 insn)
+{
+ return false;
+}
+#endif /* CONFIG_ARM64_LSE_ATOMICS */
+
static __always_inline bool aarch64_insn_is_store_single(u32 insn)
{
return aarch64_insn_is_store_imm(insn) ||
@@ -534,6 +551,21 @@ static __always_inline bool aarch64_insn_is_store_pair(u32 insn)
aarch64_insn_is_stp_post(insn);
}
+static __always_inline bool aarch64_insn_is_store_ex_or_rel(u32 insn)
+{
+ return aarch64_insn_is_store_ex(insn) ||
+ aarch64_insn_is_store_ex(insn & (~BIT(15))) ||
+ aarch64_insn_is_store_rel(insn);
+}
+
+static __always_inline bool aarch64_insn_is_store(u32 insn)
+{
+ return aarch64_insn_is_store_single(insn) ||
+ aarch64_insn_is_store_pair(insn) ||
+ aarch64_insn_is_store_ex_or_rel(insn) ||
+ aarch64_insn_is_lse_atomic(insn);
+}
+
static __always_inline bool aarch64_insn_is_load_single(u32 insn)
{
return aarch64_insn_is_load_imm(insn) ||
@@ -548,6 +580,27 @@ static __always_inline bool aarch64_insn_is_load_pair(u32 insn)
aarch64_insn_is_ldp_post(insn);
}
+static __always_inline bool aarch64_insn_is_load_ex_or_acq(u32 insn)
+{
+ return aarch64_insn_is_load_ex(insn) ||
+ aarch64_insn_is_load_ex(insn & (~BIT(15))) ||
+ aarch64_insn_is_load_acq(insn);
+}
+
+static __always_inline bool aarch64_insn_is_load(u32 insn)
+{
+ return aarch64_insn_is_load_single(insn) ||
+ aarch64_insn_is_load_pair(insn) ||
+ aarch64_insn_is_load_ex_or_acq(insn) ||
+ aarch64_insn_is_lse_atomic(insn);
+}
+
+static __always_inline bool aarch64_insn_is_ldst(u32 insn)
+{
+ return aarch64_insn_is_load(insn) ||
+ aarch64_insn_is_store(insn);
+}
+
static __always_inline bool aarch64_insn_uses_literal(u32 insn)
{
/* ldr/ldrsw (literal), prfm */
--
2.43.0