2 Copyright (c) 2002-2009 Tampere University.
4 This file is part of TTA-Based Codesign Environment (TCE).
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
27 * Inline implementation of Machine class.
29 * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30 * @note reviewed 16 Jun 2004 by ml, tr, jm, ll
34#include "Application.hh"
36#include "AddressSpace.hh"
38#include "FunctionUnit.hh"
40#include "ImmediateUnit.hh"
41#include "InstructionTemplate.hh"
42#include "RegisterFile.hh"
43#include "ImmediateSlot.hh"
44#include "ContainerTools.hh"
49 * Template method which adds the given component to machine into the given
52 * This method is used for components that can be independently without
55 * @param container The container of the machine to which the component is
57 * @param toAdd The component to add.
58 * @exception ComponentAlreadyExists If there is already another component
59 * by the same name in the container.
61template <typename ContainerType, typename ComponentType>
63Machine::addComponent(ContainerType& container, ComponentType& toAdd) {
64 if (container.item(toAdd.name()) != NULL) {
65 const std::string procName = "Machine::addComponent";
66 throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
69 if (toAdd.machine() == NULL) {
70 toAdd.setMachine(*this);
72 container.addComponent(&toAdd);
77 * Template method which adds the given component to machine into the given
80 * This method is used for components that cannot be independently without
83 * @param container The container of the machine to which the component is
85 * @param toAdd The component to add.
86 * @exception ComponentAlreadyExists If there is already another component
87 * by the same name in the container.
89template <typename ContainerType, typename ComponentType>
91Machine::addRegisteredComponent(
92 ContainerType& container, ComponentType& toAdd) {
93 if (container.item(toAdd.name()) != NULL) {
94 const std::string procName = "Machine::addRegisteredComponent";
95 throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
98 // run time check to verify that this is called from the constructor
99 // of the component only
100 assert(toAdd.machine() == NULL);
101 container.addComponent(&toAdd);
105 * Template method which removes the given component from machine from the
108 * @param container The container of the machine from which the component is
110 * @param toRemove The component to remove.
111 * @exception InstanceNotFound If the given component does not exist in the
114template <typename ContainerType, typename ComponentType>
116Machine::removeComponent(ContainerType& container, ComponentType& toRemove) {
117 if (container.item(toRemove.name()) != &toRemove) {
118 std::string procName = "Machine::removeComponent";
119 throw InstanceNotFound(__FILE__, __LINE__, procName);
122 if (toRemove.machine() == NULL) {
123 container.removeComponent(&toRemove);
125 toRemove.unsetMachine();
130 * Template method which deletes the given component from machine from the
133 * @param container The container of the machine from which the component is
135 * @param toDelete The component to deleted.
136 * @exception InstanceNotFound If the given component does not exist in the
139template <typename ContainerType, typename ComponentType>
141Machine::deleteComponent(ContainerType& container, ComponentType& toDelete) {
142 std::string componentName = toDelete.name();
143 if (container.item(componentName) != &toDelete) {
144 std::string procName = "Machine::deleteComponent";
145 throw InstanceNotFound(__FILE__, __LINE__, procName);
148 if (toDelete.machine() == NULL) {
149 container.removeComponent(&toDelete);
155/////////////////////////////////////////////////////////////////////////////
157/////////////////////////////////////////////////////////////////////////////
162 * @param container The container which the navigator handles.
164template <typename ComponentType>
165Machine::Navigator<ComponentType>::Navigator(
166 const Machine::ComponentContainer<ComponentType>& container) :
167 container_(&container) {
174template <typename ComponentType>
175Machine::Navigator<ComponentType>::~Navigator() {
182 * @param old The old Navigator from which a copy is taken.
184template <typename ComponentType>
185Machine::Navigator<ComponentType>::Navigator(const Navigator& old) :
186 container_(old.container_) {
191 * Assignment operator.
193 * @param old The Navigator which is assigned to this Navigator.
194 * @return Reference to this navigator.
196template <typename ComponentType>
197Machine::Navigator<ComponentType>&
198Machine::Navigator<ComponentType>::operator=(const Navigator& old) {
200 container_ = old.container_;
207 * Returns an item with the given index in the container.
209 * @param index The index of the returned item.
210 * @return An item with the given index in the container.
211 * @exception OutOfRange If the given index is less than 0 or greater or
212 * equal to the number of items in the navigator.
214template <typename ComponentType>
216Machine::Navigator<ComponentType>::item(int index) const {
217 if (index < 0 || index >= count()) {
218 const std::string procName = "Machine::Navigator::item";
219 throw OutOfRange(__FILE__, __LINE__, procName);
221 return container_->item(index);
225 * Returns an item with the given name.
227 * @param name The name of the returned item.
228 * @return An item with the given name.
229 * @exception InstanceNotFound If an item is not found by the given name.
231template <typename ComponentType>
233Machine::Navigator<ComponentType>::item(const std::string& name) const {
234 ComponentType* component = container_->item(name);
235 if (component != NULL) {
238 std::string msg = "Component with name: " + name +
239 "Not found in navigator.";
240 throw InstanceNotFound(__FILE__, __LINE__, __func__, msg);
245 * Returns true if a component with the given name is found,
248 * @param name Name of the component.
249 * @return True if a component with the given name is found.
251template <typename ComponentType>
253Machine::Navigator<ComponentType>::hasItem(const std::string& name) const {
254 return (container_->item(name) != NULL);
259 * Returns the item count in the container.
261 * @return Item count in the container.
263template <typename ComponentType>
265Machine::Navigator<ComponentType>::count() const {
266 return container_->count();
270 * Returns an iterator at the beginning of the container.
273template <typename ComponentType>
274typename Machine::Navigator<ComponentType>::const_iterator
275Machine::Navigator<ComponentType>::begin() const noexcept {
276 return container_->begin();
280 * Returns an iterator to the end of the container.
283template <typename ComponentType>
284typename Machine::Navigator<ComponentType>::const_iterator
285Machine::Navigator<ComponentType>::end() const noexcept {
286 return container_->end();
289/////////////////////////////////////////////////////////////////////////////
290// Machine::ComponentContainer
291/////////////////////////////////////////////////////////////////////////////
296template <typename ComponentType>
297Machine::ComponentContainer<ComponentType>::ComponentContainer() {
304template <typename ComponentType>
305Machine::ComponentContainer<ComponentType>::~ComponentContainer() {
311 * Adds component into the container.
313 * @param component Component to be added.
315template <typename ComponentType>
317Machine::ComponentContainer<ComponentType>::addComponent(
318 ComponentType* component) {
320 components_.push_back(component);
325 * Removes component from the container.
327 * @param component Component to be removed.
329template <typename ComponentType>
331Machine::ComponentContainer<ComponentType>::removeComponent(
332 ComponentType* component) {
334 typename ComponentTable::iterator iter = components_.begin();
335 while (iter != components_.end()) {
336 if (*iter == component) {
337 components_.erase(iter);
348 * Deletes all the components in the container.
350 * Calls each component's destructor.
352template <typename ComponentType>
354Machine::ComponentContainer<ComponentType>::deleteAll() {
355 // vector size is reduced when the code in component's destructor is
357 while (count() > 0) {
358 delete components_[0];
364 * Searches component from the container by name.
366 * Returns null pointer if the requested component was not found.
368 * @param name Name of the component.
369 * @return Component with the given name.
371template <typename ComponentType>
373Machine::ComponentContainer<ComponentType>::item(
374 const std::string& name) const {
376 typename ComponentTable::const_iterator iter = components_.begin();
377 while (iter != components_.end()) {
378 if ((*iter)->name() == name) {
388 * Searches component from the container by index.
390 * Returns null pointer if the requested component was not found.
392 * @param index Index of the component in the container.
393 * @return Component with the given index.
395template <typename ComponentType>
397Machine::ComponentContainer<ComponentType>::item(int index) const {
399 if (static_cast<size_t>(index) >= components_.size() || index < 0) {
402 return components_[index];
408 * Returns the number of components in the container.
410 * @return Number of components in the container.
412template <typename ComponentType>
414Machine::ComponentContainer<ComponentType>::count() const {
415 return components_.size();
420 * Moves the given component to the given position in the container.
422 * @param component The component to be moved.
423 * @param position The new position.
424 * @exception InstanceNotFound If the given component does not exist in the
426 * @exception OutOfRange If the given position is less than 0 or not smaller
427 * than the number of components in the container.
429template <typename ComponentType>
431Machine::ComponentContainer<ComponentType>::moveToPosition(
432 const ComponentType* component, int position) {
433 const std::string procName =
434 "Machine::ComponentContainer::moveToPosition";
436 if (!ContainerTools::containsValue(components_, component)) {
437 throw InstanceNotFound(__FILE__, __LINE__, procName);
440 static_cast<size_t>(position) >= components_.size()) {
441 throw OutOfRange(__FILE__, __LINE__, procName);
444 // remove the component from the container
445 for (typename ComponentTable::iterator iter = components_.begin();
446 iter != components_.end(); iter++) {
447 if (*iter == component) {
448 components_.erase(iter);
453 // add the component again to the correct place
454 typename ComponentTable::iterator addIter = components_.begin();
456 components_.insert(addIter, const_cast<ComponentType*>(component));
460 * Returns an iterator at the beginning of the container.
463template <typename ComponentType>
464typename Machine::ComponentContainer<ComponentType>::const_iterator
465Machine::ComponentContainer<ComponentType>::begin() const noexcept {
466 return components_.cbegin();
470 * Returns an iterator to the end of the container.
473template <typename ComponentType>
474typename Machine::ComponentContainer<ComponentType>::const_iterator
475Machine::ComponentContainer<ComponentType>::end() const noexcept {
476 return components_.cend();