5544c1b
From 4bf321d3f494134fe2e03c9cbc042e28ec3a1045 Mon Sep 17 00:00:00 2001
5544c1b
From: Richard Henderson <rth@twiddle.net>
5544c1b
Date: Fri, 21 Sep 2012 10:13:35 -0700
5544c1b
Subject: [PATCH] target-alpha: Use movcond
5544c1b
5544c1b
For proper cmov insns, as well as the non-goto-tb case
5544c1b
of conditional branch.
5544c1b
5544c1b
Signed-off-by: Richard Henderson <rth@twiddle.net>
5544c1b
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
5544c1b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
5544c1b
---
5544c1b
 target-alpha/translate.c | 102 ++++++++++++++++++++++-------------------------
5544c1b
 1 file changed, 48 insertions(+), 54 deletions(-)
5544c1b
5544c1b
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
5544c1b
index 12de6a3..4a9011a 100644
5544c1b
--- a/target-alpha/translate.c
5544c1b
+++ b/target-alpha/translate.c
5544c1b
@@ -426,27 +426,15 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
5544c1b
 
5544c1b
         return EXIT_GOTO_TB;
5544c1b
     } else {
5544c1b
-        int lab_over = gen_new_label();
5544c1b
-
5544c1b
-        /* ??? Consider using either
5544c1b
-             movi pc, next
5544c1b
-             addi tmp, pc, disp
5544c1b
-             movcond pc, cond, 0, tmp, pc
5544c1b
-           or
5544c1b
-             setcond tmp, cond, 0
5544c1b
-             movi pc, next
5544c1b
-             neg tmp, tmp
5544c1b
-             andi tmp, tmp, disp
5544c1b
-             add pc, pc, tmp
5544c1b
-           The current diamond subgraph surely isn't efficient.  */
5544c1b
+        TCGv_i64 z = tcg_const_i64(0);
5544c1b
+        TCGv_i64 d = tcg_const_i64(dest);
5544c1b
+        TCGv_i64 p = tcg_const_i64(ctx->pc);
5544c1b
 
5544c1b
-        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
5544c1b
-        tcg_gen_movi_i64(cpu_pc, ctx->pc);
5544c1b
-        tcg_gen_br(lab_over);
5544c1b
-        gen_set_label(lab_true);
5544c1b
-        tcg_gen_movi_i64(cpu_pc, dest);
5544c1b
-        gen_set_label(lab_over);
5544c1b
+        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
5544c1b
 
5544c1b
+        tcg_temp_free_i64(z);
5544c1b
+        tcg_temp_free_i64(d);
5544c1b
+        tcg_temp_free_i64(p);
5544c1b
         return EXIT_PC_UPDATED;
5544c1b
     }
5544c1b
 }
5544c1b
@@ -521,61 +509,67 @@ static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
5544c1b
 static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
5544c1b
                      int islit, uint8_t lit, int mask)
5544c1b
 {
5544c1b
-    TCGCond inv_cond = tcg_invert_cond(cond);
5544c1b
-    int l1;
5544c1b
+    TCGv_i64 c1, z, v1;
5544c1b
 
5544c1b
-    if (unlikely(rc == 31))
5544c1b
+    if (unlikely(rc == 31)) {
5544c1b
         return;
5544c1b
+    }
5544c1b
 
5544c1b
-    l1 = gen_new_label();
5544c1b
-
5544c1b
-    if (ra != 31) {
5544c1b
-        if (mask) {
5544c1b
-            TCGv tmp = tcg_temp_new();
5544c1b
-            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
5544c1b
-            tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
5544c1b
-            tcg_temp_free(tmp);
5544c1b
-        } else
5544c1b
-            tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
5544c1b
-    } else {
5544c1b
+    if (ra == 31) {
5544c1b
         /* Very uncommon case - Do not bother to optimize.  */
5544c1b
-        TCGv tmp = tcg_const_i64(0);
5544c1b
-        tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
5544c1b
-        tcg_temp_free(tmp);
5544c1b
+        c1 = tcg_const_i64(0);
5544c1b
+    } else if (mask) {
5544c1b
+        c1 = tcg_const_i64(1);
5544c1b
+        tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
5544c1b
+    } else {
5544c1b
+        c1 = cpu_ir[ra];
5544c1b
     }
5544c1b
+    if (islit) {
5544c1b
+        v1 = tcg_const_i64(lit);
5544c1b
+    } else {
5544c1b
+        v1 = cpu_ir[rb];
5544c1b
+    }
5544c1b
+    z = tcg_const_i64(0);
5544c1b
 
5544c1b
-    if (islit)
5544c1b
-        tcg_gen_movi_i64(cpu_ir[rc], lit);
5544c1b
-    else
5544c1b
-        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
5544c1b
-    gen_set_label(l1);
5544c1b
+    tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
5544c1b
+
5544c1b
+    tcg_temp_free_i64(z);
5544c1b
+    if (ra == 31 || mask) {
5544c1b
+        tcg_temp_free_i64(c1);
5544c1b
+    }
5544c1b
+    if (islit) {
5544c1b
+        tcg_temp_free_i64(v1);
5544c1b
+    }
5544c1b
 }
5544c1b
 
5544c1b
 static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
5544c1b
 {
5544c1b
-    TCGv cmp_tmp;
5544c1b
-    int l1;
5544c1b
+    TCGv_i64 c1, z, v1;
5544c1b
 
5544c1b
     if (unlikely(rc == 31)) {
5544c1b
         return;
5544c1b
     }
5544c1b
 
5544c1b
-    cmp_tmp = tcg_temp_new();
5544c1b
+    c1 = tcg_temp_new_i64();
5544c1b
     if (unlikely(ra == 31)) {
5544c1b
-        tcg_gen_movi_i64(cmp_tmp, 0);
5544c1b
+        tcg_gen_movi_i64(c1, 0);
5544c1b
+    } else {
5544c1b
+        gen_fold_mzero(cond, c1, cpu_fir[ra]);
5544c1b
+    }
5544c1b
+    if (rb == 31) {
5544c1b
+        v1 = tcg_const_i64(0);
5544c1b
     } else {
5544c1b
-        gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
5544c1b
+        v1 = cpu_fir[rb];
5544c1b
     }
5544c1b
+    z = tcg_const_i64(0);
5544c1b
 
5544c1b
-    l1 = gen_new_label();
5544c1b
-    tcg_gen_brcondi_i64(tcg_invert_cond(cond), cmp_tmp, 0, l1);
5544c1b
-    tcg_temp_free(cmp_tmp);
5544c1b
+    tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
5544c1b
 
5544c1b
-    if (rb != 31)
5544c1b
-        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
5544c1b
-    else
5544c1b
-        tcg_gen_movi_i64(cpu_fir[rc], 0);
5544c1b
-    gen_set_label(l1);
5544c1b
+    tcg_temp_free_i64(z);
5544c1b
+    tcg_temp_free_i64(c1);
5544c1b
+    if (rb == 31) {
5544c1b
+        tcg_temp_free_i64(v1);
5544c1b
+    }
5544c1b
 }
5544c1b
 
5544c1b
 #define QUAL_RM_N       0x080   /* Round mode nearest even */
5544c1b
-- 
5544c1b
1.7.12.1
5544c1b