fix mostly floating point related
authorAli Saidi <saidi@eecs.umich.edu>
Fri, 2 Feb 2007 23:04:42 +0000 (18:04 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Fri, 2 Feb 2007 23:04:42 +0000 (18:04 -0500)
src/arch/sparc/floatregfile.cc:
    fix fp read/writing to registers... looking for suggestions on cleaner ways if anyone has them
src/arch/sparc/isa/decoder.isa:
    fix some fp implementations
src/arch/sparc/isa/formats/basic.isa:
    add new fp op class that 0 cexec in fsr and sets rounding mode for the up comming op
src/arch/sparc/isa/includes.isa:
    include the appropriate header files for the rounding code
src/arch/sparc/miscregfile.cc:
    print fsr out when it's read/written and the Sparc traceflgas in on
src/cpu/exetrace.cc:
    fix printing of float registers

--HG--
extra : convert_revision : 49faab27f2e786a8455f9ca0f3f0132380c9d992

src/arch/sparc/floatregfile.cc
src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats/basic.isa
src/arch/sparc/isa/includes.isa
src/arch/sparc/miscregfile.cc
src/cpu/exetrace.cc

index 585782ddb3526254ce812990c259a613999001f6..e1b5ea7c8fe582225dda2277919442d0c710d87b 100644 (file)
@@ -69,22 +69,25 @@ FloatReg FloatRegFile::readReg(int floatReg, int width)
     switch(width)
     {
       case SingleWidth:
-        float32_t result32;
+        uint32_t result32;
+        float32_t fresult32;
         memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
-        result = htog(result32);
-        DPRINTF(Sparc, "Read FP32 register %d = 0x%x\n", floatReg, result);
+        result32 = htog(result32);
+        memcpy(&fresult32, &result32, sizeof(result32));
+        result = fresult32;
+        DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32);
         break;
       case DoubleWidth:
-        float64_t result64;
+        uint64_t result64;
+        float64_t fresult64;
         memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
-        result = htog(result64);
-        DPRINTF(Sparc, "Read FP64 register %d = 0x%x\n", floatReg, result);
+        result64 = htog(result64);
+        memcpy(&fresult64, &result64, sizeof(result64));
+        result = fresult64;
+        DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64);
         break;
       case QuadWidth:
-        float128_t result128;
-        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
-        result = htog(result128);
-        DPRINTF(Sparc, "Read FP128 register %d = 0x%x\n", floatReg, result);
+        panic("Quad width FP not implemented.");
         break;
       default:
         panic("Attempted to read a %d bit floating point register!", width);
@@ -113,10 +116,7 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
         DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result);
         break;
       case QuadWidth:
-        uint64_t result128;
-        memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
-        result = htog(result128);
-        DPRINTF(Sparc, "Read FP128 bits register %d = 0x%x\n", floatReg, result);
+        panic("Quad width FP not implemented.");
         break;
       default:
         panic("Attempted to read a %d bit floating point register!", width);
@@ -132,15 +132,21 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
 
     uint32_t result32;
     uint64_t result64;
+    float32_t fresult32;
+    float64_t fresult64;
     switch(width)
     {
       case SingleWidth:
-        result32 = gtoh((uint32_t)val);
+        fresult32 = val;
+        memcpy(&result32, &fresult32, sizeof(result32));
+        result32 = gtoh(result32);
         memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
         DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32);
         break;
       case DoubleWidth:
-        result64 = gtoh((uint64_t)val);
+        fresult64 = val;
+        memcpy(&result64, &fresult64, sizeof(result64));
+        result64 = gtoh(result64);
         memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
         DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64);
         break;
index 81443fecb6c272b9aefeccceee9f3aaab84cb1b2..57e0857f17a8c91020feff70facd34b192a9a53e 100644 (file)
@@ -718,7 +718,7 @@ decode OP default Unknown::unknown()
                 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
             }
             0x34: decode OPF{
-                format BasicOperate{
+                format FpBasic{
                     0x01: fmovs({{
                         Frds.uw = Frs2s.uw;
                         //fsr.ftt = fsr.cexc = 0
@@ -765,7 +765,7 @@ decode OP default Unknown::unknown()
                     0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
                     0x43: FpUnimpl::faddq();
                     0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}});
-                    0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
+                    0x46: fsubd({{Frd.df = Frs1.df - Frs2.df; }});
                     0x47: FpUnimpl::fsubq();
                     0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}});
                     0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
@@ -776,26 +776,26 @@ decode OP default Unknown::unknown()
                     0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}});
                     0x6E: FpUnimpl::fdmulq();
                     0x81: fstox({{
-                            Frd.df = (double)static_cast<int64_t>(Frs2s.sf);
+                            Frd.sdw = static_cast<int64_t>(Frs2s.sf);
                     }});
                     0x82: fdtox({{
-                            Frd.df = (double)static_cast<int64_t>(Frs2.df);
+                            Frd.sdw = static_cast<int64_t>(Frs2.df);
                     }});
                     0x83: FpUnimpl::fqtox();
                     0x84: fxtos({{
-                            Frds.sf = static_cast<float>((int64_t)Frs2.df);
+                            Frds.sf = static_cast<float>(Frs2.sdw);
                     }});
                     0x88: fxtod({{
-                            Frd.df = static_cast<double>((int64_t)Frs2.df);
+                            Frd.df = static_cast<double>(Frs2.sdw);
                     }});
                     0x8C: FpUnimpl::fxtoq();
                     0xC4: fitos({{
-                            Frds.sf = static_cast<float>((int32_t)Frs2s.sf);
+                            Frds.sf = static_cast<float>(Frs2s.sw);
                     }});
                     0xC6: fdtos({{Frds.sf = Frs2.df;}});
                     0xC7: FpUnimpl::fqtos();
                     0xC8: fitod({{
-                            Frd.df = static_cast<double>((int32_t)Frs2s.sf);
+                            Frd.df = static_cast<double>(Frs2s.sw);
                     }});
                     0xC9: fstod({{Frd.df = Frs2s.sf;}});
                     0xCB: FpUnimpl::fqtod();
@@ -803,17 +803,25 @@ decode OP default Unknown::unknown()
                     0xCD: FpUnimpl::fstoq();
                     0xCE: FpUnimpl::fdtoq();
                     0xD1: fstoi({{
-                            Frds.sf = (float)static_cast<int32_t>(Frs2s.sf);
+                            Frds.sw = static_cast<int32_t>(Frs2s.sf);
+                            float t = Frds.sw;
+                            if (t != Frs2s.sf)
+                               Fsr = insertBits(Fsr, 4,0, 0x01);
+                            Fsr |= Fsr<4:0> << 5;
                     }});
                     0xD2: fdtoi({{
-                            Frds.sf = (float)static_cast<int32_t>(Frs2.df);
+                            Frds.sw = static_cast<int32_t>(Frs2.df);
+                            double t = Frds.sw;
+                            if (t != Frs2.df)
+                               Fsr = insertBits(Fsr, 4,0, 0x01);
+                            Fsr |= Fsr<4:0> << 5;
                     }});
                     0xD3: FpUnimpl::fqtoi();
                     default: FailUnimpl::fpop1();
                 }
             }
             0x35: decode OPF{
-                format BasicOperate{
+                format FpBasic{
                     0x51: fcmps({{
                           uint8_t fcc;
                           if(isnan(Frs1s) || isnan(Frs2s))
@@ -831,11 +839,11 @@ decode OP default Unknown::unknown()
                     }});
                     0x52: fcmpd({{
                           uint8_t fcc;
-                          if(isnan(Frs1s) || isnan(Frs2s))
+                          if(isnan(Frs1) || isnan(Frs2))
                               fcc = 3;
-                          else if(Frs1s < Frs2s)
+                          else if(Frs1 < Frs2)
                               fcc = 1;
-                          else if(Frs1s > Frs2s)
+                          else if(Frs1 > Frs2)
                               fcc = 2;
                           else
                               fcc = 0;
@@ -860,11 +868,11 @@ decode OP default Unknown::unknown()
                     }});
                     0x56: fcmped({{
                           uint8_t fcc = 0;
-                          if(isnan(Frs1s) || isnan(Frs2s))
+                          if(isnan(Frs1) || isnan(Frs2))
                               fault = new FpExceptionIEEE754;
-                          if(Frs1s < Frs2s)
+                          if(Frs1 < Frs2)
                               fcc = 1;
-                          else if(Frs1s > Frs2s)
+                          else if(Frs1 > Frs2)
                               fcc = 2;
                           uint8_t firstbit = 10;
                           if(FCMPCC)
@@ -960,24 +968,24 @@ decode OP default Unknown::unknown()
                 0x55: FailUnimpl::fpsub16s();
                 0x56: FailUnimpl::fpsub32();
                 0x57: FailUnimpl::fpsub32s();
-                0x60: BasicOperate::fzero({{Frd.df = 0;}});
-                0x61: BasicOperate::fzeros({{Frds.sf = 0;}});
+                0x60: FpBasic::fzero({{Frd.df = 0;}});
+                0x61: FpBasic::fzeros({{Frds.sf = 0;}});
                 0x62: FailUnimpl::fnor();
                 0x63: FailUnimpl::fnors();
                 0x64: FailUnimpl::fandnot2();
                 0x65: FailUnimpl::fandnot2s();
-                0x66: BasicOperate::fnot2({{
+                0x66: FpBasic::fnot2({{
                         Frd.df = (double)(~((uint64_t)Frs2.df));
                 }});
-                0x67: BasicOperate::fnot2s({{
+                0x67: FpBasic::fnot2s({{
                         Frds.sf = (float)(~((uint32_t)Frs2s.sf));
                 }});
                 0x68: FailUnimpl::fandnot1();
                 0x69: FailUnimpl::fandnot1s();
-                0x6A: BasicOperate::fnot1({{
+                0x6A: FpBasic::fnot1({{
                         Frd.df = (double)(~((uint64_t)Frs1.df));
                 }});
-                0x6B: BasicOperate::fnot1s({{
+                0x6B: FpBasic::fnot1s({{
                         Frds.sf = (float)(~((uint32_t)Frs1s.sf));
                 }});
                 0x6C: FailUnimpl::fxor();
@@ -988,18 +996,18 @@ decode OP default Unknown::unknown()
                 0x71: FailUnimpl::fands();
                 0x72: FailUnimpl::fxnor();
                 0x73: FailUnimpl::fxnors();
-                0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}});
-                0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}});
+                0x74: FpBasic::fsrc1({{Frd.udw = Frs1.udw;}});
+                0x75: FpBasic::fsrc1s({{Frds.uw = Frs1s.uw;}});
                 0x76: FailUnimpl::fornot2();
                 0x77: FailUnimpl::fornot2s();
-                0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}});
-                0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}});
+                0x78: FpBasic::fsrc2({{Frd.udw = Frs2.udw;}});
+                0x79: FpBasic::fsrc2s({{Frds.uw = Frs2s.uw;}});
                 0x7A: FailUnimpl::fornot1();
                 0x7B: FailUnimpl::fornot1s();
                 0x7C: FailUnimpl::for();
                 0x7D: FailUnimpl::fors();
-                0x7E: BasicOperate::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
-                0x7F: BasicOperate::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
+                0x7E: FpBasic::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
+                0x7F: FpBasic::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
                 0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
                 0x81: FailUnimpl::siam();
             }
@@ -1236,16 +1244,20 @@ decode OP default Unknown::unknown()
                Rd.uw = uReg0;}}, {{EXT_ASI}});
         format Trap {
             0x20: Load::ldf({{Frds.uw = Mem.uw;}});
-            0x21: decode X {
+            0x21: decode RD {
                 0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
                 0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
+                default: FailUnimpl::ldfsrOther();
             }
             0x22: ldqf({{fault = new FpDisabled;}});
             0x23: Load::lddf({{Frd.udw = Mem.udw;}});
             0x24: Store::stf({{Mem.uw = Frds.uw;}});
-            0x25: decode X {
-                0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}});
-                0x1: Store::stxfsr({{Mem.udw = Fsr;}});
+            0x25: decode RD {
+                0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;
+                                    Fsr = insertBits(Fsr,16,14,0);}});
+                0x1: Store::stxfsr({{Mem.udw = Fsr;
+                                    Fsr = insertBits(Fsr,16,14,0);}});
+                default: FailUnimpl::stfsrOther();
             }
             0x26: stqf({{fault = new FpDisabled;}});
             0x27: Store::stdf({{Mem.udw = Frd.udw;}});
index e8762a20502f3b045c3efe04824c6aaeeea5e7cb..fac523aeb688a1a4cba12efa42f479826b2a45e1 100644 (file)
@@ -103,3 +103,42 @@ def format BasicOperate(code, *flags) {{
         decode_block = BasicDecode.subst(iop)
         exec_output = BasicExecute.subst(iop)
 }};
+
+def format FpBasic(code, *flags) {{
+        fp_code = """
+    Fsr = insertBits(Fsr,4,0,0);
+#if defined(__sun) || defined (__OpenBSD__)
+    fp_rnd newrnd = FP_RN;
+    switch (Fsr<31:30>) {
+      case 0: newrnd = FP_RN; break;
+      case 1: newrnd = FP_RZ; break;
+      case 2: newrnd = FP_RP; break;
+      case 3: newrnd = FP_RM; break;
+    }
+    fp_rnd oldrnd = fpsetround(newrnd);
+#else
+    int newrnd = FE_TONEAREST;
+    switch (Fsr<31:30>) {
+      case 0: newrnd = FE_TONEAREST; break;
+      case 1: newrnd = FE_TOWARDZERO; break;
+      case 2: newrnd = FE_UPWARD; break;
+      case 3: newrnd = FE_DOWNWARD; break;
+    }
+    int oldrnd = fegetround();
+    fesetround(newrnd);
+#endif
+"""
+        fp_code += code
+        fp_code += """
+#if defined(__sun) || defined (__OpenBSD__)
+    fpsetround(oldrnd);
+#else
+    fesetround(oldrnd);
+#endif
+"""
+        iop = InstObjParams(name, Name, 'SparcStaticInst', fp_code, flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = BasicExecute.subst(iop)
+}};
index a6dca9bf136ae2603eae3ee92bc34ad2903118f5..d2ef6715496c3e0fa324e4fcf617966971dda9dc 100644 (file)
@@ -53,7 +53,7 @@ output decoder {{
 #include "cpu/thread_context.hh"  // for Jump::branchTarget()
 #include "mem/packet.hh"
 
-#if defined(linux)
+#if defined(linux) || defined(__APPLE__)
 #include <fenv.h>
 #endif
 #include <algorithm>
@@ -62,9 +62,14 @@ using namespace SparcISA;
 }};
 
 output exec {{
-#if defined(linux)
+#if defined(linux) || defined(__APPLE__)
 #include <fenv.h>
 #endif
+
+#if defined(__sun) || defined (__OpenBSD__)
+#include <ieeefp.h>
+#endif
+
 #include <limits>
 
 #include <cmath>
index 0fe3e96b2405cb3dd1fd4dedf44f84d5dcf1ca24..8b612e8b4407665c570141b3fe3aaa6b8db1935c 100644 (file)
@@ -232,6 +232,7 @@ MiscReg MiscRegFile::readReg(int miscReg)
 
         /** Floating Point Status Register */
       case MISCREG_FSR:
+        DPRINTF(Sparc, "FSR read as: %#x\n", fsr);
         return fsr;
 
       case MISCREG_MMU_P_CONTEXT:
@@ -337,10 +338,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
       case MISCREG_PCR:
       case MISCREG_PIC:
         panic("Performance Instrumentation not impl\n");
-        /** Floating Point Status Register */
-      case MISCREG_FSR:
-        warn("Reading FSR Floating Point not implemented\n");
-        break;
       case MISCREG_SOFTINT_CLR:
       case MISCREG_SOFTINT_SET:
         panic("Can read from softint clr/set\n");
@@ -488,6 +485,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
         /** Floating Point Status Register */
       case MISCREG_FSR:
         fsr = val;
+        DPRINTF(Sparc, "FSR written with: %#x\n", fsr);
         break;
 
       case MISCREG_MMU_P_CONTEXT:
index e34ae3731773b1531972ee41052803adb9027b36..672b06eaf5c6043363c75aac1f4c29a96bacd893 100644 (file)
@@ -450,16 +450,13 @@ Trace::InstRecord::dump(ostream &outs)
                                 diffTlb = true;
                     }
 
-                    if ((diffPC || diffCC || diffInst || diffIntRegs ||
+                    if (diffPC || diffCC || diffInst || diffIntRegs ||
                          diffFpRegs || diffTpc || diffTnpc || diffTstate ||
                          diffTt || diffHpstate || diffHtstate || diffHtba ||
                          diffPstate || diffY || diffCcr || diffTl || diffFsr ||
                          diffGl || diffAsi || diffPil || diffCwp || diffCansave ||
                          diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
-                        && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
-                        && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
-                            && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
-                       ) {
+                       {
 
                         outs << "Differences found between M5 and Legion:";
                         if (diffPC)
@@ -639,7 +636,7 @@ Trace::InstRecord::dump(ostream &outs)
                                 char label[8];
                                 sprintf(label, "%%f%d", x);
                                 printRegPair(outs, label,
-                                 thread->readFloatRegBits(x,FloatRegFile::DoubleWidth),
+                                 thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth),
                                  shared_data->fpregs[x]);
                             }
                         }