Patchwork [1/2] target-xtensa: fix extui shift amount

login
register
mail settings
Submitter Max Filippov
Date Sept. 20, 2012, 10:59 p.m.
Message ID <1348181990-23415-2-git-send-email-jcmvbkbc@gmail.com>
Download mbox | patch
Permalink /patch/185520/
State New
Headers show

Comments

Max Filippov - Sept. 20, 2012, 10:59 p.m.
extui opcode only uses lowermost op1 bit for sa4.

Reported-by: malc <av1474@comtv.ru>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
---
 target-xtensa/translate.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)
Richard Henderson - Sept. 21, 2012, 12:02 a.m.
On 09/20/2012 03:59 PM, Max Filippov wrote:
> +                if (shiftimm) {
> +                    tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
> +                } else {
> +                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
> +                }

tcg_gen_shri_i32 will perform this conditional already.

> +                switch (maskimm) {
> +                case 0xff:
> +                    tcg_gen_ext8u_i32(cpu_R[RRR_R], tmp);
> +                    break;
> +
> +                case 0xffff:
> +                    tcg_gen_ext16u_i32(cpu_R[RRR_R], tmp);
> +                    break;

And while this optimization happens eventually, we should
change tcg-op.h to make sure it happens in tcg_gen_andi.


r~

Patch

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 1900bd5..7a1c528 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1778,12 +1778,30 @@  static void disas_xtensa_insn(DisasContext *dc)
         case 5:
             gen_window_check2(dc, RRR_R, RRR_T);
             {
-                int shiftimm = RRR_S | (OP1 << 4);
+                int shiftimm = RRR_S | ((OP1 & 1) << 4);
                 int maskimm = (1 << (OP2 + 1)) - 1;
 
                 TCGv_i32 tmp = tcg_temp_new_i32();
-                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
-                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
+
+                if (shiftimm) {
+                    tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
+                } else {
+                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
+                }
+
+                switch (maskimm) {
+                case 0xff:
+                    tcg_gen_ext8u_i32(cpu_R[RRR_R], tmp);
+                    break;
+
+                case 0xffff:
+                    tcg_gen_ext16u_i32(cpu_R[RRR_R], tmp);
+                    break;
+
+                default:
+                    tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
+                    break;
+                }
                 tcg_temp_free(tmp);
             }
             break;