⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_generic_x87.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      }      return;   }   /* It's not a zero, denormal, infinity or nan.  So it must be a      normalised number.  Rebias the exponent and build the new      number.  */   bexp += (16383 - 1023);   f80[9] = toUChar( (sign << 7) | ((bexp >> 8) & 0xFF) );   f80[8] = toUChar( bexp & 0xFF );   f80[7] = toUChar( (1 << 7) | ((f64[6] << 3) & 0x78)                               | ((f64[5] >> 5) & 7) );   f80[6] = toUChar( ((f64[5] << 3) & 0xF8) | ((f64[4] >> 5) & 7) );   f80[5] = toUChar( ((f64[4] << 3) & 0xF8) | ((f64[3] >> 5) & 7) );   f80[4] = toUChar( ((f64[3] << 3) & 0xF8) | ((f64[2] >> 5) & 7) );   f80[3] = toUChar( ((f64[2] << 3) & 0xF8) | ((f64[1] >> 5) & 7) );   f80[2] = toUChar( ((f64[1] << 3) & 0xF8) | ((f64[0] >> 5) & 7) );   f80[1] = toUChar( ((f64[0] << 3) & 0xF8) );   f80[0] = toUChar( 0 );}/* Convert an x87 extended double (80-bit) into an IEEE 754 double   (64-bit), mimicking the hardware fairly closely.  Both numbers are   stored little-endian.  Limitations, both of which could be fixed,   given some level of hassle:   * Rounding following truncation could be a bit better.   * Identity of NaNs is not preserved.   See comments in the code for more details.*/void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 ){   Bool  isInf;   Int   bexp, i, j;   UChar sign;   sign = toUChar((f80[9] >> 7) & 1);   bexp = (((UInt)f80[9]) << 8) | (UInt)f80[8];   bexp &= 0x7FFF;   /* If the exponent is zero, either we have a zero or a denormal.      But an extended precision denormal becomes a double precision      zero, so in either case, just produce the appropriately signed      zero. */   if (bexp == 0) {      f64[7] = toUChar(sign << 7);      f64[6] = f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;      return;   }      /* If the exponent is 7FFF, this is either an Infinity, a SNaN or      QNaN, as determined by examining bits 62:0, thus:          0  ... 0    Inf          0X ... X    SNaN          1X ... X    QNaN      where at least one of the Xs is not zero.   */   if (bexp == 0x7FFF) {      isInf = toBool(                 (f80[7] & 0x7F) == 0                  && f80[6] == 0 && f80[5] == 0 && f80[4] == 0                  && f80[3] == 0 && f80[2] == 0 && f80[1] == 0                  && f80[0] == 0              );      if (isInf) {         if (0 == (f80[7] & 0x80))            goto wierd_NaN;         /* Produce an appropriately signed infinity:            S 1--1 (11)  0--0 (52)         */         f64[7] = toUChar((sign << 7) | 0x7F);         f64[6] = 0xF0;         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;         return;      }      /* So it's either a QNaN or SNaN.  Distinguish by considering         bit 62.  Note, this destroys all the trailing bits         (identity?) of the NaN.  IEEE754 doesn't require preserving         these (it only requires that there be one QNaN value and one         SNaN value), but x87 does seem to have some ability to         preserve them.  Anyway, here, the NaN's identity is         destroyed.  Could be improved. */      if (f80[8] & 0x40) {         /* QNaN.  Make a QNaN:            S 1--1 (11)  1  1--1 (51)          */         f64[7] = toUChar((sign << 7) | 0x7F);         f64[6] = 0xFF;         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0xFF;      } else {         /* SNaN.  Make a SNaN:            S 1--1 (11)  0  1--1 (51)          */         f64[7] = toUChar((sign << 7) | 0x7F);         f64[6] = 0xF7;         f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0xFF;      }      return;   }   /* If it's not a Zero, NaN or Inf, and the integer part (bit 62) is      zero, the x87 FPU appears to consider the number denormalised      and converts it to a QNaN. */   if (0 == (f80[7] & 0x80)) {      wierd_NaN:      /* Strange hardware QNaN:         S 1--1 (11)  1  0--0 (51)       */      /* On a PIII, these QNaNs always appear with sign==1.  I have         no idea why. */      f64[7] = (1 /*sign*/ << 7) | 0x7F;      f64[6] = 0xF8;      f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;      return;   }   /* It's not a zero, denormal, infinity or nan.  So it must be a       normalised number.  Rebias the exponent and consider. */   bexp -= (16383 - 1023);   if (bexp >= 0x7FF) {      /* It's too big for a double.  Construct an infinity. */      f64[7] = toUChar((sign << 7) | 0x7F);      f64[6] = 0xF0;      f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;      return;   }   if (bexp <= 0) {      /* It's too small for a normalised double.  First construct a         zero and then see if it can be improved into a denormal.  */      f64[7] = toUChar(sign << 7);      f64[6] = f64[5] = f64[4] = f64[3] = f64[2] = f64[1] = f64[0] = 0;      if (bexp < -52)         /* Too small even for a denormal. */         return;      /* Ok, let's make a denormal.  Note, this is SLOW. */      /* Copy bits 63, 62, 61, etc of the src mantissa into the dst,          indexes 52+bexp, 51+bexp, etc, until k+bexp < 0. */      /* bexp is in range -52 .. 0 inclusive */      for (i = 63; i >= 0; i--) {         j = i - 12 + bexp;         if (j < 0) break;         /* We shouldn't really call vassert from generated code. */         vassert(j >= 0 && j < 52);         write_bit_array ( f64,                           j,                           read_bit_array ( f80, i ) );      }      /* and now we might have to round ... */      if (read_bit_array(f80, 10+1 - bexp) == 1)          goto do_rounding;      return;   }   /* Ok, it's a normalised number which is representable as a double.      Copy the exponent and mantissa into place. */   /*   for (i = 0; i < 52; i++)      write_bit_array ( f64,                        i,                        read_bit_array ( f80, i+11 ) );   */   f64[0] = toUChar( (f80[1] >> 3) | (f80[2] << 5) );   f64[1] = toUChar( (f80[2] >> 3) | (f80[3] << 5) );   f64[2] = toUChar( (f80[3] >> 3) | (f80[4] << 5) );   f64[3] = toUChar( (f80[4] >> 3) | (f80[5] << 5) );   f64[4] = toUChar( (f80[5] >> 3) | (f80[6] << 5) );   f64[5] = toUChar( (f80[6] >> 3) | (f80[7] << 5) );   f64[6] = toUChar( ((bexp << 4) & 0xF0) | ((f80[7] >> 3) & 0x0F) );   f64[7] = toUChar( (sign << 7) | ((bexp >> 4) & 0x7F) );   /* Now consider any rounding that needs to happen as a result of      truncating the mantissa. */   if (f80[1] & 4) /* read_bit_array(f80, 10) == 1) */ {      /* If the bottom bits of f80 are "100 0000 0000", then the         infinitely precise value is deemed to be mid-way between the         two closest representable values.  Since we're doing         round-to-nearest (the default mode), in that case it is the         bit immediately above which indicates whether we should round         upwards or not -- if 0, we don't.  All that is encapsulated         in the following simple test. */      if ((f80[1] & 0xF) == 4/*0100b*/ && f80[0] == 0)         return;      do_rounding:      /* Round upwards.  This is a kludge.  Once in every 2^24         roundings (statistically) the bottom three bytes are all 0xFF         and so we don't round at all.  Could be improved. */      if (f64[0] != 0xFF) {          f64[0]++;       }      else       if (f64[0] == 0xFF && f64[1] != 0xFF) {         f64[0] = 0;         f64[1]++;      }      else            if (f64[0] == 0xFF && f64[1] == 0xFF && f64[2] != 0xFF) {         f64[0] = 0;         f64[1] = 0;         f64[2]++;      }      /* else we don't round, but we should. */   }}/*---------------------------------------------------------------*//*--- end                       guest-generic/h_generic_x87.c ---*//*---------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -