Patchwork [v2,10/18] tcg/arm: add ext16u op

login
register
mail settings
Submitter Aurelien Jarno
Date April 10, 2010, 1:32 a.m.
Message ID <1270863186-10180-11-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/49891/
State New
Headers show

Comments

Aurelien Jarno - April 10, 2010, 1:32 a.m.
Add an ext16u op, either using the uxth instruction on ARMv6+ or two
shifts on previous ARM versions. In both cases the result use the same
number or less instructions than the pure TCG version.

Also move all sign extension code to separate functions, so that they
can be reused in other parts of the code.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 tcg/arm/tcg-target.c |   66 ++++++++++++++++++++++++++++++++++++-------------
 tcg/arm/tcg-target.h |    4 +-
 2 files changed, 50 insertions(+), 20 deletions(-)

Patch

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index b9a6abd..1bff87d 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -485,6 +485,48 @@  static inline void tcg_out_smull32(TCGContext *s,
     }
 }
 
+static inline void tcg_out_ext8s(TCGContext *s, int cond,
+                                 int rd, int rn)
+{
+    if (use_armv6_instructions) {
+        /* sxtb */
+        tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
+    } else {
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rn, SHIFT_IMM_LSL(24));
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rd, SHIFT_IMM_ASR(24));
+    }
+}
+
+static inline void tcg_out_ext16s(TCGContext *s, int cond,
+                                  int rd, int rn)
+{
+    if (use_armv6_instructions) {
+        /* sxth */
+        tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
+    } else {
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rn, SHIFT_IMM_LSL(16));
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rd, SHIFT_IMM_ASR(16));
+    }
+}
+
+static inline void tcg_out_ext16u(TCGContext *s, int cond,
+                                  int rd, int rn)
+{
+    if (use_armv6_instructions) {
+        /* uxth */
+        tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
+    } else {
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rn, SHIFT_IMM_LSL(16));
+        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
+                        rd, 0, rd, SHIFT_IMM_LSR(16));
+    }
+}
+
 static inline void tcg_out_ld32_12(TCGContext *s, int cond,
                 int rd, int rn, tcg_target_long im)
 {
@@ -1503,26 +1545,13 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_ext8s_i32:
-        if (use_armv6_instructions) {
-            /* sxtb */
-            tcg_out32(s, 0xe6af0070 | (args[0] << 12) | args[1]);
-        } else {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            args[0], 0, args[1], SHIFT_IMM_LSL(24));
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            args[0], 0, args[0], SHIFT_IMM_ASR(24));
-        }
+        tcg_out_ext8s(s, COND_AL, args[0], args[1]);
         break;
     case INDEX_op_ext16s_i32:
-        if (use_armv6_instructions) {
-            /* sxth */
-            tcg_out32(s, 0xe6bf0070 | (args[0] << 12) | args[1]);
-        } else {
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            args[0], 0, args[1], SHIFT_IMM_LSL(16));
-            tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
-                            args[0], 0, args[0], SHIFT_IMM_ASR(16));
-        }
+        tcg_out_ext16s(s, COND_AL, args[0], args[1]);
+        break;
+    case INDEX_op_ext16u_i32:
+        tcg_out_ext16u(s, COND_AL, args[0], args[1]);
         break;
 
     default:
@@ -1604,6 +1633,7 @@  static const TCGTargetOpDef arm_op_defs[] = {
 
     { INDEX_op_ext8s_i32, { "r", "r" } },
     { INDEX_op_ext16s_i32, { "r", "r" } },
+    { INDEX_op_ext16u_i32, { "r", "r" } },
 
     { -1 },
 };
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index bc08f91..1f6d665 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,8 +60,8 @@  enum {
 /* optional instructions */
 #define TCG_TARGET_HAS_ext8s_i32
 #define TCG_TARGET_HAS_ext16s_i32
-// #define TCG_TARGET_HAS_ext8u_i32
-// #define TCG_TARGET_HAS_ext16u_i32
+#undef TCG_TARGET_HAS_ext8u_i32       /* and r0, r1, #0xff */
+#define TCG_TARGET_HAS_ext16u_i32
 // #define TCG_TARGET_HAS_bswap16_i32
 // #define TCG_TARGET_HAS_bswap32_i32
 #define TCG_TARGET_HAS_not_i32