~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to VEX/priv/guest-x86/ghelpers.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-06-26 00:17:17 UTC
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: james.westby@ubuntu.com-20060626001717-qi51nzty57cb12q6
Tags: upstream-3.2.0
Import upstream version 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   This file is part of LibVEX, a library for dynamic binary
11
11
   instrumentation and translation.
12
12
 
13
 
   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.
 
13
   Copyright (C) 2004-2006 OpenWorks LLP.  All rights reserved.
14
14
 
15
15
   This library is made available under a dual licensing scheme.
16
16
 
743
743
   return eflags;
744
744
}
745
745
 
 
746
/* VISIBLE TO LIBVEX CLIENT */
 
747
void
 
748
LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
 
749
                              /*MOD*/VexGuestX86State* vex_state )
 
750
{
 
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
 
756
                 );
 
757
   if (new_carry_flag & 1) {
 
758
      oszacp |= X86G_CC_MASK_C;
 
759
   } else {
 
760
      oszacp &= ~X86G_CC_MASK_C;
 
761
   }
 
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;
 
766
}
 
767
 
746
768
 
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. */
755
777
 
756
 
static Bool isU32 ( IRExpr* e, UInt n )
 
778
static inline Bool isU32 ( IRExpr* e, UInt n )
757
779
{
758
780
   return 
759
781
      toBool( e->tag == Iex_Const
856
878
      /*---------------- SUBW ----------------*/
857
879
 
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), 
882
904
      }
883
905
 
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))));
892
914
      }
893
915
 
 
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) 
 
919
                                         --> test dst <s 0
 
920
                                         --> (UInt)dst[7] 
 
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)),
 
928
                      mkU32(1));
 
929
      }
 
930
 
894
931
      /*---------------- LOGICL ----------------*/
895
932
 
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)));
899
936
      }
900
937
 
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)));
904
941
      }
905
942
 
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)));
923
960
      }
924
961
 
 
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)),
 
967
                      mkU32(1));
 
968
      }
 
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,
 
973
                binop(Iop_And32,
 
974
                      binop(Iop_Shr32,cc_dep1,mkU8(31)),
 
975
                      mkU32(1)),
 
976
                mkU32(1));
 
977
      }
 
978
 
925
979
      /*---------------- LOGICW ----------------*/
926
980
 
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)), 
931
985
                                        mkU32(0)));
932
986
      }
933
987
 
 
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)),
 
993
                      mkU32(1));
 
994
      }
 
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] */
 
999
      //   vassert(0+0);
 
1000
      //   return binop(Iop_Xor32,
 
1001
      //          binop(Iop_And32,
 
1002
      //                binop(Iop_Shr32,cc_dep1,mkU8(15)),
 
1003
      //                mkU32(1)),
 
1004
      //          mkU32(1));
 
1005
      //}
 
1006
 
934
1007
      /*---------------- LOGICB ----------------*/
935
1008
 
936
1009
      if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) {
940
1013
                                        mkU32(0)));
941
1014
      }
942
1015
 
 
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)), 
 
1022
                                        mkU32(0)));
 
1023
      }
 
1024
 
 
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)),
 
1035
                      mkU32(1));
 
1036
      }
 
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,
 
1041
                binop(Iop_And32,
 
1042
                      binop(Iop_Shr32,cc_dep1,mkU8(7)),
 
1043
                      mkU32(1)),
 
1044
                mkU32(1));
 
1045
      }
 
1046
 
943
1047
      /*---------------- DECL ----------------*/
944
1048
 
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)));
953
1057
      }
954
1058
 
 
1059
      /*---------------- INCW ----------------*/
 
1060
 
 
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,
 
1065
                     binop(Iop_CmpEQ32, 
 
1066
                           binop(Iop_Shl32,cc_dep1,mkU8(16)),
 
1067
                           mkU32(0)));
 
1068
      }
 
1069
 
955
1070
      /*---------------- SHRL ----------------*/
956
1071
 
957
1072
      if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) {
1243
1358
}
1244
1359
 
1245
1360
 
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
1250
 
   otherwise. */
1251
 
ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp )
1252
 
{
1253
 
   ULong  uSig;
1254
 
   Long   sSig;
1255
 
   Double dSig, dExp;
1256
 
   Int    sExp, i;
1257
 
   UInt   sign;
1258
 
 
1259
 
   /*
1260
 
    S  7FF    0------0   infinity
1261
 
    S  7FF    0X-----X   snan
1262
 
    S  7FF    1X-----X   qnan
1263
 
   */
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;
1272
 
 
1273
 
   /* Mimic PIII behaviour for special cases. */
1274
 
   if (arg == posInf)
1275
 
      return getExp ? posInf : posInf;
1276
 
   if (arg == negInf)
1277
 
      return getExp ? posInf : negInf;
1278
 
   if ((arg & nanMask) == nanMask)
1279
 
      return qNan;
1280
 
   if (arg == posZero)
1281
 
      return getExp ? negInf : posZero;
1282
 
   if (arg == negZero)
1283
 
      return getExp ? negInf : negZero;
1284
 
 
1285
 
   /* Split into sign, exponent and significand. */
1286
 
   sign = ((UInt)(arg >> 63)) & 1;
1287
 
 
1288
 
   /* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
1289
 
   uSig = arg & (bit52 - 1);
1290
 
 
1291
 
   /* Get the exponent. */
1292
 
   sExp = ((Int)(arg >> 52)) & 0x7FF;
1293
 
 
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.
1298
 
   */
1299
 
   if (sExp == 0) {
1300
 
      for (i = 0; i < 52; i++) {
1301
 
         if (uSig & bit51)
1302
 
            break;
1303
 
         uSig <<= 1;
1304
 
         sExp--;
1305
 
      }
1306
 
      uSig <<= 1;
1307
 
   } else {
1308
 
      /* Add the implied leading-1 in the significand. */
1309
 
      uSig |= bit52;
1310
 
   }
1311
 
 
1312
 
   /* Roll in the sign. */
1313
 
   sSig = uSig;
1314
 
   if (sign) sSig =- sSig;
1315
 
 
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 */
1322
 
 
1323
 
   /* Convert exp into a double.  Also an exact conversion. */
1324
 
   dExp = (Double)(sExp - 1023);
1325
 
 
1326
 
   return *(ULong*)(getExp ? &dExp : &dSig);
1327
 
}
1328
 
 
1329
 
 
1330
1361
/*----------------------------------------------*/
1331
1362
/*--- The exported fns ..                    ---*/
1332
1363
/*----------------------------------------------*/
1442
1473
{
1443
1474
   Int        stno, preg;
1444
1475
   UInt       tag;
1445
 
   Double*    vexRegs = (Double*)(&vex_state->guest_FPREG[0]);
 
1476
   ULong*     vexRegs = (ULong*)(&vex_state->guest_FPREG[0]);
1446
1477
   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);
1447
1478
   Fpu_State* x87     = (Fpu_State*)x87_state;
1448
1479
   UInt       ftop    = (x87->env[FP_ENV_STAT] >> 11) & 7;
1464
1495
            of sync, in that it thinks all FP registers are defined by
1465
1496
            this helper, but in reality some have not been updated. */
1466
1497
         if (moveRegs)
1467
 
            vexRegs[preg] = 0.0;
 
1498
            vexRegs[preg] = 0; /* IEEE754 64-bit zero */
1468
1499
         vexTags[preg] = 0;
1469
1500
      } else {
1470
1501
         /* register is non-empty */
1502
1533
{
1503
1534
   Int        i, stno, preg;
1504
1535
   UInt       tagw;
1505
 
   Double*    vexRegs = (Double*)(&vex_state->guest_FPREG[0]);
 
1536
   ULong*     vexRegs = (ULong*)(&vex_state->guest_FPREG[0]);
1506
1537
   UChar*     vexTags = (UChar*)(&vex_state->guest_FPTAG[0]);
1507
1538
   Fpu_State* x87     = (Fpu_State*)x87_state;
1508
1539
   UInt       ftop    = vex_state->guest_FTOP;
2225
2256
   /* SSE2 has a 'clflush' cache-line-invalidator which uses these. */
2226
2257
   vex_state->guest_TISTART = 0;
2227
2258
   vex_state->guest_TILEN   = 0;
 
2259
 
 
2260
   vex_state->guest_NRADDR = 0;
2228
2261
}
2229
2262
 
2230
2263