Type.py revision 7002
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 310333Smitch.hayenga@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 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 self.abstract_ident = "" 552292SN/A if machine: 568232Snate@binkert.org if self.isExternal or self.isPrimitive: 578232Snate@binkert.org if "external_name" in self: 588232Snate@binkert.org self.c_ident = self["external_name"] 599527SMatt.Horsnell@arm.com else: 602722Sktlim@umich.edu # Append with machine name 612669Sktlim@umich.edu self.c_ident = "%s_%s" % (machine, ident) 622292SN/A 632669Sktlim@umich.edu self.pairs.setdefault("desc", "No description avaliable") 642678Sktlim@umich.edu 652678Sktlim@umich.edu # check for interface that this Type implements 668581Ssteve.reinhardt@amd.com if "interface" in self: 678581Ssteve.reinhardt@amd.com interface = self["interface"] 682292SN/A if interface in ("Message", "NetworkMessage"): 692292SN/A self["message"] = "yes" 702292SN/A if interface == "NetworkMessage": 712669Sktlim@umich.edu self["networkmessage"] = "yes" 722292SN/A 732678Sktlim@umich.edu # FIXME - all of the following id comparisons are fragile hacks 742292SN/A if self.ident in ("CacheMemory", "NewCacheMemory", 759444SAndreas.Sandberg@ARM.com "TLCCacheMemory", "DNUCACacheMemory", 769444SAndreas.Sandberg@ARM.com "DNUCABankCacheMemory", "L2BankCacheMemory", 779444SAndreas.Sandberg@ARM.com "CompressedCacheMemory", "PrefetchCacheMemory"): 784319Sktlim@umich.edu self["cache"] = "yes" 794319Sktlim@umich.edu 804319Sktlim@umich.edu if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"): 814319Sktlim@umich.edu self["tbe"] = "yes" 824319Sktlim@umich.edu 832678Sktlim@umich.edu if self.ident == "NewTBETable": 842678Sktlim@umich.edu self["newtbe"] = "yes" 852292SN/A 862678Sktlim@umich.edu if self.ident == "TimerTable": 872678Sktlim@umich.edu self["timer"] = "yes" 885336Shines@cs.fsu.edu 892678Sktlim@umich.edu if self.ident == "DirectoryMemory": 904873Sstever@eecs.umich.edu self["dir"] = "yes" 912678Sktlim@umich.edu 922292SN/A if self.ident == "PersistentTable": 932678Sktlim@umich.edu self["persistent"] = "yes" 942678Sktlim@umich.edu 952678Sktlim@umich.edu if self.ident == "Prefetcher": 962678Sktlim@umich.edu self["prefetcher"] = "yes" 972678Sktlim@umich.edu 982678Sktlim@umich.edu if self.ident == "DNUCA_Movement": 997852SMatt.Horsnell@arm.com self["mover"] = "yes" 1007852SMatt.Horsnell@arm.com 1012344SN/A self.isMachineType = (ident == "MachineType") 10210333Smitch.hayenga@arm.com 10310333Smitch.hayenga@arm.com self.data_members = orderdict() 10410333Smitch.hayenga@arm.com 10510333Smitch.hayenga@arm.com # Methods 10610333Smitch.hayenga@arm.com self.methods = {} 10710333Smitch.hayenga@arm.com 10810333Smitch.hayenga@arm.com # Enums 10910333Smitch.hayenga@arm.com self.enums = orderdict() 11010333Smitch.hayenga@arm.com 11110333Smitch.hayenga@arm.com @property 1122678Sktlim@umich.edu def isPrimitive(self): 1136974Stjones1@inf.ed.ac.uk return "primitive" in self 1146974Stjones1@inf.ed.ac.uk @property 1156974Stjones1@inf.ed.ac.uk def isNetworkMessage(self): 1166974Stjones1@inf.ed.ac.uk return "networkmessage" in self 1176974Stjones1@inf.ed.ac.uk @property 1186974Stjones1@inf.ed.ac.uk def isMessage(self): 1196974Stjones1@inf.ed.ac.uk return "message" in self 1209444SAndreas.Sandberg@ARM.com @property 12110327Smitch.hayenga@arm.com def isBuffer(self): 1222678Sktlim@umich.edu return "buffer" in self 1236974Stjones1@inf.ed.ac.uk @property 1246974Stjones1@inf.ed.ac.uk def isInPort(self): 1256974Stjones1@inf.ed.ac.uk return "inport" in self 1266974Stjones1@inf.ed.ac.uk @property 1276974Stjones1@inf.ed.ac.uk def isOutPort(self): 1286974Stjones1@inf.ed.ac.uk return "outport" in self 1292678Sktlim@umich.edu @property 1302678Sktlim@umich.edu def isEnumeration(self): 1312678Sktlim@umich.edu return "enumeration" in self 1322678Sktlim@umich.edu @property 1332678Sktlim@umich.edu def isExternal(self): 1342344SN/A return "external" in self 1352307SN/A @property 1366974Stjones1@inf.ed.ac.uk def isGlobal(self): 1376974Stjones1@inf.ed.ac.uk return "global" in self 1386974Stjones1@inf.ed.ac.uk @property 1396974Stjones1@inf.ed.ac.uk def isInterface(self): 14010020Smatt.horsnell@ARM.com return "interface" in self 14110020Smatt.horsnell@ARM.com 14210023Smatt.horsnell@ARM.com # Return false on error 14310023Smatt.horsnell@ARM.com def dataMemberAdd(self, ident, type, pairs, init_code): 1442678Sktlim@umich.edu if ident in self.data_members: 1454032Sktlim@umich.edu return False 1462678Sktlim@umich.edu 1472292SN/A member = DataMember(ident, type, pairs, init_code) 1482292SN/A self.data_members[ident] = member 1492292SN/A 1502292SN/A return True 1518545Ssaidi@eecs.umich.edu 15210333Smitch.hayenga@arm.com def dataMemberType(self, ident): 1532292SN/A return self.data_members[ident].type 1542292SN/A 1552292SN/A def methodId(self, name, param_type_vec): 1562292SN/A return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) 1572292SN/A 1585529Snate@binkert.org def methodIdAbstract(self, name, param_type_vec): 1595529Snate@binkert.org return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ]) 1605529Snate@binkert.org 1612292SN/A def methodAdd(self, name, return_type, param_type_vec): 1624329Sktlim@umich.edu ident = self.methodId(name, param_type_vec) 1634329Sktlim@umich.edu if ident in self.methods: 1644329Sktlim@umich.edu return False 1652907Sktlim@umich.edu 1662907Sktlim@umich.edu self.methods[ident] = Method(return_type, param_type_vec) 1672292SN/A return True 1682292SN/A 16910175SMitch.Hayenga@ARM.com def enumAdd(self, ident, pairs): 17010175SMitch.Hayenga@ARM.com if ident in self.enums: 1712329SN/A return False 1722329SN/A 1732329SN/A self.enums[ident] = Enumeration(ident, pairs) 1742292SN/A 1759936SFaissal.Sleiman@arm.com # Add default 1769936SFaissal.Sleiman@arm.com if "default" not in self: 1779936SFaissal.Sleiman@arm.com self["default"] = "%s_NUM" % self.c_ident 1789936SFaissal.Sleiman@arm.com 1792292SN/A return True 1802292SN/A 1812292SN/A def writeCodeFiles(self, path): 1828199SAli.Saidi@ARM.com if self.isExternal: 1838199SAli.Saidi@ARM.com # Do nothing 1849444SAndreas.Sandberg@ARM.com pass 1859444SAndreas.Sandberg@ARM.com elif self.isEnumeration: 1869444SAndreas.Sandberg@ARM.com self.printEnumHH(path) 1879444SAndreas.Sandberg@ARM.com self.printEnumCC(path) 1889444SAndreas.Sandberg@ARM.com else: 1899444SAndreas.Sandberg@ARM.com # User defined structs and messages 1909444SAndreas.Sandberg@ARM.com self.printTypeHH(path) 1919444SAndreas.Sandberg@ARM.com self.printTypeCC(path) 1929444SAndreas.Sandberg@ARM.com 1939444SAndreas.Sandberg@ARM.com def printTypeHH(self, path): 1949444SAndreas.Sandberg@ARM.com code = self.symtab.codeFormatter() 1959444SAndreas.Sandberg@ARM.com code(''' 1968199SAli.Saidi@ARM.com/** \\file ${{self.c_ident}}.hh 1972292SN/A * 1982292SN/A * 1992292SN/A * Auto generated C++ code started by $__file__:$__line__ 2002292SN/A */ 2012292SN/A 2022292SN/A#ifndef ${{self.c_ident}}_H 2033492Sktlim@umich.edu#define ${{self.c_ident}}_H 2042329SN/A 2052292SN/A#include <iostream> 2069444SAndreas.Sandberg@ARM.com 2079444SAndreas.Sandberg@ARM.com#include "mem/ruby/common/Global.hh" 2089814Sandreas.hansson@arm.com#include "mem/gems_common/Allocator.hh" 2092292SN/A''') 2102292SN/A 2112292SN/A for dm in self.data_members.values(): 2122292SN/A if not dm.type.isPrimitive: 2132292SN/A code('#include "mem/protocol/$0.hh"', dm.type.c_ident) 2142292SN/A 2152292SN/A parent = "" 2162292SN/A if "interface" in self: 2172292SN/A code('#include "mem/protocol/$0.hh"', self["interface"]) 2188247Snate@binkert.org parent = " : public %s" % self["interface"] 2192292SN/A 2202292SN/A code(''' 2212292SN/A$klass ${{self.c_ident}}$parent { 2222292SN/A public: 2232292SN/A ${{self.c_ident}}() 2242727Sktlim@umich.edu''', klass="class") 2252727Sktlim@umich.edu 2262727Sktlim@umich.edu # Call superclass constructor 2272727Sktlim@umich.edu if "interface" in self: 2282727Sktlim@umich.edu code(' : ${{self["interface"]}}()') 2292727Sktlim@umich.edu 2302727Sktlim@umich.edu code.indent() 2312727Sktlim@umich.edu code("{") 2322727Sktlim@umich.edu if not self.isGlobal: 2332727Sktlim@umich.edu code.indent() 2342727Sktlim@umich.edu for dm in self.data_members.values(): 2352727Sktlim@umich.edu ident = dm.ident 2362727Sktlim@umich.edu if "default" in dm: 2372727Sktlim@umich.edu # look for default value 2382727Sktlim@umich.edu code('m_$ident = ${{dm["default"]}}; // default for this field') 2392727Sktlim@umich.edu elif "default" in dm.type: 2402727Sktlim@umich.edu # Look for the type default 2412727Sktlim@umich.edu tid = dm.type.c_ident 2422361SN/A code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') 2432361SN/A else: 2442361SN/A code('// m_$ident has no default') 2452361SN/A code.dedent() 2462727Sktlim@umich.edu code('}') 2472727Sktlim@umich.edu 2482727Sktlim@umich.edu # ******** Default destructor ******** 2492727Sktlim@umich.edu code('~${{self.c_ident}}() { };') 2502727Sktlim@umich.edu 2512727Sktlim@umich.edu # ******** Full init constructor ******** 2522727Sktlim@umich.edu if not self.isGlobal: 2532727Sktlim@umich.edu params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ 2542727Sktlim@umich.edu for dm in self.data_members.itervalues() ] 2552727Sktlim@umich.edu 2562727Sktlim@umich.edu if self.isMessage: 2572727Sktlim@umich.edu params.append('const unsigned local_proc_id') 2582727Sktlim@umich.edu 2592727Sktlim@umich.edu params = ', '.join(params) 2602727Sktlim@umich.edu code('${{self.c_ident}}($params)') 2612727Sktlim@umich.edu 2622727Sktlim@umich.edu # Call superclass constructor 2632727Sktlim@umich.edu if "interface" in self: 2642727Sktlim@umich.edu code(' : ${{self["interface"]}}()') 2652727Sktlim@umich.edu 2662727Sktlim@umich.edu code('{') 2672727Sktlim@umich.edu code.indent() 2682727Sktlim@umich.edu for dm in self.data_members.values(): 2698922Swilliam.wang@arm.com code('m_${{dm.ident}} = local_${{dm.ident}};') 2704329Sktlim@umich.edu if "nextLineCallHack" in dm: 2714329Sktlim@umich.edu code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};') 2724329Sktlim@umich.edu 2734329Sktlim@umich.edu if self.isMessage: 2744329Sktlim@umich.edu code('proc_id = local_proc_id;') 2754329Sktlim@umich.edu 2762292SN/A code.dedent() 2772292SN/A code('}') 2782292SN/A 2792292SN/A # create a static factory method 2802292SN/A if "interface" in self: 2812292SN/A code(''' 2822292SN/Astatic ${{self["interface"]}}* create() { 2832292SN/A return new ${{self.c_ident}}(); 2842292SN/A} 2852292SN/A''') 2862292SN/A 2872292SN/A # ******** Message member functions ******** 2882292SN/A # FIXME: those should be moved into slicc file, slicc should 2892292SN/A # support more of the c++ class inheritance 2909444SAndreas.Sandberg@ARM.com 2912307SN/A if self.isMessage: 2929444SAndreas.Sandberg@ARM.com code(''' 2932367SN/AMessage* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); } 2942307SN/Avoid destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); } 2952329SN/Astatic Allocator<${{self.c_ident}}>* s_allocator_ptr; 2969444SAndreas.Sandberg@ARM.comstatic void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }} 2972307SN/A''') 2982307SN/A 2992307SN/A if not self.isGlobal: 3002307SN/A # const Get methods for each field 3012307SN/A code('// Const accessors methods for each field') 3022307SN/A for dm in self.data_members.values(): 3039444SAndreas.Sandberg@ARM.com code(''' 3042307SN/A/** \\brief Const accessor method for ${{dm.ident}} field. 3052307SN/A * \\return ${{dm.ident}} field 3062307SN/A */ 3072307SN/Aconst ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; } 3082292SN/A''') 3092292SN/A 3102329SN/A # Non-const Get methods for each field 3112329SN/A code('// Non const Accessors methods for each field') 3122292SN/A for dm in self.data_members.values(): 3132329SN/A code(''' 3142329SN/A/** \\brief Non-const accessor method for ${{dm.ident}} field. 3152292SN/A * \\return ${{dm.ident}} field 3162292SN/A */ 3172292SN/A${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; } 3182292SN/A''') 3192292SN/A 3202329SN/A #Set methods for each field 3212292SN/A code('// Mutator methods for each field') 3222292SN/A for dm in self.data_members.values(): 3239936SFaissal.Sleiman@arm.com code(''' 3242292SN/A/** \\brief Mutator method for ${{dm.ident}} field */ 3252292SN/Avoid set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; } 3262292SN/A''') 3272292SN/A 3282292SN/A code('void print(std::ostream& out) const;') 3292292SN/A code.dedent() 3302329SN/A code(' //private:') 3312329SN/A code.indent() 3322329SN/A 3332292SN/A # Data members for each field 3342292SN/A for dm in self.data_members.values(): 3352292SN/A if "abstract" not in dm: 3362292SN/A const = "" 3372292SN/A init = "" 3382329SN/A 3392292SN/A # global structure 3409936SFaissal.Sleiman@arm.com if self.isGlobal: 3419936SFaissal.Sleiman@arm.com const = "static const " 3422292SN/A 3432292SN/A # init value 3442292SN/A if dm.init_code: 3452292SN/A # only global structure can have init value here 3462292SN/A assert self.isGlobal 3472292SN/A init = " = %s" % (dm.init_code) 3482292SN/A 3492292SN/A desc = "" 3502292SN/A if "desc" in dm: 3512292SN/A desc = '/**< %s */' % dm["desc"] 3522292SN/A 3532292SN/A code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc') 3542292SN/A 3552292SN/A if self.isMessage: 3562292SN/A code('unsigned proc_id;') 3572292SN/A 3582292SN/A code.dedent() 3592292SN/A code('};') 3602292SN/A 3612292SN/A code(''' 3622292SN/A// Output operator declaration 3632292SN/Astd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 3642292SN/A 3652329SN/A// Output operator definition 3662329SN/Aextern inline 3672292SN/Astd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj) 3687720Sgblack@eecs.umich.edu{ 3697720Sgblack@eecs.umich.edu obj.print(out); 3702292SN/A out << std::flush; 3712292SN/A return out; 3722292SN/A} 3732292SN/A 3742292SN/A#endif // ${{self.c_ident}}_H 3752292SN/A''') 3762292SN/A 3772292SN/A code.write(path, "%s.hh" % self.c_ident) 3782292SN/A 3792292SN/A def printTypeCC(self, path): 3802292SN/A code = self.symtab.codeFormatter() 3812292SN/A 3822292SN/A code(''' 3832292SN/A/** \\file ${{self.c_ident}}.cc 3842292SN/A * 3852292SN/A * Auto generated C++ code started by $__file__:$__line__ 3862292SN/A */ 3872292SN/A 3882292SN/A#include <iostream> 3892292SN/A 3902292SN/A#include "mem/protocol/${{self.c_ident}}.hh" 3912292SN/A 3922292SN/Ausing namespace std; 3932292SN/A''') 3947720Sgblack@eecs.umich.edu 3957720Sgblack@eecs.umich.edu if self.isMessage: 3962292SN/A code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;') 3972292SN/A code(''' 3982292SN/A/** \\brief Print the state of this object */ 3992292SN/Avoid ${{self.c_ident}}::print(ostream& out) const 4002292SN/A{ 4012292SN/A out << "[${{self.c_ident}}: "; 4022292SN/A''') 4032292SN/A 4042292SN/A # For each field 4052292SN/A code.indent() 4062292SN/A for dm in self.data_members.values(): 4072292SN/A code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') 4082292SN/A 4092292SN/A if self.isMessage: 4102292SN/A code('out << "Time = " << getTime() << " ";') 4112292SN/A code.dedent() 4122292SN/A 4132292SN/A # Trailer 4142292SN/A code(''' 4152292SN/A out << "]"; 4162292SN/A}''') 4172292SN/A 4182292SN/A code.write(path, "%s.cc" % self.c_ident) 4192292SN/A 42010239Sbinhpham@cs.rutgers.edu def printEnumHH(self, path): 4212292SN/A code = self.symtab.codeFormatter() 42210239Sbinhpham@cs.rutgers.edu code(''' 42310239Sbinhpham@cs.rutgers.edu/** \\file ${{self.c_ident}}.hh 42410239Sbinhpham@cs.rutgers.edu * 42510239Sbinhpham@cs.rutgers.edu * Auto generated C++ code started by $__file__:$__line__ 42610239Sbinhpham@cs.rutgers.edu */ 4272292SN/A#ifndef ${{self.c_ident}}_H 42810239Sbinhpham@cs.rutgers.edu#define ${{self.c_ident}}_H 42910239Sbinhpham@cs.rutgers.edu 43010239Sbinhpham@cs.rutgers.edu#include <iostream> 43110239Sbinhpham@cs.rutgers.edu#include <string> 43210239Sbinhpham@cs.rutgers.edu 43310239Sbinhpham@cs.rutgers.edu#include "mem/ruby/common/Global.hh" 43410239Sbinhpham@cs.rutgers.edu 43510239Sbinhpham@cs.rutgers.edu/** \\enum ${{self.c_ident}} 43610239Sbinhpham@cs.rutgers.edu * \\brief ${{self.desc}} 43710239Sbinhpham@cs.rutgers.edu */ 4382292SN/Aenum ${{self.c_ident}} { 4392292SN/A ${{self.c_ident}}_FIRST, 4408545Ssaidi@eecs.umich.edu''') 4418545Ssaidi@eecs.umich.edu 4428545Ssaidi@eecs.umich.edu code.indent() 4438545Ssaidi@eecs.umich.edu # For each field 44410030SAli.Saidi@ARM.com for i,(ident,enum) in enumerate(self.enums.iteritems()): 4458545Ssaidi@eecs.umich.edu desc = enum.get("desc", "No description avaliable") 4469383SAli.Saidi@ARM.com if i == 0: 4479383SAli.Saidi@ARM.com init = ' = %s_FIRST' % self.c_ident 4489383SAli.Saidi@ARM.com else: 4499383SAli.Saidi@ARM.com init = '' 45010030SAli.Saidi@ARM.com code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4519383SAli.Saidi@ARM.com code.dedent() 4529383SAli.Saidi@ARM.com code(''' 4539383SAli.Saidi@ARM.com ${{self.c_ident}}_NUM 4549383SAli.Saidi@ARM.com}; 4559383SAli.Saidi@ARM.com${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 4569383SAli.Saidi@ARM.comstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 4579383SAli.Saidi@ARM.com${{self.c_ident}} &operator++(${{self.c_ident}} &e); 45810030SAli.Saidi@ARM.com''') 45910030SAli.Saidi@ARM.com 46010030SAli.Saidi@ARM.com # MachineType hack used to set the base component id for each Machine 46110030SAli.Saidi@ARM.com if self.isMachineType: 46210030SAli.Saidi@ARM.com code(''' 46310030SAli.Saidi@ARM.comint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 46410030SAli.Saidi@ARM.comMachineType ${{self.c_ident}}_from_base_level(int); 46510030SAli.Saidi@ARM.comint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 46610030SAli.Saidi@ARM.comint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 46710030SAli.Saidi@ARM.com''') 46810030SAli.Saidi@ARM.com 4698545Ssaidi@eecs.umich.edu for enum in self.enums.itervalues(): 4708545Ssaidi@eecs.umich.edu code('#define MACHINETYPE_${{enum.ident}} 1') 4718545Ssaidi@eecs.umich.edu 47210030SAli.Saidi@ARM.com # Trailer 4738545Ssaidi@eecs.umich.edu code(''' 4748545Ssaidi@eecs.umich.edustd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 47510149Smarco.elver@ed.ac.uk 47610149Smarco.elver@ed.ac.uk#endif // ${{self.c_ident}}_H 4778545Ssaidi@eecs.umich.edu''') 4788545Ssaidi@eecs.umich.edu 4798545Ssaidi@eecs.umich.edu code.write(path, "%s.hh" % self.c_ident) 4809046SAli.Saidi@ARM.com 4818545Ssaidi@eecs.umich.edu def printEnumCC(self, path): 4828545Ssaidi@eecs.umich.edu code = self.symtab.codeFormatter() 4838545Ssaidi@eecs.umich.edu code(''' 4848545Ssaidi@eecs.umich.edu/** \\file ${{self.c_ident}}.hh 4858545Ssaidi@eecs.umich.edu * 4868545Ssaidi@eecs.umich.edu * Auto generated C++ code started by $__file__:$__line__ 4878545Ssaidi@eecs.umich.edu */ 4888545Ssaidi@eecs.umich.edu 48910149Smarco.elver@ed.ac.uk#include <iostream> 49010149Smarco.elver@ed.ac.uk#include <string> 49110149Smarco.elver@ed.ac.uk 49210149Smarco.elver@ed.ac.uk#include "mem/protocol/${{self.c_ident}}.hh" 49310149Smarco.elver@ed.ac.uk 49410149Smarco.elver@ed.ac.ukusing namespace std; 49510149Smarco.elver@ed.ac.uk 49610149Smarco.elver@ed.ac.uk''') 4978545Ssaidi@eecs.umich.edu 49810030SAli.Saidi@ARM.com if self.isMachineType: 4998545Ssaidi@eecs.umich.edu for enum in self.enums.itervalues(): 5008545Ssaidi@eecs.umich.edu code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') 5018545Ssaidi@eecs.umich.edu 5028545Ssaidi@eecs.umich.edu code(''' 50310030SAli.Saidi@ARM.comostream& operator<<(ostream& out, const ${{self.c_ident}}& obj) 50410030SAli.Saidi@ARM.com{ 50510030SAli.Saidi@ARM.com out << ${{self.c_ident}}_to_string(obj); 50610030SAli.Saidi@ARM.com out << flush; 50710030SAli.Saidi@ARM.com return out; 50810030SAli.Saidi@ARM.com} 50910030SAli.Saidi@ARM.com 51010030SAli.Saidi@ARM.comstring ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 51110030SAli.Saidi@ARM.com{ 5128545Ssaidi@eecs.umich.edu switch(obj) { 5138545Ssaidi@eecs.umich.edu''') 5148545Ssaidi@eecs.umich.edu 5159046SAli.Saidi@ARM.com # For each field 5168545Ssaidi@eecs.umich.edu code.indent() 5178545Ssaidi@eecs.umich.edu for enum in self.enums.itervalues(): 5188545Ssaidi@eecs.umich.edu code(' case ${{self.c_ident}}_${{enum.ident}}:') 5198545Ssaidi@eecs.umich.edu code(' return "${{enum.ident}}";') 5208545Ssaidi@eecs.umich.edu code.dedent() 5218545Ssaidi@eecs.umich.edu 5228545Ssaidi@eecs.umich.edu # Trailer 5238545Ssaidi@eecs.umich.edu code(''' 5242292SN/A default: 5258199SAli.Saidi@ARM.com ERROR_MSG("Invalid range for type ${{self.c_ident}}"); 5268199SAli.Saidi@ARM.com return ""; 5278199SAli.Saidi@ARM.com } 5288199SAli.Saidi@ARM.com} 5298199SAli.Saidi@ARM.com 5308199SAli.Saidi@ARM.com${{self.c_ident}} string_to_${{self.c_ident}}(const string& str) 5318199SAli.Saidi@ARM.com{ 5328199SAli.Saidi@ARM.com''') 5338199SAli.Saidi@ARM.com 5348199SAli.Saidi@ARM.com # For each field 5358199SAli.Saidi@ARM.com code.indent() 5368199SAli.Saidi@ARM.com code("if (false) {") 5379046SAli.Saidi@ARM.com start = "} else " 5388199SAli.Saidi@ARM.com for enum in self.enums.itervalues(): 5398199SAli.Saidi@ARM.com code('${start}if (str == "${{enum.ident}}") {') 5408199SAli.Saidi@ARM.com code(' return ${{self.c_ident}}_${{enum.ident}};') 5418199SAli.Saidi@ARM.com code.dedent() 5428199SAli.Saidi@ARM.com 5438199SAli.Saidi@ARM.com code(''' 5448199SAli.Saidi@ARM.com } else { 5458199SAli.Saidi@ARM.com WARN_EXPR(str); 5468272SAli.Saidi@ARM.com ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}"); 5478545Ssaidi@eecs.umich.edu } 5488545Ssaidi@eecs.umich.edu} 5498545Ssaidi@eecs.umich.edu 5508545Ssaidi@eecs.umich.edu${{self.c_ident}}& operator++(${{self.c_ident}}& e) { 5519046SAli.Saidi@ARM.com assert(e < ${{self.c_ident}}_NUM); 5528545Ssaidi@eecs.umich.edu return e = ${{self.c_ident}}(e+1); 5538545Ssaidi@eecs.umich.edu} 5548545Ssaidi@eecs.umich.edu''') 5558592Sgblack@eecs.umich.edu 5568592Sgblack@eecs.umich.edu # MachineType hack used to set the base level and number of 5578545Ssaidi@eecs.umich.edu # components for each Machine 5588199SAli.Saidi@ARM.com if self.isMachineType: 5598545Ssaidi@eecs.umich.edu code(''' 5608199SAli.Saidi@ARM.com/** \\brief returns the base vector index for each machine type to be used by NetDest 5618591Sgblack@eecs.umich.edu * 5628591Sgblack@eecs.umich.edu * \\return the base vector index for each machine type to be used by NetDest 5638591Sgblack@eecs.umich.edu * \\see NetDest.hh 5648591Sgblack@eecs.umich.edu */ 5658545Ssaidi@eecs.umich.eduint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 5668545Ssaidi@eecs.umich.edu{ 5678199SAli.Saidi@ARM.com switch(obj) { 5688545Ssaidi@eecs.umich.edu''') 5698545Ssaidi@eecs.umich.edu 5709046SAli.Saidi@ARM.com # For each field 5718545Ssaidi@eecs.umich.edu code.indent() 5728545Ssaidi@eecs.umich.edu for i,enum in enumerate(self.enums.itervalues()): 5738545Ssaidi@eecs.umich.edu code(' case ${{self.c_ident}}_${{enum.ident}}:') 5748545Ssaidi@eecs.umich.edu code(' return $i;') 5758545Ssaidi@eecs.umich.edu code.dedent() 5768545Ssaidi@eecs.umich.edu 5778545Ssaidi@eecs.umich.edu # total num 5788545Ssaidi@eecs.umich.edu code(''' 5798545Ssaidi@eecs.umich.edu case ${{self.c_ident}}_NUM: 5808545Ssaidi@eecs.umich.edu return ${{len(self.enums)}}; 5818592Sgblack@eecs.umich.edu 5828592Sgblack@eecs.umich.edu default: 5838592Sgblack@eecs.umich.edu ERROR_MSG("Invalid range for type ${{self.c_ident}}"); 5848545Ssaidi@eecs.umich.edu return -1; 5858545Ssaidi@eecs.umich.edu } 5868545Ssaidi@eecs.umich.edu} 5878545Ssaidi@eecs.umich.edu 5888591Sgblack@eecs.umich.edu/** \\brief returns the machine type for each base vector index used by NetDest 5898591Sgblack@eecs.umich.edu * 5908591Sgblack@eecs.umich.edu * \\return the MachineTYpe 5918545Ssaidi@eecs.umich.edu */ 5928199SAli.Saidi@ARM.comMachineType ${{self.c_ident}}_from_base_level(int type) 5938199SAli.Saidi@ARM.com{ 5948199SAli.Saidi@ARM.com switch(type) { 5958199SAli.Saidi@ARM.com''') 5968199SAli.Saidi@ARM.com 5978199SAli.Saidi@ARM.com # For each field 5988199SAli.Saidi@ARM.com code.indent() 5998199SAli.Saidi@ARM.com for i,enum in enumerate(self.enums.itervalues()): 6008199SAli.Saidi@ARM.com code(' case $i:') 6018199SAli.Saidi@ARM.com code(' return ${{self.c_ident}}_${{enum.ident}};') 6028199SAli.Saidi@ARM.com code.dedent() 6038199SAli.Saidi@ARM.com 6042292SN/A # Trailer 6052292SN/A code(''' 6064032Sktlim@umich.edu default: 6072292SN/A ERROR_MSG("Invalid range for type ${{self.c_ident}}"); 6082292SN/A return MachineType_NUM; 6092292SN/A } 6107720Sgblack@eecs.umich.edu} 6117944SGiacomo.Gabrielli@arm.com 6122292SN/A/** \\brief The return value indicates the number of components created 6134032Sktlim@umich.edu * before a particular machine\'s components 6144032Sktlim@umich.edu * 6152669Sktlim@umich.edu * \\return the base number of components for each machine 6162292SN/A */ 6177944SGiacomo.Gabrielli@arm.comint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 6187944SGiacomo.Gabrielli@arm.com{ 6197944SGiacomo.Gabrielli@arm.com int base = 0; 6207944SGiacomo.Gabrielli@arm.com switch(obj) { 6217597Sminkyu.jeong@arm.com''') 6227597Sminkyu.jeong@arm.com 62310231Ssteve.reinhardt@amd.com # For each field 6242329SN/A code.indent() 6252329SN/A code(' case ${{self.c_ident}}_NUM:') 6262367SN/A for enum in reversed(self.enums.values()): 6272367SN/A code(' base += ${{enum.ident}}_Controller::getNumControllers();') 62810231Ssteve.reinhardt@amd.com code(' case ${{self.c_ident}}_${{enum.ident}}:') 6297848SAli.Saidi@ARM.com code(' break;') 6307600Sminkyu.jeong@arm.com code.dedent() 6317600Sminkyu.jeong@arm.com 6327600Sminkyu.jeong@arm.com code(''' 6334032Sktlim@umich.edu default: 6343731Sktlim@umich.edu ERROR_MSG("Invalid range for type ${{self.c_ident}}"); 6352367SN/A return -1; 6362367SN/A } 6372292SN/A 6382292SN/A return base; 63910333Smitch.hayenga@arm.com} 6409046SAli.Saidi@ARM.com 6414032Sktlim@umich.edu/** \\brief returns the total number of components for each machine 6424032Sktlim@umich.edu * \\return the total number of components for each machine 6434032Sktlim@umich.edu */ 6448199SAli.Saidi@ARM.comint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 6458199SAli.Saidi@ARM.com{ 6462292SN/A switch(obj) { 6472292SN/A''') 6482292SN/A 6492292SN/A # For each field 6502292SN/A for enum in self.enums.itervalues(): 6512292SN/A code(''' 6522292SN/A case ${{self.c_ident}}_${{enum.ident}}: 6532292SN/A return ${{enum.ident}}_Controller::getNumControllers(); 6542292SN/A''') 6552292SN/A 6562292SN/A # total num 6572292SN/A code(''' 6582292SN/A case ${{self.c_ident}}_NUM: 6592292SN/A default: 6602292SN/A ERROR_MSG("Invalid range for type ${{self.c_ident}}"); 6617720Sgblack@eecs.umich.edu return -1; 6627720Sgblack@eecs.umich.edu } 6632292SN/A} 6644032Sktlim@umich.edu''') 6654032Sktlim@umich.edu 6662292SN/A # Write the file 6672292SN/A code.write(path, "%s.cc" % self.c_ident) 6682292SN/A 6692292SN/A__all__ = [ "Type" ] 6702292SN/A