From: Julian Seward Date: Mon, 17 Sep 2012 18:00:06 +0000 (+0000) Subject: Merge from trunk, r2532 (AMD64: Fix PCMPxSTRx variant $0x46, #306664) X-Git-Tag: svn/VALGRIND_3_8_1^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3056b800cc94b04b7d6cb1d8ee5f6b69b086a4b;p=thirdparty%2Fvalgrind.git Merge from trunk, r2532 (AMD64: Fix PCMPxSTRx variant $0x46, #306664) git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_8_BRANCH@2536 --- diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index 39a6ae5790..b690e5e6fa 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -16919,6 +16919,7 @@ static Long dis_PCMPxSTRx ( VexAbiInfo* vbi, Prefix pfx, case 0x00: case 0x02: case 0x08: case 0x0A: case 0x0C: case 0x12: case 0x1A: case 0x38: case 0x3A: case 0x44: case 0x4A: + case 0x46: break; case 0x01: // the 16-bit character versions of the above case 0x03: case 0x09: case 0x0B: case 0x0D: case 0x13: diff --git a/VEX/priv/guest_generic_x87.c b/VEX/priv/guest_generic_x87.c index 0e9741447b..b4ed0345ef 100644 --- a/VEX/priv/guest_generic_x87.c +++ b/VEX/priv/guest_generic_x87.c @@ -798,6 +798,7 @@ Bool compute_PCMPxSTRx ( /*OUT*/V128* resV, case 0x00: case 0x02: case 0x08: case 0x0A: case 0x0C: case 0x12: case 0x1A: case 0x38: case 0x3A: case 0x44: case 0x4A: + case 0x46: break; default: return False; @@ -960,6 +961,46 @@ Bool compute_PCMPxSTRx ( /*OUT*/V128* resV, return True; } + /*----------------------------------------*/ + /*-- ranges, signed byte data --*/ + /*----------------------------------------*/ + + if (agg == 1/*ranges*/ + && fmt == 2/*sb*/) { + + /* 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 + compute_PCMPxSTRx_gen_output( + resV, resOSZACP, + intRes1, zmaskL, zmaskR, validL, pol, idx, isxSTRM + ); + + return True; + } + return False; }