qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [6198] CRIS: Slight performance improvement for flag evalua


From: Edgar E. Iglesias
Subject: [Qemu-devel] [6198] CRIS: Slight performance improvement for flag evaluation.
Date: Wed, 07 Jan 2009 12:25:15 +0000

Revision: 6198
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6198
Author:   edgar_igl
Date:     2009-01-07 12:25:15 +0000 (Wed, 07 Jan 2009)

Log Message:
-----------
CRIS: Slight performance improvement for flag evaluation.

Translate sub and cmp ops separately when evaluating flags to avoid checking
for them at runtime.

Signed-off-by: Edgar E. Iglesias <address@hidden>

Modified Paths:
--------------
    trunk/target-cris/helper.h
    trunk/target-cris/op_helper.c
    trunk/target-cris/translate.c

Modified: trunk/target-cris/helper.h
===================================================================
--- trunk/target-cris/helper.h  2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/helper.h  2009-01-07 12:25:15 UTC (rev 6198)
@@ -14,6 +14,7 @@
 DEF_HELPER_0(evaluate_flags_mulu, void)
 DEF_HELPER_0(evaluate_flags_mcp, void)
 DEF_HELPER_0(evaluate_flags_alu_4, void)
+DEF_HELPER_0(evaluate_flags_sub_4, void)
 DEF_HELPER_0(evaluate_flags_move_4, void)
 DEF_HELPER_0(evaluate_flags_move_2, void)
 DEF_HELPER_0(evaluate_flags, void)

Modified: trunk/target-cris/op_helper.c
===================================================================
--- trunk/target-cris/op_helper.c       2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/op_helper.c       2009-01-07 12:25:15 UTC (rev 6198)
@@ -245,17 +245,19 @@
 
 static void evaluate_flags_writeback(uint32_t flags)
 {
-       int x;
+       unsigned int x, z, mask;
 
        /* Extended arithmetics, leave the z flag alone.  */
        x = env->cc_x;
-       if ((x || env->cc_op == CC_OP_ADDC)
-           && flags & Z_FLAG)
-               env->cc_mask &= ~Z_FLAG;
+       mask = env->cc_mask | X_FLAG;
+        if (x) {
+               z = flags & Z_FLAG;
+               mask = mask & ~z;
+       }
+       flags &= mask;
 
        /* all insn clear the x-flag except setf or clrf.  */
-       env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
-       flags &= env->cc_mask;
+       env->pregs[PR_CCS] &= ~mask;
        env->pregs[PR_CCS] |= flags;
 }
 
@@ -323,33 +325,25 @@
        uint32_t res;
        uint32_t flags = 0;
 
-       src = env->cc_src;
-       dst = env->cc_dest;
+       src = env->cc_src & 0x80000000;
+       dst = env->cc_dest & 0x80000000;
        res = env->cc_result;
 
        if ((res & 0x80000000L) != 0L)
        {
                flags |= N_FLAG;
-               if (((src & 0x80000000L) == 0L)
-                   && ((dst & 0x80000000L) == 0L))
-               {
+               if (!src && !dst)
                        flags |= V_FLAG;
-               }
-               else if (((src & 0x80000000L) != 0L) &&
-                        ((dst & 0x80000000L) != 0L))
-               {
+               else if (src & dst)
                        flags |= R_FLAG;
-               }
        }
        else
        {
                if (res == 0L)
                        flags |= Z_FLAG;
-               if (((src & 0x80000000L) != 0L)
-                   && ((dst & 0x80000000L) != 0L))
+               if (src & dst) 
                        flags |= V_FLAG;
-               if ((dst & 0x80000000L) != 0L
-                   || (src & 0x80000000L) != 0L)
+               if (dst | src) 
                        flags |= R_FLAG;
        }
 
@@ -363,56 +357,61 @@
        uint32_t res;
        uint32_t flags = 0;
 
-       src = env->cc_src;
-       dst = env->cc_dest;
+       src = env->cc_src & 0x80000000;
+       dst = env->cc_dest & 0x80000000;
+       res = env->cc_result;
 
-       /* Reconstruct the result.  */
-       switch (env->cc_op)
+       if ((res & 0x80000000L) != 0L)
        {
-               case CC_OP_SUB:
-                       res = dst - src;
-                       break;
-               case CC_OP_ADD:
-                       res = dst + src;
-                       break;
-               default:
-                       res = env->cc_result;
-                       break;
+               flags |= N_FLAG;
+               if (!src && !dst)
+                       flags |= V_FLAG;
+               else if (src & dst)
+                       flags |= C_FLAG;
        }
+       else
+       {
+               if (res == 0L)
+                       flags |= Z_FLAG;
+               if (src & dst) 
+                       flags |= V_FLAG;
+               if (dst | src) 
+                       flags |= C_FLAG;
+       }
 
-       if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
-               src = ~src;
+       evaluate_flags_writeback(flags);
+}
 
+void  helper_evaluate_flags_sub_4(void)
+{
+       uint32_t src;
+       uint32_t dst;
+       uint32_t res;
+       uint32_t flags = 0;
+
+       src = (~env->cc_src) & 0x80000000;
+       dst = env->cc_dest & 0x80000000;
+       res = env->cc_result;
+
        if ((res & 0x80000000L) != 0L)
        {
                flags |= N_FLAG;
-               if (((src & 0x80000000L) == 0L)
-                   && ((dst & 0x80000000L) == 0L))
-               {
+               if (!src && !dst)
                        flags |= V_FLAG;
-               }
-               else if (((src & 0x80000000L) != 0L) &&
-                        ((dst & 0x80000000L) != 0L))
-               {
+               else if (src & dst)
                        flags |= C_FLAG;
-               }
        }
        else
        {
                if (res == 0L)
                        flags |= Z_FLAG;
-               if (((src & 0x80000000L) != 0L)
-                   && ((dst & 0x80000000L) != 0L))
+               if (src & dst) 
                        flags |= V_FLAG;
-               if ((dst & 0x80000000L) != 0L
-                   || (src & 0x80000000L) != 0L)
+               if (dst | src) 
                        flags |= C_FLAG;
        }
 
-       if (env->cc_op == CC_OP_SUB
-           || env->cc_op == CC_OP_CMP) {
-               flags ^= C_FLAG;
-       }
+       flags ^= C_FLAG;
        evaluate_flags_writeback(flags);
 }
 
@@ -607,6 +606,13 @@
                case CC_OP_FLAGS:
                        /* live.  */
                        break;
+               case CC_OP_SUB:
+               case CC_OP_CMP:
+                       if (env->cc_size == 4)
+                               helper_evaluate_flags_sub_4();
+                       else
+                               helper_evaluate_flags();
+                       break;
                default:
                {
                        switch (env->cc_size)

Modified: trunk/target-cris/translate.c
===================================================================
--- trunk/target-cris/translate.c       2009-01-07 12:19:50 UTC (rev 6197)
+++ trunk/target-cris/translate.c       2009-01-07 12:25:15 UTC (rev 6198)
@@ -728,8 +728,15 @@
                        case CC_OP_FLAGS:
                                /* live.  */
                                break;
+                       case CC_OP_SUB:
+                       case CC_OP_CMP:
+                               if (dc->cc_size == 4)
+                                       gen_helper_evaluate_flags_sub_4();
+                               else
+                                       gen_helper_evaluate_flags();
+
+                               break;
                        default:
-                       {
                                switch (dc->cc_size)
                                {
                                        case 4:
@@ -739,7 +746,6 @@
                                                gen_helper_evaluate_flags();
                                                break;
                                }
-                       }
                        break;
                }
                if (dc->flagx_known) {
@@ -821,13 +827,8 @@
 /* Update cc after executing ALU op. needs the result.  */
 static inline void cris_update_result(DisasContext *dc, TCGv res)
 {
-       if (dc->update_cc) {
-               if (dc->cc_size == 4 && 
-                   (dc->cc_op == CC_OP_SUB
-                    || dc->cc_op == CC_OP_ADD))
-                       return;
+       if (dc->update_cc)
                tcg_gen_mov_tl(cc_result, res);
-       }
 }
 
 /* Returns one if the write back stage should execute.  */
@@ -1890,6 +1891,10 @@
        DIS(fprintf (logfile, "addc $r%u, $r%u\n",
                    dc->op1, dc->op2));
        cris_evaluate_flags(dc);
+       /* Set for this insn.  */
+       dc->flagx_known = 1;
+       dc->flags_x = X_FLAG;
+
        cris_cc_mask(dc, CC_MASK_NZVC);
        cris_alu(dc, CC_OP_ADDC,
                 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
@@ -2615,6 +2620,11 @@
                    dc->op2));
 
        cris_evaluate_flags(dc);
+
+       /* Set for this insn.  */
+       dc->flagx_known = 1;
+       dc->flags_x = X_FLAG;
+
        cris_alu_m_alloc_temps(t);
        insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
        cris_cc_mask(dc, CC_MASK_NZVC);






reply via email to

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