OpenASIP 2.2
Loading...
Searching...
No Matches
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"
38#include "Application.hh"
39#include "ObjectState.hh"
40
41using boost::format;
42using std::string;
43using std::list;
44
45const std::string InstructionField::OSNAME_INSTRUCTION_FIELD = "instr_field";
46const std::string InstructionField::OSKEY_EXTRA_BITS = "extra_bits";
47const 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 */
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 */
117InstructionField::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 */
131int
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 */
159int
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 */
171void
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 */
213void
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 */
228int
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 */
241void
243 const string procName = "InstructionField::loadState";
244
245 try {
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 */
274
275
276/**
277 * Sets the parent instruction field.
278 *
279 * @param parent The parent field.
280 */
281void
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 */
296void
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
#define __func__
#define assert(condition)
std::string errorMessage() const
Definition Exception.cc:123
void setExtraBits(int bits)
InstructionField * parent() const
int relativePos_
Indicates the relative position of the field.
int extraBits_
The number of extra bits.
InstructionField * parent_
The parent instruction field.
virtual void loadState(const ObjectState *state)
static const std::string OSKEY_POSITION
ObjectState attribute key for the relative position of the field.
virtual int width() const =0
void setParent(InstructionField *parent)
static const std::string OSNAME_INSTRUCTION_FIELD
ObjectState name for instruction field.
virtual int childFieldCount() const =0
static void reorderSubfields(ObjectState *state)
InstructionField(InstructionField *parent)
virtual ~InstructionField()
static const std::string OSKEY_EXTRA_BITS
ObjectState attribute key for the number of extra bits.
virtual void setRelativePosition(int position)
virtual ObjectState * saveState() const
virtual InstructionField & childField(int position) const
int relativePosition() const
static NullInstructionField & instance()
bool hasAttribute(const std::string &name) const
void setAttribute(const std::string &name, const std::string &value)
void removeChild(ObjectState *child)
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string stringAttribute(const std::string &name) const
int intAttribute(const std::string &name) const
int childCount() const