2 Copyright (c) 2002-2009 Tampere University.
4 This file is part of TTA-Based Codesign Environment (TCE).
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:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
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.
25 * @file ImmediateElement.icc
27 * Inline definitions of ImmediateElement class.
29 * @author Jussi Nykänen 2003 (nykanen-no.spam-cs.tut.fi)
30 * @author Mikael Lepistö 18.12.2003 (tmlepist-no.spam-cs.tut.fi)
31 * @note reviewed 21 October 2003 by rl, ml, jn, pj
33 * @note rating: yellow
36 #include "Conversion.hh"
41 * Returns true if immediate is inline encoded.
43 * @return True immediate is inline encoded.
46 ImmediateElement::isInline() const {
47 return (destinationUnit_ == 0);
51 * Adds byte to the immediate.
53 * @param aByte Byte stored to immediate.
56 ImmediateElement::addByte(Byte aByte) {
57 value_.push_back(aByte);
61 * Sets value of one byte of element.
63 * @param index Index of byte to set.
64 * @param aValue Value to set.
65 * @exception OutOfRange Thrown if index is too big.
68 ImmediateElement::setByte(unsigned int index, Byte aValue) {
69 if (index >= length()) {
70 throw OutOfRange(__FILE__, __LINE__, "ImmediateElement::setByte()");
72 value_[index] = aValue;
76 * Returns value of one byte in immediate.
78 * @param index Index of byte to get.
79 * @return Value of immediate.
80 * @exception OutOfRange If index is out of bounds.
83 ImmediateElement::byte(unsigned int index) const {
84 if (index >= length()) {
85 throw OutOfRange(__FILE__, __LINE__, "ImmediateElement::byte()");
91 * Sets value of one word to immediate element.
93 * Clears old value and writes a word to element.
95 * If immediate is longer that written value, more significant bytes
96 * will be zeroed. See setWord(index, aValue) if you want to set
97 * word to any position of immediate without modifying other bytes
100 * @param aValue Value to set.
103 ImmediateElement::setWord(Word aValue) {
108 // check how many bytes are needed
109 Word tempValue = aValue;
111 for (unsigned int i = 0; i < sizeof(aValue); i++) {
115 tempValue = tempValue >> BYTE_BITWIDTH;
118 for (unsigned int i = 1; i <= length(); i++) {
119 setByte(length() - i, static_cast<Byte>(aValue));
120 aValue = aValue >> BYTE_BITWIDTH;
125 * Sets value of long word to immediate element.
127 * Clears old value and writes a word to element.
129 * If immediate is longer that written value, more significant bytes
130 * will be zeroed. See setWord(index, aValue) if you want to set
131 * word to any position of immediate without modifying other bytes
134 * @param aValue Value to set.
137 ImmediateElement::setULongWord(LongWord aValue) {
142 // check how many bytes are needed
143 LongWord tempValue = aValue;
145 for (unsigned int i = 0; i < sizeof(aValue); i++) {
149 tempValue = tempValue >> BYTE_BITWIDTH;
152 for (unsigned int i = 1; i <= length(); i++) {
153 setByte(length() - i, static_cast<Byte>(aValue));
154 aValue = aValue >> BYTE_BITWIDTH;
159 * Sets value of one word to immediate element.
161 * Clears old value and writes a signed word to element.
163 * If immediate is longer that written value, more significant bytes
164 * will be zeroed. See setWord(index, aValue) if you want to set
165 * word to any position of immediate without modifying other bytes
168 * @param aValue Value to set.
171 ImmediateElement::setSignedWord(SignedWord sValue) {
173 Word aValue = sValue;
177 // check how many bytes are needed
178 Word tempValue = aValue;
180 bool negative = sValue < 0;
182 for (unsigned int i = sizeof(aValue) ; i > 1; i--) {
183 int upBits = tempValue >> 24;
184 if ((negative && upBits != 255) ||
185 (!negative && upBits != 0)) {
189 tempValue <<= BYTE_BITWIDTH;
194 for (int i = 0; i < neededBytes; i++) {
198 for (unsigned int i = 1; i <= length(); i++) {
199 setByte(length() - i, static_cast<Byte>(aValue));
200 aValue = aValue >> BYTE_BITWIDTH;
203 // if we have a negative sub-sized number but upper bit not set 1
204 // add a byte full of sign-bit ones.
205 if (negative && length() < 4 && (!((byte(0) & 128) == 128))) {
206 value_.insert(value_.begin(), 255); // big endian crap
208 // if we have a positive sub-sized number but upper bit is set 1,
209 // add a byte full of zeroes.
210 if (!negative && length() < 4 && (((byte(0) & 128) == 128))) {
211 value_.insert(value_.begin(), 0); // big endian crap
217 * Sets value of one word to immediate element.
219 * Clears old value and writes a signed word to element.
221 * If immediate is longer that written value, more significant bytes
222 * will be zeroed. See setWord(index, aValue) if you want to set
223 * word to any position of immediate without modifying other bytes
226 * @param aValue Value to set.
229 ImmediateElement::setSignedLong(SLongWord sValue) {
231 LongWord aValue = sValue;
235 // check how many bytes are needed
236 LongWord tempValue = aValue;
238 bool negative = sValue < 0;
240 for (unsigned int i = sizeof(aValue) ; i > 1; i--) {
241 int upBits = tempValue >> 56;
242 if ((negative && upBits != 255) ||
243 (!negative && upBits != 0)) {
247 tempValue <<= BYTE_BITWIDTH;
252 for (int i = 0; i < neededBytes; i++) {
256 for (unsigned int i = 1; i <= length(); i++) {
257 setByte(length() - i, static_cast<Byte>(aValue));
258 aValue = aValue >> BYTE_BITWIDTH;
261 // if we have a negative sub-sized number but upper bit not set 1
262 // add a byte full of sign-bit ones.
263 if (negative && length() < 8 && (!((byte(0) & 128) == 128))) {
264 value_.insert(value_.begin(), 255); // big endian crap
266 // if we have a positive sub-sized number but upper bit is set 1,
267 // add a byte full of zeroes.
268 if (!negative && length() < 8 && (((byte(0) & 128) == 128))) {
269 value_.insert(value_.begin(), 0); // big endian crap
276 * Returns value of element as a word.
278 * If you want to get word from given index of immediate see
279 * word(index). Empty immediates are read as zero value.
281 * @return Value of immediate.
282 * @exception OutOfRange Value is too big to return as a word.
285 ImmediateElement::word() const {
288 // convert bytes to word
289 for (unsigned int i = 0; i < length(); i++) {
291 ((retValue << BYTE_BITWIDTH) |
292 static_cast<Byte>(value_[i]));
295 length() - i > sizeof(retValue)) {
298 __FILE__, __LINE__, "ImmediateElement::word()",
299 "Value to return is longer than value to return.");
307 * Returns value of element as a word.
309 * If you want to get word from given index of immediate see
310 * word(index). Empty immediates are read as zero value.
312 * @return Value of immediate.
313 * @exception OutOfRange Value is too big to return as a word.
316 ImmediateElement::longWord() const {
318 LongWord retValue = 0;
320 // convert bytes to word
321 for (unsigned int i = 0; i < length(); i++) {
323 ((retValue << BYTE_BITWIDTH) |
324 static_cast<Byte>(value_[i]));
327 length() - i > sizeof(retValue)) {
330 __FILE__, __LINE__, "ImmediateElement::word()",
331 "Value to return is longer than value to return.");
339 * Returns value of element as a signed word.
341 * If you want to get word from given index of immediate see
342 * word(index). Empty immediates are read as zero value.
344 * @return Value of immediate.
345 * @exception OutOfRange Value is too big to return as a signed word.
348 ImmediateElement::signedWord() const {
352 // convert bytes to word
353 for (unsigned int i = 0; i < length(); i++) {
355 ((retValue << BYTE_BITWIDTH) |
356 static_cast<Byte>(value_[i]));
359 length() - i > sizeof(retValue)) {
362 __FILE__, __LINE__, "ImmediateElement::word()",
363 "Value to return is longer than value to return.");
367 // If the most upper bit is true, but length < sizeof(word),
368 // this is a signed value, which need to be manually sign-extended.
369 unsigned int byteMask = ((1 << BYTE_BITWIDTH)-1);
370 if ((retValue >> (BYTE_BITWIDTH * length() -1) & 1) &&
371 length() < sizeof(SignedWord)) {
372 for (unsigned int i = length(); i < sizeof(SignedWord); i++) {
373 retValue |= (byteMask << (BYTE_BITWIDTH*i));
376 return static_cast<SignedWord>(retValue);
380 * Returns value of element as a signed word.
382 * If you want to get word from given index of immediate see
383 * word(index). Empty immediates are read as zero value.
385 * @return Value of immediate.
386 * @exception OutOfRange Value is too big to return as a signed word.
389 ImmediateElement::sLongWord() const {
391 SLongWord retValue = 0;
393 // convert bytes to word
394 for (unsigned int i = 0; i < length(); i++) {
396 ((retValue << BYTE_BITWIDTH) |
397 static_cast<Byte>(value_[i]));
400 length() - i > sizeof(retValue)) {
403 __FILE__, __LINE__, "ImmediateElement::word()",
404 "Value to return is longer than value to return.");
408 // If the most upper bit is true, but length < sizeof(word),
409 // this is a signed value, which need to be manually sign-extended.
410 unsigned long byteMask = ((1 << BYTE_BITWIDTH)-1);
411 if ((retValue >> (BYTE_BITWIDTH * length() -1) & 1) &&
412 length() < sizeof(SLongWord)) {
413 for (unsigned int i = length(); i < sizeof(SLongWord); i++) {
414 retValue |= (byteMask << (BYTE_BITWIDTH*i));
417 return static_cast<SLongWord>(retValue);
422 * Returns the number of bytes taken by the immediate value.
424 * @return Length of immediate in bytes.
427 ImmediateElement::length() const {
428 return value_.size();
432 * Returns destination unit.
434 * Unit 0x00 means that immediate is inline encoded. For inline immediates
435 * index is unique identifier and source field of move element should match
436 * to that. So destinationIndex and destinationUnit should be same that
437 * are in move element, which uses ImmediateElement.
439 * @return Destination unit.
442 ImmediateElement::destinationUnit() const {
443 return destinationUnit_;
447 * Sets destination unit.
449 * See destinationUnit().
451 * @param aDestinationUnit Destination identifier.
454 ImmediateElement::setDestinationUnit(Byte aDestinationUnit) {
455 destinationUnit_ = aDestinationUnit;
459 * Returns destination index.
461 * See destinationUnit().
463 * @return Destination index.
466 ImmediateElement::destinationIndex() const {
467 return destinationIndex_;
471 * Sets destination index.
473 * See destinationUnit().
475 * @param aDestinationIndex Destination index.
478 ImmediateElement::setDestinationIndex(Byte aDestinationIndex) {
479 destinationIndex_ = aDestinationIndex;