This commit introduces support for native library calls on the
i386 target. When encountering special instructions reserved
for native calls, this commit extracts the function name and
generates the corresponding native call.

Signed-off-by: Yeqi Fu <fufuyqqq...@gmail.com>
---
 configs/targets/i386-linux-user.mak   |  1 +
 configs/targets/x86_64-linux-user.mak |  1 +
 target/i386/tcg/translate.c           | 38 +++++++++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/configs/targets/i386-linux-user.mak 
b/configs/targets/i386-linux-user.mak
index 5b2546a430..2d8bca8f93 100644
--- a/configs/targets/i386-linux-user.mak
+++ b/configs/targets/i386-linux-user.mak
@@ -2,3 +2,4 @@ TARGET_ARCH=i386
 TARGET_SYSTBL_ABI=i386
 TARGET_SYSTBL=syscall_32.tbl
 TARGET_XML_FILES= gdb-xml/i386-32bit.xml
+CONFIG_NATIVE_CALL=y
diff --git a/configs/targets/x86_64-linux-user.mak 
b/configs/targets/x86_64-linux-user.mak
index 9ceefbb615..a53b017454 100644
--- a/configs/targets/x86_64-linux-user.mak
+++ b/configs/targets/x86_64-linux-user.mak
@@ -3,3 +3,4 @@ TARGET_BASE_ARCH=i386
 TARGET_SYSTBL_ABI=common,64
 TARGET_SYSTBL=syscall_64.tbl
 TARGET_XML_FILES= gdb-xml/i386-64bit.xml
+CONFIG_NATIVE_CALL=y
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 90c7b32f36..a7a8377832 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -33,6 +33,7 @@
 #include "helper-tcg.h"
 
 #include "exec/log.h"
+#include "native/native.h"
 
 #define HELPER_H "helper.h"
 #include "exec/helper-info.c.inc"
@@ -3075,6 +3076,37 @@ static void gen_cmpxchg16b(DisasContext *s, CPUX86State 
*env, int modrm)
 }
 #endif
 
+static void gen_native_call(CPUState *cpu, DisasContext *s, CPUX86State *env)
+{
+#ifdef CONFIG_USER_ONLY
+    uint32_t func_tmp;
+    char *func_name;
+    TCGv ret = tcg_temp_new();
+    TCGv arg1 = tcg_temp_new();
+    TCGv arg2 = tcg_temp_new();
+    TCGv arg3 = tcg_temp_new();
+    x86_ldub_code(env, s);
+    func_tmp = x86_ldl_code(env, s);
+    func_name = g2h(cpu, s->pc + func_tmp);
+#ifdef TARGET_X86_64
+    tcg_gen_mov_tl(arg1, cpu_regs[R_EDI]);
+    tcg_gen_mov_tl(arg2, cpu_regs[R_ESI]);
+    tcg_gen_mov_tl(arg3, cpu_regs[R_EDX]);
+#else
+    tcg_gen_addi_tl(arg1, cpu_regs[R_ESP], 4);
+    gen_op_ld_v(s, MO_UL, arg1, arg1);
+    tcg_gen_addi_tl(arg2, cpu_regs[R_ESP], 8);
+    gen_op_ld_v(s, MO_UL, arg2, arg2);
+    tcg_gen_addi_tl(arg3, cpu_regs[R_ESP], 12);
+    gen_op_ld_v(s, MO_UL, arg3, arg3);
+#endif
+    if (!gen_native_call_tl(func_name, ret, arg1, arg2, arg3)) {
+        gen_illegal_opcode(s);
+    }
+    tcg_gen_mov_tl(cpu_regs[R_EAX], ret);
+#endif
+}
+
 /* convert one instruction. s->base.is_jmp is set if the translation must
    be stopped. Return the next pc value */
 static bool disas_insn(DisasContext *s, CPUState *cpu)
@@ -6810,6 +6842,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1d0 ... 0x1fe:
         disas_insn_new(s, cpu, b);
         break;
+    case 0x1ff:
+        if (native_bypass_enabled()) {
+            gen_native_call(cpu, s, env);
+            break;
+        }
+        goto unknown_op;
     default:
         goto unknown_op;
     }
-- 
2.34.1


Reply via email to