diff mbox series

[05/21] target/xtensa: support copying registers up to 64 bits wide

Message ID 20200706234737.32378-6-jcmvbkbc@gmail.com
State New
Headers show
Series target/xtensa: implement double precision FPU | expand

Commit Message

Max Filippov July 6, 2020, 11:47 p.m. UTC
FLIX dependency breaking code assumes that all registers are 32 bit
wide. This may not always be correct.
Extract actual register width from the associated register file and use
it to create temporaries of correct width and generate correct data
movement instructions.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target/xtensa/cpu.h       |  1 +
 target/xtensa/translate.c | 26 +++++++++++++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

Comments

Richard Henderson July 8, 2020, 4:14 p.m. UTC | #1
On 7/6/20 4:47 PM, Max Filippov wrote:
> +                if (arg_copy[i].arg->num_bits <= 32) {
> +                    temp = tcg_temp_local_new_i32();
> +                    tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
> +                } else if (arg_copy[i].arg->num_bits <= 64) {
> +                    temp = tcg_temp_local_new_i64();
> +                    tcg_gen_mov_i64(temp, arg_copy[i].arg->in);

This shouldn't compile.

You can't assign both TCGv_i32 and TCGv_i64 to the same variable.

What's going on here?


r~
Max Filippov July 8, 2020, 5:14 p.m. UTC | #2
On Wed, Jul 8, 2020 at 9:14 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/6/20 4:47 PM, Max Filippov wrote:
> > +                if (arg_copy[i].arg->num_bits <= 32) {
> > +                    temp = tcg_temp_local_new_i32();
> > +                    tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
> > +                } else if (arg_copy[i].arg->num_bits <= 64) {
> > +                    temp = tcg_temp_local_new_i64();
> > +                    tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
>
> This shouldn't compile.
>
> You can't assign both TCGv_i32 and TCGv_i64 to the same variable.
>
> What's going on here?

temp is a void pointer, as well as OpcodeArg::in and OpcodeArg::out.
diff mbox series

Patch

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 0409aa6189cf..960f6573447f 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -359,6 +359,7 @@  typedef struct opcode_arg {
     uint32_t raw_imm;
     void *in;
     void *out;
+    uint32_t num_bits;
 } OpcodeArg;
 
 typedef struct DisasContext DisasContext;
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 9838bf6b3ec5..bc01a720719d 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -943,10 +943,10 @@  static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 
         for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
             void **register_file = NULL;
+            xtensa_regfile rf;
 
             if (xtensa_operand_is_register(isa, opc, opnd)) {
-                xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
-
+                rf = xtensa_operand_regfile(isa, opc, opnd);
                 register_file = dc->config->regfile[rf];
 
                 if (rf == dc->config->a_regfile) {
@@ -972,6 +972,9 @@  static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 if (register_file) {
                     arg[vopnd].in = register_file[v];
                     arg[vopnd].out = register_file[v];
+                    arg[vopnd].num_bits = xtensa_regfile_num_bits(isa, rf);
+                } else {
+                    arg[vopnd].num_bits = 32;
                 }
                 ++vopnd;
             }
@@ -1111,8 +1114,15 @@  static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
         for (i = j = 0; i < n_arg_copy; ++i) {
             if (i == 0 || arg_copy[i].resource != resource) {
                 resource = arg_copy[i].resource;
-                temp = tcg_temp_local_new();
-                tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
+                if (arg_copy[i].arg->num_bits <= 32) {
+                    temp = tcg_temp_local_new_i32();
+                    tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
+                } else if (arg_copy[i].arg->num_bits <= 64) {
+                    temp = tcg_temp_local_new_i64();
+                    tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
+                } else {
+                    g_assert_not_reached();
+                }
                 arg_copy[i].temp = temp;
 
                 if (i != j) {
@@ -1143,7 +1153,13 @@  static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
     }
 
     for (i = 0; i < n_arg_copy; ++i) {
-        tcg_temp_free(arg_copy[i].temp);
+        if (arg_copy[i].arg->num_bits <= 32) {
+            tcg_temp_free_i32(arg_copy[i].temp);
+        } else if (arg_copy[i].arg->num_bits <= 64) {
+            tcg_temp_free_i64(arg_copy[i].temp);
+        } else {
+            g_assert_not_reached();
+        }
     }
 
     if (dc->base.is_jmp == DISAS_NEXT) {