aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg/plugin-gen.c
diff options
context:
space:
mode:
authorPierrick Bouvier <pierrick.bouvier@linaro.org>2024-03-05 12:09:52 +0000
committerAlex Bennée <alex.bennee@linaro.org>2024-03-06 12:35:26 +0000
commit62f92b8d978aba5de931323c3de788ccb2dbd87c (patch)
treebcd8ccf02d24bf604cf1a3638ac66fd8528bd600 /accel/tcg/plugin-gen.c
parent8042e2eadfd61dcdae321c3632f06d188521bdf5 (diff)
downloadqemu-62f92b8d978aba5de931323c3de788ccb2dbd87c.zip
qemu-62f92b8d978aba5de931323c3de788ccb2dbd87c.tar.gz
qemu-62f92b8d978aba5de931323c3de788ccb2dbd87c.tar.bz2
plugins: implement inline operation relative to cpu_index
Instead of working on a fixed memory location, allow to address it based on cpu_index, an element size and a given offset. Result address: ptr + offset + cpu_index * element_size. With this, we can target a member in a struct array from a base pointer. Current semantic is not modified, thus inline operation still targets always the same memory location. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-Id: <20240304130036.124418-4-pierrick.bouvier@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20240305121005.3528075-17-alex.bennee@linaro.org>
Diffstat (limited to 'accel/tcg/plugin-gen.c')
-rw-r--r--accel/tcg/plugin-gen.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index ac6b52b..0f8be53 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -133,16 +133,28 @@ static void gen_empty_udata_cb_no_rwg(void)
*/
static void gen_empty_inline_cb(void)
{
+ TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
+ TCGv_ptr cpu_index_as_ptr = tcg_temp_ebb_new_ptr();
TCGv_i64 val = tcg_temp_ebb_new_i64();
TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
+ tcg_gen_ld_i32(cpu_index, tcg_env,
+ -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
+ /* second operand will be replaced by immediate value */
+ tcg_gen_mul_i32(cpu_index, cpu_index, cpu_index);
+ tcg_gen_ext_i32_ptr(cpu_index_as_ptr, cpu_index);
+
tcg_gen_movi_ptr(ptr, 0);
+ tcg_gen_add_ptr(ptr, ptr, cpu_index_as_ptr);
tcg_gen_ld_i64(val, ptr, 0);
- /* pass an immediate != 0 so that it doesn't get optimized away */
- tcg_gen_addi_i64(val, val, 0xdeadface);
+ /* second operand will be replaced by immediate value */
+ tcg_gen_add_i64(val, val, val);
+
tcg_gen_st_i64(val, ptr, 0);
tcg_temp_free_ptr(ptr);
tcg_temp_free_i64(val);
+ tcg_temp_free_ptr(cpu_index_as_ptr);
+ tcg_temp_free_i32(cpu_index);
}
static void gen_empty_mem_cb(TCGv_i64 addr, uint32_t info)
@@ -290,12 +302,37 @@ static TCGOp *copy_const_ptr(TCGOp **begin_op, TCGOp *op, void *ptr)
return op;
}
+static TCGOp *copy_ld_i32(TCGOp **begin_op, TCGOp *op)
+{
+ return copy_op(begin_op, op, INDEX_op_ld_i32);
+}
+
+static TCGOp *copy_ext_i32_ptr(TCGOp **begin_op, TCGOp *op)
+{
+ if (UINTPTR_MAX == UINT32_MAX) {
+ op = copy_op(begin_op, op, INDEX_op_mov_i32);
+ } else {
+ op = copy_op(begin_op, op, INDEX_op_ext_i32_i64);
+ }
+ return op;
+}
+
+static TCGOp *copy_add_ptr(TCGOp **begin_op, TCGOp *op)
+{
+ if (UINTPTR_MAX == UINT32_MAX) {
+ op = copy_op(begin_op, op, INDEX_op_add_i32);
+ } else {
+ op = copy_op(begin_op, op, INDEX_op_add_i64);
+ }
+ return op;
+}
+
static TCGOp *copy_ld_i64(TCGOp **begin_op, TCGOp *op)
{
if (TCG_TARGET_REG_BITS == 32) {
/* 2x ld_i32 */
- op = copy_op(begin_op, op, INDEX_op_ld_i32);
- op = copy_op(begin_op, op, INDEX_op_ld_i32);
+ op = copy_ld_i32(begin_op, op);
+ op = copy_ld_i32(begin_op, op);
} else {
/* ld_i64 */
op = copy_op(begin_op, op, INDEX_op_ld_i64);
@@ -331,6 +368,13 @@ static TCGOp *copy_add_i64(TCGOp **begin_op, TCGOp *op, uint64_t v)
return op;
}
+static TCGOp *copy_mul_i32(TCGOp **begin_op, TCGOp *op, uint32_t v)
+{
+ op = copy_op(begin_op, op, INDEX_op_mul_i32);
+ op->args[2] = tcgv_i32_arg(tcg_constant_i32(v));
+ return op;
+}
+
static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
{
if (UINTPTR_MAX == UINT32_MAX) {
@@ -396,18 +440,17 @@ static TCGOp *append_inline_cb(const struct qemu_plugin_dyn_cb *cb,
TCGOp *begin_op, TCGOp *op,
int *unused)
{
- /* const_ptr */
- op = copy_const_ptr(&begin_op, op, cb->userp);
-
- /* ld_i64 */
+ char *ptr = cb->userp;
+ size_t elem_size = 0;
+ size_t offset = 0;
+ op = copy_ld_i32(&begin_op, op);
+ op = copy_mul_i32(&begin_op, op, elem_size);
+ op = copy_ext_i32_ptr(&begin_op, op);
+ op = copy_const_ptr(&begin_op, op, ptr + offset);
+ op = copy_add_ptr(&begin_op, op);
op = copy_ld_i64(&begin_op, op);
-
- /* add_i64 */
op = copy_add_i64(&begin_op, op, cb->inline_insn.imm);
-
- /* st_i64 */
op = copy_st_i64(&begin_op, op);
-
return op;
}