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"
46 namespace TTAMachine {
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.
61 template <typename ContainerType, typename ComponentType>
63 Machine::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.
89 template <typename ContainerType, typename ComponentType>
91 Machine::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
114 template <typename ContainerType, typename ComponentType>
116 Machine::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
139 template <typename ContainerType, typename ComponentType>
141 Machine::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 /////////////////////////////////////////////////////////////////////////////
156 // Machine::Navigator
157 /////////////////////////////////////////////////////////////////////////////
162 * @param container The container which the navigator handles.
164 template <typename ComponentType>
165 Machine::Navigator<ComponentType>::Navigator(
166 const Machine::ComponentContainer<ComponentType>& container) :
167 container_(&container) {
174 template <typename ComponentType>
175 Machine::Navigator<ComponentType>::~Navigator() {
182 * @param old The old Navigator from which a copy is taken.
184 template <typename ComponentType>
185 Machine::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.
196 template <typename ComponentType>
197 Machine::Navigator<ComponentType>&
198 Machine::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.
214 template <typename ComponentType>
216 Machine::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.
231 template <typename ComponentType>
233 Machine::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.
251 template <typename ComponentType>
253 Machine::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.
263 template <typename ComponentType>
265 Machine::Navigator<ComponentType>::count() const {
266 return container_->count();
270 * Returns an iterator at the beginning of the container.
273 template <typename ComponentType>
274 typename Machine::Navigator<ComponentType>::const_iterator
275 Machine::Navigator<ComponentType>::begin() const noexcept {
276 return container_->begin();
280 * Returns an iterator to the end of the container.
283 template <typename ComponentType>
284 typename Machine::Navigator<ComponentType>::const_iterator
285 Machine::Navigator<ComponentType>::end() const noexcept {
286 return container_->end();
289 /////////////////////////////////////////////////////////////////////////////
290 // Machine::ComponentContainer
291 /////////////////////////////////////////////////////////////////////////////
296 template <typename ComponentType>
297 Machine::ComponentContainer<ComponentType>::ComponentContainer() {
304 template <typename ComponentType>
305 Machine::ComponentContainer<ComponentType>::~ComponentContainer() {
311 * Adds component into the container.
313 * @param component Component to be added.
315 template <typename ComponentType>
317 Machine::ComponentContainer<ComponentType>::addComponent(
318 ComponentType* component) {
320 components_.push_back(component);
325 * Removes component from the container.
327 * @param component Component to be removed.
329 template <typename ComponentType>
331 Machine::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.
352 template <typename ComponentType>
354 Machine::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.
371 template <typename ComponentType>
373 Machine::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.
395 template <typename ComponentType>
397 Machine::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.
412 template <typename ComponentType>
414 Machine::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.
429 template <typename ComponentType>
431 Machine::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.
463 template <typename ComponentType>
464 typename Machine::ComponentContainer<ComponentType>::const_iterator
465 Machine::ComponentContainer<ComponentType>::begin() const noexcept {
466 return components_.cbegin();
470 * Returns an iterator to the end of the container.
473 template <typename ComponentType>
474 typename Machine::ComponentContainer<ComponentType>::const_iterator
475 Machine::ComponentContainer<ComponentType>::end() const noexcept {
476 return components_.cend();