Patchwork [20/62] tcg-s390: Implement setcond.

login
register
mail settings
Submitter Richard Henderson
Date May 27, 2010, 8:46 p.m.
Message ID <1274993204-30766-21-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/53807/
State New
Headers show

Comments

Richard Henderson - May 27, 2010, 8:46 p.m.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/s390/tcg-target.c |   66 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 47 insertions(+), 19 deletions(-)

Patch

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index f21a9ca..b150d1a 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -381,6 +381,42 @@  static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
     }
 }
 
+static void tgen32_cmp(TCGContext *s, TCGCond c, TCGReg r1, TCGReg r2)
+{
+    if (c > TCG_COND_GT) {
+        /* unsigned */
+        tcg_out_insn(s, RR, CLR, r1, r2);
+    } else {
+        /* signed */
+        tcg_out_insn(s, RR, CR, r1, r2);
+    }
+}
+
+static void tgen64_cmp(TCGContext *s, TCGCond c, TCGReg r1, TCGReg r2)
+{
+    if (c > TCG_COND_GT) {
+        /* unsigned */
+        tcg_out_insn(s, RRE, CLGR, r1, r2);
+    } else {
+        /* signed */
+        tcg_out_insn(s, RRE, CGR, r1, r2);
+    }
+}
+
+static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
+                         TCGReg dest, TCGReg r1, TCGReg r2)
+{
+    if (type == TCG_TYPE_I32) {
+        tgen32_cmp(s, c, r1, r2);
+    } else {
+        tgen64_cmp(s, c, r1, r2);
+    }
+    /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over:  */
+    tcg_out_movi(s, type, dest, 1);
+    tcg_out_insn(s, RI, BRC, tcg_cond_to_s390_cond[c], (4 + 4) >> 1);
+    tcg_out_movi(s, type, dest, 0);
+}
+
 #if defined(CONFIG_SOFTMMU)
 static void tcg_prepare_qemu_ldst(TCGContext* s, int data_reg, int addr_reg,
                                   int mem_index, int opc,
@@ -958,27 +994,10 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_brcond_i64:
-        if (args[2] > TCG_COND_GT) {
-            /* unsigned */
-            /* clgr %ra0, %ra1 */
-            tcg_out_insn(s, RRE, CLGR, args[0], args[1]);
-        } else {
-            /* signed */
-            /* cgr %ra0, %ra1 */
-            tcg_out_insn(s, RRE, CGR, args[0], args[1]);
-        }
+        tgen64_cmp(s, args[2], args[0], args[1]);
         goto do_brcond;
-
     case INDEX_op_brcond_i32:
-        if (args[2] > TCG_COND_GT) {
-            /* unsigned */
-            /* clr %ra0, %ra1 */
-            tcg_out_insn(s, RR, CLR, args[0], args[1]);
-        } else {
-            /* signed */
-            /* cr %ra0, %ra1 */
-            tcg_out_insn(s, RR, CR, args[0], args[1]);
-        }
+        tgen32_cmp(s, args[2], args[0], args[1]);
     do_brcond:
         l = &s->labels[args[3]];
         if (l->has_value) {
@@ -993,6 +1012,13 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_insn(s, RR, BCR, tcg_cond_to_s390_cond[args[2]], TCG_REG_R13);
         break;
 
+    case INDEX_op_setcond_i32:
+        tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2]);
+        break;
+    case INDEX_op_setcond_i64:
+        tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2]);
+        break;
+
     case INDEX_op_qemu_ld8u:
         tcg_out_qemu_ld(s, args, LD_UINT8);
         break;
@@ -1083,6 +1109,7 @@  static const TCGTargetOpDef s390_op_defs[] = {
     { INDEX_op_sar_i32, { "r", "0", "Ri" } },
 
     { INDEX_op_brcond_i32, { "r", "r" } },
+    { INDEX_op_setcond_i32, { "r", "r", "r" } },
 
     { INDEX_op_qemu_ld8u, { "r", "L" } },
     { INDEX_op_qemu_ld8s, { "r", "L" } },
@@ -1129,6 +1156,7 @@  static const TCGTargetOpDef s390_op_defs[] = {
     { INDEX_op_sar_i64, { "r", "r", "Ri" } },
 
     { INDEX_op_brcond_i64, { "r", "r" } },
+    { INDEX_op_setcond_i64, { "r", "r", "r" } },
 #endif
 
     { -1 },