Upon encountering specialized instructions reserved for native calls, store the function id and argument types, then invoke helper.
Signed-off-by: Yeqi Fu <fufuyqqq...@gmail.com> --- target/arm/tcg/translate-a64.c | 27 ++++++++++++++++++++++++++- target/arm/tcg/translate.c | 25 +++++++++++++++++++++++-- target/arm/tcg/translate.h | 6 ++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 741a608739..24a664b928 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-defs.h" static TCGv_i64 cpu_X[32]; static TCGv_i64 cpu_pc; @@ -2331,11 +2332,35 @@ static void disas_exc(DisasContext *s, uint32_t insn) /* BRK */ gen_exception_bkpt_insn(s, syn_aa64_bkpt(imm16)); break; - case 2: + case 2: /* HLT */ if (op2_ll != 0) { unallocated_encoding(s); break; } + if (native_call_enabled() && (!s->native_call_status)) { + s->native_call_status = true; + s->native_call_id = imm16; + break; + } else if (native_call_enabled() && (s->native_call_status)) { + TCGv_i64 arg1 = tcg_temp_new_i64(); + TCGv_i64 arg2 = tcg_temp_new_i64(); + TCGv_i64 arg3 = tcg_temp_new_i64(); + + tcg_gen_mov_i64(arg1, cpu_reg(s, 0)); + tcg_gen_mov_i64(arg2, cpu_reg(s, 1)); + tcg_gen_mov_i64(arg3, cpu_reg(s, 2)); + + TCGv_i32 abi_map = tcg_constant_i32(imm16); + TCGv_i32 func_id = tcg_constant_i32(s->native_call_id); + TCGv_i64 res = tcg_temp_new_i64(); + TCGv_i32 mmu_idx = tcg_constant_i32(MMU_USER_IDX); + gen_helper_native_call(res, cpu_env, arg1, arg2, arg3, + abi_map, func_id, mmu_idx); + tcg_gen_mov_i64(cpu_reg(s, 0), res); + s->native_call_status = false; + s->native_call_id = 0; + break; + } /* HLT. This has two purposes. * Architecturally, it is an external halting debug instruction. * Since QEMU doesn't implement external debug, we treat this as diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index 7468476724..7b90ce50d0 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-defs.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,7 @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF; TCGv_i64 cpu_exclusive_addr; TCGv_i64 cpu_exclusive_val; + #include "exec/gen-icount.h" static const char * const regnames[] = @@ -1147,12 +1148,32 @@ static inline void gen_hlt(DisasContext *s, int imm) * semihosting, to provide some semblance of security * (and for consistency with our 32-bit semihosting). */ + if (native_call_enabled() && (!s->native_call_status)) { + s->native_call_status = true; + s->native_call_id = imm; + return; + } else if (native_call_enabled() && (s->native_call_status)) { + TCGv_i32 arg1 = load_reg(s, 0); + TCGv_i32 arg2 = load_reg(s, 1); + TCGv_i32 arg3 = load_reg(s, 2); + + TCGv_i32 abi_map = tcg_constant_i32(imm); + TCGv_i32 func_id = tcg_constant_i32(s->native_call_id); + TCGv_i32 res = tcg_temp_new_i32(); + TCGv_i32 mmu_idx = tcg_constant_i32(MMU_USER_IDX); + gen_helper_native_call_i32(res, cpu_env, arg1, arg2, arg3, + abi_map, func_id, mmu_idx); + + store_reg(s, 0, res); + s->native_call_status = false; + s->native_call_id = 0; + return; + } if (semihosting_enabled(s->current_el == 0) && (imm == (s->thumb ? 0x3c : 0xf000))) { gen_exception_internal_insn(s, EXCP_SEMIHOST); return; } - unallocated_encoding(s); } diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index a9d1f4adc2..280f8ba215 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -149,6 +149,12 @@ 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). + */ + bool native_call_status; + int native_call_id; } DisasContext; typedef struct DisasCompare { -- 2.34.1