From 80dee53b0430f829e8f9aff1a68c62e113f3ce24 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 11 May 2006 03:26:19 -0400 Subject: Fixes for Paired-Single FP Compare Operations... Now all the variations of FP should be implemented correctly in the decoder. The new formats and functions supporting these functions need to be implemented for some of the FP stuff but for the most part things are looking like their "supposed to"... arch/mips/isa/decoder.isa: Fixes for Paired-Single FP Compare Operations... Now all the variations of FP should be implemented correctly in the decoder. arch/mips/isa/formats/fp.isa: Add new PS formats arch/mips/isa_traits.cc: Add skeleton overloaded round & truncate functions arch/mips/isa_traits.hh: declare overloaded functions --HG-- extra : convert_revision : 15d5cf7b08ac2dc9ebcd6b268e92d4abffdd8597 --- arch/mips/isa/decoder.isa | 201 +++++++++++++++++++++++++++++++++++++------ arch/mips/isa/formats/fp.isa | 18 ++++ arch/mips/isa_traits.cc | 13 +++ arch/mips/isa_traits.hh | 7 +- 4 files changed, 214 insertions(+), 25 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 143d0bae2..5e1f02869 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -1021,39 +1021,193 @@ decode OPCODE_HI default Unknown::unknown() { Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE); }}); - 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }}); - 0x5: plu({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;}}); - 0x6: pul({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<31:0>; }}); - 0x7: puu({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<63:32>;}}); + 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }}); + 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }}); + 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }}); + 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }}); } } 0x6: decode FUNCTION_LO { - format FloatOp { - 0x0: c_f_ps({{ ; }}); - 0x1: c_un_ps({{ ; }}); - 0x2: c_eq_ps({{ ; }}); - 0x3: c_ueq_ps({{ ; }}); - 0x4: c_olt_ps({{ ; }}); - 0x5: c_ult_ps({{ ; }}); - 0x6: c_ole_ps({{ ; }}); - 0x7: c_ule_ps({{ ; }}); + format FloatPSCompareOp { + 0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }}); + + 0x1: c_un_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = 0; + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = 0; + + }}); + + 0x2: c_eq_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x3: c_ueq_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x4: c_olt_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x5: c_ult_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs.sf < Ft.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x6: c_ole_ps({{ + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) + cond1 = 0; + else + cond1 = (Fs.sf <= Ft.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); + + 0x7: c_ule_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); } } 0x7: decode FUNCTION_LO { - format FloatOp { - 0x0: c_sf_ps({{ ; }}); - 0x1: c_ngle_ps({{ ; }}); - 0x2: c_seq_ps({{ ; }}); - 0x3: c_ngl_ps({{ ; }}); - 0x4: c_lt_ps({{ ; }}); - 0x5: c_nge_ps({{ ; }}); - 0x6: c_le_ps({{ ; }}); - 0x7: c_ngt_ps({{ ; }}); + format FloatPSCompareWithXcptOp { + 0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }}); + + 0x1: c_ngle_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = 0; + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = 0; + }}); + + 0x2: c_seq_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x3: c_ngl_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x4: c_lt_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x5: c_nge_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x6: c_le_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); + + 0x7: c_ngt_ps({{ + if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); } } - } } } @@ -1148,7 +1302,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); 0x6: nmsub_ps({{ - 0x6: msub_ps({{ Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df); Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df); }}); diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 2ea4d6bf8..0414e30c3 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -81,3 +81,21 @@ def format Float64ConvertOp(code, *flags) {{ decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; + +def format FloatPSCompareOp(code, *flags) {{ + code = 'bool cond1;\nbool cond2;\n' + code + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatPSCompareWithXcptOp(code, *flags) {{ + code = 'bool cond1;\nbool cond2;\n' + code + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 05499f4dc..19ef46291 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -102,6 +102,12 @@ MipsISA::roundFP(float val) return 1.5; } +float +MipsISA::roundFP(uint64_t val) +{ + return 1.5; +} + double MipsISA::roundFP(double val) { @@ -120,6 +126,13 @@ MipsISA::truncFP(float val) return 1.0; } +double +MipsISA::truncFP(uint64_t val) +{ + int trunc_val = (int) val; + return (double) trunc_val; +} + double MipsISA::truncFP(double val) { diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 097736dda..6788806c1 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -138,10 +138,15 @@ namespace MipsISA void copyRegs(ExecContext *src, ExecContext *dest); uint64_t fpConvert(double fp_val, ConvertType cvt_type); + float roundFP(float val); double roundFP(double val); + float roundFP(uint64_t val); + float truncFP(float val); - float truncFP(float val); + double truncFP(uint64_t val); + double truncFP(double val); + bool unorderedFP(float val); bool unorderedFP(double val); bool getFPConditionCode(int cc); -- cgit v1.2.3