OpenASIP 2.2
Loading...
Searching...
No Matches
GuardField.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 GuardField.cc
26 *
27 * Implementation of GuardField class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include "GuardField.hh"
34#include "MoveSlot.hh"
35#include "GPRGuardEncoding.hh"
37#include "FUGuardEncoding.hh"
41#include "MathTools.hh"
42#include "ContainerTools.hh"
43#include "SequenceTools.hh"
44#include "Application.hh"
45#include "ObjectState.hh"
46
47using std::string;
48
49const std::string GuardField::OSNAME_GUARD_FIELD = "guard_field";
50
51/**
52 * The constructor.
53 *
54 * Registers the guard field to the parent move slot automatically.
55 *
56 * @param parent The parent move slot.
57 * @exception ObjectAlreadyExists If the parent move slot has a guard field
58 * already.
59 */
61 : InstructionField(&parent), alwaysTrue_(NULL), alwaysFalse_(NULL) {
62 setParent(NULL);
63 parent.setGuardField(*this);
65
66 // update the relative position of the field
67 int position(0);
68 if (parent.hasSourceField()) {
69 position++;
70 }
72 position++;
73 }
75}
76
77/**
78 * The constructor.
79 *
80 * Loads the state of the object from the given ObjectState tree.
81 *
82 * @param state The ObjectState tree.
83 * @param parent The parent move slot.
84 * @exception ObjectStateLoadingException If an error occurs while loading
85 * the state.
86 * @exception ObjectAlreadyExists If the parent move slot has a guard field
87 * already.
88 */
90 : InstructionField(state, &parent), alwaysTrue_(NULL), alwaysFalse_(NULL) {
91 loadState(state);
92 setParent(NULL);
93 parent.setGuardField(*this);
95}
96
97/**
98 * The destructor.
99 */
104 MoveSlot* oldParent = parent();
105 setParent(NULL);
106 assert(oldParent != NULL);
107 oldParent->unsetGuardField();
108}
109
110
111/**
112 * Returns the parent move slot.
113 *
114 * @return The parent move slot.
115 */
119 if (parent == NULL) {
120 return NULL;
121 } else {
122 MoveSlot* slot = dynamic_cast<MoveSlot*>(parent);
123 assert(slot != NULL);
124 return slot;
125 }
126}
127
128
129/**
130 * Adds a guard expression and its encoding to the set of expressions
131 * supported by this guard field.
132 *
133 * This method is to be called from the constructor GPRGuardEncoding.
134 *
135 * @param encoding The encoding to be added.
136 * @exception ObjectAlreadyExists If the guard field already contains a guard
137 * encoding for the same guard expression or
138 * if the given encoding is already assigned.
139 */
140void
142 // verify that this is called from GPRGuardEncoding constructor
143 assert(encoding.parent() == NULL);
144
146 encoding.registerFile(), encoding.registerIndex(),
147 encoding.isGuardInverted()) || isAssigned(encoding.encoding())) {
148 const string procName = "GuardField::addGuardEncoding";
149 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
150 }
151
152 gprGuards_.push_back(&encoding);
153}
154
155/**
156 * Removes the given guard encoding.
157 *
158 * This method is to be called from the destructor of GPRGuardField.
159 *
160 * @param encoding The encoding to be removed.
161 */
162void
164 // verify that this is called from GPRGuardEncoding destructor
165 assert(encoding.parent() == NULL);
167}
168
169
170/**
171 * Adds a guard expression and its encoding to the set of expressions
172 * supported by this guard field.
173 *
174 * This method is to be called from the constructor of FUGuardEncoding.
175 *
176 * @param encoding The encoding to be added.
177 * @exception ObjectAlreadyExists If the guard field already contains a guard
178 * encoding for the same guard expression or
179 * if the encoding is already assigned to
180 * another guard expression.
181 */
182void
184 // verify that this is called from GPRGuardEncoding constructor
185 assert(encoding.parent() == NULL);
186
188 encoding.functionUnit(), encoding.port(),
189 encoding.isGuardInverted()) || isAssigned(encoding.encoding())) {
190 const string procName = "GuardField::addGuardEncoding";
191 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
192 }
193
194 fuGuards_.push_back(&encoding);
195}
196
197/**
198 * Removes the given guard encoding.
199 *
200 * This method is to be called from the destructor of FUGuardField.
201 *
202 * @param encoding The encoding to be removed.
203 */
204void
206 // verify that this is called from GPRGuardEncoding destructor
207 assert(encoding.parent() == NULL);
209}
210
211
212/**
213 * Adds a guard expression and its encoding to the set of expressions
214 * supported by this guard field.
215 *
216 * This method is to be called from the constructor of
217 * UnconditionalGuardEncoding.
218 *
219 * @param encoding The encoding to be added.
220 * @exception ObjectAlreadyExists If the guard field already contains an
221 * encoding for the same unconditional guard
222 * expression or if the encoding is already
223 * assigned to another guard expression.
224 */
225void
227 // verify that this is called from UnconditionalGuardEncoding constructor
228 assert(encoding.parent() == NULL);
229
231 isAssigned(encoding.encoding())) {
232 const string procName = "GuardField::addGuardEncoding";
233 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
234 }
235
236 if (encoding.isGuardInverted()) {
237 alwaysFalse_ = &encoding;
238 } else {
239 alwaysTrue_ = &encoding;
240 }
241}
242
243/**
244 * Removes the encoding for unconditional guard.
245 *
246 * This method is to be called from the destructor of
247 * UnconditionalGuardEncoding class.
248 *
249 * @param encoding The encoding to be removed.
250 */
251void
253 UnconditionalGuardEncoding& encoding) {
254
256 assert(
258 &encoding);
259 assert(encoding.parent() == NULL);
260
261 if (encoding.isGuardInverted()) {
262 alwaysFalse_ = NULL;
263 } else {
264 alwaysTrue_ = NULL;
265 }
266}
267
268
269/**
270 * Returns the number of guard expressions with general purpose register term
271 * that are encoded in this field.
272 *
273 * @return The number of guard expressions.
274 */
275int
277 return gprGuards_.size();
278}
279
280
281/**
282 * Returns the GPRGuardEncoding at the given position.
283 *
284 * @param index The position.
285 * @return The GPR guard encoding.
286 * @exception OutOfRange If the given index is negative or not smaller than
287 * the number of GPR guard encodings.
288 */
291 if (index < 0 || index >= gprGuardEncodingCount()) {
292 const string procName = "GuardField::gprGuardEncoding";
293 throw OutOfRange(__FILE__, __LINE__, procName);
294 }
295
296 return *gprGuards_[index];
297}
298
299/**
300 * Tells whether the guard field has an encoding for the given guard
301 * expression.
302 *
303 * The expression is identified by a general purpose register (register file
304 * name and register index) and by the "invert" flag.
305 *
306 * @param regFile Name of the register file.
307 * @param index The register index.
308 * @param inverted The "invert" flag.
309 * @return True if the guard field has an encoding for the given guard
310 * expression, otherwise false.
311 */
312bool
314 const std::string& regFile,
315 int index,
316 bool inverted) const {
317
318 for (GPRGuardTable::const_iterator iter = gprGuards_.begin();
319 iter != gprGuards_.end(); iter++) {
320
321 GPRGuardEncoding* encoding = *iter;
322 if (encoding->registerFile() == regFile &&
323 encoding->registerIndex() == index &&
324 encoding->isGuardInverted() == inverted) {
325 return true;
326 }
327 }
328
329 return false;
330}
331
332
333/**
334 * Returns the GPRGuardEncoding for the given guard expression.
335 *
336 * The expression is identified by a general purpose register
337 * (register file name and register index) and by the "invert" flag. Returns
338 * a NullGPRGuardEncoding instance if there is no such guard.
339 *
340 * @param regFile Name of the register file.
341 * @param index The register index.
342 * @param inverted The "invert" flag.
343 * @return GPRGuardEncoding of the given guard expression.
344 */
347 const std::string& regFile,
348 int index,
349 bool inverted) const {
350
351 for (GPRGuardTable::const_iterator iter = gprGuards_.begin();
352 iter != gprGuards_.end(); iter++) {
353
354 GPRGuardEncoding* encoding = *iter;
355 if (encoding->registerFile() == regFile &&
356 encoding->registerIndex() == index &&
357 encoding->isGuardInverted() == inverted) {
358 return *encoding;
359 }
360 }
361
363}
364
365
366/**
367 * Returns the number of guard expressions with function unit output term
368 * that are encoded in this field.
369 *
370 * @return The number of guard expressions.
371 */
372int
374 return fuGuards_.size();
375}
376
377
378/**
379 * Returns the FUGuardEncoding at the given position.
380 *
381 * @param index The position.
382 * @return The FU guard encoding.
383 * @exception OutOfRange If the given index is negative or not smaller than
384 * the number of FU guard encodings.
385 */
388 if (index < 0 || index >= fuGuardEncodingCount()) {
389 const string procName = "GuardField::fuGuardEncoding";
390 throw OutOfRange(__FILE__, __LINE__, procName);
391 }
392
393 return *fuGuards_[index];
394}
395
396/**
397 * Tells whether the guard field has an encoding for the given guard
398 * expression.
399 *
400 * The expression is identified by a function unit output port (FU name and
401 * port name) and by the "invert" flag.
402 *
403 * @param fu Name of the function unit.
404 * @param port Name of the port.
405 * @param inverted The "invert" flag.
406 * @return True if the guard field has an encoding for the given guard
407 * expression, otherwise false.
408 */
409bool
411 const std::string& fu,
412 const std::string& port,
413 bool inverted) const {
414
415 for (FUGuardTable::const_iterator iter = fuGuards_.begin();
416 iter != fuGuards_.end(); iter++) {
417
418 FUGuardEncoding* encoding = *iter;
419 if (encoding->functionUnit() == fu &&
420 encoding->port() == port &&
421 encoding->isGuardInverted() == inverted) {
422 return true;
423 }
424 }
425
426 return false;
427}
428
429
430/**
431 * Returns the FUGuardEncoding for the given guard expression.
432 *
433 * The expression is identified by a function unit output port (FU
434 * name and port name) and by the "invert" flag. Returns a
435 * NullFUGuardEncoding instance if there is no such guard.
436 *
437 * @param fu Name of the function unit.
438 * @param port Name of the port.
439 * @param inverted The "invert" flag.
440 * @return FUGuardEncoding of the given guard expression.
441 */
444 const std::string& fu,
445 const std::string& port,
446 bool inverted) const {
447
448 for (FUGuardTable::const_iterator iter = fuGuards_.begin();
449 iter != fuGuards_.end(); iter++) {
450
451 FUGuardEncoding* encoding = *iter;
452 if (encoding->functionUnit() == fu &&
453 encoding->port() == port &&
454 encoding->isGuardInverted() == inverted) {
455 return *encoding;
456 }
457 }
458
460}
461
462
463/**
464 * Tells whether the guard field has an encoding for unconditional guard.
465 *
466 * @param inverted The "invert" flag.
467 * @return True if there is an encoding for unconditional guard, otherwise
468 * false.
469 */
470bool
472 if (inverted) {
473 return alwaysFalse_ != NULL;
474 } else {
475 return alwaysTrue_ != NULL;
476 }
477}
478
479
480/**
481 * Returns the unconditional guard encoding.
482 *
483 * Returns NullUnconditionalGuardEncoding instance if there is no encoding
484 * for unconditional guard.
485 *
486 * @param inverted The "invert" flag.
487 * @return The unconditional guard encoding.
488 */
491 if (hasUnconditionalGuardEncoding(inverted)) {
492 if (inverted) {
493 return *alwaysFalse_;
494 } else {
495 return *alwaysTrue_;
496 }
497 } else {
499 }
500}
501
502
503/**
504 * Always returns 0 because guard field does not have any child fields.
505 *
506 * @return 0.
507 */
508int
510 return 0;
511}
512
513
514/**
515 * Always throws OutOfRange exception since guard field does not have any
516 * child fields.
517 *
518 * @return Never returns.
519 * @exception OutOfRange Always thrown.
520 */
523 const string procName = "GuardField::childField";
524 throw OutOfRange(__FILE__, __LINE__, procName);
525}
526
527/**
528 * Returns the bit width of the guard field.
529 *
530 * @return Bit width of the field.
531 */
532int
534
535 int gprGuards = gprGuardEncodingCount();
536 int fuGuards = fuGuardEncodingCount();
537 int width(0);
538
539 for (int i = 0; i < gprGuards; i++) {
540 GPRGuardEncoding& encoding = gprGuardEncoding(i);
541 int requiredBits = MathTools::bitLength(encoding.encoding());
542 if (requiredBits > width) {
543 width = requiredBits;
544 }
545 }
546
547 for (int i = 0; i < fuGuards; i++) {
548 FUGuardEncoding& encoding = fuGuardEncoding(i);
549 int requiredBits = MathTools::bitLength(encoding.encoding());
550 if (requiredBits > width) {
551 width = requiredBits;
552 }
553 }
554
557 true);
558 int requiredBits = MathTools::bitLength(encoding.encoding());
559 if (requiredBits > width) {
560 width = requiredBits;
561 }
562 }
563
566 false);
567 int requiredBits = MathTools::bitLength(encoding.encoding());
568 if (requiredBits > width) {
569 width = requiredBits;
570 }
571 }
572
573 return width + extraBits();
574}
575
576
577/**
578 * Loads the state of the object from the given ObjectState tree.
579 *
580 * @param state The ObjectState tree.
581 * @exception ObjectStateLoadingException If an error occurs while loading
582 * the state.
583 */
584void
586 const string procName = "GuardField::loadState";
587
588 if (state->name() != OSNAME_GUARD_FIELD) {
589 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
590 }
591
595
596 try {
597 for (int i = 0; i < state->childCount(); i++) {
598 ObjectState* child = state->child(i);
600 new FUGuardEncoding(child, *this);
601 } else if (child->name() ==
603 new GPRGuardEncoding(child, *this);
604 } else if (child->name() ==
606 OSNAME_UNCONDITIONAL_GUARD_ENCODING) {
607 new UnconditionalGuardEncoding(child, *this);
608 }
609 }
610 } catch (const Exception& exception) {
612 __FILE__, __LINE__, procName, exception.errorMessage());
613 }
614}
615
616/**
617 * Saves the state of the guard field to an ObjectState tree.
618 *
619 * @return The newly created ObjectState tree.
620 */
623
626
627 // add GPR guard encodings
628 for (int i = 0; i < gprGuardEncodingCount(); i++) {
630 state->addChild(enc.saveState());
631 }
632
633 // add FU guard encodings
634 for (int i = 0; i < fuGuardEncodingCount(); i++) {
636 state->addChild(enc.saveState());
637 }
638
639 // add unconditional guard encodings
642 }
645 }
646
647 return state;
648}
649
650
651/**
652 * Deletes all the register guard encodings from the guard field.
653 */
654void
658
659
660/**
661 * Deletes all the function unit port guard encodings from the guard field.
662 */
663void
667
668
669/**
670 * Deletes the unconditional guard encodings from the guard field.
671 */
672void
675 delete alwaysFalse_;
676 alwaysFalse_ = NULL;
677 }
679 delete alwaysTrue_;
680 alwaysTrue_ = NULL;
681 }
682}
683
684
685/**
686 * Tells whether the given encoding is assigned to a guard expression.
687 *
688 * @param encoding The encoding.
689 * @return True if the encoding is assigned, otherwise false.
690 */
691bool
692GuardField::isAssigned(unsigned int encoding) const {
693
694 int fuGuards = fuGuardEncodingCount();
695 int rfGuards = gprGuardEncodingCount();
696
697 for (int i = 0; i < fuGuards; i++) {
699 if (guard.encoding() == encoding) {
700 return true;
701 }
702 }
703
704 for (int i = 0; i < rfGuards; i++) {
706 if (guard.encoding() == encoding) {
707 return true;
708 }
709 }
710
712 if (unconditionalGuardEncoding(false).encoding() == encoding) {
713 return true;
714 }
715 }
716
718 if (unconditionalGuardEncoding(true).encoding() == encoding) {
719 return true;
720 }
721 }
722
723 return false;
724}
725
#define assert(condition)
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
std::string errorMessage() const
Definition Exception.cc:123
static const std::string OSNAME_FU_GUARD_ENCODING
ObjectState name for FU guard encoding.
std::string port() const
virtual ObjectState * saveState() const
std::string functionUnit() const
static const std::string OSNAME_GPR_GUARD_ENCODING
ObjectState name for GPR guard encoding.
virtual ObjectState * saveState() const
int registerIndex() const
std::string registerFile() const
GuardField * parent() const
unsigned int encoding() const
bool isGuardInverted() const
FUGuardEncoding & fuGuardEncoding(int index) const
bool hasUnconditionalGuardEncoding(bool inverted) const
UnconditionalGuardEncoding * alwaysFalse_
Unconditional guard encoding for always-false expression.
void deleteFUGuardEncodings()
void addGuardEncoding(GPRGuardEncoding &encoding)
int gprGuardEncodingCount() const
UnconditionalGuardEncoding & unconditionalGuardEncoding(bool inverted) const
GPRGuardEncoding & gprGuardEncoding(int index) const
void deleteGPRGuardEncodings()
bool hasGPRGuardEncoding(const std::string &regFile, int index, bool inverted) const
virtual ObjectState * saveState() const
bool isAssigned(unsigned int encoding) const
GuardField(MoveSlot &parent)
Definition GuardField.cc:60
void removeGuardEncoding(GPRGuardEncoding &encoding)
UnconditionalGuardEncoding * alwaysTrue_
Unconditional guard encoding for always-true expression.
void removeUnconditionalGuardEncoding(UnconditionalGuardEncoding &encoding)
GPRGuardTable gprGuards_
GPR guard encodings.
virtual int childFieldCount() const
FUGuardTable fuGuards_
FU guard encodings.
bool hasFUGuardEncoding(const std::string &fu, const std::string &port, bool inverted) const
virtual ~GuardField()
virtual int width() const
int fuGuardEncodingCount() const
MoveSlot * parent() const
virtual void loadState(const ObjectState *state)
static const std::string OSNAME_GUARD_FIELD
ObjectState name for guard field.
Definition GuardField.hh:99
void deleteUnconditionalGuardEncodings()
virtual InstructionField & childField(int) const
InstructionField * parent() const
virtual void loadState(const ObjectState *state)
void setParent(InstructionField *parent)
virtual void setRelativePosition(int position)
virtual ObjectState * saveState() const
static unsigned int bitLength(long unsigned int number)
void setGuardField(GuardField &field)
Definition MoveSlot.cc:171
bool hasSourceField() const
Definition MoveSlot.cc:264
void unsetGuardField()
Definition MoveSlot.cc:189
bool hasDestinationField() const
Definition MoveSlot.cc:327
static NullFUGuardEncoding & instance()
static NullGPRGuardEncoding & instance()
static NullUnconditionalGuardEncoding & instance()
void setName(const std::string &name)
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string name() const
int childCount() const
static void deleteAllItems(SequenceType &aSequence)