Type.py revision 11118
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 36657Snate@binkert.org# All rights reserved. 46657Snate@binkert.org# 56657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org# modification, are permitted provided that the following conditions are 76657Snate@binkert.org# met: redistributions of source code must retain the above copyright 86657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org# documentation and/or other materials provided with the distribution; 126657Snate@binkert.org# neither the name of the copyright holders nor the names of its 136657Snate@binkert.org# contributors may be used to endorse or promote products derived from 146657Snate@binkert.org# this software without specific prior written permission. 156657Snate@binkert.org# 166657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org 286999Snate@binkert.orgfrom m5.util import orderdict 296657Snate@binkert.org 306657Snate@binkert.orgfrom slicc.util import PairContainer 316657Snate@binkert.orgfrom slicc.symbols.Symbol import Symbol 329302Snilay@cs.wisc.edufrom slicc.symbols.Var import Var 336657Snate@binkert.org 3411117Snilay@cs.wisc.educlass DataMember(Var): 3511117Snilay@cs.wisc.edu def __init__(self, symtab, ident, location, type, code, pairs, 3611117Snilay@cs.wisc.edu machine, init_code): 3711117Snilay@cs.wisc.edu super(DataMember, self).__init__(symtab, ident, location, type, 3811117Snilay@cs.wisc.edu code, pairs, machine) 396657Snate@binkert.org self.init_code = init_code 406657Snate@binkert.org 416657Snate@binkert.orgclass Enumeration(PairContainer): 426657Snate@binkert.org def __init__(self, ident, pairs): 436657Snate@binkert.org super(Enumeration, self).__init__(pairs) 446657Snate@binkert.org self.ident = ident 456657Snate@binkert.org 466657Snate@binkert.orgclass Type(Symbol): 476657Snate@binkert.org def __init__(self, table, ident, location, pairs, machine=None): 486657Snate@binkert.org super(Type, self).__init__(table, ident, location, pairs) 496657Snate@binkert.org self.c_ident = ident 506882SBrad.Beckmann@amd.com self.abstract_ident = "" 516657Snate@binkert.org if machine: 526657Snate@binkert.org if self.isExternal or self.isPrimitive: 536657Snate@binkert.org if "external_name" in self: 546657Snate@binkert.org self.c_ident = self["external_name"] 556657Snate@binkert.org else: 566657Snate@binkert.org # Append with machine name 576657Snate@binkert.org self.c_ident = "%s_%s" % (machine, ident) 586657Snate@binkert.org 596657Snate@binkert.org self.pairs.setdefault("desc", "No description avaliable") 606657Snate@binkert.org 616657Snate@binkert.org # check for interface that this Type implements 626657Snate@binkert.org if "interface" in self: 636657Snate@binkert.org interface = self["interface"] 6410895Snilay@cs.wisc.edu if interface in ("Message"): 656657Snate@binkert.org self["message"] = "yes" 666657Snate@binkert.org 676657Snate@binkert.org # FIXME - all of the following id comparisons are fragile hacks 6810228Snilay@cs.wisc.edu if self.ident in ("CacheMemory"): 696657Snate@binkert.org self["cache"] = "yes" 706657Snate@binkert.org 7110228Snilay@cs.wisc.edu if self.ident in ("TBETable"): 726657Snate@binkert.org self["tbe"] = "yes" 736657Snate@binkert.org 746657Snate@binkert.org if self.ident == "TimerTable": 756657Snate@binkert.org self["timer"] = "yes" 766657Snate@binkert.org 776657Snate@binkert.org if self.ident == "DirectoryMemory": 786657Snate@binkert.org self["dir"] = "yes" 796657Snate@binkert.org 806657Snate@binkert.org if self.ident == "PersistentTable": 816657Snate@binkert.org self["persistent"] = "yes" 826657Snate@binkert.org 836657Snate@binkert.org if self.ident == "Prefetcher": 846657Snate@binkert.org self["prefetcher"] = "yes" 856657Snate@binkert.org 866657Snate@binkert.org self.isMachineType = (ident == "MachineType") 876657Snate@binkert.org 888086SBrad.Beckmann@amd.com self.isStateDecl = ("state_decl" in self) 898086SBrad.Beckmann@amd.com self.statePermPairs = [] 908086SBrad.Beckmann@amd.com 916657Snate@binkert.org self.data_members = orderdict() 926657Snate@binkert.org self.methods = {} 936657Snate@binkert.org self.enums = orderdict() 946657Snate@binkert.org 956657Snate@binkert.org @property 966657Snate@binkert.org def isPrimitive(self): 976657Snate@binkert.org return "primitive" in self 9810895Snilay@cs.wisc.edu 996657Snate@binkert.org @property 1006657Snate@binkert.org def isMessage(self): 1016657Snate@binkert.org return "message" in self 1026657Snate@binkert.org @property 1036657Snate@binkert.org def isBuffer(self): 1046657Snate@binkert.org return "buffer" in self 1056657Snate@binkert.org @property 1066657Snate@binkert.org def isInPort(self): 1076657Snate@binkert.org return "inport" in self 1086657Snate@binkert.org @property 1096657Snate@binkert.org def isOutPort(self): 1106657Snate@binkert.org return "outport" in self 1116657Snate@binkert.org @property 1126657Snate@binkert.org def isEnumeration(self): 1136657Snate@binkert.org return "enumeration" in self 1146657Snate@binkert.org @property 1156657Snate@binkert.org def isExternal(self): 1166657Snate@binkert.org return "external" in self 1176657Snate@binkert.org @property 1186657Snate@binkert.org def isGlobal(self): 1196657Snate@binkert.org return "global" in self 1206657Snate@binkert.org @property 1216657Snate@binkert.org def isInterface(self): 1226657Snate@binkert.org return "interface" in self 1236657Snate@binkert.org 1246657Snate@binkert.org # Return false on error 1259298Snilay@cs.wisc.edu def addDataMember(self, ident, type, pairs, init_code): 1266657Snate@binkert.org if ident in self.data_members: 1276657Snate@binkert.org return False 1286657Snate@binkert.org 12911117Snilay@cs.wisc.edu member = DataMember(self.symtab, ident, self.location, type, 13011117Snilay@cs.wisc.edu "m_%s" % ident, pairs, None, init_code) 13111117Snilay@cs.wisc.edu 1326657Snate@binkert.org self.data_members[ident] = member 13311117Snilay@cs.wisc.edu self.symtab.registerSym(ident, member) 1346657Snate@binkert.org return True 1356657Snate@binkert.org 1366657Snate@binkert.org def dataMemberType(self, ident): 1376657Snate@binkert.org return self.data_members[ident].type 1386657Snate@binkert.org 1396657Snate@binkert.org def methodId(self, name, param_type_vec): 1406657Snate@binkert.org return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) 1416657Snate@binkert.org 1426882SBrad.Beckmann@amd.com def methodIdAbstract(self, name, param_type_vec): 1436882SBrad.Beckmann@amd.com return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ]) 1446882SBrad.Beckmann@amd.com 1458086SBrad.Beckmann@amd.com def statePermPairAdd(self, state_name, perm_name): 1468086SBrad.Beckmann@amd.com self.statePermPairs.append([state_name, perm_name]) 1478086SBrad.Beckmann@amd.com 14810307Snilay@cs.wisc.edu def addFunc(self, func): 14910307Snilay@cs.wisc.edu ident = self.methodId(func.ident, func.param_types) 1506657Snate@binkert.org if ident in self.methods: 1516657Snate@binkert.org return False 1526657Snate@binkert.org 15310307Snilay@cs.wisc.edu self.methods[ident] = func 1549298Snilay@cs.wisc.edu return True 1559298Snilay@cs.wisc.edu 1569298Snilay@cs.wisc.edu def addEnum(self, ident, pairs): 1576657Snate@binkert.org if ident in self.enums: 1586657Snate@binkert.org return False 1596657Snate@binkert.org 1606657Snate@binkert.org self.enums[ident] = Enumeration(ident, pairs) 1616657Snate@binkert.org 1626657Snate@binkert.org # Add default 1636657Snate@binkert.org if "default" not in self: 1646657Snate@binkert.org self["default"] = "%s_NUM" % self.c_ident 1656657Snate@binkert.org 1666657Snate@binkert.org return True 1676657Snate@binkert.org 1689219Spower.jg@gmail.com def writeCodeFiles(self, path, includes): 1696657Snate@binkert.org if self.isExternal: 1706657Snate@binkert.org # Do nothing 1716657Snate@binkert.org pass 1726657Snate@binkert.org elif self.isEnumeration: 1736657Snate@binkert.org self.printEnumHH(path) 1746657Snate@binkert.org self.printEnumCC(path) 1756657Snate@binkert.org else: 1766657Snate@binkert.org # User defined structs and messages 1776657Snate@binkert.org self.printTypeHH(path) 1786657Snate@binkert.org self.printTypeCC(path) 1796657Snate@binkert.org 1806657Snate@binkert.org def printTypeHH(self, path): 1816999Snate@binkert.org code = self.symtab.codeFormatter() 1826657Snate@binkert.org code(''' 1836657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 1846657Snate@binkert.org * 1856657Snate@binkert.org * 1866657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 1876657Snate@binkert.org */ 1886657Snate@binkert.org 1897007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 1907007Snate@binkert.org#define __${{self.c_ident}}_HH__ 1916657Snate@binkert.org 1927002Snate@binkert.org#include <iostream> 1937002Snate@binkert.org 1949466Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 1956657Snate@binkert.org''') 1966657Snate@binkert.org 1976657Snate@binkert.org for dm in self.data_members.values(): 1986657Snate@binkert.org if not dm.type.isPrimitive: 1996657Snate@binkert.org code('#include "mem/protocol/$0.hh"', dm.type.c_ident) 2006657Snate@binkert.org 2016657Snate@binkert.org parent = "" 2026657Snate@binkert.org if "interface" in self: 2036657Snate@binkert.org code('#include "mem/protocol/$0.hh"', self["interface"]) 2046657Snate@binkert.org parent = " : public %s" % self["interface"] 2056657Snate@binkert.org 2066657Snate@binkert.org code(''' 2077007Snate@binkert.org$klass ${{self.c_ident}}$parent 2087007Snate@binkert.org{ 2096657Snate@binkert.org public: 2109466Snilay@cs.wisc.edu ${{self.c_ident}} 2116657Snate@binkert.org''', klass="class") 2126657Snate@binkert.org 2139466Snilay@cs.wisc.edu if self.isMessage: 2149508Snilay@cs.wisc.edu code('(Tick curTime) : %s(curTime) {' % self["interface"]) 2159466Snilay@cs.wisc.edu else: 2169466Snilay@cs.wisc.edu code('()\n\t\t{') 2179466Snilay@cs.wisc.edu 2186657Snate@binkert.org code.indent() 2196657Snate@binkert.org if not self.isGlobal: 2206657Snate@binkert.org code.indent() 2216657Snate@binkert.org for dm in self.data_members.values(): 2226657Snate@binkert.org ident = dm.ident 2236657Snate@binkert.org if "default" in dm: 2246657Snate@binkert.org # look for default value 2256657Snate@binkert.org code('m_$ident = ${{dm["default"]}}; // default for this field') 2266657Snate@binkert.org elif "default" in dm.type: 2276657Snate@binkert.org # Look for the type default 2286657Snate@binkert.org tid = dm.type.c_ident 2296657Snate@binkert.org code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') 2306657Snate@binkert.org else: 2316657Snate@binkert.org code('// m_$ident has no default') 2326657Snate@binkert.org code.dedent() 2336657Snate@binkert.org code('}') 2346657Snate@binkert.org 2357453Snate@binkert.org # ******** Copy constructor ******** 2367453Snate@binkert.org if not self.isGlobal: 2377453Snate@binkert.org code('${{self.c_ident}}(const ${{self.c_ident}}&other)') 2387453Snate@binkert.org 2397453Snate@binkert.org # Call superclass constructor 2407453Snate@binkert.org if "interface" in self: 2417453Snate@binkert.org code(' : ${{self["interface"]}}(other)') 2427453Snate@binkert.org 2437453Snate@binkert.org code('{') 2447453Snate@binkert.org code.indent() 2457453Snate@binkert.org 2467453Snate@binkert.org for dm in self.data_members.values(): 2477453Snate@binkert.org code('m_${{dm.ident}} = other.m_${{dm.ident}};') 2487453Snate@binkert.org 2497453Snate@binkert.org code.dedent() 2507453Snate@binkert.org code('}') 2517453Snate@binkert.org 2526657Snate@binkert.org # ******** Full init constructor ******** 2536657Snate@binkert.org if not self.isGlobal: 2546657Snate@binkert.org params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ 2556657Snate@binkert.org for dm in self.data_members.itervalues() ] 2569466Snilay@cs.wisc.edu params = ', '.join(params) 2576657Snate@binkert.org 2589466Snilay@cs.wisc.edu if self.isMessage: 2599508Snilay@cs.wisc.edu params = "const Tick curTime, " + params 2609466Snilay@cs.wisc.edu 2616657Snate@binkert.org code('${{self.c_ident}}($params)') 2626657Snate@binkert.org 2636657Snate@binkert.org # Call superclass constructor 2646657Snate@binkert.org if "interface" in self: 2659466Snilay@cs.wisc.edu if self.isMessage: 2669466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}(curTime)') 2679466Snilay@cs.wisc.edu else: 2689466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}()') 2696657Snate@binkert.org 2706657Snate@binkert.org code('{') 2716657Snate@binkert.org code.indent() 2726657Snate@binkert.org for dm in self.data_members.values(): 2736657Snate@binkert.org code('m_${{dm.ident}} = local_${{dm.ident}};') 2746657Snate@binkert.org 2756657Snate@binkert.org code.dedent() 2766657Snate@binkert.org code('}') 2776657Snate@binkert.org 2789466Snilay@cs.wisc.edu # create a clone member 27910472Sandreas.hansson@arm.com if self.isMessage: 28010472Sandreas.hansson@arm.com code(''' 28110472Sandreas.hansson@arm.comMsgPtr 28210472Sandreas.hansson@arm.comclone() const 28310472Sandreas.hansson@arm.com{ 28410472Sandreas.hansson@arm.com return std::shared_ptr<Message>(new ${{self.c_ident}}(*this)); 28510472Sandreas.hansson@arm.com} 28610472Sandreas.hansson@arm.com''') 28710472Sandreas.hansson@arm.com else: 28810472Sandreas.hansson@arm.com code(''' 2897453Snate@binkert.org${{self.c_ident}}* 2907007Snate@binkert.orgclone() const 2917007Snate@binkert.org{ 2927453Snate@binkert.org return new ${{self.c_ident}}(*this); 2937007Snate@binkert.org} 2946657Snate@binkert.org''') 2956657Snate@binkert.org 2966657Snate@binkert.org if not self.isGlobal: 2976657Snate@binkert.org # const Get methods for each field 2986657Snate@binkert.org code('// Const accessors methods for each field') 2996657Snate@binkert.org for dm in self.data_members.values(): 3006657Snate@binkert.org code(''' 3016657Snate@binkert.org/** \\brief Const accessor method for ${{dm.ident}} field. 3026657Snate@binkert.org * \\return ${{dm.ident}} field 3036657Snate@binkert.org */ 3047007Snate@binkert.orgconst ${{dm.type.c_ident}}& 3057007Snate@binkert.orgget${{dm.ident}}() const 3067007Snate@binkert.org{ 3077007Snate@binkert.org return m_${{dm.ident}}; 3087007Snate@binkert.org} 3096657Snate@binkert.org''') 3106657Snate@binkert.org 3116657Snate@binkert.org # Non-const Get methods for each field 3126657Snate@binkert.org code('// Non const Accessors methods for each field') 3136657Snate@binkert.org for dm in self.data_members.values(): 3146657Snate@binkert.org code(''' 3156657Snate@binkert.org/** \\brief Non-const accessor method for ${{dm.ident}} field. 3166657Snate@binkert.org * \\return ${{dm.ident}} field 3176657Snate@binkert.org */ 3187007Snate@binkert.org${{dm.type.c_ident}}& 3197007Snate@binkert.orgget${{dm.ident}}() 3207007Snate@binkert.org{ 3217007Snate@binkert.org return m_${{dm.ident}}; 3227007Snate@binkert.org} 3236657Snate@binkert.org''') 3246657Snate@binkert.org 3256657Snate@binkert.org #Set methods for each field 3266657Snate@binkert.org code('// Mutator methods for each field') 3276657Snate@binkert.org for dm in self.data_members.values(): 3286657Snate@binkert.org code(''' 3296657Snate@binkert.org/** \\brief Mutator method for ${{dm.ident}} field */ 3307007Snate@binkert.orgvoid 3317007Snate@binkert.orgset${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) 3327007Snate@binkert.org{ 3337007Snate@binkert.org m_${{dm.ident}} = local_${{dm.ident}}; 3347007Snate@binkert.org} 3356657Snate@binkert.org''') 3366657Snate@binkert.org 3377002Snate@binkert.org code('void print(std::ostream& out) const;') 3386657Snate@binkert.org code.dedent() 3396657Snate@binkert.org code(' //private:') 3406657Snate@binkert.org code.indent() 3416657Snate@binkert.org 3426657Snate@binkert.org # Data members for each field 3436657Snate@binkert.org for dm in self.data_members.values(): 3446657Snate@binkert.org if "abstract" not in dm: 3456657Snate@binkert.org const = "" 3466657Snate@binkert.org init = "" 3476657Snate@binkert.org 3486657Snate@binkert.org # global structure 3496657Snate@binkert.org if self.isGlobal: 3506657Snate@binkert.org const = "static const " 3516657Snate@binkert.org 3526657Snate@binkert.org # init value 3536657Snate@binkert.org if dm.init_code: 3546657Snate@binkert.org # only global structure can have init value here 3556657Snate@binkert.org assert self.isGlobal 3566657Snate@binkert.org init = " = %s" % (dm.init_code) 3576657Snate@binkert.org 3586657Snate@binkert.org if "desc" in dm: 3597007Snate@binkert.org code('/** ${{dm["desc"]}} */') 3606657Snate@binkert.org 3617007Snate@binkert.org code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;') 3626657Snate@binkert.org 36310307Snilay@cs.wisc.edu # Prototypes for methods defined for the Type 36410307Snilay@cs.wisc.edu for item in self.methods: 36510307Snilay@cs.wisc.edu proto = self.methods[item].prototype 3669298Snilay@cs.wisc.edu if proto: 3679298Snilay@cs.wisc.edu code('$proto') 3689298Snilay@cs.wisc.edu 3696657Snate@binkert.org code.dedent() 3706657Snate@binkert.org code('};') 3716657Snate@binkert.org 3726657Snate@binkert.org code(''' 3737055Snate@binkert.orginline std::ostream& 3747007Snate@binkert.orgoperator<<(std::ostream& out, const ${{self.c_ident}}& obj) 3756657Snate@binkert.org{ 3766657Snate@binkert.org obj.print(out); 3777002Snate@binkert.org out << std::flush; 3786657Snate@binkert.org return out; 3796657Snate@binkert.org} 3806657Snate@binkert.org 3817007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 3826657Snate@binkert.org''') 3836657Snate@binkert.org 3846657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 3856657Snate@binkert.org 3866657Snate@binkert.org def printTypeCC(self, path): 3876999Snate@binkert.org code = self.symtab.codeFormatter() 3886657Snate@binkert.org 3896657Snate@binkert.org code(''' 3906657Snate@binkert.org/** \\file ${{self.c_ident}}.cc 3916657Snate@binkert.org * 3926657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 3936657Snate@binkert.org */ 3946657Snate@binkert.org 3957002Snate@binkert.org#include <iostream> 39610472Sandreas.hansson@arm.com#include <memory> 3977002Snate@binkert.org 3986657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 39911108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh" 4007002Snate@binkert.org 4017002Snate@binkert.orgusing namespace std; 4026657Snate@binkert.org''') 4036657Snate@binkert.org 4046657Snate@binkert.org code(''' 4056657Snate@binkert.org/** \\brief Print the state of this object */ 4067007Snate@binkert.orgvoid 4077007Snate@binkert.org${{self.c_ident}}::print(ostream& out) const 4086657Snate@binkert.org{ 4096657Snate@binkert.org out << "[${{self.c_ident}}: "; 4106657Snate@binkert.org''') 4116657Snate@binkert.org 4126657Snate@binkert.org # For each field 4136657Snate@binkert.org code.indent() 4146657Snate@binkert.org for dm in self.data_members.values(): 41511118Snilay@cs.wisc.edu if dm.type.c_ident == "Addr": 41611118Snilay@cs.wisc.edu code(''' 41711118Snilay@cs.wisc.eduout << "${{dm.ident}} = " << printAddress(m_${{dm.ident}}) << " ";''') 41811118Snilay@cs.wisc.edu else: 41911118Snilay@cs.wisc.edu code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') 4206657Snate@binkert.org 4216657Snate@binkert.org code.dedent() 4226657Snate@binkert.org 4236657Snate@binkert.org # Trailer 4246657Snate@binkert.org code(''' 4256657Snate@binkert.org out << "]"; 4266657Snate@binkert.org}''') 4276657Snate@binkert.org 42810307Snilay@cs.wisc.edu # print the code for the methods in the type 42910307Snilay@cs.wisc.edu for item in self.methods: 43010307Snilay@cs.wisc.edu code(self.methods[item].generateCode()) 4319298Snilay@cs.wisc.edu 4326657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 4336657Snate@binkert.org 4346657Snate@binkert.org def printEnumHH(self, path): 4356999Snate@binkert.org code = self.symtab.codeFormatter() 4366657Snate@binkert.org code(''' 4376657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 4386657Snate@binkert.org * 4396657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4406657Snate@binkert.org */ 4417007Snate@binkert.org 4427007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 4437007Snate@binkert.org#define __${{self.c_ident}}_HH__ 4446657Snate@binkert.org 4457002Snate@binkert.org#include <iostream> 4467002Snate@binkert.org#include <string> 4477002Snate@binkert.org 4488086SBrad.Beckmann@amd.com''') 4498086SBrad.Beckmann@amd.com if self.isStateDecl: 4508086SBrad.Beckmann@amd.com code('#include "mem/protocol/AccessPermission.hh"') 4518086SBrad.Beckmann@amd.com 4528602Snilay@cs.wisc.edu if self.isMachineType: 4538602Snilay@cs.wisc.edu code('#include "base/misc.hh"') 4548602Snilay@cs.wisc.edu code('#include "mem/ruby/common/Address.hh"') 45511025Snilay@cs.wisc.edu code('#include "mem/ruby/common/TypeDefines.hh"') 4568602Snilay@cs.wisc.edu code('struct MachineID;') 4578602Snilay@cs.wisc.edu 4588086SBrad.Beckmann@amd.com code(''' 4596657Snate@binkert.org 4607007Snate@binkert.org// Class definition 4616657Snate@binkert.org/** \\enum ${{self.c_ident}} 4626657Snate@binkert.org * \\brief ${{self.desc}} 4636657Snate@binkert.org */ 4646657Snate@binkert.orgenum ${{self.c_ident}} { 4656657Snate@binkert.org ${{self.c_ident}}_FIRST, 4666657Snate@binkert.org''') 4676657Snate@binkert.org 4686657Snate@binkert.org code.indent() 4696657Snate@binkert.org # For each field 4706657Snate@binkert.org for i,(ident,enum) in enumerate(self.enums.iteritems()): 4716657Snate@binkert.org desc = enum.get("desc", "No description avaliable") 47210917Sbrandon.potter@amd.com if i == 0: 47310917Sbrandon.potter@amd.com init = ' = %s_FIRST' % self.c_ident 4746862Sdrh5@cs.wisc.edu else: 4756862Sdrh5@cs.wisc.edu init = '' 4766657Snate@binkert.org code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4776657Snate@binkert.org code.dedent() 4786657Snate@binkert.org code(''' 4796657Snate@binkert.org ${{self.c_ident}}_NUM 4806657Snate@binkert.org}; 4817007Snate@binkert.org 4827007Snate@binkert.org// Code to convert from a string to the enumeration 4837002Snate@binkert.org${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 4847007Snate@binkert.org 4857007Snate@binkert.org// Code to convert state to a string 4867002Snate@binkert.orgstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 4877007Snate@binkert.org 4887007Snate@binkert.org// Code to increment an enumeration type 4896657Snate@binkert.org${{self.c_ident}} &operator++(${{self.c_ident}} &e); 4906657Snate@binkert.org''') 4916657Snate@binkert.org 4926657Snate@binkert.org # MachineType hack used to set the base component id for each Machine 4936657Snate@binkert.org if self.isMachineType: 4946657Snate@binkert.org code(''' 4956657Snate@binkert.orgint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 4966657Snate@binkert.orgMachineType ${{self.c_ident}}_from_base_level(int); 4976657Snate@binkert.orgint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 4986657Snate@binkert.orgint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 4996657Snate@binkert.org''') 5006657Snate@binkert.org 5016657Snate@binkert.org for enum in self.enums.itervalues(): 5028602Snilay@cs.wisc.edu if enum.ident == "DMA": 5038602Snilay@cs.wisc.edu code(''' 50411025Snilay@cs.wisc.eduMachineID map_Address_to_DMA(const Addr &addr); 5058602Snilay@cs.wisc.edu''') 5068602Snilay@cs.wisc.edu code(''' 5078602Snilay@cs.wisc.edu 5088602Snilay@cs.wisc.eduMachineID get${{enum.ident}}MachineID(NodeID RubyNode); 5098602Snilay@cs.wisc.edu''') 5108602Snilay@cs.wisc.edu 5118086SBrad.Beckmann@amd.com if self.isStateDecl: 5128086SBrad.Beckmann@amd.com code(''' 5138086SBrad.Beckmann@amd.com 5148086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5158086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); 5168086SBrad.Beckmann@amd.com 5178086SBrad.Beckmann@amd.com''') 5188086SBrad.Beckmann@amd.com 5196657Snate@binkert.org # Trailer 5206657Snate@binkert.org code(''' 5217002Snate@binkert.orgstd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 5226657Snate@binkert.org 5237007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 5246657Snate@binkert.org''') 5256657Snate@binkert.org 5266657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 5276657Snate@binkert.org 5286657Snate@binkert.org def printEnumCC(self, path): 5296999Snate@binkert.org code = self.symtab.codeFormatter() 5306657Snate@binkert.org code(''' 5316657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 5326657Snate@binkert.org * 5336657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 5346657Snate@binkert.org */ 5356657Snate@binkert.org 5367832Snate@binkert.org#include <cassert> 5377002Snate@binkert.org#include <iostream> 5387002Snate@binkert.org#include <string> 5397002Snate@binkert.org 5407805Snilay@cs.wisc.edu#include "base/misc.hh" 5416657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 5426657Snate@binkert.org 5437002Snate@binkert.orgusing namespace std; 5447002Snate@binkert.org 5456657Snate@binkert.org''') 5466657Snate@binkert.org 5478086SBrad.Beckmann@amd.com if self.isStateDecl: 5488086SBrad.Beckmann@amd.com code(''' 5498086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5508086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) 5518086SBrad.Beckmann@amd.com{ 5528086SBrad.Beckmann@amd.com switch(obj) { 5538086SBrad.Beckmann@amd.com''') 5548086SBrad.Beckmann@amd.com # For each case 5558086SBrad.Beckmann@amd.com code.indent() 5568086SBrad.Beckmann@amd.com for statePerm in self.statePermPairs: 5578086SBrad.Beckmann@amd.com code(' case ${{self.c_ident}}_${{statePerm[0]}}:') 5588086SBrad.Beckmann@amd.com code(' return AccessPermission_${{statePerm[1]}};') 5598086SBrad.Beckmann@amd.com code.dedent() 5608086SBrad.Beckmann@amd.com code (''' 5618086SBrad.Beckmann@amd.com default: 5628086SBrad.Beckmann@amd.com panic("Unknown state access permission converstion for ${{self.c_ident}}"); 5638086SBrad.Beckmann@amd.com } 5648086SBrad.Beckmann@amd.com} 5658086SBrad.Beckmann@amd.com 5668086SBrad.Beckmann@amd.com''') 5678086SBrad.Beckmann@amd.com 5686657Snate@binkert.org if self.isMachineType: 5696657Snate@binkert.org for enum in self.enums.itervalues(): 5709773Snilay@cs.wisc.edu if enum.get("Primary"): 5719773Snilay@cs.wisc.edu code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') 57210301Snilay@cs.wisc.edu code('#include "mem/ruby/common/MachineID.hh"') 5736657Snate@binkert.org 5746657Snate@binkert.org code(''' 5757007Snate@binkert.org// Code for output operator 5767007Snate@binkert.orgostream& 5777007Snate@binkert.orgoperator<<(ostream& out, const ${{self.c_ident}}& obj) 5786657Snate@binkert.org{ 5796657Snate@binkert.org out << ${{self.c_ident}}_to_string(obj); 5806657Snate@binkert.org out << flush; 5816657Snate@binkert.org return out; 5826657Snate@binkert.org} 5836657Snate@binkert.org 5847007Snate@binkert.org// Code to convert state to a string 5857007Snate@binkert.orgstring 5867007Snate@binkert.org${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 5876657Snate@binkert.org{ 5886657Snate@binkert.org switch(obj) { 5896657Snate@binkert.org''') 5906657Snate@binkert.org 5916657Snate@binkert.org # For each field 5926657Snate@binkert.org code.indent() 5936657Snate@binkert.org for enum in self.enums.itervalues(): 5946657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 5956657Snate@binkert.org code(' return "${{enum.ident}}";') 5966657Snate@binkert.org code.dedent() 5976657Snate@binkert.org 5986657Snate@binkert.org # Trailer 5996657Snate@binkert.org code(''' 6006657Snate@binkert.org default: 6017805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6026657Snate@binkert.org } 6036657Snate@binkert.org} 6046657Snate@binkert.org 6057007Snate@binkert.org// Code to convert from a string to the enumeration 6067007Snate@binkert.org${{self.c_ident}} 6077007Snate@binkert.orgstring_to_${{self.c_ident}}(const string& str) 6086657Snate@binkert.org{ 6096657Snate@binkert.org''') 6106657Snate@binkert.org 6116657Snate@binkert.org # For each field 6127007Snate@binkert.org start = "" 6136657Snate@binkert.org code.indent() 6146657Snate@binkert.org for enum in self.enums.itervalues(): 6156657Snate@binkert.org code('${start}if (str == "${{enum.ident}}") {') 6166657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6177007Snate@binkert.org start = "} else " 6186657Snate@binkert.org code.dedent() 6196657Snate@binkert.org 6206657Snate@binkert.org code(''' 6216657Snate@binkert.org } else { 6227805Snilay@cs.wisc.edu panic("Invalid string conversion for %s, type ${{self.c_ident}}", str); 6236657Snate@binkert.org } 6246657Snate@binkert.org} 6256657Snate@binkert.org 6267007Snate@binkert.org// Code to increment an enumeration type 6277007Snate@binkert.org${{self.c_ident}}& 6287007Snate@binkert.orgoperator++(${{self.c_ident}}& e) 6297007Snate@binkert.org{ 6306657Snate@binkert.org assert(e < ${{self.c_ident}}_NUM); 6316657Snate@binkert.org return e = ${{self.c_ident}}(e+1); 6326657Snate@binkert.org} 6336657Snate@binkert.org''') 6346657Snate@binkert.org 6356657Snate@binkert.org # MachineType hack used to set the base level and number of 6366657Snate@binkert.org # components for each Machine 6376657Snate@binkert.org if self.isMachineType: 6386657Snate@binkert.org code(''' 6397007Snate@binkert.org/** \\brief returns the base vector index for each machine type to be 6407007Snate@binkert.org * used by NetDest 6416657Snate@binkert.org * 6426657Snate@binkert.org * \\return the base vector index for each machine type to be used by NetDest 6436657Snate@binkert.org * \\see NetDest.hh 6446657Snate@binkert.org */ 6457007Snate@binkert.orgint 6467007Snate@binkert.org${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 6476657Snate@binkert.org{ 6486657Snate@binkert.org switch(obj) { 6496657Snate@binkert.org''') 6506657Snate@binkert.org 6516657Snate@binkert.org # For each field 6526657Snate@binkert.org code.indent() 6536657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6546657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6556657Snate@binkert.org code(' return $i;') 6566657Snate@binkert.org code.dedent() 6576657Snate@binkert.org 6586657Snate@binkert.org # total num 6596657Snate@binkert.org code(''' 6606657Snate@binkert.org case ${{self.c_ident}}_NUM: 6616657Snate@binkert.org return ${{len(self.enums)}}; 6626657Snate@binkert.org 6636657Snate@binkert.org default: 6647805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6656657Snate@binkert.org } 6666657Snate@binkert.org} 6676657Snate@binkert.org 6686657Snate@binkert.org/** \\brief returns the machine type for each base vector index used by NetDest 6696657Snate@binkert.org * 6707007Snate@binkert.org * \\return the MachineType 6716657Snate@binkert.org */ 6727007Snate@binkert.orgMachineType 6737007Snate@binkert.org${{self.c_ident}}_from_base_level(int type) 6746657Snate@binkert.org{ 6756657Snate@binkert.org switch(type) { 6766657Snate@binkert.org''') 6776657Snate@binkert.org 6786657Snate@binkert.org # For each field 6796657Snate@binkert.org code.indent() 6806657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6816657Snate@binkert.org code(' case $i:') 6826657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6836657Snate@binkert.org code.dedent() 6846657Snate@binkert.org 6856657Snate@binkert.org # Trailer 6866657Snate@binkert.org code(''' 6876657Snate@binkert.org default: 6887805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6896657Snate@binkert.org } 6906657Snate@binkert.org} 6916657Snate@binkert.org 6926657Snate@binkert.org/** \\brief The return value indicates the number of components created 6936657Snate@binkert.org * before a particular machine\'s components 6946657Snate@binkert.org * 6956657Snate@binkert.org * \\return the base number of components for each machine 6966657Snate@binkert.org */ 6977007Snate@binkert.orgint 6987007Snate@binkert.org${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 6996657Snate@binkert.org{ 7006657Snate@binkert.org int base = 0; 7016657Snate@binkert.org switch(obj) { 7026657Snate@binkert.org''') 7036657Snate@binkert.org 7046657Snate@binkert.org # For each field 7056657Snate@binkert.org code.indent() 7066657Snate@binkert.org code(' case ${{self.c_ident}}_NUM:') 7076657Snate@binkert.org for enum in reversed(self.enums.values()): 7089773Snilay@cs.wisc.edu # Check if there is a defined machine with this type 7099773Snilay@cs.wisc.edu if enum.get("Primary"): 7109773Snilay@cs.wisc.edu code(' base += ${{enum.ident}}_Controller::getNumControllers();') 7119773Snilay@cs.wisc.edu else: 7129773Snilay@cs.wisc.edu code(' base += 0;') 7136657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 7146657Snate@binkert.org code(' break;') 7156657Snate@binkert.org code.dedent() 7166657Snate@binkert.org 7176657Snate@binkert.org code(''' 7186657Snate@binkert.org default: 7197805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7206657Snate@binkert.org } 7216657Snate@binkert.org 7226657Snate@binkert.org return base; 7236657Snate@binkert.org} 7246657Snate@binkert.org 7256657Snate@binkert.org/** \\brief returns the total number of components for each machine 7266657Snate@binkert.org * \\return the total number of components for each machine 7276657Snate@binkert.org */ 7287007Snate@binkert.orgint 7297007Snate@binkert.org${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 7306657Snate@binkert.org{ 7316657Snate@binkert.org switch(obj) { 7326657Snate@binkert.org''') 7336657Snate@binkert.org 7346657Snate@binkert.org # For each field 7356657Snate@binkert.org for enum in self.enums.itervalues(): 7369773Snilay@cs.wisc.edu code('case ${{self.c_ident}}_${{enum.ident}}:') 7379773Snilay@cs.wisc.edu if enum.get("Primary"): 7389773Snilay@cs.wisc.edu code('return ${{enum.ident}}_Controller::getNumControllers();') 7399773Snilay@cs.wisc.edu else: 7409773Snilay@cs.wisc.edu code('return 0;') 7416657Snate@binkert.org 7426657Snate@binkert.org # total num 7436657Snate@binkert.org code(''' 7446657Snate@binkert.org case ${{self.c_ident}}_NUM: 7456657Snate@binkert.org default: 7467805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7476657Snate@binkert.org } 7486657Snate@binkert.org} 7496657Snate@binkert.org''') 7506657Snate@binkert.org 7518602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 7528602Snilay@cs.wisc.edu if enum.ident == "DMA": 7538602Snilay@cs.wisc.edu code(''' 7548602Snilay@cs.wisc.eduMachineID 75511025Snilay@cs.wisc.edumap_Address_to_DMA(const Addr &addr) 7568602Snilay@cs.wisc.edu{ 7578602Snilay@cs.wisc.edu MachineID dma = {MachineType_DMA, 0}; 7588602Snilay@cs.wisc.edu return dma; 7598602Snilay@cs.wisc.edu} 7608602Snilay@cs.wisc.edu''') 7618602Snilay@cs.wisc.edu 7628602Snilay@cs.wisc.edu code(''' 7638602Snilay@cs.wisc.edu 7648602Snilay@cs.wisc.eduMachineID 7658602Snilay@cs.wisc.eduget${{enum.ident}}MachineID(NodeID RubyNode) 7668602Snilay@cs.wisc.edu{ 7678602Snilay@cs.wisc.edu MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; 7688602Snilay@cs.wisc.edu return mach; 7698602Snilay@cs.wisc.edu} 7708602Snilay@cs.wisc.edu''') 7718602Snilay@cs.wisc.edu 7726657Snate@binkert.org # Write the file 7736657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 7746657Snate@binkert.org 7756657Snate@binkert.org__all__ = [ "Type" ] 776