GUI: Implement ToLongDoubleString
This commit is contained in:
parent
f0fc15c96b
commit
6fc3258f01
|
@ -1,11 +1,11 @@
|
|||
#include "RegistersView.h"
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
#include <stdint.h>
|
||||
#include "RegistersView.h"
|
||||
#include "Configuration.h"
|
||||
#include "WordEditDialog.h"
|
||||
#include "LineEditDialog.h"
|
||||
#include "SelectFields.h"
|
||||
#include <QMessageBox>
|
||||
#include <stdint.h>
|
||||
|
||||
void RegistersView::SetChangeButton(QPushButton* push_button)
|
||||
{
|
||||
|
@ -1357,70 +1357,6 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected)
|
|||
return newText;
|
||||
}
|
||||
|
||||
double readFloat80(const uint8_t buffer[10])
|
||||
{
|
||||
/*
|
||||
* WE ARE LOSSING 2 BYTES WITH THIS FUNCTION.
|
||||
* TODO: CHANGE THIS FOR ONE BETTER.
|
||||
*/
|
||||
//80 bit floating point value according to IEEE-754:
|
||||
//1 bit sign, 15 bit exponent, 64 bit mantissa
|
||||
|
||||
const uint16_t SIGNBIT = 1 << 15;
|
||||
const uint16_t EXP_BIAS = (1 << 14) - 1; // 2^(n-1) - 1 = 16383
|
||||
const uint16_t SPECIALEXP = (1 << 15) - 1; // all bits set
|
||||
const uint64_t HIGHBIT = (uint64_t)1 << 63;
|
||||
const uint64_t QUIETBIT = (uint64_t)1 << 62;
|
||||
|
||||
// Extract sign, exponent and mantissa
|
||||
uint16_t exponent = *((uint16_t*)&buffer[8]);
|
||||
uint64_t mantissa = *((uint64_t*)&buffer[0]);
|
||||
|
||||
double sign = (exponent & SIGNBIT) ? -1.0 : 1.0;
|
||||
exponent &= ~SIGNBIT;
|
||||
|
||||
// Check for undefined values
|
||||
if((!exponent && (mantissa & HIGHBIT)) || (exponent && !(mantissa & HIGHBIT)))
|
||||
{
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
// Check for special values (infinity, NaN)
|
||||
if(exponent == 0)
|
||||
{
|
||||
if(mantissa == 0)
|
||||
{
|
||||
return sign * 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// denormalized
|
||||
}
|
||||
}
|
||||
else if(exponent == SPECIALEXP)
|
||||
{
|
||||
if(!(mantissa & ~HIGHBIT))
|
||||
{
|
||||
return sign * std::numeric_limits<double>::infinity();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mantissa & QUIETBIT)
|
||||
{
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::numeric_limits<double>::signaling_NaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//value = (-1)^s * (m / 2^63) * 2^(e - 16383)
|
||||
double significand = ((double)mantissa / ((uint64_t)1 << 63));
|
||||
return sign * ldexp(significand, exponent - EXP_BIAS);
|
||||
}
|
||||
|
||||
QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value)
|
||||
{
|
||||
QString valueText;
|
||||
|
@ -1815,7 +1751,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value)
|
|||
if(DbgIsDebugging() && mRegisterUpdates.contains(reg))
|
||||
p->setPen(ConfigColor("RegistersModifiedColor"));
|
||||
|
||||
newText += QString::number(readFloat80(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->data));
|
||||
newText += ToLongDoubleString(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->data);
|
||||
width = newText.length() * mCharWidth;
|
||||
p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText);
|
||||
}
|
||||
|
@ -2585,15 +2521,13 @@ void RegistersView::setRegisters(REGDUMP* reg)
|
|||
mCip = reg->regcontext.cip;
|
||||
}
|
||||
|
||||
QMap<REGISTER_NAME, QString>::const_iterator it = mRegisterMapping.begin();
|
||||
// iterate all ids (CAX, CBX, ...)
|
||||
while(it != mRegisterMapping.end())
|
||||
for(auto itr = mRegisterMapping.begin(); itr != mRegisterMapping.end(); itr++)
|
||||
{
|
||||
if(CompareRegisters(it.key(), reg, &wCipRegDumpStruct) != 0)
|
||||
mRegisterUpdates.insert(it.key());
|
||||
else if(mRegisterUpdates.contains(it.key())) //registers are equal
|
||||
mRegisterUpdates.remove(it.key());
|
||||
it++;
|
||||
if(CompareRegisters(itr.key(), reg, &wCipRegDumpStruct) != 0)
|
||||
mRegisterUpdates.insert(itr.key());
|
||||
else if(mRegisterUpdates.contains(itr.key())) //registers are equal
|
||||
mRegisterUpdates.remove(itr.key());
|
||||
}
|
||||
|
||||
// now we can save the values
|
||||
|
@ -2604,5 +2538,4 @@ void RegistersView::setRegisters(REGDUMP* reg)
|
|||
|
||||
// force repaint
|
||||
emit refresh();
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "Float128.h"
|
||||
#include "float128.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#include <stdint.h>
|
||||
#include "StringUtil.h"
|
||||
#include "float128.h"
|
||||
|
||||
QString ToLongDoubleString(void* buffer)
|
||||
{
|
||||
// Assumes that "buffer" is 10 bytes at the minimum
|
||||
//
|
||||
// 80-bit floating point precision
|
||||
// https://en.wikipedia.org/wiki/Extended_precision#IEEE_754_extended_precision_formats
|
||||
const uint16_t SIGNBIT = (1 << 15);
|
||||
const uint16_t EXP_BIAS = (1 << 14) - 1; // 2^(n-1) - 1 = 16383
|
||||
const uint64_t HIGHBIT = (uint64_t)1 << 63;
|
||||
const uint64_t QUIETBIT = (uint64_t)1 << 62;
|
||||
|
||||
// Convert to pointer of array of bytes
|
||||
uint8_t* bytes = (uint8_t*)buffer;
|
||||
|
||||
// Extract exponent and mantissa
|
||||
uint16_t exponent = *(uint16_t*)&bytes[8];
|
||||
uint64_t mantissa = *(uint64_t*)&bytes[0];
|
||||
|
||||
// Extract sign
|
||||
bool sign = (exponent & SIGNBIT) != 0;
|
||||
exponent &= ~SIGNBIT;
|
||||
|
||||
switch(exponent)
|
||||
{
|
||||
// Default: exponent is ignored
|
||||
default:
|
||||
break;
|
||||
|
||||
// If exponent zero
|
||||
case 0:
|
||||
{
|
||||
if((mantissa & HIGHBIT) == 0)
|
||||
{
|
||||
if((mantissa & QUIETBIT) == 0)
|
||||
return (sign) ? "-0.0" : "0.0";
|
||||
}
|
||||
|
||||
// Everything else psuedo denormal
|
||||
// (−1)^s * m * 2^−16382
|
||||
}
|
||||
break;
|
||||
|
||||
// If exponent all ones
|
||||
case 0x7FFF:
|
||||
{
|
||||
// if (bit 63 is zero)
|
||||
if((mantissa & HIGHBIT) == 0)
|
||||
{
|
||||
// if (bits 61-0 are zero) infinity;
|
||||
if((mantissa & (QUIETBIT - 1)) == 0)
|
||||
return (sign) ? "-INF" : "INF";
|
||||
|
||||
// else psuedo_nan;
|
||||
return "NAN";
|
||||
}
|
||||
|
||||
// Bit 63 is 1 at this point
|
||||
//
|
||||
// if (bit 62 is not set)
|
||||
if((mantissa & QUIETBIT) == 0)
|
||||
{
|
||||
// if (bits 61-0 are zero) infinity;
|
||||
if((mantissa & (QUIETBIT - 1)) == 0)
|
||||
return (sign) ? "-INF" : "INF";
|
||||
|
||||
// else signalling_nan;
|
||||
return "NAN";
|
||||
}
|
||||
|
||||
// else quiet_nan;
|
||||
return "NAN";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert both numbers to 128 bit types
|
||||
dd_real dd_mantissa((double)mantissa);
|
||||
dd_real dd_divisor((uint64_t)1 << 63);
|
||||
|
||||
// Calculate significand (m) and exponent (e)
|
||||
//
|
||||
// (-1)^s * (m / 2^63) * 2^(e - 16383)
|
||||
dd_real significand = dd_mantissa / dd_divisor;
|
||||
dd_real exp = pown(2, exponent - EXP_BIAS);
|
||||
|
||||
// Calculate final result with sign
|
||||
significand *= exp;
|
||||
|
||||
if(sign)
|
||||
significand *= -1;
|
||||
|
||||
// Print result
|
||||
return QString::fromStdString(significand.to_string(16));
|
||||
}
|
|
@ -71,10 +71,6 @@ static QString ToDoubleString(void* buffer)
|
|||
return ToFloatingString<double>(buffer);
|
||||
}
|
||||
|
||||
static QString ToLongDoubleString(void* buffer)
|
||||
{
|
||||
//TODO: properly implement this because VS doesn't support it.
|
||||
return ToDoubleString(buffer);
|
||||
}
|
||||
QString ToLongDoubleString(void* buffer);
|
||||
|
||||
#endif // STRINGUTIL_H
|
||||
|
|
|
@ -141,7 +141,8 @@ SOURCES += \
|
|||
Src/Gui/NotepadView.cpp \
|
||||
Src/Gui/CPUMultiDump.cpp \
|
||||
Src/Gui/AssembleDialog.cpp \
|
||||
Src/ThirdPartyLibs/float128/float128.cpp
|
||||
Src/ThirdPartyLibs/float128/float128.cpp \
|
||||
Src/Utils/StringUtil.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
|
|
Loading…
Reference in New Issue