Add test cases for PCMPxSTRx variant $0x46.  See #306664.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12979 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/amd64/pcmpstr64.c b/none/tests/amd64/pcmpstr64.c
index b3a07b5..9e53202 100644
--- a/none/tests/amd64/pcmpstr64.c
+++ b/none/tests/amd64/pcmpstr64.c
@@ -10,6 +10,7 @@
 typedef  unsigned int   UInt;
 typedef  signed int     Int;
 typedef  unsigned char  UChar;
+typedef  signed char    Char;
 typedef  unsigned long long int ULong;
 typedef  UChar          Bool;
 #define False ((Bool)0)
@@ -204,7 +205,7 @@
    switch (imm8) {
       case 0x00:
       case 0x02: case 0x08: case 0x0C: case 0x12: case 0x1A:
-      case 0x38: case 0x3A: case 0x44: case 0x4A:
+      case 0x38: case 0x3A: case 0x44: case 0x46: case 0x4A:
          break;
       default:
          return False;
@@ -371,6 +372,47 @@
       return True;
    }
 
+   /*----------------------------------------*/
+   /*-- ranges, signed byte data           --*/
+   /*----------------------------------------*/
+
+   if (agg == 1/*ranges*/
+       && fmt == 2/*sb*/
+       && !isSTRM) {
+
+      /* argL: string,  argR: range-pairs */
+      UInt   ri, si;
+      Char*  argL    = (Char*)argLV;
+      Char*  argR    = (Char*)argRV;
+      UInt   boolRes = 0;
+      UInt   validL  = ~(zmaskL | -zmaskL);  // not(left(zmaskL))
+      UInt   validR  = ~(zmaskR | -zmaskR);  // not(left(zmaskR))
+      for (si = 0; si < 16; si++) {
+         if ((validL & (1 << si)) == 0)
+            // run off the end of the string
+            break;
+         UInt m = 0;
+         for (ri = 0; ri < 16; ri += 2) {
+            if ((validR & (3 << ri)) != (3 << ri)) break;
+            if (argR[ri] <= argL[si] && argL[si] <= argR[ri+1]) { 
+               m = 1; break;
+            }
+         }
+         boolRes |= (m << si);
+      }
+
+      // boolRes is "pre-invalidated"
+      UInt intRes1 = boolRes & 0xFFFF;
+
+      // generate I-format output
+      pcmpXstrX_WRK_gen_output_fmt_I(
+         resV, resOSZACP,
+         intRes1, zmaskL, zmaskR, validL, pol, idx
+      );
+
+      return True;
+   }
+
    return False;
 }
 
@@ -1075,6 +1117,11 @@
 
    try_istri(wot,h,s, "0123456789abcdef", "00000000dca86532");
    try_istri(wot,h,s, "123456789abcdef1", "00000000dca86532");
+
+   try_istri(wot,h,s, "163887ec041a9b72", "fcd75adb9b3e895a");
+   try_istri(wot,h,s, "fc937cbfbf53f8e2", "0d136bcb024d3fb7");
+   try_istri(wot,h,s, "2ca34182c29a82ab", "302ebd646775ab54");
+   try_istri(wot,h,s, "3f2987608c11be6f", "a9ecb661f8e0a8cb");
 }
 
 
@@ -1255,6 +1302,89 @@
 
 //////////////////////////////////////////////////////////
 //                                                      //
+//                       ISTRI_46                       //
+//                                                      //
+//////////////////////////////////////////////////////////
+
+UInt h_pcmpistri_46 ( V128* argL, V128* argR )
+{
+   V128 block[2];
+   memcpy(&block[0], argL, sizeof(V128));
+   memcpy(&block[1], argR, sizeof(V128));
+   ULong res, flags;
+   __asm__ __volatile__(
+      "subq      $1024,  %%rsp"             "\n\t"
+      "movdqu    0(%2),  %%xmm2"            "\n\t"
+      "movdqu    16(%2), %%xmm11"           "\n\t"
+      "pcmpistri $0x46,  %%xmm2, %%xmm11"   "\n\t"
+      "pushfq"                              "\n\t"
+      "popq      %%rdx"                     "\n\t"
+      "movq      %%rcx,  %0"                "\n\t"
+      "movq      %%rdx,  %1"                "\n\t"
+      "addq      $1024,  %%rsp"             "\n\t"
+      : /*out*/ "=r"(res), "=r"(flags) : "r"/*in*/(&block[0])
+      : "rcx","rdx","xmm0","xmm2","xmm11","cc","memory"
+   );
+   return ((flags & 0x8D5) << 16) | (res & 0xFFFF);
+}
+
+UInt s_pcmpistri_46 ( V128* argLU, V128* argRU )
+{
+   V128 resV;
+   UInt resOSZACP, resECX;
+   Bool ok
+      = pcmpXstrX_WRK( &resV, &resOSZACP, argLU, argRU,
+                       zmask_from_V128(argLU),
+                       zmask_from_V128(argRU),
+                       0x46, False/*!isSTRM*/
+        );
+   assert(ok);
+   resECX = resV.uInt[0];
+   return (resOSZACP << 16) | resECX;
+}
+
+void istri_46 ( void )
+{
+   char* wot = "46";
+   UInt(*h)(V128*,V128*) = h_pcmpistri_46;
+   UInt(*s)(V128*,V128*) = s_pcmpistri_46;
+
+   try_istri(wot,h,s, "aaaabbbbccccdddd", "00000000000000bc"); 
+   try_istri(wot,h,s, "aaaabbbbccccdddd", "00000000000000cb"); 
+   try_istri(wot,h,s, "baaabbbbccccdddd", "00000000000000cb"); 
+   try_istri(wot,h,s, "baaabbbbccccdddc", "00000000000000cb"); 
+
+   try_istri(wot,h,s, "bbbbbbbbbbbbbbbb", "00000000000000cb"); 
+   try_istri(wot,h,s, "bbbbbbbb0bbbbbbb", "00000000000000cb"); 
+   try_istri(wot,h,s, "bbbbbbbbbbbbbb0b", "00000000000000cb"); 
+   try_istri(wot,h,s, "bbbbbbbbbbbbbbb0", "00000000000000cb"); 
+   try_istri(wot,h,s, "0000000000000000", "00000000000000cb"); 
+
+   try_istri(wot,h,s, "0000000000000000", "0000000000000000"); 
+
+   try_istri(wot,h,s, "bbbbbbbbbbbbbbbb", "00000000000000cb"); 
+   try_istri(wot,h,s, "bbbbbbbbbbbbbbbb", "000000000000000b"); 
+   try_istri(wot,h,s, "b4b4b4b4b4b4b4b4", "00000000000062cb"); 
+
+   try_istri(wot,h,s, "b4b4b4b4b4b4b4b4", "00000000000002cb"); 
+   try_istri(wot,h,s, "b4b4b4b4b4b4b4b4", "00000000000000cb"); 
+   try_istri(wot,h,s, "b4b4b4b4b4b4b4b4", "000000000000000b");
+
+   try_istri(wot,h,s, "0123456789abcdef", "000000fecb975421");
+   try_istri(wot,h,s, "123456789abcdef1", "000000fecb975421");
+
+   try_istri(wot,h,s, "0123456789abcdef", "00000000dca86532");
+   try_istri(wot,h,s, "123456789abcdef1", "00000000dca86532");
+
+   try_istri(wot,h,s, "163887ec041a9b72", "fcd75adb9b3e895a");
+   try_istri(wot,h,s, "fc937cbfbf53f8e2", "0d136bcb024d3fb7");
+   try_istri(wot,h,s, "2ca34182c29a82ab", "302ebd646775ab54");
+   try_istri(wot,h,s, "3f2987608c11be6f", "a9ecb661f8e0a8cb");
+}
+
+
+//////////////////////////////////////////////////////////
+//                                                      //
 //                         main                         //
 //                                                      //
 //////////////////////////////////////////////////////////
@@ -1271,5 +1401,6 @@
    istri_44();
    istri_00();
    istri_38();
+   istri_46();
    return 0;
 }
diff --git a/none/tests/amd64/pcmpstr64.stdout.exp b/none/tests/amd64/pcmpstr64.stdout.exp
index c94e0a4..e326d16 100644
--- a/none/tests/amd64/pcmpstr64.stdout.exp
+++ b/none/tests/amd64/pcmpstr64.stdout.exp
@@ -208,6 +208,10 @@
 istri 44  123456789abcdef1 000000fecb975421 -> 0881000f 0881000f 
 istri 44  0123456789abcdef 00000000dca86532 -> 00c1000d 00c1000d 
 istri 44  123456789abcdef1 00000000dca86532 -> 0081000e 0081000e 
+istri 44  163887ec041a9b72 fcd75adb9b3e895a -> 00410004 00410004 
+istri 44  fc937cbfbf53f8e2 0d136bcb024d3fb7 -> 0081000d 0081000d 
+istri 44  2ca34182c29a82ab 302ebd646775ab54 -> 0081000b 0081000b 
+istri 44  3f2987608c11be6f a9ecb661f8e0a8cb -> 00c10007 00c10007 
 istri 00  abcdacbdabcdabcd 000000000000000a -> 00810003 00810003 
 istri 00  abcdabcdabcdabcd 000000000000000b -> 00810002 00810002 
 istri 00  abcdabcdabcdabcd 00000000000000ab -> 00810002 00810002 
@@ -260,3 +264,27 @@
 istri 38  0000000000000001 aaaaaaaa0aaaaaaa -> 08c10000 08c10000 
 istri 38  0000000000000000 aaaaaaaaaaaaaaaa -> 00400010 00400010 
 istri 38  aaaaaaaaaaaaaaaa 0000000000000000 -> 08810000 08810000 
+istri 46  aaaabbbbccccdddd 00000000000000bc -> 00800010 00800010 
+istri 46  aaaabbbbccccdddd 00000000000000cb -> 0081000b 0081000b 
+istri 46  baaabbbbccccdddd 00000000000000cb -> 0081000f 0081000f 
+istri 46  baaabbbbccccdddc 00000000000000cb -> 0881000f 0881000f 
+istri 46  bbbbbbbbbbbbbbbb 00000000000000cb -> 0881000f 0881000f 
+istri 46  bbbbbbbb0bbbbbbb 00000000000000cb -> 08c10006 08c10006 
+istri 46  bbbbbbbbbbbbbb0b 00000000000000cb -> 08c10000 08c10000 
+istri 46  bbbbbbbbbbbbbbb0 00000000000000cb -> 00c00010 00c00010 
+istri 46  0000000000000000 00000000000000cb -> 00c00010 00c00010 
+istri 46  0000000000000000 0000000000000000 -> 00c00010 00c00010 
+istri 46  bbbbbbbbbbbbbbbb 00000000000000cb -> 0881000f 0881000f 
+istri 46  bbbbbbbbbbbbbbbb 000000000000000b -> 00800010 00800010 
+istri 46  b4b4b4b4b4b4b4b4 00000000000062cb -> 0881000f 0881000f 
+istri 46  b4b4b4b4b4b4b4b4 00000000000002cb -> 0081000f 0081000f 
+istri 46  b4b4b4b4b4b4b4b4 00000000000000cb -> 0081000f 0081000f 
+istri 46  b4b4b4b4b4b4b4b4 000000000000000b -> 00800010 00800010 
+istri 46  0123456789abcdef 000000fecb975421 -> 08c1000e 08c1000e 
+istri 46  123456789abcdef1 000000fecb975421 -> 0881000f 0881000f 
+istri 46  0123456789abcdef 00000000dca86532 -> 00c1000d 00c1000d 
+istri 46  123456789abcdef1 00000000dca86532 -> 0081000e 0081000e 
+istri 46  163887ec041a9b72 fcd75adb9b3e895a -> 08410006 08410006 
+istri 46  fc937cbfbf53f8e2 0d136bcb024d3fb7 -> 0881000f 0881000f 
+istri 46  2ca34182c29a82ab 302ebd646775ab54 -> 0081000f 0081000f 
+istri 46  3f2987608c11be6f a9ecb661f8e0a8cb -> 00c10007 00c10007