Type.py revision 11283
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 36657Snate@binkert.org# All rights reserved. 46657Snate@binkert.org# 56657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org# modification, are permitted provided that the following conditions are 76657Snate@binkert.org# met: redistributions of source code must retain the above copyright 86657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org# documentation and/or other materials provided with the distribution; 126657Snate@binkert.org# neither the name of the copyright holders nor the names of its 136657Snate@binkert.org# contributors may be used to endorse or promote products derived from 146657Snate@binkert.org# this software without specific prior written permission. 156657Snate@binkert.org# 166657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org 286999Snate@binkert.orgfrom m5.util import orderdict 296657Snate@binkert.org 306657Snate@binkert.orgfrom slicc.util import PairContainer 316657Snate@binkert.orgfrom slicc.symbols.Symbol import Symbol 329302Snilay@cs.wisc.edufrom slicc.symbols.Var import Var 336657Snate@binkert.org 3411117Snilay@cs.wisc.educlass DataMember(Var): 3511117Snilay@cs.wisc.edu def __init__(self, symtab, ident, location, type, code, pairs, 3611117Snilay@cs.wisc.edu machine, init_code): 3711117Snilay@cs.wisc.edu super(DataMember, self).__init__(symtab, ident, location, type, 3811117Snilay@cs.wisc.edu code, pairs, machine) 396657Snate@binkert.org self.init_code = init_code 406657Snate@binkert.org 416657Snate@binkert.orgclass Enumeration(PairContainer): 426657Snate@binkert.org def __init__(self, ident, pairs): 436657Snate@binkert.org super(Enumeration, self).__init__(pairs) 446657Snate@binkert.org self.ident = ident 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 926657Snate@binkert.org self.data_members = orderdict() 936657Snate@binkert.org self.methods = {} 946657Snate@binkert.org self.enums = orderdict() 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: 4628602Snilay@cs.wisc.edu code('#include "base/misc.hh"') 4638602Snilay@cs.wisc.edu code('#include "mem/ruby/common/Address.hh"') 46411025Snilay@cs.wisc.edu code('#include "mem/ruby/common/TypeDefines.hh"') 4658602Snilay@cs.wisc.edu code('struct MachineID;') 4668602Snilay@cs.wisc.edu 4678086SBrad.Beckmann@amd.com code(''' 4686657Snate@binkert.org 4697007Snate@binkert.org// Class definition 4706657Snate@binkert.org/** \\enum ${{self.c_ident}} 4716657Snate@binkert.org * \\brief ${{self.desc}} 4726657Snate@binkert.org */ 4736657Snate@binkert.orgenum ${{self.c_ident}} { 4746657Snate@binkert.org ${{self.c_ident}}_FIRST, 4756657Snate@binkert.org''') 4766657Snate@binkert.org 4776657Snate@binkert.org code.indent() 4786657Snate@binkert.org # For each field 4796657Snate@binkert.org for i,(ident,enum) in enumerate(self.enums.iteritems()): 4806657Snate@binkert.org desc = enum.get("desc", "No description avaliable") 48110917Sbrandon.potter@amd.com if i == 0: 48210917Sbrandon.potter@amd.com init = ' = %s_FIRST' % self.c_ident 4836862Sdrh5@cs.wisc.edu else: 4846862Sdrh5@cs.wisc.edu init = '' 4856657Snate@binkert.org code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */') 4866657Snate@binkert.org code.dedent() 4876657Snate@binkert.org code(''' 4886657Snate@binkert.org ${{self.c_ident}}_NUM 4896657Snate@binkert.org}; 4907007Snate@binkert.org 4917007Snate@binkert.org// Code to convert from a string to the enumeration 4927002Snate@binkert.org${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str); 4937007Snate@binkert.org 4947007Snate@binkert.org// Code to convert state to a string 4957002Snate@binkert.orgstd::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); 4967007Snate@binkert.org 4977007Snate@binkert.org// Code to increment an enumeration type 4986657Snate@binkert.org${{self.c_ident}} &operator++(${{self.c_ident}} &e); 4996657Snate@binkert.org''') 5006657Snate@binkert.org 5016657Snate@binkert.org # MachineType hack used to set the base component id for each Machine 5026657Snate@binkert.org if self.isMachineType: 5036657Snate@binkert.org code(''' 5046657Snate@binkert.orgint ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj); 5056657Snate@binkert.orgMachineType ${{self.c_ident}}_from_base_level(int); 5066657Snate@binkert.orgint ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj); 5076657Snate@binkert.orgint ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); 5086657Snate@binkert.org''') 5096657Snate@binkert.org 5106657Snate@binkert.org for enum in self.enums.itervalues(): 5118602Snilay@cs.wisc.edu if enum.ident == "DMA": 5128602Snilay@cs.wisc.edu code(''' 51311025Snilay@cs.wisc.eduMachineID map_Address_to_DMA(const Addr &addr); 5148602Snilay@cs.wisc.edu''') 5158602Snilay@cs.wisc.edu code(''' 5168602Snilay@cs.wisc.edu 5178602Snilay@cs.wisc.eduMachineID get${{enum.ident}}MachineID(NodeID RubyNode); 5188602Snilay@cs.wisc.edu''') 5198602Snilay@cs.wisc.edu 5208086SBrad.Beckmann@amd.com if self.isStateDecl: 5218086SBrad.Beckmann@amd.com code(''' 5228086SBrad.Beckmann@amd.com 5238086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5248086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj); 5258086SBrad.Beckmann@amd.com 5268086SBrad.Beckmann@amd.com''') 5278086SBrad.Beckmann@amd.com 5286657Snate@binkert.org # Trailer 5296657Snate@binkert.org code(''' 5307002Snate@binkert.orgstd::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj); 5316657Snate@binkert.org 5327007Snate@binkert.org#endif // __${{self.c_ident}}_HH__ 5336657Snate@binkert.org''') 5346657Snate@binkert.org 5356657Snate@binkert.org code.write(path, "%s.hh" % self.c_ident) 5366657Snate@binkert.org 5376657Snate@binkert.org def printEnumCC(self, path): 5386999Snate@binkert.org code = self.symtab.codeFormatter() 5396657Snate@binkert.org code(''' 5406657Snate@binkert.org/** \\file ${{self.c_ident}}.hh 5416657Snate@binkert.org * 5426657Snate@binkert.org * Auto generated C++ code started by $__file__:$__line__ 5436657Snate@binkert.org */ 5446657Snate@binkert.org 5457832Snate@binkert.org#include <cassert> 5467002Snate@binkert.org#include <iostream> 5477002Snate@binkert.org#include <string> 5487002Snate@binkert.org 5497805Snilay@cs.wisc.edu#include "base/misc.hh" 5506657Snate@binkert.org#include "mem/protocol/${{self.c_ident}}.hh" 5516657Snate@binkert.org 5527002Snate@binkert.orgusing namespace std; 5537002Snate@binkert.org 5546657Snate@binkert.org''') 5556657Snate@binkert.org 5568086SBrad.Beckmann@amd.com if self.isStateDecl: 5578086SBrad.Beckmann@amd.com code(''' 5588086SBrad.Beckmann@amd.com// Code to convert the current state to an access permission 5598086SBrad.Beckmann@amd.comAccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) 5608086SBrad.Beckmann@amd.com{ 5618086SBrad.Beckmann@amd.com switch(obj) { 5628086SBrad.Beckmann@amd.com''') 5638086SBrad.Beckmann@amd.com # For each case 5648086SBrad.Beckmann@amd.com code.indent() 5658086SBrad.Beckmann@amd.com for statePerm in self.statePermPairs: 5668086SBrad.Beckmann@amd.com code(' case ${{self.c_ident}}_${{statePerm[0]}}:') 5678086SBrad.Beckmann@amd.com code(' return AccessPermission_${{statePerm[1]}};') 5688086SBrad.Beckmann@amd.com code.dedent() 5698086SBrad.Beckmann@amd.com code (''' 5708086SBrad.Beckmann@amd.com default: 5718086SBrad.Beckmann@amd.com panic("Unknown state access permission converstion for ${{self.c_ident}}"); 5728086SBrad.Beckmann@amd.com } 5738086SBrad.Beckmann@amd.com} 5748086SBrad.Beckmann@amd.com 5758086SBrad.Beckmann@amd.com''') 5768086SBrad.Beckmann@amd.com 5776657Snate@binkert.org if self.isMachineType: 5786657Snate@binkert.org for enum in self.enums.itervalues(): 57911283Santhony.gutierrez@amd.com if enum.primary: 5809773Snilay@cs.wisc.edu code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') 58110301Snilay@cs.wisc.edu code('#include "mem/ruby/common/MachineID.hh"') 5826657Snate@binkert.org 5836657Snate@binkert.org code(''' 5847007Snate@binkert.org// Code for output operator 5857007Snate@binkert.orgostream& 5867007Snate@binkert.orgoperator<<(ostream& out, const ${{self.c_ident}}& obj) 5876657Snate@binkert.org{ 5886657Snate@binkert.org out << ${{self.c_ident}}_to_string(obj); 5896657Snate@binkert.org out << flush; 5906657Snate@binkert.org return out; 5916657Snate@binkert.org} 5926657Snate@binkert.org 5937007Snate@binkert.org// Code to convert state to a string 5947007Snate@binkert.orgstring 5957007Snate@binkert.org${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj) 5966657Snate@binkert.org{ 5976657Snate@binkert.org switch(obj) { 5986657Snate@binkert.org''') 5996657Snate@binkert.org 6006657Snate@binkert.org # For each field 6016657Snate@binkert.org code.indent() 6026657Snate@binkert.org for enum in self.enums.itervalues(): 6036657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6046657Snate@binkert.org code(' return "${{enum.ident}}";') 6056657Snate@binkert.org code.dedent() 6066657Snate@binkert.org 6076657Snate@binkert.org # Trailer 6086657Snate@binkert.org code(''' 6096657Snate@binkert.org default: 6107805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6116657Snate@binkert.org } 6126657Snate@binkert.org} 6136657Snate@binkert.org 6147007Snate@binkert.org// Code to convert from a string to the enumeration 6157007Snate@binkert.org${{self.c_ident}} 6167007Snate@binkert.orgstring_to_${{self.c_ident}}(const string& str) 6176657Snate@binkert.org{ 6186657Snate@binkert.org''') 6196657Snate@binkert.org 6206657Snate@binkert.org # For each field 6217007Snate@binkert.org start = "" 6226657Snate@binkert.org code.indent() 6236657Snate@binkert.org for enum in self.enums.itervalues(): 6246657Snate@binkert.org code('${start}if (str == "${{enum.ident}}") {') 6256657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6267007Snate@binkert.org start = "} else " 6276657Snate@binkert.org code.dedent() 6286657Snate@binkert.org 6296657Snate@binkert.org code(''' 6306657Snate@binkert.org } else { 6317805Snilay@cs.wisc.edu panic("Invalid string conversion for %s, type ${{self.c_ident}}", str); 6326657Snate@binkert.org } 6336657Snate@binkert.org} 6346657Snate@binkert.org 6357007Snate@binkert.org// Code to increment an enumeration type 6367007Snate@binkert.org${{self.c_ident}}& 6377007Snate@binkert.orgoperator++(${{self.c_ident}}& e) 6387007Snate@binkert.org{ 6396657Snate@binkert.org assert(e < ${{self.c_ident}}_NUM); 6406657Snate@binkert.org return e = ${{self.c_ident}}(e+1); 6416657Snate@binkert.org} 6426657Snate@binkert.org''') 6436657Snate@binkert.org 6446657Snate@binkert.org # MachineType hack used to set the base level and number of 6456657Snate@binkert.org # components for each Machine 6466657Snate@binkert.org if self.isMachineType: 6476657Snate@binkert.org code(''' 6487007Snate@binkert.org/** \\brief returns the base vector index for each machine type to be 6497007Snate@binkert.org * used by NetDest 6506657Snate@binkert.org * 6516657Snate@binkert.org * \\return the base vector index for each machine type to be used by NetDest 6526657Snate@binkert.org * \\see NetDest.hh 6536657Snate@binkert.org */ 6547007Snate@binkert.orgint 6557007Snate@binkert.org${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj) 6566657Snate@binkert.org{ 6576657Snate@binkert.org switch(obj) { 6586657Snate@binkert.org''') 6596657Snate@binkert.org 6606657Snate@binkert.org # For each field 6616657Snate@binkert.org code.indent() 6626657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6636657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 6646657Snate@binkert.org code(' return $i;') 6656657Snate@binkert.org code.dedent() 6666657Snate@binkert.org 6676657Snate@binkert.org # total num 6686657Snate@binkert.org code(''' 6696657Snate@binkert.org case ${{self.c_ident}}_NUM: 6706657Snate@binkert.org return ${{len(self.enums)}}; 6716657Snate@binkert.org 6726657Snate@binkert.org default: 6737805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6746657Snate@binkert.org } 6756657Snate@binkert.org} 6766657Snate@binkert.org 6776657Snate@binkert.org/** \\brief returns the machine type for each base vector index used by NetDest 6786657Snate@binkert.org * 6797007Snate@binkert.org * \\return the MachineType 6806657Snate@binkert.org */ 6817007Snate@binkert.orgMachineType 6827007Snate@binkert.org${{self.c_ident}}_from_base_level(int type) 6836657Snate@binkert.org{ 6846657Snate@binkert.org switch(type) { 6856657Snate@binkert.org''') 6866657Snate@binkert.org 6876657Snate@binkert.org # For each field 6886657Snate@binkert.org code.indent() 6896657Snate@binkert.org for i,enum in enumerate(self.enums.itervalues()): 6906657Snate@binkert.org code(' case $i:') 6916657Snate@binkert.org code(' return ${{self.c_ident}}_${{enum.ident}};') 6926657Snate@binkert.org code.dedent() 6936657Snate@binkert.org 6946657Snate@binkert.org # Trailer 6956657Snate@binkert.org code(''' 6966657Snate@binkert.org default: 6977805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 6986657Snate@binkert.org } 6996657Snate@binkert.org} 7006657Snate@binkert.org 7016657Snate@binkert.org/** \\brief The return value indicates the number of components created 7026657Snate@binkert.org * before a particular machine\'s components 7036657Snate@binkert.org * 7046657Snate@binkert.org * \\return the base number of components for each machine 7056657Snate@binkert.org */ 7067007Snate@binkert.orgint 7077007Snate@binkert.org${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) 7086657Snate@binkert.org{ 7096657Snate@binkert.org int base = 0; 7106657Snate@binkert.org switch(obj) { 7116657Snate@binkert.org''') 7126657Snate@binkert.org 7136657Snate@binkert.org # For each field 7146657Snate@binkert.org code.indent() 7156657Snate@binkert.org code(' case ${{self.c_ident}}_NUM:') 7166657Snate@binkert.org for enum in reversed(self.enums.values()): 7179773Snilay@cs.wisc.edu # Check if there is a defined machine with this type 71811283Santhony.gutierrez@amd.com if enum.primary: 7199773Snilay@cs.wisc.edu code(' base += ${{enum.ident}}_Controller::getNumControllers();') 7209773Snilay@cs.wisc.edu else: 7219773Snilay@cs.wisc.edu code(' base += 0;') 7226657Snate@binkert.org code(' case ${{self.c_ident}}_${{enum.ident}}:') 7236657Snate@binkert.org code(' break;') 7246657Snate@binkert.org code.dedent() 7256657Snate@binkert.org 7266657Snate@binkert.org code(''' 7276657Snate@binkert.org default: 7287805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7296657Snate@binkert.org } 7306657Snate@binkert.org 7316657Snate@binkert.org return base; 7326657Snate@binkert.org} 7336657Snate@binkert.org 7346657Snate@binkert.org/** \\brief returns the total number of components for each machine 7356657Snate@binkert.org * \\return the total number of components for each machine 7366657Snate@binkert.org */ 7377007Snate@binkert.orgint 7387007Snate@binkert.org${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) 7396657Snate@binkert.org{ 7406657Snate@binkert.org switch(obj) { 7416657Snate@binkert.org''') 7426657Snate@binkert.org 7436657Snate@binkert.org # For each field 7446657Snate@binkert.org for enum in self.enums.itervalues(): 7459773Snilay@cs.wisc.edu code('case ${{self.c_ident}}_${{enum.ident}}:') 74611283Santhony.gutierrez@amd.com if enum.primary: 7479773Snilay@cs.wisc.edu code('return ${{enum.ident}}_Controller::getNumControllers();') 7489773Snilay@cs.wisc.edu else: 7499773Snilay@cs.wisc.edu code('return 0;') 7506657Snate@binkert.org 7516657Snate@binkert.org # total num 7526657Snate@binkert.org code(''' 7536657Snate@binkert.org case ${{self.c_ident}}_NUM: 7546657Snate@binkert.org default: 7557805Snilay@cs.wisc.edu panic("Invalid range for type ${{self.c_ident}}"); 7566657Snate@binkert.org } 7576657Snate@binkert.org} 7586657Snate@binkert.org''') 7596657Snate@binkert.org 7608602Snilay@cs.wisc.edu for enum in self.enums.itervalues(): 7618602Snilay@cs.wisc.edu if enum.ident == "DMA": 7628602Snilay@cs.wisc.edu code(''' 7638602Snilay@cs.wisc.eduMachineID 76411025Snilay@cs.wisc.edumap_Address_to_DMA(const Addr &addr) 7658602Snilay@cs.wisc.edu{ 7668602Snilay@cs.wisc.edu MachineID dma = {MachineType_DMA, 0}; 7678602Snilay@cs.wisc.edu return dma; 7688602Snilay@cs.wisc.edu} 7698602Snilay@cs.wisc.edu''') 7708602Snilay@cs.wisc.edu 7718602Snilay@cs.wisc.edu code(''' 7728602Snilay@cs.wisc.edu 7738602Snilay@cs.wisc.eduMachineID 7748602Snilay@cs.wisc.eduget${{enum.ident}}MachineID(NodeID RubyNode) 7758602Snilay@cs.wisc.edu{ 7768602Snilay@cs.wisc.edu MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; 7778602Snilay@cs.wisc.edu return mach; 7788602Snilay@cs.wisc.edu} 7798602Snilay@cs.wisc.edu''') 7808602Snilay@cs.wisc.edu 7816657Snate@binkert.org # Write the file 7826657Snate@binkert.org code.write(path, "%s.cc" % self.c_ident) 7836657Snate@binkert.org 7846657Snate@binkert.org__all__ = [ "Type" ] 785