qemu-commits
[Top][All Lists]
Advanced

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

[Qemu-commits] [COMMIT c45851c] When targeting PPU use rlwinm instead of


From: Anthony Liguori
Subject: [Qemu-commits] [COMMIT c45851c] When targeting PPU use rlwinm instead of andi. ifpossible
Date: Sun, 06 Sep 2009 03:27:51 -0000

From: malc <address@hidden>

andi. is microcoded and slow there.

Signed-off-by: malc <address@hidden>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 2409288..0739515 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -1253,14 +1253,60 @@ static void tcg_out_op(TCGContext *s, int opc, const 
TCGArg *args,
 
     case INDEX_op_and_i32:
         if (const_args[2]) {
-            if ((args[2] & 0xffff) == args[2])
-                tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
-            else if ((args[2] & 0xffff0000) == args[2])
-                tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
-                           | ((args[2] >> 16) & 0xffff));
-            else {
-                tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
-                tcg_out32 (s, AND | SAB (args[1], args[0], 0));
+            uint32_t c;
+
+            c = args[2];
+
+            if (!c) {
+                tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
+                break;
+            }
+#ifdef __PPU__
+            uint32_t t, n;
+            int mb, me;
+
+            n = c ^ -(c & 1);
+            t = n + (n & -n);
+
+            if ((t & (t - 1)) == 0) {
+                int lzc, tzc;
+
+                if ((c & 0x80000001) == 0x80000001) {
+                    lzc = clz32 (n);
+                    tzc = ctz32 (n);
+
+                    mb = 32 - tzc;
+                    me = lzc - 1;
+                }
+                else {
+                    lzc = clz32 (c);
+                    tzc = ctz32 (c);
+
+                    mb = lzc;
+                    me = 31 - tzc;
+                }
+
+                tcg_out32 (s, (RLWINM
+                               | RA (args[0])
+                               | RS (args[1])
+                               | SH (0)
+                               | MB (mb)
+                               | ME (me)
+                               )
+                    );
+            }
+            else
+#endif /* !__PPU__ */
+            {
+                if ((c & 0xffff) == c)
+                    tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
+                else if ((c & 0xffff0000) == c)
+                    tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
+                               | ((c >> 16) & 0xffff));
+                else {
+                    tcg_out_movi (s, TCG_TYPE_I32, 0, c);
+                    tcg_out32 (s, AND | SAB (args[1], args[0], 0));
+                }
             }
         }
         else




reply via email to

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