]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement SSAT16. Fixes #318929. (Vasily Golubev, w.golubev@mail.ru)
authorJulian Seward <jseward@acm.org>
Mon, 13 May 2013 10:02:33 +0000 (10:02 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 13 May 2013 10:02:33 +0000 (10:02 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2721

VEX/priv/guest_arm_toIR.c

index 17cdce1959c4befb55f75e1d27a87e1fc2c3d8c4..959bbe41b2f2b5991057a06219ba431f73bd41d2 100644 (file)
@@ -9207,6 +9207,70 @@ static Bool decode_V6MEDIA_instruction (
     /* fall through */
   }
 
+   /* ----------- ssat16<c> <Rd>,#<imm>,<Rn> ----------- */
+   {
+     UInt regD = 99, regN = 99, sat_imm = 99;
+     Bool gate = False;
+
+     if (isT) {
+        if (INSNT0(15,6) == BITS10(1,1,1,1,0,0,1,1,0,0)
+            && INSNT0(5,4) == BITS2(1,0)
+            && INSNT1(15,12) == BITS4(0,0,0,0)
+            && INSNT1(7,4) == BITS4(0,0,0,0)) {
+           regD       = INSNT1(11,8);
+           regN       = INSNT0(3,0);
+           sat_imm    = INSNT1(3,0) + 1;
+           if (!isBadRegT(regD) && !isBadRegT(regN))
+              gate = True;
+        }
+     } else {
+        if (INSNA(27,20) == BITS8(0,1,1,0,1,0,1,0) &&
+            INSNA(11,4)   == BITS8(1,1,1,1,0,0,1,1)) {
+           regD       = INSNA(15,12);
+           regN       = INSNA(3,0);
+           sat_imm    = INSNA(19,16) + 1;
+           if (regD != 15 && regN != 15)
+              gate = True;
+        }
+     }
+
+     if (gate) {
+        IRTemp irt_regN    = newTemp(Ity_I32);
+        IRTemp irt_regN_lo = newTemp(Ity_I32);
+        IRTemp irt_regN_hi = newTemp(Ity_I32);
+        IRTemp irt_Q_lo    = newTemp(Ity_I32);
+        IRTemp irt_Q_hi    = newTemp(Ity_I32);
+        IRTemp irt_res_lo  = newTemp(Ity_I32);
+        IRTemp irt_res_hi  = newTemp(Ity_I32);
+
+        assign( irt_regN, isT ? getIRegT(regN) : getIRegA(regN) );
+        assign( irt_regN_lo,
+                binop( Iop_Sar32,
+                       binop(Iop_Shl32, mkexpr(irt_regN), mkU8(16)),
+                       mkU8(16)) );
+        assign( irt_regN_hi, binop(Iop_Sar32, mkexpr(irt_regN), mkU8(16)) );
+
+        armSignedSatQ( irt_regN_lo, sat_imm, &irt_res_lo, &irt_Q_lo );
+        or_into_QFLAG32( mkexpr(irt_Q_lo), condT );
+
+        armSignedSatQ( irt_regN_hi, sat_imm, &irt_res_hi, &irt_Q_hi );
+        or_into_QFLAG32( mkexpr(irt_Q_hi), condT );
+
+        IRExpr* ire_result 
+           = binop(Iop_Or32, 
+                   binop(Iop_And32, mkexpr(irt_res_lo), mkU32(0xFFFF)),
+                   binop(Iop_Shl32, mkexpr(irt_res_hi), mkU8(16)));
+        if (isT)
+           putIRegT( regD, ire_result, condT );
+        else
+           putIRegA( regD, ire_result, condT, Ijk_Boring );
+
+        DIP( "ssat16%s r%u, #0x%04x, r%u\n", nCC(conq), regD, sat_imm, regN );
+        return True;
+     }
+     /* fall through */
+   }
+
    /* -------------- usat16<c> <Rd>,#<imm4>,<Rn> --------------- */
    {
      UInt regD = 99, regN = 99, sat_imm = 99;