From a183f66a8ad2a1ac822b07d9b399a3a3e6d3cb5c Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 28 Apr 2006 00:24:25 -0400 Subject: [PATCH] Use lower two bits of FCSR reg to determine rounding mode (may want to move this out of decoder.isa and into a template) Have FP conversion instructions use re-defined convert_and_round() function arch/mips/isa/decoder.isa: Use lower two bits of FCSR reg to determine rounding mode (may want to move this out of decoder.isa and into a template) Have FP conversion instructions to use re-defined convert_and_round() function arch/mips/isa/formats/util.isa: Remove convert_and_round function from here arch/mips/isa_traits.cc: Define convert_and_round function here arch/mips/isa_traits.hh: Use "enums" to define FP conversion types & Round Modes Declare convert_and_round function here --HG-- extra : convert_revision : 0f4f8c1732a53b277361559ea71af2a1feb4fc64 --- arch/mips/isa/decoder.isa | 147 +++++++++++++++++++++------------ arch/mips/isa/formats/util.isa | 21 ----- arch/mips/isa_traits.cc | 31 +++++++ arch/mips/isa_traits.hh | 32 ++++++- 4 files changed, 156 insertions(+), 75 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 4b6e475a8..6feaec7cb 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -511,19 +511,40 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode FUNCTION_LO { - //only legal for 64 bit-FP format Float64Op { - 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}}); - 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}}); - 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}}); - 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}}); + 0x0: round_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST); + }}); + + 0x1: trunc_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO); + }}); + + 0x2: ceil_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP); + }}); + + 0x3: floor_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN); + }}); } format FloatOp { - 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}}); - 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}}); - 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}}); - 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}}); + 0x4: round_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST); + }}); + + 0x5: trunc_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO); + }}); + + 0x6: ceil_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP); + }}); + + 0x7: floor_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN); + }}); } } @@ -550,26 +571,25 @@ decode OPCODE_HI default Unknown::unknown() { format FloatOp { 0x1: cvt_d_s({{ - //int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(,DOUBLE_TO_SINGLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_DOUBLE, rnd_mode); }}); 0x4: cvt_w_s({{ - //int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode); }}); } //only legal for 64 bit format Float64Op { 0x5: cvt_l_s({{ - //int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode); }}); - 0x6: cvt_ps_s({{ - //int rnd_mode = xc->readMiscReg(FCSR); - /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ + 0x6: cvt_ps_st({{ + Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw; }}); } } @@ -591,19 +611,40 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode FUNCTION_LO { - //only legal for 64 bit format Float64Op { - 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); - 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}}); - 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}}); - 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}}); + 0x0: round_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST); + }}); + + 0x1: trunc_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO); + }}); + + 0x2: ceil_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP); + }}); + + 0x3: floor_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN); + }}); } format FloatOp { - 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); - 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }}); - 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }}); - 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }}); + 0x4: round_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST); + }}); + + 0x5: trunc_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO); + }}); + + 0x6: ceil_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP); + }}); + + 0x7: floor_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN); + }}); } } @@ -629,21 +670,21 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode); }}); } //only legal for 64 bit format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode); }}); } } @@ -652,14 +693,14 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { format FloatOp { - 0x20: cvt_s({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); + 0x20: cvt_s_w({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode); }}); - 0x21: cvt_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); + 0x21: cvt_d_w({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode); }}); } } @@ -668,15 +709,15 @@ decode OPCODE_HI default Unknown::unknown() { //Note: "1. Format type L is legal only if 64-bit floating point operations //are enabled." 0x5: decode FUNCTION_HI { - format FloatOp { + format Float64Op { 0x10: cvt_s_l({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode); }}); 0x11: cvt_d_l({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode); }}); } } @@ -736,21 +777,23 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode); }}); } 0x5: decode FUNCTION_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, PLOWER_TO_SINGLE, + rnd_mode); }}); - 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}}); - 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}}); - 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}}); - 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}}); + + 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>;}}); } } } diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index dcdf46757..615160931 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -95,9 +95,6 @@ output exec {{ using namespace MipsISA; - - - /// CLEAR ALL CPU INST/EXE HAZARDS inline void clear_exe_inst_hazards() @@ -126,25 +123,7 @@ output exec {{ } #endif - double convert_and_round(float w, int x, int y, int z) - { - double temp = .34000; - - return temp; - } - enum FPTypes{ - FP_SINGLE, - FP_DOUBLE, - FP_LONG, - FP_PS_LO, - FP_PS_HI, - FP_WORD, - RND_NEAREST, - RND_ZERO, - RND_UP, - RND_DOWN - }; }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index c6cfb2a0f..d23cdf367 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -33,7 +33,38 @@ using namespace MipsISA; +uint64_t +MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) +{ + uint64_t ret_val = 0; + + switch (cvt_type) + { + case SINGLE_TO_DOUBLE: + break; + + case SINGLE_TO_WORD: + break; + + case SINGLE_TO_LONG: + break; + + case DOUBLE_TO_SINGLE: + break; + + case LONG_TO_SINGLE: + break; + + case WORD_TO_SINGLE: + break; + + default: + panic("Invalid Floating Point Conversion type being used.\n"); + } + + return ret_val; +} void MipsISA::copyRegs(ExecContext *src, ExecContext *dest) diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index e5de675cf..3ea72bde2 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -315,13 +315,41 @@ namespace MipsISA return NoFault; } - - void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); }; + enum ConvertType{ + SINGLE_TO_DOUBLE, + SINGLE_TO_WORD, + SINGLE_TO_LONG, + + DOUBLE_TO_SINGLE, + DOUBLE_TO_WORD, + DOUBLE_TO_LONG, + + LONG_TO_SINGLE, + LONG_TO_DOUBLE, + LONG_TO_WORD, + + WORD_TO_SINGLE, + WORD_TO_DOUBLE, + WORD_TO_LONG, + + PLOWER_TO_SINGLE, + PUPPER_TO_SINGLE + }; + + enum RoundMode{ + RND_ZERO, + RND_DOWN, + RND_UP, + RND_NEAREST + }; + + uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0); + void copyRegs(ExecContext *src, ExecContext *dest); -- 2.30.2