OpenASIP 2.2
Loading...
Searching...
No Matches
Machine.icc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
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:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
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.
23 */
24/**
25 * @file Machine.icc
26 *
27 * Inline implementation of Machine class.
28 *
29 * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30 * @note reviewed 16 Jun 2004 by ml, tr, jm, ll
31 * @note rating: red
32 */
33
34#include "Application.hh"
35#include "Socket.hh"
36#include "AddressSpace.hh"
37#include "Bus.hh"
38#include "FunctionUnit.hh"
39#include "Bridge.hh"
40#include "ImmediateUnit.hh"
41#include "InstructionTemplate.hh"
42#include "RegisterFile.hh"
43#include "ImmediateSlot.hh"
44#include "ContainerTools.hh"
45
46namespace TTAMachine {
47
48/**
49 * Template method which adds the given component to machine into the given
50 * container.
51 *
52 * This method is used for components that can be independently without
53 * machine.
54 *
55 * @param container The container of the machine to which the component is
56 * inserted.
57 * @param toAdd The component to add.
58 * @exception ComponentAlreadyExists If there is already another component
59 * by the same name in the container.
60 */
61template <typename ContainerType, typename ComponentType>
62void
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);
67 }
68
69 if (toAdd.machine() == NULL) {
70 toAdd.setMachine(*this);
71 } else {
72 container.addComponent(&toAdd);
73 }
74}
75
76/**
77 * Template method which adds the given component to machine into the given
78 * container.
79 *
80 * This method is used for components that cannot be independently without
81 * machine.
82 *
83 * @param container The container of the machine to which the component is
84 * inserted.
85 * @param toAdd The component to add.
86 * @exception ComponentAlreadyExists If there is already another component
87 * by the same name in the container.
88 */
89template <typename ContainerType, typename ComponentType>
90void
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);
96 }
97
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);
102}
103
104/**
105 * Template method which removes the given component from machine from the
106 * given container.
107 *
108 * @param container The container of the machine from which the component is
109 * removed
110 * @param toRemove The component to remove.
111 * @exception InstanceNotFound If the given component does not exist in the
112 * given container.
113 */
114template <typename ContainerType, typename ComponentType>
115void
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);
120 }
121
122 if (toRemove.machine() == NULL) {
123 container.removeComponent(&toRemove);
124 } else {
125 toRemove.unsetMachine();
126 }
127}
128
129/**
130 * Template method which deletes the given component from machine from the
131 * given container.
132 *
133 * @param container The container of the machine from which the component is
134 * deleted
135 * @param toDelete The component to deleted.
136 * @exception InstanceNotFound If the given component does not exist in the
137 * given container.
138 */
139template <typename ContainerType, typename ComponentType>
140void
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);
146 }
147
148 if (toDelete.machine() == NULL) {
149 container.removeComponent(&toDelete);
150 } else {
151 delete &toDelete;
152 }
153}
154
155/////////////////////////////////////////////////////////////////////////////
156// Machine::Navigator
157/////////////////////////////////////////////////////////////////////////////
158
159/**
160 * Constructor.
161 *
162 * @param container The container which the navigator handles.
163 */
164template <typename ComponentType>
165Machine::Navigator<ComponentType>::Navigator(
166 const Machine::ComponentContainer<ComponentType>& container) :
167 container_(&container) {
168}
169
170
171/**
172 * Destructor.
173 */
174template <typename ComponentType>
175Machine::Navigator<ComponentType>::~Navigator() {
176}
177
178
179/**
180 * Copy constructor.
181 *
182 * @param old The old Navigator from which a copy is taken.
183 */
184template <typename ComponentType>
185Machine::Navigator<ComponentType>::Navigator(const Navigator& old) :
186 container_(old.container_) {
187}
188
189
190/**
191 * Assignment operator.
192 *
193 * @param old The Navigator which is assigned to this Navigator.
194 * @return Reference to this navigator.
195 */
196template <typename ComponentType>
197Machine::Navigator<ComponentType>&
198Machine::Navigator<ComponentType>::operator=(const Navigator& old) {
199 if (this != &old) {
200 container_ = old.container_;
201 }
202 return *this;
203}
204
205
206/**
207 * Returns an item with the given index in the container.
208 *
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.
213 */
214template <typename ComponentType>
215ComponentType*
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);
220 }
221 return container_->item(index);
222}
223
224/**
225 * Returns an item with the given name.
226 *
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.
230 */
231template <typename ComponentType>
232ComponentType*
233Machine::Navigator<ComponentType>::item(const std::string& name) const {
234 ComponentType* component = container_->item(name);
235 if (component != NULL) {
236 return component;
237 } else {
238 std::string msg = "Component with name: " + name +
239 "Not found in navigator.";
240 throw InstanceNotFound(__FILE__, __LINE__, __func__, msg);
241 }
242}
243
244/**
245 * Returns true if a component with the given name is found,
246 * otherwise false.
247 *
248 * @param name Name of the component.
249 * @return True if a component with the given name is found.
250 */
251template <typename ComponentType>
252bool
253Machine::Navigator<ComponentType>::hasItem(const std::string& name) const {
254 return (container_->item(name) != NULL);
255}
256
257
258/**
259 * Returns the item count in the container.
260 *
261 * @return Item count in the container.
262 */
263template <typename ComponentType>
264int
265Machine::Navigator<ComponentType>::count() const {
266 return container_->count();
267}
268
269/**
270 * Returns an iterator at the beginning of the container.
271 *
272 */
273template <typename ComponentType>
274typename Machine::Navigator<ComponentType>::const_iterator
275Machine::Navigator<ComponentType>::begin() const noexcept {
276 return container_->begin();
277}
278
279/**
280 * Returns an iterator to the end of the container.
281 *
282 */
283template <typename ComponentType>
284typename Machine::Navigator<ComponentType>::const_iterator
285Machine::Navigator<ComponentType>::end() const noexcept {
286 return container_->end();
287}
288
289/////////////////////////////////////////////////////////////////////////////
290// Machine::ComponentContainer
291/////////////////////////////////////////////////////////////////////////////
292
293/**
294 * Constructor.
295 */
296template <typename ComponentType>
297Machine::ComponentContainer<ComponentType>::ComponentContainer() {
298}
299
300
301/**
302 * Destructor.
303 */
304template <typename ComponentType>
305Machine::ComponentContainer<ComponentType>::~ComponentContainer() {
306 deleteAll();
307}
308
309
310/**
311 * Adds component into the container.
312 *
313 * @param component Component to be added.
314 */
315template <typename ComponentType>
316void
317Machine::ComponentContainer<ComponentType>::addComponent(
318 ComponentType* component) {
319
320 components_.push_back(component);
321}
322
323
324/**
325 * Removes component from the container.
326 *
327 * @param component Component to be removed.
328 */
329template <typename ComponentType>
330void
331Machine::ComponentContainer<ComponentType>::removeComponent(
332 ComponentType* component) {
333
334 typename ComponentTable::iterator iter = components_.begin();
335 while (iter != components_.end()) {
336 if (*iter == component) {
337 components_.erase(iter);
338 return;
339 }
340 iter++;
341 }
342
343 assert(false);
344}
345
346
347/**
348 * Deletes all the components in the container.
349 *
350 * Calls each component's destructor.
351 */
352template <typename ComponentType>
353void
354Machine::ComponentContainer<ComponentType>::deleteAll() {
355 // vector size is reduced when the code in component's destructor is
356 // executed
357 while (count() > 0) {
358 delete components_[0];
359 }
360}
361
362
363/**
364 * Searches component from the container by name.
365 *
366 * Returns null pointer if the requested component was not found.
367 *
368 * @param name Name of the component.
369 * @return Component with the given name.
370 */
371template <typename ComponentType>
372ComponentType*
373Machine::ComponentContainer<ComponentType>::item(
374 const std::string& name) const {
375
376 typename ComponentTable::const_iterator iter = components_.begin();
377 while (iter != components_.end()) {
378 if ((*iter)->name() == name) {
379 return *iter;
380 }
381 iter++;
382 }
383 return NULL;
384}
385
386
387/**
388 * Searches component from the container by index.
389 *
390 * Returns null pointer if the requested component was not found.
391 *
392 * @param index Index of the component in the container.
393 * @return Component with the given index.
394 */
395template <typename ComponentType>
396ComponentType*
397Machine::ComponentContainer<ComponentType>::item(int index) const {
398
399 if (static_cast<size_t>(index) >= components_.size() || index < 0) {
400 return NULL;
401 } else {
402 return components_[index];
403 }
404}
405
406
407/**
408 * Returns the number of components in the container.
409 *
410 * @return Number of components in the container.
411 */
412template <typename ComponentType>
413int
414Machine::ComponentContainer<ComponentType>::count() const {
415 return components_.size();
416}
417
418
419/**
420 * Moves the given component to the given position in the container.
421 *
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
425 * container.
426 * @exception OutOfRange If the given position is less than 0 or not smaller
427 * than the number of components in the container.
428 */
429template <typename ComponentType>
430void
431Machine::ComponentContainer<ComponentType>::moveToPosition(
432 const ComponentType* component, int position) {
433 const std::string procName =
434 "Machine::ComponentContainer::moveToPosition";
435
436 if (!ContainerTools::containsValue(components_, component)) {
437 throw InstanceNotFound(__FILE__, __LINE__, procName);
438 }
439 if (position < 0 ||
440 static_cast<size_t>(position) >= components_.size()) {
441 throw OutOfRange(__FILE__, __LINE__, procName);
442 }
443
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);
449 break;
450 }
451 }
452
453 // add the component again to the correct place
454 typename ComponentTable::iterator addIter = components_.begin();
455 addIter += position;
456 components_.insert(addIter, const_cast<ComponentType*>(component));
457}
458
459/**
460 * Returns an iterator at the beginning of the container.
461 *
462 */
463template <typename ComponentType>
464typename Machine::ComponentContainer<ComponentType>::const_iterator
465Machine::ComponentContainer<ComponentType>::begin() const noexcept {
466 return components_.cbegin();
467}
468
469/**
470 * Returns an iterator to the end of the container.
471 *
472 */
473template <typename ComponentType>
474typename Machine::ComponentContainer<ComponentType>::const_iterator
475Machine::ComponentContainer<ComponentType>::end() const noexcept {
476 return components_.cend();
477}
478}