OSDN Git Service

tcg/ppc: Implement some of the optional ops
authormalc <av1474@comtv.ru>
Mon, 22 Feb 2010 18:50:01 +0000 (21:50 +0300)
committermalc <av1474@comtv.ru>
Mon, 22 Feb 2010 18:50:01 +0000 (21:50 +0300)
Signed-off-by: malc <av1474@comtv.ru>
tcg/ppc/tcg-target.c
tcg/ppc/tcg-target.h

index 15d8b85..31101c8 100644 (file)
@@ -333,6 +333,7 @@ static int tcg_target_const_match(tcg_target_long val,
 #define STWU   OPCD(37)
 
 #define RLWINM OPCD(21)
+#define RLWNM  OPCD(23)
 
 #define BCLR   XO19( 16)
 #define BCCTR  XO19(528)
@@ -369,6 +370,9 @@ static int tcg_target_const_match(tcg_target_long val,
 #define NEG    XO31(104)
 #define MFCR   XO31( 19)
 #define CNTLZW XO31( 26)
+#define NOR    XO31(124)
+#define ANDC   XO31( 60)
+#define ORC    XO31(412)
 
 #define LBZX   XO31( 87)
 #define LHZX   XO31(279)
@@ -1468,6 +1472,12 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
         else
             tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
         break;
+    case INDEX_op_andc_i32:
+        tcg_out32 (s, ANDC | SAB (args[1], args[0], args[2]));
+        break;
+    case INDEX_op_orc_i32:
+        tcg_out32 (s, ORC | SAB (args[1], args[0], args[2]));
+        break;
 
     case INDEX_op_mul_i32:
         if (const_args[2]) {
@@ -1549,6 +1559,45 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
         else
             tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
         break;
+    case INDEX_op_rotl_i32:
+        {
+            int op = 0
+                | RA (args[0])
+                | RS (args[1])
+                | MB (0)
+                | ME (31)
+                | (const_args[2] ? RLWINM | SH (args[2])
+                                 : RLWNM | RB (args[2]))
+                ;
+            tcg_out32 (s, op);
+        }
+        break;
+    case INDEX_op_rotr_i32:
+        if (const_args[2]) {
+            if (!args[2]) {
+                tcg_out_mov (s, args[0], args[2]);
+            }
+            else {
+                tcg_out32 (s, RLWINM
+                           | RA (args[0])
+                           | RS (args[1])
+                           | SH (32 - args[2])
+                           | MB (0)
+                           | ME (31)
+                    );
+            }
+        }
+        else {
+            tcg_out32 (s, ADDI | RT (0) | RA (args[2]) | 0xffe0);
+            tcg_out32 (s, RLWNM
+                       | RA (args[0])
+                       | RS (args[1])
+                       | RB (0)
+                       | MB (0)
+                       | ME (31)
+                );
+        }
+        break;
 
     case INDEX_op_add2_i32:
         if (args[0] == args[3] || args[0] == args[5]) {
@@ -1591,6 +1640,10 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
         tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
         break;
 
+    case INDEX_op_not_i32:
+        tcg_out32 (s, NOR | SAB (args[1], args[0], args[0]));
+        break;
+
     case INDEX_op_qemu_ld8u:
         tcg_out_qemu_ld(s, args, 0);
         break;
@@ -1625,9 +1678,27 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
     case INDEX_op_ext8s_i32:
         tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
         break;
+    case INDEX_op_ext8u_i32:
+        tcg_out32 (s, RLWINM
+                   | RA (args[0])
+                   | RS (args[1])
+                   | SH (0)
+                   | MB (24)
+                   | ME (31)
+            );
+        break;
     case INDEX_op_ext16s_i32:
         tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
         break;
+    case INDEX_op_ext16u_i32:
+        tcg_out32 (s, RLWINM
+                   | RA (args[0])
+                   | RS (args[1])
+                   | SH (0)
+                   | MB (16)
+                   | ME (31)
+            );
+        break;
 
     case INDEX_op_setcond_i32:
         tcg_out_setcond (s, args[3], args[0], args[1], args[2], const_args[2]);
@@ -1676,6 +1747,9 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_shr_i32, { "r", "r", "ri" } },
     { INDEX_op_sar_i32, { "r", "r", "ri" } },
 
+    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
+    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
+
     { INDEX_op_brcond_i32, { "r", "ri" } },
 
     { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
@@ -1683,6 +1757,10 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
 
     { INDEX_op_neg_i32, { "r", "r" } },
+    { INDEX_op_not_i32, { "r", "r" } },
+
+    { INDEX_op_andc_i32, { "r", "r", "r" } },
+    { INDEX_op_orc_i32, { "r", "r", "r" } },
 
     { INDEX_op_setcond_i32, { "r", "r", "ri" } },
     { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
@@ -1714,7 +1792,9 @@ static const TCGTargetOpDef ppc_op_defs[] = {
 #endif
 
     { INDEX_op_ext8s_i32, { "r", "r" } },
+    { INDEX_op_ext8u_i32, { "r", "r" } },
     { INDEX_op_ext16s_i32, { "r", "r" } },
+    { INDEX_op_ext16u_i32, { "r", "r" } },
 
     { -1 },
 };
index 71bc7c1..0c71a11 100644 (file)
@@ -78,17 +78,17 @@ enum {
 
 /* optional instructions */
 #define TCG_TARGET_HAS_div_i32
-// #define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_rot_i32
 #define TCG_TARGET_HAS_ext8s_i32
 #define TCG_TARGET_HAS_ext16s_i32
-// #define TCG_TARGET_HAS_ext8u_i32
-// #define TCG_TARGET_HAS_ext16u_i32
-// #define TCG_TARGET_HAS_bswap16_i32
-// #define TCG_TARGET_HAS_bswap32_i32
-// #define TCG_TARGET_HAS_not_i32
+#define TCG_TARGET_HAS_ext8u_i32
+#define TCG_TARGET_HAS_ext16u_i32
+/* #define TCG_TARGET_HAS_bswap16_i32 */
+/* #define TCG_TARGET_HAS_bswap32_i32 */
+#define TCG_TARGET_HAS_not_i32
 #define TCG_TARGET_HAS_neg_i32
-// #define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
+#define TCG_TARGET_HAS_andc_i32
+#define TCG_TARGET_HAS_orc_i32
 
 #define TCG_AREG0 TCG_REG_R27
 #define TCG_AREG1 TCG_REG_R24