]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
* iropt: constant-fold Sar32, and be more careful with Shl32
authorJulian Seward <jseward@acm.org>
Fri, 20 Aug 2004 00:28:13 +0000 (00:28 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 20 Aug 2004 00:28:13 +0000 (00:28 +0000)
* x86-host: add a case to the assembler for 'mul'

git-svn-id: svn://svn.valgrind.org/vex/trunk@187

VEX/priv/host-x86/hdefs.c
VEX/priv/ir/iropt.c

index abe07f40faf84c660434289d0f3f7e6041f79e81..efac34f1e385a94ba9fac555dc3ad6301d89bb9f 100644 (file)
@@ -1218,10 +1218,12 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
                   *p++ = 0x6B;
                   p = doAMode_R(p, i->Xin.Alu32R.dst, i->Xin.Alu32R.dst);
                   *p++ = 0xFF & i->Xin.Alu32R.src->Xrmi.Imm.imm32;
-                  goto done;
                } else {
-                  goto bad;
+                  *p++ = 0x69;
+                  p = doAMode_R(p, i->Xin.Alu32R.dst, i->Xin.Alu32R.dst);
+                  p = emit32(p, i->Xin.Alu32R.src->Xrmi.Imm.imm32);
                }
+               goto done;
             default:
                goto bad;
          }
index 1c66e8beb9ab2e0aceaab77de0ab39175c714d32..c680d679efef6bfb8b64c74da1541862e1eb60d4 100644 (file)
@@ -300,6 +300,7 @@ static IRBB* flatten_BB ( IRBB* in )
 
 static IRExpr* fold_Expr ( IRExpr* e )
 {
+   Int     shift;
    IRExpr* e2 = e; /* e2 is the result of folding e, if possible */
 
    /* UNARY ops */
@@ -356,10 +357,23 @@ static IRExpr* fold_Expr ( IRExpr* e )
                         | e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));
                break;
             case Iop_Shl32:
-               e2 = IRExpr_Const(IRConst_U32(
-                       (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32
-                        << e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)));
+               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32);
+              if (shift >= 0 && shift <= 31)
+                  e2 = IRExpr_Const(IRConst_U32(
+                          (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32
+                           << shift)));
+               break;
+            case Iop_Sar32: {
+               /* paranoid ... */
+               /*signed*/ Int s32;
+               s32   = (Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32);
+               shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32);
+               if (shift >= 0 && shift <= 31) {
+                  s32 >>=/*signed*/ shift;
+                  e2 = IRExpr_Const(IRConst_U32((UInt)s32));
+               }
                break;
+            }
             case Iop_CmpEQ32:
                e2 = IRExpr_Const(IRConst_Bit(
                        (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32