Use lower two bits of FCSR reg to determine rounding mode (may want to move this...
authorKorey Sewell <ksewell@umich.edu>
Fri, 28 Apr 2006 04:24:25 +0000 (00:24 -0400)
committerKorey Sewell <ksewell@umich.edu>
Fri, 28 Apr 2006 04:24:25 +0000 (00:24 -0400)
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
arch/mips/isa/formats/util.isa
arch/mips/isa_traits.cc
arch/mips/isa_traits.hh

index 4b6e475a83de594d6c9a161679040018d2af17bf..6feaec7cbe1d118794b108a745825b9cf86cce80 100644 (file)
@@ -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>;}});
                             }
                         }
                     }
index dcdf4675798ddef02dfbb6b2f25501e1e451e50e..615160931cb00f7f184a71a4bd294ffe76cc6a04 100644 (file)
@@ -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
-    };
 }};
 
 
index c6cfb2a0fd1c5009f7fc85d69ca013414c665475..d23cdf367802eb9a505c363e6fab2809a1b9338f 100644 (file)
 
 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)
index e5de675cfded58dac4a21f1ce60b2ce9de0af0cd..3ea72bde292185330e5c9f7ae4e422ce8051ee46 100644 (file)
@@ -315,13 +315,41 @@ namespace MipsISA
             return NoFault;
         }
 
-
-
         void serialize(std::ostream &os);
 
         void unserialize(Checkpoint *cp, const std::string &section);
     };
 
+        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);