Create a filter and a union to translate the SPARC instruction implementations from...
authorGabe Black <gblack@eecs.umich.edu>
Wed, 11 Apr 2007 12:25:00 +0000 (12:25 +0000)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 11 Apr 2007 12:25:00 +0000 (12:25 +0000)
--HG--
extra : convert_revision : 609ba35bbb13cbd1998e93957cb051461442d1f9

src/arch/sparc/isa/base.isa
src/arch/sparc/isa/formats/basic.isa
src/arch/sparc/isa/formats/mem/basicmem.isa
src/arch/sparc/isa/formats/mem/blockmem.isa
src/arch/sparc/isa/operands.isa

index bba63f40798eeb9afb611e707fabc171097846ed..4339003e075a114376565c3da9c530bc363312e1 100644 (file)
@@ -154,6 +154,76 @@ def template ROrImmDecode {{
     }
 }};
 
+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 ("Frd", "Frs1", "Frs2", "Frd_N"):
+            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
+                foundOne = True
+                op = match.groups()
+                (op_full, op_base, op_ext) = op
+                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, code)
+                is_int = False
+                member = "d"
+                if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
+                    is_int = True
+                    member = "ui"
+                if is_src:
+                    code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
+                        (opName, opName, opName, member)) + code
+                if is_dest:
+                    code += '''
+                        %s_low = DoubleSingle(%s).s[1];
+                        %s_high = DoubleSingle(%s).s[0];''' % \
+                             (opName, opName, opName, opName)
+                if is_int:
+                    code = ("uint64_t %s;" % opName) + code
+                else:
+                    code = ("double %s;" % opName) + code
+        return code
+}};
+
 let {{
     def splitOutImm(code):
         matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
index 017f43780d1ac905d4a0ae0faab057250de6bb90..7665d2d4fa7e13105c858cd12de39e0f34ed3499 100644 (file)
@@ -97,6 +97,7 @@ def template BasicDecodeWithMnemonic {{
 
 // The most basic instruction format... used only for a few misc. insts
 def format BasicOperate(code, *flags) {{
+        code = filterDoubles(code)
         iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
@@ -140,6 +141,7 @@ def format FpBasic(code, *flags) {{
     fesetround(oldrnd);
 #endif
 """
+        fp_code = filterDoubles(fp_code)
         iop = InstObjParams(name, Name, 'SparcStaticInst', fp_code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
index 7512628112307b0d8ad084eb40ae60a4c48a5bb0..2f62c7bef008c573be4dd516398dc396ae9ea258 100644 (file)
@@ -71,6 +71,7 @@ let {{
 }};
 
 def format LoadAlt(code, asi, *opt_flags) {{
+        code = filterDoubles(code)
         (header_output,
          decoder_output,
          exec_output,
@@ -79,6 +80,7 @@ def format LoadAlt(code, asi, *opt_flags) {{
 }};
 
 def format StoreAlt(code, asi, *opt_flags) {{
+        code = filterDoubles(code)
         (header_output,
          decoder_output,
          exec_output,
@@ -87,6 +89,7 @@ def format StoreAlt(code, asi, *opt_flags) {{
 }};
 
 def format Load(code, *opt_flags) {{
+        code = filterDoubles(code)
         (header_output,
          decoder_output,
          exec_output,
@@ -95,6 +98,7 @@ def format Load(code, *opt_flags) {{
 }};
 
 def format Store(code, *opt_flags) {{
+        code = filterDoubles(code)
         (header_output,
          decoder_output,
          exec_output,
index 499685a5cfeb19fbd8939abec213e51ad8d2d02a..e19016bd0359a9614c5855892a3b7eb868d650a5 100644 (file)
@@ -317,6 +317,7 @@ let {{
 }};
 
 def format BlockLoad(code, asi, *opt_flags) {{
+        code = filterDoubles(code)
         # We need to make sure to check the highest priority fault last.
         # That way, if other faults have been detected, they'll be overwritten
         # rather than the other way around.
@@ -329,6 +330,7 @@ def format BlockLoad(code, asi, *opt_flags) {{
 }};
 
 def format BlockStore(code, asi, *opt_flags) {{
+        code = filterDoubles(code)
         # We need to make sure to check the highest priority fault last.
         # That way, if other faults have been detected, they'll be overwritten
         # rather than the other way around.
index 038919bd1fcdb6fd849bc1f4faf5c2c8f087e102..58d616a7a20d9f30a56d84e2eb8a333b9eb56aa5 100644 (file)
@@ -52,6 +52,16 @@ output header {{
     {
         return (regNum & (~1)) | ((regNum & 1) << 5);
     }
+
+    static inline unsigned int dfprl(unsigned int regNum)
+    {
+        return dfpr(regNum) & (~0x1);
+    }
+
+    static inline unsigned int dfprh(unsigned int regNum)
+    {
+        return dfpr(regNum) | 0x1;
+    }
 }};
 
 def operands {{
@@ -79,21 +89,43 @@ def operands {{
     # differently, they get different operands. The single precision versions
     # have an s post pended to their name.
     'Frds':            ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
-    'Frd':             ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
+    #'Frd':            ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
+    'Frd_low':         ('FloatReg', 'uw', 'dfprl(RD)', 'IsFloating', 10),
+    'Frd_high':                ('FloatReg', 'uw', 'dfprh(RD)', 'IsFloating', 10),
     # Each Frd_N refers to the Nth double precision register from Frd.
     # Note that this adds twice N to the register number.
-    'Frd_0':           ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
-    'Frd_1':           ('FloatReg', 'df', 'dfpr(RD) + 2', 'IsFloating', 10),
-    'Frd_2':           ('FloatReg', 'df', 'dfpr(RD) + 4', 'IsFloating', 10),
-    'Frd_3':           ('FloatReg', 'df', 'dfpr(RD) + 6', 'IsFloating', 10),
-    'Frd_4':           ('FloatReg', 'df', 'dfpr(RD) + 8', 'IsFloating', 10),
-    'Frd_5':           ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10),
-    'Frd_6':           ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10),
-    'Frd_7':           ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10),
+    #'Frd_0':          ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
+    'Frd_0_low':       ('FloatReg', 'uw', 'dfprl(RD)', 'IsFloating', 10),
+    'Frd_0_high':      ('FloatReg', 'uw', 'dfprh(RD)', 'IsFloating', 10),
+    #'Frd_1':          ('FloatReg', 'df', 'dfpr(RD) + 2', 'IsFloating', 10),
+    'Frd_1_low':       ('FloatReg', 'uw', 'dfprl(RD) + 2', 'IsFloating', 10),
+    'Frd_1_high':      ('FloatReg', 'uw', 'dfprh(RD) + 2', 'IsFloating', 10),
+    #'Frd_2':          ('FloatReg', 'df', 'dfpr(RD) + 4', 'IsFloating', 10),
+    'Frd_2_low':       ('FloatReg', 'uw', 'dfprl(RD) + 4', 'IsFloating', 10),
+    'Frd_2_high':      ('FloatReg', 'uw', 'dfprh(RD) + 4', 'IsFloating', 10),
+    #'Frd_3':          ('FloatReg', 'df', 'dfpr(RD) + 6', 'IsFloating', 10),
+    'Frd_3_low':       ('FloatReg', 'uw', 'dfprl(RD) + 6', 'IsFloating', 10),
+    'Frd_3_high':      ('FloatReg', 'uw', 'dfprh(RD) + 6', 'IsFloating', 10),
+    #'Frd_4':          ('FloatReg', 'df', 'dfpr(RD) + 8', 'IsFloating', 10),
+    'Frd_4_low':       ('FloatReg', 'uw', 'dfprl(RD) + 8', 'IsFloating', 10),
+    'Frd_4_high':      ('FloatReg', 'uw', 'dfprh(RD) + 8', 'IsFloating', 10),
+    #'Frd_5':          ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10),
+    'Frd_5_low':       ('FloatReg', 'uw', 'dfprl(RD) + 10', 'IsFloating', 10),
+    'Frd_5_high':      ('FloatReg', 'uw', 'dfprh(RD) + 10', 'IsFloating', 10),
+    #'Frd_6':          ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10),
+    'Frd_6_low':       ('FloatReg', 'uw', 'dfprl(RD) + 12', 'IsFloating', 10),
+    'Frd_6_high':      ('FloatReg', 'uw', 'dfprh(RD) + 12', 'IsFloating', 10),
+    #'Frd_7':          ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10),
+    'Frd_7_low':       ('FloatReg', 'uw', 'dfprl(RD) + 14', 'IsFloating', 10),
+    'Frd_7_high':      ('FloatReg', 'uw', 'dfprh(RD) + 14', 'IsFloating', 10),
     'Frs1s':           ('FloatReg', 'sf', 'RS1', 'IsFloating', 11),
-    'Frs1':            ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
+    #'Frs1':           ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
+    'Frs1_low':                ('FloatReg', 'uw', 'dfprl(RS1)', 'IsFloating', 11),
+    'Frs1_high':       ('FloatReg', 'uw', 'dfprh(RS1)', 'IsFloating', 11),
     'Frs2s':           ('FloatReg', 'sf', 'RS2', 'IsFloating', 12),
-    'Frs2':            ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
+    #'Frs2':           ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
+    'Frs2_low':                ('FloatReg', 'uw', 'dfprl(RS2)', 'IsFloating', 12),
+    'Frs2_high':       ('FloatReg', 'uw', 'dfprh(RS2)', 'IsFloating', 12),
     'NPC':             ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
     'NNPC':            ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
     # Registers which are used explicitly in instructions