mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
eda9127c26
36 changed files with 3492 additions and 1126 deletions
|
@ -223,7 +223,6 @@ double FloatFormat::getHostFloat(uintb encoding,floatclass *type) const
|
|||
if (exp == 0) {
|
||||
if ( frac == 0 ) { // Floating point zero
|
||||
*type = zero;
|
||||
// FIXME: add on sign-bit for +0 or -0 allowed by standard
|
||||
return sgn ? -0.0 : +0.0;
|
||||
}
|
||||
*type = denormalized;
|
||||
|
@ -233,7 +232,6 @@ double FloatFormat::getHostFloat(uintb encoding,floatclass *type) const
|
|||
else if (exp == maxexponent) {
|
||||
if ( frac == 0 ) { // Floating point infinity
|
||||
*type = infinity;
|
||||
// FIXME: add on sign-bit for +inf or -inf allowed by standard
|
||||
return sgn ? -INFINITY : +INFINITY;
|
||||
}
|
||||
*type = nan;
|
||||
|
@ -254,6 +252,27 @@ double FloatFormat::getHostFloat(uintb encoding,floatclass *type) const
|
|||
return createFloat(sgn,frac,exp);
|
||||
}
|
||||
|
||||
/// \brief Round a floating point value to the nearest even
|
||||
///
|
||||
/// \param signif the significant bits of a floating point value
|
||||
/// \param lowbitpos the position in signif of the floating point
|
||||
/// \return true if we rounded up
|
||||
|
||||
bool FloatFormat::roundToNearestEven(uintb &signif, int4 lowbitpos)
|
||||
|
||||
{
|
||||
uintb lowbitmask = (lowbitpos < 8 * sizeof(uintb)) ? (1UL << lowbitpos) : 0;
|
||||
uintb midbitmask = 1UL << (lowbitpos - 1);
|
||||
uintb epsmask = midbitmask - 1;
|
||||
bool odd = (signif & lowbitmask) != 0;
|
||||
if ((signif & midbitmask) != 0 && ((signif & epsmask) != 0 || odd)) {
|
||||
signif += midbitmask;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// \param host is the double value to convert
|
||||
/// \return the equivalent encoded value
|
||||
uintb FloatFormat::getEncoding(double host) const
|
||||
|
@ -264,7 +283,7 @@ uintb FloatFormat::getEncoding(double host) const
|
|||
uintb signif;
|
||||
int4 exp;
|
||||
|
||||
type = extractExpSig(host,&sgn,&signif,&exp);
|
||||
type = extractExpSig(host, &sgn, &signif, &exp);
|
||||
if (type == zero)
|
||||
return getZeroEncoding(sgn);
|
||||
else if (type == infinity)
|
||||
|
@ -274,53 +293,114 @@ uintb FloatFormat::getEncoding(double host) const
|
|||
|
||||
// convert exponent and fractional to their encodings
|
||||
exp += bias;
|
||||
if (exp < 0) // Exponent is too small to represent
|
||||
return getZeroEncoding(sgn);
|
||||
if (exp > maxexponent) // Exponent is too big to represent
|
||||
|
||||
if (exp < -frac_size) // Exponent is too small to represent
|
||||
return getZeroEncoding(sgn); // TODO handle round to non-zero
|
||||
|
||||
if (exp < 1) { // Must be denormalized
|
||||
if (roundToNearestEven(signif, 8 * sizeof(uintb) - frac_size - exp)) {
|
||||
// TODO handle round to normal case
|
||||
if ((signif >> (8 * sizeof(uintb) - 1)) == 0) {
|
||||
signif = 1UL << (8 * sizeof(uintb) - 1);
|
||||
exp += 1;
|
||||
}
|
||||
}
|
||||
uintb res = getZeroEncoding(sgn);
|
||||
return setFractionalCode(res, signif >> (-exp));
|
||||
}
|
||||
|
||||
if (roundToNearestEven(signif, 8 * sizeof(uintb) - frac_size - 1)) {
|
||||
// if high bit is clear, then the add overflowed. Increase exp and set
|
||||
// signif to 1.
|
||||
if ((signif >> (8 * sizeof(uintb) - 1)) == 0) {
|
||||
signif = 1UL << (8 * sizeof(uintb) - 1);
|
||||
exp += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (exp >= maxexponent) // Exponent is too big to represent
|
||||
return getInfinityEncoding(sgn);
|
||||
if (jbitimplied && (exp !=0))
|
||||
|
||||
if (jbitimplied && (exp != 0))
|
||||
signif <<= 1; // Cut off top bit (which should be 1)
|
||||
|
||||
uintb res = 0;
|
||||
res = setFractionalCode(res,signif);
|
||||
res = setExponentCode(res,(uintb)exp);
|
||||
return setSign(res,sgn);
|
||||
res = setFractionalCode(res, signif);
|
||||
res = setExponentCode(res, (uintb)exp);
|
||||
return setSign(res, sgn);
|
||||
}
|
||||
|
||||
|
||||
/// \param encoding is the value in the \e other FloatFormat
|
||||
/// \param formin is the \e other FloatFormat
|
||||
/// \return the equivalent value in \b this FloatFormat
|
||||
uintb FloatFormat::convertEncoding(uintb encoding,const FloatFormat *formin) const
|
||||
uintb FloatFormat::convertEncoding(uintb encoding,
|
||||
const FloatFormat *formin) const
|
||||
|
||||
{
|
||||
bool sgn = formin->extractSign(encoding);
|
||||
uintb frac = formin->extractFractionalCode(encoding);
|
||||
uintb signif = formin->extractFractionalCode(encoding);
|
||||
int4 exp = formin->extractExponentCode(encoding);
|
||||
|
||||
|
||||
if (exp == formin->maxexponent) { // NaN or INFINITY encoding
|
||||
exp = maxexponent;
|
||||
}
|
||||
else {
|
||||
exp -= formin->bias;
|
||||
exp += bias;
|
||||
if (exp < 0)
|
||||
return getZeroEncoding(sgn);
|
||||
if (exp > maxexponent)
|
||||
if (signif != 0)
|
||||
return getNaNEncoding(sgn);
|
||||
else
|
||||
return getInfinityEncoding(sgn);
|
||||
}
|
||||
if (jbitimplied && !formin->jbitimplied)
|
||||
frac <<= 1; // Cut off top bit (which should be 1)
|
||||
else if (formin->jbitimplied && !jbitimplied) {
|
||||
frac >>= 1; // Make room for 1 jbit
|
||||
uintb highbit = 1;
|
||||
highbit <<= 8*sizeof(uintb)-1;
|
||||
frac |= highbit; // Stick bit in at top
|
||||
|
||||
if (exp == 0) { // incoming is subnormal
|
||||
if (signif == 0)
|
||||
return getZeroEncoding(sgn);
|
||||
|
||||
// normalize
|
||||
int4 lz = count_leading_zeros(signif);
|
||||
signif <<= lz;
|
||||
exp = -formin->bias - lz;
|
||||
}
|
||||
else { // incoming is normal
|
||||
exp -= formin->bias;
|
||||
if (jbitimplied)
|
||||
signif = (1UL << (8 * sizeof(uintb) - 1)) | (signif >> 1);
|
||||
}
|
||||
|
||||
exp += bias;
|
||||
|
||||
if (exp < -frac_size) // Exponent is too small to represent
|
||||
return getZeroEncoding(sgn); // TODO handle round to non-zero
|
||||
|
||||
if (exp < 1) { // Must be denormalized
|
||||
if (roundToNearestEven(signif, 8 * sizeof(uintb) - frac_size - exp)) {
|
||||
// TODO handle carry to normal case
|
||||
if ((signif >> (8 * sizeof(uintb) - 1)) == 0) {
|
||||
signif = 1UL << (8 * sizeof(uintb) - 1);
|
||||
exp += 1;
|
||||
}
|
||||
}
|
||||
uintb res = getZeroEncoding(sgn);
|
||||
return setFractionalCode(res, signif >> (-exp));
|
||||
}
|
||||
|
||||
if (roundToNearestEven(signif, 8 * sizeof(uintb) - frac_size - 1)) {
|
||||
// if high bit is clear, then the add overflowed. Increase exp and set
|
||||
// signif to 1.
|
||||
if ((signif >> (8 * sizeof(uintb) - 1)) == 0) {
|
||||
signif = 1UL << (8 * sizeof(uintb) - 1);
|
||||
exp += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (exp >= maxexponent) // Exponent is too big to represent
|
||||
return getInfinityEncoding(sgn);
|
||||
|
||||
if (jbitimplied && (exp != 0))
|
||||
signif <<= 1; // Cut off top bit (which should be 1)
|
||||
|
||||
uintb res = 0;
|
||||
res = setFractionalCode(res,frac);
|
||||
res = setExponentCode(res,(uintb)exp);
|
||||
return setSign(res,sgn);
|
||||
res = setFractionalCode(res, signif);
|
||||
res = setExponentCode(res, (uintb)exp);
|
||||
return setSign(res, sgn);
|
||||
}
|
||||
|
||||
// Currently we emulate floating point operations on the target
|
||||
|
@ -487,9 +567,7 @@ uintb FloatFormat::opInt2Float(uintb a,int4 sizein) const
|
|||
uintb FloatFormat::opFloat2Float(uintb a,const FloatFormat &outformat) const
|
||||
|
||||
{
|
||||
floatclass type;
|
||||
double val = getHostFloat(a,&type);
|
||||
return outformat.getEncoding(val);
|
||||
return outformat.convertEncoding(a, this);
|
||||
}
|
||||
|
||||
/// \param a is an encoded floating-point value
|
||||
|
@ -533,7 +611,8 @@ uintb FloatFormat::opRound(uintb a) const
|
|||
{
|
||||
floatclass type;
|
||||
double val = getHostFloat(a,&type);
|
||||
return getEncoding(floor(val+0.5));
|
||||
// return getEncoding(floor(val+.5)); // round half up
|
||||
return getEncoding(round(val)); // round half away from zero
|
||||
}
|
||||
|
||||
/// Write the format out to a \<floatformat> XML tag.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue