no python files to be committed in isafunctions
[openpower-isa.git] / src / openpower / decoder / pseudo / parser.py
index b24baeacf24d94ec01c66a2288ba749961c5e800..4f11f6f14c996caf50ddb5a83e99c2a9e1e707c7 100644 (file)
@@ -24,7 +24,7 @@ import ast
 # Helper function
 
 regs = ['RA', 'RS', 'RB', 'RC', 'RT']
-fregs = ['FRA', 'FRS', 'FRB', 'FRC', 'FRT']
+fregs = ['FRA', 'FRS', 'FRB', 'FRC', 'FRT', 'FRS']
 
 def Assign(autoassign, assignname, left, right, iea_mode):
     names = []
@@ -196,6 +196,15 @@ def apply_trailer(atom, trailer, read_regs):
         trailer = trailer[2]
     if trailer[0] == "CALL":
         #p[0] = ast.Expr(ast.Call(p[1], p[2][1], []))
+        for arg in trailer[1]:
+            if isinstance(arg, ast.Name):
+                name = arg.id
+                if name in regs + fregs:
+                    read_regs.add(name)
+        # special-case, function named "SVSTATE_NEXT" must be made "self.xxxx"
+        if atom.id == 'SVSTATE_NEXT':
+            name = ast.Name("self", ast.Load())
+            atom = ast.Attribute(name, atom, ast.Load())
         return ast.Call(atom, trailer[1], [])
         # if p[1].id == 'print':
         #    p[0] = ast.Printnl(ast.Tuple(p[2][1]), None, None)
@@ -266,10 +275,14 @@ class PowerParser:
     def __init__(self, form, include_carry_in_write=False):
         self.include_ca_in_write = include_carry_in_write
         self.gprs = {}
-        form = self.sd.sigforms[form]
-        print(form)
-        formkeys = form._asdict().keys()
+        if form is not None:
+            form = self.sd.sigforms[form]
+            print(form)
+            formkeys = form._asdict().keys()
+        else:
+            formkeys = []
         self.declared_vars = set()
+        self.fnparm_vars = set()
         for rname in regs + fregs:
             self.gprs[rname] = None
             self.declared_vars.add(rname)
@@ -317,6 +330,8 @@ class PowerParser:
     def p_funcdef(self, p):
         "funcdef : DEF NAME parameters COLON suite"
         p[0] = ast.FunctionDef(p[2], p[3], p[5], ())
+        # reset function parameters after suite is identified
+        self.fnparm_vars = set()
 
     # parameters: '(' [varargslist] ')'
     def p_parameters(self, p):
@@ -327,6 +342,13 @@ class PowerParser:
         else:
             args = p[2]
         p[0] = ast.arguments(args=args, vararg=None, kwarg=None, defaults=[])
+        # during the time between parameters identified and suite is not
+        # there is a window of opportunity to declare the function parameters
+        # in-scope, for use to not overwrite them with auto-assign
+        self.fnparm_vars = set()
+        for arg in args:
+            print ("adding fn parm", arg)
+            self.fnparm_vars.add(arg)
 
     # varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] |
     # '**' NAME) |
@@ -336,7 +358,8 @@ class PowerParser:
         """varargslist : varargslist COMMA NAME
                        | NAME"""
         if len(p) == 4:
-            p[0] = p[1] + p[3]
+            print (p[1], p[3])
+            p[0] = p[1] + [p[3]]
         else:
             p[0] = [p[1]]
 
@@ -374,10 +397,11 @@ class PowerParser:
                       | expr_stmt"""
         if isinstance(p[1], ast.Call):
             p[0] = ast.Expr(p[1])
-        elif isinstance(p[1], ast.Name) and p[1].id == 'TRAP':
-            # TRAP needs to actually be a function
+        elif isinstance(p[1], ast.Name) and p[1].id in ['TRAP', 'SVSTATE_NEXT']:
+            fname = p[1].id
+            # TRAP and SVSTATE_NEXT needs to actually be a function
             name = ast.Name("self", ast.Load())
-            name = ast.Attribute(name, "TRAP", ast.Load())
+            name = ast.Attribute(name, fname, ast.Load())
             p[0] = ast.Call(name, [], [])
         else:
             p[0] = p[1]
@@ -407,16 +431,23 @@ class PowerParser:
                     if name in self.gprs:
                         # add to list of uninitialised
                         self.uninit_regs.add(name)
+                    # work out if this is an ininitialised variable
+                    # that should be auto-assigned simply by being "sliced"
                     autoassign = (name not in self.declared_vars and
+                                  name not in self.fnparm_vars and
                                   name not in self.special_regs)
             elif isinstance(p[1], ast.Call) and p[1].func.id in \
                             ['GPR', 'FPR', 'SPR']:
                 print(astor.dump_tree(p[1]))
                 # replace GPR(x) with GPR[x]
                 idx = p[1].args[0].id
-                ridx = ast.Name("_%s" % idx, ast.Load())
+                if idx in regs + fregs:
+                    ridx = ast.Name("_%s" % idx, ast.Load())
+                else:
+                    ridx = ast.Name(idx, ast.Load())
                 p[1] = ast.Subscript(p[1].func, ridx, ast.Load())
-                self.read_regs.add(idx)  # add to list of regs to read
+                if idx in self.gprs:
+                    self.read_regs.add(idx)  # add to list of regs to read
             elif isinstance(p[1], ast.Call) and p[1].func.id == 'MEM':
                 print("mem assign")
                 print(astor.dump_tree(p[1]))
@@ -700,7 +731,9 @@ class PowerParser:
         if self.include_ca_in_write:
             if name in ['CA', 'CA32']:
                 self.write_regs.add(name)
-        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR', 'SVSTATE']:
+        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR',
+                     'SVSTATE', 'SVREMAP',
+                     'SVSHAPE0', 'SVSHAPE1', 'SVSHAPE2', 'SVSHAPE3']:
             self.special_regs.add(name)
             self.write_regs.add(name)  # and add to list to write
         p[0] = ast.Name(id=name, ctx=ast.Load())
@@ -866,7 +899,8 @@ class PowerParser:
 
 class GardenSnakeParser(PowerParser):
     def __init__(self, lexer=None, debug=False, form=None, incl_carry=False):
-        self.sd = create_pdecode()
+        if form is not None:
+            self.sd = create_pdecode()
         PowerParser.__init__(self, form, incl_carry)
         self.debug = debug
         if lexer is None: