OpenASIP 2.2
Loading...
Searching...
No Matches
ImmediateElement.icc
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 ImmediateElement.icc
26 *
27 * Inline definitions of ImmediateElement class.
28 *
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
32 *
33 * @note rating: yellow
34 */
35
36#include "Conversion.hh"
37
38namespace TPEF {
39
40/**
41 * Returns true if immediate is inline encoded.
42 *
43 * @return True immediate is inline encoded.
44 */
45inline bool
46ImmediateElement::isInline() const {
47 return (destinationUnit_ == 0);
48}
49
50/**
51 * Adds byte to the immediate.
52 *
53 * @param aByte Byte stored to immediate.
54 */
55inline void
56ImmediateElement::addByte(Byte aByte) {
57 value_.push_back(aByte);
58}
59
60/**
61 * Sets value of one byte of element.
62 *
63 * @param index Index of byte to set.
64 * @param aValue Value to set.
65 * @exception OutOfRange Thrown if index is too big.
66 */
67inline void
68ImmediateElement::setByte(unsigned int index, Byte aValue) {
69 if (index >= length()) {
70 throw OutOfRange(__FILE__, __LINE__, "ImmediateElement::setByte()");
71 }
72 value_[index] = aValue;
73}
74
75/**
76 * Returns value of one byte in immediate.
77 *
78 * @param index Index of byte to get.
79 * @return Value of immediate.
80 * @exception OutOfRange If index is out of bounds.
81 */
82inline Byte
83ImmediateElement::byte(unsigned int index) const {
84 if (index >= length()) {
85 throw OutOfRange(__FILE__, __LINE__, "ImmediateElement::byte()");
86 }
87 return value_[index];
88}
89
90/**
91 * Sets value of one word to immediate element.
92 *
93 * Clears old value and writes a word to element.
94 *
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
98 * stored inside.
99 *
100 * @param aValue Value to set.
101 */
102inline void
103ImmediateElement::setWord(Word aValue) {
104
105 // remove old value
106 value_.clear();
107
108 // check how many bytes are needed
109 Word tempValue = aValue;
110
111 for (unsigned int i = 0; i < sizeof(aValue); i++) {
112 if (tempValue > 0) {
113 addByte(0);
114 }
115 tempValue = tempValue >> BYTE_BITWIDTH;
116 }
117
118 for (unsigned int i = 1; i <= length(); i++) {
119 setByte(length() - i, static_cast<Byte>(aValue));
120 aValue = aValue >> BYTE_BITWIDTH;
121 }
122}
123
124/**
125 * Sets value of long word to immediate element.
126 *
127 * Clears old value and writes a word to element.
128 *
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
132 * stored inside.
133 *
134 * @param aValue Value to set.
135 */
136inline void
137ImmediateElement::setULongWord(LongWord aValue) {
138
139 // remove old value
140 value_.clear();
141
142 // check how many bytes are needed
143 LongWord tempValue = aValue;
144
145 for (unsigned int i = 0; i < sizeof(aValue); i++) {
146 if (tempValue > 0) {
147 addByte(0);
148 }
149 tempValue = tempValue >> BYTE_BITWIDTH;
150 }
151
152 for (unsigned int i = 1; i <= length(); i++) {
153 setByte(length() - i, static_cast<Byte>(aValue));
154 aValue = aValue >> BYTE_BITWIDTH;
155 }
156}
157
158/**
159 * Sets value of one word to immediate element.
160 *
161 * Clears old value and writes a signed word to element.
162 *
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
166 * stored inside.
167 *
168 * @param aValue Value to set.
169 */
170inline void
171ImmediateElement::setSignedWord(SignedWord sValue) {
172
173 Word aValue = sValue;
174 // remove old value
175 value_.clear();
176
177 // check how many bytes are needed
178 Word tempValue = aValue;
179
180 bool negative = sValue < 0;
181 int neededBytes = 1;
182 for (unsigned int i = sizeof(aValue) ; i > 1; i--) {
183 int upBits = tempValue >> 24;
184 if ((negative && upBits != 255) ||
185 (!negative && upBits != 0)) {
186 neededBytes = i;
187 break;
188 } else {
189 tempValue <<= BYTE_BITWIDTH;
190 }
191
192 }
193
194 for (int i = 0; i < neededBytes; i++) {
195 addByte(0);
196 }
197
198 for (unsigned int i = 1; i <= length(); i++) {
199 setByte(length() - i, static_cast<Byte>(aValue));
200 aValue = aValue >> BYTE_BITWIDTH;
201 }
202
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
207 }
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
212 }
213}
214
215
216/**
217 * Sets value of one word to immediate element.
218 *
219 * Clears old value and writes a signed word to element.
220 *
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
224 * stored inside.
225 *
226 * @param aValue Value to set.
227 */
228inline void
229ImmediateElement::setSignedLong(SLongWord sValue) {
230
231 LongWord aValue = sValue;
232 // remove old value
233 value_.clear();
234
235 // check how many bytes are needed
236 LongWord tempValue = aValue;
237
238 bool negative = sValue < 0;
239 int neededBytes = 1;
240 for (unsigned int i = sizeof(aValue) ; i > 1; i--) {
241 int upBits = tempValue >> 56;
242 if ((negative && upBits != 255) ||
243 (!negative && upBits != 0)) {
244 neededBytes = i;
245 break;
246 } else {
247 tempValue <<= BYTE_BITWIDTH;
248 }
249
250 }
251
252 for (int i = 0; i < neededBytes; i++) {
253 addByte(0);
254 }
255
256 for (unsigned int i = 1; i <= length(); i++) {
257 setByte(length() - i, static_cast<Byte>(aValue));
258 aValue = aValue >> BYTE_BITWIDTH;
259 }
260
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
265 }
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
270 }
271}
272
273
274
275/**
276 * Returns value of element as a word.
277 *
278 * If you want to get word from given index of immediate see
279 * word(index). Empty immediates are read as zero value.
280 *
281 * @return Value of immediate.
282 * @exception OutOfRange Value is too big to return as a word.
283 */
284inline Word
285ImmediateElement::word() const {
286 Word retValue = 0;
287
288 // convert bytes to word
289 for (unsigned int i = 0; i < length(); i++) {
290 retValue =
291 ((retValue << BYTE_BITWIDTH) |
292 static_cast<Byte>(value_[i]));
293
294 if (retValue != 0 &&
295 length() - i > sizeof(retValue)) {
296
297 throw OutOfRange(
298 __FILE__, __LINE__, "ImmediateElement::word()",
299 "Value to return is longer than value to return.");
300 }
301 }
302
303 return retValue;
304}
305
306/**
307 * Returns value of element as a word.
308 *
309 * If you want to get word from given index of immediate see
310 * word(index). Empty immediates are read as zero value.
311 *
312 * @return Value of immediate.
313 * @exception OutOfRange Value is too big to return as a word.
314 */
315inline LongWord
316ImmediateElement::longWord() const {
317
318 LongWord retValue = 0;
319
320 // convert bytes to word
321 for (unsigned int i = 0; i < length(); i++) {
322 retValue =
323 ((retValue << BYTE_BITWIDTH) |
324 static_cast<Byte>(value_[i]));
325
326 if (retValue != 0 &&
327 length() - i > sizeof(retValue)) {
328
329 throw OutOfRange(
330 __FILE__, __LINE__, "ImmediateElement::word()",
331 "Value to return is longer than value to return.");
332 }
333 }
334
335 return retValue;
336}
337
338/**
339 * Returns value of element as a signed word.
340 *
341 * If you want to get word from given index of immediate see
342 * word(index). Empty immediates are read as zero value.
343 *
344 * @return Value of immediate.
345 * @exception OutOfRange Value is too big to return as a signed word.
346 */
347inline SignedWord
348ImmediateElement::signedWord() const {
349
350 Word retValue = 0;
351
352 // convert bytes to word
353 for (unsigned int i = 0; i < length(); i++) {
354 retValue =
355 ((retValue << BYTE_BITWIDTH) |
356 static_cast<Byte>(value_[i]));
357
358 if (retValue != 0 &&
359 length() - i > sizeof(retValue)) {
360
361 throw OutOfRange(
362 __FILE__, __LINE__, "ImmediateElement::word()",
363 "Value to return is longer than value to return.");
364 }
365 }
366
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));
374 }
375 }
376 return static_cast<SignedWord>(retValue);
377}
378
379/**
380 * Returns value of element as a signed word.
381 *
382 * If you want to get word from given index of immediate see
383 * word(index). Empty immediates are read as zero value.
384 *
385 * @return Value of immediate.
386 * @exception OutOfRange Value is too big to return as a signed word.
387 */
388inline SLongWord
389ImmediateElement::sLongWord() const {
390
391 SLongWord retValue = 0;
392
393 // convert bytes to word
394 for (unsigned int i = 0; i < length(); i++) {
395 retValue =
396 ((retValue << BYTE_BITWIDTH) |
397 static_cast<Byte>(value_[i]));
398
399 if (retValue != 0 &&
400 length() - i > sizeof(retValue)) {
401
402 throw OutOfRange(
403 __FILE__, __LINE__, "ImmediateElement::word()",
404 "Value to return is longer than value to return.");
405 }
406 }
407
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));
415 }
416 }
417 return static_cast<SLongWord>(retValue);
418}
419
420
421/**
422 * Returns the number of bytes taken by the immediate value.
423 *
424 * @return Length of immediate in bytes.
425 */
426inline unsigned int
427ImmediateElement::length() const {
428 return value_.size();
429}
430
431/**
432 * Returns destination unit.
433 *
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.
438 *
439 * @return Destination unit.
440 */
441inline Byte
442ImmediateElement::destinationUnit() const {
443 return destinationUnit_;
444}
445
446/**
447 * Sets destination unit.
448 *
449 * See destinationUnit().
450 *
451 * @param aDestinationUnit Destination identifier.
452 */
453inline void
454ImmediateElement::setDestinationUnit(Byte aDestinationUnit) {
455 destinationUnit_ = aDestinationUnit;
456}
457
458/**
459 * Returns destination index.
460 *
461 * See destinationUnit().
462 *
463 * @return Destination index.
464 */
465inline Byte
466ImmediateElement::destinationIndex() const {
467 return destinationIndex_;
468}
469
470/**
471 * Sets destination index.
472 *
473 * See destinationUnit().
474 *
475 * @param aDestinationIndex Destination index.
476 */
477inline void
478ImmediateElement::setDestinationIndex(Byte aDestinationIndex) {
479 destinationIndex_ = aDestinationIndex;
480}
481
482}