I stumbled across another MIPS floating-point problem.  This one has
to do with conversion from fixed-point to floating point.  The CVT
instructions convert between various formats.  Two of the supported
conversions are Word to Single (cvt.s.w) and Word to Double (cvt.d.w).
When the integer to be converted is a negative number the conversion
to floating-point should result in a floating-point number that is
negative as well.  However, because the integer word is incorrectly
treated as unsigned by M5 before the conversion, the conversion
results in an incorrect floating-point result.  Here is a simple C
program that reveals the bug:

#include <stdio.h>
int main (void)
{
  int i = -13;
  float f = (float)i;
  printf ("%f\n", f);
  return 0;
}

When I compile this for MIPS, a cvt.s.w instruction handles the cast
conversion and the variable f is incorrect.  The following is printed
out:
4294967296.000000
instead of the correct answer:
-13.000000

The bug affects the SPEC 2000 benchmark crafty and results in
incorrect output.  The affected function in crafty is
DisplayEvaluation() in utility.c

The attached patch fixes the bug.


On Wed, Dec 23, 2009 at 1:51 PM, Matt <[email protected]> wrote:
> I followed your advice, Gabe, and fixed double-precision
> floating-point in MIPS by following the SPARC implementation.  With the
> attached patch, basic double-precision stuff is fixed.  There are a
> couple of things that are not yet fixed:
> 1. floating-point NaN checking.
> 2. instructions that assume a 64-bit FPU (like most of the Paired
>   Single format instructions).  I don't think that at this time there
>   is a way to configure M5 to model a 64-bit FPU anyway.
>
> --
> Cheers,
> Matt
>



-- 
Cheers,
Matt
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index c531347..69f5b7b 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -1287,8 +1287,8 @@ decode OPCODE_HI default Unknown::unknown() {
                     //Field When rs=W
                     0x4: decode FUNCTION {
                         format FloatConvertOp {
-                            0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
-                            0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
+                            0x20: cvt_s_w({{ val = Fs.sw; }}, ToSingle);
+                            0x21: cvt_d_w({{ val = Fs.sw; }}, ToDouble);
                             0x26: CP1Unimpl::cvt_ps_w();
                         }
                         default: CP1Unimpl::unknown();
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
index b86f240..9c00523 100644
--- a/src/arch/mips/isa/formats/fp.isa
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -269,6 +269,9 @@ def format FloatConvertOp(code, *flags) {{
     elif '.uw' in code:
         code = 'uint32_t ' + code + '\n'
         convert += 'WORD_TO_'
+    elif '.sw' in code:
+        code = 'int32_t ' + code + '\n'
+        convert += 'WORD_TO_'
     elif '.ud' in code:
         code = 'uint64_t ' + code + '\n'
         convert += 'LONG_TO_'
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to