]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support the UMAAL instruction. (n-i-bz). Based on a patch from
authorJulian Seward <jseward@acm.org>
Wed, 12 Dec 2012 00:16:41 +0000 (00:16 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 12 Dec 2012 00:16:41 +0000 (00:16 +0000)
Torbjorn Granlund, tg@gmplib.org.

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

VEX/priv/guest_arm_toIR.c
VEX/priv/host_arm_isel.c

index fe8ee477ad24161825aa54502e1ee933a6524379..f20ef7a3677b6b7b100d0cb16eec8b61c7acc2bf 100644 (file)
@@ -13841,6 +13841,44 @@ DisResult disInstr_ARM_WRK (
       /* fall through */
    }
 
+   // UMAAL
+   if (BITS8(0,0,0,0,0,1,0,0) == INSN(27,20) && INSN(7,4) == BITS4(1,0,0,1)) {
+      UInt rDhi = INSN(19,16);
+      UInt rDlo = INSN(15,12);
+      UInt rM   = INSN(11,8);
+      UInt rN   = INSN(3,0);
+      if (rDlo == 15 || rDhi == 15 || rN == 15 || rM == 15 || rDhi == rDlo)  {
+         /* Unpredictable; don't decode; fall through */
+      } else {
+         IRTemp argN   = newTemp(Ity_I32);
+         IRTemp argM   = newTemp(Ity_I32);
+         IRTemp argDhi = newTemp(Ity_I32);
+         IRTemp argDlo = newTemp(Ity_I32);
+         IRTemp res    = newTemp(Ity_I64);
+         IRTemp resHi  = newTemp(Ity_I32);
+         IRTemp resLo  = newTemp(Ity_I32);
+         assign( argN,   getIRegA(rN) );
+         assign( argM,   getIRegA(rM) );
+         assign( argDhi, getIRegA(rDhi) );
+         assign( argDlo, getIRegA(rDlo) );
+         assign( res, 
+                 binop(Iop_Add64,
+                       binop(Iop_Add64,
+                             binop(Iop_MullU32, mkexpr(argN), mkexpr(argM)),
+                             unop(Iop_32Uto64, mkexpr(argDhi))),
+                       unop(Iop_32Uto64, mkexpr(argDlo))) );
+         assign( resHi, unop(Iop_64HIto32, mkexpr(res)) );
+         assign( resLo, unop(Iop_64to32, mkexpr(res)) );
+         // now update guest state
+         putIRegA( rDhi, mkexpr(resHi), condT, Ijk_Boring );
+         putIRegA( rDlo, mkexpr(resLo), condT, Ijk_Boring );
+         DIP("umaal %s r%u, r%u, r%u, r%u\n",
+             nCC(INSN_COND), rDlo, rDhi, rN, rM);
+         goto decode_success;
+      }
+      /* fall through */
+   }
+
    /* --------------------- Msr etc --------------------- */
 
    // MSR apsr, #imm
@@ -18251,6 +18289,40 @@ DisResult disInstr_THUMB_WRK (
       }
    }
 
+   /* ------------------ (T1) UMAAL ------------------ */
+   if (INSN0(15,4) == 0xFBE && INSN1(7,4) == BITS4(0,1,1,0)) {
+      UInt rN   = INSN0(3,0);
+      UInt rDlo = INSN1(15,12);
+      UInt rDhi = INSN1(11,8);
+      UInt rM   = INSN1(3,0);
+      if (!isBadRegT(rDlo) && !isBadRegT(rDhi) && !isBadRegT(rN)
+          && !isBadRegT(rM) && rDhi != rDlo) {
+         IRTemp argN   = newTemp(Ity_I32);
+         IRTemp argM   = newTemp(Ity_I32);
+         IRTemp argDhi = newTemp(Ity_I32);
+         IRTemp argDlo = newTemp(Ity_I32);
+         IRTemp res    = newTemp(Ity_I64);
+         IRTemp resHi  = newTemp(Ity_I32);
+         IRTemp resLo  = newTemp(Ity_I32);
+         assign( argN,   getIRegT(rN) );
+         assign( argM,   getIRegT(rM) );
+         assign( argDhi, getIRegT(rDhi) );
+         assign( argDlo, getIRegT(rDlo) );
+         assign( res, 
+                 binop(Iop_Add64,
+                       binop(Iop_Add64,
+                             binop(Iop_MullU32, mkexpr(argN), mkexpr(argM)),
+                             unop(Iop_32Uto64, mkexpr(argDhi))),
+                       unop(Iop_32Uto64, mkexpr(argDlo))) );
+         assign( resHi, unop(Iop_64HIto32, mkexpr(res)) );
+         assign( resLo, unop(Iop_64to32, mkexpr(res)) );
+         putIRegT( rDhi, mkexpr(resHi), condT );
+         putIRegT( rDlo, mkexpr(resLo), condT );
+         DIP("umaal r%u, r%u, r%u, r%u\n", rDlo, rDhi, rN, rM);
+         goto decode_success;
+      }
+   }
+
    /* ------------------ (T2) ADR ------------------ */
    if ((INSN0(15,0) == 0xF2AF || INSN0(15,0) == 0xF6AF)
        && INSN1(15,15) == 0) {
index 8a6326303e164832d7fd883298bded3e60e942f1..8cb985a197fa2a19fa263ff195b1b0f59a3928c6 100644 (file)
@@ -3085,6 +3085,16 @@ static HReg iselNeon64Expr_wrk ( ISelEnv* env, IRExpr* e )
    if (e->tag == Iex_Unop) {
       switch (e->Iex.Unop.op) {
 
+         /* 32Uto64 */
+         case Iop_32Uto64: {
+            HReg rLo = iselIntExpr_R(env, e->Iex.Unop.arg);
+            HReg rHi = newVRegI(env);
+            HReg res = newVRegD(env);
+            addInstr(env, ARMInstr_Imm32(rHi, 0));
+            addInstr(env, ARMInstr_VXferD(True/*toD*/, res, rHi, rLo));
+            return res;
+         }
+
          /* ReinterpF64asI64 */
          case Iop_ReinterpF64asI64:
          /* Left64(e) */