x86: Fix loading of floating point constants
This changeset actually fixes two issues: * The lfpimm instruction didn't work correctly when applied to a floating point constant (it did work for integers containing the bit string representation of a constant) since it used reinterpret_cast to convert a double to a uint64_t. This caused a compilation error, at least, in gcc 4.6.3. * The instructions loading floating point constants in the x87 processor didn't work correctly since they just stored a truncated integer instead of a double in the floating point register. This changeset fixes the old microcode by using lfpimm instruction instead of the limm instructions.
This commit is contained in:
parent
c9c02efb99
commit
a8e8c4f433
5 changed files with 17 additions and 9 deletions
|
@ -64,6 +64,7 @@ output header {{
|
|||
#include "arch/x86/isa_traits.hh"
|
||||
#include "arch/x86/registers.hh"
|
||||
#include "arch/x86/types.hh"
|
||||
#include "arch/x86/utility.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
|
|
@ -40,17 +40,17 @@
|
|||
microcode = '''
|
||||
|
||||
def macroop FLDZ {
|
||||
limm ufp1, "double(0)"
|
||||
lfpimm ufp1, 0.0
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
def macroop FLD1 {
|
||||
limm ufp1, "double(1)"
|
||||
lfpimm ufp1, 1.0
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
def macroop FLDPI {
|
||||
limm ufp1, "double(3.14159265359)"
|
||||
lfpimm ufp1, 3.14159265359
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
|
|
|
@ -40,22 +40,22 @@
|
|||
microcode = '''
|
||||
|
||||
def macroop FLDL2E {
|
||||
limm ufp1, "double(1.44269504089)"
|
||||
lfpimm ufp1, 1.44269504089
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
def macroop FLDL2T {
|
||||
limm ufp1, "double(3.32192809489)"
|
||||
lfpimm ufp1, 3.32192809489
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
def macroop FLDLG2 {
|
||||
limm ufp1, "double(0.30102999566)"
|
||||
lfpimm ufp1, 0.30102999566
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
def macroop FLDLN2 {
|
||||
limm ufp1, "double(0.69314718056)"
|
||||
lfpimm ufp1, 0.69314718056
|
||||
movfp st(-1), ufp1, spm=-1
|
||||
};
|
||||
|
||||
|
|
|
@ -140,8 +140,8 @@ let {{
|
|||
self.dest = dest
|
||||
if isinstance(imm, (int, long)):
|
||||
imm = "ULL(%d)" % imm
|
||||
if isinstance(imm, float):
|
||||
imm = "reinterpret_cast<uint64_t>((double)(%d))"
|
||||
elif isinstance(imm, float):
|
||||
imm = "getDoubleBits(%.16f)" % imm
|
||||
self.imm = imm
|
||||
self.dataSize = dataSize
|
||||
|
||||
|
|
|
@ -134,6 +134,13 @@ namespace X86ISA
|
|||
* @param val New rflags value to store in TC
|
||||
*/
|
||||
void setRFlags(ThreadContext *tc, uint64_t val);
|
||||
|
||||
/**
|
||||
* Extract the bit string representing a double value.
|
||||
*/
|
||||
inline uint64_t getDoubleBits(double val) {
|
||||
return *(uint64_t *)(&val);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __ARCH_X86_UTILITY_HH__
|
||||
|
|
Loading…
Reference in a new issue