[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 16/17] target/arm: Introduce gen_pc_plus_diff for aarch32
From: |
Richard Henderson |
Subject: |
[PATCH v3 16/17] target/arm: Introduce gen_pc_plus_diff for aarch32 |
Date: |
Mon, 22 Aug 2022 16:23:37 -0700 |
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/translate.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4d13e365e2..f01c8df60a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -276,11 +276,16 @@ static int jmp_diff(DisasContext *s, int diff)
return diff + (s->thumb ? 4 : 8);
}
+static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, int diff)
+{
+ tcg_gen_movi_i32(var, s->pc_curr + diff);
+}
+
/* Set a variable to the value of a CPU register. */
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
{
if (reg == 15) {
- tcg_gen_movi_i32(var, read_pc(s));
+ gen_pc_plus_diff(s, var, jmp_diff(s, 0));
} else {
tcg_gen_mov_i32(var, cpu_R[reg]);
}
@@ -296,7 +301,8 @@ TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
TCGv_i32 tmp = tcg_temp_new_i32();
if (reg == 15) {
- tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
+ /* This difference computes a page offset so ok for TARGET_TB_PCREL. */
+ gen_pc_plus_diff(s, tmp, (read_pc(s) & ~3) - s->pc_curr + ofs);
} else {
tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
}
@@ -1158,7 +1164,7 @@ void unallocated_encoding(DisasContext *s)
/* Force a TB lookup after an instruction that changes the CPU state. */
void gen_lookup_tb(DisasContext *s)
{
- tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
+ gen_pc_plus_diff(s, cpu_R[15], curr_insn_len(s));
s->base.is_jmp = DISAS_EXIT;
}
@@ -6485,7 +6491,7 @@ static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
return false;
}
tmp = load_reg(s, a->rm);
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
gen_bx(s, tmp);
return true;
}
@@ -8356,7 +8362,7 @@ static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
static bool trans_BL(DisasContext *s, arg_i *a)
{
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
gen_jmp(s, jmp_diff(s, a->imm));
return true;
}
@@ -8375,7 +8381,7 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
if (s->thumb && (a->imm & 2)) {
return false;
}
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
store_cpu_field_constant(!s->thumb, thumb);
/* This difference computes a page offset so ok for TARGET_TB_PCREL. */
gen_jmp(s, (read_pc(s) & ~3) - s->pc_curr + a->imm);
@@ -8385,7 +8391,7 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
{
assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
- tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
+ gen_pc_plus_diff(s, cpu_R[14], jmp_diff(s, a->imm << 12));
return true;
}
@@ -8395,7 +8401,7 @@ static bool trans_BL_suffix(DisasContext *s,
arg_BL_suffix *a)
assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
gen_bx(s, tmp);
return true;
}
@@ -8411,7 +8417,7 @@ static bool trans_BLX_suffix(DisasContext *s,
arg_BLX_suffix *a)
tmp = tcg_temp_new_i32();
tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
gen_bx(s, tmp);
return true;
}
@@ -8734,10 +8740,11 @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a,
bool half)
tcg_gen_add_i32(addr, addr, tmp);
gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
- tcg_temp_free_i32(addr);
tcg_gen_add_i32(tmp, tmp, tmp);
- tcg_gen_addi_i32(tmp, tmp, read_pc(s));
+ gen_pc_plus_diff(s, addr, jmp_diff(s, 0));
+ tcg_gen_add_i32(tmp, tmp, addr);
+ tcg_temp_free_i32(addr);
store_reg(s, 15, tmp);
return true;
}
--
2.34.1
- [PATCH v3 13/17] target/arm: Change gen_exception_internal to work on displacements, (continued)
- [PATCH v3 13/17] target/arm: Change gen_exception_internal to work on displacements, Richard Henderson, 2022/08/22
- [PATCH v3 14/17] target/arm: Change gen_jmp* to work on displacements, Richard Henderson, 2022/08/22
- [PATCH v3 11/17] target/arm: Change gen_*set_pc_im to gen_*update_pc, Richard Henderson, 2022/08/22
- [PATCH v3 15/17] target/arm: Introduce gen_pc_plus_diff for aarch64, Richard Henderson, 2022/08/22
- [PATCH v3 07/17] accel/tcg: Introduce TARGET_TB_PCREL, Richard Henderson, 2022/08/22
- [PATCH v3 08/17] accel/tcg: Split log_cpu_exec into inline and slow path, Richard Henderson, 2022/08/22
- [PATCH v3 12/17] target/arm: Change gen_exception_insn* to work on displacements, Richard Henderson, 2022/08/22
- [PATCH v3 09/17] target/arm: Introduce curr_insn_len, Richard Henderson, 2022/08/22
- [PATCH v3 06/17] accel/tcg: Introduce tb_pc and tb_pc_log, Richard Henderson, 2022/08/22
- [PATCH v3 10/17] target/arm: Change gen_goto_tb to work on displacements, Richard Henderson, 2022/08/22
- [PATCH v3 16/17] target/arm: Introduce gen_pc_plus_diff for aarch32,
Richard Henderson <=
- [PATCH v3 17/17] target/arm: Enable TARGET_TB_PCREL, Richard Henderson, 2022/08/22