diff options
author | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-06-18 16:30:06 +0200 |
---|---|---|
committer | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-06-18 16:30:06 +0200 |
commit | a8e8c4f433fb3cce354950ba72136b84abb78015 (patch) | |
tree | c1b93c2399e0474da011b9aaaa324d4bd14b919e /src | |
parent | c9c02efb99c0a982c116c7d1d8ed9a984c174198 (diff) | |
download | gem5-a8e8c4f433fb3cce354950ba72136b84abb78015.tar.xz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/x87/load_constants/load_0_1_or_pi.py | 6 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/x87/load_constants/load_logarithm.py | 8 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/limmop.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/utility.hh | 7 |
5 files changed, 17 insertions, 9 deletions
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index eda2ebceb..43565fda5 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -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" diff --git a/src/arch/x86/isa/insts/x87/load_constants/load_0_1_or_pi.py b/src/arch/x86/isa/insts/x87/load_constants/load_0_1_or_pi.py index cb8947312..9f22af89b 100644 --- a/src/arch/x86/isa/insts/x87/load_constants/load_0_1_or_pi.py +++ b/src/arch/x86/isa/insts/x87/load_constants/load_0_1_or_pi.py @@ -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 }; diff --git a/src/arch/x86/isa/insts/x87/load_constants/load_logarithm.py b/src/arch/x86/isa/insts/x87/load_constants/load_logarithm.py index 7e71c4006..88eb01086 100644 --- a/src/arch/x86/isa/insts/x87/load_constants/load_logarithm.py +++ b/src/arch/x86/isa/insts/x87/load_constants/load_logarithm.py @@ -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 }; diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 9e88e4b94..2c61aaa45 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -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 diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh index 6fc802f2f..48840ac77 100644 --- a/src/arch/x86/utility.hh +++ b/src/arch/x86/utility.hh @@ -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__ |