Implement a couple of backend artefacts needed by Memcheck on large
applications:
  Iop_CmpNEZ64x2 expressions
  Ijk_NoRedir block terminators


git-svn-id: svn://svn.valgrind.org/vex/trunk@2836 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host_arm64_defs.c b/priv/host_arm64_defs.c
index 049b459..47b2df5 100644
--- a/priv/host_arm64_defs.c
+++ b/priv/host_arm64_defs.c
@@ -4425,7 +4425,7 @@
             //case Ijk_MapFail:     trcval = VEX_TRC_JMP_MAPFAIL;     break;
             case Ijk_NoDecode:    trcval = VEX_TRC_JMP_NODECODE;    break;
             //case Ijk_TInval:      trcval = VEX_TRC_JMP_TINVAL;      break;
-            //case Ijk_NoRedir:     trcval = VEX_TRC_JMP_NOREDIR;     break;
+            case Ijk_NoRedir:     trcval = VEX_TRC_JMP_NOREDIR;     break;
             //case Ijk_SigTRAP:     trcval = VEX_TRC_JMP_SIGTRAP;     break;
             //case Ijk_SigSEGV:     trcval = VEX_TRC_JMP_SIGSEGV;     break;
             case Ijk_Boring:      trcval = VEX_TRC_JMP_BORING;      break;
diff --git a/priv/host_arm64_isel.c b/priv/host_arm64_isel.c
index 31ee5dc..40978dd 100644
--- a/priv/host_arm64_isel.c
+++ b/priv/host_arm64_isel.c
@@ -4414,6 +4414,26 @@
             addInstr(env, ARM64Instr_VUnaryV(op, res, arg));
             return res;
          }
+         //ATC case Iop_CmpNEZ8x16:
+         //ATC case Iop_CmpNEZ16x8:
+         //ATC case Iop_CmpNEZ32x4:
+         case Iop_CmpNEZ64x2: {
+            HReg arg  = iselV128Expr(env, e->Iex.Unop.arg);
+            HReg zero = newVRegV(env);
+            HReg res  = newVRegV(env);
+            ARM64VecBinOp cmp = ARM64vecb_INVALID;
+            switch (e->Iex.Unop.op) {
+               case Iop_CmpNEZ64x2: cmp = ARM64vecb_CMEQ64x2; break;
+               default: vassert(0);
+            }
+            // This is pretty feeble.  Better: use CMP against zero
+            // and avoid the extra instruction and extra register.
+            addInstr(env, ARM64Instr_VImmQ(zero, 0x0000));
+            addInstr(env, ARM64Instr_VBinV(cmp, res, arg, zero));
+            addInstr(env, ARM64Instr_VUnaryV(ARM64vecu_NOT, res, res));
+            return res;
+         }
+
 //ZZ          case Iop_NotV128: {
 //ZZ             DECLARE_PATTERN(p_veqz_8x16);
 //ZZ             DECLARE_PATTERN(p_veqz_16x8);
@@ -4669,23 +4689,6 @@
 //ZZ                                            res, tmp, x, 0, True));
 //ZZ             return res;
 //ZZ          }
-//ZZ          case Iop_CmpNEZ8x16:
-//ZZ          case Iop_CmpNEZ16x8:
-//ZZ          case Iop_CmpNEZ32x4: {
-//ZZ             HReg res = newVRegV(env);
-//ZZ             HReg tmp = newVRegV(env);
-//ZZ             HReg arg = iselNeonExpr(env, e->Iex.Unop.arg);
-//ZZ             UInt size;
-//ZZ             switch (e->Iex.Unop.op) {
-//ZZ                case Iop_CmpNEZ8x16: size = 0; break;
-//ZZ                case Iop_CmpNEZ16x8: size = 1; break;
-//ZZ                case Iop_CmpNEZ32x4: size = 2; break;
-//ZZ                default: vassert(0);
-//ZZ             }
-//ZZ             addInstr(env, ARMInstr_NUnary(ARMneon_EQZ, tmp, arg, size, True));
-//ZZ             addInstr(env, ARMInstr_NUnary(ARMneon_NOT, res, tmp, 4, True));
-//ZZ             return res;
-//ZZ          }
 //ZZ          case Iop_Widen8Uto16x8:
 //ZZ          case Iop_Widen16Uto32x4:
 //ZZ          case Iop_Widen32Uto64x2: {
@@ -6760,7 +6763,6 @@
       ARM64AMode* amPC
          = mk_baseblock_64bit_access_amode(stmt->Ist.Exit.offsIP);
 
-
       /* Case: boring transfer to known address */
       if (stmt->Ist.Exit.jk == Ijk_Boring
           /*ATC || stmt->Ist.Exit.jk == Ijk_Call */
@@ -6881,7 +6883,7 @@
       /* Keep this list in sync with that for Ist_Exit above */
       case Ijk_ClientReq:
       case Ijk_NoDecode:
-//ZZ       case Ijk_NoRedir:
+      case Ijk_NoRedir:
       case Ijk_Sys_syscall:
 //ZZ       case Ijk_TInval:
 //ZZ       case Ijk_Yield: