Lines 7325-7330
Link Here
|
7325 |
|
7325 |
|
7326 |
|
7326 |
|
7327 |
|
7327 |
|
|
|
7328 |
/* Handle LZCNT in terms of BSR */ |
7329 |
static |
7330 |
ULong dis_LZCNT ( VexAbiInfo* vbi, |
7331 |
Prefix pfx, Int sz, Long delta) |
7332 |
{ |
7333 |
Bool isReg; |
7334 |
UChar modrm; |
7335 |
HChar dis_buf[50]; |
7336 |
|
7337 |
IRType ty = szToITy(sz); |
7338 |
IRTemp src = newTemp(ty); |
7339 |
IRTemp dst = newTemp(ty); |
7340 |
IRTemp src64 = newTemp(Ity_I64); |
7341 |
IRTemp dst64 = newTemp(Ity_I64); |
7342 |
IRTemp src8 = newTemp(Ity_I8); |
7343 |
IRTemp dst8 = newTemp(Ity_I8); |
7344 |
|
7345 |
vassert(sz == 8 || sz == 4 || sz == 2); |
7346 |
|
7347 |
ULong maxbit = 8 * sz -1; |
7348 |
|
7349 |
modrm = getUChar(delta); |
7350 |
isReg = epartIsReg(modrm); |
7351 |
if (isReg) { |
7352 |
delta++; |
7353 |
assign( src, getIRegE(sz, pfx, modrm) ); |
7354 |
} else { |
7355 |
Int len; |
7356 |
IRTemp addr = disAMode( &len, vbi, pfx, delta, dis_buf, 0 ); |
7357 |
delta += len; |
7358 |
assign( src, loadLE(ty, mkexpr(addr)) ); |
7359 |
} |
7360 |
|
7361 |
DIP("lzcnt %s, %s\n", |
7362 |
( isReg ? nameIRegE(sz, pfx, modrm) : dis_buf ), |
7363 |
nameIRegG(sz, pfx, modrm)); |
7364 |
|
7365 |
/* First, widen src to 64 bits if it is not already. */ |
7366 |
assign( src64, widenUto64(mkexpr(src)) ); |
7367 |
|
7368 |
/* make a zero expression iff src64 is zero */ |
7369 |
assign( src8, |
7370 |
unop(Iop_1Uto8, |
7371 |
binop(Iop_CmpNE64, |
7372 |
mkexpr(src64), mkU64(0))) ); |
7373 |
|
7374 |
/* clean all flags */ |
7375 |
stmt( IRStmt_Put( OFFB_CC_OP, mkU64(AMD64G_CC_OP_COPY) )); |
7376 |
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) )); |
7377 |
|
7378 |
|
7379 |
/* Hack: Execute the operation by using BSR |
7380 |
Iff the input value is zero, store the size of |
7381 |
the operant in the |
7382 |
result. otherwise store sieof(src)-1-BSR(src). |
7383 |
*/ |
7384 |
assign( dst64, |
7385 |
IRExpr_Mux0X( |
7386 |
mkexpr(src8), |
7387 |
/* src == 0 -- set result to width of src */ |
7388 |
mkU64(8 * sz), |
7389 |
/* src != 0 */ |
7390 |
binop(Iop_Sub64, |
7391 |
mkU64(maxbit), |
7392 |
binop(Iop_Sub64, |
7393 |
mkU64(63), |
7394 |
unop(Iop_Clz64, mkexpr(src64))) |
7395 |
) |
7396 |
) |
7397 |
); |
7398 |
|
7399 |
assign( dst8, |
7400 |
unop(Iop_1Uto8, |
7401 |
binop(Iop_CmpNE64, |
7402 |
mkexpr(dst64), mkU64(0))) ); |
7403 |
|
7404 |
/* set c flag if src is zero and z flag if dst is zero */ |
7405 |
stmt( IRStmt_Put( |
7406 |
OFFB_CC_DEP1, |
7407 |
binop(Iop_Or64, |
7408 |
IRExpr_Mux0X( |
7409 |
mkexpr(src8), |
7410 |
/* src==0 */ |
7411 |
mkU64(AMD64G_CC_MASK_C), |
7412 |
/* src!=0 */ |
7413 |
mkU64(0) |
7414 |
), |
7415 |
IRExpr_Mux0X( |
7416 |
mkexpr(dst8), |
7417 |
/* dst==0 */ |
7418 |
mkU64(AMD64G_CC_MASK_Z), |
7419 |
/* dst!=0 */ |
7420 |
mkU64(0) |
7421 |
) |
7422 |
) |
7423 |
) |
7424 |
); |
7425 |
|
7426 |
|
7427 |
if (sz == 2) |
7428 |
assign( dst, unop(Iop_64to16, mkexpr(dst64)) ); |
7429 |
else |
7430 |
if (sz == 4) |
7431 |
assign( dst, unop(Iop_64to32, mkexpr(dst64)) ); |
7432 |
else |
7433 |
assign( dst, mkexpr(dst64) ); |
7434 |
|
7435 |
/* dump result back */ |
7436 |
putIRegG( sz, pfx, modrm, mkexpr(dst) ); |
7437 |
|
7438 |
return delta; |
7439 |
} |
7440 |
|
7441 |
|
7328 |
/* Handle BSF/BSR. Only v-size seems necessary. */ |
7442 |
/* Handle BSF/BSR. Only v-size seems necessary. */ |
7329 |
static |
7443 |
static |
7330 |
ULong dis_bs_E_G ( VexAbiInfo* vbi, |
7444 |
ULong dis_bs_E_G ( VexAbiInfo* vbi, |
Lines 15348-15356
Link Here
|
15348 |
if (haveF2orF3(pfx)) goto decode_failure; |
15462 |
if (haveF2orF3(pfx)) goto decode_failure; |
15349 |
delta = dis_bs_E_G ( vbi, pfx, sz, delta, True ); |
15463 |
delta = dis_bs_E_G ( vbi, pfx, sz, delta, True ); |
15350 |
break; |
15464 |
break; |
15351 |
case 0xBD: /* BSR Gv,Ev */ |
15465 |
case 0xBD: |
15352 |
if (haveF2orF3(pfx)) goto decode_failure; |
15466 |
if (haveF3(pfx)) |
15353 |
delta = dis_bs_E_G ( vbi, pfx, sz, delta, False ); |
15467 |
delta = dis_LZCNT ( vbi, pfx, sz, delta ); |
|
|
15468 |
else if (haveF2(pfx)) |
15469 |
goto decode_failure; |
15470 |
else |
15471 |
/* BSR Gv,Ev */ |
15472 |
delta = dis_bs_E_G ( vbi, pfx, sz, delta, False ); |
15354 |
break; |
15473 |
break; |
15355 |
|
15474 |
|
15356 |
/* =-=-=-=-=-=-=-=-=- BSWAP -=-=-=-=-=-=-=-=-=-=-= */ |
15475 |
/* =-=-=-=-=-=-=-=-=- BSWAP -=-=-=-=-=-=-=-=-=-=-= */ |