10
10
This file is part of LibVEX, a library for dynamic binary
11
11
instrumentation and translation.
13
Copyright (C) 2004-2005 OpenWorks LLP. All rights reserved.
13
Copyright (C) 2004-2006 OpenWorks LLP. All rights reserved.
15
15
This library is made available under a dual licensing scheme.
746
/* VISIBLE TO LIBVEX CLIENT */
748
LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
749
/*MOD*/VexGuestX86State* vex_state )
751
UInt oszacp = x86g_calculate_eflags_all_WRK(
752
vex_state->guest_CC_OP,
753
vex_state->guest_CC_DEP1,
754
vex_state->guest_CC_DEP2,
755
vex_state->guest_CC_NDEP
757
if (new_carry_flag & 1) {
758
oszacp |= X86G_CC_MASK_C;
760
oszacp &= ~X86G_CC_MASK_C;
762
vex_state->guest_CC_OP = X86G_CC_OP_COPY;
763
vex_state->guest_CC_DEP1 = oszacp;
764
vex_state->guest_CC_DEP2 = 0;
765
vex_state->guest_CC_NDEP = 0;
747
769
/*---------------------------------------------------------------*/
748
770
/*--- %eflags translation-time function specialisers. ---*/
753
775
/* Used by the optimiser to try specialisations. Returns an
754
776
equivalent expression, or NULL if none. */
756
static Bool isU32 ( IRExpr* e, UInt n )
778
static inline Bool isU32 ( IRExpr* e, UInt n )
759
781
toBool( e->tag == Iex_Const
856
878
/*---------------- SUBW ----------------*/
858
880
if (isU32(cc_op, X86G_CC_OP_SUBW) && isU32(cond, X86CondZ)) {
859
/* byte sub/cmp, then Z --> test dst==src */
881
/* word sub/cmp, then Z --> test dst==src */
860
882
return unop(Iop_1Uto32,
861
883
binop(Iop_CmpEQ16,
862
884
unop(Iop_32to16,cc_dep1),
884
906
if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondNBE)) {
885
/* long sub/cmp, then NBE (unsigned greater than)
886
--> test src <=u dst */
907
/* byte sub/cmp, then NBE (unsigned greater than)
908
--> test src <u dst */
887
909
/* Note, args are opposite way round from the usual */
888
910
return unop(Iop_1Uto32,
889
911
binop(Iop_CmpLT32U,
891
913
binop(Iop_And32,cc_dep1,mkU32(0xFF))));
916
if (isU32(cc_op, X86G_CC_OP_SUBB) && isU32(cond, X86CondS)
917
&& isU32(cc_dep2, 0)) {
918
/* byte sub/cmp of zero, then S --> test (dst-0 <s 0)
921
This is yet another scheme by which gcc figures out if the
922
top bit of a byte is 1 or 0. See also LOGICB/CondS below. */
923
/* Note: isU32(cc_dep2, 0) is correct, even though this is
924
for an 8-bit comparison, since the args to the helper
925
function are always U32s. */
926
return binop(Iop_And32,
927
binop(Iop_Shr32,cc_dep1,mkU8(7)),
894
931
/*---------------- LOGICL ----------------*/
896
933
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondZ)) {
898
935
return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
901
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) {
902
/* long and/or/xor, then S --> test dst <s 0 */
903
return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0)));
938
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNZ)) {
939
/* long and/or/xor, then NZ --> test dst!=0 */
940
return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0)));
906
943
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondLE)) {
922
959
return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
962
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) {
963
/* see comment below for (LOGICB, CondS) */
964
/* long and/or/xor, then S --> (UInt)result[31] */
965
return binop(Iop_And32,
966
binop(Iop_Shr32,cc_dep1,mkU8(31)),
969
if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNS)) {
970
/* see comment below for (LOGICB, CondNS) */
971
/* long and/or/xor, then S --> (UInt) ~ result[31] */
972
return binop(Iop_Xor32,
974
binop(Iop_Shr32,cc_dep1,mkU8(31)),
925
979
/*---------------- LOGICW ----------------*/
927
981
if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) {
928
/* byte and/or/xor, then Z --> test dst==0 */
982
/* word and/or/xor, then Z --> test dst==0 */
929
983
return unop(Iop_1Uto32,
930
984
binop(Iop_CmpEQ32, binop(Iop_And32,cc_dep1,mkU32(0xFFFF)),
988
if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondS)) {
989
/* see comment below for (LOGICB, CondS) */
990
/* word and/or/xor, then S --> (UInt)result[15] */
991
return binop(Iop_And32,
992
binop(Iop_Shr32,cc_dep1,mkU8(15)),
995
//Probably correct, but no test case for it yet found
996
//if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondNS)) {
997
// /* see comment below for (LOGICB, CondNS) */
998
// /* word and/or/xor, then S --> (UInt) ~ result[15] */
1000
// return binop(Iop_Xor32,
1002
// binop(Iop_Shr32,cc_dep1,mkU8(15)),
934
1007
/*---------------- LOGICB ----------------*/
936
1009
if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) {
1016
if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNZ)) {
1017
/* byte and/or/xor, then Z --> test dst!=0 */
1018
/* b9ac9: 84 c0 test %al,%al
1019
b9acb: 75 0d jne b9ada */
1020
return unop(Iop_1Uto32,
1021
binop(Iop_CmpNE32, binop(Iop_And32,cc_dep1,mkU32(255)),
1025
if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondS)) {
1026
/* this is an idiom gcc sometimes uses to find out if the top
1027
bit of a byte register is set: eg testb %al,%al; js ..
1028
Since it just depends on the top bit of the byte, extract
1029
that bit and explicitly get rid of all the rest. This
1030
helps memcheck avoid false positives in the case where any
1031
of the other bits in the byte are undefined. */
1032
/* byte and/or/xor, then S --> (UInt)result[7] */
1033
return binop(Iop_And32,
1034
binop(Iop_Shr32,cc_dep1,mkU8(7)),
1037
if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNS)) {
1038
/* ditto, for negation-of-S. */
1039
/* byte and/or/xor, then S --> (UInt) ~ result[7] */
1040
return binop(Iop_Xor32,
1042
binop(Iop_Shr32,cc_dep1,mkU8(7)),
943
1047
/*---------------- DECL ----------------*/
945
1049
if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondZ)) {
952
1056
return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0)));
1059
/*---------------- INCW ----------------*/
1061
if (isU32(cc_op, X86G_CC_OP_INCW) && isU32(cond, X86CondZ)) {
1062
/* This rewrite helps memcheck on 'incw %ax ; je ...'. */
1063
/* inc W, then Z --> test dst == 0 */
1064
return unop(Iop_1Uto32,
1066
binop(Iop_Shl32,cc_dep1,mkU8(16)),
955
1070
/*---------------- SHRL ----------------*/
957
1072
if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) {
1246
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
1247
/* Extract the signed significand or exponent component as per
1248
fxtract. Arg and result are doubles travelling under the guise of
1249
ULongs. Returns significand when getExp is zero and exponent
1251
ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp )
1260
S 7FF 0------0 infinity
1264
const ULong posInf = 0x7FF0000000000000ULL;
1265
const ULong negInf = 0xFFF0000000000000ULL;
1266
const ULong nanMask = 0x7FF0000000000000ULL;
1267
const ULong qNan = 0x7FF8000000000000ULL;
1268
const ULong posZero = 0x0000000000000000ULL;
1269
const ULong negZero = 0x8000000000000000ULL;
1270
const ULong bit51 = 1ULL << 51;
1271
const ULong bit52 = 1ULL << 52;
1273
/* Mimic PIII behaviour for special cases. */
1275
return getExp ? posInf : posInf;
1277
return getExp ? posInf : negInf;
1278
if ((arg & nanMask) == nanMask)
1281
return getExp ? negInf : posZero;
1283
return getExp ? negInf : negZero;
1285
/* Split into sign, exponent and significand. */
1286
sign = ((UInt)(arg >> 63)) & 1;
1288
/* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
1289
uSig = arg & (bit52 - 1);
1291
/* Get the exponent. */
1292
sExp = ((Int)(arg >> 52)) & 0x7FF;
1294
/* Deal with denormals: if the exponent is zero, then the
1295
significand cannot possibly be zero (negZero/posZero are handled
1296
above). Shift the significand left until bit 51 of it becomes
1297
1, and decrease the exponent accordingly.
1300
for (i = 0; i < 52; i++) {
1308
/* Add the implied leading-1 in the significand. */
1312
/* Roll in the sign. */
1314
if (sign) sSig =- sSig;
1316
/* Convert sig into a double. This should be an exact conversion.
1317
Then divide by 2^52, which should give a value in the range 1.0
1318
to 2.0-epsilon, at least for normalised args. */
1319
dSig = (Double)sSig;
1320
dSig /= 67108864.0; /* 2^26 */
1321
dSig /= 67108864.0; /* 2^26 */
1323
/* Convert exp into a double. Also an exact conversion. */
1324
dExp = (Double)(sExp - 1023);
1326
return *(ULong*)(getExp ? &dExp : &dSig);
1330
1361
/*----------------------------------------------*/
1331
1362
/*--- The exported fns .. ---*/
1332
1363
/*----------------------------------------------*/