OpenASIP  2.0
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 
46 namespace 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  */
61 template <typename ContainerType, typename ComponentType>
62 void
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);
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  */
89 template <typename ContainerType, typename ComponentType>
90 void
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);
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  */
114 template <typename ContainerType, typename ComponentType>
115 void
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);
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  */
139 template <typename ContainerType, typename ComponentType>
140 void
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);
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  */
164 template <typename ComponentType>
165 Machine::Navigator<ComponentType>::Navigator(
166  const Machine::ComponentContainer<ComponentType>& container) :
167  container_(&container) {
168 }
169 
170 
171 /**
172  * Destructor.
173  */
174 template <typename ComponentType>
175 Machine::Navigator<ComponentType>::~Navigator() {
176 }
177 
178 
179 /**
180  * Copy constructor.
181  *
182  * @param old The old Navigator from which a copy is taken.
183  */
184 template <typename ComponentType>
185 Machine::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  */
196 template <typename ComponentType>
197 Machine::Navigator<ComponentType>&
198 Machine::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  */
214 template <typename ComponentType>
215 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);
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  */
231 template <typename ComponentType>
232 ComponentType*
233 Machine::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  */
251 template <typename ComponentType>
252 bool
253 Machine::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  */
263 template <typename ComponentType>
264 int
265 Machine::Navigator<ComponentType>::count() const {
266  return container_->count();
267 }
268 
269 /**
270  * Returns an iterator at the beginning of the container.
271  *
272  */
273 template <typename ComponentType>
274 typename Machine::Navigator<ComponentType>::const_iterator
275 Machine::Navigator<ComponentType>::begin() const noexcept {
276  return container_->begin();
277 }
278 
279 /**
280  * Returns an iterator to the end of the container.
281  *
282  */
283 template <typename ComponentType>
284 typename Machine::Navigator<ComponentType>::const_iterator
285 Machine::Navigator<ComponentType>::end() const noexcept {
286  return container_->end();
287 }
288 
289 /////////////////////////////////////////////////////////////////////////////
290 // Machine::ComponentContainer
291 /////////////////////////////////////////////////////////////////////////////
292 
293 /**
294  * Constructor.
295  */
296 template <typename ComponentType>
297 Machine::ComponentContainer<ComponentType>::ComponentContainer() {
298 }
299 
300 
301 /**
302  * Destructor.
303  */
304 template <typename ComponentType>
305 Machine::ComponentContainer<ComponentType>::~ComponentContainer() {
306  deleteAll();
307 }
308 
309 
310 /**
311  * Adds component into the container.
312  *
313  * @param component Component to be added.
314  */
315 template <typename ComponentType>
316 void
317 Machine::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  */
329 template <typename ComponentType>
330 void
331 Machine::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  */
352 template <typename ComponentType>
353 void
354 Machine::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  */
371 template <typename ComponentType>
372 ComponentType*
373 Machine::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  */
395 template <typename ComponentType>
396 ComponentType*
397 Machine::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  */
412 template <typename ComponentType>
413 int
414 Machine::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  */
429 template <typename ComponentType>
430 void
431 Machine::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  */
463 template <typename ComponentType>
464 typename Machine::ComponentContainer<ComponentType>::const_iterator
465 Machine::ComponentContainer<ComponentType>::begin() const noexcept {
466  return components_.cbegin();
467 }
468 
469 /**
470  * Returns an iterator to the end of the container.
471  *
472  */
473 template <typename ComponentType>
474 typename Machine::ComponentContainer<ComponentType>::const_iterator
475 Machine::ComponentContainer<ComponentType>::end() const noexcept {
476  return components_.cend();
477 }
478 }