Type.py revision 6862
19814Sandreas.hansson@arm.com# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
22292SN/A# Copyright (c) 2009 The Hewlett-Packard Development Company
313590Srekai.gonzalezalberquilla@arm.com# All rights reserved.
410239Sbinhpham@cs.rutgers.edu#
57597Sminkyu.jeong@arm.com# Redistribution and use in source and binary forms, with or without
67597Sminkyu.jeong@arm.com# modification, are permitted provided that the following conditions are
77597Sminkyu.jeong@arm.com# met: redistributions of source code must retain the above copyright
87597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer;
97597Sminkyu.jeong@arm.com# redistributions in binary form must reproduce the above copyright
107597Sminkyu.jeong@arm.com# notice, this list of conditions and the following disclaimer in the
117597Sminkyu.jeong@arm.com# documentation and/or other materials provided with the distribution;
127597Sminkyu.jeong@arm.com# neither the name of the copyright holders nor the names of its
137597Sminkyu.jeong@arm.com# contributors may be used to endorse or promote products derived from
147597Sminkyu.jeong@arm.com# this software without specific prior written permission.
157597Sminkyu.jeong@arm.com#
162292SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172292SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182292SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192292SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202292SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212292SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222292SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232292SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242292SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252292SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262292SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272292SN/A
282292SN/Afrom m5.util import code_formatter, orderdict
292292SN/A
302292SN/Afrom slicc.util import PairContainer
312292SN/Afrom slicc.symbols.Symbol import Symbol
322292SN/A
332292SN/Aclass DataMember(PairContainer):
342292SN/A    def __init__(self, ident, type, pairs, init_code):
352292SN/A        super(DataMember, self).__init__(pairs)
362292SN/A        self.ident = ident
372292SN/A        self.type = type
382292SN/A        self.init_code = init_code
392292SN/A
402292SN/Aclass Enumeration(PairContainer):
412689Sktlim@umich.edu    def __init__(self, ident, pairs):
422689Sktlim@umich.edu        super(Enumeration, self).__init__(pairs)
432689Sktlim@umich.edu        self.ident = ident
442292SN/A
452292SN/Aclass Method(object):
469944Smatt.horsnell@ARM.com    def __init__(self, return_type, param_types):
479944Smatt.horsnell@ARM.com        self.return_type = return_type
489944Smatt.horsnell@ARM.com        self.param_types = param_types
498591Sgblack@eecs.umich.edu
503326Sktlim@umich.educlass Type(Symbol):
518229Snate@binkert.org    def __init__(self, table, ident, location, pairs, machine=None):
526658Snate@binkert.org        super(Type, self).__init__(table, ident, location, pairs)
538887Sgeoffrey.blake@arm.com        self.c_ident = ident
542907Sktlim@umich.edu        if machine:
552292SN/A            if self.isExternal or self.isPrimitive:
568232Snate@binkert.org                if "external_name" in self:
578232Snate@binkert.org                    self.c_ident = self["external_name"]
588232Snate@binkert.org            else:
599527SMatt.Horsnell@arm.com                # Append with machine name
602722Sktlim@umich.edu                self.c_ident = "%s_%s" % (machine, ident)
612669Sktlim@umich.edu
622292SN/A        self.pairs.setdefault("desc", "No description avaliable")
632669Sktlim@umich.edu
6413429Srekai.gonzalezalberquilla@arm.com        # check for interface that this Type implements
6513429Srekai.gonzalezalberquilla@arm.com        if "interface" in self:
668581Ssteve.reinhardt@amd.com            interface = self["interface"]
678581Ssteve.reinhardt@amd.com            if interface in ("Message", "NetworkMessage"):
682292SN/A                self["message"] = "yes"
6913590Srekai.gonzalezalberquilla@arm.com            if interface == "NetworkMessage":
7013590Srekai.gonzalezalberquilla@arm.com                self["networkmessage"] = "yes"
712292SN/A
722292SN/A        # FIXME - all of the following id comparisons are fragile hacks
732669Sktlim@umich.edu        if self.ident in ("CacheMemory", "NewCacheMemory",
742292SN/A                          "TLCCacheMemory", "DNUCACacheMemory",
752678Sktlim@umich.edu                          "DNUCABankCacheMemory", "L2BankCacheMemory",
762292SN/A                          "CompressedCacheMemory", "PrefetchCacheMemory"):
779444SAndreas.Sandberg@ARM.com            self["cache"] = "yes"
789444SAndreas.Sandberg@ARM.com
799444SAndreas.Sandberg@ARM.com        if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"):
804319Sktlim@umich.edu            self["tbe"] = "yes"
8113590Srekai.gonzalezalberquilla@arm.com
8213590Srekai.gonzalezalberquilla@arm.com        if self.ident == "NewTBETable":
832678Sktlim@umich.edu            self["newtbe"] = "yes"
842678Sktlim@umich.edu
852292SN/A        if self.ident == "TimerTable":
862678Sktlim@umich.edu            self["timer"] = "yes"
872678Sktlim@umich.edu
885336Shines@cs.fsu.edu        if self.ident == "DirectoryMemory":
892678Sktlim@umich.edu            self["dir"] = "yes"
904873Sstever@eecs.umich.edu
912678Sktlim@umich.edu        if self.ident == "PersistentTable":
922292SN/A            self["persistent"] = "yes"
9313590Srekai.gonzalezalberquilla@arm.com
9413590Srekai.gonzalezalberquilla@arm.com        if self.ident == "Prefetcher":
9513590Srekai.gonzalezalberquilla@arm.com            self["prefetcher"] = "yes"
9613590Srekai.gonzalezalberquilla@arm.com
9713590Srekai.gonzalezalberquilla@arm.com        if self.ident == "DNUCA_Movement":
9813590Srekai.gonzalezalberquilla@arm.com            self["mover"] = "yes"
9913590Srekai.gonzalezalberquilla@arm.com
10013590Srekai.gonzalezalberquilla@arm.com        self.isMachineType = (ident == "MachineType")
10113590Srekai.gonzalezalberquilla@arm.com
10213590Srekai.gonzalezalberquilla@arm.com        self.data_members = orderdict()
10313590Srekai.gonzalezalberquilla@arm.com
10413590Srekai.gonzalezalberquilla@arm.com        # Methods
10513590Srekai.gonzalezalberquilla@arm.com        self.methods = {}
10613590Srekai.gonzalezalberquilla@arm.com
10713590Srekai.gonzalezalberquilla@arm.com        # Enums
10813590Srekai.gonzalezalberquilla@arm.com        self.enums = orderdict()
10913590Srekai.gonzalezalberquilla@arm.com
11013590Srekai.gonzalezalberquilla@arm.com    @property
1112678Sktlim@umich.edu    def isPrimitive(self):
1122678Sktlim@umich.edu        return "primitive" in self
1132678Sktlim@umich.edu    @property
1142678Sktlim@umich.edu    def isNetworkMessage(self):
1152678Sktlim@umich.edu        return "networkmessage" in self
1162678Sktlim@umich.edu    @property
1172344SN/A    def isMessage(self):
11813590Srekai.gonzalezalberquilla@arm.com        return "message" in self
1192678Sktlim@umich.edu    @property
12013590Srekai.gonzalezalberquilla@arm.com    def isBuffer(self):
12113590Srekai.gonzalezalberquilla@arm.com        return "buffer" in self
12213590Srekai.gonzalezalberquilla@arm.com    @property
1236974Stjones1@inf.ed.ac.uk    def isInPort(self):
1249444SAndreas.Sandberg@ARM.com        return "inport" in self
12510327Smitch.hayenga@arm.com    @property
12613590Srekai.gonzalezalberquilla@arm.com    def isOutPort(self):
12713652Sqtt2@cornell.edu        return "outport" in self
12812216Snikos.nikoleris@arm.com    @property
12913652Sqtt2@cornell.edu    def isEnumeration(self):
13013652Sqtt2@cornell.edu        return "enumeration" in self
13113590Srekai.gonzalezalberquilla@arm.com    @property
13213652Sqtt2@cornell.edu    def isExternal(self):
13313590Srekai.gonzalezalberquilla@arm.com        return "external" in self
13413590Srekai.gonzalezalberquilla@arm.com    @property
13513590Srekai.gonzalezalberquilla@arm.com    def isGlobal(self):
1366974Stjones1@inf.ed.ac.uk        return "global" in self
13713590Srekai.gonzalezalberquilla@arm.com    @property
13813652Sqtt2@cornell.edu    def isInterface(self):
13913652Sqtt2@cornell.edu        return "interface" in self
14013590Srekai.gonzalezalberquilla@arm.com
1412678Sktlim@umich.edu    # Return false on error
1422344SN/A    def dataMemberAdd(self, ident, type, pairs, init_code):
1432292SN/A        if ident in self.data_members:
1442292SN/A            return False
1452292SN/A
14613472Srekai.gonzalezalberquilla@arm.com        member = DataMember(ident, type, pairs, init_code)
14713472Srekai.gonzalezalberquilla@arm.com        self.data_members[ident] = member
14813472Srekai.gonzalezalberquilla@arm.com
14913590Srekai.gonzalezalberquilla@arm.com        return True
15013590Srekai.gonzalezalberquilla@arm.com
1512292SN/A    def dataMemberType(self, ident):
1522292SN/A        return self.data_members[ident].type
1532292SN/A
1542292SN/A    def methodId(self, name, param_type_vec):
1552292SN/A        return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])
1565529Snate@binkert.org
15713472Srekai.gonzalezalberquilla@arm.com    def methodAdd(self, name, return_type, param_type_vec):
1582292SN/A        ident = self.methodId(name, param_type_vec)
15913472Srekai.gonzalezalberquilla@arm.com        if ident in self.methods:
16013472Srekai.gonzalezalberquilla@arm.com            return False
1614329Sktlim@umich.edu
1624329Sktlim@umich.edu        self.methods[ident] = Method(return_type, param_type_vec)
1634329Sktlim@umich.edu        return True
1642907Sktlim@umich.edu
1652907Sktlim@umich.edu    def enumAdd(self, ident, pairs):
16613472Srekai.gonzalezalberquilla@arm.com        if ident in self.enums:
1672292SN/A            return False
1688199SAli.Saidi@ARM.com
1698199SAli.Saidi@ARM.com        self.enums[ident] = Enumeration(ident, pairs)
1709444SAndreas.Sandberg@ARM.com
1719444SAndreas.Sandberg@ARM.com        # Add default
1729444SAndreas.Sandberg@ARM.com        if "default" not in self:
1739444SAndreas.Sandberg@ARM.com            self["default"] = "%s_NUM" % self.c_ident
1749444SAndreas.Sandberg@ARM.com
1759444SAndreas.Sandberg@ARM.com        return True
1769444SAndreas.Sandberg@ARM.com
1779444SAndreas.Sandberg@ARM.com    def writeCodeFiles(self, path):
1789444SAndreas.Sandberg@ARM.com        if self.isExternal:
1799444SAndreas.Sandberg@ARM.com            # Do nothing
1809444SAndreas.Sandberg@ARM.com            pass
1818199SAli.Saidi@ARM.com        elif self.isEnumeration:
1822292SN/A            self.printEnumHH(path)
18313590Srekai.gonzalezalberquilla@arm.com            self.printEnumCC(path)
1842292SN/A        else:
1853492Sktlim@umich.edu            # User defined structs and messages
1862329SN/A            self.printTypeHH(path)
1872292SN/A            self.printTypeCC(path)
1889444SAndreas.Sandberg@ARM.com
1899444SAndreas.Sandberg@ARM.com    def printTypeHH(self, path):
1909814Sandreas.hansson@arm.com        code = code_formatter()
1912292SN/A        code('''
1922292SN/A/** \\file ${{self.c_ident}}.hh
1932292SN/A *
1942292SN/A *
1952292SN/A * Auto generated C++ code started by $__file__:$__line__
1962292SN/A */
1972292SN/A
1982292SN/A#ifndef ${{self.c_ident}}_H
1992292SN/A#define ${{self.c_ident}}_H
20010386Sandreas.hansson@arm.com
2012292SN/A#include "mem/ruby/common/Global.hh"
2022292SN/A#include "mem/gems_common/Allocator.hh"
2032292SN/A''')
2042292SN/A
2052292SN/A        for dm in self.data_members.values():
2062727Sktlim@umich.edu            if not dm.type.isPrimitive:
2072727Sktlim@umich.edu                code('#include "mem/protocol/$0.hh"', dm.type.c_ident)
2082727Sktlim@umich.edu
2092727Sktlim@umich.edu        parent = ""
2102727Sktlim@umich.edu        if "interface" in self:
2112727Sktlim@umich.edu            code('#include "mem/protocol/$0.hh"', self["interface"])
2122727Sktlim@umich.edu            parent = " :  public %s" % self["interface"]
2132727Sktlim@umich.edu
2142727Sktlim@umich.edu        code('''
2152727Sktlim@umich.edu$klass ${{self.c_ident}}$parent {
2162727Sktlim@umich.edu  public:
2172727Sktlim@umich.edu    ${{self.c_ident}}()
2182727Sktlim@umich.edu''', klass="class")
2192727Sktlim@umich.edu
2202727Sktlim@umich.edu        # Call superclass constructor
2212727Sktlim@umich.edu        if "interface" in self:
2222727Sktlim@umich.edu            code('        : ${{self["interface"]}}()')
2232727Sktlim@umich.edu
2242361SN/A        code.indent()
2252361SN/A        code("{")
2262361SN/A        if not self.isGlobal:
2272361SN/A            code.indent()
2282727Sktlim@umich.edu            for dm in self.data_members.values():
2292727Sktlim@umich.edu                ident = dm.ident
2302727Sktlim@umich.edu                if "default" in dm:
2312727Sktlim@umich.edu                    # look for default value
2322727Sktlim@umich.edu                    code('m_$ident = ${{dm["default"]}}; // default for this field')
2332727Sktlim@umich.edu                elif "default" in dm.type:
2342727Sktlim@umich.edu                    # Look for the type default
2352727Sktlim@umich.edu                    tid = dm.type.c_ident
2362727Sktlim@umich.edu                    code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
2372727Sktlim@umich.edu                else:
2382727Sktlim@umich.edu                    code('// m_$ident has no default')
2392727Sktlim@umich.edu            code.dedent()
2402727Sktlim@umich.edu        code('}')
2412727Sktlim@umich.edu
2422727Sktlim@umich.edu        # ******** Default destructor ********
2432727Sktlim@umich.edu        code('~${{self.c_ident}}() { };')
2442727Sktlim@umich.edu
2452727Sktlim@umich.edu        # ******** Full init constructor ********
2462727Sktlim@umich.edu        if not self.isGlobal:
2472727Sktlim@umich.edu            params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
2482727Sktlim@umich.edu                       for dm in self.data_members.itervalues() ]
2492727Sktlim@umich.edu
2502727Sktlim@umich.edu            if self.isMessage:
2518922Swilliam.wang@arm.com                params.append('const unsigned local_proc_id')
2524329Sktlim@umich.edu
2534329Sktlim@umich.edu            params = ', '.join(params)
2544329Sktlim@umich.edu            code('${{self.c_ident}}($params)')
2554329Sktlim@umich.edu
2564329Sktlim@umich.edu            # Call superclass constructor
2574329Sktlim@umich.edu            if "interface" in self:
2589444SAndreas.Sandberg@ARM.com                code('    : ${{self["interface"]}}()')
2592307SN/A
26013590Srekai.gonzalezalberquilla@arm.com            code('{')
26113590Srekai.gonzalezalberquilla@arm.com            code.indent()
2622307SN/A            for dm in self.data_members.values():
2632329SN/A                code('m_${{dm.ident}} = local_${{dm.ident}};')
2649444SAndreas.Sandberg@ARM.com                if "nextLineCallHack" in dm:
2652307SN/A                    code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};')
2662307SN/A
2672307SN/A            if self.isMessage:
2682307SN/A                code('proc_id = local_proc_id;')
2692307SN/A
2702307SN/A            code.dedent()
2719444SAndreas.Sandberg@ARM.com            code('}')
2722307SN/A
2732307SN/A        # create a static factory method
2742292SN/A        if "interface" in self:
2752292SN/A            code('''
27613429Srekai.gonzalezalberquilla@arm.comstatic ${{self["interface"]}}* create() {
2772292SN/A    return new ${{self.c_ident}}();
2782292SN/A}
2792292SN/A''')
28013652Sqtt2@cornell.edu
2812292SN/A        # ******** Message member functions ********
2822292SN/A        # FIXME: those should be moved into slicc file, slicc should
2832292SN/A        # support more of the c++ class inheritance
2842292SN/A
2852292SN/A        if self.isMessage:
2862292SN/A            code('''
2872292SN/AMessage* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }
2882292SN/Avoid destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }
2892292SN/Astatic Allocator<${{self.c_ident}}>* s_allocator_ptr;
2902292SN/Astatic void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }}
2912292SN/A''')
2922292SN/A
29313429Srekai.gonzalezalberquilla@arm.com        if not self.isGlobal:
2942292SN/A            # const Get methods for each field
29513590Srekai.gonzalezalberquilla@arm.com            code('// Const accessors methods for each field')
29613590Srekai.gonzalezalberquilla@arm.com            for dm in self.data_members.values():
2972292SN/A                code('''
2987720Sgblack@eecs.umich.edu/** \\brief Const accessor method for ${{dm.ident}} field.
29913590Srekai.gonzalezalberquilla@arm.com *  \\return ${{dm.ident}} field
3002292SN/A */
30113590Srekai.gonzalezalberquilla@arm.comconst ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; }
30213590Srekai.gonzalezalberquilla@arm.com''')
3032292SN/A
30413590Srekai.gonzalezalberquilla@arm.com            # Non-const Get methods for each field
3052292SN/A            code('// Non const Accessors methods for each field')
30613590Srekai.gonzalezalberquilla@arm.com            for dm in self.data_members.values():
30713590Srekai.gonzalezalberquilla@arm.com                code('''
30813590Srekai.gonzalezalberquilla@arm.com/** \\brief Non-const accessor method for ${{dm.ident}} field.
30913590Srekai.gonzalezalberquilla@arm.com *  \\return ${{dm.ident}} field
3102292SN/A */
3112292SN/A${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; }
3122292SN/A''')
3132292SN/A
3142292SN/A            #Set methods for each field
3152292SN/A            code('// Mutator methods for each field')
31613590Srekai.gonzalezalberquilla@arm.com            for dm in self.data_members.values():
3172292SN/A                code('''
3182292SN/A/** \\brief Mutator method for ${{dm.ident}} field */
31913590Srekai.gonzalezalberquilla@arm.comvoid set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; }
32013590Srekai.gonzalezalberquilla@arm.com''')
3212292SN/A
3227720Sgblack@eecs.umich.edu        code('void print(ostream& out) const;')
32313590Srekai.gonzalezalberquilla@arm.com        code.dedent()
32413590Srekai.gonzalezalberquilla@arm.com        code('  //private:')
3252292SN/A        code.indent()
32613590Srekai.gonzalezalberquilla@arm.com
32713590Srekai.gonzalezalberquilla@arm.com        # Data members for each field
32813590Srekai.gonzalezalberquilla@arm.com        for dm in self.data_members.values():
3292292SN/A            if "abstract" not in dm:
33013590Srekai.gonzalezalberquilla@arm.com                const = ""
3312292SN/A                init = ""
3322292SN/A
3332292SN/A                # global structure
3342292SN/A                if self.isGlobal:
3352292SN/A                    const = "static const "
3362292SN/A
3372292SN/A                # init value
3382292SN/A                if dm.init_code:
3392292SN/A                    # only global structure can have init value here
3402292SN/A                    assert self.isGlobal
3412292SN/A                    init = " = %s" % (dm.init_code)
3422292SN/A
3432292SN/A                desc = ""
3442292SN/A                if "desc" in dm:
3452292SN/A                    desc = '/**< %s */' % dm["desc"]
3462292SN/A
3472292SN/A                code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc')
34810239Sbinhpham@cs.rutgers.edu
3492292SN/A        if self.isMessage:
35010239Sbinhpham@cs.rutgers.edu            code('unsigned proc_id;')
35110239Sbinhpham@cs.rutgers.edu
35213590Srekai.gonzalezalberquilla@arm.com        code.dedent()
35313590Srekai.gonzalezalberquilla@arm.com        code('};')
35413590Srekai.gonzalezalberquilla@arm.com
35510239Sbinhpham@cs.rutgers.edu        code('''
3562292SN/A// Output operator declaration
35710239Sbinhpham@cs.rutgers.eduostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
35810239Sbinhpham@cs.rutgers.edu
35910239Sbinhpham@cs.rutgers.edu// Output operator definition
36010239Sbinhpham@cs.rutgers.eduextern inline
36110239Sbinhpham@cs.rutgers.eduostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
36210239Sbinhpham@cs.rutgers.edu{
36313590Srekai.gonzalezalberquilla@arm.com    obj.print(out);
36413590Srekai.gonzalezalberquilla@arm.com    out << flush;
36513590Srekai.gonzalezalberquilla@arm.com    return out;
36610239Sbinhpham@cs.rutgers.edu}
36710239Sbinhpham@cs.rutgers.edu
3682292SN/A#endif // ${{self.c_ident}}_H
3692292SN/A''')
3708545Ssaidi@eecs.umich.edu
3718545Ssaidi@eecs.umich.edu        code.write(path, "%s.hh" % self.c_ident)
3728545Ssaidi@eecs.umich.edu
37311357Sstephan.diestelhorst@arm.com    def printTypeCC(self, path):
37411357Sstephan.diestelhorst@arm.com        code = code_formatter()
37511357Sstephan.diestelhorst@arm.com
37610030SAli.Saidi@ARM.com        code('''
3778545Ssaidi@eecs.umich.edu/** \\file ${{self.c_ident}}.cc
37810030SAli.Saidi@ARM.com *
3799383SAli.Saidi@ARM.com * Auto generated C++ code started by $__file__:$__line__
3809383SAli.Saidi@ARM.com */
3819383SAli.Saidi@ARM.com
3829383SAli.Saidi@ARM.com#include "mem/protocol/${{self.c_ident}}.hh"
3839383SAli.Saidi@ARM.com''')
3849383SAli.Saidi@ARM.com
3859383SAli.Saidi@ARM.com        if self.isMessage:
38613590Srekai.gonzalezalberquilla@arm.com            code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;')
38713590Srekai.gonzalezalberquilla@arm.com        code('''
38813590Srekai.gonzalezalberquilla@arm.com/** \\brief Print the state of this object */
38913590Srekai.gonzalezalberquilla@arm.comvoid ${{self.c_ident}}::print(ostream& out) const
39013590Srekai.gonzalezalberquilla@arm.com{
39110030SAli.Saidi@ARM.com    out << "[${{self.c_ident}}: ";
39210030SAli.Saidi@ARM.com''')
39313590Srekai.gonzalezalberquilla@arm.com
39413590Srekai.gonzalezalberquilla@arm.com        # For each field
39513590Srekai.gonzalezalberquilla@arm.com        code.indent()
39611097Songal@cs.wisc.edu        for dm in self.data_members.values():
39713590Srekai.gonzalezalberquilla@arm.com            code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
39813590Srekai.gonzalezalberquilla@arm.com
39913590Srekai.gonzalezalberquilla@arm.com        if self.isMessage:
40013590Srekai.gonzalezalberquilla@arm.com            code('out << "Time = " << getTime() << " ";')
40113590Srekai.gonzalezalberquilla@arm.com        code.dedent()
4028545Ssaidi@eecs.umich.edu
40310149Smarco.elver@ed.ac.uk        # Trailer
40410149Smarco.elver@ed.ac.uk        code('''
40513590Srekai.gonzalezalberquilla@arm.com    out << "]";
40613590Srekai.gonzalezalberquilla@arm.com}''')
40713590Srekai.gonzalezalberquilla@arm.com
40813590Srekai.gonzalezalberquilla@arm.com        code.write(path, "%s.cc" % self.c_ident)
40913590Srekai.gonzalezalberquilla@arm.com
41013590Srekai.gonzalezalberquilla@arm.com    def printEnumHH(self, path):
4118545Ssaidi@eecs.umich.edu        code = code_formatter()
41213590Srekai.gonzalezalberquilla@arm.com        code('''
41313590Srekai.gonzalezalberquilla@arm.com/** \\file ${{self.c_ident}}.hh
4148545Ssaidi@eecs.umich.edu *
41513590Srekai.gonzalezalberquilla@arm.com * Auto generated C++ code started by $__file__:$__line__
41613590Srekai.gonzalezalberquilla@arm.com */
41710149Smarco.elver@ed.ac.uk#ifndef ${{self.c_ident}}_H
41810149Smarco.elver@ed.ac.uk#define ${{self.c_ident}}_H
41910149Smarco.elver@ed.ac.uk
42010149Smarco.elver@ed.ac.uk#include "mem/ruby/common/Global.hh"
42110149Smarco.elver@ed.ac.uk
42210149Smarco.elver@ed.ac.uk/** \\enum ${{self.c_ident}}
42310149Smarco.elver@ed.ac.uk *  \\brief ${{self.desc}}
4248545Ssaidi@eecs.umich.edu */
42510030SAli.Saidi@ARM.comenum ${{self.c_ident}} {
4268545Ssaidi@eecs.umich.edu    ${{self.c_ident}}_FIRST,
4278545Ssaidi@eecs.umich.edu''')
42810474Sandreas.hansson@arm.com
4298545Ssaidi@eecs.umich.edu        code.indent()
43010030SAli.Saidi@ARM.com        # For each field
43110030SAli.Saidi@ARM.com        for i,(ident,enum) in enumerate(self.enums.iteritems()):
43210030SAli.Saidi@ARM.com            desc = enum.get("desc", "No description avaliable")
43310030SAli.Saidi@ARM.com            if i == 0:
43410030SAli.Saidi@ARM.com                init = ' = %s_FIRST' % self.c_ident
43510030SAli.Saidi@ARM.com            else:
43610030SAli.Saidi@ARM.com                init = ''
43710030SAli.Saidi@ARM.com            code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
43810030SAli.Saidi@ARM.com        code.dedent()
4398545Ssaidi@eecs.umich.edu        code('''
4408545Ssaidi@eecs.umich.edu    ${{self.c_ident}}_NUM
4418545Ssaidi@eecs.umich.edu};
4429046SAli.Saidi@ARM.com${{self.c_ident}} string_to_${{self.c_ident}}(const string& str);
4438545Ssaidi@eecs.umich.edustring ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
4448545Ssaidi@eecs.umich.edu${{self.c_ident}} &operator++(${{self.c_ident}} &e);
4458545Ssaidi@eecs.umich.edu''')
4468545Ssaidi@eecs.umich.edu
4478545Ssaidi@eecs.umich.edu        # MachineType hack used to set the base component id for each Machine
4488545Ssaidi@eecs.umich.edu        if self.isMachineType:
4498545Ssaidi@eecs.umich.edu            code('''
4502292SN/Aint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
45113590Srekai.gonzalezalberquilla@arm.comMachineType ${{self.c_ident}}_from_base_level(int);
45213590Srekai.gonzalezalberquilla@arm.comint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
4538199SAli.Saidi@ARM.comint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
4548199SAli.Saidi@ARM.com''')
4558199SAli.Saidi@ARM.com
4568199SAli.Saidi@ARM.com            for enum in self.enums.itervalues():
4578199SAli.Saidi@ARM.com                code('#define MACHINETYPE_${{enum.ident}} 1')
4588199SAli.Saidi@ARM.com
4598199SAli.Saidi@ARM.com        # Trailer
4608199SAli.Saidi@ARM.com        code('''
4618199SAli.Saidi@ARM.comostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
46213590Srekai.gonzalezalberquilla@arm.com
46313590Srekai.gonzalezalberquilla@arm.com#endif // ${{self.c_ident}}_H
46410824SAndreas.Sandberg@ARM.com''')
46513590Srekai.gonzalezalberquilla@arm.com
4668199SAli.Saidi@ARM.com        code.write(path, "%s.hh" % self.c_ident)
4678199SAli.Saidi@ARM.com
4688199SAli.Saidi@ARM.com    def printEnumCC(self, path):
4698199SAli.Saidi@ARM.com        code = code_formatter()
4708199SAli.Saidi@ARM.com        code('''
4718199SAli.Saidi@ARM.com/** \\file ${{self.c_ident}}.hh
4728199SAli.Saidi@ARM.com *
4738272SAli.Saidi@ARM.com * Auto generated C++ code started by $__file__:$__line__
4748545Ssaidi@eecs.umich.edu */
4758545Ssaidi@eecs.umich.edu
4768545Ssaidi@eecs.umich.edu#include "mem/protocol/${{self.c_ident}}.hh"
4778545Ssaidi@eecs.umich.edu
4789046SAli.Saidi@ARM.com''')
4798545Ssaidi@eecs.umich.edu
4808545Ssaidi@eecs.umich.edu        if self.isMachineType:
4818545Ssaidi@eecs.umich.edu            code('#include "mem/protocol/ControllerFactory.hh"')
4828592Sgblack@eecs.umich.edu            for enum in self.enums.itervalues():
4838592Sgblack@eecs.umich.edu                code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
4848545Ssaidi@eecs.umich.edu
4858199SAli.Saidi@ARM.com        code('''
4868545Ssaidi@eecs.umich.eduostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
4878199SAli.Saidi@ARM.com{
48810474Sandreas.hansson@arm.com    out << ${{self.c_ident}}_to_string(obj);
48910474Sandreas.hansson@arm.com    out << flush;
49010474Sandreas.hansson@arm.com    return out;
49110474Sandreas.hansson@arm.com}
4928545Ssaidi@eecs.umich.edu
4938545Ssaidi@eecs.umich.edustring ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
4948199SAli.Saidi@ARM.com{
4958545Ssaidi@eecs.umich.edu    switch(obj) {
4968545Ssaidi@eecs.umich.edu''')
4979046SAli.Saidi@ARM.com
49810575SMarco.Elver@ARM.com        # For each field
4998545Ssaidi@eecs.umich.edu        code.indent()
5008545Ssaidi@eecs.umich.edu        for enum in self.enums.itervalues():
5018545Ssaidi@eecs.umich.edu            code('  case ${{self.c_ident}}_${{enum.ident}}:')
5028545Ssaidi@eecs.umich.edu            code('    return "${{enum.ident}}";')
5038545Ssaidi@eecs.umich.edu        code.dedent()
5048545Ssaidi@eecs.umich.edu
5058545Ssaidi@eecs.umich.edu        # Trailer
5068545Ssaidi@eecs.umich.edu        code('''
5078545Ssaidi@eecs.umich.edu      default:
5088592Sgblack@eecs.umich.edu        ERROR_MSG("Invalid range for type ${{self.c_ident}}");
5098592Sgblack@eecs.umich.edu        return "";
5108592Sgblack@eecs.umich.edu    }
5118545Ssaidi@eecs.umich.edu}
5128545Ssaidi@eecs.umich.edu
5138545Ssaidi@eecs.umich.edu${{self.c_ident}} string_to_${{self.c_ident}}(const string& str)
5148545Ssaidi@eecs.umich.edu{
51510474Sandreas.hansson@arm.com''')
51610474Sandreas.hansson@arm.com
51710474Sandreas.hansson@arm.com        # For each field
51810474Sandreas.hansson@arm.com        code.indent()
5198545Ssaidi@eecs.umich.edu        code("if (false) {")
5208199SAli.Saidi@ARM.com        start = "} else "
5218199SAli.Saidi@ARM.com        for enum in self.enums.itervalues():
52213590Srekai.gonzalezalberquilla@arm.com            code('${start}if (str == "${{enum.ident}}") {')
5238199SAli.Saidi@ARM.com            code('    return ${{self.c_ident}}_${{enum.ident}};')
5248199SAli.Saidi@ARM.com        code.dedent()
5258199SAli.Saidi@ARM.com
5268199SAli.Saidi@ARM.com        code('''
5278199SAli.Saidi@ARM.com    } else {
5288199SAli.Saidi@ARM.com        WARN_EXPR(str);
5298199SAli.Saidi@ARM.com        ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}");
5308199SAli.Saidi@ARM.com    }
5318199SAli.Saidi@ARM.com}
53213429Srekai.gonzalezalberquilla@arm.com
5332292SN/A${{self.c_ident}}& operator++(${{self.c_ident}}& e) {
5344032Sktlim@umich.edu    assert(e < ${{self.c_ident}}_NUM);
5352292SN/A    return e = ${{self.c_ident}}(e+1);
5362292SN/A}
5372292SN/A''')
5387720Sgblack@eecs.umich.edu
5397944SGiacomo.Gabrielli@arm.com        # MachineType hack used to set the base level and number of
5402292SN/A        # components for each Machine
5414032Sktlim@umich.edu        if self.isMachineType:
5424032Sktlim@umich.edu            code('''
5432669Sktlim@umich.edu/** \\brief returns the base vector index for each machine type to be used by NetDest
5442292SN/A  *
54513954Sgiacomo.gabrielli@arm.com  * \\return the base vector index for each machine type to be used by NetDest
54613953Sgiacomo.gabrielli@arm.com  * \\see NetDest.hh
54713953Sgiacomo.gabrielli@arm.com  */
54813953Sgiacomo.gabrielli@arm.comint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
54913953Sgiacomo.gabrielli@arm.com{
55013953Sgiacomo.gabrielli@arm.com    switch(obj) {
55113953Sgiacomo.gabrielli@arm.com''')
55213953Sgiacomo.gabrielli@arm.com
55313953Sgiacomo.gabrielli@arm.com            # For each field
55413590Srekai.gonzalezalberquilla@arm.com            code.indent()
5557944SGiacomo.Gabrielli@arm.com            for i,enum in enumerate(self.enums.itervalues()):
5567944SGiacomo.Gabrielli@arm.com                code('  case ${{self.c_ident}}_${{enum.ident}}:')
55714105Sgabor.dozsa@arm.com                code('    return $i;')
55814105Sgabor.dozsa@arm.com            code.dedent()
55914105Sgabor.dozsa@arm.com
56014105Sgabor.dozsa@arm.com            # total num
56114105Sgabor.dozsa@arm.com            code('''
56214105Sgabor.dozsa@arm.com      case ${{self.c_ident}}_NUM:
56314105Sgabor.dozsa@arm.com        return ${{len(self.enums)}};
56414105Sgabor.dozsa@arm.com
56514105Sgabor.dozsa@arm.com      default:
56614105Sgabor.dozsa@arm.com        ERROR_MSG("Invalid range for type ${{self.c_ident}}");
5677597Sminkyu.jeong@arm.com        return -1;
5687597Sminkyu.jeong@arm.com    }
56910231Ssteve.reinhardt@amd.com}
5702329SN/A
57110824SAndreas.Sandberg@ARM.com/** \\brief returns the machine type for each base vector index used by NetDest
57210824SAndreas.Sandberg@ARM.com *
57310824SAndreas.Sandberg@ARM.com * \\return the MachineTYpe
57410231Ssteve.reinhardt@amd.com */
5757848SAli.Saidi@ARM.comMachineType ${{self.c_ident}}_from_base_level(int type)
5767600Sminkyu.jeong@arm.com{
5777600Sminkyu.jeong@arm.com    switch(type) {
5787600Sminkyu.jeong@arm.com''')
57910824SAndreas.Sandberg@ARM.com
5803731Sktlim@umich.edu            # For each field
5812367SN/A            code.indent()
5822367SN/A            for i,enum in enumerate(self.enums.itervalues()):
5832292SN/A                code('  case $i:')
5842292SN/A                code('    return ${{self.c_ident}}_${{enum.ident}};')
58510333Smitch.hayenga@arm.com            code.dedent()
58613590Srekai.gonzalezalberquilla@arm.com
58713590Srekai.gonzalezalberquilla@arm.com            # Trailer
58813590Srekai.gonzalezalberquilla@arm.com            code('''
5894032Sktlim@umich.edu      default:
59013590Srekai.gonzalezalberquilla@arm.com        ERROR_MSG("Invalid range for type ${{self.c_ident}}");
59113590Srekai.gonzalezalberquilla@arm.com        return MachineType_NUM;
59213590Srekai.gonzalezalberquilla@arm.com    }
5932292SN/A}
5942292SN/A
5952292SN/A/** \\brief The return value indicates the number of components created
5962292SN/A * before a particular machine\'s components
5972292SN/A *
5982292SN/A * \\return the base number of components for each machine
5992292SN/A */
60013429Srekai.gonzalezalberquilla@arm.comint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
6012292SN/A{
6022292SN/A    int base = 0;
6032292SN/A    switch(obj) {
6042292SN/A''')
6052292SN/A
6062292SN/A            # For each field
6072292SN/A            code.indent()
6087720Sgblack@eecs.umich.edu            code('  case ${{self.c_ident}}_NUM:')
6097720Sgblack@eecs.umich.edu            for enum in reversed(self.enums.values()):
6102292SN/A                code('    base += ${{enum.ident}}_Controller::getNumControllers();')
6114032Sktlim@umich.edu                code('  case ${{self.c_ident}}_${{enum.ident}}:')
6124032Sktlim@umich.edu            code('    break;')
6132292SN/A            code.dedent()
6142292SN/A
61513590Srekai.gonzalezalberquilla@arm.com            code('''
6162292SN/A      default:
6172292SN/A        ERROR_MSG("Invalid range for type ${{self.c_ident}}");
6182292SN/A        return -1;
6197944SGiacomo.Gabrielli@arm.com    }
6207944SGiacomo.Gabrielli@arm.com
6217944SGiacomo.Gabrielli@arm.com    return base;
6227944SGiacomo.Gabrielli@arm.com}
62312217Snikos.nikoleris@arm.com
62412217Snikos.nikoleris@arm.com/** \\brief returns the total number of components for each machine
62512217Snikos.nikoleris@arm.com * \\return the total number of components for each machine
6267848SAli.Saidi@ARM.com */
62712217Snikos.nikoleris@arm.comint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
62812217Snikos.nikoleris@arm.com{
6297848SAli.Saidi@ARM.com    switch(obj) {
63013590Srekai.gonzalezalberquilla@arm.com''')
6317782Sminkyu.jeong@arm.com
6327720Sgblack@eecs.umich.edu            # For each field
6332292SN/A            for enum in self.enums.itervalues():
6342292SN/A                code('''
6352292SN/A      case ${{self.c_ident}}_${{enum.ident}}:
6362292SN/A        return ${{enum.ident}}_Controller::getNumControllers();
6372292SN/A''')
6382292SN/A
63913652Sqtt2@cornell.edu            # total num
64013652Sqtt2@cornell.edu            code('''
6412336SN/A      case ${{self.c_ident}}_NUM:
64213590Srekai.gonzalezalberquilla@arm.com      default:
6432292SN/A        ERROR_MSG("Invalid range for type ${{self.c_ident}}");
6442329SN/A        return -1;
6452292SN/A    }
6462292SN/A}
64713590Srekai.gonzalezalberquilla@arm.com''')
6482292SN/A
6492292SN/A        # Write the file
6502292SN/A        code.write(path, "%s.cc" % self.c_ident)
6512292SN/A
6522292SN/A__all__ = [ "Type" ]
6532292SN/A