110458Sandreas.hansson@arm.com/* 210458Sandreas.hansson@arm.com * Copyright (c) 2014 ARM Limited 310458Sandreas.hansson@arm.com * All rights reserved 410458Sandreas.hansson@arm.com * 510458Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610458Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 710458Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 810458Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 910458Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1010458Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1110458Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1210458Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1310458Sandreas.hansson@arm.com * 1410458Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 1510458Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 1610458Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1710458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1810458Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1910458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2010458Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2110458Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2210458Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2310458Sandreas.hansson@arm.com * this software without specific prior written permission. 2410458Sandreas.hansson@arm.com * 2510458Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610458Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710458Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810458Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910458Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010458Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110458Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210458Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310458Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410458Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510458Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610458Sandreas.hansson@arm.com * 3710458Sandreas.hansson@arm.com * Authors: Andrew Bardsley 3810458Sandreas.hansson@arm.com */ 3910458Sandreas.hansson@arm.com 4011793Sbrandon.potter@amd.com#include "sim/cxx_manager.hh" 4111793Sbrandon.potter@amd.com 4210458Sandreas.hansson@arm.com#include <cstdlib> 4310458Sandreas.hansson@arm.com#include <sstream> 4410458Sandreas.hansson@arm.com 4510458Sandreas.hansson@arm.com#include "base/str.hh" 4611800Sbrandon.potter@amd.com#include "base/trace.hh" 4710458Sandreas.hansson@arm.com#include "debug/CxxConfig.hh" 4810458Sandreas.hansson@arm.com#include "sim/serialize.hh" 4913892Sgabeblack@google.com#include "sim/sim_object.hh" 5010458Sandreas.hansson@arm.com 5110458Sandreas.hansson@arm.comCxxConfigManager::CxxConfigManager(CxxConfigFileBase &configFile_) : 5210458Sandreas.hansson@arm.com configFile(configFile_), flags(configFile_.getFlags()), 5310458Sandreas.hansson@arm.com simObjectResolver(*this) 5410458Sandreas.hansson@arm.com{ 5510458Sandreas.hansson@arm.com} 5610458Sandreas.hansson@arm.com 5710458Sandreas.hansson@arm.comconst CxxConfigDirectoryEntry & 5810458Sandreas.hansson@arm.comCxxConfigManager::findObjectType(const std::string &object_name, 5910458Sandreas.hansson@arm.com std::string &object_type) 6010458Sandreas.hansson@arm.com{ 6110458Sandreas.hansson@arm.com if (!configFile.objectExists(object_name)) 6210458Sandreas.hansson@arm.com throw Exception(object_name, "Can't find sim object"); 6310458Sandreas.hansson@arm.com 6410458Sandreas.hansson@arm.com if (!configFile.getParam(object_name, "type", object_type)) 6510458Sandreas.hansson@arm.com throw Exception(object_name, "Sim object has no 'type' field"); 6610458Sandreas.hansson@arm.com 6710458Sandreas.hansson@arm.com if (cxx_config_directory.find(object_type) == 6810458Sandreas.hansson@arm.com cxx_config_directory.end()) 6910458Sandreas.hansson@arm.com { 7010458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 7110458Sandreas.hansson@arm.com "No sim object type %s is available", object_type)); 7210458Sandreas.hansson@arm.com } 7310458Sandreas.hansson@arm.com 7410458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry *entry = cxx_config_directory[object_type]; 7510458Sandreas.hansson@arm.com 7610458Sandreas.hansson@arm.com return *entry; 7710458Sandreas.hansson@arm.com} 7810458Sandreas.hansson@arm.com 7910458Sandreas.hansson@arm.comstd::string 8010458Sandreas.hansson@arm.comCxxConfigManager::rename(const std::string &from_name) 8110458Sandreas.hansson@arm.com{ 8210458Sandreas.hansson@arm.com for (auto i = renamings.begin(); i != renamings.end(); ++ i) { 8310458Sandreas.hansson@arm.com const Renaming &renaming = *i; 8410458Sandreas.hansson@arm.com 8510458Sandreas.hansson@arm.com if (from_name.find(renaming.fromPrefix) == 0) { 8610458Sandreas.hansson@arm.com return renaming.toPrefix + 8710458Sandreas.hansson@arm.com from_name.substr(renaming.fromPrefix.length()); 8810458Sandreas.hansson@arm.com } 8910458Sandreas.hansson@arm.com } 9010458Sandreas.hansson@arm.com 9110458Sandreas.hansson@arm.com return from_name; 9210458Sandreas.hansson@arm.com} 9310458Sandreas.hansson@arm.com 9410458Sandreas.hansson@arm.comstd::string 9510458Sandreas.hansson@arm.comCxxConfigManager::unRename(const std::string &to_name) 9610458Sandreas.hansson@arm.com{ 9710458Sandreas.hansson@arm.com for (auto i = renamings.begin(); i != renamings.end(); ++ i) { 9810458Sandreas.hansson@arm.com const Renaming &renaming = *i; 9910458Sandreas.hansson@arm.com 10010458Sandreas.hansson@arm.com if (to_name.find(renaming.toPrefix) == 0) { 10110458Sandreas.hansson@arm.com return renaming.fromPrefix + 10210458Sandreas.hansson@arm.com to_name.substr(renaming.toPrefix.length()); 10310458Sandreas.hansson@arm.com } 10410458Sandreas.hansson@arm.com } 10510458Sandreas.hansson@arm.com 10610458Sandreas.hansson@arm.com return to_name; 10710458Sandreas.hansson@arm.com} 10810458Sandreas.hansson@arm.com 10910458Sandreas.hansson@arm.comstatic 11010458Sandreas.hansson@arm.comstd::string formatParamList(const std::vector<std::string> ¶m_values) 11110458Sandreas.hansson@arm.com{ 11210458Sandreas.hansson@arm.com std::ostringstream params; 11310458Sandreas.hansson@arm.com 11410458Sandreas.hansson@arm.com auto i = param_values.begin(); 11510458Sandreas.hansson@arm.com auto end_i = param_values.end(); 11610458Sandreas.hansson@arm.com 11710458Sandreas.hansson@arm.com params << '['; 11810458Sandreas.hansson@arm.com while (i != end_i) { 11910458Sandreas.hansson@arm.com params << (*i); 12010458Sandreas.hansson@arm.com ++i; 12110458Sandreas.hansson@arm.com 12210458Sandreas.hansson@arm.com if (i != end_i) 12310458Sandreas.hansson@arm.com params << ", "; 12410458Sandreas.hansson@arm.com } 12510458Sandreas.hansson@arm.com params << ']'; 12610458Sandreas.hansson@arm.com 12710458Sandreas.hansson@arm.com return params.str(); 12810458Sandreas.hansson@arm.com} 12910458Sandreas.hansson@arm.com 13010458Sandreas.hansson@arm.comSimObject * 13110458Sandreas.hansson@arm.comCxxConfigManager::findObject(const std::string &object_name, 13210458Sandreas.hansson@arm.com bool visit_children) 13310458Sandreas.hansson@arm.com{ 13410458Sandreas.hansson@arm.com std::string instance_name = rename(object_name); 13510458Sandreas.hansson@arm.com 13610458Sandreas.hansson@arm.com if (object_name == "Null") 13710458Sandreas.hansson@arm.com return NULL; 13810458Sandreas.hansson@arm.com 13910458Sandreas.hansson@arm.com /* Already constructed */ 14010458Sandreas.hansson@arm.com if (objectsByName.find(instance_name) != objectsByName.end()) 14110458Sandreas.hansson@arm.com return objectsByName[instance_name]; 14210458Sandreas.hansson@arm.com 14310458Sandreas.hansson@arm.com if (inVisit.find(instance_name) != inVisit.end()) 14410458Sandreas.hansson@arm.com throw Exception(instance_name, "Cycle in configuration"); 14510458Sandreas.hansson@arm.com 14610458Sandreas.hansson@arm.com std::string object_type; 14710458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry &entry = 14810458Sandreas.hansson@arm.com findObjectType(object_name, object_type); 14910458Sandreas.hansson@arm.com 15010458Sandreas.hansson@arm.com SimObject *object = NULL; 15110458Sandreas.hansson@arm.com 15210458Sandreas.hansson@arm.com CxxConfigParams *object_params = findObjectParams(object_name); 15310458Sandreas.hansson@arm.com 15410458Sandreas.hansson@arm.com try { 15510458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Configuring sim object references for: %s" 15610458Sandreas.hansson@arm.com " (%s from object %s)\n", instance_name, object_type, 15710458Sandreas.hansson@arm.com object_name); 15810458Sandreas.hansson@arm.com 15910458Sandreas.hansson@arm.com /* Remember the path back to the top of the recursion to detect 16010458Sandreas.hansson@arm.com * cycles */ 16110458Sandreas.hansson@arm.com inVisit.insert(instance_name); 16210458Sandreas.hansson@arm.com 16310458Sandreas.hansson@arm.com /* Resolve pointed-to SimObjects by recursing into them */ 16410458Sandreas.hansson@arm.com for (auto i = entry.parameters.begin(); 16510458Sandreas.hansson@arm.com i != entry.parameters.end(); ++i) 16610458Sandreas.hansson@arm.com { 16710458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second; 16810458Sandreas.hansson@arm.com 16910458Sandreas.hansson@arm.com if (param->isSimObject) { 17010458Sandreas.hansson@arm.com if (param->isVector) { 17110458Sandreas.hansson@arm.com std::vector<std::string> sub_object_names; 17210458Sandreas.hansson@arm.com 17310458Sandreas.hansson@arm.com if (!configFile.getParamVector(object_name, param->name, 17410458Sandreas.hansson@arm.com sub_object_names)) 17510458Sandreas.hansson@arm.com { 17610458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 17710458Sandreas.hansson@arm.com "Element not found: %s", param->name)); 17810458Sandreas.hansson@arm.com } 17910458Sandreas.hansson@arm.com 18010458Sandreas.hansson@arm.com std::vector<SimObject *> sub_objects; 18110458Sandreas.hansson@arm.com 18210458Sandreas.hansson@arm.com for (auto n = sub_object_names.begin(); 18310458Sandreas.hansson@arm.com n != sub_object_names.end(); ++n) 18410458Sandreas.hansson@arm.com { 18510458Sandreas.hansson@arm.com SimObject *sub_object = findObject(*n, 18610458Sandreas.hansson@arm.com visit_children); 18710458Sandreas.hansson@arm.com 18810458Sandreas.hansson@arm.com if (sub_object) 18910458Sandreas.hansson@arm.com sub_objects.push_back(sub_object); 19010458Sandreas.hansson@arm.com } 19110458Sandreas.hansson@arm.com 19210458Sandreas.hansson@arm.com if (!object_params->setSimObjectVector(param->name, 19310458Sandreas.hansson@arm.com sub_objects)) 19410458Sandreas.hansson@arm.com { 19510458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 19610458Sandreas.hansson@arm.com "Can't assign sim object element %s from \"%s\"", 19710458Sandreas.hansson@arm.com param->name, formatParamList(sub_object_names))); 19810458Sandreas.hansson@arm.com } 19910458Sandreas.hansson@arm.com 20010458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting sim object(s): %s.%s=%s\n", 20110458Sandreas.hansson@arm.com object_name, param->name, 20210458Sandreas.hansson@arm.com formatParamList(sub_object_names)); 20310458Sandreas.hansson@arm.com } else { 20410458Sandreas.hansson@arm.com std::string sub_object_name; 20510458Sandreas.hansson@arm.com 20610458Sandreas.hansson@arm.com if (!configFile.getParam(object_name, param->name, 20710458Sandreas.hansson@arm.com sub_object_name)) 20810458Sandreas.hansson@arm.com { 20910458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 21010458Sandreas.hansson@arm.com "Element not found: %s", param->name)); 21110458Sandreas.hansson@arm.com } 21210458Sandreas.hansson@arm.com 21310458Sandreas.hansson@arm.com SimObject *sub_object = findObject(sub_object_name, 21410458Sandreas.hansson@arm.com visit_children); 21510458Sandreas.hansson@arm.com 21610458Sandreas.hansson@arm.com if (sub_object) { 21710458Sandreas.hansson@arm.com if (!object_params->setSimObject(param->name, 21810458Sandreas.hansson@arm.com sub_object)) 21910458Sandreas.hansson@arm.com { 22010458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 22110458Sandreas.hansson@arm.com "Can't assign sim object element %s from" 22210458Sandreas.hansson@arm.com " \"%s\"", param->name, sub_object_name)); 22310458Sandreas.hansson@arm.com } 22410458Sandreas.hansson@arm.com } 22510458Sandreas.hansson@arm.com 22610458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting sim object(s):" 22710458Sandreas.hansson@arm.com " %s.%s=%s\n", object_name, param->name, 22810458Sandreas.hansson@arm.com sub_object_name); 22910458Sandreas.hansson@arm.com } 23010458Sandreas.hansson@arm.com } 23110458Sandreas.hansson@arm.com } 23210458Sandreas.hansson@arm.com 23310458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Creating SimObject: %s\n", instance_name); 23410458Sandreas.hansson@arm.com object = object_params->simObjectCreate(); 23510458Sandreas.hansson@arm.com 23610458Sandreas.hansson@arm.com if (!object) { 23710458Sandreas.hansson@arm.com throw Exception(object_name, csprintf("Couldn't create object of" 23810458Sandreas.hansson@arm.com " type: %s", object_type)); 23910458Sandreas.hansson@arm.com } 24010458Sandreas.hansson@arm.com 24110458Sandreas.hansson@arm.com objectsByName[instance_name] = object; 24210458Sandreas.hansson@arm.com objectParamsByName[instance_name] = object_params; 24310458Sandreas.hansson@arm.com 24410458Sandreas.hansson@arm.com if (visit_children) { 24510458Sandreas.hansson@arm.com std::vector<std::string> children; 24610458Sandreas.hansson@arm.com configFile.getObjectChildren(object_name, children, true); 24710458Sandreas.hansson@arm.com 24810458Sandreas.hansson@arm.com /* Visit all your children */ 24910458Sandreas.hansson@arm.com for (auto i = children.begin(); i != children.end(); ++i) 25010458Sandreas.hansson@arm.com findObject(*i, visit_children); 25110458Sandreas.hansson@arm.com } 25210458Sandreas.hansson@arm.com } catch (Exception &) { 25310458Sandreas.hansson@arm.com delete object_params; 25410458Sandreas.hansson@arm.com throw; 25510458Sandreas.hansson@arm.com } 25610458Sandreas.hansson@arm.com 25710458Sandreas.hansson@arm.com /* Mark that we've exited object 25810458Sandreas.hansson@arm.com * construction and so 'find'ing this object again won't be a 25910458Sandreas.hansson@arm.com * configuration loop */ 26010458Sandreas.hansson@arm.com inVisit.erase(object_name); 26110458Sandreas.hansson@arm.com return object; 26210458Sandreas.hansson@arm.com} 26310458Sandreas.hansson@arm.com 26410458Sandreas.hansson@arm.comCxxConfigParams * 26510458Sandreas.hansson@arm.comCxxConfigManager::findObjectParams(const std::string &object_name) 26610458Sandreas.hansson@arm.com{ 26710458Sandreas.hansson@arm.com std::string instance_name = rename(object_name); 26810458Sandreas.hansson@arm.com 26910458Sandreas.hansson@arm.com /* Already constructed */ 27010458Sandreas.hansson@arm.com if (objectParamsByName.find(instance_name) != objectParamsByName.end()) 27110458Sandreas.hansson@arm.com return objectParamsByName[instance_name]; 27210458Sandreas.hansson@arm.com 27310458Sandreas.hansson@arm.com std::string object_type; 27410458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry &entry = 27510458Sandreas.hansson@arm.com findObjectType(object_name, object_type); 27610458Sandreas.hansson@arm.com 27710458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Configuring parameters of object: %s (%s)\n", 27810458Sandreas.hansson@arm.com instance_name, object_type); 27910458Sandreas.hansson@arm.com 28010458Sandreas.hansson@arm.com CxxConfigParams *object_params = entry.makeParamsObject(); 28110458Sandreas.hansson@arm.com 28210458Sandreas.hansson@arm.com try { 28310458Sandreas.hansson@arm.com /* Fill in the implicit parameters that don't necessarily 28410458Sandreas.hansson@arm.com * appear in config files */ 28510458Sandreas.hansson@arm.com object_params->setName(instance_name); 28610458Sandreas.hansson@arm.com 28710458Sandreas.hansson@arm.com /* Fill in parameters */ 28810458Sandreas.hansson@arm.com for (auto i = entry.parameters.begin(); 28910458Sandreas.hansson@arm.com i != entry.parameters.end(); ++i) 29010458Sandreas.hansson@arm.com { 29110458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second; 29210458Sandreas.hansson@arm.com 29310458Sandreas.hansson@arm.com if (!param->isSimObject) { 29410458Sandreas.hansson@arm.com /* Only handle non-SimObject parameters here (see below) */ 29510458Sandreas.hansson@arm.com 29610458Sandreas.hansson@arm.com if (param->isVector) { 29710458Sandreas.hansson@arm.com std::vector<std::string> param_values; 29810458Sandreas.hansson@arm.com 29910458Sandreas.hansson@arm.com if (!configFile.getParamVector(object_name, param->name, 30010458Sandreas.hansson@arm.com param_values)) 30110458Sandreas.hansson@arm.com { 30210458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 30310458Sandreas.hansson@arm.com "Element not found for parameter: %s", 30410458Sandreas.hansson@arm.com param->name)); 30510458Sandreas.hansson@arm.com } 30610458Sandreas.hansson@arm.com 30710458Sandreas.hansson@arm.com if (!object_params->setParamVector(param->name, 30810458Sandreas.hansson@arm.com param_values, flags)) 30910458Sandreas.hansson@arm.com { 31010458Sandreas.hansson@arm.com throw Exception(instance_name, csprintf( 31110458Sandreas.hansson@arm.com "Bad parameter value: .%s=X=\"%s\"", 31210458Sandreas.hansson@arm.com param->name, formatParamList(param_values))); 31310458Sandreas.hansson@arm.com } 31410458Sandreas.hansson@arm.com 31510458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting parameter" 31610458Sandreas.hansson@arm.com " %s.%s=%s\n", instance_name, param->name, 31710458Sandreas.hansson@arm.com formatParamList(param_values)); 31810458Sandreas.hansson@arm.com } else { 31910458Sandreas.hansson@arm.com std::string param_value; 32010458Sandreas.hansson@arm.com 32110458Sandreas.hansson@arm.com if (!configFile.getParam(object_name, param->name, 32210458Sandreas.hansson@arm.com param_value)) 32310458Sandreas.hansson@arm.com { 32410458Sandreas.hansson@arm.com throw Exception(object_name, csprintf( 32510458Sandreas.hansson@arm.com "Element not found for parameter: %s", 32610458Sandreas.hansson@arm.com param->name)); 32710458Sandreas.hansson@arm.com } 32810458Sandreas.hansson@arm.com 32910458Sandreas.hansson@arm.com if (!object_params->setParam(param->name, param_value, 33010458Sandreas.hansson@arm.com flags)) 33110458Sandreas.hansson@arm.com { 33210458Sandreas.hansson@arm.com throw Exception(instance_name, csprintf( 33310458Sandreas.hansson@arm.com "Bad parameter value: .%s=X=\"%s\"", 33410458Sandreas.hansson@arm.com param->name, param_value)); 33510458Sandreas.hansson@arm.com } 33610458Sandreas.hansson@arm.com 33710458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n", 33810458Sandreas.hansson@arm.com instance_name, param->name, param_value); 33910458Sandreas.hansson@arm.com } 34010458Sandreas.hansson@arm.com } 34110458Sandreas.hansson@arm.com } 34210458Sandreas.hansson@arm.com 34310458Sandreas.hansson@arm.com /* Find the number of ports that will need binding and set the 34410458Sandreas.hansson@arm.com * appropriate port_..._connection_count parameters */ 34510458Sandreas.hansson@arm.com for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) { 34610458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::PortDesc *port = (*i).second; 34710458Sandreas.hansson@arm.com std::vector<std::string> peers; 34810458Sandreas.hansson@arm.com 34910458Sandreas.hansson@arm.com if (!configFile.getPortPeers(object_name, port->name, peers)) { 35010458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Port not found: %s.%s," 35110458Sandreas.hansson@arm.com " assuming there are no connections\n", 35210458Sandreas.hansson@arm.com instance_name, port->name); 35310458Sandreas.hansson@arm.com } 35410458Sandreas.hansson@arm.com 35510458Sandreas.hansson@arm.com unsigned int peer_count = peers.size(); 35610458Sandreas.hansson@arm.com 35710458Sandreas.hansson@arm.com /* It would be more efficient to split the peer list and 35810458Sandreas.hansson@arm.com * save the values for peer binding later but that would 35910458Sandreas.hansson@arm.com * require another annoying intermediate structure to 36010458Sandreas.hansson@arm.com * hold for little performance increase */ 36110458Sandreas.hansson@arm.com 36210458Sandreas.hansson@arm.com if (!object_params->setPortConnectionCount(port->name, 36310458Sandreas.hansson@arm.com peer_count)) 36410458Sandreas.hansson@arm.com { 36510458Sandreas.hansson@arm.com throw Exception(instance_name, csprintf( 36610458Sandreas.hansson@arm.com "Unconnected port: %s", port->name)); 36710458Sandreas.hansson@arm.com } 36810458Sandreas.hansson@arm.com 36910458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting port connection count" 37010458Sandreas.hansson@arm.com " for: %s.%s to %d\n", 37110458Sandreas.hansson@arm.com instance_name, port->name, peer_count); 37210458Sandreas.hansson@arm.com } 37310458Sandreas.hansson@arm.com 37410458Sandreas.hansson@arm.com /* Set pointed-to SimObjects to NULL */ 37510458Sandreas.hansson@arm.com for (auto i = entry.parameters.begin(); 37610458Sandreas.hansson@arm.com i != entry.parameters.end(); ++i) 37710458Sandreas.hansson@arm.com { 37810458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::ParamDesc *param = (*i).second; 37910458Sandreas.hansson@arm.com 38010458Sandreas.hansson@arm.com if (param->isSimObject) { 38110458Sandreas.hansson@arm.com bool ret; 38210458Sandreas.hansson@arm.com 38310458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Nulling sim object reference: %s.%s\n", 38410458Sandreas.hansson@arm.com instance_name, param->name); 38510458Sandreas.hansson@arm.com 38610458Sandreas.hansson@arm.com if (param->isVector) { 38710458Sandreas.hansson@arm.com /* Clear the reference list. */ 38810458Sandreas.hansson@arm.com std::vector<SimObject *> empty; 38910458Sandreas.hansson@arm.com ret = object_params->setSimObjectVector(param->name, 39010458Sandreas.hansson@arm.com empty); 39110458Sandreas.hansson@arm.com } else { 39210458Sandreas.hansson@arm.com ret = object_params->setSimObject(param->name, NULL); 39310458Sandreas.hansson@arm.com } 39410458Sandreas.hansson@arm.com 39510458Sandreas.hansson@arm.com if (!ret) { 39610458Sandreas.hansson@arm.com throw Exception(instance_name, csprintf( 39710458Sandreas.hansson@arm.com "Error nulling sim object reference(s): %s", 39810458Sandreas.hansson@arm.com param->name)); 39910458Sandreas.hansson@arm.com } 40010458Sandreas.hansson@arm.com } 40110458Sandreas.hansson@arm.com } 40210458Sandreas.hansson@arm.com } catch (Exception &) { 40310458Sandreas.hansson@arm.com delete object_params; 40410458Sandreas.hansson@arm.com throw; 40510458Sandreas.hansson@arm.com } 40610458Sandreas.hansson@arm.com 40710458Sandreas.hansson@arm.com objectParamsByName[instance_name] = object_params; 40810458Sandreas.hansson@arm.com 40910458Sandreas.hansson@arm.com return object_params; 41010458Sandreas.hansson@arm.com} 41110458Sandreas.hansson@arm.com 41210458Sandreas.hansson@arm.comvoid 41310458Sandreas.hansson@arm.comCxxConfigManager::findAllObjects() 41410458Sandreas.hansson@arm.com{ 41510458Sandreas.hansson@arm.com std::vector<std::string> objects; 41610458Sandreas.hansson@arm.com configFile.getAllObjectNames(objects); 41710458Sandreas.hansson@arm.com 41810458Sandreas.hansson@arm.com /* Set the traversal order for further iterators */ 41910458Sandreas.hansson@arm.com objectsInOrder.clear(); 42010458Sandreas.hansson@arm.com findTraversalOrder("root"); 42110458Sandreas.hansson@arm.com} 42210458Sandreas.hansson@arm.com 42310458Sandreas.hansson@arm.comvoid 42410458Sandreas.hansson@arm.comCxxConfigManager::findTraversalOrder(const std::string &object_name) 42510458Sandreas.hansson@arm.com{ 42610458Sandreas.hansson@arm.com SimObject *object = findObject(object_name); 42710458Sandreas.hansson@arm.com 42810458Sandreas.hansson@arm.com if (object) { 42910458Sandreas.hansson@arm.com objectsInOrder.push_back(object); 43010458Sandreas.hansson@arm.com 43110458Sandreas.hansson@arm.com std::vector<std::string> children; 43210458Sandreas.hansson@arm.com configFile.getObjectChildren(object_name, children, true); 43310458Sandreas.hansson@arm.com 43410458Sandreas.hansson@arm.com /* Visit all your children */ 43510458Sandreas.hansson@arm.com for (auto i = children.begin(); i != children.end(); ++i) 43610458Sandreas.hansson@arm.com findTraversalOrder(*i); 43710458Sandreas.hansson@arm.com } 43810458Sandreas.hansson@arm.com} 43910458Sandreas.hansson@arm.com 44010458Sandreas.hansson@arm.comvoid 44110458Sandreas.hansson@arm.comCxxConfigManager::bindAllPorts() 44210458Sandreas.hansson@arm.com{ 44310458Sandreas.hansson@arm.com for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i) 44410458Sandreas.hansson@arm.com bindObjectPorts(*i); 44510458Sandreas.hansson@arm.com} 44610458Sandreas.hansson@arm.com 44710458Sandreas.hansson@arm.comvoid 44810458Sandreas.hansson@arm.comCxxConfigManager::bindPort( 44910458Sandreas.hansson@arm.com SimObject *master_object, const std::string &master_port_name, 45010458Sandreas.hansson@arm.com PortID master_port_index, 45110458Sandreas.hansson@arm.com SimObject *slave_object, const std::string &slave_port_name, 45210458Sandreas.hansson@arm.com PortID slave_port_index) 45310458Sandreas.hansson@arm.com{ 45410458Sandreas.hansson@arm.com /* FIXME, check slave_port_index against connection_count 45510458Sandreas.hansson@arm.com * defined for port, need getPortConnectionCount and a 45610458Sandreas.hansson@arm.com * getCxxConfigDirectoryEntry for each object. */ 45710458Sandreas.hansson@arm.com 45810458Sandreas.hansson@arm.com /* It would be nice to be able to catch the errors from these calls. */ 45913892Sgabeblack@google.com Port &master_port = master_object->getPort( 46010458Sandreas.hansson@arm.com master_port_name, master_port_index); 46113892Sgabeblack@google.com Port &slave_port = slave_object->getPort( 46210458Sandreas.hansson@arm.com slave_port_name, slave_port_index); 46310458Sandreas.hansson@arm.com 46410458Sandreas.hansson@arm.com if (master_port.isConnected()) { 46510458Sandreas.hansson@arm.com throw Exception(master_object->name(), csprintf( 46610458Sandreas.hansson@arm.com "Master port: %s[%d] is already connected\n", master_port_name, 46710458Sandreas.hansson@arm.com master_port_index)); 46810458Sandreas.hansson@arm.com } 46910458Sandreas.hansson@arm.com 47010458Sandreas.hansson@arm.com if (slave_port.isConnected()) { 47110458Sandreas.hansson@arm.com throw Exception(slave_object->name(), csprintf( 47210458Sandreas.hansson@arm.com "Slave port: %s[%d] is already connected\n", slave_port_name, 47310458Sandreas.hansson@arm.com slave_port_index)); 47410458Sandreas.hansson@arm.com } 47510458Sandreas.hansson@arm.com 47610458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Binding port %s.%s[%d]" 47710458Sandreas.hansson@arm.com " to %s:%s[%d]\n", 47810458Sandreas.hansson@arm.com master_object->name(), master_port_name, master_port_index, 47910458Sandreas.hansson@arm.com slave_object->name(), slave_port_name, slave_port_index); 48010458Sandreas.hansson@arm.com 48110458Sandreas.hansson@arm.com master_port.bind(slave_port); 48210458Sandreas.hansson@arm.com} 48310458Sandreas.hansson@arm.com 48410458Sandreas.hansson@arm.comvoid 48510458Sandreas.hansson@arm.comCxxConfigManager::bindMasterPort(SimObject *object, 48610458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::PortDesc &port, 48710458Sandreas.hansson@arm.com const std::vector<std::string> &peers) 48810458Sandreas.hansson@arm.com{ 48910458Sandreas.hansson@arm.com unsigned int master_port_index = 0; 49010458Sandreas.hansson@arm.com 49110458Sandreas.hansson@arm.com for (auto peer_i = peers.begin(); peer_i != peers.end(); 49210458Sandreas.hansson@arm.com ++peer_i) 49310458Sandreas.hansson@arm.com { 49410458Sandreas.hansson@arm.com const std::string &peer = *peer_i; 49510458Sandreas.hansson@arm.com std::string slave_object_name; 49610458Sandreas.hansson@arm.com std::string slave_port_name; 49710458Sandreas.hansson@arm.com unsigned int slave_port_index; 49810458Sandreas.hansson@arm.com 49910458Sandreas.hansson@arm.com parsePort(peer, slave_object_name, slave_port_name, 50010458Sandreas.hansson@arm.com slave_port_index); 50110458Sandreas.hansson@arm.com 50210458Sandreas.hansson@arm.com std::string slave_instance_name = rename(slave_object_name); 50310458Sandreas.hansson@arm.com 50410458Sandreas.hansson@arm.com if (objectsByName.find(slave_instance_name) == objectsByName.end()) { 50510458Sandreas.hansson@arm.com throw Exception(object->name(), csprintf( 50610458Sandreas.hansson@arm.com "Can't find slave port object: %s", slave_instance_name)); 50710458Sandreas.hansson@arm.com } 50810458Sandreas.hansson@arm.com 50910458Sandreas.hansson@arm.com SimObject *slave_object = objectsByName[slave_instance_name]; 51010458Sandreas.hansson@arm.com 51110458Sandreas.hansson@arm.com bindPort(object, port.name, master_port_index, 51210458Sandreas.hansson@arm.com slave_object, slave_port_name, slave_port_index); 51310458Sandreas.hansson@arm.com 51410458Sandreas.hansson@arm.com master_port_index++; 51510458Sandreas.hansson@arm.com } 51610458Sandreas.hansson@arm.com} 51710458Sandreas.hansson@arm.com 51810458Sandreas.hansson@arm.comvoid 51910458Sandreas.hansson@arm.comCxxConfigManager::bindObjectPorts(SimObject *object) 52010458Sandreas.hansson@arm.com{ 52110458Sandreas.hansson@arm.com /* We may want to separate object->name() from the name in configuration 52210458Sandreas.hansson@arm.com * later to allow (for example) repetition of fragments of configs */ 52310458Sandreas.hansson@arm.com const std::string &instance_name = object->name(); 52410458Sandreas.hansson@arm.com 52510458Sandreas.hansson@arm.com std::string object_name = unRename(instance_name); 52610458Sandreas.hansson@arm.com 52710458Sandreas.hansson@arm.com std::string object_type; 52810458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry &entry = 52910458Sandreas.hansson@arm.com findObjectType(object_name, object_type); 53010458Sandreas.hansson@arm.com 53110458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Binding ports of object: %s (%s)\n", 53210458Sandreas.hansson@arm.com instance_name, object_type); 53310458Sandreas.hansson@arm.com 53410458Sandreas.hansson@arm.com for (auto i = entry.ports.begin(); i != entry.ports.end(); ++i) { 53510458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::PortDesc *port = (*i).second; 53610458Sandreas.hansson@arm.com 53710458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Binding port: %s.%s\n", instance_name, 53810458Sandreas.hansson@arm.com port->name); 53910458Sandreas.hansson@arm.com 54010458Sandreas.hansson@arm.com std::vector<std::string> peers; 54110458Sandreas.hansson@arm.com configFile.getPortPeers(object_name, port->name, peers); 54210458Sandreas.hansson@arm.com 54310458Sandreas.hansson@arm.com /* Only handle master ports as binding only needs to happen once 54410458Sandreas.hansson@arm.com * for each observed pair of ports */ 54510458Sandreas.hansson@arm.com if (port->isMaster) { 54610458Sandreas.hansson@arm.com if (!port->isVector && peers.size() > 1) { 54710458Sandreas.hansson@arm.com throw Exception(instance_name, csprintf( 54810458Sandreas.hansson@arm.com "Too many connections to non-vector port %s (%d)\n", 54910458Sandreas.hansson@arm.com port->name, peers.size())); 55010458Sandreas.hansson@arm.com } 55110458Sandreas.hansson@arm.com 55210458Sandreas.hansson@arm.com bindMasterPort(object, *port, peers); 55310458Sandreas.hansson@arm.com } 55410458Sandreas.hansson@arm.com } 55510458Sandreas.hansson@arm.com} 55610458Sandreas.hansson@arm.com 55710458Sandreas.hansson@arm.comvoid 55810458Sandreas.hansson@arm.comCxxConfigManager::parsePort(const std::string &inp, 55910458Sandreas.hansson@arm.com std::string &path, std::string &port, unsigned int &index) 56010458Sandreas.hansson@arm.com{ 56110458Sandreas.hansson@arm.com std::size_t dot_i = inp.rfind('.'); 56210458Sandreas.hansson@arm.com std::size_t open_square_i = inp.rfind('['); 56310458Sandreas.hansson@arm.com 56410458Sandreas.hansson@arm.com if (dot_i == std::string::npos) { 56510458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Bad port string: %s\n", inp); 56610458Sandreas.hansson@arm.com path = ""; 56710458Sandreas.hansson@arm.com port = ""; 56810458Sandreas.hansson@arm.com index = 0; 56910458Sandreas.hansson@arm.com } else { 57010458Sandreas.hansson@arm.com path = std::string(inp, 0, dot_i); 57110458Sandreas.hansson@arm.com 57210458Sandreas.hansson@arm.com if (open_square_i == std::string::npos) { 57310458Sandreas.hansson@arm.com /* Singleton port */ 57410458Sandreas.hansson@arm.com port = std::string(inp, dot_i + 1, inp.length() - dot_i); 57510458Sandreas.hansson@arm.com index = 0; 57610458Sandreas.hansson@arm.com } else { 57710458Sandreas.hansson@arm.com /* Vectored port elemnt */ 57810458Sandreas.hansson@arm.com port = std::string(inp, dot_i + 1, (open_square_i - 1) - dot_i); 57910458Sandreas.hansson@arm.com index = std::atoi(inp.c_str() + open_square_i + 1); 58010458Sandreas.hansson@arm.com } 58110458Sandreas.hansson@arm.com } 58210458Sandreas.hansson@arm.com} 58310458Sandreas.hansson@arm.com 58410458Sandreas.hansson@arm.comvoid 58510458Sandreas.hansson@arm.comCxxConfigManager::forEachObject(void (SimObject::*mem_func)()) 58610458Sandreas.hansson@arm.com{ 58710458Sandreas.hansson@arm.com for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++i) 58810458Sandreas.hansson@arm.com ((*i)->*mem_func)(); 58910458Sandreas.hansson@arm.com} 59010458Sandreas.hansson@arm.com 59110458Sandreas.hansson@arm.comvoid 59210458Sandreas.hansson@arm.comCxxConfigManager::instantiate(bool build_all) 59310458Sandreas.hansson@arm.com{ 59410458Sandreas.hansson@arm.com if (build_all) { 59510458Sandreas.hansson@arm.com findAllObjects(); 59610458Sandreas.hansson@arm.com bindAllPorts(); 59710458Sandreas.hansson@arm.com } 59810458Sandreas.hansson@arm.com 59910458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Initialising all objects\n"); 60010458Sandreas.hansson@arm.com forEachObject(&SimObject::init); 60110458Sandreas.hansson@arm.com 60210458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Registering stats\n"); 60310458Sandreas.hansson@arm.com forEachObject(&SimObject::regStats); 60410458Sandreas.hansson@arm.com 60510458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Registering probe points\n"); 60610458Sandreas.hansson@arm.com forEachObject(&SimObject::regProbePoints); 60710458Sandreas.hansson@arm.com 60810458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Connecting probe listeners\n"); 60910458Sandreas.hansson@arm.com forEachObject(&SimObject::regProbeListeners); 61010458Sandreas.hansson@arm.com} 61110458Sandreas.hansson@arm.com 61210458Sandreas.hansson@arm.comvoid 61310458Sandreas.hansson@arm.comCxxConfigManager::initState() 61410458Sandreas.hansson@arm.com{ 61510458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Calling initState on all objects\n"); 61610458Sandreas.hansson@arm.com forEachObject(&SimObject::initState); 61710458Sandreas.hansson@arm.com} 61810458Sandreas.hansson@arm.com 61910458Sandreas.hansson@arm.comvoid 62010458Sandreas.hansson@arm.comCxxConfigManager::startup() 62110458Sandreas.hansson@arm.com{ 62210458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Starting up all objects\n"); 62310458Sandreas.hansson@arm.com forEachObject(&SimObject::startup); 62410458Sandreas.hansson@arm.com} 62510458Sandreas.hansson@arm.com 62610458Sandreas.hansson@arm.comunsigned int 62710912Sandreas.sandberg@arm.comCxxConfigManager::drain() 62810458Sandreas.hansson@arm.com{ 62910912Sandreas.sandberg@arm.com return DrainManager::instance().tryDrain() ? 0 : 1; 63010458Sandreas.hansson@arm.com} 63110458Sandreas.hansson@arm.com 63210458Sandreas.hansson@arm.comvoid 63310458Sandreas.hansson@arm.comCxxConfigManager::drainResume() 63410458Sandreas.hansson@arm.com{ 63510912Sandreas.sandberg@arm.com DrainManager::instance().resume(); 63610458Sandreas.hansson@arm.com} 63710458Sandreas.hansson@arm.com 63810458Sandreas.hansson@arm.comvoid 63910458Sandreas.hansson@arm.comCxxConfigManager::serialize(std::ostream &os) 64010458Sandreas.hansson@arm.com{ 64110458Sandreas.hansson@arm.com for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i) { 64210458Sandreas.hansson@arm.com // (*i)->nameOut(os); FIXME, change access spec. for nameOut 64310458Sandreas.hansson@arm.com os << '[' << (*i)->name() << "]\n"; 64410458Sandreas.hansson@arm.com (*i)->serialize(os); 64510458Sandreas.hansson@arm.com } 64610458Sandreas.hansson@arm.com} 64710458Sandreas.hansson@arm.com 64810458Sandreas.hansson@arm.comvoid 64910905Sandreas.sandberg@arm.comCxxConfigManager::loadState(CheckpointIn &checkpoint) 65010458Sandreas.hansson@arm.com{ 65110458Sandreas.hansson@arm.com for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i) 65210458Sandreas.hansson@arm.com (*i)->loadState(checkpoint); 65310458Sandreas.hansson@arm.com} 65410458Sandreas.hansson@arm.com 65510458Sandreas.hansson@arm.comvoid 65610458Sandreas.hansson@arm.comCxxConfigManager::deleteObjects() 65710458Sandreas.hansson@arm.com{ 65810458Sandreas.hansson@arm.com for (auto i = objectsInOrder.rbegin(); i != objectsInOrder.rend(); ++i) { 65910458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Freeing sim object: %s\n", (*i)->name()); 66010458Sandreas.hansson@arm.com delete *i; 66110458Sandreas.hansson@arm.com } 66210458Sandreas.hansson@arm.com 66310458Sandreas.hansson@arm.com for (auto i = objectParamsByName.rbegin(); 66410458Sandreas.hansson@arm.com i != objectParamsByName.rend(); ++i) 66510458Sandreas.hansson@arm.com { 66610458Sandreas.hansson@arm.com CxxConfigParams *params = (*i).second; 66710458Sandreas.hansson@arm.com 66810458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Freeing sim object params: %s\n", 66910458Sandreas.hansson@arm.com params->getName()); 67010458Sandreas.hansson@arm.com delete params; 67110458Sandreas.hansson@arm.com } 67210458Sandreas.hansson@arm.com 67310458Sandreas.hansson@arm.com objectsInOrder.clear(); 67410458Sandreas.hansson@arm.com objectsByName.clear(); 67510458Sandreas.hansson@arm.com} 67610458Sandreas.hansson@arm.com 67710458Sandreas.hansson@arm.comvoid 67810458Sandreas.hansson@arm.comCxxConfigManager::setParam(const std::string &object_name, 67910458Sandreas.hansson@arm.com const std::string ¶m_name, const std::string ¶m_value) 68010458Sandreas.hansson@arm.com{ 68110458Sandreas.hansson@arm.com CxxConfigParams *params = findObjectParams(object_name); 68210458Sandreas.hansson@arm.com 68310458Sandreas.hansson@arm.com if (!params->setParam(param_name, param_value, flags)) { 68410458Sandreas.hansson@arm.com throw Exception(object_name, csprintf("Bad parameter value:" 68510458Sandreas.hansson@arm.com " .%s=X=\"%s\"", param_name, param_value)); 68610458Sandreas.hansson@arm.com } else { 68710458Sandreas.hansson@arm.com std::string instance_name = rename(object_name); 68810458Sandreas.hansson@arm.com 68910458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting parameter %s.%s=%s\n", 69010458Sandreas.hansson@arm.com instance_name, param_name, param_value); 69110458Sandreas.hansson@arm.com } 69210458Sandreas.hansson@arm.com} 69310458Sandreas.hansson@arm.com 69410458Sandreas.hansson@arm.comvoid 69510458Sandreas.hansson@arm.comCxxConfigManager::setParamVector(const std::string &object_name, 69610458Sandreas.hansson@arm.com const std::string ¶m_name, 69710458Sandreas.hansson@arm.com const std::vector<std::string> ¶m_values) 69810458Sandreas.hansson@arm.com{ 69910458Sandreas.hansson@arm.com CxxConfigParams *params = findObjectParams(object_name); 70010458Sandreas.hansson@arm.com 70110458Sandreas.hansson@arm.com if (!params->setParamVector(param_name, param_values, flags)) { 70210458Sandreas.hansson@arm.com throw Exception(object_name, csprintf("Bad vector parameter value:" 70310458Sandreas.hansson@arm.com " .%s=X=\"%s\"", param_name, formatParamList(param_values))); 70410458Sandreas.hansson@arm.com } else { 70510458Sandreas.hansson@arm.com std::string instance_name = rename(object_name); 70610458Sandreas.hansson@arm.com 70710458Sandreas.hansson@arm.com DPRINTF(CxxConfig, "Setting parameter %s.%s=\"%s\"\n", 70810458Sandreas.hansson@arm.com instance_name, param_name, formatParamList(param_values)); 70910458Sandreas.hansson@arm.com } 71010458Sandreas.hansson@arm.com} 71110458Sandreas.hansson@arm.com 71210458Sandreas.hansson@arm.comvoid CxxConfigManager::addRenaming(const Renaming &renaming) 71310458Sandreas.hansson@arm.com{ 71410458Sandreas.hansson@arm.com renamings.push_back(renaming); 71510458Sandreas.hansson@arm.com} 716