Type.py revision 13709
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" 2046657Snate@binkert.org''') 2056657Snate@binkert.org 2066657Snate@binkert.org for dm in self.data_members.values(): 2076657Snate@binkert.org if not dm.type.isPrimitive: 2086657Snate@binkert.org code('#include "mem/protocol/$0.hh"', dm.type.c_ident) 2096657Snate@binkert.org 2106657Snate@binkert.org parent = "" 2116657Snate@binkert.org if "interface" in self: 2126657Snate@binkert.org code('#include "mem/protocol/$0.hh"', self["interface"]) 2136657Snate@binkert.org parent = " : public %s" % self["interface"] 2146657Snate@binkert.org 2156657Snate@binkert.org code(''' 2167007Snate@binkert.org$klass ${{self.c_ident}}$parent 2177007Snate@binkert.org{ 2186657Snate@binkert.org public: 2199466Snilay@cs.wisc.edu ${{self.c_ident}} 2206657Snate@binkert.org''', klass="class") 2216657Snate@binkert.org 2229466Snilay@cs.wisc.edu if self.isMessage: 2239508Snilay@cs.wisc.edu code('(Tick curTime) : %s(curTime) {' % self["interface"]) 2249466Snilay@cs.wisc.edu else: 2259466Snilay@cs.wisc.edu code('()\n\t\t{') 2269466Snilay@cs.wisc.edu 2276657Snate@binkert.org code.indent() 2286657Snate@binkert.org if not self.isGlobal: 2296657Snate@binkert.org code.indent() 2306657Snate@binkert.org for dm in self.data_members.values(): 2316657Snate@binkert.org ident = dm.ident 2326657Snate@binkert.org if "default" in dm: 2336657Snate@binkert.org # look for default value 2346657Snate@binkert.org code('m_$ident = ${{dm["default"]}}; // default for this field') 2356657Snate@binkert.org elif "default" in dm.type: 2366657Snate@binkert.org # Look for the type default 2376657Snate@binkert.org tid = dm.type.c_ident 2386657Snate@binkert.org code('m_$ident = ${{dm.type["default"]}}; // default value of $tid') 2396657Snate@binkert.org else: 2406657Snate@binkert.org code('// m_$ident has no default') 2416657Snate@binkert.org code.dedent() 2426657Snate@binkert.org code('}') 2436657Snate@binkert.org 2447453Snate@binkert.org # ******** Copy constructor ******** 2457453Snate@binkert.org if not self.isGlobal: 2467453Snate@binkert.org code('${{self.c_ident}}(const ${{self.c_ident}}&other)') 2477453Snate@binkert.org 2487453Snate@binkert.org # Call superclass constructor 2497453Snate@binkert.org if "interface" in self: 2507453Snate@binkert.org code(' : ${{self["interface"]}}(other)') 2517453Snate@binkert.org 2527453Snate@binkert.org code('{') 2537453Snate@binkert.org code.indent() 2547453Snate@binkert.org 2557453Snate@binkert.org for dm in self.data_members.values(): 2567453Snate@binkert.org code('m_${{dm.ident}} = other.m_${{dm.ident}};') 2577453Snate@binkert.org 2587453Snate@binkert.org code.dedent() 2597453Snate@binkert.org code('}') 2607453Snate@binkert.org 2616657Snate@binkert.org # ******** Full init constructor ******** 2626657Snate@binkert.org if not self.isGlobal: 2636657Snate@binkert.org params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \ 2646657Snate@binkert.org for dm in self.data_members.itervalues() ] 2659466Snilay@cs.wisc.edu params = ', '.join(params) 2666657Snate@binkert.org 2679466Snilay@cs.wisc.edu if self.isMessage: 2689508Snilay@cs.wisc.edu params = "const Tick curTime, " + params 2699466Snilay@cs.wisc.edu 2706657Snate@binkert.org code('${{self.c_ident}}($params)') 2716657Snate@binkert.org 2726657Snate@binkert.org # Call superclass constructor 2736657Snate@binkert.org if "interface" in self: 2749466Snilay@cs.wisc.edu if self.isMessage: 2759466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}(curTime)') 2769466Snilay@cs.wisc.edu else: 2779466Snilay@cs.wisc.edu code(' : ${{self["interface"]}}()') 2786657Snate@binkert.org 2796657Snate@binkert.org code('{') 2806657Snate@binkert.org code.indent() 2816657Snate@binkert.org for dm in self.data_members.values(): 2826657Snate@binkert.org code('m_${{dm.ident}} = local_${{dm.ident}};') 2836657Snate@binkert.org 2846657Snate@binkert.org code.dedent() 2856657Snate@binkert.org code('}') 2866657Snate@binkert.org 2879466Snilay@cs.wisc.edu # create a clone member 28810472Sandreas.hansson@arm.com if self.isMessage: 28910472Sandreas.hansson@arm.com code(''' 29010472Sandreas.hansson@arm.comMsgPtr 29110472Sandreas.hansson@arm.comclone() const 29210472Sandreas.hansson@arm.com{ 29310472Sandreas.hansson@arm.com return std::shared_ptr<Message>(new ${{self.c_ident}}(*this)); 29410472Sandreas.hansson@arm.com} 29510472Sandreas.hansson@arm.com''') 29610472Sandreas.hansson@arm.com else: 29710472Sandreas.hansson@arm.com code(''' 2987453Snate@binkert.org${{self.c_ident}}* 2997007Snate@binkert.orgclone() const 3007007Snate@binkert.org{ 3017453Snate@binkert.org return new ${{self.c_ident}}(*this); 3027007Snate@binkert.org} 3036657Snate@binkert.org''') 3046657Snate@binkert.org 3056657Snate@binkert.org if not self.isGlobal: 3066657Snate@binkert.org # const Get methods for each field 3076657Snate@binkert.org code('// Const accessors methods for each field') 3086657Snate@binkert.org for dm in self.data_members.values(): 3096657Snate@binkert.org code(''' 3106657Snate@binkert.org/** \\brief Const accessor method for ${{dm.ident}} field. 3116657Snate@binkert.org * \\return ${{dm.ident}} field 3126657Snate@binkert.org */ 3137007Snate@binkert.orgconst ${{dm.type.c_ident}}& 3147007Snate@binkert.orgget${{dm.ident}}() const 3157007Snate@binkert.org{ 3167007Snate@binkert.org return m_${{dm.ident}}; 3177007Snate@binkert.org} 3186657Snate@binkert.org''') 3196657Snate@binkert.org 3206657Snate@binkert.org # Non-const Get methods for each field 3216657Snate@binkert.org code('// Non const Accessors methods for each field') 3226657Snate@binkert.org for dm in self.data_members.values(): 3236657Snate@binkert.org code(''' 3246657Snate@binkert.org/** \\brief Non-const accessor method for ${{dm.ident}} field. 3256657Snate@binkert.org * \\return ${{dm.ident}} field 3266657Snate@binkert.org */ 3277007Snate@binkert.org${{dm.type.c_ident}}& 3287007Snate@binkert.orgget${{dm.ident}}() 3297007Snate@binkert.org{ 3307007Snate@binkert.org return m_${{dm.ident}}; 3317007Snate@binkert.org} 3326657Snate@binkert.org''') 3336657Snate@binkert.org 3346657Snate@binkert.org #Set methods for each field 3356657Snate@binkert.org code('// Mutator methods for each field') 3366657Snate@binkert.org for dm in self.data_members.values(): 3376657Snate@binkert.org code(''' 3386657Snate@binkert.org/** \\brief Mutator method for ${{dm.ident}} field */ 3397007Snate@binkert.orgvoid 3407007Snate@binkert.orgset${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) 3417007Snate@binkert.org{ 3427007Snate@binkert.org m_${{dm.ident}} = local_${{dm.ident}}; 3437007Snate@binkert.org} 3446657Snate@binkert.org''') 3456657Snate@binkert.org 3467002Snate@binkert.org code('void print(std::ostream& out) const;') 3476657Snate@binkert.org code.dedent() 3486657Snate@binkert.org code(' //private:') 3496657Snate@binkert.org code.indent() 3506657Snate@binkert.org 3516657Snate@binkert.org # Data members for each field 3526657Snate@binkert.org for dm in self.data_members.values(): 3536657Snate@binkert.org if "abstract" not in dm: 3546657Snate@binkert.org const = "" 3556657Snate@binkert.org init = "" 3566657Snate@binkert.org 3576657Snate@binkert.org # global structure 3586657Snate@binkert.org if self.isGlobal: 3596657Snate@binkert.org const = "static const " 3606657Snate@binkert.org 3616657Snate@binkert.org # init value 3626657Snate@binkert.org if dm.init_code: 3636657Snate@binkert.org # only global structure can have init value here 3646657Snate@binkert.org assert self.isGlobal 3656657Snate@binkert.org init = " = %s" % (dm.init_code) 3666657Snate@binkert.org 3676657Snate@binkert.org if "desc" in dm: 3687007Snate@binkert.org code('/** ${{dm["desc"]}} */') 3696657Snate@binkert.org 3707007Snate@binkert.org code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;') 3716657Snate@binkert.org 37210307Snilay@cs.wisc.edu # Prototypes for methods defined for the Type 37310307Snilay@cs.wisc.edu for item in self.methods: 37410307Snilay@cs.wisc.edu proto = self.methods[item].prototype 3759298Snilay@cs.wisc.edu if proto: 3769298Snilay@cs.wisc.edu code('$proto') 3779298Snilay@cs.wisc.edu 3786657Snate@binkert.org code.dedent() 3796657Snate@binkert.org code('};') 3806657Snate@binkert.org 3816657Snate@binkert.org code(''' 3827055Snate@binkert.orginline std::ostream& 3837007Snate@binkert.orgoperator<<(std::ostream& out, const ${{self.c_ident}}& obj) 3846657Snate@binkert.org{ 3856657Snate@binkert.org obj.print(out); 3867002Snate@binkert.org out << std::flush; 3876657Snate@binkert.org return out; 3886657Snate@binkert.org} 3896657Snate@binkert.org 3907007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 3916657Snate@binkert.org''') 3926657Snate@binkert.org 3936657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 3946657Snate@binkert.org 3956657Snate@binkert.org def printTypeCC(self, path): 3966999Snate@binkert.org code = self.symtab.codeFormatter() 3976657Snate@binkert.org 3986657Snate@binkert.org code(''' 3996657Snate@binkert.org/** \\file ${{self.c_ident}}.cc 4006657Snate@binkert.org * 4016657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4026657Snate@binkert.org */ 4036657Snate@binkert.org 4047002Snate@binkert.org#include <iostream> 40510472Sandreas.hansson@arm.com#include <memory> 4067002Snate@binkert.org 4076657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 40811108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh" 4097002Snate@binkert.org 4107002Snate@binkert.orgusing namespace std; 4116657Snate@binkert.org''') 4126657Snate@binkert.org 4136657Snate@binkert.org code(''' 4146657Snate@binkert.org/** \\brief Print the state of this object */ 4157007Snate@binkert.orgvoid 4167007Snate@binkert.org${{self.c_ident}}::print(ostream& out) const 4176657Snate@binkert.org{ 4186657Snate@binkert.org out << "[${{self.c_ident}}: "; 4196657Snate@binkert.org''') 4206657Snate@binkert.org 4216657Snate@binkert.org # For each field 4226657Snate@binkert.org code.indent() 4236657Snate@binkert.org for dm in self.data_members.values(): 42411118Snilay@cs.wisc.edu if dm.type.c_ident == "Addr": 42511118Snilay@cs.wisc.edu code(''' 42611118Snilay@cs.wisc.eduout << "${{dm.ident}} = " << printAddress(m_${{dm.ident}}) << " ";''') 42711118Snilay@cs.wisc.edu else: 42811118Snilay@cs.wisc.edu code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''') 4296657Snate@binkert.org 4306657Snate@binkert.org code.dedent() 4316657Snate@binkert.org 4326657Snate@binkert.org # Trailer 4336657Snate@binkert.org code(''' 4346657Snate@binkert.org out << "]"; 4356657Snate@binkert.org}''') 4366657Snate@binkert.org 43710307Snilay@cs.wisc.edu # print the code for the methods in the type 43810307Snilay@cs.wisc.edu for item in self.methods: 43910307Snilay@cs.wisc.edu code(self.methods[item].generateCode()) 4409298Snilay@cs.wisc.edu 4416657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 4426657Snate@binkert.org 4436657Snate@binkert.org def printEnumHH(self, path): 4446999Snate@binkert.org code = self.symtab.codeFormatter() 4456657Snate@binkert.org code(''' 4466657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 4476657Snate@binkert.org * 4486657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 4496657Snate@binkert.org */ 4507007Snate@binkert.org 4517007Snate@binkert.org#ifndef __${{self.c_ident}}_HH__ 4527007Snate@binkert.org#define __${{self.c_ident}}_HH__ 4536657Snate@binkert.org 4547002Snate@binkert.org#include <iostream> 4557002Snate@binkert.org#include <string> 4567002Snate@binkert.org 4578086SBrad.Beckmann@amd.com''') 4588086SBrad.Beckmann@amd.com if self.isStateDecl: 4598086SBrad.Beckmann@amd.com code('#include "mem/protocol/AccessPermission.hh"') 4608086SBrad.Beckmann@amd.com 4618602Snilay@cs.wisc.edu if self.isMachineType: 46212065Snikos.nikoleris@arm.com code('#include <functional>') 46312334Sgabeblack@google.com code('#include "base/logging.hh"') 4648602Snilay@cs.wisc.edu code('#include "mem/ruby/common/Address.hh"') 46511025Snilay@cs.wisc.edu code('#include "mem/ruby/common/TypeDefines.hh"') 4668602Snilay@cs.wisc.edu code('struct MachineID;') 4678602Snilay@cs.wisc.edu 4688086SBrad.Beckmann@amd.com code(''' 4696657Snate@binkert.org 4707007Snate@binkert.org// Class definition 4716657Snate@binkert.org/** \\enum ${{self.c_ident}} 4726657Snate@binkert.org * \\brief ${{self.desc}} 4736657Snate@binkert.org */ 4746657Snate@binkert.orgenum ${{self.c_ident}} { 4756657Snate@binkert.org ${{self.c_ident}}_FIRST, 4766657Snate@binkert.org''') 4776657Snate@binkert.org 4786657Snate@binkert.org code.indent() 4796657Snate@binkert.org # For each field 4806657Snate@binkert.org for i,(ident,enum) in enumerate(self.enums.iteritems()): 4816657Snate@binkert.org desc = enum.get("desc", "No description avaliable") 48210917Sbrandon.potter@amd.com if i == 0: 48310917Sbrandon.potter@amd.com init = ' = %s_FIRST' % self.c_ident 4846862Sdrh5@cs.wisc.edu else: 4856862Sdrh5@cs.wisc.edu init = '' 4866657Snate@binkert.org code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4876657Snate@binkert.org code.dedent() 4886657Snate@binkert.org code(''' 4896657Snate@binkert.org ${{self.c_ident}}_NUM 4906657Snate@binkert.org}; 4917007Snate@binkert.org 4927007Snate@binkert.org// Code to convert from a string to the enumeration 4937002Snate@binkert.org${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 4947007Snate@binkert.org 4957007Snate@binkert.org// Code to convert state to a string 4967002Snate@binkert.orgstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 4977007Snate@binkert.org 4987007Snate@binkert.org// Code to increment an enumeration type 4996657Snate@binkert.org${{self.c_ident}} &operator++(${{self.c_ident}} &e); 5006657Snate@binkert.org''') 5016657Snate@binkert.org 50212065Snikos.nikoleris@arm.com if self.isMachineType: 50312065Snikos.nikoleris@arm.com code(''' 50412065Snikos.nikoleris@arm.com 50512065Snikos.nikoleris@arm.com// define a hash function for the MachineType class 50612065Snikos.nikoleris@arm.comnamespace std { 50712065Snikos.nikoleris@arm.comtemplate<> 50812065Snikos.nikoleris@arm.comstruct hash<MachineType> { 50912065Snikos.nikoleris@arm.com std::size_t operator()(const MachineType &mtype) const { 51012065Snikos.nikoleris@arm.com return hash<size_t>()(static_cast<size_t>(mtype)); 51112065Snikos.nikoleris@arm.com } 51212065Snikos.nikoleris@arm.com}; 51312065Snikos.nikoleris@arm.com} 51412065Snikos.nikoleris@arm.com 51512065Snikos.nikoleris@arm.com''') 5166657Snate@binkert.org # MachineType hack used to set the base component id for each Machine 5176657Snate@binkert.org if self.isMachineType: 5186657Snate@binkert.org code(''' 5196657Snate@binkert.orgint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 5206657Snate@binkert.orgMachineType ${{self.c_ident}}_from_base_level(int); 5216657Snate@binkert.orgint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 5226657Snate@binkert.orgint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 5236657Snate@binkert.org''') 5246657Snate@binkert.org 5256657Snate@binkert.org for enum in self.enums.itervalues(): 5268602Snilay@cs.wisc.edu code(''' 5278602Snilay@cs.wisc.edu 5288602Snilay@cs.wisc.eduMachineID get${{enum.ident}}MachineID(NodeID RubyNode); 5298602Snilay@cs.wisc.edu''') 5308602Snilay@cs.wisc.edu 5318086SBrad.Beckmann@amd.com if self.isStateDecl: 5328086SBrad.Beckmann@amd.com code(''' 5338086SBrad.Beckmann@amd.com 5348086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5358086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); 5368086SBrad.Beckmann@amd.com 5378086SBrad.Beckmann@amd.com''') 5388086SBrad.Beckmann@amd.com 5396657Snate@binkert.org # Trailer 5406657Snate@binkert.org code(''' 5417002Snate@binkert.orgstd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 5426657Snate@binkert.org 5437007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 5446657Snate@binkert.org''') 5456657Snate@binkert.org 5466657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 5476657Snate@binkert.org 5486657Snate@binkert.org def printEnumCC(self, path): 5496999Snate@binkert.org code = self.symtab.codeFormatter() 5506657Snate@binkert.org code(''' 5516657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 5526657Snate@binkert.org * 5536657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 5546657Snate@binkert.org */ 5556657Snate@binkert.org 5567832Snate@binkert.org#include <cassert> 5577002Snate@binkert.org#include <iostream> 5587002Snate@binkert.org#include <string> 5597002Snate@binkert.org 56012334Sgabeblack@google.com#include "base/logging.hh" 5616657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 5626657Snate@binkert.org 5637002Snate@binkert.orgusing namespace std; 5647002Snate@binkert.org 5656657Snate@binkert.org''') 5666657Snate@binkert.org 5678086SBrad.Beckmann@amd.com if self.isStateDecl: 5688086SBrad.Beckmann@amd.com code(''' 5698086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5708086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) 5718086SBrad.Beckmann@amd.com{ 5728086SBrad.Beckmann@amd.com switch(obj) { 5738086SBrad.Beckmann@amd.com''') 5748086SBrad.Beckmann@amd.com # For each case 5758086SBrad.Beckmann@amd.com code.indent() 5768086SBrad.Beckmann@amd.com for statePerm in self.statePermPairs: 5778086SBrad.Beckmann@amd.com code(' case ${{self.c_ident}}_${{statePerm[0]}}:') 5788086SBrad.Beckmann@amd.com code(' return AccessPermission_${{statePerm[1]}};') 5798086SBrad.Beckmann@amd.com code.dedent() 5808086SBrad.Beckmann@amd.com code (''' 5818086SBrad.Beckmann@amd.com default: 5828086SBrad.Beckmann@amd.com panic("Unknown state access permission converstion for ${{self.c_ident}}"); 5838086SBrad.Beckmann@amd.com } 5848086SBrad.Beckmann@amd.com} 5858086SBrad.Beckmann@amd.com 5868086SBrad.Beckmann@amd.com''') 5878086SBrad.Beckmann@amd.com 5886657Snate@binkert.org if self.isMachineType: 5896657Snate@binkert.org for enum in self.enums.itervalues(): 59011283Santhony.gutierrez@amd.com if enum.primary: 5919773Snilay@cs.wisc.edu code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') 59210301Snilay@cs.wisc.edu code('#include "mem/ruby/common/MachineID.hh"') 5936657Snate@binkert.org 5946657Snate@binkert.org code(''' 5957007Snate@binkert.org// Code for output operator 5967007Snate@binkert.orgostream& 5977007Snate@binkert.orgoperator<<(ostream& out, const ${{self.c_ident}}& obj) 5986657Snate@binkert.org{ 5996657Snate@binkert.org out << ${{self.c_ident}}_to_string(obj); 6006657Snate@binkert.org out << flush; 6016657Snate@binkert.org return out; 6026657Snate@binkert.org} 6036657Snate@binkert.org 6047007Snate@binkert.org// Code to convert state to a string 6057007Snate@binkert.orgstring 6067007Snate@binkert.org${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 6076657Snate@binkert.org{ 6086657Snate@binkert.org switch(obj) { 6096657Snate@binkert.org''') 6106657Snate@binkert.org 6116657Snate@binkert.org # For each field 6126657Snate@binkert.org code.indent() 6136657Snate@binkert.org for enum in self.enums.itervalues(): 6146657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6156657Snate@binkert.org code(' return "${{enum.ident}}";') 6166657Snate@binkert.org code.dedent() 6176657Snate@binkert.org 6186657Snate@binkert.org # Trailer 6196657Snate@binkert.org code(''' 6206657Snate@binkert.org default: 6217805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6226657Snate@binkert.org } 6236657Snate@binkert.org} 6246657Snate@binkert.org 6257007Snate@binkert.org// Code to convert from a string to the enumeration 6267007Snate@binkert.org${{self.c_ident}} 6277007Snate@binkert.orgstring_to_${{self.c_ident}}(const string& str) 6286657Snate@binkert.org{ 6296657Snate@binkert.org''') 6306657Snate@binkert.org 6316657Snate@binkert.org # For each field 6327007Snate@binkert.org start = "" 6336657Snate@binkert.org code.indent() 6346657Snate@binkert.org for enum in self.enums.itervalues(): 6356657Snate@binkert.org code('${start}if (str == "${{enum.ident}}") {') 6366657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6377007Snate@binkert.org start = "} else " 6386657Snate@binkert.org code.dedent() 6396657Snate@binkert.org 6406657Snate@binkert.org code(''' 6416657Snate@binkert.org } else { 6427805Snilay@cs.wisc.edu panic("Invalid string conversion for %s, type ${{self.c_ident}}", str); 6436657Snate@binkert.org } 6446657Snate@binkert.org} 6456657Snate@binkert.org 6467007Snate@binkert.org// Code to increment an enumeration type 6477007Snate@binkert.org${{self.c_ident}}& 6487007Snate@binkert.orgoperator++(${{self.c_ident}}& e) 6497007Snate@binkert.org{ 6506657Snate@binkert.org assert(e < ${{self.c_ident}}_NUM); 6516657Snate@binkert.org return e = ${{self.c_ident}}(e+1); 6526657Snate@binkert.org} 6536657Snate@binkert.org''') 6546657Snate@binkert.org 6556657Snate@binkert.org # MachineType hack used to set the base level and number of 6566657Snate@binkert.org # components for each Machine 6576657Snate@binkert.org if self.isMachineType: 6586657Snate@binkert.org code(''' 6597007Snate@binkert.org/** \\brief returns the base vector index for each machine type to be 6607007Snate@binkert.org * used by NetDest 6616657Snate@binkert.org * 6626657Snate@binkert.org * \\return the base vector index for each machine type to be used by NetDest 6636657Snate@binkert.org * \\see NetDest.hh 6646657Snate@binkert.org */ 6657007Snate@binkert.orgint 6667007Snate@binkert.org${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 6676657Snate@binkert.org{ 6686657Snate@binkert.org switch(obj) { 6696657Snate@binkert.org''') 6706657Snate@binkert.org 6716657Snate@binkert.org # For each field 6726657Snate@binkert.org code.indent() 6736657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6746657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6756657Snate@binkert.org code(' return $i;') 6766657Snate@binkert.org code.dedent() 6776657Snate@binkert.org 6786657Snate@binkert.org # total num 6796657Snate@binkert.org code(''' 6806657Snate@binkert.org case ${{self.c_ident}}_NUM: 6816657Snate@binkert.org return ${{len(self.enums)}}; 6826657Snate@binkert.org 6836657Snate@binkert.org default: 6847805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6856657Snate@binkert.org } 6866657Snate@binkert.org} 6876657Snate@binkert.org 6886657Snate@binkert.org/** \\brief returns the machine type for each base vector index used by NetDest 6896657Snate@binkert.org * 6907007Snate@binkert.org * \\return the MachineType 6916657Snate@binkert.org */ 6927007Snate@binkert.orgMachineType 6937007Snate@binkert.org${{self.c_ident}}_from_base_level(int type) 6946657Snate@binkert.org{ 6956657Snate@binkert.org switch(type) { 6966657Snate@binkert.org''') 6976657Snate@binkert.org 6986657Snate@binkert.org # For each field 6996657Snate@binkert.org code.indent() 7006657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 7016657Snate@binkert.org code(' case $i:') 7026657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 7036657Snate@binkert.org code.dedent() 7046657Snate@binkert.org 7056657Snate@binkert.org # Trailer 7066657Snate@binkert.org code(''' 7076657Snate@binkert.org default: 7087805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7096657Snate@binkert.org } 7106657Snate@binkert.org} 7116657Snate@binkert.org 7126657Snate@binkert.org/** \\brief The return value indicates the number of components created 7136657Snate@binkert.org * before a particular machine\'s components 7146657Snate@binkert.org * 7156657Snate@binkert.org * \\return the base number of components for each machine 7166657Snate@binkert.org */ 7177007Snate@binkert.orgint 7187007Snate@binkert.org${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 7196657Snate@binkert.org{ 7206657Snate@binkert.org int base = 0; 7216657Snate@binkert.org switch(obj) { 7226657Snate@binkert.org''') 7236657Snate@binkert.org 7246657Snate@binkert.org # For each field 7256657Snate@binkert.org code.indent() 7266657Snate@binkert.org code(' case ${{self.c_ident}}_NUM:') 72713709Sandreas.sandberg@arm.com for enum in reversed(list(self.enums.values())): 7289773Snilay@cs.wisc.edu # Check if there is a defined machine with this type 72911283Santhony.gutierrez@amd.com if enum.primary: 7309773Snilay@cs.wisc.edu code(' base += ${{enum.ident}}_Controller::getNumControllers();') 7319773Snilay@cs.wisc.edu else: 7329773Snilay@cs.wisc.edu code(' base += 0;') 73312392Sjason@lowepower.com code(' M5_FALLTHROUGH;') 7346657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 7356657Snate@binkert.org code(' break;') 7366657Snate@binkert.org code.dedent() 7376657Snate@binkert.org 7386657Snate@binkert.org code(''' 7396657Snate@binkert.org default: 7407805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7416657Snate@binkert.org } 7426657Snate@binkert.org 7436657Snate@binkert.org return base; 7446657Snate@binkert.org} 7456657Snate@binkert.org 7466657Snate@binkert.org/** \\brief returns the total number of components for each machine 7476657Snate@binkert.org * \\return the total number of components for each machine 7486657Snate@binkert.org */ 7497007Snate@binkert.orgint 7507007Snate@binkert.org${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 7516657Snate@binkert.org{ 7526657Snate@binkert.org switch(obj) { 7536657Snate@binkert.org''') 7546657Snate@binkert.org 7556657Snate@binkert.org # For each field 7566657Snate@binkert.org for enum in self.enums.itervalues(): 7579773Snilay@cs.wisc.edu code('case ${{self.c_ident}}_${{enum.ident}}:') 75811283Santhony.gutierrez@amd.com if enum.primary: 7599773Snilay@cs.wisc.edu code('return ${{enum.ident}}_Controller::getNumControllers();') 7609773Snilay@cs.wisc.edu else: 7619773Snilay@cs.wisc.edu code('return 0;') 7626657Snate@binkert.org 7636657Snate@binkert.org # total num 7646657Snate@binkert.org code(''' 7656657Snate@binkert.org case ${{self.c_ident}}_NUM: 7666657Snate@binkert.org default: 7677805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7686657Snate@binkert.org } 7696657Snate@binkert.org} 7706657Snate@binkert.org''') 7716657Snate@binkert.org 7728602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 7738602Snilay@cs.wisc.edu code(''' 7748602Snilay@cs.wisc.edu 7758602Snilay@cs.wisc.eduMachineID 7768602Snilay@cs.wisc.eduget${{enum.ident}}MachineID(NodeID RubyNode) 7778602Snilay@cs.wisc.edu{ 7788602Snilay@cs.wisc.edu MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; 7798602Snilay@cs.wisc.edu return mach; 7808602Snilay@cs.wisc.edu} 7818602Snilay@cs.wisc.edu''') 7828602Snilay@cs.wisc.edu 7836657Snate@binkert.org # Write the file 7846657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 7856657Snate@binkert.org 7866657Snate@binkert.org__all__ = [ "Type" ] 787