Uc hook tcg improve (#2011)

* Add handling UC_TCG_OP_FLAG_CMP for ARM

Implementation is not well-tested and complete

* Hook ARM32 CMP and CMN for cmplog
This commit is contained in:
dotcirill
2025-02-10 10:01:21 +03:00
committed by GitHub
parent ada8091ccc
commit dc1f7a88d5
2 changed files with 93 additions and 0 deletions

View File

@@ -31,6 +31,7 @@
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "uc_priv.h"
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
@@ -451,9 +452,29 @@ static void gen_sub_carry(TCGContext *tcg_ctx, TCGv_i32 dest, TCGv_i32 t0, TCGv_
tcg_gen_subi_i32(tcg_ctx, dest, dest, 1);
}
static inline void mb_tcg_opcode_cmp_hook(TCGContext *tcg_ctx, TCGv_i64 v0, TCGv_i64 v1, uint32_t size)
{
CPUARMState *cpuarm = (CPUARMState *)(tcg_ctx->cpu->env_ptr);
uint64_t pc = cpuarm->regs[15] + (cpuarm->thumb ? 1 : 0);
uc_engine *uc = tcg_ctx->uc;
if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_TCG_OPCODE, pc)) {
struct hook *hook;
HOOK_FOREACH_VAR_DECLARE;
HOOK_FOREACH(uc, hook, UC_HOOK_TCG_OPCODE) {
if (hook->to_delete)
continue;
if (hook->op == UC_TCG_OP_SUB && (hook->op_flags & UC_TCG_OP_FLAG_CMP)) {
gen_uc_traceopcode(tcg_ctx, hook, v0, v1, size, uc, pc);
}
}
}
}
/* dest = T0 + T1. Compute C, N, V and Z flags */
static void gen_add_CC(TCGContext *tcg_ctx, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
mb_tcg_opcode_cmp_hook(tcg_ctx, (TCGv_i64)t0, (TCGv_i64)t1, 32);
TCGv_i32 tmp = tcg_temp_new_i32(tcg_ctx);
tcg_gen_movi_i32(tcg_ctx, tmp, 0);
tcg_gen_add2_i32(tcg_ctx, tcg_ctx->cpu_NF, tcg_ctx->cpu_CF, t0, tmp, t1, tmp);
@@ -496,6 +517,8 @@ static void gen_adc_CC(TCGContext *tcg_ctx, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32
/* dest = T0 - T1. Compute C, N, V and Z flags */
static void gen_sub_CC(TCGContext *tcg_ctx, TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
mb_tcg_opcode_cmp_hook(tcg_ctx, (TCGv_i64)t0, (TCGv_i64)t1, 32);
TCGv_i32 tmp;
tcg_gen_sub_i32(tcg_ctx, tcg_ctx->cpu_NF, t0, t1);
tcg_gen_mov_i32(tcg_ctx, tcg_ctx->cpu_ZF, tcg_ctx->cpu_NF);