OpenASIP  2.0
InstructionField.cc
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 InstructionField.cc
26  *
27  * Implementation of InstructionField class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @note rating: red
31  */
32 
33 #include <list>
34 #include <boost/format.hpp>
35 
36 #include "InstructionField.hh"
37 #include "NullInstructionField.hh"
38 #include "Application.hh"
39 #include "ObjectState.hh"
40 
41 using boost::format;
42 using std::string;
43 using std::list;
44 
45 const std::string InstructionField::OSNAME_INSTRUCTION_FIELD = "instr_field";
46 const std::string InstructionField::OSKEY_EXTRA_BITS = "extra_bits";
47 const std::string InstructionField::OSKEY_POSITION = "position";
48 
49 /**
50  * The constructor.
51  *
52  * @param relativePosition Relative position of the instruction field within
53  * its parent field.
54  * @param parent The parent instruction field.
55  */
57  relativePos_(0), extraBits_(0), parent_(parent) {
58 
59  if (parent != NULL) {
61  }
62 }
63 
64 
65 /**
66  * The constructor.
67  *
68  * Loads the state of the object from the given ObjectState tree.
69  *
70  * @param state The ObjectState tree.
71  * @param parent The parent instruction field.
72  * @exception ObjectStateLoadingException If an error occurs while loading
73  * the state.
74  */
76  const ObjectState* state, InstructionField* parent)
77  : relativePos_(0), extraBits_(0), parent_(parent) {
78  if (parent != NULL) {
80  }
81 
82  loadState(state);
83 }
84 
85 /**
86  * The destructor.
87  */
89 }
90 
91 
92 /**
93  * Returns the parent instruction field.
94  *
95  * Returns NULL if the field has no parent field (BinaryEncoding).
96  *
97  * @return The parent instruction field.
98  */
101  return parent_;
102 }
103 
104 
105 /**
106  * Returns the child field which has the given relative position within
107  * the instruction field.
108  *
109  * This base class implementation just checks whether the given position is
110  * out of range and throw the exception if necessary.
111  *
112  * @param position The position.
113  * @exception OutOfRange If the position is negative or not smaller than
114  * the number of child fields.
115  */
117 InstructionField::childField(int position) const {
118  if (position < 0 || position >= childFieldCount()) {
119  const string procName = "InstructionField::childField";
120  throw OutOfRange(__FILE__, __LINE__, procName);
121  }
122 
124 }
125 
126 /**
127  * Returns the bit-accurate position of the field within its parent field.
128  *
129  * @return The position.
130  */
131 int
133 
134  InstructionField* parent = this->parent();
135 
136  if (parent == NULL) {
137  return 0;
138  }
139 
140  int position(0);
141 
142  for (int i = 0; i < relativePosition(); i++) {
144  position += childField.width();
145  }
146 
147  return position;
148 }
149 
150 
151 /**
152  * Returns the relative position of the field compared to sibling fields.
153  *
154  * If the field is the rightmost field, returns 0. The leftmost field returns
155  * the number of sibling fields - 1.
156  *
157  * @return The relative position.
158  */
159 int
161  return relativePos_;
162 }
163 
164 
165 /**
166  * Sets a new relative position for the field.
167  *
168  * @param position The new relative position.
169  * @exception OutOfRange If the given position is negative.
170  */
171 void
173  if (position < 0 || position >= parent()->childFieldCount()) {
174  const string procName = "InstructionField::setRelativePosition";
175  throw OutOfRange(__FILE__, __LINE__, procName);
176  }
177 
178  InstructionField& fieldToMove = parent()->childField(position);
179  relativePos_ = position;
180 
181  int childFields = parent()->childFieldCount();
182  int emptyPosition(-1);
183  for (int i = 0; i < childFields; i++) {
185  emptyPosition = i;
186  break;
187  }
188  }
189 
190  if (emptyPosition != -1) {
191  if (emptyPosition < fieldToMove.relativePosition()) {
192  fieldToMove.
193  setRelativePosition(fieldToMove.relativePosition() - 1);
194  } else if (emptyPosition > fieldToMove.relativePosition()) {
195  fieldToMove.
196  setRelativePosition(fieldToMove.relativePosition() + 1);
197  } else {
198  assert(false);
199  }
200  }
201 }
202 
203 /**
204  * Sets the number of extra (zero) bits to the field.
205  *
206  * The field can be forced longer than necessary by defining some number of
207  * extra bits. In practice, there will be the given amount of zeros always in
208  * the MSB end of the field.
209  *
210  * @param bits The number of extra bits.
211  * @exception OutOfRange If the given number is negative.
212  */
213 void
215  if (bits < 0) {
216  const string procName = "InstructionField::setExtraBits";
217  throw OutOfRange(__FILE__, __LINE__, procName);
218  }
219 
220  extraBits_ = bits;
221 }
222 
223 /**
224  * Returns the number of extra bits in the field.
225  *
226  * @return The number of extra bits.
227  */
228 int
230  return extraBits_;
231 }
232 
233 
234 /**
235  * Loads the state of the object from the given ObjectState tree.
236  *
237  * @param state The ObjectState tree.
238  * @exception ObjectStateLoadingException If an error occurs while loading
239  * the state.
240  */
241 void
243  const string procName = "InstructionField::loadState";
244 
245  try {
247  if (relativePosition() != state->intAttribute(OSKEY_POSITION)) {
248  format errorMsg(
249  "Invalid relative position %1%. Should be %2%.");
250  errorMsg % state->stringAttribute(OSKEY_POSITION) %
253  __FILE__, __LINE__, __func__, errorMsg.str());
254  }
255 
256  } catch (const Exception& exception) {
258  __FILE__, __LINE__, procName, exception.errorMessage());
259  }
260 }
261 
262 /**
263  * Saves the state of the object to an ObjectState tree.
264  *
265  * @return The newly created ObjectState tree.
266  */
272  return state;
273 }
274 
275 
276 /**
277  * Sets the parent instruction field.
278  *
279  * @param parent The parent field.
280  */
281 void
283  parent_ = parent;
284 }
285 
286 
287 /**
288  * Sorts the child ObjectState instances of the given ObjectState instance
289  * such that they are returned by child(index) method in the correct order.
290  *
291  * The correct order means that at first the rightmost subfield is returned
292  * and then the next to left and so on.
293  *
294  * @param state The ObjectState instance.
295  */
296 void
298 
299  typedef list<ObjectState*> OSList;
300  OSList list;
301 
302  for (int i = 0; i < state->childCount();) {
303  ObjectState* child = state->child(i);
305  state->removeChild(child);
306  int position = child->intAttribute(
308 
309  // insert the object to the list at correct position
310  bool inserted = false;
311  for (OSList::iterator iter = list.begin(); iter != list.end();
312  iter++) {
313  ObjectState* item = *iter;
314  int itemPosition = item->intAttribute(
316  if (itemPosition > position) {
317  list.insert(iter, child);
318  inserted = true;
319  break;
320  }
321  }
322  if (!inserted) {
323  list.push_back(child);
324  }
325  } else {
326  i++;
327  }
328  }
329 
330  // add the sub fields again in the correct order
331  for (OSList::const_iterator iter = list.begin(); iter != list.end();
332  iter++) {
333  ObjectState* child = *iter;
334  state->addChild(child);
335  }
336 }
337 
ObjectState::hasAttribute
bool hasAttribute(const std::string &name) const
Definition: ObjectState.cc:205
InstructionField::OSKEY_POSITION
static const std::string OSKEY_POSITION
ObjectState attribute key for the relative position of the field.
Definition: InstructionField.hh:77
InstructionField::bitPosition
int bitPosition() const
Definition: InstructionField.cc:132
InstructionField.hh
ObjectState::stringAttribute
std::string stringAttribute(const std::string &name) const
Definition: ObjectState.cc:249
ObjectStateLoadingException
Definition: Exception.hh:551
OutOfRange
Definition: Exception.hh:320
InstructionField::childField
virtual InstructionField & childField(int position) const
Definition: InstructionField.cc:117
ObjectState
Definition: ObjectState.hh:59
InstructionField::relativePos_
int relativePos_
Indicates the relative position of the field.
Definition: InstructionField.hh:88
NullInstructionField.hh
InstructionField::OSKEY_EXTRA_BITS
static const std::string OSKEY_EXTRA_BITS
ObjectState attribute key for the number of extra bits.
Definition: InstructionField.hh:75
NullInstructionField::instance
static NullInstructionField & instance()
Definition: NullInstructionField.cc:62
InstructionField
Definition: InstructionField.hh:43
InstructionField::saveState
virtual ObjectState * saveState() const
Definition: InstructionField.cc:268
assert
#define assert(condition)
Definition: Application.hh:86
InstructionField::width
virtual int width() const =0
Application.hh
InstructionField::setParent
void setParent(InstructionField *parent)
Definition: InstructionField.cc:282
__func__
#define __func__
Definition: Application.hh:67
InstructionField::parent
InstructionField * parent() const
Definition: InstructionField.cc:100
ObjectState.hh
ObjectState::child
ObjectState * child(int index) const
Definition: ObjectState.cc:471
ObjectState::addChild
void addChild(ObjectState *child)
Definition: ObjectState.cc:376
ObjectState::childCount
int childCount() const
Exception
Definition: Exception.hh:54
InstructionField::reorderSubfields
static void reorderSubfields(ObjectState *state)
Definition: InstructionField.cc:297
InstructionField::OSNAME_INSTRUCTION_FIELD
static const std::string OSNAME_INSTRUCTION_FIELD
ObjectState name for instruction field.
Definition: InstructionField.hh:73
InstructionField::setExtraBits
void setExtraBits(int bits)
Definition: InstructionField.cc:214
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
InstructionField::childFieldCount
virtual int childFieldCount() const =0
InstructionField::extraBits
int extraBits() const
Definition: InstructionField.cc:229
ObjectState::removeChild
void removeChild(ObjectState *child)
Definition: ObjectState.cc:389
InstructionField::loadState
virtual void loadState(const ObjectState *state)
Definition: InstructionField.cc:242
InstructionField::relativePosition
int relativePosition() const
Definition: InstructionField.cc:160
ObjectState::intAttribute
int intAttribute(const std::string &name) const
Definition: ObjectState.cc:276
InstructionField::parent_
InstructionField * parent_
The parent instruction field.
Definition: InstructionField.hh:92
InstructionField::InstructionField
InstructionField(InstructionField *parent)
Definition: InstructionField.cc:56
ObjectState::setAttribute
void setAttribute(const std::string &name, const std::string &value)
Definition: ObjectState.cc:100
InstructionField::extraBits_
int extraBits_
The number of extra bits.
Definition: InstructionField.hh:90
InstructionField::setRelativePosition
virtual void setRelativePosition(int position)
Definition: InstructionField.cc:172
InstructionField::~InstructionField
virtual ~InstructionField()
Definition: InstructionField.cc:88