OpenASIP 2.2
Loading...
Searching...
No Matches
ImmediateControlField.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 ImmediateControlField.cc
26 *
27 * Implementation of ImmediateControlField class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @note rating: red
31 */
32
34#include "BinaryEncoding.hh"
35#include "MoveSlot.hh"
37#include "MathTools.hh"
38#include "MapTools.hh"
39#include "Application.hh"
40#include "ObjectState.hh"
41
42using std::string;
43using std::pair;
44
45const std::string ImmediateControlField::OSNAME_IMM_CONTROL_FIELD = "ic_field";
46const std::string ImmediateControlField::OSNAME_TEMPLATE_MAP = "temp_map";
47const std::string ImmediateControlField::OSKEY_TEMPLATE_NAME = "temp_name";
48const std::string ImmediateControlField::OSKEY_ENCODING = "encoding";
49
50/**
51 * The constructor.
52 *
53 * Registers the immediate control field to the parent BinaryEncoding
54 * automatically. The field is added as the leftmost field of the TTA
55 * instruction.
56 *
57 * @param parent The parent encoding map.
58 * @exception ObjectAlreadyExists If the given encoding map has an immediate
59 * control field already.
60 */
67
68/**
69 * The constructor.
70 *
71 * Loads the state of the object from the given ObjectState tree.
72 *
73 * @param state The ObjectState tree.
74 * @param parent The parent encoding map.
75 * @exception ObjectStateLoadingException If an error occurs while loading
76 * the state.
77 * @exception ObjectAlreadyExists If the given encoding map has an immediate
78 * control field already.
79 */
81 const ObjectState* state, BinaryEncoding& parent)
82 : InstructionField(state, &parent) {
83 loadState(state);
84 setParent(NULL);
87}
88
89/**
90 * The destructor.
91 */
93 BinaryEncoding* oldParent = parent();
94 assert(oldParent != NULL);
95 setParent(NULL);
96 oldParent->unsetImmediateControlField();
97}
98
99
100/**
101 * Returns the parent encoding map.
102 *
103 * @return The parent encoding map.
104 */
108 if (parent == NULL) {
109 return NULL;
110 } else {
111 BinaryEncoding* encoding = dynamic_cast<BinaryEncoding*>(parent);
112 assert(encoding != NULL);
113 return encoding;
114 }
115}
116
117
118/**
119 * Returns the number of instruction templates with a binary encoding assigned.
120 *
121 * @return The number of instruction templates.
122 */
123int
125 return templates_.size();
126}
127
128
129/**
130 * Returns the name of the instruction template encoded in this field at the
131 * given position.
132 *
133 * @param index The position index.
134 * @exception OutOfRange If the given index is negative or not smaller than the
135 * number of encodings of instruction templates.
136 */
137std::string
139 if (index < 0 || index >= templateCount()) {
140 const string procName = "ImmediateControlField::instructionTemplate";
141 throw OutOfRange(__FILE__, __LINE__, procName);
142 }
143
144 int counter(0);
145 for (EncodingMap::const_iterator iter = templates_.begin();
146 iter != templates_.end(); iter++) {
147
148 if (counter == index) {
149 return iter->first;
150 } else {
151 counter++;
152 }
153 }
154
155 assert(false);
156 return "";
157}
158
159/**
160 * Tells whether the instruction template with the given name has has a binary
161 * encoding in this field.
162 *
163 * @param name Name of the instruction template.
164 * @return True if the template has a binary encoding, otherwise false.
165 */
166bool
167ImmediateControlField::hasTemplateEncoding(const std::string& name) const {
168 return MapTools::containsKey(templates_, name);
169}
170
171
172/**
173 * Returns the code that identifies the instruction template with the given
174 * name.
175 *
176 * @param name Name of the instruction template.
177 * @return The code that identifies the given instruction template.
178 * @exception InstanceNotFound If the given instruction template does not have
179 * a binary encoding in this field.
180 */
181unsigned int
182ImmediateControlField::templateEncoding(const std::string& name) const {
183 if (!hasTemplateEncoding(name)) {
184 const string procName = "ImmediateControlField::templateEncoding";
185 throw InstanceNotFound(__FILE__, __LINE__, procName);
186 }
187
188 EncodingMap::const_iterator iter = templates_.find(name);
189 assert(iter != templates_.end());
190 return iter->second;
191}
192
193/**
194 * Assings the given code to the instruction template identified by the given
195 * name.
196 *
197 * If the given instruction template has an encoding already, replaces the
198 * encoding with the given one.
199 *
200 * @param name Name of the instruction template.
201 * @param encoding The code to be assigned.
202 * @exception ObjectAlreadyExists If the given code is already assigned to
203 * another instruction template.
204 */
205void
207 const std::string& name, unsigned int encoding) {
208 if (MapTools::containsValue(templates_, encoding) &&
209 MapTools::keyForValue<string>(templates_, encoding) != name) {
210 const string procName = "ImmediateControlField::addTemplateEncoding";
211 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
212 }
213
214
215 pair<EncodingMap::iterator, bool> result =
216 templates_.insert(pair<string, int>(name, encoding));
217
218 if (!result.second) {
219 // if there is a code for the template already
220 EncodingMap::iterator iter = templates_.find(name);
221 assert(iter != templates_.end());
222 iter->second = encoding;
223 }
224}
225
226/**
227 * Removes the code of the instruction template with the given name.
228 *
229 * @param name Name of the instruction template.
230 */
231void
233 templates_.erase(name);
234}
235
236
237/**
238 * Returns the bit width of the immediate control field.
239 *
240 * @return The bit width of the field.
241 */
242int
244 int minWidth(0);
245 for (EncodingMap::const_iterator iter = templates_.begin();
246 iter != templates_.end(); iter++) {
247 int encoding = iter->second;
248 int requiredBits = MathTools::bitLength(encoding);
249 if (requiredBits > minWidth) {
250 minWidth = requiredBits;
251 }
252 }
253 return minWidth + extraBits();
254}
255
256
257/**
258 * Always returns 0.
259 *
260 * @return 0.
261 */
262int
264 return 0;
265}
266
267
268/**
269 * Always throws OutOfRange exception because immediate control field does
270 * not have any child fields.
271 *
272 * @return Never returns.
273 * @exception OutOfRange Always thrown.
274 */
277 const string procName = "ImmediateControlField::childField";
278 throw OutOfRange(__FILE__, __LINE__, procName);
279}
280
281/**
282 * Loads the state of the immediate control field from the given ObjectState
283 * tree.
284 *
285 * @param state The ObjectState tree.
286 * @exception ObjectStateLoadingException If an error occurs while loading
287 * the state.
288 */
289void
293 const string procName = "ImmediateControlField::loadState";
294
295 if (state->name() != OSNAME_IMM_CONTROL_FIELD) {
296 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
297 }
298
299 try {
300 for (int i = 0; i < state->childCount(); i++) {
301 ObjectState* child = state->child(i);
302 if (child->name() != OSNAME_TEMPLATE_MAP) {
304 __FILE__, __LINE__, procName);
305 }
306 string tempName = child->stringAttribute(OSKEY_TEMPLATE_NAME);
307 int encoding = child->intAttribute(OSKEY_ENCODING);
308 addTemplateEncoding(tempName, encoding);
309 }
310
311 } catch (const Exception& exception) {
313 __FILE__, __LINE__, procName, exception.errorMessage());
314 }
315}
316
317/**
318 * Saves the state of the immediate control field to an ObjectState tree.
319 *
320 * @return The newly created ObjectState tree.
321 */
324
328
329 for (int i = 0; i < templateCount(); i++) {
330 string temp = instructionTemplate(i);
331 int encoding = templateEncoding(temp);
333 state->addChild(tempMap);
334 tempMap->setAttribute(OSKEY_TEMPLATE_NAME, temp);
335 tempMap->setAttribute(OSKEY_ENCODING, encoding);
336 }
337
338 return state;
339}
340
341
342/**
343 * Clears all the template encodings from the immediate control field.
344 */
345void
#define assert(condition)
void unsetImmediateControlField()
void setImmediateControlField(ImmediateControlField &field)
std::string errorMessage() const
Definition Exception.cc:123
static const std::string OSKEY_TEMPLATE_NAME
ObjectState attribute key for the name of the instruction template.
static const std::string OSNAME_TEMPLATE_MAP
ObjectState name for a template mapping.
unsigned int templateEncoding(const std::string &name) const
static const std::string OSNAME_IMM_CONTROL_FIELD
ObjectState name for immediate control field.
bool hasTemplateEncoding(const std::string &name) const
void removeTemplateEncoding(const std::string &name)
virtual int childFieldCount() const
std::string instructionTemplate(int index) const
virtual InstructionField & childField(int) const
ImmediateControlField(BinaryEncoding &parent)
BinaryEncoding * parent() const
static const std::string OSKEY_ENCODING
ObjectState attribute key for the encoding of the instruction template.
virtual void loadState(const ObjectState *state)
void addTemplateEncoding(const std::string &name, unsigned int encoding)
virtual ObjectState * saveState() const
EncodingMap templates_
Binary encodings for instruction templates.
InstructionField * parent() const
virtual void loadState(const ObjectState *state)
static const std::string OSKEY_POSITION
ObjectState attribute key for the relative position of the field.
void setParent(InstructionField *parent)
virtual ObjectState * saveState() const
int relativePosition() const
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
static bool containsValue(const MapType &aMap, const ValueType &aValue)
static unsigned int bitLength(long unsigned int number)
void setName(const std::string &name)
void setAttribute(const std::string &name, const std::string &value)
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string stringAttribute(const std::string &name) const
int intAttribute(const std::string &name) const
std::string name() const
int childCount() const