Signed-off-by: Yeqi Fu <fufuyqqq...@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
diff --git a/target/mips/helper.h b/target/mips/helper.h index de32d82e98..9fa949d78c 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -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 */ diff --git a/target/mips/tcg/meson.build b/target/mips/tcg/meson.build index 7ee969ec8f..fb1ea64047 100644 --- a/target/mips/tcg/meson.build +++ b/target/mips/tcg/meson.build @@ -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', diff --git a/target/mips/tcg/native_helper.c b/target/mips/tcg/native_helper.c new file mode 100644 index 0000000000..bfd9c92e17 --- /dev/null +++ b/target/mips/tcg/native_helper.c @@ -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 diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index a6ca2e5a3b..d68ce6bc2f 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -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: diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h index 69f85841d2..f0112d88aa 100644 --- a/target/mips/tcg/translate.h +++ b/target/mips/tcg/translate.h @@ -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 +} -- 2.34.1