Comment 8 for bug 1027977

Revision history for this message
In , Josef-weidendorfer (josef-weidendorfer) wrote :

(In reply to comment #4)
> Josef, I am not surprised to hear that (+ thanks for chasing it). Which
> pcmpistri case
> is it (iow, which immediate byte) ?

It's imm8 = 0xc. I think I found the problem:

There is a discrepancy between real hardware and emulation if the needle is an empty string, ie. starts with "\0". This happens on the last call to pcmpistri in __strstr_sse42 when the needle length is a multiple of 16.

For all positions in the haystack, VEX stops search whenever the end of the needle is found. As it starts with assuming "no hit found", all search results will be false.
In contrast to that, according to table 4-3 in the SDM, the real pcmpistri
starts with the assumption "hit found".

Patch, which makes the test case of this bug report work
(needs also be changed for the _wide variant):

--- a/VEX/priv/guest_generic_x87.c
+++ b/VEX/priv/guest_generic_x87.c
@@ -891,7 +891,7 @@ Bool compute_PCMPxSTRx ( /*OUT*/V128* resV,
       UInt ni, hi;
       UChar* argL = (UChar*)argLV;
       UChar* argR = (UChar*)argRV;
- UInt boolRes = 0;
+ UInt boolRes = 0xFFFF;
       UInt validL = ~(zmaskL | -zmaskL); // not(left(zmaskL))
       UInt validR = ~(zmaskR | -zmaskR); // not(left(zmaskR))
       for (hi = 0; hi < 16; hi++) {
@@ -905,7 +905,7 @@ Bool compute_PCMPxSTRx ( /*OUT*/V128* resV,
             if (i >= 16) break;
             if (argL[i] != argR[ni]) { m = 0; break; }
          }
- boolRes |= (m << hi);
+ if (m==0) boolRes &= ~(1 << hi);
       }

Of course it would be nice to add some test cases.