OpenASIP 2.2
Loading...
Searching...
No Matches
CodeSectionCreator.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 CodeSectionCreator.cc
26 *
27 * Definitions of CodeSectionCreator class.
28 *
29 * @author Mikael Lepistö 2005 (tmlepist-no.spam-cs.tut.fi)
30 * @author Pekka Jääskeläinen 2006 (pekka.jaaskelainen-no.spam-tut.fi)
31 *
32 * @note rating: yellow
33 */
34
35#include <deque>
36
37#include "CodeSectionCreator.hh"
38
40#include "LabelManager.hh"
42
43#include "Binary.hh"
44#include "Section.hh"
45#include "MoveElement.hh"
46#include "ImmediateElement.hh"
47#include "CodeSection.hh"
48#include "ResourceElement.hh"
49#include "ResourceSection.hh"
50
51#include "Machine.hh"
52#include "MathTools.hh"
53
54using namespace TPEF;
55
56// in future this can be defined by code address space size
58
59/**
60 * Constructor.
61 *
62 * @param resourceManager TPEF resources and strings.
63 * @param parent Assembler root class.
64 */
66 MachineResourceManager &resourceManager,
67 const TTAMachine::Machine& targetMachine,
69 mach_(targetMachine),
70 resources_(resourceManager), parent_(parent),
71 isNextBegin_(true), slotNumber_(0), immediateIndex_(0) {
72}
73
74/**
75 * Creator to start new section from given start address.
76 *
77 * @param startAddress Start address of next section.
78 * @exception OutOfRange Start address is not in code address space.
79 */
80void
82 // Checks are not needed yet, since we support currently only
83 // one code section.
84
85 // @todo if multiple times then create new section each time..
86 // for now only one code section is supported
87
88 // @todo sanity checks for addresses and moves (next is begin...)
89
90 internalSection_.startAddress = startAddress;
91}
92
93/**
94 * Adds new move to section.
95 *
96 * If exception is thrown, creator will remain as it was before function call.
97 *
98 * @param move Parsed move.
99 * @exception CompileError If referenced resource is not found from machine.
100 */
101void
103 try {
104 if (move.isBegin) {
106 }
107
108 InternalElement* newMove = NULL;
109 InternalElement* newImmediate = NULL;
110
111 UValue srcWidth = 0, dstWidth = 0;
112
113 switch (move.type) {
114
116
117 // check that source is valid
118 if (move.source.isRegister) {
119 CompileError error(
120 __FILE__, __LINE__, __func__,
121 "Internal error: Immediate source must be literal or "
122 "expression.");
123
125 throw error;
126 }
127
128 static InternalElement newElement;
129 newImmediate = &newElement;
130
131 newElement.type = IMMEDIATE;
132 newElement.asmLineNumber = move.asmLineNumber;
133 newElement.isBegin = false;
134
135 newElement.annotationes = move.annotationes;
136
137 // check value bitwidth
138 newElement.immValue = move.source.immTerm;
139
140 UValue tempValue = newElement.immValue.value;
141 while(tempValue > 0) {
142 tempValue = tempValue >> 1;
143 srcWidth++;
144 }
145
146 // destination of the immediate
149 move.asmLineNumber, move.destination, newElement.slot,
151
152 newElement.dstType = resID.type;
153
154 if (newElement.dstType != MoveElement::MF_IMM) {
155 CompileError error(
156 __FILE__, __LINE__, __func__,
157 "Long immediate destination must be immediate unit.");
158
160 throw error;
161 }
162
163 newElement.dstUnit = resID.unit;
164 newElement.dstIndex = resID.index;
165 dstWidth = resID.width;
166
167 } break;
168
169 case ParserMove::EMPTY: {
170 static InternalElement newElement;
171 newMove = &newElement;
172
173 newElement.asmLineNumber = move.asmLineNumber;
174 newElement.type = EMPTY;
175 newElement.isBegin = move.isBegin;
176 newElement.slot = slotNumber();
177 } break;
178
180 static InternalElement newElement;
181 newElement.asmLineNumber = move.asmLineNumber;
182 newMove = &newElement;
183
184 newElement.slot = slotNumber();
185 newElement.type = MOVE;
186
187 newElement.annotationes = move.annotationes;
188
189 // source
190 if (move.source.isRegister) {
191
194 move.asmLineNumber,
195 move.source.regTerm, newElement.slot,
197
198 newElement.srcType = resID.type;
199 newElement.srcUnit = resID.unit;
200 newElement.srcIndex = resID.index;
201
202 srcWidth = resID.width;
203
204 } else {
205 // inline immediate
206 static InternalElement immediate;
207 immediate.asmLineNumber = move.asmLineNumber;
208 newImmediate = &immediate;
209
210 immediate.slot = newElement.slot;
211 immediate.type = IMMEDIATE;
213 immediate.dstIndex = immediateIndex();
214 immediate.isBegin = false;
215 immediate.immValue = move.source.immTerm;
216
217 newElement.srcType = MoveElement::MF_IMM;
218 newElement.srcUnit = immediate.dstUnit;
219 newElement.srcIndex = immediate.dstIndex;
220
221 // check value bitwidth
222 UValue tempValue = immediate.immValue.value;
223 while(tempValue > 0) {
224 tempValue = tempValue >> 1;
225 srcWidth++;
226 }
227 }
228
229 // destination
232 move.destination, newElement.slot,
234
235 newElement.dstType = resID.type;
236 newElement.dstUnit = resID.unit;
237 newElement.dstIndex = resID.index;
238 newElement.isBegin = move.isBegin;
239 dstWidth = resID.width;
240
241 // guard
242 newElement.isGuarded = move.guard.isGuarded;
243
244 if (newElement.isGuarded) {
245 newElement.isInverted = move.guard.isInverted;
246
248
249 if (newElement.isInverted) {
250 resID = &resources_.resourceID(
251 move.asmLineNumber,
252 move.guard.regTerm, newElement.slot,
254
255 } else {
256 resID = &resources_.resourceID(
257 move.asmLineNumber,
258 move.guard.regTerm, newElement.slot,
260 }
261
262 newElement.guardType = resID->type;
263 newElement.guardUnit = resID->unit;
264 newElement.guardIndex = resID->index;
265 }
266
267 if (isDestinationAlreadyWritten(newElement)) {
269 move.asmLineNumber,
270 "Move destination: " +
271 move.destination.toString() +
272 " is already written "
273 "in current instruction.");
274 }
275
276 } break;
277
278 default:
279 assert(false);
280 }
281
282 if (newMove != NULL) {
283 // check that there are enough busses with sufficient width for
284 // all parsed moves
285 try {
286 // if source is wider than bus
287 UValue busWidth = resources_.findBusWidth(newMove->slot);
288 if ( busWidth < srcWidth) {
289
291 move.asmLineNumber,
292 "Bus width: " +
293 Conversion::toString(busWidth) +
294 " is smaller than source: " +
295 Conversion::toString(srcWidth));
296 }
297
298 // if source or destination is wider than bus
299 if (dstWidth < srcWidth) {
301 move.asmLineNumber,
302 "Source is wider than destination.");
303 }
304
305 } catch (OutOfRange& e) {
306 CompileError error(
307 __FILE__, __LINE__, __func__,
308 "Too many bus slots used.");
310 error.setCause(e);
311
312 throw error;
313 }
314
315 internalSection_.elements.push_back(*newMove);
316 }
317
318 if (newImmediate != NULL) {
319 internalSection_.elements.push_back(*newImmediate);
320 }
321
322 } catch (IllegalMachine& e) {
323 CompileError error(
324 __FILE__, __LINE__, __func__, e.errorMessage());
325
327 error.setCause(e);
328
329 throw error;
330 }
331}
332
333/**
334 * Writes created sections to given binary.
335 *
336 * All data stored inside creator is freed after this call, unless
337 * exception is thrown.
338 *
339 * In case of exception creator restores its state to be same that
340 * state was before running finalize() (finalize() can be runned again).
341 *
342 * @param tpef Binary where to created sections should be added.
343 * @param labels LabelManager where to add data labels and relocations.
344 * @exception CompileError If there is any errors during compiling.
345 */
346void
348 // we don't have to have emty CodeSection
349 if (internalSection_.elements.size() > 0) {
350
351 CodeSection* codeSection = dynamic_cast<CodeSection*>(
353
354 assert(codeSection != NULL);
355
356 try {
357 codeSection->setLink(resources_.resourceSection());
358 codeSection->setName(resources_.stringToChunk(""));
359
360 try {
361 codeSection->setASpace(resources_.codeAddressSpace());
362
363 } catch (IllegalMachine& e) {
364 CompileError error(
365 __FILE__, __LINE__, __func__,
366 "Can't find code address space.");
367
368 error.setCause(e);
369
370 throw error;
371 }
372
373 std::vector<ImmediateElement*> recentImmediates;
374
375 // create the moves
376 for (unsigned int i = 0;
377 i < internalSection_.elements.size(); i++) {
378
380
381 assert(elem.slot <= 0xff);
382
383 if (elem.isBegin) {
384 // TODO: Check that the recent long immediates are well
385 // formed, as per following conditions.
386
387 // A valid instruction template exists that encodes
388 // them.
389
390 // The same unit is never written twice.
391
392 // There exists a combination of all destination units
393 // needed.
394
395 // The fields that encode each immediate are wide enough
396 // to encode the given constant.
397
398 recentImmediates.clear();
399 }
400
401 switch(elem.type) {
402 case EMPTY: {
403 MoveElement *emptyMove = new MoveElement();
404 emptyMove->setBegin(elem.isBegin);
405 emptyMove->setEmpty(true);
406 emptyMove->setBus(elem.slot + 1);
407 addAnnotationes(*emptyMove, elem, labels);
408 codeSection->addElement(emptyMove);
409 } break;
410
411 case IMMEDIATE: {
412 ImmediateElement *immElem = new ImmediateElement();
413 immElem->setBegin(elem.isBegin);
414
415 UValue immValue = 0;
416 if (elem.immValue.isExpression) {
417
418 immValue = labels.resolveExpressionValue(
419 elem.asmLineNumber, elem.immValue);
420
421 // MARK
422 ASpaceElement& aSpaceElement =
423 labels.aSpaceElement(
425
426 const std::string aSpaceName =
427 labels.aSpaceName(elem.immValue.expression.label);
428
429 std::size_t relocSize = CODE_RELOC_SIZE;
430
431 try {
432 // figure out what is the maximum address of
433 // the referred address space and set it as
434 // the relocation width for the immediate
435 const TTAMachine::AddressSpace* addressSpace =
436 mach_.addressSpaceNavigator().item(aSpaceName);
437 assert(addressSpace != NULL);
438 relocSize = MathTools::requiredBits(
439 static_cast<unsigned int>(
440 addressSpace->end()));
441 } catch (const Exception& e) {
443 << "Could not get access to MOM address space."
444 << std::endl;
445 }
446
447
448 labels.addRelocation(
449 *codeSection, *immElem, aSpaceElement, immValue,
450 relocSize);
451
452 } else {
453 immValue = elem.immValue.value;
454 }
455
456 immElem->setDestinationUnit(elem.dstUnit);
457 immElem->setDestinationIndex(elem.dstIndex);
458 immElem->setWord(immValue);
459
460 if (immElem->destinationUnit() !=
462
463 recentImmediates.push_back(immElem);
464 }
465
466 addAnnotationes(*immElem, elem, labels);
467 codeSection->addElement(immElem);
468 } break;
469
470 case MOVE: {
471 MoveElement *newMove = new MoveElement();
472 newMove->setEmpty(false);
473 newMove->setBegin(elem.isBegin);
474
475 newMove->setBus(elem.slot + 1);
476
477 newMove->setSourceType(elem.srcType);
478 newMove->setSourceUnit(elem.srcUnit);
479 newMove->setSourceIndex(elem.srcIndex);
480
481 newMove->setDestinationType(elem.dstType);
482 newMove->setDestinationUnit(elem.dstUnit);
483 newMove->setDestinationIndex(elem.dstIndex);
484
485 newMove->setGuardType(elem.guardType);
486 newMove->setGuardUnit(elem.guardUnit);
487 newMove->setGuardIndex(elem.guardIndex);
488
489 newMove->setGuarded(elem.isGuarded);
490 newMove->setGuardInverted(elem.isInverted);
491
492 addAnnotationes(*newMove, elem, labels);
493 codeSection->addElement(newMove);
494 } break;
495
496 default:
497 assert(false);
498 }
499 }
500
501 } catch (CompileError& e) {
502 labels.clearLastRelocations();
503 delete codeSection;
504 throw e;
505 }
506
507 labels.commitLastRelocations();
508 tpef.addSection(codeSection);
509 }
510
511 cleanup();
512}
513
514/**
515 * Frees all internally allocated data.
516 */
517void
523
524/**
525 * Inits privat attributes for start of new instruction.
526 */
527void
532
533/**
534 * Returns slot number for currently added move.
535 *
536 * @return Slot number for currently added move.
537 */
538UValue
543
544/**
545 * Returns next possible index for inline immediate.
546 *
547 * @return Next possible index for inline immediate.
548 */
549UValue
554
555/**
556 * Returns true if RF index or FU port is written twice in a same instruction.
557 *
558 * @param elem Move to check.
559 * @return True if RF index or FU port is written twice in a same instruction.
560 */
561bool
563 const InternalElement& elem) const {
564
565 if (elem.type == MOVE && !elem.isBegin) {
566
567 std::vector<const InternalElement*> guardedMoves;
568
569 for (int i = internalSection_.elements.size() - 1;
570 i >= 0 && !internalSection_.elements[i].isBegin; i--) {
571
572 const InternalElement &compare = internalSection_.elements[i];
573
574 if (compare.type == elem.type &&
575 compare.dstType == elem.dstType &&
576 compare.dstUnit == elem.dstUnit &&
577 compare.dstIndex == elem.dstIndex) {
578
579 if (!compare.isGuarded || !elem.isGuarded) {
580 // destination is same and only one of the moves
581 // is guarded
582 return true;
583
584 } else {
585
586 if (compare.guardType == elem.guardType &&
587 compare.guardUnit == elem.guardUnit &&
588 compare.guardIndex == elem.guardIndex &&
589 compare.isInverted == elem.isInverted) {
590
591 // same destination and same guards
592 return true;
593 }
594
595 // gather possibly colliding moves
596 guardedMoves.push_back(&compare);
597 }
598 }
599
600 }
601
602 // check if possibly colliding moves has two opposites of same guard
603 for (unsigned int i = 0; i < guardedMoves.size(); i++) {
604 for (unsigned int j = i + 1; j < guardedMoves.size(); j++) {
605
606 const InternalElement* iMove = guardedMoves[i];
607 const InternalElement* jMove = guardedMoves[j];
608
609 if (iMove->guardType == jMove->guardType &&
610 iMove->guardUnit == jMove->guardUnit &&
611 iMove->guardIndex == jMove->guardIndex &&
612 iMove->isInverted != jMove->isInverted) {
613
614 // destination that is currently written is
615 // definately already written in this instruction
616 return true;
617 }
618 }
619 }
620 }
621
622 return false;
623}
624
625
626/**
627 * Adds annotations of element of internal presentation to TPEF element.
628 *
629 * @param instrElem TPEF InstructionElement where to add annotation data.
630 * @param elem Element of internal presentation that caontains annotationes
631 * from assembly code.
632 * @exception CompileError If defined value needs more room that is defined
633 * in init data.
634 */
635void
637 InternalElement& elem, LabelManager& labels) const {
638
639 for (unsigned int i = 0; i < elem.annotationes.size();i++) {
640 Word id = elem.annotationes[i].id;
641 std::vector<Byte> payload;
642
643 for (unsigned int j = 0; j < elem.annotationes[i].payload.size(); j++) {
644 InitDataField& initData = elem.annotationes[i].payload[j];
645 std::deque<Byte> temp;
646
647 UValue value = 0;
648 if (initData.litOrExpr.isExpression) {
649 value = labels.resolveExpressionValue(elem.asmLineNumber,
650 initData.litOrExpr);
651 } else {
652 value = initData.litOrExpr.value;
653 }
654
655 // write value to field
656 for (int k = sizeof(value) - 1; k >= 0; k--) {
657 Byte nextVal = (value >> (k*BYTE_BITWIDTH));
658 temp.push_back(nextVal);
659 }
660
661 // remove extra leading ones if signed
662 if (initData.litOrExpr.isSigned) {
663 while (temp.size() > 1 && temp[0] == 0xff &&
664 temp.size() > initData.width &&
665 (temp[1] & 0x80) != 0) {
666
667 temp.pop_front();
668 }
669 }
670
671 // remove extra leading zeroes
672 while (temp[0] == 0 && temp.size() > initData.width) {
673 temp.pop_front();
674 }
675
676 // add needed leading zeroes or ones if signed
677 while (temp.size() < initData.width) {
678
679 if (initData.litOrExpr.isSigned && (temp[0] & 0x80) != 0) {
680 temp.push_front(0xff);
681 } else {
682 temp.push_front(0);
683 }
684
685 }
686
687 if (initData.width != 0 && temp.size() > initData.width) {
688 std::string errorMessage =
689 "Annotation payload " + initData.toString() +
690 " is too big for defined field size.";
691
692 throw CompileError(
693 __FILE__, __LINE__, __func__,
694 errorMessage);
695 }
696
697 // add to payload
698 for (unsigned int j = 0; j < temp.size(); j++) {
699 payload.push_back(temp[j]);
700 }
701 }
702
703 instrElem.addAnnotation(new InstructionAnnotation(id, payload));
704 }
705}
#define __func__
#define assert(condition)
const Byte BYTE_BITWIDTH
Definition BaseType.hh:136
unsigned char Byte
Definition BaseType.hh:116
unsigned long UValue
static std::ostream & logStream()
void addWarning(UValue lineNumber, const std::string &message)
AssemblyParserDiagnostic * parent_
Place to add warnings during compilation.
UValue immediateIndex_
Immediate index.
void addAnnotationes(TPEF::InstructionElement &instrElem, InternalElement &elem, LabelManager &lables) const
@ IMMEDIATE
Long immediate assignment.
@ MOVE
Data transport.
CodeSectionCreator(MachineResourceManager &resourceManager, const TTAMachine::Machine &targetMachine, AssemblyParserDiagnostic *parent)
UValue slotNumber_
Slot number of current move.
void newSection(UValue startAddress)
void addMove(const ParserMove &move)
bool isNextBegin_
Next element is starting element of instruction.
bool isDestinationAlreadyWritten(const InternalElement &elem) const
const TTAMachine::Machine & mach_
MachineResourceManager & resources_
TPEF Resources and strings.
static const UValue CODE_RELOC_SIZE
Bitwidth of immediate value containing address to relocate.
InternalSection internalSection_
Internal representation of code section.
void finalize(TPEF::Binary &tpef, LabelManager &labels)
void setCodeFileLineNumber(int lineNum)
static std::string toString(const T &source)
std::string errorMessage() const
Definition Exception.cc:123
void setCause(const Exception &cause)
Definition Exception.cc:75
std::string label
Name of the label.
std::string toString() const
LiteralOrExpression litOrExpr
Initialisation value.
UValue width
Number of MAUs that are initialized by the init field.
void clearLastRelocations()
UValue resolveExpressionValue(UValue asmLineNumber, LiteralOrExpression &litOrExpr)
std::string aSpaceName(std::string &labelName)
void commitLastRelocations()
TPEF::ASpaceElement & aSpaceElement(std::string &labelName)
void addRelocation(TPEF::Section &locationSect, TPEF::SectionElement &location, TPEF::ASpaceElement &dstASpace, UValue destination, UValue bitWidth)
bool isExpression
Does object contain expression or literal.
UValue value
If literal, the literal. Otherwise not used.
bool isSigned
Sign of the value.
Expression expression
If expression the expression, Otherwise not used.
ResourceID & resourceID(UValue currentLine, const RegisterTerm &term, UValue slotNumber, RequestType type)
UValue findBusWidth(UValue slotNumber)
@ RQST_INVGUARD
Inverted register or port guard.
@ RQST_READ
Register of port for reading.
@ RQST_WRITE
Register or port for writing.
@ RQST_GUARD
Register or port guard.
TPEF::Chunk * stringToChunk(const std::string aStr)
TPEF::ASpaceElement * codeAddressSpace()
TPEF::ResourceSection * resourceSection()
static int requiredBits(unsigned long int number)
RegisterTerm regTerm
Guard port or register.
bool isInverted
Is guard inverted.
bool isGuarded
Is guard used.
@ TRANSPORT
Data transport (move).
@ EMPTY
Empty move slot.
@ LONG_IMMEDIATE
Encoding of one long immediate slot.
std::vector< Annotation > annotationes
MoveType type
Type of move.
ParserSource source
Source field.
bool isBegin
Tells whether the slot is the first of the instruction.
UValue asmLineNumber
Line number of source code for errors.
ParserGuard guard
Guard field.
RegisterTerm destination
Destination field.
bool isRegister
Is source register or immediate reference.
LiteralOrExpression immTerm
If immediate value, the literal or expression. Otherwise not used.
RegisterTerm regTerm
If register, the register. Otherwise not used.
std::string toString() const
void addSection(Section *section)
virtual void addElement(SectionElement *element)
void setDestinationIndex(Byte aDestinationIndex)
void setDestinationUnit(Byte aDestinationUnit)
Byte destinationUnit() const
void setWord(Word aValue)
void setBegin(bool isBegin)
void addAnnotation(InstructionAnnotation *anAnnotation)
void setGuardIndex(HalfWord aGuardIndex)
void setSourceType(FieldType aType)
void setGuardInverted(bool flag)
void setSourceIndex(HalfWord aSourceIndex)
void setBus(HalfWord aBus)
void setDestinationUnit(HalfWord aDestinationUnit)
void setGuarded(bool flag)
void setSourceUnit(HalfWord aSourceUnit)
void setGuardUnit(HalfWord aGuardUnit)
void setDestinationIndex(HalfWord aDestinationIndex)
void setEmpty(bool flag)
void setDestinationType(FieldType aType)
void setGuardType(FieldType gType)
@ MF_IMM
Immediate.
@ INLINE_IMM
Inline immediate unit id.
static Section * createSection(SectionType type)
Definition Section.cc:91
@ ST_CODE
Text section.
Definition Section.hh:79
void setLink(const ReferenceManager::SafePointer *aLink)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
void setName(const ReferenceManager::SafePointer *sectionName)
virtual ULongWord end() const
ComponentType * item(int index) const
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
UValue guardUnit
TPEF Resource section unit id of guard register or port.
UValue srcUnit
TPEF Resource section unit id of register or port.
UValue srcIndex
TPEF Resource section operand id or register number.
TPEF::MoveElement::FieldType guardType
Guard type.
TPEF::MoveElement::FieldType srcType
Source type.
std::vector< Annotation > annotationes
Annotations for the element.
UValue asmLineNumber
Line number where in source code this move is located.
TPEF::MoveElement::FieldType dstType
Destination type.
LiteralOrExpression immValue
If source is immediate, the value.
UValue dstIndex
TPEF Resource section operand id or register number.
UValue dstUnit
TPEF Resource section unit id of register or port.
UValue guardIndex
TPEF Resource section operand id or register number.
bool isBegin
Is first move of an instruction.
std::vector< InternalElement > elements
Elements of the section.
UValue startAddress
Start address of the section.
UValue width
Width of accessed port or other resource.
TPEF::MoveElement::FieldType type
Resource type.
UValue index
TPEF Resource operand id or register file index.