qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B


From: Alexander Graf
Subject: [Qemu-ppc] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B
Date: Fri, 7 Mar 2014 00:33:28 +0100

From: Tom Musta <address@hidden>

The existing implementation of xxpermdi is defective if the target
VSR is also a source VSR.  This patch fixes the defect in this case
but also preserves the simpler, two TCG operation implementation
when the target is not once of the two sources.

Signed-off-by: Tom Musta <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
 target-ppc/translate.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 8885490..655aca6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7332,15 +7332,40 @@ static void gen_xxpermdi(DisasContext *ctx)
         return;
     }
 
-    if ((DM(ctx->opcode) & 2) == 0) {
-        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
-    } else {
-        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
-    }
-    if ((DM(ctx->opcode) & 1) == 0) {
-        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
+    if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
+                 (xT(ctx->opcode) == xB(ctx->opcode)))) {
+        TCGv_i64 xh, xl;
+
+        xh = tcg_temp_new_i64();
+        xl = tcg_temp_new_i64();
+
+        if ((DM(ctx->opcode) & 2) == 0) {
+            tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
+        }
+        if ((DM(ctx->opcode) & 1) == 0) {
+            tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
+        }
+
+        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
+        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
+
+        tcg_temp_free_i64(xh);
+        tcg_temp_free_i64(xl);
     } else {
-        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
+        if ((DM(ctx->opcode) & 2) == 0) {
+            tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), 
cpu_vsrh(xA(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), 
cpu_vsrl(xA(ctx->opcode)));
+        }
+        if ((DM(ctx->opcode) & 1) == 0) {
+            tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), 
cpu_vsrh(xB(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), 
cpu_vsrl(xB(ctx->opcode)));
+        }
     }
 }
 
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]