[RFC PATCH v1 05/43] tcg: Add helper function dispatcher and hook tcg_gen_callN

Anton Johansson via posted 43 patches 2 days, 13 hours ago
[RFC PATCH v1 05/43] tcg: Add helper function dispatcher and hook tcg_gen_callN
Posted by Anton Johansson via 2 days, 13 hours ago
Adds a function pointer to the TCGContext which may be set by targets via
the TARGET_HELPER_DISPATCHER macro.  The dispatcher is function

  (void *func, TCGTemp *ret, int nargs, TCGTemp **args) -> bool

which allows targets to hook the generation of helper calls in TCG and
take over translation.  Specifically, this will be used by helper-to-tcg
to replace helper function translation, without having to modify frontends.

Signed-off-by: Anton Johansson <anjo@rev.ng>
---
 accel/tcg/translate-all.c | 4 ++++
 include/tcg/tcg.h         | 4 ++++
 tcg/tcg.c                 | 5 +++++
 3 files changed, 13 insertions(+)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index fdf6d8ac19..814aae93ae 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -352,6 +352,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
     tcg_ctx->guest_mo = TCG_MO_ALL;
 #endif
 
+#if defined(CONFIG_HELPER_TO_TCG) && defined(TARGET_HELPER_DISPATCHER)
+    tcg_ctx->helper_dispatcher = TARGET_HELPER_DISPATCHER;
+#endif
+
  restart_translate:
     trace_translate_block(tb, pc, tb->tc.ptr);
 
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index a77ed12b9d..d3e820568f 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -549,6 +549,10 @@ struct TCGContext {
 
     /* Exit to translator on overflow. */
     sigjmp_buf jmp_trans;
+
+
+    bool (*helper_dispatcher)(void *func, TCGTemp *ret_temp,
+                              int nargs, TCGTemp **args);
 };
 
 static inline bool temp_readonly(TCGTemp *ts)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0babae1b88..5f03bef688 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2252,6 +2252,11 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
     }
 
     total_args = info->nr_out + info->nr_in + 2;
+    if (unlikely(tcg_ctx->helper_dispatcher) &&
+        tcg_ctx->helper_dispatcher(info->func, ret, total_args, args)) {
+        return;
+    }
+
     op = tcg_op_alloc(INDEX_op_call, total_args);
 
 #ifdef CONFIG_PLUGIN
-- 
2.45.2
Re: [RFC PATCH v1 05/43] tcg: Add helper function dispatcher and hook tcg_gen_callN
Posted by Richard Henderson 21 hours ago
On 11/20/24 19:49, Anton Johansson wrote:
> Adds a function pointer to the TCGContext which may be set by targets via
> the TARGET_HELPER_DISPATCHER macro.  The dispatcher is function
> 
>    (void *func, TCGTemp *ret, int nargs, TCGTemp **args) -> bool
> 
> which allows targets to hook the generation of helper calls in TCG and
> take over translation.  Specifically, this will be used by helper-to-tcg
> to replace helper function translation, without having to modify frontends.
> 
> Signed-off-by: Anton Johansson <anjo@rev.ng>
> ---
>   accel/tcg/translate-all.c | 4 ++++
>   include/tcg/tcg.h         | 4 ++++
>   tcg/tcg.c                 | 5 +++++
>   3 files changed, 13 insertions(+)

I guess I'll have to read further to understand this, but my first reaction is: why would 
we not modify how the gen_helper_* functions are defined instead?


r~

> 
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index fdf6d8ac19..814aae93ae 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -352,6 +352,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
>       tcg_ctx->guest_mo = TCG_MO_ALL;
>   #endif
>   
> +#if defined(CONFIG_HELPER_TO_TCG) && defined(TARGET_HELPER_DISPATCHER)
> +    tcg_ctx->helper_dispatcher = TARGET_HELPER_DISPATCHER;
> +#endif
> +
>    restart_translate:
>       trace_translate_block(tb, pc, tb->tc.ptr);
>   
> diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
> index a77ed12b9d..d3e820568f 100644
> --- a/include/tcg/tcg.h
> +++ b/include/tcg/tcg.h
> @@ -549,6 +549,10 @@ struct TCGContext {
>   
>       /* Exit to translator on overflow. */
>       sigjmp_buf jmp_trans;
> +
> +
> +    bool (*helper_dispatcher)(void *func, TCGTemp *ret_temp,
> +                              int nargs, TCGTemp **args);
>   };
>   
>   static inline bool temp_readonly(TCGTemp *ts)
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 0babae1b88..5f03bef688 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -2252,6 +2252,11 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
>       }
>   
>       total_args = info->nr_out + info->nr_in + 2;
> +    if (unlikely(tcg_ctx->helper_dispatcher) &&
> +        tcg_ctx->helper_dispatcher(info->func, ret, total_args, args)) {
> +        return;
> +    }
> +
>       op = tcg_op_alloc(INDEX_op_call, total_args);
>   
>   #ifdef CONFIG_PLUGIN