OpenASIP 2.2
Loading...
Searching...
No Matches
Operand.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 Operand.cc
26 *
27 * Definition of Operand class.
28 *
29 * @author Jussi Nykänen 2004 (nykanen-no.spam-cs.tut.fi)
30 * @author Mikael Lepistö 2007 (tmlepist-no.spam-cs.tut.fi)
31 * @note rating: yellow
32 * @note reviewed 17 August 2004 by jn, ll, tr, pj
33 */
34
35#include <vector>
36#include <string>
37#include <boost/format.hpp>
38
39#include "Operand.hh"
40#include "Conversion.hh"
41#include "Application.hh"
42#include "ContainerTools.hh"
43#include "ObjectState.hh"
44
45using std::vector;
46using std::string;
47using std::set;
48
49// const declarations used in Operation property file
50const string Operand::OPRND_ID = "id";
51const string Operand::OPRND_TYPE = "type";
52const string Operand::OPRND_MEM_ADDRESS = "mem-address";
53const string Operand::OPRND_MEM_UNITS = "mem-units";
54const string Operand::OPRND_MEM_DATA = "mem-data";
55const string Operand::OPRND_CAN_SWAP = "can-swap";
56const string Operand::OPRND_IN = "in";
57const string Operand::OPRND_OUT = "out";
58const string Operand::OPRND_ELEM_WIDTH = "element-width";
59const string Operand::OPRND_ELEM_COUNT = "element-count";
60
61const std::string Operand::SLONG_WORD_STRING = "SLongWord";
62const std::string Operand::ULONG_WORD_STRING = "ULongWord";
63const std::string Operand::SINT_WORD_STRING = "SIntWord";
64const std::string Operand::UINT_WORD_STRING = "UIntWord";
65const std::string Operand::FLOAT_WORD_STRING = "FloatWord";
66const std::string Operand::HALF_FLOAT_WORD_STRING = "HalfFloatWord";
67const std::string Operand::DOUBLE_WORD_STRING = "DoubleWord";
68const std::string Operand::BOOL_STRING = "Bool";
69const std::string Operand::RAW_DATA_STRING = "RawData";
70const std::string Operand::UNKNOWN_TYPE_STRING = "InvalidValue";
71
72/**
73 * Default constructor.
74 */
75Operand::Operand(bool isInput) :
76 Serializable(), index_(0), isInput_(isInput), type_(SINT_WORD),
77 elementCount_(1), isAddress_(false), addressUnits_(0),
78 isMemoryData_(false) {
80}
81
82/**
83 * Constructor.
84 *
85 * @param index Index of operand.
86 */
87Operand::Operand(bool isInput, int index, OperandType type) :
88 Serializable(), index_(index), isInput_(isInput), type_(type),
89 elementCount_(1), isAddress_(false), addressUnits_(0),
90 isMemoryData_(false) {
92}
93
94/**
95 * Copy constructor.
96 *
97 * @param op Operand to be copied.
98 */
100 Serializable(), index_(op.index()), isInput_(op.isInput()),
101 type_(op.type()), elementWidth_(op.elementWidth()),
102 elementCount_(op.elementCount()), isAddress_(op.isAddress()),
103 addressUnits_(op.addressUnits_), isMemoryData_(op.isMemoryData()),
104 swap_(op.swap()) {
105}
106
107/**
108 * Destructor.
109 */
112
113/**
114 * Clears the operand.
115 *
116 * This is used when operand state is reloaded from ObjectState tree. Old
117 * must be cleared first.
118 */
119void
121 index_ = 0;
122 elementWidth_ = 0;
123 elementCount_ = 0;
124 isAddress_ = false;
125 isMemoryData_ = false;
126 swap_.clear();
127}
128
129/**
130 * Returns the index of the Operand.
131 *
132 * @return The index of the Operand.
133 */
134int
136 return index_;
137}
138
139/**
140 * Returns true if operand is input.
141 *
142 * @return True if operand is input.
143 */
144bool
146 return isInput_;
147}
148
149/**
150 * Returns true if operand is output.
151 *
152 * @return True if operand is output.
153 */
154bool
156 return !isInput_;
157}
158
159/**
160 * Returns the type of the Operand.
161 *
162 * @return The type of the Operand.
163 */
166 return type_;
167}
168
169/**
170 * Sets the operand type.
171 *
172 * @param type The new type of the operand.
173 */
174void
178
179/**
180 * Returns the string type of the Operand.
181 *
182 * @return The string type of the Operand.
183 */
184const std::string&
186 switch (type_)
187 {
188 case SINT_WORD:
189 return SINT_WORD_STRING;
190 break;
191 case UINT_WORD:
192 return UINT_WORD_STRING;
193 break;
194 case SLONG_WORD:
195 return SLONG_WORD_STRING;
196 break;
197 case ULONG_WORD:
198 return ULONG_WORD_STRING;
199 break;
200 case FLOAT_WORD:
201 return FLOAT_WORD_STRING;
202 break;
203 case DOUBLE_WORD:
204 return DOUBLE_WORD_STRING;
205 break;
206 case HALF_FLOAT_WORD:
208 break;
209 case BOOL:
210 return BOOL_STRING;
211 break;
212 case RAW_DATA:
213 return RAW_DATA_STRING;
214 break;
215 default:
216 return UNKNOWN_TYPE_STRING;
217 break;
218 }
219}
220
223 if (isVector()) {
224 return "";
225 }
227 switch (this->type()) {
229 type = "signed";
230 break;
232 type = "unsigned";
233 break;
235 return "float";
236 break;
238 return "double";
239 break;
241 return "";
242 break;
243 default:
244 // TODO: how do halffloats work?
245 // they should not need any casts.
246 // cannot return half as it's only supported in opencl.
247 return "";
248 }
249 if (elementWidth() <= 8) {
250 return type + " char";
251 }
252 if (elementWidth() <= 16) {
253 return type + " short";
254 }
255 if (elementWidth() == 64) {
256 return type + " long";
257 }
258 return type + " int";
259}
260
261
262/**
263 * Tells if the operand is a vector operand, in other words, has subwords.
264 *
265 * @return True, if the operand is a vector operand.
266 */
267bool
269 return (elementCount_ > 1);
270}
271
272/**
273 * Returns width of an operand element in bits.
274 *
275 * @return Bit width of an element.
276 */
277int
279 return elementWidth_;
280}
281
282/**
283 * Sets the element bit width.
284 *
285 * @param New element bit width.
286 */
287void
291
292/**
293 * Returns total number of elements.
294 *
295 * @return Number of elements.
296 */
297int
299 return elementCount_;
300}
301
302/**
303 * Sets the number of elements.
304 *
305 * @param New element count.
306 */
307void
311
312/**
313 * Returns width of the operand in bits.
314 *
315 * @return Bit width of the operand.
316 */
317int
320}
321
322/**
323 * Returns true if Operand is address.
324 *
325 * @return True if Operand is address, false otherwise.
326 */
327bool
329 return isAddress_;
330}
331
332/**
333 * Returns the count of MAU's which this operand addresses.
334 *
335 * returns 0 if the operand is not a memory address,
336 * or the size of the memory access int MAU's this operation accesses.
337 *
338 * @return count of MAUs addressed by this operand.
339 */
340int
342 return addressUnits_;
343}
344
345/**
346 * Returns true if Operand is memory data.
347 *
348 * @return True if Operand is memory data, false otherwise.
349 */
350bool
352 return isMemoryData_;
353}
354
355/**
356 * Returns the set of operands that can be swapped with this operand.
357 *
358 * @return The set of operands that can be swapped with this operand.
359 */
360const std::set<int>&
362 return swap_;
363}
364
365/**
366 * Returns true if Operand can be swapped with op.
367 *
368 * @param op Operand being investigated.
369 * @return True if Operand can be swapped with op, false otherwise.
370 */
371bool
372Operand::canSwap(const Operand& op) const {
374}
375
376/**
377 * Loads Operand state from an ObjectState object.
378 *
379 * @param state State containing operand properties.
380 * @exception ObjectStateLoadingException If loading fails for some reason.
381 */
382void
384 clear();
385
386 string method = "Operand::loadState()";
387
388 try {
389 index_ = state->intAttribute(OPRND_ID);
390 std::string typeString = state->stringAttribute(OPRND_TYPE);
391
392 if (typeString.compare(SINT_WORD_STRING) == 0) {
394 } else if (typeString.compare(UINT_WORD_STRING) == 0) {
396 } else if (typeString.compare(SLONG_WORD_STRING) == 0) {
398 } else if (typeString.compare(ULONG_WORD_STRING) == 0) {
400 } else if (typeString.compare(FLOAT_WORD_STRING) == 0) {
402 } else if (typeString.compare(DOUBLE_WORD_STRING) == 0) {
404 } else if (typeString.compare(HALF_FLOAT_WORD_STRING) == 0) {
406 } else if (typeString.compare(BOOL_STRING) == 0) {
407 type_ = BOOL;
408 } else if (typeString.compare(RAW_DATA_STRING) == 0) {
409 type_ = RAW_DATA;
410 } else {
411 string msg = "Invalid operand type: \"" + typeString + "\"";
412 throw Exception(__FILE__, __LINE__, method, msg);
413 }
414
415 if (state->hasAttribute(OPRND_ELEM_WIDTH)) {
417 } else {
419 }
420
421 if (state->hasAttribute(OPRND_ELEM_COUNT)) {
423 } else {
424 elementCount_ = 1;
425 }
426
429
430 if (state->hasAttribute(OPRND_MEM_UNITS)) {
432 }
433
434 if (state->childCount() > 1) {
435 string msg = "Erronous number of children";
436 throw Exception(__FILE__, __LINE__, method, msg);
437 }
438
439 for (int j = 0; j < state->childCount(); j++) {
440 ObjectState* child = state->child(j);
441 if (child->name() == OPRND_CAN_SWAP) {
442 for (int i = 0; i < child->childCount(); i++) {
443 ObjectState* canSwap = child->child(i);
444 int id =
445 Conversion::toInt(canSwap->stringAttribute(OPRND_ID));
446 swap_.insert(id);
447 }
448 } else {
449 string msg = "Unknown attribute: " + child->name();
450 throw Exception(__FILE__, __LINE__, method, msg);
451 }
452 }
453
454 } catch (const NumberFormatException& n) {
455 string message = "Conversion failed: " + n.errorMessage();
457 __FILE__, __LINE__, method, message);
458
459 } catch (const KeyNotFound& k) {
460 string message = "Attribute not found: " + k.errorMessage();
462 __FILE__, __LINE__, method, message);
463 error.setCause(k);
464 throw error;
465 } catch (Exception& e) {
466 string message =
467 "Error while loading operation operand settings. "
468 "An error in the operation format?" + e.errorMessageStack();
470 __FILE__, __LINE__, __func__, message);
471 newe.setCause(e);
472 throw newe;
473 }
474 catch (...) {
475 string message =
476 "Error while loading operation operand settings. "
477 "An error in the operation format?";
479 __FILE__, __LINE__, __func__, message);
480 throw newe;
481 }
482}
483
484/**
485 * Saves the state of the Operation to ObjectState object.
486 *
487 * @return The created ObjectState tree.
488 */
491
492 ObjectState* root = new ObjectState("");
494
495 switch(type_) {
496 case SINT_WORD:
498 break;
499 case UINT_WORD:
501 break;
502 case SLONG_WORD:
504 break;
505 case ULONG_WORD:
507 break;
508 case FLOAT_WORD:
510 break;
511 case DOUBLE_WORD:
513 break;
514 case HALF_FLOAT_WORD:
516 break;
517 case BOOL:
519 break;
520 case RAW_DATA:
522 break;
523 default:
525 }
526
529
532 if (addressUnits_ != 0) {
534 }
535
536 if (swap_.size() > 0) {
538 set<int>::const_iterator it = swap_.begin();
539 while (it != swap_.end()) {
540 ObjectState* canSwapChild = new ObjectState(OPRND_IN);
541 canSwapChild->setAttribute(OPRND_ID, *it);
542 canSwap->addChild(canSwapChild);
543 it++;
544 }
545 root->addChild(canSwap);
546 }
547 return root;
548}
549
550/**
551 * Returns default element width depending on operand's type.
552 *
553 * @param type Operand type.
554 * @return Element bit width of the operand.
555 */
556int
558 if (type == DOUBLE_WORD || type == SLONG_WORD || type == ULONG_WORD) {
559 return 64;
560 } else if (type == HALF_FLOAT_WORD) {
561 return 16;
562 } else if (type == BOOL) {
563 return 1;
564 } else {
565 return 32;
566 }
567}
568
569//////////////////////////////////////////////////////////////////////////////
570// NullOperand
571//////////////////////////////////////////////////////////////////////////////
572
574
575/**
576 * Constructor.
577 */
580
581/**
582 * Destructor.
583 */
586
587/**
588 * Aborts program with error log message.
589 *
590 * @return 0.
591 */
592int
594 abortWithError("index()");
595 return 0;
596}
597
598/**
599 * Aborts program with error log message.
600 *
601 * @return False.
602 */
603bool
605 abortWithError("isInput()");
606 return 0;
607}
608
609/**
610 * Aborts program with error log message.
611 *
612 * @return False.
613 */
614bool
616 abortWithError("isOutput()");
617 return 0;
618}
619
620/**
621 * Aborts program with error log message.
622 *
623 * @return False.
624 */
625bool
627 abortWithError("isAddress()");
628 return false;
629}
630
631/**
632 * Aborts program with error log message.
633 *
634 * @return False.
635 */
636bool
638 abortWithError("isMemoryData()");
639 return false;
640}
641
642/**
643 * Aborts program with error log message.
644 *
645 * @return An empty vector.
646 */
647const set<int>&
649 abortWithError("swap()");
650 return swap_;
651}
652
653/**
654 * Aborts the program with error message.
655 *
656 * @return false.
657 */
658bool
660 abortWithError("canSwap()");
661 return false;
662}
663
#define __func__
#define abortWithError(message)
find Finds info of the inner loops in the false
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
static int toInt(const T &source)
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
std::string errorMessage() const
Definition Exception.cc:123
void setCause(const Exception &cause)
Definition Exception.cc:75
virtual bool isAddress() const
Definition Operand.cc:626
std::set< int > swap_
Needed for one method, always empty.
Definition Operand.hh:194
virtual bool isInput() const
Definition Operand.cc:604
virtual int index() const
Definition Operand.cc:593
virtual const std::set< int > & swap() const
Definition Operand.cc:648
virtual bool isOutput() const
Definition Operand.cc:615
static NullOperand * instance_
Unique instance.
Definition Operand.hh:191
virtual bool canSwap(const Operand &op) const
Definition Operand.cc:659
virtual ~NullOperand()
Definition Operand.cc:584
virtual bool isMemoryData() const
Definition Operand.cc:637
bool hasAttribute(const std::string &name) const
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
bool boolAttribute(const std::string &name) const
int intAttribute(const std::string &name) const
std::string name() const
int childCount() const
bool isInput_
Direction of operand.
Definition Operand.hh:143
virtual bool isVector() const
Definition Operand.cc:268
virtual const std::string & typeString() const
Definition Operand.cc:185
Operand(bool isInput)
Definition Operand.cc:75
virtual bool isMemoryData() const
Definition Operand.cc:351
static const std::string OPRND_IN
Object state name for input operand.
Definition Operand.hh:94
virtual int elementCount() const
Definition Operand.cc:298
virtual bool isAddress() const
Definition Operand.cc:328
virtual void setElementWidth(int elementWidth)
Definition Operand.cc:288
static const std::string FLOAT_WORD_STRING
Definition Operand.hh:75
static const std::string OPRND_CAN_SWAP
Object state name for can swap.
Definition Operand.hh:92
virtual bool isInput() const
Definition Operand.cc:145
void clear()
Definition Operand.cc:120
static const std::string OPRND_ELEM_WIDTH
Object state name for element width.
Definition Operand.hh:98
static const std::string SLONG_WORD_STRING
Definition Operand.hh:70
virtual bool isOutput() const
Definition Operand.cc:155
static const std::string OPRND_MEM_UNITS
Object state name for memory unit count.
Definition Operand.hh:88
virtual int index() const
Definition Operand.cc:135
virtual void setType(OperandType type)
Definition Operand.cc:175
bool isAddress_
Flag indicating whether Operand is address or not.
Definition Operand.hh:151
virtual const std::set< int > & swap() const
Definition Operand.cc:361
int index_
Index of the Operand.
Definition Operand.hh:141
static const std::string OPRND_TYPE
Object state name for operand type.
Definition Operand.hh:84
static int defaultElementWidth(OperandType type)
Definition Operand.cc:557
virtual int memoryUnits() const
Definition Operand.cc:341
static const std::string OPRND_MEM_ADDRESS
Object state name for memory address.
Definition Operand.hh:86
static const std::string OPRND_OUT
Object state name for output operand.
Definition Operand.hh:96
int addressUnits_
size of the data this operation addresses. 0 if unknown.
Definition Operand.hh:153
static const std::string OPRND_ELEM_COUNT
Object state name for element count.
Definition Operand.hh:100
static const std::string HALF_FLOAT_WORD_STRING
Definition Operand.hh:74
virtual int width() const
Definition Operand.cc:318
static const std::string BOOL_STRING
Definition Operand.hh:77
virtual ~Operand()
Definition Operand.cc:110
OperandType type_
Type of the Operand.
Definition Operand.hh:145
virtual OperandType type() const
Definition Operand.cc:165
static const std::string DOUBLE_WORD_STRING
Definition Operand.hh:76
virtual void setElementCount(int elementCount)
Definition Operand.cc:308
OperandType
Definition Operand.hh:58
@ SLONG_WORD
Definition Operand.hh:66
@ FLOAT_WORD
Definition Operand.hh:61
@ ULONG_WORD
Definition Operand.hh:67
@ RAW_DATA
Definition Operand.hh:65
@ SINT_WORD
Definition Operand.hh:59
@ DOUBLE_WORD
Definition Operand.hh:62
@ UINT_WORD
Definition Operand.hh:60
@ HALF_FLOAT_WORD
Definition Operand.hh:63
virtual bool canSwap(const Operand &op) const
Definition Operand.cc:372
virtual TCEString CTypeString() const
Definition Operand.cc:222
static const std::string UNKNOWN_TYPE_STRING
Definition Operand.hh:79
virtual ObjectState * saveState() const
Definition Operand.cc:490
static const std::string ULONG_WORD_STRING
Definition Operand.hh:71
int elementWidth_
Width of an element.
Definition Operand.hh:147
static const std::string OPRND_MEM_DATA
Object state name for memory data.
Definition Operand.hh:90
static const std::string OPRND_ID
Object state name for operand id.
Definition Operand.hh:82
static const std::string UINT_WORD_STRING
Definition Operand.hh:73
static const std::string RAW_DATA_STRING
Definition Operand.hh:78
static const std::string SINT_WORD_STRING
Definition Operand.hh:72
bool isMemoryData_
Flag indicating whether Operand is memory data or not.
Definition Operand.hh:155
virtual void loadState(const ObjectState *state)
Definition Operand.cc:383
std::set< int > swap_
Indexes of Operands which can be swapped with this Operand.
Definition Operand.hh:157
virtual int elementWidth() const
Definition Operand.cc:278
int elementCount_
Number of total elements.
Definition Operand.hh:149