|
@@ -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;
|
|
|
}
|
|
|
|