diff mbox series

[v5,8/9] target/arm: Introduce gen_pc_plus_diff for aarch32

Message ID 20220930220312.135327-9-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm: pc-relative translation blocks | expand

Commit Message

Richard Henderson Sept. 30, 2022, 10:03 p.m. UTC
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

Comments

Peter Maydell Oct. 11, 2022, 2:51 p.m. UTC | #1
On Fri, 30 Sept 2022 at 23:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 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 fd35db8c8c..050da9e740 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -276,11 +276,16 @@ static target_long jmp_diff(DisasContext *s, target_long diff)
>      return diff + (s->thumb ? 4 : 8);
>  }
>
> +static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long 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);

We could rephrase this one also to not do the "pc_curr - pc_curr" thing,
the way we did for BLX in patch 6, right ?

thanks
-- PMM
Richard Henderson Oct. 11, 2022, 3:52 p.m. UTC | #2
On 10/11/22 07:51, Peter Maydell wrote:
> On Fri, 30 Sept 2022 at 23:05, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
>>
>> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> 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 fd35db8c8c..050da9e740 100644
>> --- a/target/arm/translate.c
>> +++ b/target/arm/translate.c
>> @@ -276,11 +276,16 @@ static target_long jmp_diff(DisasContext *s, target_long diff)
>>       return diff + (s->thumb ? 4 : 8);
>>   }
>>
>> +static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long 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);
> 
> We could rephrase this one also to not do the "pc_curr - pc_curr" thing,
> the way we did for BLX in patch 6, right ?

Ah yes.  I missed that in revision.


r~
diff mbox series

Patch

diff --git a/target/arm/translate.c b/target/arm/translate.c
index fd35db8c8c..050da9e740 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -276,11 +276,16 @@  static target_long jmp_diff(DisasContext *s, target_long diff)
     return diff + (s->thumb ? 4 : 8);
 }
 
+static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long 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);
     }
@@ -1159,7 +1165,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;
 }
 
@@ -6483,7 +6489,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;
 }
@@ -8351,7 +8357,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;
 }
@@ -8370,7 +8376,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);
@@ -8380,7 +8386,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;
 }
 
@@ -8390,7 +8396,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;
 }
@@ -8406,7 +8412,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;
 }
@@ -8729,10 +8735,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;
 }