@@ -589,6 +589,12 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env)
DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env)
DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
+#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
+
#ifndef CONFIG_USER_ONLY
#include "tcg/sysemu_helper.h.inc"
#endif /* !CONFIG_USER_ONLY */
@@ -22,6 +22,7 @@ mips_ss.add(files(
'txx9_translate.c',
'vr54xx_helper.c',
'vr54xx_translate.c',
+ 'native_helper.c',
))
mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
'tx79_translate.c',
new file mode 100644
@@ -0,0 +1,55 @@
+/*
+ * native function call helpers
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USER_NATIVE_CALL)
+
+#define NATIVE_FN_W_3W() \
+ target_ulong arg0, arg1, arg2; \
+ arg0 = env->active_tc.gpr[4]; /*"a0"*/ \
+ arg1 = env->active_tc.gpr[5]; /*"a1"*/ \
+ arg2 = env->active_tc.gpr[6]; /*"a2"*/
+
+void helper_native_memcpy(CPUMIPSState *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->active_tc.gpr[2] = (target_ulong)h2g(ret);
+}
+
+void helper_native_memcmp(CPUMIPSState *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->active_tc.gpr[2] = ret;
+}
+
+void helper_native_memset(CPUMIPSState *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->active_tc.gpr[2] = (target_ulong)h2g(ret);
+}
+
+#endif
@@ -36,6 +36,7 @@
#include "qemu/qemu-print.h"
#include "fpu_helper.h"
#include "translate.h"
+#include "native/native-func.h"
/*
* Many sysemu-only helpers are not reachable for user-only.
@@ -13591,7 +13592,24 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
#endif
break;
- case OPC_SYSCALL:
+ case OPC_SYSCALL: /* 00 00 00 0C */
+ if (native_bypass() && ((((ctx->opcode) >> 24) & 0xff) == 0x1)) {
+ uint16_t sig = (ctx->opcode) >> 8 & 0xffff;
+ switch (sig) {
+ case NATIVE_MEMCPY:
+ gen_helper_native_memcpy(cpu_env);
+ break;
+ case NATIVE_MEMSET:
+ gen_helper_native_memset(cpu_env);
+ break;
+ case NATIVE_MEMCMP:
+ gen_helper_native_memcmp(cpu_env);
+ break;
+ default:
+ gen_reserved_instruction(ctx);
+ }
+ break;
+ }
generate_exception_end(ctx, EXCP_SYSCALL);
break;
case OPC_BREAK:
@@ -237,3 +237,15 @@ static inline bool cpu_is_bigendian(DisasContext *ctx)
}
#endif
+
+/*
+ * 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
+}
Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com> --- target/mips/helper.h | 6 ++++ target/mips/tcg/meson.build | 1 + target/mips/tcg/native_helper.c | 55 +++++++++++++++++++++++++++++++++ target/mips/tcg/translate.c | 20 +++++++++++- target/mips/tcg/translate.h | 12 +++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 target/mips/tcg/native_helper.c