Patchwork [06/21] tcg-i386: Tidy shift operations.

login
register
mail settings
Submitter Richard Henderson
Date April 13, 2010, 11:44 p.m.
Message ID <34b3e2152f8d37d5de1b0f4f02cb0000c3fc9b7f.1271277329.git.rth@twiddle.net>
Download mbox | patch
Permalink /patch/50184/
State New
Headers show

Comments

Richard Henderson - April 13, 2010, 11:44 p.m.
Define OPC_SHIFT_{1,Ib,cl}.  Factor opcode emission to a function.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/i386/tcg-target.c |   47 +++++++++++++++++++++++------------------------
 1 files changed, 23 insertions(+), 24 deletions(-)

Patch

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 0bafd00..2df45bf 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -168,6 +168,9 @@  static inline int tcg_target_const_match(tcg_target_long val,
 #define OPC_MOVZWL	(0xb7 | P_EXT)
 #define OPC_MOVSBL	(0xbe | P_EXT)
 #define OPC_MOVSWL	(0xbf | P_EXT)
+#define OPC_SHIFT_1	(0xd1)
+#define OPC_SHIFT_Ib	(0xc1)
+#define OPC_SHIFT_cl	(0xd3)
 
 #define ARITH_ADD 0
 #define ARITH_OR  1
@@ -294,6 +297,16 @@  static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
     tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2);
 }
 
+static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
+{
+    if (count == 1) {
+        tcg_out_modrm(s, OPC_SHIFT_1, subopc, reg);
+    } else {
+        tcg_out_modrm(s, OPC_SHIFT_Ib, subopc, reg);
+        tcg_out8(s, count);
+    }
+}
+
 static void tcg_out_ext8u(TCGContext *s, int dest, int src)
 {
     if (src >= 4) {
@@ -314,12 +327,8 @@  static void tcg_out_ext8s(TCGContext *s, int dest, int src)
     if (src >= 4) {
         tcg_out_mov(s, dest, src);
         if (dest >= 4) {
-            /* shl $24, dest */
-            tcg_out_modrm(s, 0xc1, SHIFT_SHL, dest);
-            tcg_out8(s, 24);
-            /* sar $24, dest */
-            tcg_out_modrm(s, 0xc1, SHIFT_SAR, dest);
-            tcg_out8(s, 24);
+            tcg_out_shifti(s, SHIFT_SHL, dest, 24);
+            tcg_out_shifti(s, SHIFT_SAR, dest, 24);
             return;
         }
         src = dest;
@@ -351,9 +360,7 @@  static inline void tcg_out_bswap16(TCGContext *s, int reg, int sign)
        the sign or zero extension required.  It also doesn't suffer the
        problem of partial register stalls that using rolw does.  */
     tcg_out_bswap32(s, reg);
-    /* shr $16, dest */
-    tcg_out_modrm(s, 0xc1, (sign ? SHIFT_SAR : SHIFT_SHR), reg);
-    tcg_out8(s, 16);
+    tcg_out_shifti(s, (sign ? SHIFT_SAR : SHIFT_SHR), reg, 16);
 }
 
 static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val, int cf)
@@ -648,9 +655,8 @@  static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
 
     tcg_out_mov(s, r0, addr_reg); 
  
-    tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
-    tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
-    
+    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
+
     tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
     tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
     
@@ -845,9 +851,8 @@  static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
 
     tcg_out_mov(s, r0, addr_reg); 
  
-    tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
-    tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
-    
+    tcg_out_shifti(s, SHIFT_SHR, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
+
     tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
     tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
     
@@ -977,8 +982,7 @@  static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
         if (bswap) {
             tcg_out_mov(s, r1, data_reg);
             tcg_out8(s, 0x66); /* rolw $8, %ecx */
-            tcg_out_modrm(s, 0xc1, 0, r1);
-            tcg_out8(s, 8);
+            tcg_out_shifti(s, SHIFT_ROL, r1, 8);
             data_reg = r1;
         }
         /* movw */
@@ -1146,14 +1150,9 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         c = SHIFT_SHL;
     gen_shift32:
         if (const_args[2]) {
-            if (args[2] == 1) {
-                tcg_out_modrm(s, 0xd1, c, args[0]);
-            } else {
-                tcg_out_modrm(s, 0xc1, c, args[0]);
-                tcg_out8(s, args[2]);
-            }
+            tcg_out_shifti(s, c, args[0], args[2]);
         } else {
-            tcg_out_modrm(s, 0xd3, c, args[0]);
+            tcg_out_modrm(s, OPC_SHIFT_cl, c, args[0]);
         }
         break;
     case INDEX_op_shr_i32: