]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm64: implement: rbit 16b,8b, rev16 16b,8b
authorJulian Seward <jseward@acm.org>
Thu, 26 Jun 2014 12:39:05 +0000 (12:39 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 26 Jun 2014 12:39:05 +0000 (12:39 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2891

VEX/priv/guest_arm64_toIR.c
VEX/priv/host_arm64_defs.c
VEX/priv/host_arm64_defs.h
VEX/priv/host_arm64_isel.c
VEX/priv/ir_defs.c
VEX/pub/libvex_ir.h

index 48851aa2474a0eb869ec8bf3bb2ae3ec341985ff..1bc824af407e0e42b2d301af721a7ec98fed9433 100644 (file)
@@ -5657,6 +5657,16 @@ void putLO64andZUorPutHI64 ( Bool is2, UInt dd, IRTemp new64 )
 }
 
 
+/* |fullWidth| is a full V128 width result.  Depending on bitQ,
+   zero out the upper half. */
+static IRExpr* math_MAYBE_ZERO_HI64 ( UInt bitQ, IRTemp fullWidth )
+{
+   if (bitQ == 1) return mkexpr(fullWidth);
+   if (bitQ == 0) return unop(Iop_ZeroHI64ofV128, mkexpr(fullWidth));
+   vassert(0);
+}
+
+
 static
 Bool dis_AdvSIMD_EXT(/*MB_OUT*/DisResult* dres, UInt insn)
 {
@@ -7464,6 +7474,17 @@ Bool dis_AdvSIMD_two_reg_misc(/*MB_OUT*/DisResult* dres, UInt insn)
    UInt dd     = INSN(4,0);
    vassert(size < 4);
 
+   if (bitU == 0 && size == X00 && opcode == BITS5(0,0,0,0,1)) {
+      /* -------- 0,00,00001: REV16 16b_16b, 8b_8b -------- */
+      IRTemp res = newTemp(Ity_V128);
+      assign(res, unop(Iop_Reverse8sIn16_x8, getQReg128(nn)));
+      putQReg128(dd, math_MAYBE_ZERO_HI64(bitQ, res));
+      const HChar* arr = nameArr_Q_SZ(bitQ, 0);
+      DIP("%s %s.%s, %s.%s\n", "rev16",
+          nameQReg128(dd), arr, nameQReg128(nn), arr);
+      return True;
+   }
+
    if (opcode == BITS5(0,0,1,0,0)) {
       /* -------- 0,xx,00100: CLS std6_std6 -------- */
       /* -------- 1,xx,00100: CLZ std6_std6 -------- */
@@ -7489,12 +7510,24 @@ Bool dis_AdvSIMD_two_reg_misc(/*MB_OUT*/DisResult* dres, UInt insn)
       assign(res, unop(bitU == 0 ? Iop_Cnt8x16 : Iop_NotV128, getQReg128(nn)));
       putQReg128(dd, bitQ == 0 ? unop(Iop_ZeroHI64ofV128, mkexpr(res))
                                : mkexpr(res));
-      const HChar* arr = nameArr_Q_SZ(bitQ, size);
+      const HChar* arr = nameArr_Q_SZ(bitQ, 0);
       DIP("%s %s.%s, %s.%s\n", bitU == 0 ? "cnt" : "not",
           nameQReg128(dd), arr, nameQReg128(nn), arr);
       return True;
    }
 
+   if (bitU == 1 && size == X01 && opcode == BITS5(0,0,1,0,1)) {
+      /* -------- 1,01,00101  RBIT 16b_16b, 8b_8b -------- */
+      IRTemp res = newTemp(Ity_V128);
+      assign(res, unop(Iop_Reverse1sIn8_x16, getQReg128(nn)));
+      putQReg128(dd, bitQ == 0 ? unop(Iop_ZeroHI64ofV128, mkexpr(res))
+                               : mkexpr(res));
+      const HChar* arr = nameArr_Q_SZ(bitQ, 0);
+      DIP("%s %s.%s, %s.%s\n", "rbit",
+          nameQReg128(dd), arr, nameQReg128(nn), arr);
+      return True;
+   }
+
    if (opcode == BITS5(0,1,0,0,0)) {
       /* -------- 0,xx,01000: CMGT std7_std7_#0 -------- */ // >s 0
       /* -------- 1,xx,01000: CMGE std7_std7_#0 -------- */ // >=s 0
index dbb485d6d5269fccb210128d5ae57537c64b20c8..041309deb705ef8f087c271ee38946da5cc6a290 100644 (file)
@@ -947,6 +947,8 @@ static void showARM64VecUnaryOp(/*OUT*/const HChar** nm,
       case ARM64vecu_CLZ16x8:  *nm = "clz  "; *ar = "8h";  return;
       case ARM64vecu_CLZ8x16:  *nm = "clz  "; *ar = "16b"; return;
       case ARM64vecu_CNT8x16:  *nm = "cnt  "; *ar = "16b"; return;
+      case ARM64vecu_RBIT:     *nm = "rbit "; *ar = "16b"; return;
+      case ARM64vecu_REV1616B: *nm = "rev16"; *ar = "16b"; return;
       default: vpanic("showARM64VecUnaryOp");
    }
 }
@@ -5387,6 +5389,10 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc,
             011 01110 00 1 00000 010010 n d  CLZ  Vd.16b, Vn.16b
 
             010 01110 00 1 00000 010110 n d  CNT  Vd.16b, Vn.16b
+
+            011 01110 01 1 00000 010110 n d  RBIT  Vd.16b, Vn.16b
+
+            010 01110 00 1 00000 000110 n d  REV16 Vd.16b, Vn.16b
          */
          UInt vD = qregNo(i->ARM64in.VUnaryV.dst);
          UInt vN = qregNo(i->ARM64in.VUnaryV.arg);
@@ -5439,6 +5445,12 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc,
             case ARM64vecu_CNT8x16:
                *p++ = X_3_8_5_6_5_5(X010, X01110001, X00000, X010110, vN, vD);
                break;
+            case ARM64vecu_RBIT:
+               *p++ = X_3_8_5_6_5_5(X011, X01110011, X00000, X010110, vN, vD);
+               break;
+            case ARM64vecu_REV1616B:
+               *p++ = X_3_8_5_6_5_5(X010, X01110001, X00000, X000110, vN, vD);
+               break;
             default:
                goto bad;
          }
index 12b098095e15c9f0224e52cf25df8ffad040135b..7c1a233b10f2b5ef7cde6350343b8fa419632093 100644 (file)
@@ -360,6 +360,8 @@ typedef
       ARM64vecu_CLS32x4,      ARM64vecu_CLS16x8,      ARM64vecu_CLS8x16, 
       ARM64vecu_CLZ32x4,      ARM64vecu_CLZ16x8,      ARM64vecu_CLZ8x16, 
       ARM64vecu_CNT8x16,
+      ARM64vecu_RBIT,
+      ARM64vecu_REV1616B,
       ARM64vecu_INVALID
    }
    ARM64VecUnaryOp;
index 35bebfaad208155c8cee170ce15002a402325a61..60c351cfefcb963fafa583d5782dd6110b866379 100644 (file)
@@ -4417,6 +4417,8 @@ static HReg iselV128Expr_wrk ( ISelEnv* env, IRExpr* e )
          case Iop_Cls32x4: case Iop_Cls16x8: case Iop_Cls8x16:
          case Iop_Clz32x4: case Iop_Clz16x8: case Iop_Clz8x16:
          case Iop_Cnt8x16:
+         case Iop_Reverse1sIn8_x16:
+         case Iop_Reverse8sIn16_x8:
          {
             HReg res = newVRegV(env);
             HReg arg = iselV128Expr(env, e->Iex.Unop.arg);
@@ -4438,6 +4440,8 @@ static HReg iselV128Expr_wrk ( ISelEnv* env, IRExpr* e )
                case Iop_Clz16x8:  op = ARM64vecu_CLZ16x8;  break;
                case Iop_Clz8x16:  op = ARM64vecu_CLZ8x16;  break;
                case Iop_Cnt8x16:  op = ARM64vecu_CNT8x16;  break;
+               case Iop_Reverse1sIn8_x16: op = ARM64vecu_RBIT;     break;
+               case Iop_Reverse8sIn16_x8: op = ARM64vecu_REV1616B; break;
                default: vassert(0);
             }
             addInstr(env, ARM64Instr_VUnaryV(op, res, arg));
index df26947b73706268b13f7a05c64ce12c012e61b2..b81a96e30dffc87aa747e289f31346caf9a10670 100644 (file)
@@ -976,6 +976,7 @@ void ppIROp ( IROp op )
       case Iop_Reverse8sIn64_x2: vex_printf("Reverse8sIn64_x2"); return;
       case Iop_Reverse16sIn64_x2: vex_printf("Reverse16sIn64_x2"); return;
       case Iop_Reverse32sIn64_x2: vex_printf("Reverse32sIn64_x2"); return;
+      case Iop_Reverse1sIn8_x16: vex_printf("Reverse1sIn8_x16"); return;
 
       case Iop_F32ToFixed32Ux4_RZ: vex_printf("F32ToFixed32Ux4_RZ"); return;
       case Iop_F32ToFixed32Sx4_RZ: vex_printf("F32ToFixed32Sx4_RZ"); return;
@@ -2912,6 +2913,7 @@ void typeOfPrimop ( IROp op,
       case Iop_Reverse32sIn64_x2:
       case Iop_Reverse8sIn32_x4: case Iop_Reverse16sIn32_x4:
       case Iop_Reverse8sIn16_x8:
+      case Iop_Reverse1sIn8_x16:
       case Iop_Neg64Fx2: case Iop_Neg32Fx4:
       case Iop_Abs8x16: case Iop_Abs16x8: case Iop_Abs32x4: case Iop_Abs64x2:
       case Iop_CipherSV128:
index c9a49bb01ea14a2c7edf1178621d34c74383ae3e..78128470c77125c6b8bdfdc49482667196804085 100644 (file)
@@ -1598,6 +1598,7 @@ typedef
       Iop_Reverse8sIn16_x8,
       Iop_Reverse8sIn32_x4, Iop_Reverse16sIn32_x4,
       Iop_Reverse8sIn64_x2, Iop_Reverse16sIn64_x2, Iop_Reverse32sIn64_x2,
+      Iop_Reverse1sIn8_x16, /* Reverse bits in each byte lane. */
 
       /* PERMUTING -- copy src bytes to dst,
          as indexed by control vector bytes: