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