[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v2 5/6] target/arm: Add native library calls
From: |
Yeqi Fu |
Subject: |
[RFC v2 5/6] target/arm: Add native library calls |
Date: |
Thu, 8 Jun 2023 00:47:49 +0800 |
Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
---
target/arm/helper.c | 47 ++++++++++++++++++++++++++++++++++
target/arm/helper.h | 6 +++++
target/arm/tcg/translate-a64.c | 22 ++++++++++++++++
target/arm/tcg/translate.c | 25 +++++++++++++++++-
target/arm/tcg/translate.h | 19 ++++++++++++++
5 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0b7fd2e7e6..03fbc3724b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -25,6 +25,7 @@
#include "sysemu/tcg.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
+#include "exec/cpu_ldst.h"
#ifdef CONFIG_TCG
#include "semihosting/common-semi.h"
#endif
@@ -12045,3 +12046,49 @@ void aarch64_sve_change_el(CPUARMState *env, int
old_el,
}
}
#endif
+
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USER_NATIVE_CALL)
+
+#define NATIVE_FN_W_3W() \
+ target_ulong arg0, arg1, arg2; \
+ arg0 = env->regs[0]; \
+ arg1 = env->regs[1]; \
+ arg2 = env->regs[2];
+
+void helper_native_memcpy(CPUARMState *env)
+{
+ CPUState *cs = env_cpu(env);
+ NATIVE_FN_W_3W();
+ void *ret;
+ void *dest = g2h(cs, arg0);
+ void *src = g2h(cs, arg1);
+ size_t n = (size_t)arg2;
+ ret = memcpy(dest, src, n);
+ env->regs[0] = (target_ulong)h2g(ret);
+}
+
+void helper_native_memcmp(CPUARMState *env)
+{
+ CPUState *cs = env_cpu(env);
+ NATIVE_FN_W_3W();
+ int ret;
+ void *s1 = g2h(cs, arg0);
+ void *s2 = g2h(cs, arg1);
+ size_t n = (size_t)arg2;
+ ret = memcmp(s1, s2, n);
+ env->regs[0] = ret;
+}
+
+void helper_native_memset(CPUARMState *env)
+{
+ CPUState *cs = env_cpu(env);
+ NATIVE_FN_W_3W();
+ void *ret;
+ void *s = g2h(cs, arg0);
+ int c = (int)arg1;
+ size_t n = (size_t)arg2;
+ ret = memset(s, c, n);
+ env->regs[0] = (target_ulong)h2g(ret);
+}
+
+#endif
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 3335c2b10b..57144bf6fb 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1038,6 +1038,12 @@ DEF_HELPER_FLAGS_5(gvec_uclamp_s, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USER_NATIVE_CALL)
+DEF_HELPER_1(native_memcpy, void, env)
+DEF_HELPER_1(native_memcmp, void, env)
+DEF_HELPER_1(native_memset, void, env)
+#endif
+
#ifdef TARGET_AARCH64
#include "tcg/helper-a64.h"
#include "tcg/helper-sve.h"
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 741a608739..04421af6c6 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -35,6 +35,7 @@
#include "cpregs.h"
#include "translate-a64.h"
#include "qemu/atomic128.h"
+#include "native/native-func.h"
static TCGv_i64 cpu_X[32];
static TCGv_i64 cpu_pc;
@@ -2291,6 +2292,9 @@ static void disas_exc(DisasContext *s, uint32_t insn)
if (s->fgt_svc) {
gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
break;
+ } else if (native_bypass() && imm16 == 0xff) {
+ s->native_call_status = true;
+ break;
}
gen_ss_advance(s);
gen_exception_insn(s, 4, EXCP_SWI, syndrome);
@@ -14203,6 +14207,24 @@ static void aarch64_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cpu)
s->fp_access_checked = false;
s->sve_access_checked = false;
+ if (native_bypass() && s->native_call_status) {
+ switch (insn) {
+ case NATIVE_MEMCPY:
+ gen_helper_native_memcpy(cpu_env);
+ break;
+ case NATIVE_MEMCMP:
+ gen_helper_native_memcmp(cpu_env);
+ break;
+ case NATIVE_MEMSET:
+ gen_helper_native_memset(cpu_env);
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+ s->native_call_status = false;
+ return;
+ }
+
if (s->pstate_il) {
/*
* Illegal execution state. This has priority over BTI
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 7468476724..83ce0f7437 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -34,7 +34,7 @@
#include "exec/helper-gen.h"
#include "exec/log.h"
#include "cpregs.h"
-
+#include "native/native-func.h"
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
@@ -58,6 +58,10 @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
TCGv_i64 cpu_exclusive_addr;
TCGv_i64 cpu_exclusive_val;
+#if defined(CONFIG_USER_ONLY) && !defined(TARGET_AARCH64) \
+ && defined(CONFIG_USER_NATIVE_CALL)
+#endif
+
#include "exec/gen-icount.h"
static const char * const regnames[] =
@@ -8576,6 +8580,8 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
if (s->fgt_svc) {
uint32_t syndrome = syn_aa32_svc(a->imm, s->thumb);
gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
+ } else if (native_bypass() && a->imm == 0xff) {
+ s->native_call_status = true;
} else {
gen_update_pc(s, curr_insn_len(s));
s->svc_imm = a->imm;
@@ -9372,6 +9378,23 @@ static void arm_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cpu)
insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
dc->insn = insn;
dc->base.pc_next = pc + 4;
+ if (native_bypass() && dc->native_call_status) {
+ switch (insn) {
+ case NATIVE_MEMCPY:
+ gen_helper_native_memcpy(cpu_env);
+ break;
+ case NATIVE_MEMCMP:
+ gen_helper_native_memcmp(cpu_env);
+ break;
+ case NATIVE_MEMSET:
+ gen_helper_native_memset(cpu_env);
+ break;
+ default:
+ unallocated_encoding(dc);
+ }
+ dc->native_call_status = false;
+ return;
+ }
disas_arm_insn(dc, insn);
arm_post_translate_insn(dc);
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index a9d1f4adc2..19c4f7af7f 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -149,6 +149,13 @@ typedef struct DisasContext {
int c15_cpar;
/* TCG op of the current insn_start. */
TCGOp *insn_start;
+ /*
+ * Indicate whether the next instruction is a native function call (true)
+ * or not (false).
+ */
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USER_NATIVE_CALL)
+ bool native_call_status;
+#endif
} DisasContext;
typedef struct DisasCompare {
@@ -657,3 +664,15 @@ static inline void gen_restore_rmode(TCGv_i32 old,
TCGv_ptr fpst)
}
#endif /* TARGET_ARM_TRANSLATE_H */
+
+/*
+ * Check if the native bypass feature is enabled.
+ */
+static inline bool native_bypass(void)
+{
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USER_NATIVE_CALL)
+ return true;
+#else
+ return false;
+#endif
+}
--
2.34.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [RFC v2 5/6] target/arm: Add native library calls,
Yeqi Fu <=