Changes to get Floating Point Instructions w/new regfile to at least not segfault...
authorKorey Sewell <ksewell@umich.edu>
Wed, 26 Apr 2006 20:13:47 +0000 (16:13 -0400)
committerKorey Sewell <ksewell@umich.edu>
Wed, 26 Apr 2006 20:13:47 +0000 (16:13 -0400)
arch/mips/isa/decoder.isa:
    Change decoder to read COP1 (floating point) instructions to decode correctly
arch/mips/isa_traits.hh:
    Change to use overlapping single/double FP regfile

--HG--
extra : convert_revision : 2d15d6d88939f7e0d63279d5c35d7eea536a573c

arch/mips/isa/decoder.isa
arch/mips/isa_traits.hh

index 077f0afd08ab17bc5df813bf9e92f3fad14286d9..1a188d67ad2239a39c02246cb524a4006ff2d4aa 100644 (file)
@@ -450,8 +450,8 @@ decode OPCODE_HI default Unknown::unknown() {
 
                     //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
                     //(( single-word ))
-                    0x0: decode RS_HI {
-                        0x0: decode RS_LO {
+                    0x0: decode FUNCTION_HI {
+                        0x0: decode FUNCTION_LO {
                             format FloatOp {
                                 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
                                 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
@@ -464,7 +464,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x1: decode RS_LO {
+                        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);}});
@@ -481,7 +481,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x2: decode RS_LO {
+                        0x2: decode FUNCTION_LO {
                             0x1: decode MOVCF {
                                 format FloatOp {
                                     0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
@@ -500,7 +500,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x4: decode RS_LO {
+                        0x4: decode FUNCTION_LO {
 
                             format FloatOp {
                                 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
@@ -524,8 +524,8 @@ decode OPCODE_HI default Unknown::unknown() {
                     }
 
                     //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
-                    0x1: decode RS_HI {
-                        0x0: decode RS_LO {
+                    0x1: decode FUNCTION_HI {
+                        0x0: decode FUNCTION_LO {
                             format FloatOp {
                                 0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
                                 0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
@@ -538,7 +538,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x1: decode RS_LO {
+                        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); }});
@@ -555,7 +555,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x2: decode RS_LO {
+                        0x2: decode FUNCTION_LO {
                             0x1: decode MOVCF {
                                 format FloatOp {
                                     0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
@@ -574,7 +574,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x4: decode RS_LO {
+                        0x4: decode FUNCTION_LO {
                             format FloatOp {
                                 0x0: cvt_s_d({{
                                     int rnd_mode = xc->readMiscReg(FCSR);
@@ -632,8 +632,8 @@ decode OPCODE_HI default Unknown::unknown() {
                     //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
                     //Note: "1. Format type PS is legal only if 64-bit floating point operations
                     //are enabled. "
-                    0x6: decode RS_HI {
-                        0x0: decode RS_LO {
+                    0x6: decode FUNCTION_HI {
+                        0x0: decode FUNCTION_LO {
                             format Float64Op {
                                 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
                                     //Lower Halves Independently but we take simulator shortcut
@@ -667,7 +667,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             }
                         }
 
-                        0x2: decode RS_LO {
+                        0x2: decode FUNCTION_LO {
                             0x1: decode MOVCF {
                                 format Float64Op {
                                     0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
@@ -682,14 +682,14 @@ decode OPCODE_HI default Unknown::unknown() {
 
                         }
 
-                        0x4: decode RS_LO {
+                        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);
                             }});
                         }
 
-                        0x5: decode RS_LO {
+                        0x5: decode FUNCTION_LO {
                             format Float64Op {
                                 0x0: cvt_s_pl({{
                                     int rnd_mode = xc->readMiscReg(FCSR);
index 1f4ccbd90a16a826d1d4dd75647c7e835e1c2d37..2403782d074bef5535fa4493a927b9981ec8fce0 100644 (file)
 #define __ARCH_MIPS_ISA_TRAITS_HH__
 
 //#include "arch/mips/misc_regfile.hh"
+#include "arch/mips/faults.hh"
 #include "base/misc.hh"
 #include "config/full_system.hh"
+#include "sim/byteswap.hh"
 #include "sim/host.hh"
 #include "sim/faults.hh"
 
@@ -105,7 +107,7 @@ namespace MipsISA
     const int NumPALShadowRegs = 8;
     const int NumFloatArchRegs = 32;
     // @todo: Figure out what this number really should be.
-    const int NumMiscArchRegs = 32;
+    const int NumMiscArchRegs = 265;
 
     const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
     const int NumFloatRegs = NumFloatArchRegs;
@@ -189,63 +191,135 @@ namespace MipsISA
 
     typedef double FloatReg;
     typedef uint64_t FloatRegBits;
+
+    const int SingleWidth = 32;
+    const int SingleBytes = SingleWidth / 4;
+
+    const int DoubleWidth = 64;
+    const int DoubleBytes = DoubleWidth / 4;
+
+    const int QuadWidth = 128;
+    const int QuadBytes = QuadWidth / 4;
+
+    const int FloatRegSize = SingleWidth / SingleBytes;
+    const int DoubleRegSize = FloatRegSize * 2;
+
     class FloatRegFile
     {
       protected:
 
-        FloatRegBits q[NumFloatRegs];  // integer qword view
-        double d[NumFloatRegs];        // double-precision floating point view
+        //Since the floating point registers overlap each other,
+        //A generic storage space is used. The float to be returned is
+        //pulled from the appropriate section of this region.
+        char regSpace[FloatRegSize * NumFloatRegs];
 
       public:
 
-        FloatReg readReg(int floatReg)
+        void clear()
         {
-            return d[floatReg];
+            bzero(regSpace, sizeof(regSpace));
         }
 
         FloatReg readReg(int floatReg, int width)
         {
-            return readReg(floatReg);
-        }
+            //In each of these cases, we have to copy the value into a temporary
+            //variable. This is because we may otherwise try to access an
+            //unaligned portion of memory.
+            switch(width)
+            {
+              case SingleWidth:
+                float result32;
+                memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
+                return htog(result32);
 
-        FloatRegBits readRegBits(int floatReg)
-        {
-            return q[floatReg];
-        }
+              case DoubleWidth:
+                double result64;
+                memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
+                return htog(result64);
 
-        FloatRegBits readRegBits(int floatReg, int width)
-        {
-            return readRegBits(floatReg);
+              default:
+                panic("Attempted to read a %d bit floating point register!", width);
+            }
         }
 
-        Fault setReg(int floatReg, const FloatReg &val)
+        FloatRegBits readRegBits(int floatReg, int width)
         {
-            d[floatReg] = val;
-            return NoFault;
+            //In each of these cases, we have to copy the value into a temporary
+            //variable. This is because we may otherwise try to access an
+            //unaligned portion of memory.
+            switch(width)
+            {
+              case SingleWidth:
+                uint32_t result32;
+                memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
+                return htog(result32);
+              case DoubleWidth:
+                uint64_t result64;
+                memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
+                return htog(result64);
+
+              default:
+                panic("Attempted to read a %d bit floating point register!", width);
+            }
         }
 
         Fault setReg(int floatReg, const FloatReg &val, int width)
         {
-            return setReg(floatReg, val);
-        }
-
-        Fault setRegBits(int floatReg, const FloatRegBits &val)
-        {
-            q[floatReg] = val;
+            //In each of these cases, we have to copy the value into a temporary
+            //variable. This is because we may otherwise try to access an
+            //unaligned portion of memory.
+            switch(width)
+            {
+              case SingleWidth:
+                uint32_t result32;
+                result32 = gtoh((uint32_t)val);
+                memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+                break;
+
+              case DoubleWidth:
+                uint64_t result64;
+                result64 = gtoh((uint64_t)val);
+                memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+                break;
+
+
+              default:
+                panic("Attempted to read a %d bit floating point register!", width);
+            }
             return NoFault;
         }
 
         Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
         {
-            return setRegBits(floatReg, val);
+            //In each of these cases, we have to copy the value into a temporary
+            //variable. This is because we may otherwise try to access an
+            //unaligned portion of memory.
+            switch(width)
+            {
+              case SingleWidth:
+                uint32_t result32;
+                result32 = gtoh((uint32_t)val);
+                memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+                break;
+
+              case DoubleWidth:
+                uint64_t result64;
+                result64 = gtoh((uint64_t)val);
+                memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+                break;
+
+              default:
+                panic("Attempted to read a %d bit floating point register!", width);
+            }
+            return NoFault;
         }
 
         void serialize(std::ostream &os);
 
         void unserialize(Checkpoint *cp, const std::string &section);
-
     };
 
+
         void copyRegs(ExecContext *src, ExecContext *dest);
 
     // cop-0/cop-1 system control register file
@@ -532,44 +606,45 @@ extern const Addr PageOffset;
             return miscRegFile.setRegWithEffect(miscReg, val, xc);
         }
 
+
         FloatReg readFloatReg(int floatReg)
         {
-            return floatRegFile.readReg(floatReg);
+            return floatRegFile.readReg(floatReg,SingleWidth);
         }
 
         FloatReg readFloatReg(int floatReg, int width)
         {
-            return readFloatReg(floatReg);
+            return floatRegFile.readReg(floatReg,width);
         }
 
         FloatRegBits readFloatRegBits(int floatReg)
         {
-            return floatRegFile.readRegBits(floatReg);
+            return floatRegFile.readRegBits(floatReg,SingleWidth);
         }
 
         FloatRegBits readFloatRegBits(int floatReg, int width)
         {
-            return readFloatRegBits(floatReg);
+            return floatRegFile.readRegBits(floatReg,width);
         }
 
         Fault setFloatReg(int floatReg, const FloatReg &val)
         {
-            return floatRegFile.setReg(floatReg, val);
+            return floatRegFile.setReg(floatReg, val, SingleWidth);
         }
 
         Fault setFloatReg(int floatReg, const FloatReg &val, int width)
         {
-            return setFloatReg(floatReg, val);
+            return floatRegFile.setReg(floatReg, val, width);
         }
 
         Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
         {
-            return floatRegFile.setRegBits(floatReg, val);
+            return floatRegFile.setRegBits(floatReg, val, SingleWidth);
         }
 
         Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
         {
-            return setFloatRegBits(floatReg, val);
+            return floatRegFile.setRegBits(floatReg, val, width);
         }
 
         IntReg readIntReg(int intReg)