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
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index 4e2b12f..2fa00f2 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -60,6 +60,81 @@ output header {{
 
 }};
 
+output header {{
+    union DoubleSingle
+    {
+        double d;
+        uint64_t ui;
+        uint32_t s[2];
+        DoubleSingle(double _d) : d(_d)
+        {}
+        DoubleSingle(uint64_t _ui) : ui(_ui)
+        {}
+        DoubleSingle(uint32_t _s0, uint32_t _s1)
+        {
+            s[0] = _s0;
+            s[1] = _s1;
+        }
+    };
+}};
+
+let {{
+    def filterDoubles(code):
+        assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
+        for opName in ("Fd", "Fs", "Ft", "Fr"):
+            next_pos = 0
+            operandsREString = (r'''
+            (?<![\w\.])             # neg. lookbehind assertion: prevent partial matches
+            ((%s)(?:\.(\w+))?)   # match: operand with optional '.' then suffix
+            (?![\w\.])             # neg. lookahead assertion: prevent partial matches
+            ''' % opName)
+            operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
+            is_src = False
+            is_dest = False
+            extension = None
+            foundOne = False
+            while 1:
+                match = operandsRE.search(code, next_pos)
+                if not match:
+                    break
+                op = match.groups()
+                (op_full, op_base, op_ext) = op
+                # A floating-point operand is 64-bits wide if the
+                # extension is either df (double float) or ud
+                # (uninterpreted doubleword).
+                if not op_ext in ("df", "ud"):
+                    break
+                foundOne = True
+                is_dest_local = (assignRE.match(code, match.end()) != None)
+                is_dest = is_dest or is_dest_local
+                is_src = is_src or not is_dest_local
+                if extension and extension != op_ext:
+                    raise Exception, "Inconsistent extensions in double filter."
+                extension = op_ext
+                next_pos = match.end()
+            if foundOne:
+                # Get rid of any unwanted extension
+                code = operandsRE.sub(op_base + "_d", code)
+                is_int = False
+                member = "d"
+                if extension in ("ud"):
+                    is_int = True
+                    member = "ui"
+                if is_src:
+                    code = ("%s_d = DoubleSingle(%s_low, %s_high).%s;\n" % \
+                        (opName, opName, opName, member)) + code
+                if is_dest:
+                    code += '''
+                        %s_low = DoubleSingle(%s_d).s[0];
+                        %s_high = DoubleSingle(%s_d).s[1];\n''' % \
+                             (opName, opName, opName, opName)
+                if is_int:
+                    code = ("uint64_t %s_d;\n" % opName) + code
+                else:
+                    code = ("double %s_d;\n" % opName) + code
+        return code
+}};
+
 //Ouputs to decoder.cc
 output decoder {{
 
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
index 92568c5..653c607 100644
--- a/src/arch/mips/isa/formats/basic.isa
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -91,6 +91,7 @@ def template BasicDecodeWithMnemonic {{
 
 // The most basic instruction format...
 def format BasicOp(code, *flags) {{
+        code = filterDoubles(code)
         iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
index 72d87f9..b86f240 100644
--- a/src/arch/mips/isa/formats/fp.isa
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -181,7 +181,7 @@ def template FloatingPointExecute {{
                 %(op_rd)s;
 
                 //Check if any FP operand is a NaN value
-                if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
+                //if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
                     %(code)s;
 
                     //Change this code for Full-System/Sycall Emulation
@@ -192,14 +192,14 @@ def template FloatingPointExecute {{
                     //Check for IEEE 754 FP Exceptions
                     //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
                     if (
-#if FULL_SYSTEM
-                        !fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
-#endif
+                        //#if FULL_SYSTEM
+                        //!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
+                        //#endif
                         fault == NoFault)
                     {
                         %(op_wb)s;
                     }
-                }
+                    //}
 
                 return fault;
         }
@@ -207,6 +207,7 @@ def template FloatingPointExecute {{
 
 // Primary format for float point operate instructions:
 def format FloatOp(code, *flags) {{
+        code = filterDoubles(code)
         iop = InstObjParams(name, Name, 'FPOp', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
@@ -246,6 +247,7 @@ def format FloatCompareOp(cond_code, *flags) {{
     code +=  cond_code + '}'
     code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
 
+    code = filterDoubles(code)
     iop = InstObjParams(name, Name, 'FPCompareOp', code)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
@@ -297,6 +299,7 @@ def format FloatConvertOp(code, *flags) {{
     else:
         code += 'val); '
 
+    code = filterDoubles(code)
     iop = InstObjParams(name, Name, 'FPOp', code)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
@@ -305,6 +308,7 @@ def format FloatConvertOp(code, *flags) {{
 }};
 
 def format FloatAccOp(code, *flags) {{
+        code = filterDoubles(code)
         iop = InstObjParams(name, Name, 'FPOp', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
@@ -314,6 +318,7 @@ def format FloatAccOp(code, *flags) {{
 
 // Primary format for float64 operate instructions:
 def format Float64Op(code, *flags) {{
+        code = filterDoubles(code)
         iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index 161a52b..7ecc35e 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -534,6 +534,7 @@ def template MiscCompleteAcc {{
 
 def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                       decode_template = ImmNopCheckDecode,
@@ -543,6 +544,7 @@ def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
 
 def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                       exec_template_base = 'Store')
@@ -550,6 +552,7 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
 
 def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     inst_flags += ['IsIndexed']
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -559,6 +562,7 @@ def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
 
 def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     inst_flags += ['IsIndexed']
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -567,6 +571,7 @@ def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
 
 def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     inst_flags += ['IsIndexed', 'IsFloating']
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -576,6 +581,7 @@ def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
 
 def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     inst_flags += ['IsIndexed', 'IsFloating']
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -585,6 +591,7 @@ def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
 
 def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     decl_code = 'uint32_t mem_word = Mem.uw;\n'
     decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
     decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
@@ -602,6 +609,7 @@ def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
 
 def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     decl_code = 'uint32_t mem_word = 0;\n'
     decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
     decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
@@ -633,6 +641,7 @@ def format Prefetch(ea_code = {{ EA = Rs + disp; }},
 def format StoreCond(memacc_code, postacc_code,
                      ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
+    memacc_code = filterDoubles(memacc_code)
     (header_output, decoder_output, decode_block, exec_output) = \
         LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                       postacc_code, exec_template_base = 'StoreCond')
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
index 50726cd..ca52265 100644
--- a/src/arch/mips/isa/operands.isa
+++ b/src/arch/mips/isa/operands.isa
@@ -82,9 +82,17 @@ def operands {{
 
     #Floating Point Reg Operands
     'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
+    'Fd_low': ('FloatReg', 'uw', 'FD', 'IsFloating', 1),
+    'Fd_high': ('FloatReg', 'uw', 'FD + 1', 'IsFloating', 1),
     'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
+    'Fs_low': ('FloatReg', 'uw', 'FS', 'IsFloating', 2),
+    'Fs_high': ('FloatReg', 'uw', 'FS + 1', 'IsFloating', 2),
     'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
+    'Ft_low': ('FloatReg', 'uw', 'FT', 'IsFloating', 3),
+    'Ft_high': ('FloatReg', 'uw', 'FT + 1', 'IsFloating', 3),
     'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
+    'Fr_low': ('FloatReg', 'uw', 'FR', 'IsFloating', 3),
+    'Fr_high': ('FloatReg', 'uw', 'FR + 1', 'IsFloating', 3),
 
     #Special Purpose Floating Point Control Reg Operands
     'FIR':  ('FloatReg', 'uw', 'FLOATREG_FIR', 'IsFloating', 1),
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to