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 2813672Sandreas.sandberg@arm.comfrom collections import OrderedDict 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 4511283Santhony.gutierrez@amd.com self.primary = False 466657Snate@binkert.org 476657Snate@binkert.orgclass Type(Symbol): 486657Snate@binkert.org def __init__(self, table, ident, location, pairs, machine=None): 496657Snate@binkert.org super(Type, self).__init__(table, ident, location, pairs) 506657Snate@binkert.org self.c_ident = ident 516882SBrad.Beckmann@amd.com self.abstract_ident = "" 526657Snate@binkert.org if machine: 536657Snate@binkert.org if self.isExternal or self.isPrimitive: 546657Snate@binkert.org if "external_name" in self: 556657Snate@binkert.org self.c_ident = self["external_name"] 566657Snate@binkert.org else: 576657Snate@binkert.org # Append with machine name 586657Snate@binkert.org self.c_ident = "%s_%s" % (machine, ident) 596657Snate@binkert.org 606657Snate@binkert.org self.pairs.setdefault("desc", "No description avaliable") 616657Snate@binkert.org 626657Snate@binkert.org # check for interface that this Type implements 636657Snate@binkert.org if "interface" in self: 646657Snate@binkert.org interface = self["interface"] 6510895Snilay@cs.wisc.edu if interface in ("Message"): 666657Snate@binkert.org self["message"] = "yes" 676657Snate@binkert.org 686657Snate@binkert.org # FIXME - all of the following id comparisons are fragile hacks 6910228Snilay@cs.wisc.edu if self.ident in ("CacheMemory"): 706657Snate@binkert.org self["cache"] = "yes" 716657Snate@binkert.org 7210228Snilay@cs.wisc.edu if self.ident in ("TBETable"): 736657Snate@binkert.org self["tbe"] = "yes" 746657Snate@binkert.org 756657Snate@binkert.org if self.ident == "TimerTable": 766657Snate@binkert.org self["timer"] = "yes" 776657Snate@binkert.org 786657Snate@binkert.org if self.ident == "DirectoryMemory": 796657Snate@binkert.org self["dir"] = "yes" 806657Snate@binkert.org 816657Snate@binkert.org if self.ident == "PersistentTable": 826657Snate@binkert.org self["persistent"] = "yes" 836657Snate@binkert.org 846657Snate@binkert.org if self.ident == "Prefetcher": 856657Snate@binkert.org self["prefetcher"] = "yes" 866657Snate@binkert.org 876657Snate@binkert.org self.isMachineType = (ident == "MachineType") 886657Snate@binkert.org 898086SBrad.Beckmann@amd.com self.isStateDecl = ("state_decl" in self) 908086SBrad.Beckmann@amd.com self.statePermPairs = [] 918086SBrad.Beckmann@amd.com 9213672Sandreas.sandberg@arm.com self.data_members = OrderedDict() 936657Snate@binkert.org self.methods = {} 9413672Sandreas.sandberg@arm.com self.enums = OrderedDict() 956657Snate@binkert.org 966657Snate@binkert.org @property 976657Snate@binkert.org def isPrimitive(self): 986657Snate@binkert.org return "primitive" in self 9910895Snilay@cs.wisc.edu 1006657Snate@binkert.org @property 1016657Snate@binkert.org def isMessage(self): 1026657Snate@binkert.org return "message" in self 1036657Snate@binkert.org @property 1046657Snate@binkert.org def isBuffer(self): 1056657Snate@binkert.org return "buffer" in self 1066657Snate@binkert.org @property 1076657Snate@binkert.org def isInPort(self): 1086657Snate@binkert.org return "inport" in self 1096657Snate@binkert.org @property 1106657Snate@binkert.org def isOutPort(self): 1116657Snate@binkert.org return "outport" in self 1126657Snate@binkert.org @property 1136657Snate@binkert.org def isEnumeration(self): 1146657Snate@binkert.org return "enumeration" in self 1156657Snate@binkert.org @property 1166657Snate@binkert.org def isExternal(self): 1176657Snate@binkert.org return "external" in self 1186657Snate@binkert.org @property 1196657Snate@binkert.org def isGlobal(self): 1206657Snate@binkert.org return "global" in self 1216657Snate@binkert.org @property 1226657Snate@binkert.org def isInterface(self): 1236657Snate@binkert.org return "interface" in self 1246657Snate@binkert.org 1256657Snate@binkert.org # Return false on error 1269298Snilay@cs.wisc.edu def addDataMember(self, ident, type, pairs, init_code): 1276657Snate@binkert.org if ident in self.data_members: 1286657Snate@binkert.org return False 1296657Snate@binkert.org 13011117Snilay@cs.wisc.edu member = DataMember(self.symtab, ident, self.location, type, 13111117Snilay@cs.wisc.edu "m_%s" % ident, pairs, None, init_code) 13211117Snilay@cs.wisc.edu 1336657Snate@binkert.org self.data_members[ident] = member 13411117Snilay@cs.wisc.edu self.symtab.registerSym(ident, member) 1356657Snate@binkert.org return True 1366657Snate@binkert.org 1376657Snate@binkert.org def dataMemberType(self, ident): 1386657Snate@binkert.org return self.data_members[ident].type 1396657Snate@binkert.org 1406657Snate@binkert.org def methodId(self, name, param_type_vec): 1416657Snate@binkert.org return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ]) 1426657Snate@binkert.org 1436882SBrad.Beckmann@amd.com def methodIdAbstract(self, name, param_type_vec): 1446882SBrad.Beckmann@amd.com return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ]) 1456882SBrad.Beckmann@amd.com 1468086SBrad.Beckmann@amd.com def statePermPairAdd(self, state_name, perm_name): 1478086SBrad.Beckmann@amd.com self.statePermPairs.append([state_name, perm_name]) 1488086SBrad.Beckmann@amd.com 14910307Snilay@cs.wisc.edu def addFunc(self, func): 15010307Snilay@cs.wisc.edu ident = self.methodId(func.ident, func.param_types) 1516657Snate@binkert.org if ident in self.methods: 1526657Snate@binkert.org return False 1536657Snate@binkert.org 15410307Snilay@cs.wisc.edu self.methods[ident] = func 1559298Snilay@cs.wisc.edu return True 1569298Snilay@cs.wisc.edu 1579298Snilay@cs.wisc.edu def addEnum(self, ident, pairs): 1586657Snate@binkert.org if ident in self.enums: 1596657Snate@binkert.org return False 1606657Snate@binkert.org 1616657Snate@binkert.org self.enums[ident] = Enumeration(ident, pairs) 1626657Snate@binkert.org 1636657Snate@binkert.org # Add default 1646657Snate@binkert.org if "default" not in self: 1656657Snate@binkert.org self["default"] = "%s_NUM" % self.c_ident 1666657Snate@binkert.org 1676657Snate@binkert.org return True 1686657Snate@binkert.org 16911283Santhony.gutierrez@amd.com ## Used to check if an enum has been already used and therefore 17011283Santhony.gutierrez@amd.com ## should not be used again. 17111283Santhony.gutierrez@amd.com def checkEnum(self, ident): 17211283Santhony.gutierrez@amd.com if ident in self.enums and not self.enums[ident].primary: 17311283Santhony.gutierrez@amd.com self.enums[ident].primary = True 17411283Santhony.gutierrez@amd.com return True 17511283Santhony.gutierrez@amd.com return False 17611283Santhony.gutierrez@amd.com 1779219Spower.jg@gmail.com def writeCodeFiles(self, path, includes): 1786657Snate@binkert.org if self.isExternal: 1796657Snate@binkert.org # Do nothing 1806657Snate@binkert.org pass 1816657Snate@binkert.org elif self.isEnumeration: 1826657Snate@binkert.org self.printEnumHH(path) 1836657Snate@binkert.org self.printEnumCC(path) 1846657Snate@binkert.org else: 1856657Snate@binkert.org # User defined structs and messages 1866657Snate@binkert.org self.printTypeHH(path) 1876657Snate@binkert.org self.printTypeCC(path) 1886657Snate@binkert.org 1896657Snate@binkert.org def printTypeHH(self, path): 1906999Snate@binkert.org code = self.symtab.codeFormatter() 1916657Snate@binkert.org code(''' 1926657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 1936657Snate@binkert.org * 1946657Snate@binkert.org * 1956657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 1966657Snate@binkert.org */ 1976657Snate@binkert.org 1987007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 1997007Snate@binkert.org#define __${{self.c_ident}}_HH__ 2006657Snate@binkert.org 2017002Snate@binkert.org#include <iostream> 2027002Snate@binkert.org 2039466Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" 20414184Sgabeblack@google.com 2056657Snate@binkert.org''') 2066657Snate@binkert.org 2076657Snate@binkert.org for dm in self.data_members.values(): 2086657Snate@binkert.org if not dm.type.isPrimitive: 20914184Sgabeblack@google.com code('#include "mem/ruby/protocol/$0.hh"', dm.type.c_ident) 2106657Snate@binkert.org 2116657Snate@binkert.org parent = "" 2126657Snate@binkert.org if "interface" in self: 21314184Sgabeblack@google.com code('#include "mem/ruby/protocol/$0.hh"', self["interface"]) 2146657Snate@binkert.org parent = " : public %s" % self["interface"] 2156657Snate@binkert.org 2166657Snate@binkert.org code(''' 2177007Snate@binkert.org$klass ${{self.c_ident}}$parent 2187007Snate@binkert.org{ 2196657Snate@binkert.org public: 2209466Snilay@cs.wisc.edu ${{self.c_ident}} 2216657Snate@binkert.org''', klass="class") 2226657Snate@binkert.org 2239466Snilay@cs.wisc.edu if self.isMessage: 2249508Snilay@cs.wisc.edu code('(Tick curTime) : %s(curTime) {' % self["interface"]) 2259466Snilay@cs.wisc.edu else: 2269466Snilay@cs.wisc.edu code('()\n\t\t{') 2279466Snilay@cs.wisc.edu 2286657Snate@binkert.org code.indent() 2296657Snate@binkert.org if not self.isGlobal: 2306657Snate@binkert.org code.indent() 2316657Snate@binkert.org for dm in self.data_members.values(): 2326657Snate@binkert.org ident = dm.ident 2336657Snate@binkert.org if "default" in dm: 2346657Snate@binkert.org # look for default value 2356657Snate@binkert.org code('m_$ident = ${{dm["default"]}}; // default for this field') 2366657Snate@binkert.org elif "default" in dm.type: 2376657Snate@binkert.org # Look for the type default 2386657Snate@binkert.org tid = dm.type.c_ident 2396657Snate@binkert.org code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') 2406657Snate@binkert.org else: 2416657Snate@binkert.org code('// m_$ident has no default') 2426657Snate@binkert.org code.dedent() 2436657Snate@binkert.org code('}') 2446657Snate@binkert.org 2457453Snate@binkert.org # ******** Copy constructor ******** 2467453Snate@binkert.org if not self.isGlobal: 2477453Snate@binkert.org code('${{self.c_ident}}(const ${{self.c_ident}}&other)') 2487453Snate@binkert.org 2497453Snate@binkert.org # Call superclass constructor 2507453Snate@binkert.org if "interface" in self: 2517453Snate@binkert.org code(' : ${{self["interface"]}}(other)') 2527453Snate@binkert.org 2537453Snate@binkert.org code('{') 2547453Snate@binkert.org code.indent() 2557453Snate@binkert.org 2567453Snate@binkert.org for dm in self.data_members.values(): 2577453Snate@binkert.org code('m_${{dm.ident}} = other.m_${{dm.ident}};') 2587453Snate@binkert.org 2597453Snate@binkert.org code.dedent() 2607453Snate@binkert.org code('}') 2617453Snate@binkert.org 2626657Snate@binkert.org # ******** Full init constructor ******** 2636657Snate@binkert.org if not self.isGlobal: 2646657Snate@binkert.org params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ 2656657Snate@binkert.org for dm in self.data_members.itervalues() ] 2669466Snilay@cs.wisc.edu params = ', '.join(params) 2676657Snate@binkert.org 2689466Snilay@cs.wisc.edu if self.isMessage: 2699508Snilay@cs.wisc.edu params = "const Tick curTime, " + params 2709466Snilay@cs.wisc.edu 2716657Snate@binkert.org code('${{self.c_ident}}($params)') 2726657Snate@binkert.org 2736657Snate@binkert.org # Call superclass constructor 2746657Snate@binkert.org if "interface" in self: 2759466Snilay@cs.wisc.edu if self.isMessage: 2769466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}(curTime)') 2779466Snilay@cs.wisc.edu else: 2789466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}()') 2796657Snate@binkert.org 2806657Snate@binkert.org code('{') 2816657Snate@binkert.org code.indent() 2826657Snate@binkert.org for dm in self.data_members.values(): 2836657Snate@binkert.org code('m_${{dm.ident}} = local_${{dm.ident}};') 2846657Snate@binkert.org 2856657Snate@binkert.org code.dedent() 2866657Snate@binkert.org code('}') 2876657Snate@binkert.org 2889466Snilay@cs.wisc.edu # create a clone member 28910472Sandreas.hansson@arm.com if self.isMessage: 29010472Sandreas.hansson@arm.com code(''' 29110472Sandreas.hansson@arm.comMsgPtr 29210472Sandreas.hansson@arm.comclone() const 29310472Sandreas.hansson@arm.com{ 29410472Sandreas.hansson@arm.com return std::shared_ptr<Message>(new ${{self.c_ident}}(*this)); 29510472Sandreas.hansson@arm.com} 29610472Sandreas.hansson@arm.com''') 29710472Sandreas.hansson@arm.com else: 29810472Sandreas.hansson@arm.com code(''' 2997453Snate@binkert.org${{self.c_ident}}* 3007007Snate@binkert.orgclone() const 3017007Snate@binkert.org{ 3027453Snate@binkert.org return new ${{self.c_ident}}(*this); 3037007Snate@binkert.org} 3046657Snate@binkert.org''') 3056657Snate@binkert.org 3066657Snate@binkert.org if not self.isGlobal: 3076657Snate@binkert.org # const Get methods for each field 3086657Snate@binkert.org code('// Const accessors methods for each field') 3096657Snate@binkert.org for dm in self.data_members.values(): 3106657Snate@binkert.org code(''' 3116657Snate@binkert.org/** \\brief Const accessor method for ${{dm.ident}} field. 3126657Snate@binkert.org * \\return ${{dm.ident}} field 3136657Snate@binkert.org */ 3147007Snate@binkert.orgconst ${{dm.type.c_ident}}& 3157007Snate@binkert.orgget${{dm.ident}}() const 3167007Snate@binkert.org{ 3177007Snate@binkert.org return m_${{dm.ident}}; 3187007Snate@binkert.org} 3196657Snate@binkert.org''') 3206657Snate@binkert.org 3216657Snate@binkert.org # Non-const Get methods for each field 3226657Snate@binkert.org code('// Non const Accessors methods for each field') 3236657Snate@binkert.org for dm in self.data_members.values(): 3246657Snate@binkert.org code(''' 3256657Snate@binkert.org/** \\brief Non-const accessor method for ${{dm.ident}} field. 3266657Snate@binkert.org * \\return ${{dm.ident}} field 3276657Snate@binkert.org */ 3287007Snate@binkert.org${{dm.type.c_ident}}& 3297007Snate@binkert.orgget${{dm.ident}}() 3307007Snate@binkert.org{ 3317007Snate@binkert.org return m_${{dm.ident}}; 3327007Snate@binkert.org} 3336657Snate@binkert.org''') 3346657Snate@binkert.org 3356657Snate@binkert.org #Set methods for each field 3366657Snate@binkert.org code('// Mutator methods for each field') 3376657Snate@binkert.org for dm in self.data_members.values(): 3386657Snate@binkert.org code(''' 3396657Snate@binkert.org/** \\brief Mutator method for ${{dm.ident}} field */ 3407007Snate@binkert.orgvoid 3417007Snate@binkert.orgset${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) 3427007Snate@binkert.org{ 3437007Snate@binkert.org m_${{dm.ident}} = local_${{dm.ident}}; 3447007Snate@binkert.org} 3456657Snate@binkert.org''') 3466657Snate@binkert.org 3477002Snate@binkert.org code('void print(std::ostream& out) const;') 3486657Snate@binkert.org code.dedent() 3496657Snate@binkert.org code(' //private:') 3506657Snate@binkert.org code.indent() 3516657Snate@binkert.org 3526657Snate@binkert.org # Data members for each field 3536657Snate@binkert.org for dm in self.data_members.values(): 3546657Snate@binkert.org if "abstract" not in dm: 3556657Snate@binkert.org const = "" 3566657Snate@binkert.org init = "" 3576657Snate@binkert.org 3586657Snate@binkert.org # global structure 3596657Snate@binkert.org if self.isGlobal: 3606657Snate@binkert.org const = "static const " 3616657Snate@binkert.org 3626657Snate@binkert.org # init value 3636657Snate@binkert.org if dm.init_code: 3646657Snate@binkert.org # only global structure can have init value here 3656657Snate@binkert.org assert self.isGlobal 3666657Snate@binkert.org init = " = %s" % (dm.init_code) 3676657Snate@binkert.org 3686657Snate@binkert.org if "desc" in dm: 3697007Snate@binkert.org code('/** ${{dm["desc"]}} */') 3706657Snate@binkert.org 3717007Snate@binkert.org code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;') 3726657Snate@binkert.org 37310307Snilay@cs.wisc.edu # Prototypes for methods defined for the Type 37410307Snilay@cs.wisc.edu for item in self.methods: 37510307Snilay@cs.wisc.edu proto = self.methods[item].prototype 3769298Snilay@cs.wisc.edu if proto: 3779298Snilay@cs.wisc.edu code('$proto') 3789298Snilay@cs.wisc.edu 3796657Snate@binkert.org code.dedent() 3806657Snate@binkert.org code('};') 3816657Snate@binkert.org 3826657Snate@binkert.org code(''' 3837055Snate@binkert.orginline std::ostream& 3847007Snate@binkert.orgoperator<<(std::ostream& out, const ${{self.c_ident}}& obj) 3856657Snate@binkert.org{ 3866657Snate@binkert.org obj.print(out); 3877002Snate@binkert.org out << std::flush; 3886657Snate@binkert.org return out; 3896657Snate@binkert.org} 3906657Snate@binkert.org 3917007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 3926657Snate@binkert.org''') 3936657Snate@binkert.org 3946657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 3956657Snate@binkert.org 3966657Snate@binkert.org def printTypeCC(self, path): 3976999Snate@binkert.org code = self.symtab.codeFormatter() 3986657Snate@binkert.org 3996657Snate@binkert.org code(''' 4006657Snate@binkert.org/** \\file ${{self.c_ident}}.cc 4016657Snate@binkert.org * 4026657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4036657Snate@binkert.org */ 4046657Snate@binkert.org 4057002Snate@binkert.org#include <iostream> 40610472Sandreas.hansson@arm.com#include <memory> 4077002Snate@binkert.org 40814184Sgabeblack@google.com#include "mem/ruby/protocol/${{self.c_ident}}.hh" 40911108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh" 4107002Snate@binkert.org 4117002Snate@binkert.orgusing namespace std; 4126657Snate@binkert.org''') 4136657Snate@binkert.org 4146657Snate@binkert.org code(''' 4156657Snate@binkert.org/** \\brief Print the state of this object */ 4167007Snate@binkert.orgvoid 4177007Snate@binkert.org${{self.c_ident}}::print(ostream& out) const 4186657Snate@binkert.org{ 4196657Snate@binkert.org out << "[${{self.c_ident}}: "; 4206657Snate@binkert.org''') 4216657Snate@binkert.org 4226657Snate@binkert.org # For each field 4236657Snate@binkert.org code.indent() 4246657Snate@binkert.org for dm in self.data_members.values(): 42511118Snilay@cs.wisc.edu if dm.type.c_ident == "Addr": 42611118Snilay@cs.wisc.edu code(''' 42711118Snilay@cs.wisc.eduout << "${{dm.ident}} = " << printAddress(m_${{dm.ident}}) << " ";''') 42811118Snilay@cs.wisc.edu else: 42911118Snilay@cs.wisc.edu code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') 4306657Snate@binkert.org 4316657Snate@binkert.org code.dedent() 4326657Snate@binkert.org 4336657Snate@binkert.org # Trailer 4346657Snate@binkert.org code(''' 4356657Snate@binkert.org out << "]"; 4366657Snate@binkert.org}''') 4376657Snate@binkert.org 43810307Snilay@cs.wisc.edu # print the code for the methods in the type 43910307Snilay@cs.wisc.edu for item in self.methods: 44010307Snilay@cs.wisc.edu code(self.methods[item].generateCode()) 4419298Snilay@cs.wisc.edu 4426657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 4436657Snate@binkert.org 4446657Snate@binkert.org def printEnumHH(self, path): 4456999Snate@binkert.org code = self.symtab.codeFormatter() 4466657Snate@binkert.org code(''' 4476657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 4486657Snate@binkert.org * 4496657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4506657Snate@binkert.org */ 4517007Snate@binkert.org 4527007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 4537007Snate@binkert.org#define __${{self.c_ident}}_HH__ 4546657Snate@binkert.org 4557002Snate@binkert.org#include <iostream> 4567002Snate@binkert.org#include <string> 4577002Snate@binkert.org 4588086SBrad.Beckmann@amd.com''') 4598086SBrad.Beckmann@amd.com if self.isStateDecl: 46014184Sgabeblack@google.com code('#include "mem/ruby/protocol/AccessPermission.hh"') 4618086SBrad.Beckmann@amd.com 4628602Snilay@cs.wisc.edu if self.isMachineType: 46312065Snikos.nikoleris@arm.com code('#include <functional>') 46412334Sgabeblack@google.com code('#include "base/logging.hh"') 4658602Snilay@cs.wisc.edu code('#include "mem/ruby/common/Address.hh"') 46611025Snilay@cs.wisc.edu code('#include "mem/ruby/common/TypeDefines.hh"') 4678602Snilay@cs.wisc.edu code('struct MachineID;') 4688602Snilay@cs.wisc.edu 4698086SBrad.Beckmann@amd.com code(''' 4706657Snate@binkert.org 4717007Snate@binkert.org// Class definition 4726657Snate@binkert.org/** \\enum ${{self.c_ident}} 4736657Snate@binkert.org * \\brief ${{self.desc}} 4746657Snate@binkert.org */ 4756657Snate@binkert.orgenum ${{self.c_ident}} { 4766657Snate@binkert.org ${{self.c_ident}}_FIRST, 4776657Snate@binkert.org''') 4786657Snate@binkert.org 4796657Snate@binkert.org code.indent() 4806657Snate@binkert.org # For each field 4816657Snate@binkert.org for i,(ident,enum) in enumerate(self.enums.iteritems()): 4826657Snate@binkert.org desc = enum.get("desc", "No description avaliable") 48310917Sbrandon.potter@amd.com if i == 0: 48410917Sbrandon.potter@amd.com init = ' = %s_FIRST' % self.c_ident 4856862Sdrh5@cs.wisc.edu else: 4866862Sdrh5@cs.wisc.edu init = '' 4876657Snate@binkert.org code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4886657Snate@binkert.org code.dedent() 4896657Snate@binkert.org code(''' 4906657Snate@binkert.org ${{self.c_ident}}_NUM 4916657Snate@binkert.org}; 4927007Snate@binkert.org 4937007Snate@binkert.org// Code to convert from a string to the enumeration 4947002Snate@binkert.org${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 4957007Snate@binkert.org 4967007Snate@binkert.org// Code to convert state to a string 4977002Snate@binkert.orgstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 4987007Snate@binkert.org 4997007Snate@binkert.org// Code to increment an enumeration type 5006657Snate@binkert.org${{self.c_ident}} &operator++(${{self.c_ident}} &e); 5016657Snate@binkert.org''') 5026657Snate@binkert.org 50312065Snikos.nikoleris@arm.com if self.isMachineType: 50412065Snikos.nikoleris@arm.com code(''' 50512065Snikos.nikoleris@arm.com 50612065Snikos.nikoleris@arm.com// define a hash function for the MachineType class 50712065Snikos.nikoleris@arm.comnamespace std { 50812065Snikos.nikoleris@arm.comtemplate<> 50912065Snikos.nikoleris@arm.comstruct hash<MachineType> { 51012065Snikos.nikoleris@arm.com std::size_t operator()(const MachineType &mtype) const { 51112065Snikos.nikoleris@arm.com return hash<size_t>()(static_cast<size_t>(mtype)); 51212065Snikos.nikoleris@arm.com } 51312065Snikos.nikoleris@arm.com}; 51412065Snikos.nikoleris@arm.com} 51512065Snikos.nikoleris@arm.com 51612065Snikos.nikoleris@arm.com''') 5176657Snate@binkert.org # MachineType hack used to set the base component id for each Machine 5186657Snate@binkert.org if self.isMachineType: 5196657Snate@binkert.org code(''' 5206657Snate@binkert.orgint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 5216657Snate@binkert.orgMachineType ${{self.c_ident}}_from_base_level(int); 5226657Snate@binkert.orgint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 5236657Snate@binkert.orgint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 5246657Snate@binkert.org''') 5256657Snate@binkert.org 5266657Snate@binkert.org for enum in self.enums.itervalues(): 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 5328086SBrad.Beckmann@amd.com if self.isStateDecl: 5338086SBrad.Beckmann@amd.com code(''' 5348086SBrad.Beckmann@amd.com 5358086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5368086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); 5378086SBrad.Beckmann@amd.com 5388086SBrad.Beckmann@amd.com''') 5398086SBrad.Beckmann@amd.com 5406657Snate@binkert.org # Trailer 5416657Snate@binkert.org code(''' 5427002Snate@binkert.orgstd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 5436657Snate@binkert.org 5447007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 5456657Snate@binkert.org''') 5466657Snate@binkert.org 5476657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 5486657Snate@binkert.org 5496657Snate@binkert.org def printEnumCC(self, path): 5506999Snate@binkert.org code = self.symtab.codeFormatter() 5516657Snate@binkert.org code(''' 5526657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 5536657Snate@binkert.org * 5546657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 5556657Snate@binkert.org */ 5566657Snate@binkert.org 5577832Snate@binkert.org#include <cassert> 5587002Snate@binkert.org#include <iostream> 5597002Snate@binkert.org#include <string> 5607002Snate@binkert.org 56112334Sgabeblack@google.com#include "base/logging.hh" 56214184Sgabeblack@google.com#include "mem/ruby/protocol/${{self.c_ident}}.hh" 5636657Snate@binkert.org 5647002Snate@binkert.orgusing namespace std; 5657002Snate@binkert.org 5666657Snate@binkert.org''') 5676657Snate@binkert.org 5688086SBrad.Beckmann@amd.com if self.isStateDecl: 5698086SBrad.Beckmann@amd.com code(''' 5708086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5718086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) 5728086SBrad.Beckmann@amd.com{ 5738086SBrad.Beckmann@amd.com switch(obj) { 5748086SBrad.Beckmann@amd.com''') 5758086SBrad.Beckmann@amd.com # For each case 5768086SBrad.Beckmann@amd.com code.indent() 5778086SBrad.Beckmann@amd.com for statePerm in self.statePermPairs: 5788086SBrad.Beckmann@amd.com code(' case ${{self.c_ident}}_${{statePerm[0]}}:') 5798086SBrad.Beckmann@amd.com code(' return AccessPermission_${{statePerm[1]}};') 5808086SBrad.Beckmann@amd.com code.dedent() 5818086SBrad.Beckmann@amd.com code (''' 5828086SBrad.Beckmann@amd.com default: 5838086SBrad.Beckmann@amd.com panic("Unknown state access permission converstion for ${{self.c_ident}}"); 5848086SBrad.Beckmann@amd.com } 5858086SBrad.Beckmann@amd.com} 5868086SBrad.Beckmann@amd.com 5878086SBrad.Beckmann@amd.com''') 5888086SBrad.Beckmann@amd.com 5896657Snate@binkert.org if self.isMachineType: 5906657Snate@binkert.org for enum in self.enums.itervalues(): 59111283Santhony.gutierrez@amd.com if enum.primary: 59214184Sgabeblack@google.com code('#include "mem/ruby/protocol/${{enum.ident}}' 59314184Sgabeblack@google.com '_Controller.hh"') 59410301Snilay@cs.wisc.edu code('#include "mem/ruby/common/MachineID.hh"') 5956657Snate@binkert.org 5966657Snate@binkert.org code(''' 5977007Snate@binkert.org// Code for output operator 5987007Snate@binkert.orgostream& 5997007Snate@binkert.orgoperator<<(ostream& out, const ${{self.c_ident}}& obj) 6006657Snate@binkert.org{ 6016657Snate@binkert.org out << ${{self.c_ident}}_to_string(obj); 6026657Snate@binkert.org out << flush; 6036657Snate@binkert.org return out; 6046657Snate@binkert.org} 6056657Snate@binkert.org 6067007Snate@binkert.org// Code to convert state to a string 6077007Snate@binkert.orgstring 6087007Snate@binkert.org${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 6096657Snate@binkert.org{ 6106657Snate@binkert.org switch(obj) { 6116657Snate@binkert.org''') 6126657Snate@binkert.org 6136657Snate@binkert.org # For each field 6146657Snate@binkert.org code.indent() 6156657Snate@binkert.org for enum in self.enums.itervalues(): 6166657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6176657Snate@binkert.org code(' return "${{enum.ident}}";') 6186657Snate@binkert.org code.dedent() 6196657Snate@binkert.org 6206657Snate@binkert.org # Trailer 6216657Snate@binkert.org code(''' 6226657Snate@binkert.org default: 6237805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6246657Snate@binkert.org } 6256657Snate@binkert.org} 6266657Snate@binkert.org 6277007Snate@binkert.org// Code to convert from a string to the enumeration 6287007Snate@binkert.org${{self.c_ident}} 6297007Snate@binkert.orgstring_to_${{self.c_ident}}(const string& str) 6306657Snate@binkert.org{ 6316657Snate@binkert.org''') 6326657Snate@binkert.org 6336657Snate@binkert.org # For each field 6347007Snate@binkert.org start = "" 6356657Snate@binkert.org code.indent() 6366657Snate@binkert.org for enum in self.enums.itervalues(): 6376657Snate@binkert.org code('${start}if (str == "${{enum.ident}}") {') 6386657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6397007Snate@binkert.org start = "} else " 6406657Snate@binkert.org code.dedent() 6416657Snate@binkert.org 6426657Snate@binkert.org code(''' 6436657Snate@binkert.org } else { 6447805Snilay@cs.wisc.edu panic("Invalid string conversion for %s, type ${{self.c_ident}}", str); 6456657Snate@binkert.org } 6466657Snate@binkert.org} 6476657Snate@binkert.org 6487007Snate@binkert.org// Code to increment an enumeration type 6497007Snate@binkert.org${{self.c_ident}}& 6507007Snate@binkert.orgoperator++(${{self.c_ident}}& e) 6517007Snate@binkert.org{ 6526657Snate@binkert.org assert(e < ${{self.c_ident}}_NUM); 6536657Snate@binkert.org return e = ${{self.c_ident}}(e+1); 6546657Snate@binkert.org} 6556657Snate@binkert.org''') 6566657Snate@binkert.org 6576657Snate@binkert.org # MachineType hack used to set the base level and number of 6586657Snate@binkert.org # components for each Machine 6596657Snate@binkert.org if self.isMachineType: 6606657Snate@binkert.org code(''' 6617007Snate@binkert.org/** \\brief returns the base vector index for each machine type to be 6627007Snate@binkert.org * used by NetDest 6636657Snate@binkert.org * 6646657Snate@binkert.org * \\return the base vector index for each machine type to be used by NetDest 6656657Snate@binkert.org * \\see NetDest.hh 6666657Snate@binkert.org */ 6677007Snate@binkert.orgint 6687007Snate@binkert.org${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 6696657Snate@binkert.org{ 6706657Snate@binkert.org switch(obj) { 6716657Snate@binkert.org''') 6726657Snate@binkert.org 6736657Snate@binkert.org # For each field 6746657Snate@binkert.org code.indent() 6756657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6766657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6776657Snate@binkert.org code(' return $i;') 6786657Snate@binkert.org code.dedent() 6796657Snate@binkert.org 6806657Snate@binkert.org # total num 6816657Snate@binkert.org code(''' 6826657Snate@binkert.org case ${{self.c_ident}}_NUM: 6836657Snate@binkert.org return ${{len(self.enums)}}; 6846657Snate@binkert.org 6856657Snate@binkert.org default: 6867805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6876657Snate@binkert.org } 6886657Snate@binkert.org} 6896657Snate@binkert.org 6906657Snate@binkert.org/** \\brief returns the machine type for each base vector index used by NetDest 6916657Snate@binkert.org * 6927007Snate@binkert.org * \\return the MachineType 6936657Snate@binkert.org */ 6947007Snate@binkert.orgMachineType 6957007Snate@binkert.org${{self.c_ident}}_from_base_level(int type) 6966657Snate@binkert.org{ 6976657Snate@binkert.org switch(type) { 6986657Snate@binkert.org''') 6996657Snate@binkert.org 7006657Snate@binkert.org # For each field 7016657Snate@binkert.org code.indent() 7026657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 7036657Snate@binkert.org code(' case $i:') 7046657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 7056657Snate@binkert.org code.dedent() 7066657Snate@binkert.org 7076657Snate@binkert.org # Trailer 7086657Snate@binkert.org code(''' 7096657Snate@binkert.org default: 7107805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7116657Snate@binkert.org } 7126657Snate@binkert.org} 7136657Snate@binkert.org 7146657Snate@binkert.org/** \\brief The return value indicates the number of components created 7156657Snate@binkert.org * before a particular machine\'s components 7166657Snate@binkert.org * 7176657Snate@binkert.org * \\return the base number of components for each machine 7186657Snate@binkert.org */ 7197007Snate@binkert.orgint 7207007Snate@binkert.org${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 7216657Snate@binkert.org{ 7226657Snate@binkert.org int base = 0; 7236657Snate@binkert.org switch(obj) { 7246657Snate@binkert.org''') 7256657Snate@binkert.org 7266657Snate@binkert.org # For each field 7276657Snate@binkert.org code.indent() 7286657Snate@binkert.org code(' case ${{self.c_ident}}_NUM:') 72913709Sandreas.sandberg@arm.com for enum in reversed(list(self.enums.values())): 7309773Snilay@cs.wisc.edu # Check if there is a defined machine with this type 73111283Santhony.gutierrez@amd.com if enum.primary: 7329773Snilay@cs.wisc.edu code(' base += ${{enum.ident}}_Controller::getNumControllers();') 7339773Snilay@cs.wisc.edu else: 7349773Snilay@cs.wisc.edu code(' base += 0;') 73512392Sjason@lowepower.com code(' M5_FALLTHROUGH;') 7366657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 7376657Snate@binkert.org code(' break;') 7386657Snate@binkert.org code.dedent() 7396657Snate@binkert.org 7406657Snate@binkert.org code(''' 7416657Snate@binkert.org default: 7427805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7436657Snate@binkert.org } 7446657Snate@binkert.org 7456657Snate@binkert.org return base; 7466657Snate@binkert.org} 7476657Snate@binkert.org 7486657Snate@binkert.org/** \\brief returns the total number of components for each machine 7496657Snate@binkert.org * \\return the total number of components for each machine 7506657Snate@binkert.org */ 7517007Snate@binkert.orgint 7527007Snate@binkert.org${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 7536657Snate@binkert.org{ 7546657Snate@binkert.org switch(obj) { 7556657Snate@binkert.org''') 7566657Snate@binkert.org 7576657Snate@binkert.org # For each field 7586657Snate@binkert.org for enum in self.enums.itervalues(): 7599773Snilay@cs.wisc.edu code('case ${{self.c_ident}}_${{enum.ident}}:') 76011283Santhony.gutierrez@amd.com if enum.primary: 7619773Snilay@cs.wisc.edu code('return ${{enum.ident}}_Controller::getNumControllers();') 7629773Snilay@cs.wisc.edu else: 7639773Snilay@cs.wisc.edu code('return 0;') 7646657Snate@binkert.org 7656657Snate@binkert.org # total num 7666657Snate@binkert.org code(''' 7676657Snate@binkert.org case ${{self.c_ident}}_NUM: 7686657Snate@binkert.org default: 7697805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7706657Snate@binkert.org } 7716657Snate@binkert.org} 7726657Snate@binkert.org''') 7736657Snate@binkert.org 7748602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 7758602Snilay@cs.wisc.edu code(''' 7768602Snilay@cs.wisc.edu 7778602Snilay@cs.wisc.eduMachineID 7788602Snilay@cs.wisc.eduget${{enum.ident}}MachineID(NodeID RubyNode) 7798602Snilay@cs.wisc.edu{ 7808602Snilay@cs.wisc.edu MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; 7818602Snilay@cs.wisc.edu return mach; 7828602Snilay@cs.wisc.edu} 7838602Snilay@cs.wisc.edu''') 7848602Snilay@cs.wisc.edu 7856657Snate@binkert.org # Write the file 7866657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 7876657Snate@binkert.org 7886657Snate@binkert.org__all__ = [ "Type" ] 789