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
|
@ -64,6 +64,7 @@ output header {{
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "arch/x86/registers.hh"
|
#include "arch/x86/registers.hh"
|
||||||
#include "arch/x86/types.hh"
|
#include "arch/x86/types.hh"
|
||||||
|
#include "arch/x86/utility.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
|
|
@ -40,17 +40,17 @@
|
||||||
microcode = '''
|
microcode = '''
|
||||||
|
|
||||||
def macroop FLDZ {
|
def macroop FLDZ {
|
||||||
limm ufp1, "double(0)"
|
lfpimm ufp1, 0.0
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop FLD1 {
|
def macroop FLD1 {
|
||||||
limm ufp1, "double(1)"
|
lfpimm ufp1, 1.0
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop FLDPI {
|
def macroop FLDPI {
|
||||||
limm ufp1, "double(3.14159265359)"
|
lfpimm ufp1, 3.14159265359
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,22 +40,22 @@
|
||||||
microcode = '''
|
microcode = '''
|
||||||
|
|
||||||
def macroop FLDL2E {
|
def macroop FLDL2E {
|
||||||
limm ufp1, "double(1.44269504089)"
|
lfpimm ufp1, 1.44269504089
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop FLDL2T {
|
def macroop FLDL2T {
|
||||||
limm ufp1, "double(3.32192809489)"
|
lfpimm ufp1, 3.32192809489
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop FLDLG2 {
|
def macroop FLDLG2 {
|
||||||
limm ufp1, "double(0.30102999566)"
|
lfpimm ufp1, 0.30102999566
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
def macroop FLDLN2 {
|
def macroop FLDLN2 {
|
||||||
limm ufp1, "double(0.69314718056)"
|
lfpimm ufp1, 0.69314718056
|
||||||
movfp st(-1), ufp1, spm=-1
|
movfp st(-1), ufp1, spm=-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,8 @@ let {{
|
||||||
self.dest = dest
|
self.dest = dest
|
||||||
if isinstance(imm, (int, long)):
|
if isinstance(imm, (int, long)):
|
||||||
imm = "ULL(%d)" % imm
|
imm = "ULL(%d)" % imm
|
||||||
if isinstance(imm, float):
|
elif isinstance(imm, float):
|
||||||
imm = "reinterpret_cast<uint64_t>((double)(%d))"
|
imm = "getDoubleBits(%.16f)" % imm
|
||||||
self.imm = imm
|
self.imm = imm
|
||||||
self.dataSize = dataSize
|
self.dataSize = dataSize
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,13 @@ namespace X86ISA
|
||||||
* @param val New rflags value to store in TC
|
* @param val New rflags value to store in TC
|
||||||
*/
|
*/
|
||||||
void setRFlags(ThreadContext *tc, uint64_t val);
|
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__
|
#endif // __ARCH_X86_UTILITY_HH__
|
||||||
|
|
Loading…
Reference in a new issue