Redo the FloatRegFile using unsigned integers
authorKorey Sewell <ksewell@umich.edu>
Wed, 3 May 2006 00:05:16 +0000 (20:05 -0400)
committerKorey Sewell <ksewell@umich.edu>
Wed, 3 May 2006 00:05:16 +0000 (20:05 -0400)
Edit the convert_and_round function which access FloatRegFile

arch/isa_parser.py:
    recognize when we are writing a 'uint64_t' FloatReg and set the width appropriately
arch/mips/isa/decoder.isa:
    Send a 'float' to the convert function instead of a unsigned word. Do this so we dont have to worry about the
    bit manipulation ourselves. We can just concern ourselves with values.

    Use unsigned double to get movd...
arch/mips/isa/formats/fp.isa:
    float debug statement
arch/mips/isa_traits.cc:
    add different versions of convert_and_round functions
arch/mips/isa_traits.hh:
    Use an array of uint32_t unsigned integers to represent the Floating Point Regfile
configs/test/hello_mips:
    basic FP program
cpu/simple/cpu.hh:
    spacing

--HG--
extra : convert_revision : a6fca91ad6365c83025f1131d71fa1b8ee76d7bc

arch/isa_parser.py
arch/mips/isa/decoder.isa
arch/mips/isa/formats/fp.isa
arch/mips/isa_traits.cc
arch/mips/isa_traits.hh
configs/test/hello_mips
cpu/simple/cpu.hh

index 921a6fa821edbafabef98408c941f94f5205e98d..83620a9f166d428311a011aadb1e5e7142aa31e0 100755 (executable)
@@ -1251,6 +1251,9 @@ class FloatRegOperand(Operand):
         elif (self.ctype == 'double'):
             width = 64
             func = 'setFloatReg'
+        elif (self.ctype == 'uint64_t'):
+            func = 'setFloatRegBits'
+            width = 64
         else:
             func = 'setFloatRegBits'
             final_ctype = 'uint%d_t' % self.dflt_size
index 99ff4d737f749bdff4084156c76fa3c31136bd00..9bafe9f34dd4dfcaaf7bcda84b03dbd5f68e3d5a 100644 (file)
@@ -397,7 +397,7 @@ decode OPCODE_HI default Unknown::unknown() {
                     format FloatOp {
                         0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
                         0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
-                        0x4: mtc1 ({{ Fs.uw = Rt.uw;           }});
+                        0x4: mtc1 ({{ Fs.uw = Rt.uw;       }});
                         0x7: mthc1({{
                              uint64_t fs_hi = Rt.ud << 32;
                              uint64_t fs_lo = Fs.ud & 0x0000FFFF;
@@ -572,7 +572,7 @@ decode OPCODE_HI default Unknown::unknown() {
                             format FloatOp {
                                 0x1: cvt_d_s({{
                                     int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
-                                    Fd.ud = convert_and_round(Fs.uw, SINGLE_TO_DOUBLE, rnd_mode);
+                                    Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_DOUBLE, rnd_mode);
                                 }});
 
                                 0x4: cvt_w_s({{
@@ -605,7 +605,7 @@ decode OPCODE_HI default Unknown::unknown() {
                                 0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
                                 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
                                 0x5: absd({{ Fd.df = fabs(Fs.df);}});
-                                0x6: movd({{ Fd.df = Fs.df;}});
+                                0x6: movd({{ Fd.ud = Fs.ud;}});
                                 0x7: negd({{ Fd.df = -1 * Fs.df;}});
                             }
                         }
index 65b259e200dedccab220c94d1669034979d782d0..fe6bd437f101a8453c21a04763b80844ecb33e64 100644 (file)
@@ -32,6 +32,7 @@ output decoder {{
 
 // Primary format for float operate instructions:
 def format FloatOp(code, *flags) {{
+        code = 'std::cout << "Floating Point Op" << std::endl;\n' + code
         iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
@@ -41,6 +42,7 @@ def format FloatOp(code, *flags) {{
 
 // Primary format for float64 operate instructions:
 def format Float64Op(code, *flags) {{
+        code = 'std::cout << "Floating Point 64" << std::endl;\n' + code
         iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
index 648e9ac624f1f47dc810f16ccc982748eba1a0bf..20c13fd36b2a9dc75ae08306a00ee8edc5ed33f4 100644 (file)
 #include "config/full_system.hh"
 #include "cpu/static_inst.hh"
 #include "sim/serialize.hh"
+#include "base/bitfield.hh"
 
 using namespace MipsISA;
+using namespace std;
+
+uint64_t
+MipsISA::convert_and_round(uint32_t fp_val, ConvertType cvt_type, int rnd_mode)
+{
+
+    uint64_t ret_val = 0;
+
+    switch (cvt_type)
+    {
+      case SINGLE_TO_DOUBLE:
+        uint64_t single_sign     = fp_val & 0x80000000;
+
+        uint64_t single_exp      = (fp_val & 0x7F800000) >> 22;
+        single_exp -= 127;
+
+        uint64_t single_mantissa = fp_val & 0x007FFFFF;
+
+        uint64_t double_exp = single_exp + 1023;
+        double_exp = double_exp << 51;
+
+        uint64_t double_val =  single_sign << 63 | double_exp | single_mantissa;
+
+        return double_val;
+
+      default:
+        panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+        return ret_val;
+    }
+}
 
 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:
+        uint64_t single_sign     = fp_val & 0x80000000;
 
-        break;
+        uint64_t single_exp      = (fp_val & 0x7F800000) >> 22;
+        single_exp -= 127;
+
+        uint64_t single_mantissa = fp_val & 0x007FFFFF;
+
+        uint64_t double_exp = single_exp + 1023;
+        double_exp = double_exp << 51;
+
+        uint64_t double_val =  single_sign << 63 | double_exp | single_mantissa;
+
+        return double_val;
 
       default:
         panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+        return ret_val;
     }
+}
+
+
+uint64_t
+MipsISA::convert_and_round(float fp_val, ConvertType cvt_type, int rnd_mode)
+{
+    void * ptr = &fp_val;
+    uint32_t fp_bits = * (uint32_t *) ptr;
+
+    cout << "Converting " << fp_val << " (" << hex << fp_bits << ") " << endl;
 
-    return ret_val;
+    uint64_t ret_val = 0;
+
+    switch (cvt_type)
+    {
+      case SINGLE_TO_DOUBLE:
+        double double_val = fp_val;
+        void *double_ptr = &double_val;
+        uint64_t dp_bits =  *(uint64_t *) double_ptr ;
+        cout << "To " << double_val << " (" << hex << dp_bits << ") " << endl;
+        double_ptr = &dp_bits;
+        cout << "Testing: " << *(double *) double_ptr << endl;
+        return dp_bits;
+
+      default:
+        panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+        return ret_val;
+    }
 }
 
 void
index 3ea72bde292185330e5c9f7ae4e422ce8051ee46..671d36b878c3f2e295f1b5dddf6e0d7a2e67dbe6 100644 (file)
@@ -189,21 +189,24 @@ namespace MipsISA
 
     };
 
-    typedef double FloatReg;
+    typedef float FloatReg;
+
+    typedef uint32_t FloatReg32;
+    typedef uint64_t FloatReg64;
     typedef uint64_t FloatRegBits;
 
+//  const uint64_t hi_mask64 = 0xFFFFFFFF00000000;
+//const uint64_t lo_mask64 = 0x00000000FFFFFFFF;
+
     const int SingleWidth = 32;
-    const int SingleBytes = SingleWidth / 4;
+    const int SingleBytes = 4;
 
     const int DoubleWidth = 64;
-    const int DoubleBytes = DoubleWidth / 4;
+    const int DoubleBytes = 8;
 
     const int QuadWidth = 128;
     const int QuadBytes = QuadWidth / 4;
 
-    const int FloatRegSize = SingleWidth / SingleBytes;
-    const int DoubleRegSize = FloatRegSize * 2;
-
     class FloatRegFile
     {
       protected:
@@ -211,31 +214,27 @@ namespace MipsISA
         //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];
+        //char regSpace[SingleBytes * NumFloatRegs];
+        FloatReg32 regs[NumFloatRegs];
 
       public:
 
         void clear()
         {
-            bzero(regSpace, sizeof(regSpace));
+            bzero(regs, sizeof(regs));
         }
 
-        FloatReg readReg(int floatReg, int width)
+        double readReg(int floatReg, int width)
         {
-            //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);
+                void *float_ptr = &regs[floatReg];
+                return *(float *) float_ptr;
 
               case DoubleWidth:
-                double result64;
-                memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
-                return htog(result64);
+                void *double_ptr = &regs[floatReg];
+                return *(double *) double_ptr;
 
               default:
                 panic("Attempted to read a %d bit floating point register!", width);
@@ -244,20 +243,17 @@ namespace MipsISA
 
         FloatRegBits readRegBits(int floatReg, int width)
         {
-            //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.
+            using namespace std;
+
             switch(width)
             {
               case SingleWidth:
-                uint32_t result32;
-                memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
-                return htog(result32);
+                return regs[floatReg];
 
               case DoubleWidth:
-                uint64_t result64;
-                memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
-                return htog(result64);
+                cout << hex << "Combining " << regs[floatReg + 1] << " & " << regs[floatReg + 1] << endl;
+                cout << hex << "Returning " << ((FloatReg64)regs[floatReg] << 32 | regs[floatReg + 1]) << endl;
+                return (FloatReg64)regs[floatReg] << 32 | regs[floatReg + 1];
 
               default:
                 panic("Attempted to read a %d bit floating point register!", width);
@@ -266,47 +262,45 @@ namespace MipsISA
 
         Fault setReg(int floatReg, const FloatReg &val, int width)
         {
-            //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);
+                float temp = val;
+                void *float_ptr = &temp;
+                regs[floatReg] = *(FloatReg32 *) float_ptr;
                 break;
 
               case DoubleWidth:
-                uint64_t result64;
-                result64 = gtoh((uint64_t)val);
-                memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+                const void *double_ptr = &val;
+                FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
+                regs[floatReg] = temp_double >> 32;
+                regs[floatReg + 1] = temp_double;
                 break;
 
-
               default:
                 panic("Attempted to read a %d bit floating point register!", width);
             }
+
             return NoFault;
         }
 
         Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
         {
-            //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.
+            using namespace std;
+
             switch(width)
             {
               case SingleWidth:
-                uint32_t result32;
-                result32 = gtoh((uint32_t)val);
-                memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+                regs[floatReg] = val;
                 break;
 
               case DoubleWidth:
-                uint64_t result64;
-                result64 = gtoh((uint64_t)val);
-                memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+                cout << hex << "Setting val: " << val << endl;
+                regs[floatReg] = val >> 32;
+                regs[floatReg + 1] = val;
+                cout << dec << "f" << floatReg << ": " << hex<< readRegBits(floatReg,32) << endl;
+                cout << dec << "f" << floatReg + 1 << ": " << hex << readRegBits(floatReg+1,32) << endl;
                 break;
 
               default:
@@ -348,8 +342,9 @@ namespace MipsISA
             RND_NEAREST
         };
 
+        uint64_t convert_and_round(uint32_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
         uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
-
+        uint64_t convert_and_round(float fp_val,ConvertType cvt_type, int rnd_mode = 0);
 
         void copyRegs(ExecContext *src, ExecContext *dest);
 
@@ -637,7 +632,6 @@ extern const Addr PageOffset;
             return miscRegFile.setRegWithEffect(miscReg, val, xc);
         }
 
-
         FloatReg readFloatReg(int floatReg)
         {
             return floatRegFile.readReg(floatReg,SingleWidth);
index a3db001ec870fe17678195527e6720c511722a1c..33d9fbb5880bfa0f884a1d6088c90e90e2ccaf90 100755 (executable)
Binary files a/configs/test/hello_mips and b/configs/test/hello_mips differ
index 3640348a3c90f7b27d694feb5deb4b5705f2f51e..af585a2e5b84439e1695274d467c51519dad19d2 100644 (file)
@@ -369,7 +369,7 @@ class SimpleCPU : public BaseCPU
     }
 
     void setFloatRegBits(const StaticInst *si, int idx,
-            FloatRegBits val, int width)
+                         FloatRegBits val, int width)
     {
         int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
         cpuXC->setFloatRegBits(reg_idx, val, width);