Type.py revision 9171:ae88ecf37145
17322Sgblack@eecs.umich.edu# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
27322Sgblack@eecs.umich.edu# Copyright (c) 2009 The Hewlett-Packard Development Company
37322Sgblack@eecs.umich.edu# All rights reserved.
47322Sgblack@eecs.umich.edu#
57322Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
67322Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
77322Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
87322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
97322Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
107322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
117322Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
127322Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
137322Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
147322Sgblack@eecs.umich.edu# this software without specific prior written permission.
157322Sgblack@eecs.umich.edu#
167322Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177322Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187322Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197322Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207322Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217322Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227322Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237322Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247322Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257322Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267322Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277322Sgblack@eecs.umich.edu
287322Sgblack@eecs.umich.edufrom m5.util import orderdict
297322Sgblack@eecs.umich.edu
307322Sgblack@eecs.umich.edufrom slicc.util import PairContainer
317322Sgblack@eecs.umich.edufrom slicc.symbols.Symbol import Symbol
327322Sgblack@eecs.umich.edu
337322Sgblack@eecs.umich.educlass DataMember(PairContainer):
347322Sgblack@eecs.umich.edu    def __init__(self, ident, type, pairs, init_code):
357322Sgblack@eecs.umich.edu        super(DataMember, self).__init__(pairs)
367322Sgblack@eecs.umich.edu        self.ident = ident
377322Sgblack@eecs.umich.edu        self.type = type
387322Sgblack@eecs.umich.edu        self.init_code = init_code
397322Sgblack@eecs.umich.edu
407376Sgblack@eecs.umich.educlass Enumeration(PairContainer):
417376Sgblack@eecs.umich.edu    def __init__(self, ident, pairs):
427376Sgblack@eecs.umich.edu        super(Enumeration, self).__init__(pairs)
437376Sgblack@eecs.umich.edu        self.ident = ident
447376Sgblack@eecs.umich.edu
457376Sgblack@eecs.umich.educlass Method(object):
467376Sgblack@eecs.umich.edu    def __init__(self, return_type, param_types):
477376Sgblack@eecs.umich.edu        self.return_type = return_type
487376Sgblack@eecs.umich.edu        self.param_types = param_types
497376Sgblack@eecs.umich.edu
507376Sgblack@eecs.umich.educlass Type(Symbol):
517376Sgblack@eecs.umich.edu    def __init__(self, table, ident, location, pairs, machine=None):
527376Sgblack@eecs.umich.edu        super(Type, self).__init__(table, ident, location, pairs)
537376Sgblack@eecs.umich.edu        self.c_ident = ident
547376Sgblack@eecs.umich.edu        self.abstract_ident = ""
557376Sgblack@eecs.umich.edu        if machine:
567376Sgblack@eecs.umich.edu            if self.isExternal or self.isPrimitive:
577376Sgblack@eecs.umich.edu                if "external_name" in self:
587376Sgblack@eecs.umich.edu                    self.c_ident = self["external_name"]
597376Sgblack@eecs.umich.edu            else:
607376Sgblack@eecs.umich.edu                # Append with machine name
617376Sgblack@eecs.umich.edu                self.c_ident = "%s_%s" % (machine, ident)
627376Sgblack@eecs.umich.edu
637376Sgblack@eecs.umich.edu        self.pairs.setdefault("desc", "No description avaliable")
647376Sgblack@eecs.umich.edu
657376Sgblack@eecs.umich.edu        # check for interface that this Type implements
667376Sgblack@eecs.umich.edu        if "interface" in self:
677376Sgblack@eecs.umich.edu            interface = self["interface"]
687376Sgblack@eecs.umich.edu            if interface in ("Message", "NetworkMessage"):
697376Sgblack@eecs.umich.edu                self["message"] = "yes"
707376Sgblack@eecs.umich.edu            if interface == "NetworkMessage":
717376Sgblack@eecs.umich.edu                self["networkmessage"] = "yes"
727376Sgblack@eecs.umich.edu
737376Sgblack@eecs.umich.edu        # FIXME - all of the following id comparisons are fragile hacks
747376Sgblack@eecs.umich.edu        if self.ident in ("CacheMemory", "NewCacheMemory",
757376Sgblack@eecs.umich.edu                          "TLCCacheMemory", "DNUCACacheMemory",
767376Sgblack@eecs.umich.edu                          "DNUCABankCacheMemory", "L2BankCacheMemory",
777376Sgblack@eecs.umich.edu                          "CompressedCacheMemory", "PrefetchCacheMemory"):
787376Sgblack@eecs.umich.edu            self["cache"] = "yes"
797376Sgblack@eecs.umich.edu
807376Sgblack@eecs.umich.edu        if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"):
817376Sgblack@eecs.umich.edu            self["tbe"] = "yes"
827376Sgblack@eecs.umich.edu
837376Sgblack@eecs.umich.edu        if self.ident == "NewTBETable":
847376Sgblack@eecs.umich.edu            self["newtbe"] = "yes"
857376Sgblack@eecs.umich.edu
867376Sgblack@eecs.umich.edu        if self.ident == "TimerTable":
877376Sgblack@eecs.umich.edu            self["timer"] = "yes"
887376Sgblack@eecs.umich.edu
897376Sgblack@eecs.umich.edu        if self.ident == "DirectoryMemory":
907376Sgblack@eecs.umich.edu            self["dir"] = "yes"
917376Sgblack@eecs.umich.edu
927376Sgblack@eecs.umich.edu        if self.ident == "PersistentTable":
937376Sgblack@eecs.umich.edu            self["persistent"] = "yes"
947376Sgblack@eecs.umich.edu
957376Sgblack@eecs.umich.edu        if self.ident == "Prefetcher":
967376Sgblack@eecs.umich.edu            self["prefetcher"] = "yes"
977376Sgblack@eecs.umich.edu
987376Sgblack@eecs.umich.edu        if self.ident == "DNUCA_Movement":
997376Sgblack@eecs.umich.edu            self["mover"] = "yes"
1007376Sgblack@eecs.umich.edu
1017376Sgblack@eecs.umich.edu        self.isMachineType = (ident == "MachineType")
1027376Sgblack@eecs.umich.edu
1037376Sgblack@eecs.umich.edu        self.isStateDecl = ("state_decl" in self)
1047376Sgblack@eecs.umich.edu        self.statePermPairs = []
1057376Sgblack@eecs.umich.edu
1067376Sgblack@eecs.umich.edu        self.data_members = orderdict()
1077376Sgblack@eecs.umich.edu
1087376Sgblack@eecs.umich.edu        # Methods
1097376Sgblack@eecs.umich.edu        self.methods = {}
1107376Sgblack@eecs.umich.edu
1117376Sgblack@eecs.umich.edu        # Enums
1127376Sgblack@eecs.umich.edu        self.enums = orderdict()
1137376Sgblack@eecs.umich.edu
1147376Sgblack@eecs.umich.edu    @property
1157376Sgblack@eecs.umich.edu    def isPrimitive(self):
1167376Sgblack@eecs.umich.edu        return "primitive" in self
1177376Sgblack@eecs.umich.edu    @property
1187376Sgblack@eecs.umich.edu    def isNetworkMessage(self):
1197376Sgblack@eecs.umich.edu        return "networkmessage" in self
1207376Sgblack@eecs.umich.edu    @property
1217376Sgblack@eecs.umich.edu    def isMessage(self):
1227376Sgblack@eecs.umich.edu        return "message" in self
1237376Sgblack@eecs.umich.edu    @property
1247376Sgblack@eecs.umich.edu    def isBuffer(self):
1257376Sgblack@eecs.umich.edu        return "buffer" in self
1267376Sgblack@eecs.umich.edu    @property
1277376Sgblack@eecs.umich.edu    def isInPort(self):
1287376Sgblack@eecs.umich.edu        return "inport" in self
1297376Sgblack@eecs.umich.edu    @property
1307376Sgblack@eecs.umich.edu    def isOutPort(self):
1317376Sgblack@eecs.umich.edu        return "outport" in self
1327376Sgblack@eecs.umich.edu    @property
1337376Sgblack@eecs.umich.edu    def isEnumeration(self):
1347376Sgblack@eecs.umich.edu        return "enumeration" in self
1357376Sgblack@eecs.umich.edu    @property
1367376Sgblack@eecs.umich.edu    def isExternal(self):
1377376Sgblack@eecs.umich.edu        return "external" in self
1387376Sgblack@eecs.umich.edu    @property
1397376Sgblack@eecs.umich.edu    def isGlobal(self):
1407376Sgblack@eecs.umich.edu        return "global" in self
1417376Sgblack@eecs.umich.edu    @property
1427376Sgblack@eecs.umich.edu    def isInterface(self):
1437376Sgblack@eecs.umich.edu        return "interface" in self
1447376Sgblack@eecs.umich.edu
1457376Sgblack@eecs.umich.edu    # Return false on error
1467376Sgblack@eecs.umich.edu    def dataMemberAdd(self, ident, type, pairs, init_code):
1477376Sgblack@eecs.umich.edu        if ident in self.data_members:
1487376Sgblack@eecs.umich.edu            return False
1497376Sgblack@eecs.umich.edu
1507376Sgblack@eecs.umich.edu        member = DataMember(ident, type, pairs, init_code)
1517376Sgblack@eecs.umich.edu        self.data_members[ident] = member
1527376Sgblack@eecs.umich.edu
1537376Sgblack@eecs.umich.edu        return True
1547376Sgblack@eecs.umich.edu
1557376Sgblack@eecs.umich.edu    def dataMemberType(self, ident):
1567376Sgblack@eecs.umich.edu        return self.data_members[ident].type
1577376Sgblack@eecs.umich.edu
1587376Sgblack@eecs.umich.edu    def methodId(self, name, param_type_vec):
1597376Sgblack@eecs.umich.edu        return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])
1607376Sgblack@eecs.umich.edu
1617376Sgblack@eecs.umich.edu    def methodIdAbstract(self, name, param_type_vec):
1627376Sgblack@eecs.umich.edu        return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ])
1637376Sgblack@eecs.umich.edu
1647376Sgblack@eecs.umich.edu    def statePermPairAdd(self, state_name, perm_name):
1657376Sgblack@eecs.umich.edu        self.statePermPairs.append([state_name, perm_name])
1667376Sgblack@eecs.umich.edu
1677376Sgblack@eecs.umich.edu    def methodAdd(self, name, return_type, param_type_vec):
1687376Sgblack@eecs.umich.edu        ident = self.methodId(name, param_type_vec)
1697376Sgblack@eecs.umich.edu        if ident in self.methods:
1707376Sgblack@eecs.umich.edu            return False
1717376Sgblack@eecs.umich.edu
1727376Sgblack@eecs.umich.edu        self.methods[ident] = Method(return_type, param_type_vec)
1737376Sgblack@eecs.umich.edu        return True
1747376Sgblack@eecs.umich.edu
1757376Sgblack@eecs.umich.edu    def enumAdd(self, ident, pairs):
1767376Sgblack@eecs.umich.edu        if ident in self.enums:
1777376Sgblack@eecs.umich.edu            return False
1787376Sgblack@eecs.umich.edu
1797376Sgblack@eecs.umich.edu        self.enums[ident] = Enumeration(ident, pairs)
1807376Sgblack@eecs.umich.edu
1817376Sgblack@eecs.umich.edu        # Add default
1827376Sgblack@eecs.umich.edu        if "default" not in self:
1837376Sgblack@eecs.umich.edu            self["default"] = "%s_NUM" % self.c_ident
1847376Sgblack@eecs.umich.edu
1857376Sgblack@eecs.umich.edu        return True
1867376Sgblack@eecs.umich.edu
1877376Sgblack@eecs.umich.edu    def writeCodeFiles(self, path):
1887322Sgblack@eecs.umich.edu        if self.isExternal:
1897322Sgblack@eecs.umich.edu            # Do nothing
1907322Sgblack@eecs.umich.edu            pass
1917322Sgblack@eecs.umich.edu        elif self.isEnumeration:
1927322Sgblack@eecs.umich.edu            self.printEnumHH(path)
1937322Sgblack@eecs.umich.edu            self.printEnumCC(path)
1947396Sgblack@eecs.umich.edu        else:
1957644Sali.saidi@arm.com            # User defined structs and messages
1967640Sgblack@eecs.umich.edu            self.printTypeHH(path)
1977760SGiacomo.Gabrielli@arm.com            self.printTypeCC(path)
1987760SGiacomo.Gabrielli@arm.com
1997648SAli.Saidi@ARM.com    def printTypeHH(self, path):
2007396Sgblack@eecs.umich.edu        code = self.symtab.codeFormatter()
2017396Sgblack@eecs.umich.edu        code('''
2027322Sgblack@eecs.umich.edu/** \\file ${{self.c_ident}}.hh
2037324Sgblack@eecs.umich.edu *
2047644Sali.saidi@arm.com *
2057643Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__
2067643Sgblack@eecs.umich.edu */
2077643Sgblack@eecs.umich.edu
2087643Sgblack@eecs.umich.edu#ifndef __${{self.c_ident}}_HH__
2097643Sgblack@eecs.umich.edu#define __${{self.c_ident}}_HH__
2107760SGiacomo.Gabrielli@arm.com
2117783SGiacomo.Gabrielli@arm.com#include <iostream>
2127783SGiacomo.Gabrielli@arm.com
2137643Sgblack@eecs.umich.edu#include "mem/ruby/common/Global.hh"
2147643Sgblack@eecs.umich.edu''')
2157643Sgblack@eecs.umich.edu
2167643Sgblack@eecs.umich.edu        for dm in self.data_members.values():
2177396Sgblack@eecs.umich.edu            if not dm.type.isPrimitive:
2187644Sali.saidi@arm.com                code('#include "mem/protocol/$0.hh"', dm.type.c_ident)
2197760SGiacomo.Gabrielli@arm.com
2207760SGiacomo.Gabrielli@arm.com        parent = ""
2217783SGiacomo.Gabrielli@arm.com        if "interface" in self:
2227783SGiacomo.Gabrielli@arm.com            code('#include "mem/protocol/$0.hh"', self["interface"])
2237396Sgblack@eecs.umich.edu            parent = " :  public %s" % self["interface"]
2247396Sgblack@eecs.umich.edu
2257324Sgblack@eecs.umich.edu        code('''
2267333Sgblack@eecs.umich.edu$klass ${{self.c_ident}}$parent
2277643Sgblack@eecs.umich.edu{
2287644Sali.saidi@arm.com  public:
2297643Sgblack@eecs.umich.edu    ${{self.c_ident}}()
2307760SGiacomo.Gabrielli@arm.com    {
2317783SGiacomo.Gabrielli@arm.com''', klass="class")
2327783SGiacomo.Gabrielli@arm.com
2337643Sgblack@eecs.umich.edu        code.indent()
2347643Sgblack@eecs.umich.edu        if not self.isGlobal:
2357643Sgblack@eecs.umich.edu            code.indent()
2367643Sgblack@eecs.umich.edu            for dm in self.data_members.values():
2377644Sali.saidi@arm.com                ident = dm.ident
2387643Sgblack@eecs.umich.edu                if "default" in dm:
2397643Sgblack@eecs.umich.edu                    # look for default value
2407396Sgblack@eecs.umich.edu                    code('m_$ident = ${{dm["default"]}}; // default for this field')
2417392Sgblack@eecs.umich.edu                elif "default" in dm.type:
2427760SGiacomo.Gabrielli@arm.com                    # Look for the type default
2437783SGiacomo.Gabrielli@arm.com                    tid = dm.type.c_ident
2447783SGiacomo.Gabrielli@arm.com                    code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
2457396Sgblack@eecs.umich.edu                else:
2467396Sgblack@eecs.umich.edu                    code('// m_$ident has no default')
2477392Sgblack@eecs.umich.edu            code.dedent()
2487392Sgblack@eecs.umich.edu        code('}')
2497644Sali.saidi@arm.com
2507643Sgblack@eecs.umich.edu        # ******** Copy constructor ********
2517643Sgblack@eecs.umich.edu        if not self.isGlobal:
2527643Sgblack@eecs.umich.edu            code('${{self.c_ident}}(const ${{self.c_ident}}&other)')
2537643Sgblack@eecs.umich.edu
2547643Sgblack@eecs.umich.edu            # Call superclass constructor
2557760SGiacomo.Gabrielli@arm.com            if "interface" in self:
2567783SGiacomo.Gabrielli@arm.com                code('    : ${{self["interface"]}}(other)')
2577783SGiacomo.Gabrielli@arm.com
2587643Sgblack@eecs.umich.edu            code('{')
2597643Sgblack@eecs.umich.edu            code.indent()
2607643Sgblack@eecs.umich.edu
2617643Sgblack@eecs.umich.edu            for dm in self.data_members.values():
2627640Sgblack@eecs.umich.edu                code('m_${{dm.ident}} = other.m_${{dm.ident}};')
2637333Sgblack@eecs.umich.edu
2647333Sgblack@eecs.umich.edu            code.dedent()
2657396Sgblack@eecs.umich.edu            code('}')
2667333Sgblack@eecs.umich.edu
2677760SGiacomo.Gabrielli@arm.com        # ******** Full init constructor ********
2687760SGiacomo.Gabrielli@arm.com        if not self.isGlobal:
2697396Sgblack@eecs.umich.edu            params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
2707396Sgblack@eecs.umich.edu                       for dm in self.data_members.itervalues() ]
2717333Sgblack@eecs.umich.edu
2727333Sgblack@eecs.umich.edu            params = ', '.join(params)
2737640Sgblack@eecs.umich.edu            code('${{self.c_ident}}($params)')
2747333Sgblack@eecs.umich.edu
2757333Sgblack@eecs.umich.edu            # Call superclass constructor
2767333Sgblack@eecs.umich.edu            if "interface" in self:
2777396Sgblack@eecs.umich.edu                code('    : ${{self["interface"]}}()')
2787333Sgblack@eecs.umich.edu
2797760SGiacomo.Gabrielli@arm.com            code('{')
2807760SGiacomo.Gabrielli@arm.com            code.indent()
2817396Sgblack@eecs.umich.edu            for dm in self.data_members.values():
2827396Sgblack@eecs.umich.edu                code('m_${{dm.ident}} = local_${{dm.ident}};')
2837333Sgblack@eecs.umich.edu                if "nextLineCallHack" in dm:
2847333Sgblack@eecs.umich.edu                    code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};')
2857640Sgblack@eecs.umich.edu
2867333Sgblack@eecs.umich.edu            code.dedent()
2877333Sgblack@eecs.umich.edu            code('}')
2887333Sgblack@eecs.umich.edu
2897333Sgblack@eecs.umich.edu        # create a static factory method and a clone member
2907333Sgblack@eecs.umich.edu        code('''
2917396Sgblack@eecs.umich.edustatic ${{self.c_ident}}*
2927333Sgblack@eecs.umich.educreate()
2937760SGiacomo.Gabrielli@arm.com{
2947760SGiacomo.Gabrielli@arm.com    return new ${{self.c_ident}}();
2957396Sgblack@eecs.umich.edu}
2967396Sgblack@eecs.umich.edu
2977333Sgblack@eecs.umich.edu${{self.c_ident}}*
2987333Sgblack@eecs.umich.educlone() const
2997640Sgblack@eecs.umich.edu{
3007333Sgblack@eecs.umich.edu     return new ${{self.c_ident}}(*this);
3017333Sgblack@eecs.umich.edu}
3027396Sgblack@eecs.umich.edu''')
3037333Sgblack@eecs.umich.edu
3047760SGiacomo.Gabrielli@arm.com        if not self.isGlobal:
3057760SGiacomo.Gabrielli@arm.com            # const Get methods for each field
3067396Sgblack@eecs.umich.edu            code('// Const accessors methods for each field')
3077396Sgblack@eecs.umich.edu            for dm in self.data_members.values():
3087333Sgblack@eecs.umich.edu                code('''
3097333Sgblack@eecs.umich.edu/** \\brief Const accessor method for ${{dm.ident}} field.
3107640Sgblack@eecs.umich.edu *  \\return ${{dm.ident}} field
3117333Sgblack@eecs.umich.edu */
3127333Sgblack@eecs.umich.educonst ${{dm.type.c_ident}}&
3137333Sgblack@eecs.umich.eduget${{dm.ident}}() const
3147396Sgblack@eecs.umich.edu{
3157333Sgblack@eecs.umich.edu    return m_${{dm.ident}};
3167760SGiacomo.Gabrielli@arm.com}
3177760SGiacomo.Gabrielli@arm.com''')
3187396Sgblack@eecs.umich.edu
3197396Sgblack@eecs.umich.edu            # Non-const Get methods for each field
3207333Sgblack@eecs.umich.edu            code('// Non const Accessors methods for each field')
3217333Sgblack@eecs.umich.edu            for dm in self.data_members.values():
3227640Sgblack@eecs.umich.edu                code('''
3237333Sgblack@eecs.umich.edu/** \\brief Non-const accessor method for ${{dm.ident}} field.
3247333Sgblack@eecs.umich.edu *  \\return ${{dm.ident}} field
3257333Sgblack@eecs.umich.edu */
3267333Sgblack@eecs.umich.edu${{dm.type.c_ident}}&
3277333Sgblack@eecs.umich.eduget${{dm.ident}}()
3287396Sgblack@eecs.umich.edu{
3297333Sgblack@eecs.umich.edu    return m_${{dm.ident}};
3307760SGiacomo.Gabrielli@arm.com}
3317760SGiacomo.Gabrielli@arm.com''')
3327396Sgblack@eecs.umich.edu
3337396Sgblack@eecs.umich.edu            #Set methods for each field
3347333Sgblack@eecs.umich.edu            code('// Mutator methods for each field')
3357333Sgblack@eecs.umich.edu            for dm in self.data_members.values():
3367640Sgblack@eecs.umich.edu                code('''
3377639Sgblack@eecs.umich.edu/** \\brief Mutator method for ${{dm.ident}} field */
3387333Sgblack@eecs.umich.eduvoid
3397396Sgblack@eecs.umich.eduset${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}})
3407333Sgblack@eecs.umich.edu{
3417760SGiacomo.Gabrielli@arm.com    m_${{dm.ident}} = local_${{dm.ident}};
3427760SGiacomo.Gabrielli@arm.com}
3437396Sgblack@eecs.umich.edu''')
3447396Sgblack@eecs.umich.edu
3457333Sgblack@eecs.umich.edu        code('void print(std::ostream& out) const;')
3467333Sgblack@eecs.umich.edu        code.dedent()
3477640Sgblack@eecs.umich.edu        code('  //private:')
3487639Sgblack@eecs.umich.edu        code.indent()
3497333Sgblack@eecs.umich.edu
3507396Sgblack@eecs.umich.edu        # Data members for each field
3517333Sgblack@eecs.umich.edu        for dm in self.data_members.values():
3527760SGiacomo.Gabrielli@arm.com            if "abstract" not in dm:
3537760SGiacomo.Gabrielli@arm.com                const = ""
3547396Sgblack@eecs.umich.edu                init = ""
3557396Sgblack@eecs.umich.edu
3567333Sgblack@eecs.umich.edu                # global structure
3577333Sgblack@eecs.umich.edu                if self.isGlobal:
3587640Sgblack@eecs.umich.edu                    const = "static const "
3597333Sgblack@eecs.umich.edu
3607333Sgblack@eecs.umich.edu                # init value
3617396Sgblack@eecs.umich.edu                if dm.init_code:
3627333Sgblack@eecs.umich.edu                    # only global structure can have init value here
3637760SGiacomo.Gabrielli@arm.com                    assert self.isGlobal
3647760SGiacomo.Gabrielli@arm.com                    init = " = %s" % (dm.init_code)
3657396Sgblack@eecs.umich.edu
3667396Sgblack@eecs.umich.edu                if "desc" in dm:
3677333Sgblack@eecs.umich.edu                    code('/** ${{dm["desc"]}} */')
3687333Sgblack@eecs.umich.edu
3697640Sgblack@eecs.umich.edu                code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;')
3707639Sgblack@eecs.umich.edu
3717639Sgblack@eecs.umich.edu        code.dedent()
3727333Sgblack@eecs.umich.edu        code('};')
3737396Sgblack@eecs.umich.edu
3747333Sgblack@eecs.umich.edu        code('''
3757760SGiacomo.Gabrielli@arm.cominline std::ostream&
3767760SGiacomo.Gabrielli@arm.comoperator<<(std::ostream& out, const ${{self.c_ident}}& obj)
3777396Sgblack@eecs.umich.edu{
3787396Sgblack@eecs.umich.edu    obj.print(out);
3797333Sgblack@eecs.umich.edu    out << std::flush;
3807333Sgblack@eecs.umich.edu    return out;
3817640Sgblack@eecs.umich.edu}
3827639Sgblack@eecs.umich.edu
3837639Sgblack@eecs.umich.edu#endif // __${{self.c_ident}}_HH__
3847333Sgblack@eecs.umich.edu''')
3857396Sgblack@eecs.umich.edu
3867333Sgblack@eecs.umich.edu        code.write(path, "%s.hh" % self.c_ident)
3877760SGiacomo.Gabrielli@arm.com
3887760SGiacomo.Gabrielli@arm.com    def printTypeCC(self, path):
3897396Sgblack@eecs.umich.edu        code = self.symtab.codeFormatter()
3907396Sgblack@eecs.umich.edu
3917333Sgblack@eecs.umich.edu        code('''
3927333Sgblack@eecs.umich.edu/** \\file ${{self.c_ident}}.cc
3937640Sgblack@eecs.umich.edu *
3947639Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__
3957639Sgblack@eecs.umich.edu */
3967333Sgblack@eecs.umich.edu
3977396Sgblack@eecs.umich.edu#include <iostream>
3987333Sgblack@eecs.umich.edu
3997760SGiacomo.Gabrielli@arm.com#include "mem/protocol/${{self.c_ident}}.hh"
4007760SGiacomo.Gabrielli@arm.com
4017396Sgblack@eecs.umich.eduusing namespace std;
4027396Sgblack@eecs.umich.edu''')
4037333Sgblack@eecs.umich.edu
4047333Sgblack@eecs.umich.edu        code('''
4057640Sgblack@eecs.umich.edu/** \\brief Print the state of this object */
4067639Sgblack@eecs.umich.eduvoid
4077639Sgblack@eecs.umich.edu${{self.c_ident}}::print(ostream& out) const
4087333Sgblack@eecs.umich.edu{
4097396Sgblack@eecs.umich.edu    out << "[${{self.c_ident}}: ";
4107333Sgblack@eecs.umich.edu''')
4117760SGiacomo.Gabrielli@arm.com
4127760SGiacomo.Gabrielli@arm.com        # For each field
4137396Sgblack@eecs.umich.edu        code.indent()
4147396Sgblack@eecs.umich.edu        for dm in self.data_members.values():
4157333Sgblack@eecs.umich.edu            code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
4167333Sgblack@eecs.umich.edu
4177640Sgblack@eecs.umich.edu        if self.isMessage:
4187333Sgblack@eecs.umich.edu            code('out << "Time = " << getTime() * g_system_ptr->getClock() << " ";')
4197333Sgblack@eecs.umich.edu        code.dedent()
4207396Sgblack@eecs.umich.edu
4217333Sgblack@eecs.umich.edu        # Trailer
4227760SGiacomo.Gabrielli@arm.com        code('''
4237760SGiacomo.Gabrielli@arm.com    out << "]";
4247396Sgblack@eecs.umich.edu}''')
4257396Sgblack@eecs.umich.edu
4267333Sgblack@eecs.umich.edu        code.write(path, "%s.cc" % self.c_ident)
4277333Sgblack@eecs.umich.edu
4287640Sgblack@eecs.umich.edu    def printEnumHH(self, path):
4297333Sgblack@eecs.umich.edu        code = self.symtab.codeFormatter()
4307333Sgblack@eecs.umich.edu        code('''
4317333Sgblack@eecs.umich.edu/** \\file ${{self.c_ident}}.hh
4327396Sgblack@eecs.umich.edu *
4337333Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__
4347760SGiacomo.Gabrielli@arm.com */
4357760SGiacomo.Gabrielli@arm.com
4367396Sgblack@eecs.umich.edu#ifndef __${{self.c_ident}}_HH__
4377396Sgblack@eecs.umich.edu#define __${{self.c_ident}}_HH__
4387333Sgblack@eecs.umich.edu
4397333Sgblack@eecs.umich.edu#include <iostream>
4407640Sgblack@eecs.umich.edu#include <string>
4417333Sgblack@eecs.umich.edu
4427333Sgblack@eecs.umich.edu''')
4437333Sgblack@eecs.umich.edu        if self.isStateDecl:
4447396Sgblack@eecs.umich.edu            code('#include "mem/protocol/AccessPermission.hh"')
4457333Sgblack@eecs.umich.edu
4467760SGiacomo.Gabrielli@arm.com        if self.isMachineType:
4477760SGiacomo.Gabrielli@arm.com            code('#include "base/misc.hh"')
4487396Sgblack@eecs.umich.edu            code('#include "mem/protocol/GenericMachineType.hh"')
4497396Sgblack@eecs.umich.edu            code('#include "mem/ruby/common/Address.hh"')
4507333Sgblack@eecs.umich.edu            code('struct MachineID;')
4517381Sgblack@eecs.umich.edu
4527381Sgblack@eecs.umich.edu        code('''
4537381Sgblack@eecs.umich.edu
4547381Sgblack@eecs.umich.edu// Class definition
4557381Sgblack@eecs.umich.edu/** \\enum ${{self.c_ident}}
4567381Sgblack@eecs.umich.edu *  \\brief ${{self.desc}}
4577381Sgblack@eecs.umich.edu */
4587364Sgblack@eecs.umich.eduenum ${{self.c_ident}} {
4597783SGiacomo.Gabrielli@arm.com    ${{self.c_ident}}_FIRST,
4607783SGiacomo.Gabrielli@arm.com''')
4617396Sgblack@eecs.umich.edu
4627783SGiacomo.Gabrielli@arm.com        code.indent()
4637783SGiacomo.Gabrielli@arm.com        # For each field
4647783SGiacomo.Gabrielli@arm.com        for i,(ident,enum) in enumerate(self.enums.iteritems()):
4657364Sgblack@eecs.umich.edu            desc = enum.get("desc", "No description avaliable")
4667396Sgblack@eecs.umich.edu            if i == 0:
4677639Sgblack@eecs.umich.edu                init = ' = %s_FIRST' % self.c_ident
4687396Sgblack@eecs.umich.edu            else:
4697640Sgblack@eecs.umich.edu                init = ''
4707783SGiacomo.Gabrielli@arm.com            code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
4717396Sgblack@eecs.umich.edu        code.dedent()
4727396Sgblack@eecs.umich.edu        code('''
4737396Sgblack@eecs.umich.edu    ${{self.c_ident}}_NUM
4747783SGiacomo.Gabrielli@arm.com};
4757396Sgblack@eecs.umich.edu
4767396Sgblack@eecs.umich.edu// Code to convert from a string to the enumeration
4777396Sgblack@eecs.umich.edu${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str);
4787396Sgblack@eecs.umich.edu
4797639Sgblack@eecs.umich.edu// Code to convert state to a string
4807396Sgblack@eecs.umich.edustd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
4817396Sgblack@eecs.umich.edu
4827396Sgblack@eecs.umich.edu// Code to increment an enumeration type
4837396Sgblack@eecs.umich.edu${{self.c_ident}} &operator++(${{self.c_ident}} &e);
4847396Sgblack@eecs.umich.edu''')
4857364Sgblack@eecs.umich.edu
4867760SGiacomo.Gabrielli@arm.com        # MachineType hack used to set the base component id for each Machine
4877396Sgblack@eecs.umich.edu        if self.isMachineType:
4887365Sgblack@eecs.umich.edu            code('''
4897396Sgblack@eecs.umich.eduint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
4907396Sgblack@eecs.umich.eduMachineType ${{self.c_ident}}_from_base_level(int);
4917396Sgblack@eecs.umich.eduint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
4927760SGiacomo.Gabrielli@arm.comint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
4937760SGiacomo.Gabrielli@arm.com''')
4947760SGiacomo.Gabrielli@arm.com
4957396Sgblack@eecs.umich.edu            for enum in self.enums.itervalues():
4967396Sgblack@eecs.umich.edu                if enum.ident == "DMA":
4977396Sgblack@eecs.umich.edu                    code('''
4987760SGiacomo.Gabrielli@arm.comMachineID map_Address_to_DMA(const Address &addr);
4997760SGiacomo.Gabrielli@arm.com''')
5007760SGiacomo.Gabrielli@arm.com                code('''
5017365Sgblack@eecs.umich.edu
5027396Sgblack@eecs.umich.eduMachineID get${{enum.ident}}MachineID(NodeID RubyNode);
5037396Sgblack@eecs.umich.edu''')
5047366Sgblack@eecs.umich.edu
5057396Sgblack@eecs.umich.edu            code('''
5067396Sgblack@eecs.umich.eduinline GenericMachineType
5077396Sgblack@eecs.umich.eduConvertMachToGenericMach(MachineType machType)
5087396Sgblack@eecs.umich.edu{
5097366Sgblack@eecs.umich.edu''')
5107760SGiacomo.Gabrielli@arm.com            for enum in self.enums.itervalues():
5117760SGiacomo.Gabrielli@arm.com                code('''
5127760SGiacomo.Gabrielli@arm.com      if (machType == MachineType_${{enum.ident}})
5137760SGiacomo.Gabrielli@arm.com          return GenericMachineType_${{enum.ident}};
5147760SGiacomo.Gabrielli@arm.com''')
5157760SGiacomo.Gabrielli@arm.com            code('''
5167760SGiacomo.Gabrielli@arm.com      panic("cannot convert to a GenericMachineType");
5177760SGiacomo.Gabrielli@arm.com}
5187367Sgblack@eecs.umich.edu''')
5197760SGiacomo.Gabrielli@arm.com
5207396Sgblack@eecs.umich.edu        if self.isStateDecl:
5217396Sgblack@eecs.umich.edu            code('''
5227396Sgblack@eecs.umich.edu
5237367Sgblack@eecs.umich.edu// Code to convert the current state to an access permission
5247396Sgblack@eecs.umich.eduAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj);
5257396Sgblack@eecs.umich.edu
5267396Sgblack@eecs.umich.edu''')
5277760SGiacomo.Gabrielli@arm.com
5287760SGiacomo.Gabrielli@arm.com        # Trailer
5297760SGiacomo.Gabrielli@arm.com        code('''
5307396Sgblack@eecs.umich.edustd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);
5317396Sgblack@eecs.umich.edu
5327396Sgblack@eecs.umich.edu#endif // __${{self.c_ident}}_HH__
5337760SGiacomo.Gabrielli@arm.com''')
5347760SGiacomo.Gabrielli@arm.com
5357760SGiacomo.Gabrielli@arm.com        code.write(path, "%s.hh" % self.c_ident)
5367368Sgblack@eecs.umich.edu
5377396Sgblack@eecs.umich.edu    def printEnumCC(self, path):
5387396Sgblack@eecs.umich.edu        code = self.symtab.codeFormatter()
5397368Sgblack@eecs.umich.edu        code('''
5407396Sgblack@eecs.umich.edu/** \\file ${{self.c_ident}}.hh
5417396Sgblack@eecs.umich.edu *
5427396Sgblack@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__
5437396Sgblack@eecs.umich.edu */
5447369Sgblack@eecs.umich.edu
5457760SGiacomo.Gabrielli@arm.com#include <cassert>
5467760SGiacomo.Gabrielli@arm.com#include <iostream>
5477369Sgblack@eecs.umich.edu#include <string>
5487760SGiacomo.Gabrielli@arm.com
5497760SGiacomo.Gabrielli@arm.com#include "base/misc.hh"
5507396Sgblack@eecs.umich.edu#include "mem/protocol/${{self.c_ident}}.hh"
5517396Sgblack@eecs.umich.edu
5527396Sgblack@eecs.umich.eduusing namespace std;
5537369Sgblack@eecs.umich.edu
5547396Sgblack@eecs.umich.edu''')
5557783SGiacomo.Gabrielli@arm.com
5567760SGiacomo.Gabrielli@arm.com        if self.isStateDecl:
5577760SGiacomo.Gabrielli@arm.com            code('''
5587396Sgblack@eecs.umich.edu// Code to convert the current state to an access permission
5597396Sgblack@eecs.umich.eduAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj)
5607760SGiacomo.Gabrielli@arm.com{
5617760SGiacomo.Gabrielli@arm.com    switch(obj) {
5627369Sgblack@eecs.umich.edu''')
5637396Sgblack@eecs.umich.edu            # For each case
5647396Sgblack@eecs.umich.edu            code.indent()
5657396Sgblack@eecs.umich.edu            for statePerm in self.statePermPairs:
5667396Sgblack@eecs.umich.edu                code('  case ${{self.c_ident}}_${{statePerm[0]}}:')
5677396Sgblack@eecs.umich.edu                code('    return AccessPermission_${{statePerm[1]}};')
5687396Sgblack@eecs.umich.edu            code.dedent()
5697396Sgblack@eecs.umich.edu            code ('''
5707396Sgblack@eecs.umich.edu      default:
5717760SGiacomo.Gabrielli@arm.com        panic("Unknown state access permission converstion for ${{self.c_ident}}");
5727396Sgblack@eecs.umich.edu    }
5737760SGiacomo.Gabrielli@arm.com}
5747396Sgblack@eecs.umich.edu
5757381Sgblack@eecs.umich.edu''')
5767381Sgblack@eecs.umich.edu
5777381Sgblack@eecs.umich.edu        if self.isMachineType:
5787381Sgblack@eecs.umich.edu            for enum in self.enums.itervalues():
5797381Sgblack@eecs.umich.edu                code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
5807381Sgblack@eecs.umich.edu            code('#include "mem/ruby/system/MachineID.hh"')
5817381Sgblack@eecs.umich.edu
5827370Sgblack@eecs.umich.edu        code('''
5837640Sgblack@eecs.umich.edu// Code for output operator
5847783SGiacomo.Gabrielli@arm.comostream&
5857396Sgblack@eecs.umich.eduoperator<<(ostream& out, const ${{self.c_ident}}& obj)
5867639Sgblack@eecs.umich.edu{
5877639Sgblack@eecs.umich.edu    out << ${{self.c_ident}}_to_string(obj);
5887639Sgblack@eecs.umich.edu    out << flush;
5897783SGiacomo.Gabrielli@arm.com    return out;
5907370Sgblack@eecs.umich.edu}
5917396Sgblack@eecs.umich.edu
5927370Sgblack@eecs.umich.edu// Code to convert state to a string
5937760SGiacomo.Gabrielli@arm.comstring
5947760SGiacomo.Gabrielli@arm.com${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
5957396Sgblack@eecs.umich.edu{
5967396Sgblack@eecs.umich.edu    switch(obj) {
5977370Sgblack@eecs.umich.edu''')
5987370Sgblack@eecs.umich.edu
5997640Sgblack@eecs.umich.edu        # For each field
6007783SGiacomo.Gabrielli@arm.com        code.indent()
6017396Sgblack@eecs.umich.edu        for enum in self.enums.itervalues():
6027396Sgblack@eecs.umich.edu            code('  case ${{self.c_ident}}_${{enum.ident}}:')
6037639Sgblack@eecs.umich.edu            code('    return "${{enum.ident}}";')
6047396Sgblack@eecs.umich.edu        code.dedent()
6057639Sgblack@eecs.umich.edu
6067639Sgblack@eecs.umich.edu        # Trailer
6077396Sgblack@eecs.umich.edu        code('''
6087396Sgblack@eecs.umich.edu      default:
6097783SGiacomo.Gabrielli@arm.com        panic("Invalid range for type ${{self.c_ident}}");
6107370Sgblack@eecs.umich.edu    }
6117396Sgblack@eecs.umich.edu}
6127370Sgblack@eecs.umich.edu
6137760SGiacomo.Gabrielli@arm.com// Code to convert from a string to the enumeration
6147760SGiacomo.Gabrielli@arm.com${{self.c_ident}}
6157396Sgblack@eecs.umich.edustring_to_${{self.c_ident}}(const string& str)
6167396Sgblack@eecs.umich.edu{
6177370Sgblack@eecs.umich.edu''')
6187370Sgblack@eecs.umich.edu
6197640Sgblack@eecs.umich.edu        # For each field
6207783SGiacomo.Gabrielli@arm.com        start = ""
6217396Sgblack@eecs.umich.edu        code.indent()
6227639Sgblack@eecs.umich.edu        for enum in self.enums.itervalues():
6237639Sgblack@eecs.umich.edu            code('${start}if (str == "${{enum.ident}}") {')
6247639Sgblack@eecs.umich.edu            code('    return ${{self.c_ident}}_${{enum.ident}};')
6257783SGiacomo.Gabrielli@arm.com            start = "} else "
6267370Sgblack@eecs.umich.edu        code.dedent()
6277396Sgblack@eecs.umich.edu
6287370Sgblack@eecs.umich.edu        code('''
6297760SGiacomo.Gabrielli@arm.com    } else {
6307760SGiacomo.Gabrielli@arm.com        panic("Invalid string conversion for %s, type ${{self.c_ident}}", str);
6317396Sgblack@eecs.umich.edu    }
6327396Sgblack@eecs.umich.edu}
6337370Sgblack@eecs.umich.edu
6347370Sgblack@eecs.umich.edu// Code to increment an enumeration type
6357640Sgblack@eecs.umich.edu${{self.c_ident}}&
6367783SGiacomo.Gabrielli@arm.comoperator++(${{self.c_ident}}& e)
6377396Sgblack@eecs.umich.edu{
6387396Sgblack@eecs.umich.edu    assert(e < ${{self.c_ident}}_NUM);
6397639Sgblack@eecs.umich.edu    return e = ${{self.c_ident}}(e+1);
6407396Sgblack@eecs.umich.edu}
6417639Sgblack@eecs.umich.edu''')
6427639Sgblack@eecs.umich.edu
6437396Sgblack@eecs.umich.edu        # MachineType hack used to set the base level and number of
6447396Sgblack@eecs.umich.edu        # components for each Machine
6457783SGiacomo.Gabrielli@arm.com        if self.isMachineType:
6467370Sgblack@eecs.umich.edu            code('''
6477396Sgblack@eecs.umich.edu/** \\brief returns the base vector index for each machine type to be
6487370Sgblack@eecs.umich.edu  * used by NetDest
6497760SGiacomo.Gabrielli@arm.com  *
6507760SGiacomo.Gabrielli@arm.com  * \\return the base vector index for each machine type to be used by NetDest
6517396Sgblack@eecs.umich.edu  * \\see NetDest.hh
6527396Sgblack@eecs.umich.edu  */
6537370Sgblack@eecs.umich.eduint
6547371Sgblack@eecs.umich.edu${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
6557640Sgblack@eecs.umich.edu{
6567783SGiacomo.Gabrielli@arm.com    switch(obj) {
6577396Sgblack@eecs.umich.edu''')
6587639Sgblack@eecs.umich.edu
6597639Sgblack@eecs.umich.edu            # For each field
6607639Sgblack@eecs.umich.edu            code.indent()
6617783SGiacomo.Gabrielli@arm.com            for i,enum in enumerate(self.enums.itervalues()):
6627371Sgblack@eecs.umich.edu                code('  case ${{self.c_ident}}_${{enum.ident}}:')
6637396Sgblack@eecs.umich.edu                code('    return $i;')
6647371Sgblack@eecs.umich.edu            code.dedent()
6657760SGiacomo.Gabrielli@arm.com
6667760SGiacomo.Gabrielli@arm.com            # total num
6677396Sgblack@eecs.umich.edu            code('''
6687396Sgblack@eecs.umich.edu      case ${{self.c_ident}}_NUM:
6697371Sgblack@eecs.umich.edu        return ${{len(self.enums)}};
6707371Sgblack@eecs.umich.edu
6717640Sgblack@eecs.umich.edu      default:
6727783SGiacomo.Gabrielli@arm.com        panic("Invalid range for type ${{self.c_ident}}");
6737396Sgblack@eecs.umich.edu    }
6747396Sgblack@eecs.umich.edu}
6757639Sgblack@eecs.umich.edu
6767396Sgblack@eecs.umich.edu/** \\brief returns the machine type for each base vector index used by NetDest
6777639Sgblack@eecs.umich.edu *
6787639Sgblack@eecs.umich.edu * \\return the MachineType
6797396Sgblack@eecs.umich.edu */
6807396Sgblack@eecs.umich.eduMachineType
6817783SGiacomo.Gabrielli@arm.com${{self.c_ident}}_from_base_level(int type)
6827371Sgblack@eecs.umich.edu{
6837396Sgblack@eecs.umich.edu    switch(type) {
6847371Sgblack@eecs.umich.edu''')
6857760SGiacomo.Gabrielli@arm.com
6867760SGiacomo.Gabrielli@arm.com            # For each field
6877396Sgblack@eecs.umich.edu            code.indent()
6887396Sgblack@eecs.umich.edu            for i,enum in enumerate(self.enums.itervalues()):
6897371Sgblack@eecs.umich.edu                code('  case $i:')
6907371Sgblack@eecs.umich.edu                code('    return ${{self.c_ident}}_${{enum.ident}};')
6917640Sgblack@eecs.umich.edu            code.dedent()
6927783SGiacomo.Gabrielli@arm.com
6937396Sgblack@eecs.umich.edu            # Trailer
6947639Sgblack@eecs.umich.edu            code('''
6957639Sgblack@eecs.umich.edu      default:
6967639Sgblack@eecs.umich.edu        panic("Invalid range for type ${{self.c_ident}}");
6977783SGiacomo.Gabrielli@arm.com    }
6987371Sgblack@eecs.umich.edu}
6997396Sgblack@eecs.umich.edu
7007760SGiacomo.Gabrielli@arm.com/** \\brief The return value indicates the number of components created
7017760SGiacomo.Gabrielli@arm.com * before a particular machine\'s components
7027760SGiacomo.Gabrielli@arm.com *
7037396Sgblack@eecs.umich.edu * \\return the base number of components for each machine
7047396Sgblack@eecs.umich.edu */
7057371Sgblack@eecs.umich.eduint
7067371Sgblack@eecs.umich.edu${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
7077640Sgblack@eecs.umich.edu{
7087783SGiacomo.Gabrielli@arm.com    int base = 0;
7097396Sgblack@eecs.umich.edu    switch(obj) {
7107396Sgblack@eecs.umich.edu''')
7117639Sgblack@eecs.umich.edu
7127396Sgblack@eecs.umich.edu            # For each field
7137639Sgblack@eecs.umich.edu            code.indent()
7147639Sgblack@eecs.umich.edu            code('  case ${{self.c_ident}}_NUM:')
7157396Sgblack@eecs.umich.edu            for enum in reversed(self.enums.values()):
7167396Sgblack@eecs.umich.edu                code('    base += ${{enum.ident}}_Controller::getNumControllers();')
7177783SGiacomo.Gabrielli@arm.com                code('  case ${{self.c_ident}}_${{enum.ident}}:')
7187371Sgblack@eecs.umich.edu            code('    break;')
7197396Sgblack@eecs.umich.edu            code.dedent()
7207760SGiacomo.Gabrielli@arm.com
7217760SGiacomo.Gabrielli@arm.com            code('''
7227760SGiacomo.Gabrielli@arm.com      default:
7237396Sgblack@eecs.umich.edu        panic("Invalid range for type ${{self.c_ident}}");
7247396Sgblack@eecs.umich.edu    }
7257371Sgblack@eecs.umich.edu
7267371Sgblack@eecs.umich.edu    return base;
7277640Sgblack@eecs.umich.edu}
7287783SGiacomo.Gabrielli@arm.com
7297639Sgblack@eecs.umich.edu/** \\brief returns the total number of components for each machine
7307639Sgblack@eecs.umich.edu * \\return the total number of components for each machine
7317783SGiacomo.Gabrielli@arm.com */
7327371Sgblack@eecs.umich.eduint
7337396Sgblack@eecs.umich.edu${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
7347760SGiacomo.Gabrielli@arm.com{
7357760SGiacomo.Gabrielli@arm.com    switch(obj) {
7367760SGiacomo.Gabrielli@arm.com''')
7377396Sgblack@eecs.umich.edu
7387396Sgblack@eecs.umich.edu            # For each field
7397371Sgblack@eecs.umich.edu            for enum in self.enums.itervalues():
7407371Sgblack@eecs.umich.edu                code('''
7417640Sgblack@eecs.umich.edu      case ${{self.c_ident}}_${{enum.ident}}:
7427783SGiacomo.Gabrielli@arm.com        return ${{enum.ident}}_Controller::getNumControllers();
7437396Sgblack@eecs.umich.edu''')
7447396Sgblack@eecs.umich.edu
7457639Sgblack@eecs.umich.edu            # total num
7467639Sgblack@eecs.umich.edu            code('''
7477396Sgblack@eecs.umich.edu      case ${{self.c_ident}}_NUM:
7487396Sgblack@eecs.umich.edu      default:
7497783SGiacomo.Gabrielli@arm.com        panic("Invalid range for type ${{self.c_ident}}");
7507371Sgblack@eecs.umich.edu    }
7517396Sgblack@eecs.umich.edu}
7527371Sgblack@eecs.umich.edu''')
7537760SGiacomo.Gabrielli@arm.com
7547760SGiacomo.Gabrielli@arm.com            for enum in self.enums.itervalues():
7557396Sgblack@eecs.umich.edu                if enum.ident == "DMA":
7567396Sgblack@eecs.umich.edu                    code('''
7577371Sgblack@eecs.umich.eduMachineID
7587381Sgblack@eecs.umich.edumap_Address_to_DMA(const Address &addr)
7597381Sgblack@eecs.umich.edu{
7607381Sgblack@eecs.umich.edu      MachineID dma = {MachineType_DMA, 0};
7617381Sgblack@eecs.umich.edu      return dma;
7627381Sgblack@eecs.umich.edu}
7637381Sgblack@eecs.umich.edu''')
7647381Sgblack@eecs.umich.edu
7657373Sgblack@eecs.umich.edu                code('''
7667640Sgblack@eecs.umich.edu
7677783SGiacomo.Gabrielli@arm.comMachineID
7687397Sgblack@eecs.umich.eduget${{enum.ident}}MachineID(NodeID RubyNode)
7697381Sgblack@eecs.umich.edu{
7707373Sgblack@eecs.umich.edu      MachineID mach = {MachineType_${{enum.ident}}, RubyNode};
7717381Sgblack@eecs.umich.edu      return mach;
7727639Sgblack@eecs.umich.edu}
7737783SGiacomo.Gabrielli@arm.com''')
7747373Sgblack@eecs.umich.edu
7757396Sgblack@eecs.umich.edu        # Write the file
7767373Sgblack@eecs.umich.edu        code.write(path, "%s.cc" % self.c_ident)
7777760SGiacomo.Gabrielli@arm.com
7787760SGiacomo.Gabrielli@arm.com__all__ = [ "Type" ]
7797396Sgblack@eecs.umich.edu