summaryrefslogtreecommitdiff
path: root/src/mem/slicc/ast/ChipComponentAccessAST.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/slicc/ast/ChipComponentAccessAST.py')
-rw-r--r--src/mem/slicc/ast/ChipComponentAccessAST.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py
new file mode 100644
index 000000000..841220c94
--- /dev/null
+++ b/src/mem/slicc/ast/ChipComponentAccessAST.py
@@ -0,0 +1,161 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import re
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Type
+
+class ChipComponentAccessAST(ExprAST):
+ def __init__(self, slicc, machine, mach_version, component):
+ super(ChipComponentAccessAST, self).__init__(slicc)
+ self.mach_var = machine
+ self.comp_var = component
+ self.mach_ver_expr = mach_version
+
+ def __repr__(self):
+ return "[ChipAccessExpr: %r]" % self.expr_vec
+
+ def generate(self, code):
+ void_type = self.symtab.find("void", Type)
+
+ mname = self.mach_var.name
+ cname = self.comp_var.name
+ var = self.symtab.machine_components[mname][cname]
+
+ vcode = str(var.code)
+
+ if self.chip_ver_expr is not None:
+ # replace self.chip with specified chip
+ gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline()
+ vcode = re.sub("m_chip", gcode, vcode)
+
+ # replace default "m_version" with the version we really want
+ gcode = "(%s)" % self.mach_ver_expr.inline()
+ vcode = re.sub("m_version", gcode, vcode)
+
+ return_type, gcode = self.generate_access(var)
+ code("($vcode)$gcode")
+ return return_type
+
+class ChipMethodAccessAST(ChipComponentAccessAST):
+ def __init__(self, slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec):
+ s = super(ChipMethodAccessAST, self)
+ s.__init__(slicc, machine, mach_version, component)
+
+ self.chip_ver_expr = chip_version
+ self.expr_vec = expr_vec
+ self.proc_name = proc_name
+
+ def generate_access(self, var):
+ # generate code
+ paramTypes = []
+ gcode = []
+ for expr in self.expr_vec:
+ t,c = expr.generate()
+ paramTypes.append(t)
+ gcode.append(c)
+
+ methodId = var.type.methodId(self.proc_name, paramTypes)
+
+ # Verify that this is a method of the object
+ if not var.type.methodExist(methodId):
+ error("%s: Type '%s' does not have a method '%s'" % \
+ ("Invalid method call", var.type, methodId))
+
+ expected_size = len(var.type.methodParamType(methodId))
+ if len(self.expr_vec) != expected_size:
+ # Right number of parameters
+ self.error("Wrong number of parameters for function name: " +\
+ "'%s', expected: %d, actual: %d",
+ self.proc_name, expected_size, len(self.expr_vec))
+
+ for expr,expected,actual in zip(self.expr_vec,
+ var.type.methodParamType(methodId),
+ paramTypes):
+ # Check the types of the parameter
+ if actual != expected:
+ expr.error("Type mismatch: expected: %s actual: %s",
+ expected, actual)
+
+ # method call
+ code = ".%s(%s)" % (self.proc_name, ', '.join(gcode))
+
+ # Return the return type of the method
+ return var.type.methodReturnType(methodId), code
+
+class LocalChipMethodAST(ChipMethodAccessAST):
+ # method call from local chip
+ def __init__(self, slicc, machine, mach_version, component, proc_name,
+ expr_vec):
+ s = super(LocalChipMethodAST, self)
+ s.__init__(slicc, None, machine, mach_version, component, proc_name,
+ expr_vec)
+
+class SpecifiedChipMethodAST(ChipMethodAccessAST):
+ # method call from specified chip
+ def __init__(self, slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec):
+ s = super(SpecifiedChipMethodAST, self)
+ s.__init__(slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec)
+
+class ChipMemberAccessAST(ChipComponentAccessAST):
+ # member access from specified chip
+ def __init__(self, chip_version, machine, mach_version, component,
+ field_name):
+ s = super(ChipMemberAccessAST, self)
+ s.__init__(slicc, machine, mach_version, component)
+
+ self.chip_ver_expr = chip_version
+ self.field_name = field_name
+
+ def generate_access(self, var):
+ # Verify that this is a valid field name for this type
+ if not var.type.dataMemberExist(self.field_name):
+ self.error("Invalid object field: " +\
+ "Type '%s' does not have data member %s",
+ var.type, self.field_name)
+
+ code += ").m_%s" % self.field_name
+
+ return var.type.dataMemberType(self.field_name), code
+
+class LocalChipMemberAST(ChipMemberAccessAST):
+ # member access from local chip
+ def __init__(self, slicc, machine, mach_version, component, field_name):
+ s = super(LocalChipMemberAST, self)
+ s.__init__(slicc, None, machine, mach_version, component, field_name)
+
+class SpecifiedChipMemberAST(ChipMemberAccessAST):
+ # member access from specified chip
+ def __init__(self, chip_version, machine, mach_version, component,
+ field_name):
+ s = super(SpecifiedChipMemberAST, self)
+ s.__init__(slicc, chip_version, machine, mach_version, component,
+ field_name)