Type.py revision 9302
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 346657Snate@binkert.orgclass DataMember(PairContainer): 356657Snate@binkert.org def __init__(self, ident, type, pairs, init_code): 366657Snate@binkert.org super(DataMember, self).__init__(pairs) 376657Snate@binkert.org self.ident = ident 386657Snate@binkert.org self.type = type 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 Method(object): 476657Snate@binkert.org def __init__(self, return_type, param_types): 486657Snate@binkert.org self.return_type = return_type 496657Snate@binkert.org self.param_types = param_types 506657Snate@binkert.org 516657Snate@binkert.orgclass Type(Symbol): 526657Snate@binkert.org def __init__(self, table, ident, location, pairs, machine=None): 536657Snate@binkert.org super(Type, self).__init__(table, ident, location, pairs) 546657Snate@binkert.org self.c_ident = ident 556882SBrad.Beckmann@amd.com self.abstract_ident = "" 566657Snate@binkert.org if machine: 576657Snate@binkert.org if self.isExternal or self.isPrimitive: 586657Snate@binkert.org if "external_name" in self: 596657Snate@binkert.org self.c_ident = self["external_name"] 606657Snate@binkert.org else: 616657Snate@binkert.org # Append with machine name 626657Snate@binkert.org self.c_ident = "%s_%s" % (machine, ident) 636657Snate@binkert.org 646657Snate@binkert.org self.pairs.setdefault("desc", "No description avaliable") 656657Snate@binkert.org 666657Snate@binkert.org # check for interface that this Type implements 676657Snate@binkert.org if "interface" in self: 686657Snate@binkert.org interface = self["interface"] 696657Snate@binkert.org if interface in ("Message", "NetworkMessage"): 706657Snate@binkert.org self["message"] = "yes" 716657Snate@binkert.org if interface == "NetworkMessage": 726657Snate@binkert.org self["networkmessage"] = "yes" 736657Snate@binkert.org 746657Snate@binkert.org # FIXME - all of the following id comparisons are fragile hacks 756657Snate@binkert.org if self.ident in ("CacheMemory", "NewCacheMemory", 766657Snate@binkert.org "TLCCacheMemory", "DNUCACacheMemory", 776657Snate@binkert.org "DNUCABankCacheMemory", "L2BankCacheMemory", 786657Snate@binkert.org "CompressedCacheMemory", "PrefetchCacheMemory"): 796657Snate@binkert.org self["cache"] = "yes" 806657Snate@binkert.org 816657Snate@binkert.org if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"): 826657Snate@binkert.org self["tbe"] = "yes" 836657Snate@binkert.org 846657Snate@binkert.org if self.ident == "NewTBETable": 856657Snate@binkert.org self["newtbe"] = "yes" 866657Snate@binkert.org 876657Snate@binkert.org if self.ident == "TimerTable": 886657Snate@binkert.org self["timer"] = "yes" 896657Snate@binkert.org 906657Snate@binkert.org if self.ident == "DirectoryMemory": 916657Snate@binkert.org self["dir"] = "yes" 926657Snate@binkert.org 936657Snate@binkert.org if self.ident == "PersistentTable": 946657Snate@binkert.org self["persistent"] = "yes" 956657Snate@binkert.org 966657Snate@binkert.org if self.ident == "Prefetcher": 976657Snate@binkert.org self["prefetcher"] = "yes" 986657Snate@binkert.org 996657Snate@binkert.org if self.ident == "DNUCA_Movement": 1006657Snate@binkert.org self["mover"] = "yes" 1016657Snate@binkert.org 1026657Snate@binkert.org self.isMachineType = (ident == "MachineType") 1036657Snate@binkert.org 1048086SBrad.Beckmann@amd.com self.isStateDecl = ("state_decl" in self) 1058086SBrad.Beckmann@amd.com self.statePermPairs = [] 1068086SBrad.Beckmann@amd.com 1076657Snate@binkert.org self.data_members = orderdict() 1086657Snate@binkert.org 1096657Snate@binkert.org # Methods 1106657Snate@binkert.org self.methods = {} 1119298Snilay@cs.wisc.edu self.functions = {} 1126657Snate@binkert.org 1136657Snate@binkert.org # Enums 1146657Snate@binkert.org self.enums = orderdict() 1156657Snate@binkert.org 1166657Snate@binkert.org @property 1176657Snate@binkert.org def isPrimitive(self): 1186657Snate@binkert.org return "primitive" in self 1196657Snate@binkert.org @property 1206657Snate@binkert.org def isNetworkMessage(self): 1216657Snate@binkert.org return "networkmessage" in self 1226657Snate@binkert.org @property 1236657Snate@binkert.org def isMessage(self): 1246657Snate@binkert.org return "message" in self 1256657Snate@binkert.org @property 1266657Snate@binkert.org def isBuffer(self): 1276657Snate@binkert.org return "buffer" in self 1286657Snate@binkert.org @property 1296657Snate@binkert.org def isInPort(self): 1306657Snate@binkert.org return "inport" in self 1316657Snate@binkert.org @property 1326657Snate@binkert.org def isOutPort(self): 1336657Snate@binkert.org return "outport" in self 1346657Snate@binkert.org @property 1356657Snate@binkert.org def isEnumeration(self): 1366657Snate@binkert.org return "enumeration" in self 1376657Snate@binkert.org @property 1386657Snate@binkert.org def isExternal(self): 1396657Snate@binkert.org return "external" in self 1406657Snate@binkert.org @property 1416657Snate@binkert.org def isGlobal(self): 1426657Snate@binkert.org return "global" in self 1436657Snate@binkert.org @property 1446657Snate@binkert.org def isInterface(self): 1456657Snate@binkert.org return "interface" in self 1466657Snate@binkert.org 1476657Snate@binkert.org # Return false on error 1489298Snilay@cs.wisc.edu def addDataMember(self, ident, type, pairs, init_code): 1496657Snate@binkert.org if ident in self.data_members: 1506657Snate@binkert.org return False 1516657Snate@binkert.org 1526657Snate@binkert.org member = DataMember(ident, type, pairs, init_code) 1536657Snate@binkert.org self.data_members[ident] = member 1546657Snate@binkert.org 1559302Snilay@cs.wisc.edu var = Var(self.symtab, ident, self.location, type, 1569302Snilay@cs.wisc.edu "m_%s" % ident, {}, None) 1579302Snilay@cs.wisc.edu self.symtab.registerSym(ident, var) 1586657Snate@binkert.org return True 1596657Snate@binkert.org 1606657Snate@binkert.org def dataMemberType(self, ident): 1616657Snate@binkert.org return self.data_members[ident].type 1626657Snate@binkert.org 1636657Snate@binkert.org def methodId(self, name, param_type_vec): 1646657Snate@binkert.org return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) 1656657Snate@binkert.org 1666882SBrad.Beckmann@amd.com def methodIdAbstract(self, name, param_type_vec): 1676882SBrad.Beckmann@amd.com return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ]) 1686882SBrad.Beckmann@amd.com 1698086SBrad.Beckmann@amd.com def statePermPairAdd(self, state_name, perm_name): 1708086SBrad.Beckmann@amd.com self.statePermPairs.append([state_name, perm_name]) 1718086SBrad.Beckmann@amd.com 1729298Snilay@cs.wisc.edu def addMethod(self, name, return_type, param_type_vec): 1736657Snate@binkert.org ident = self.methodId(name, param_type_vec) 1746657Snate@binkert.org if ident in self.methods: 1756657Snate@binkert.org return False 1766657Snate@binkert.org 1776657Snate@binkert.org self.methods[ident] = Method(return_type, param_type_vec) 1786657Snate@binkert.org return True 1796657Snate@binkert.org 1809298Snilay@cs.wisc.edu # Ideally either this function or the one above should exist. But 1819298Snilay@cs.wisc.edu # methods and functions have different structures right now. 1829298Snilay@cs.wisc.edu # Hence, these are different, at least for the time being. 1839298Snilay@cs.wisc.edu def addFunc(self, func): 1849298Snilay@cs.wisc.edu ident = self.methodId(func.ident, func.param_types) 1859298Snilay@cs.wisc.edu if ident in self.functions: 1869298Snilay@cs.wisc.edu return False 1879298Snilay@cs.wisc.edu 1889298Snilay@cs.wisc.edu self.functions[ident] = func 1899298Snilay@cs.wisc.edu return True 1909298Snilay@cs.wisc.edu 1919298Snilay@cs.wisc.edu def addEnum(self, ident, pairs): 1926657Snate@binkert.org if ident in self.enums: 1936657Snate@binkert.org return False 1946657Snate@binkert.org 1956657Snate@binkert.org self.enums[ident] = Enumeration(ident, pairs) 1966657Snate@binkert.org 1976657Snate@binkert.org # Add default 1986657Snate@binkert.org if "default" not in self: 1996657Snate@binkert.org self["default"] = "%s_NUM" % self.c_ident 2006657Snate@binkert.org 2016657Snate@binkert.org return True 2026657Snate@binkert.org 2039219Spower.jg@gmail.com def writeCodeFiles(self, path, includes): 2046657Snate@binkert.org if self.isExternal: 2056657Snate@binkert.org # Do nothing 2066657Snate@binkert.org pass 2076657Snate@binkert.org elif self.isEnumeration: 2086657Snate@binkert.org self.printEnumHH(path) 2096657Snate@binkert.org self.printEnumCC(path) 2106657Snate@binkert.org else: 2116657Snate@binkert.org # User defined structs and messages 2126657Snate@binkert.org self.printTypeHH(path) 2136657Snate@binkert.org self.printTypeCC(path) 2146657Snate@binkert.org 2156657Snate@binkert.org def printTypeHH(self, path): 2166999Snate@binkert.org code = self.symtab.codeFormatter() 2176657Snate@binkert.org code(''' 2186657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 2196657Snate@binkert.org * 2206657Snate@binkert.org * 2216657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 2226657Snate@binkert.org */ 2236657Snate@binkert.org 2247007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 2257007Snate@binkert.org#define __${{self.c_ident}}_HH__ 2266657Snate@binkert.org 2277002Snate@binkert.org#include <iostream> 2287002Snate@binkert.org 2296657Snate@binkert.org#include "mem/ruby/common/Global.hh" 2306657Snate@binkert.org''') 2316657Snate@binkert.org 2326657Snate@binkert.org for dm in self.data_members.values(): 2336657Snate@binkert.org if not dm.type.isPrimitive: 2346657Snate@binkert.org code('#include "mem/protocol/$0.hh"', dm.type.c_ident) 2356657Snate@binkert.org 2366657Snate@binkert.org parent = "" 2376657Snate@binkert.org if "interface" in self: 2386657Snate@binkert.org code('#include "mem/protocol/$0.hh"', self["interface"]) 2396657Snate@binkert.org parent = " : public %s" % self["interface"] 2406657Snate@binkert.org 2416657Snate@binkert.org code(''' 2427007Snate@binkert.org$klass ${{self.c_ident}}$parent 2437007Snate@binkert.org{ 2446657Snate@binkert.org public: 2456657Snate@binkert.org ${{self.c_ident}}() 2467007Snate@binkert.org { 2476657Snate@binkert.org''', klass="class") 2486657Snate@binkert.org 2496657Snate@binkert.org code.indent() 2506657Snate@binkert.org if not self.isGlobal: 2516657Snate@binkert.org code.indent() 2526657Snate@binkert.org for dm in self.data_members.values(): 2536657Snate@binkert.org ident = dm.ident 2546657Snate@binkert.org if "default" in dm: 2556657Snate@binkert.org # look for default value 2566657Snate@binkert.org code('m_$ident = ${{dm["default"]}}; // default for this field') 2576657Snate@binkert.org elif "default" in dm.type: 2586657Snate@binkert.org # Look for the type default 2596657Snate@binkert.org tid = dm.type.c_ident 2606657Snate@binkert.org code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') 2616657Snate@binkert.org else: 2626657Snate@binkert.org code('// m_$ident has no default') 2636657Snate@binkert.org code.dedent() 2646657Snate@binkert.org code('}') 2656657Snate@binkert.org 2667453Snate@binkert.org # ******** Copy constructor ******** 2677453Snate@binkert.org if not self.isGlobal: 2687453Snate@binkert.org code('${{self.c_ident}}(const ${{self.c_ident}}&other)') 2697453Snate@binkert.org 2707453Snate@binkert.org # Call superclass constructor 2717453Snate@binkert.org if "interface" in self: 2727453Snate@binkert.org code(' : ${{self["interface"]}}(other)') 2737453Snate@binkert.org 2747453Snate@binkert.org code('{') 2757453Snate@binkert.org code.indent() 2767453Snate@binkert.org 2777453Snate@binkert.org for dm in self.data_members.values(): 2787453Snate@binkert.org code('m_${{dm.ident}} = other.m_${{dm.ident}};') 2797453Snate@binkert.org 2807453Snate@binkert.org code.dedent() 2817453Snate@binkert.org code('}') 2827453Snate@binkert.org 2836657Snate@binkert.org # ******** Full init constructor ******** 2846657Snate@binkert.org if not self.isGlobal: 2856657Snate@binkert.org params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ 2866657Snate@binkert.org for dm in self.data_members.itervalues() ] 2876657Snate@binkert.org 2886657Snate@binkert.org params = ', '.join(params) 2896657Snate@binkert.org code('${{self.c_ident}}($params)') 2906657Snate@binkert.org 2916657Snate@binkert.org # Call superclass constructor 2926657Snate@binkert.org if "interface" in self: 2936657Snate@binkert.org code(' : ${{self["interface"]}}()') 2946657Snate@binkert.org 2956657Snate@binkert.org code('{') 2966657Snate@binkert.org code.indent() 2976657Snate@binkert.org for dm in self.data_members.values(): 2986657Snate@binkert.org code('m_${{dm.ident}} = local_${{dm.ident}};') 2996657Snate@binkert.org if "nextLineCallHack" in dm: 3006657Snate@binkert.org code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};') 3016657Snate@binkert.org 3026657Snate@binkert.org code.dedent() 3036657Snate@binkert.org code('}') 3046657Snate@binkert.org 3057453Snate@binkert.org # create a static factory method and a clone member 3067453Snate@binkert.org code(''' 3077453Snate@binkert.orgstatic ${{self.c_ident}}* 3087007Snate@binkert.orgcreate() 3097007Snate@binkert.org{ 3106657Snate@binkert.org return new ${{self.c_ident}}(); 3116657Snate@binkert.org} 3126657Snate@binkert.org 3137453Snate@binkert.org${{self.c_ident}}* 3147007Snate@binkert.orgclone() const 3157007Snate@binkert.org{ 3167453Snate@binkert.org return new ${{self.c_ident}}(*this); 3177007Snate@binkert.org} 3186657Snate@binkert.org''') 3196657Snate@binkert.org 3206657Snate@binkert.org if not self.isGlobal: 3216657Snate@binkert.org # const Get methods for each field 3226657Snate@binkert.org code('// Const accessors methods for each field') 3236657Snate@binkert.org for dm in self.data_members.values(): 3246657Snate@binkert.org code(''' 3256657Snate@binkert.org/** \\brief Const accessor method for ${{dm.ident}} field. 3266657Snate@binkert.org * \\return ${{dm.ident}} field 3276657Snate@binkert.org */ 3287007Snate@binkert.orgconst ${{dm.type.c_ident}}& 3297007Snate@binkert.orgget${{dm.ident}}() const 3307007Snate@binkert.org{ 3317007Snate@binkert.org return m_${{dm.ident}}; 3327007Snate@binkert.org} 3336657Snate@binkert.org''') 3346657Snate@binkert.org 3356657Snate@binkert.org # Non-const Get methods for each field 3366657Snate@binkert.org code('// Non const Accessors methods for each field') 3376657Snate@binkert.org for dm in self.data_members.values(): 3386657Snate@binkert.org code(''' 3396657Snate@binkert.org/** \\brief Non-const accessor method for ${{dm.ident}} field. 3406657Snate@binkert.org * \\return ${{dm.ident}} field 3416657Snate@binkert.org */ 3427007Snate@binkert.org${{dm.type.c_ident}}& 3437007Snate@binkert.orgget${{dm.ident}}() 3447007Snate@binkert.org{ 3457007Snate@binkert.org return m_${{dm.ident}}; 3467007Snate@binkert.org} 3476657Snate@binkert.org''') 3486657Snate@binkert.org 3496657Snate@binkert.org #Set methods for each field 3506657Snate@binkert.org code('// Mutator methods for each field') 3516657Snate@binkert.org for dm in self.data_members.values(): 3526657Snate@binkert.org code(''' 3536657Snate@binkert.org/** \\brief Mutator method for ${{dm.ident}} field */ 3547007Snate@binkert.orgvoid 3557007Snate@binkert.orgset${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) 3567007Snate@binkert.org{ 3577007Snate@binkert.org m_${{dm.ident}} = local_${{dm.ident}}; 3587007Snate@binkert.org} 3596657Snate@binkert.org''') 3606657Snate@binkert.org 3617002Snate@binkert.org code('void print(std::ostream& out) const;') 3626657Snate@binkert.org code.dedent() 3636657Snate@binkert.org code(' //private:') 3646657Snate@binkert.org code.indent() 3656657Snate@binkert.org 3666657Snate@binkert.org # Data members for each field 3676657Snate@binkert.org for dm in self.data_members.values(): 3686657Snate@binkert.org if "abstract" not in dm: 3696657Snate@binkert.org const = "" 3706657Snate@binkert.org init = "" 3716657Snate@binkert.org 3726657Snate@binkert.org # global structure 3736657Snate@binkert.org if self.isGlobal: 3746657Snate@binkert.org const = "static const " 3756657Snate@binkert.org 3766657Snate@binkert.org # init value 3776657Snate@binkert.org if dm.init_code: 3786657Snate@binkert.org # only global structure can have init value here 3796657Snate@binkert.org assert self.isGlobal 3806657Snate@binkert.org init = " = %s" % (dm.init_code) 3816657Snate@binkert.org 3826657Snate@binkert.org if "desc" in dm: 3837007Snate@binkert.org code('/** ${{dm["desc"]}} */') 3846657Snate@binkert.org 3857007Snate@binkert.org code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;') 3866657Snate@binkert.org 3879298Snilay@cs.wisc.edu # Prototypes for functions defined for the Type 3889298Snilay@cs.wisc.edu for item in self.functions: 3899298Snilay@cs.wisc.edu proto = self.functions[item].prototype 3909298Snilay@cs.wisc.edu if proto: 3919298Snilay@cs.wisc.edu code('$proto') 3929298Snilay@cs.wisc.edu 3936657Snate@binkert.org code.dedent() 3946657Snate@binkert.org code('};') 3956657Snate@binkert.org 3966657Snate@binkert.org code(''' 3977055Snate@binkert.orginline std::ostream& 3987007Snate@binkert.orgoperator<<(std::ostream& out, const ${{self.c_ident}}& obj) 3996657Snate@binkert.org{ 4006657Snate@binkert.org obj.print(out); 4017002Snate@binkert.org out << std::flush; 4026657Snate@binkert.org return out; 4036657Snate@binkert.org} 4046657Snate@binkert.org 4057007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 4066657Snate@binkert.org''') 4076657Snate@binkert.org 4086657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 4096657Snate@binkert.org 4106657Snate@binkert.org def printTypeCC(self, path): 4116999Snate@binkert.org code = self.symtab.codeFormatter() 4126657Snate@binkert.org 4136657Snate@binkert.org code(''' 4146657Snate@binkert.org/** \\file ${{self.c_ident}}.cc 4156657Snate@binkert.org * 4166657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4176657Snate@binkert.org */ 4186657Snate@binkert.org 4197002Snate@binkert.org#include <iostream> 4207002Snate@binkert.org 4216657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 4229302Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 4237002Snate@binkert.org 4247002Snate@binkert.orgusing namespace std; 4256657Snate@binkert.org''') 4266657Snate@binkert.org 4276657Snate@binkert.org code(''' 4286657Snate@binkert.org/** \\brief Print the state of this object */ 4297007Snate@binkert.orgvoid 4307007Snate@binkert.org${{self.c_ident}}::print(ostream& out) const 4316657Snate@binkert.org{ 4326657Snate@binkert.org out << "[${{self.c_ident}}: "; 4336657Snate@binkert.org''') 4346657Snate@binkert.org 4356657Snate@binkert.org # For each field 4366657Snate@binkert.org code.indent() 4376657Snate@binkert.org for dm in self.data_members.values(): 4386657Snate@binkert.org code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') 4396657Snate@binkert.org 4406657Snate@binkert.org if self.isMessage: 4419206Snilay@cs.wisc.edu code('out << "Time = " << g_system_ptr->clockPeriod() * getTime() << " ";') 4426657Snate@binkert.org code.dedent() 4436657Snate@binkert.org 4446657Snate@binkert.org # Trailer 4456657Snate@binkert.org code(''' 4466657Snate@binkert.org out << "]"; 4476657Snate@binkert.org}''') 4486657Snate@binkert.org 4499298Snilay@cs.wisc.edu # print the code for the functions in the type 4509298Snilay@cs.wisc.edu for item in self.functions: 4519298Snilay@cs.wisc.edu code(self.functions[item].generateCode()) 4529298Snilay@cs.wisc.edu 4536657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 4546657Snate@binkert.org 4556657Snate@binkert.org def printEnumHH(self, path): 4566999Snate@binkert.org code = self.symtab.codeFormatter() 4576657Snate@binkert.org code(''' 4586657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 4596657Snate@binkert.org * 4606657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4616657Snate@binkert.org */ 4627007Snate@binkert.org 4637007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 4647007Snate@binkert.org#define __${{self.c_ident}}_HH__ 4656657Snate@binkert.org 4667002Snate@binkert.org#include <iostream> 4677002Snate@binkert.org#include <string> 4687002Snate@binkert.org 4698086SBrad.Beckmann@amd.com''') 4708086SBrad.Beckmann@amd.com if self.isStateDecl: 4718086SBrad.Beckmann@amd.com code('#include "mem/protocol/AccessPermission.hh"') 4728086SBrad.Beckmann@amd.com 4738602Snilay@cs.wisc.edu if self.isMachineType: 4748602Snilay@cs.wisc.edu code('#include "base/misc.hh"') 4758602Snilay@cs.wisc.edu code('#include "mem/protocol/GenericMachineType.hh"') 4768602Snilay@cs.wisc.edu code('#include "mem/ruby/common/Address.hh"') 4778602Snilay@cs.wisc.edu code('struct MachineID;') 4788602Snilay@cs.wisc.edu 4798086SBrad.Beckmann@amd.com code(''' 4806657Snate@binkert.org 4817007Snate@binkert.org// Class definition 4826657Snate@binkert.org/** \\enum ${{self.c_ident}} 4836657Snate@binkert.org * \\brief ${{self.desc}} 4846657Snate@binkert.org */ 4856657Snate@binkert.orgenum ${{self.c_ident}} { 4866657Snate@binkert.org ${{self.c_ident}}_FIRST, 4876657Snate@binkert.org''') 4886657Snate@binkert.org 4896657Snate@binkert.org code.indent() 4906657Snate@binkert.org # For each field 4916657Snate@binkert.org for i,(ident,enum) in enumerate(self.enums.iteritems()): 4926657Snate@binkert.org desc = enum.get("desc", "No description avaliable") 4936862Sdrh5@cs.wisc.edu if i == 0: 4946862Sdrh5@cs.wisc.edu init = ' = %s_FIRST' % self.c_ident 4956862Sdrh5@cs.wisc.edu else: 4966862Sdrh5@cs.wisc.edu init = '' 4976657Snate@binkert.org code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4986657Snate@binkert.org code.dedent() 4996657Snate@binkert.org code(''' 5006657Snate@binkert.org ${{self.c_ident}}_NUM 5016657Snate@binkert.org}; 5027007Snate@binkert.org 5037007Snate@binkert.org// Code to convert from a string to the enumeration 5047002Snate@binkert.org${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 5057007Snate@binkert.org 5067007Snate@binkert.org// Code to convert state to a string 5077002Snate@binkert.orgstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 5087007Snate@binkert.org 5097007Snate@binkert.org// Code to increment an enumeration type 5106657Snate@binkert.org${{self.c_ident}} &operator++(${{self.c_ident}} &e); 5116657Snate@binkert.org''') 5126657Snate@binkert.org 5136657Snate@binkert.org # MachineType hack used to set the base component id for each Machine 5146657Snate@binkert.org if self.isMachineType: 5156657Snate@binkert.org code(''' 5166657Snate@binkert.orgint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 5176657Snate@binkert.orgMachineType ${{self.c_ident}}_from_base_level(int); 5186657Snate@binkert.orgint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 5196657Snate@binkert.orgint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 5206657Snate@binkert.org''') 5216657Snate@binkert.org 5226657Snate@binkert.org for enum in self.enums.itervalues(): 5238602Snilay@cs.wisc.edu if enum.ident == "DMA": 5248602Snilay@cs.wisc.edu code(''' 5258602Snilay@cs.wisc.eduMachineID map_Address_to_DMA(const Address &addr); 5268602Snilay@cs.wisc.edu''') 5278602Snilay@cs.wisc.edu code(''' 5288602Snilay@cs.wisc.edu 5298602Snilay@cs.wisc.eduMachineID get${{enum.ident}}MachineID(NodeID RubyNode); 5308602Snilay@cs.wisc.edu''') 5318602Snilay@cs.wisc.edu 5328602Snilay@cs.wisc.edu code(''' 5338602Snilay@cs.wisc.eduinline GenericMachineType 5348602Snilay@cs.wisc.eduConvertMachToGenericMach(MachineType machType) 5358602Snilay@cs.wisc.edu{ 5368602Snilay@cs.wisc.edu''') 5378602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 5388602Snilay@cs.wisc.edu code(''' 5398602Snilay@cs.wisc.edu if (machType == MachineType_${{enum.ident}}) 5408602Snilay@cs.wisc.edu return GenericMachineType_${{enum.ident}}; 5418602Snilay@cs.wisc.edu''') 5428602Snilay@cs.wisc.edu code(''' 5438602Snilay@cs.wisc.edu panic("cannot convert to a GenericMachineType"); 5448602Snilay@cs.wisc.edu} 5458602Snilay@cs.wisc.edu''') 5466657Snate@binkert.org 5478086SBrad.Beckmann@amd.com if self.isStateDecl: 5488086SBrad.Beckmann@amd.com code(''' 5498086SBrad.Beckmann@amd.com 5508086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5518086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); 5528086SBrad.Beckmann@amd.com 5538086SBrad.Beckmann@amd.com''') 5548086SBrad.Beckmann@amd.com 5556657Snate@binkert.org # Trailer 5566657Snate@binkert.org code(''' 5577002Snate@binkert.orgstd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 5586657Snate@binkert.org 5597007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 5606657Snate@binkert.org''') 5616657Snate@binkert.org 5626657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 5636657Snate@binkert.org 5646657Snate@binkert.org def printEnumCC(self, path): 5656999Snate@binkert.org code = self.symtab.codeFormatter() 5666657Snate@binkert.org code(''' 5676657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 5686657Snate@binkert.org * 5696657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 5706657Snate@binkert.org */ 5716657Snate@binkert.org 5727832Snate@binkert.org#include <cassert> 5737002Snate@binkert.org#include <iostream> 5747002Snate@binkert.org#include <string> 5757002Snate@binkert.org 5767805Snilay@cs.wisc.edu#include "base/misc.hh" 5776657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 5786657Snate@binkert.org 5797002Snate@binkert.orgusing namespace std; 5807002Snate@binkert.org 5816657Snate@binkert.org''') 5826657Snate@binkert.org 5838086SBrad.Beckmann@amd.com if self.isStateDecl: 5848086SBrad.Beckmann@amd.com code(''' 5858086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5868086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) 5878086SBrad.Beckmann@amd.com{ 5888086SBrad.Beckmann@amd.com switch(obj) { 5898086SBrad.Beckmann@amd.com''') 5908086SBrad.Beckmann@amd.com # For each case 5918086SBrad.Beckmann@amd.com code.indent() 5928086SBrad.Beckmann@amd.com for statePerm in self.statePermPairs: 5938086SBrad.Beckmann@amd.com code(' case ${{self.c_ident}}_${{statePerm[0]}}:') 5948086SBrad.Beckmann@amd.com code(' return AccessPermission_${{statePerm[1]}};') 5958086SBrad.Beckmann@amd.com code.dedent() 5968086SBrad.Beckmann@amd.com code (''' 5978086SBrad.Beckmann@amd.com default: 5988086SBrad.Beckmann@amd.com panic("Unknown state access permission converstion for ${{self.c_ident}}"); 5998086SBrad.Beckmann@amd.com } 6008086SBrad.Beckmann@amd.com} 6018086SBrad.Beckmann@amd.com 6028086SBrad.Beckmann@amd.com''') 6038086SBrad.Beckmann@amd.com 6046657Snate@binkert.org if self.isMachineType: 6056657Snate@binkert.org for enum in self.enums.itervalues(): 6066657Snate@binkert.org code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') 6078602Snilay@cs.wisc.edu code('#include "mem/ruby/system/MachineID.hh"') 6086657Snate@binkert.org 6096657Snate@binkert.org code(''' 6107007Snate@binkert.org// Code for output operator 6117007Snate@binkert.orgostream& 6127007Snate@binkert.orgoperator<<(ostream& out, const ${{self.c_ident}}& obj) 6136657Snate@binkert.org{ 6146657Snate@binkert.org out << ${{self.c_ident}}_to_string(obj); 6156657Snate@binkert.org out << flush; 6166657Snate@binkert.org return out; 6176657Snate@binkert.org} 6186657Snate@binkert.org 6197007Snate@binkert.org// Code to convert state to a string 6207007Snate@binkert.orgstring 6217007Snate@binkert.org${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 6226657Snate@binkert.org{ 6236657Snate@binkert.org switch(obj) { 6246657Snate@binkert.org''') 6256657Snate@binkert.org 6266657Snate@binkert.org # For each field 6276657Snate@binkert.org code.indent() 6286657Snate@binkert.org for enum in self.enums.itervalues(): 6296657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6306657Snate@binkert.org code(' return "${{enum.ident}}";') 6316657Snate@binkert.org code.dedent() 6326657Snate@binkert.org 6336657Snate@binkert.org # Trailer 6346657Snate@binkert.org code(''' 6356657Snate@binkert.org default: 6367805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6376657Snate@binkert.org } 6386657Snate@binkert.org} 6396657Snate@binkert.org 6407007Snate@binkert.org// Code to convert from a string to the enumeration 6417007Snate@binkert.org${{self.c_ident}} 6427007Snate@binkert.orgstring_to_${{self.c_ident}}(const string& str) 6436657Snate@binkert.org{ 6446657Snate@binkert.org''') 6456657Snate@binkert.org 6466657Snate@binkert.org # For each field 6477007Snate@binkert.org start = "" 6486657Snate@binkert.org code.indent() 6496657Snate@binkert.org for enum in self.enums.itervalues(): 6506657Snate@binkert.org code('${start}if (str == "${{enum.ident}}") {') 6516657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6527007Snate@binkert.org start = "} else " 6536657Snate@binkert.org code.dedent() 6546657Snate@binkert.org 6556657Snate@binkert.org code(''' 6566657Snate@binkert.org } else { 6577805Snilay@cs.wisc.edu panic("Invalid string conversion for %s, type ${{self.c_ident}}", str); 6586657Snate@binkert.org } 6596657Snate@binkert.org} 6606657Snate@binkert.org 6617007Snate@binkert.org// Code to increment an enumeration type 6627007Snate@binkert.org${{self.c_ident}}& 6637007Snate@binkert.orgoperator++(${{self.c_ident}}& e) 6647007Snate@binkert.org{ 6656657Snate@binkert.org assert(e < ${{self.c_ident}}_NUM); 6666657Snate@binkert.org return e = ${{self.c_ident}}(e+1); 6676657Snate@binkert.org} 6686657Snate@binkert.org''') 6696657Snate@binkert.org 6706657Snate@binkert.org # MachineType hack used to set the base level and number of 6716657Snate@binkert.org # components for each Machine 6726657Snate@binkert.org if self.isMachineType: 6736657Snate@binkert.org code(''' 6747007Snate@binkert.org/** \\brief returns the base vector index for each machine type to be 6757007Snate@binkert.org * used by NetDest 6766657Snate@binkert.org * 6776657Snate@binkert.org * \\return the base vector index for each machine type to be used by NetDest 6786657Snate@binkert.org * \\see NetDest.hh 6796657Snate@binkert.org */ 6807007Snate@binkert.orgint 6817007Snate@binkert.org${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 6826657Snate@binkert.org{ 6836657Snate@binkert.org switch(obj) { 6846657Snate@binkert.org''') 6856657Snate@binkert.org 6866657Snate@binkert.org # For each field 6876657Snate@binkert.org code.indent() 6886657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6896657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6906657Snate@binkert.org code(' return $i;') 6916657Snate@binkert.org code.dedent() 6926657Snate@binkert.org 6936657Snate@binkert.org # total num 6946657Snate@binkert.org code(''' 6956657Snate@binkert.org case ${{self.c_ident}}_NUM: 6966657Snate@binkert.org return ${{len(self.enums)}}; 6976657Snate@binkert.org 6986657Snate@binkert.org default: 6997805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7006657Snate@binkert.org } 7016657Snate@binkert.org} 7026657Snate@binkert.org 7036657Snate@binkert.org/** \\brief returns the machine type for each base vector index used by NetDest 7046657Snate@binkert.org * 7057007Snate@binkert.org * \\return the MachineType 7066657Snate@binkert.org */ 7077007Snate@binkert.orgMachineType 7087007Snate@binkert.org${{self.c_ident}}_from_base_level(int type) 7096657Snate@binkert.org{ 7106657Snate@binkert.org switch(type) { 7116657Snate@binkert.org''') 7126657Snate@binkert.org 7136657Snate@binkert.org # For each field 7146657Snate@binkert.org code.indent() 7156657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 7166657Snate@binkert.org code(' case $i:') 7176657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 7186657Snate@binkert.org code.dedent() 7196657Snate@binkert.org 7206657Snate@binkert.org # Trailer 7216657Snate@binkert.org code(''' 7226657Snate@binkert.org default: 7237805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7246657Snate@binkert.org } 7256657Snate@binkert.org} 7266657Snate@binkert.org 7276657Snate@binkert.org/** \\brief The return value indicates the number of components created 7286657Snate@binkert.org * before a particular machine\'s components 7296657Snate@binkert.org * 7306657Snate@binkert.org * \\return the base number of components for each machine 7316657Snate@binkert.org */ 7327007Snate@binkert.orgint 7337007Snate@binkert.org${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 7346657Snate@binkert.org{ 7356657Snate@binkert.org int base = 0; 7366657Snate@binkert.org switch(obj) { 7376657Snate@binkert.org''') 7386657Snate@binkert.org 7396657Snate@binkert.org # For each field 7406657Snate@binkert.org code.indent() 7416657Snate@binkert.org code(' case ${{self.c_ident}}_NUM:') 7426657Snate@binkert.org for enum in reversed(self.enums.values()): 7436657Snate@binkert.org code(' base += ${{enum.ident}}_Controller::getNumControllers();') 7446657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 7456657Snate@binkert.org code(' break;') 7466657Snate@binkert.org code.dedent() 7476657Snate@binkert.org 7486657Snate@binkert.org code(''' 7496657Snate@binkert.org default: 7507805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7516657Snate@binkert.org } 7526657Snate@binkert.org 7536657Snate@binkert.org return base; 7546657Snate@binkert.org} 7556657Snate@binkert.org 7566657Snate@binkert.org/** \\brief returns the total number of components for each machine 7576657Snate@binkert.org * \\return the total number of components for each machine 7586657Snate@binkert.org */ 7597007Snate@binkert.orgint 7607007Snate@binkert.org${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 7616657Snate@binkert.org{ 7626657Snate@binkert.org switch(obj) { 7636657Snate@binkert.org''') 7646657Snate@binkert.org 7656657Snate@binkert.org # For each field 7666657Snate@binkert.org for enum in self.enums.itervalues(): 7676657Snate@binkert.org code(''' 7686657Snate@binkert.org case ${{self.c_ident}}_${{enum.ident}}: 7696657Snate@binkert.org return ${{enum.ident}}_Controller::getNumControllers(); 7706657Snate@binkert.org''') 7716657Snate@binkert.org 7726657Snate@binkert.org # total num 7736657Snate@binkert.org code(''' 7746657Snate@binkert.org case ${{self.c_ident}}_NUM: 7756657Snate@binkert.org default: 7767805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7776657Snate@binkert.org } 7786657Snate@binkert.org} 7796657Snate@binkert.org''') 7806657Snate@binkert.org 7818602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 7828602Snilay@cs.wisc.edu if enum.ident == "DMA": 7838602Snilay@cs.wisc.edu code(''' 7848602Snilay@cs.wisc.eduMachineID 7858602Snilay@cs.wisc.edumap_Address_to_DMA(const Address &addr) 7868602Snilay@cs.wisc.edu{ 7878602Snilay@cs.wisc.edu MachineID dma = {MachineType_DMA, 0}; 7888602Snilay@cs.wisc.edu return dma; 7898602Snilay@cs.wisc.edu} 7908602Snilay@cs.wisc.edu''') 7918602Snilay@cs.wisc.edu 7928602Snilay@cs.wisc.edu code(''' 7938602Snilay@cs.wisc.edu 7948602Snilay@cs.wisc.eduMachineID 7958602Snilay@cs.wisc.eduget${{enum.ident}}MachineID(NodeID RubyNode) 7968602Snilay@cs.wisc.edu{ 7978602Snilay@cs.wisc.edu MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; 7988602Snilay@cs.wisc.edu return mach; 7998602Snilay@cs.wisc.edu} 8008602Snilay@cs.wisc.edu''') 8018602Snilay@cs.wisc.edu 8026657Snate@binkert.org # Write the file 8036657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 8046657Snate@binkert.org 8056657Snate@binkert.org__all__ = [ "Type" ] 806