diff options
author | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-09-30 12:00:20 +0200 |
---|---|---|
committer | Andreas Sandberg <andreas@sandberg.pp.se> | 2013-09-30 12:00:20 +0200 |
commit | 654d1e675a3dc1f598aeadb0824bdb3357820a59 (patch) | |
tree | e249108fcd6737dda985b993c95d926a33abca21 /src/arch/x86/isa/insts | |
parent | c299dcedc6d73aab56d9c659623d7112c2e9c4bb (diff) | |
download | gem5-654d1e675a3dc1f598aeadb0824bdb3357820a59.tar.xz |
x86: Add support for loading 32-bit and 80-bit floats in the x87
The x87 FPU supports three floating point formats: 32-bit, 64-bit, and
80-bit floats. The current gem5 implementation supports 32-bit and
64-bit floats, but only works correctly for 64-bit floats. This
changeset fixes the 32-bit float handling by correctly loading and
rounding (using truncation) 32-bit floats instead of simply truncating
the bit pattern.
80-bit floats are loaded by first loading the 80-bits of the float to
two temporary integer registers. A micro-op (cvtint_fp80) then
converts the contents of the two integer registers to the internal FP
representation (double). Similarly, when storing an 80-bit float,
there are two conversion routines (ctvfp80h_int and cvtfp80l_int) that
convert an internal FP register to 80-bit and stores the upper 64-bits
or lower 32-bits to an integer register, which is the written to
memory using normal integer stores.
Diffstat (limited to 'src/arch/x86/isa/insts')
-rw-r--r-- | src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py index 5a19aabd9..6f3a8d3a6 100644 --- a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py +++ b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/load_or_store_floating_point.py @@ -37,13 +37,13 @@ microcode = ''' def macroop FLD_M { - ldfp ufp1, seg, sib, disp + ldfp87 ufp1, seg, sib, disp movfp st(-1), ufp1, spm=-1 }; def macroop FLD_P { rdip t7 - ldfp ufp1, seg, riprel, disp + ldfp87 ufp1, seg, riprel, disp movfp st(-1), ufp1, spm=-1 }; @@ -51,17 +51,30 @@ def macroop FLD_R { movfp st(-1), sti, spm=-1 }; +def macroop FLD80_M { + ld t1, seg, sib, "DISPLACEMENT", dataSize=8 + ld t2, seg, sib, "DISPLACEMENT + 8", dataSize=2 + cvtint_fp80 st(-1), t1, t2, spm=-1 +}; + +def macroop FLD80_P { + rdip t7 + ld t1, seg, riprel, "DISPLACEMENT", dataSize=8 + ld t2, seg, riprel, "DISPLACEMENT + 8", dataSize=2 + cvtint_fp80 st(-1), t1, t2, spm=-1 +}; + def macroop FST_R { movfp sti, st(0) }; def macroop FST_M { - stfp st(0), seg, sib, disp + stfp87 st(0), seg, sib, disp }; def macroop FST_P { rdip t7 - stfp st(0), seg, riprel, disp + stfp87 st(0), seg, riprel, disp }; def macroop FSTP_R { @@ -70,14 +83,32 @@ def macroop FSTP_R { def macroop FSTP_M { movfp ufp1, st(0) - stfp ufp1, seg, sib, disp + stfp87 ufp1, seg, sib, disp pop87 }; def macroop FSTP_P { movfp ufp1, st(0) rdip t7 - stfp ufp1, seg, riprel, disp + stfp87 ufp1, seg, riprel, disp pop87 }; + +def macroop FST80P_M { + cvtfp80h_int t1, st(0) + cvtfp80l_int t2, st(0) + st t1, seg, sib, "DISPLACEMENT + 0", dataSize=8 + st t2, seg, sib, "DISPLACEMENT + 8", dataSize=2 + pop87 +}; + +def macroop FST80P_P { + rdip t7 + cvtfp80h_int t1, st(0) + cvtfp80l_int t2, st(0) + st t1, seg, riprel, "DISPLACEMENT + 0", dataSize=8 + st t2, seg, riprel, "DISPLACEMENT + 8", dataSize=2 + pop87 +}; + ''' |