mips: Floating point convert bug fix
authorChristopher Torng <clt67@cornell.edu>
Mon, 30 Dec 2013 01:29:45 +0000 (19:29 -0600)
committerChristopher Torng <clt67@cornell.edu>
Mon, 30 Dec 2013 01:29:45 +0000 (19:29 -0600)
In mips architecture, floating point convert instructions use the
FloatConvertOp format defined in src/arch/mips/isa/formats/fp.isa. The type
of the operands in the ISA description file (_sw for signed word, or _sf for
signed float, etc.) is  used to create a type for the operand in C++. Then the
operand is converted using the fpConvert() function in src/arch/mips/utility.cc.

If we are converting from a word to a float, and we want to convert 0xffffffff,
we expect -1 to be passed into fpConvert(). Instead, we see MAX_INT passed in.
Then fpConvert() converts _val_ to MAX_INT in single-precision floating point,
and we get the wrong value.

To fix it, the signs of the convert operands are being changed from unsigned to
signed in the MIPS ISA description.

Then, the FloatConvertOp format is being changed to insert a int32_t into the
C++ code instead of a uint32_t.

Committed by: Nilay Vaish <nilay@cs.wisc.edu>

src/arch/mips/isa/decoder.isa
src/arch/mips/isa/formats/fp.isa

index 5ff23ca5e6c1437b8a409fc27f886e000736344c..22e34e32a1193fd02ddcc9f1dcbba072ff2caaa4 100644 (file)
@@ -1242,8 +1242,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();
@@ -1255,8 +1255,8 @@ decode OPCODE_HI default Unknown::unknown() {
                     //floating point operations are enabled."
                     0x5: decode FUNCTION {
                         format FloatConvertOp {
-                            0x20: cvt_s_l({{ val = Fs_ud; }}, ToSingle);
-                            0x21: cvt_d_l({{ val = Fs_ud; }}, ToDouble);
+                            0x20: cvt_s_l({{ val = Fs_sd; }}, ToSingle);
+                            0x21: cvt_d_l({{ val = Fs_sd; }}, ToDouble);
                             0x26: CP1Unimpl::cvt_ps_l();
                         }
                         default: CP1Unimpl::unknown();
index e6f0258a0854f594f153dd9ef52d39531a96fb01..1b061bc63449a83bb5c6de10e89550f3c4e255dc 100644 (file)
@@ -268,11 +268,11 @@ def format FloatConvertOp(code, *flags) {{
     elif '_df' in code:
         code = 'double ' + code + '\n'
         convert += 'DOUBLE_TO_'
-    elif '_uw' in code:
-        code = 'uint32_t ' + code + '\n'
+    elif '_sw' in code:
+        code = 'int32_t ' + code + '\n'
         convert += 'WORD_TO_'
-    elif '_ud' in code:
-        code = 'uint64_t ' + code + '\n'
+    elif '_sd' in code:
+        code = 'int64_t ' + code + '\n'
         convert += 'LONG_TO_'
     else:
         sys.exit("Error Determining Source Type for Conversion")