diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/isa/decoder.isa | 201 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 18 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 13 | ||||
-rw-r--r-- | 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) { @@ -121,6 +127,13 @@ MipsISA::truncFP(float val) } double +MipsISA::truncFP(uint64_t val) +{ + int trunc_val = (int) val; + return (double) trunc_val; +} + +double MipsISA::truncFP(double val) { int trunc_val = (int) 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); |