OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Protected Types | Protected Member Functions | Private Attributes | List of all members
TPEFDisassembler Class Reference

#include <TPEFDisassembler.hh>

Collaboration diagram for TPEFDisassembler:
Collaboration graph

Public Member Functions

 TPEFDisassembler (const TPEF::Binary &aTpef)
 
virtual ~TPEFDisassembler ()
 
virtual DisassemblyInstructioncreateInstruction (Word instructionIndex) const
 
virtual Word startAddress () const
 
virtual Word instructionCount () const
 
void clearCache () const
 

Protected Types

typedef std::pair< Word, Word > ImmediateKey
 
typedef std::map< ImmediateKey, TPEF::ImmediateElement * > ImmediateMap
 

Protected Member Functions

void initCache () const
 
DisassemblyElementcreateDisassemblyElement (TPEF::MoveElement::FieldType type, Word unit, Word index, ImmediateMap &immediateMap) const
 

Private Attributes

const TPEF::Binarytpef_
 Binary where data for disassembler is retrieved.
 
std::vector< Word > instructionStartCache_
 Cache of starting elements of instructions.
 

Detailed Description

TPEF Disassembler.

Retrievs data from TPEF and builds Disassembler instructions out of TPEF hierarchy.

Contains internal cache to speedup instruction fetching, so if instruction ordering of TPEF is changed cache will not be valid anymore and must be cleared.

NOTE: Class disassembles only the first of code sections in binary.

Definition at line 58 of file TPEFDisassembler.hh.

Member Typedef Documentation

◆ ImmediateKey

typedef std::pair<Word,Word> TPEFDisassembler::ImmediateKey
protected

Definition at line 72 of file TPEFDisassembler.hh.

◆ ImmediateMap

Definition at line 73 of file TPEFDisassembler.hh.

Constructor & Destructor Documentation

◆ TPEFDisassembler()

TPEFDisassembler::TPEFDisassembler ( const TPEF::Binary aTpef)

Constructor.

Parameters
aTpefTPEF hierarchy whose code sections are disassembled.

Definition at line 70 of file TPEFDisassembler.cc.

70 :
71 tpef_(&aTpef) {
72}
const TPEF::Binary * tpef_
Binary where data for disassembler is retrieved.

◆ ~TPEFDisassembler()

TPEFDisassembler::~TPEFDisassembler ( )
virtual

Destructor.

Definition at line 77 of file TPEFDisassembler.cc.

77 {
78}

Member Function Documentation

◆ clearCache()

void TPEFDisassembler::clearCache ( ) const

Clears internal cache of instruction start indexes in TPEF code section.

If you modify order or begin flags of instruction elements in TPEF, chache should be cleared, because instruction start indexes might be changed.

Definition at line 296 of file TPEFDisassembler.cc.

296 {
298}
std::vector< Word > instructionStartCache_
Cache of starting elements of instructions.

References instructionStartCache_.

◆ createDisassemblyElement()

DisassemblyElement * TPEFDisassembler::createDisassemblyElement ( TPEF::MoveElement::FieldType  type,
Word  unit,
Word  index,
ImmediateMap immediateMap 
) const
protected

Creates DisassemblyElement out of given paramters.

Finds needed strings and stuff from TPEF hierarchy.

Parameters
typeType of elemet to create.
unitUnit id of referred resource.
indexIndex part of referred resource.
immediateMapAll immediate values found in instruction.
Returns
Dynamically allocated fully contructed DisassemblerElement.

Definition at line 334 of file TPEFDisassembler.cc.

336 {
337
338 ResourceSection *resources =
339 dynamic_cast<ResourceSection*>(tpef_->section(Section::ST_MR,0));
340
341 assert(resources != NULL);
342
343 StringSection *strings =
344 dynamic_cast<StringSection*>(resources->link());
345
346 switch (type) {
347
348 case MoveElement::MF_RF: {
350 switch (unit) {
352 return new DisassemblyIntRegister(index);
354 // only one boolean register for now
355 assert(index == 0);
356 return new DisassemblyBoolRegister();
358 return new DisassemblyFPRegister(index);
359 default:
360 // Error: not universal unit
361 assert(false);
362 }
363 } else {
364 // real resources from real machines
365 ResourceElement &rfUnit =
366 resources->findResource(ResourceElement::MRT_RF,unit);
367
368 std::string rfName = strings->chunk2String(rfUnit.name());
369
370 return new DisassemblyRegister(rfName, index);
371 }
372
373 } break;
374
375 case MoveElement::MF_IMM: {
376 ImmediateKey immKey(unit, index);
377
378 if (MapTools::containsKey(immediateMap, immKey)) {
379
380 ImmediateElement *imm =
381 MapTools::valueForKey<ImmediateElement*>(immediateMap, immKey);
382
383 assert(imm->isInline());
384
385 SimValue immValue(64);
386 immValue = imm->sLongWord();
387 return new DisassemblyImmediate(immValue, false);
388
389 } else {
390 // register reference to immediate register.
391
392 // get that immediate unit
393 ResourceElement &immUnit =
394 resources->findResource(ResourceElement::MRT_IMM, unit);
395
396 std::string immUnitName = strings->chunk2String(immUnit.name());
397
398 return new DisassemblyImmediateRegister(immUnitName, index);
399 }
400
401 } break;
402
404
405 if (unit == ResourceElement::UNIVERSAL_FU) {
406
407 // TODO refactor
408
409 if (resources->hasResource(
410 ResourceElement::MRT_OP, index)) {
411
412 ResourceElement resource =
413 resources->findResource(
415
416 std::string opString =
417 strings->chunk2String(resource.name());
418
419 std::string::size_type dotIndex = opString.rfind('.');
420 std::string opName = opString.substr(0,dotIndex);
421
422 // move dotIndex to start of regnumber part of operation
423 dotIndex++;
424
425 std::string opIndexStr = opString.substr(
426 dotIndex, opString.length() - dotIndex);
427
428 Word opIndex = Conversion::toInt(opIndexStr);
429
430 return new DisassemblyOperand(opName, opIndex);
431
432 } else if (resources->hasResource(
433 ResourceElement::MRT_SR, index)) {
434
435 ResourceElement &resource =
436 resources->findResource(
438
439 std::string regName = strings->chunk2String(resource.name());
440
443
444 } else {
445 abortWithError("Unknown special register");
446 }
447
448 } else {
450 "Can't find universal operand or special register "
451 "resource by index:" + Conversion::toString(index));
452 }
453
454 } else {
455 // terminal types fuName.portName or fuName.opName.index
456 // not universal FU, which has no fuName field
457
458 // get FU name
459 ResourceElement &fuResource =
460 resources->findResource(ResourceElement::MRT_UNIT, unit);
461
462 std::string fuName = strings->chunk2String(fuResource.name());
463
464 // TODO refactor
465 if (resources->hasResource(
467
468 ResourceElement &fuPort =
469 resources->findResource(ResourceElement::MRT_PORT, index);
470
471 std::string fuPortName =
472 strings->chunk2String(fuPort.name());
473
474 return new DisassemblyFUPort(fuName, fuPortName);
475
476 } else if (resources->hasResource(
477 ResourceElement::MRT_OP, index)) {
478
479 ResourceElement &fuOperationOperand =
480 resources->findResource(ResourceElement::MRT_OP, index);
481
482 std::string operandString =
483 strings->chunk2String(fuOperationOperand.name());
484
485 std::string::size_type dotPos = operandString.rfind(".");
486
487 assert(dotPos != std::string::npos);
488
489 std::string opName = operandString.substr(0, dotPos);
490
491 std::string operandIndexString =
492 operandString.substr(
493 dotPos+1, operandString.length() - dotPos - 1);
494
495 Word operandIndex =
496 Conversion::toUnsignedInt(operandIndexString);
497
498 return new DisassemblyFUOperand(fuName, opName, operandIndex);
499
500 } else if (resources->hasResource(
501 ResourceElement::MRT_SR, index)) {
502
503 ResourceElement &fuSpecialRegister =
504 resources->findResource(ResourceElement::MRT_SR, index);
505
506 std::string srName =
507 strings->chunk2String(fuSpecialRegister.name());
508
509 return new DisassemblyFUPort(fuName, srName);
510
511 } else {
513 "Can't find real port, operation or special register by "
514 "index: " + Conversion::toString(index));
515 }
516 }
517
518 } break;
519
520 default:
521 abortWithError("Unknown type: " + Conversion::toString((int)type));
522 }
523
524 assert(false);
525 return NULL;
526}
#define abortWithError(message)
#define assert(condition)
static std::string toString(const T &source)
static int toInt(const T &source)
static unsigned int toUnsignedInt(const T &source)
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
std::pair< Word, Word > ImmediateKey
Section * section(Word index) const
SignedLongWord sLongWord() const
@ MF_RF
Register file.
@ MF_IMM
Immediate.
@ MF_UNIT
Function unit.
static const std::string RETURN_ADDRESS_NAME
Reserved string of return address special register.
@ MRT_IMM
Immediate unit.
@ MRT_SR
Special register.
@ MRT_UNIT
Function unit.
@ MRT_PORT
Function unit port.
@ MRT_OP
Operation operand or function unit register.
@ UNIVERSAL_FU
Universal function unit.
@ INT_RF
Universal integer register file.
@ UNIVERSAL_RF_MASK
Bit to check if registerfile is real or universal.
@ BOOL_RF
Universal boolean register file.
@ FP_RF
Universal floating point register file.
Chunk * name() const
ResourceElement & findResource(ResourceElement::ResourceType aType, HalfWord anId) const
bool hasResource(ResourceElement::ResourceType aType, HalfWord anId) const
Section * link() const
@ ST_MR
Machine resources section.
Definition Section.hh:78
std::string chunk2String(const Chunk *chunk) const

References abortWithError, assert, TPEF::ResourceElement::BOOL_RF, TPEF::StringSection::chunk2String(), MapTools::containsKey(), TPEF::ResourceSection::findResource(), TPEF::ResourceElement::FP_RF, TPEF::ResourceSection::hasResource(), TPEF::ResourceElement::INT_RF, TPEF::ImmediateElement::isInline(), MapTools::keyForValue(), TPEF::Section::link(), TPEF::MoveElement::MF_IMM, TPEF::MoveElement::MF_RF, TPEF::MoveElement::MF_UNIT, TPEF::ResourceElement::MRT_IMM, TPEF::ResourceElement::MRT_OP, TPEF::ResourceElement::MRT_PORT, TPEF::ResourceElement::MRT_RF, TPEF::ResourceElement::MRT_SR, TPEF::ResourceElement::MRT_UNIT, TPEF::ResourceElement::name(), TPEF::ResourceElement::RETURN_ADDRESS_NAME, TPEF::Binary::section(), TPEF::ImmediateElement::sLongWord(), TPEF::Section::ST_MR, Conversion::toInt(), Conversion::toString(), Conversion::toUnsignedInt(), tpef_, TPEF::ResourceElement::UNIVERSAL_FU, and TPEF::ResourceElement::UNIVERSAL_RF_MASK.

Referenced by createInstruction().

Here is the call graph for this function:

◆ createInstruction()

DisassemblyInstruction * TPEFDisassembler::createInstruction ( Word  instructionIndex) const
virtual

Creates dynamically allocated disassembler instruction.

Parameters
instructionIndexNumber of instruction to return.
Returns
Dynamically allocated disassembler instruction.

Definition at line 87 of file TPEFDisassembler.cc.

87 {
88
89 CodeSection *theCodeSection =
90 dynamic_cast<CodeSection*>(tpef_->section(Section::ST_CODE,0));
91
92 assert(theCodeSection != NULL);
93
94 if (instructionStartCache_.empty()) {
95 initCache();
96 }
97
98 Word currIndex = instructionStartCache_[instructionIndex];
99
100 InstructionElement *currElement =
101 dynamic_cast<InstructionElement*>(
102 theCodeSection->element(currIndex));
103
104 DisassemblyInstruction *newInstruction = new DisassemblyInstruction();
105
106 // scan all elements in first pass, because we want to have also
107 // immediates when we build instructions
108 ImmediateMap immediates;
109 std::vector<MoveElement*> moves;
110
111 do {
112 if (currElement->isMove()) {
113 MoveElement *move = dynamic_cast<MoveElement*>(currElement);
114 assert (move != NULL);
115 moves.push_back(move);
116
117 } else if (currElement->isImmediate()) {
118 ImmediateElement *imm =
119 dynamic_cast<ImmediateElement*>(currElement);
120
121 assert (imm != NULL);
122
123 if (imm->isInline()) {
125 immKey(imm->destinationUnit(), imm->destinationIndex());
126
127 immediates[immKey] = imm;
128
129 } else {
130 // this is long immediate
131 DisassemblyElement* dest =
133 imm->destinationUnit(),
134 imm->destinationIndex(),
135 immediates);
136
137 SimValue immValue(64);
138 immValue = imm->longWord();
139
140 // do not know if unit is signed or not without adf
142 new DisassemblyImmediateAssignment(immValue, false, dest);
143
144 // add annotationes for the move
145 for (Word j = 0; j < imm->annotationCount(); j++) {
146 InstructionAnnotation& ann = *(imm->annotation(j));
147 immAssign->addAnnotation(
148 new DisassemblyAnnotation(ann.id(), ann.payload()));
149 }
150
151 newInstruction->addLongImmediate(immAssign);
152 }
153
154 } else {
155 assert(false);
156 }
157
158 currIndex++;
159
160 // if we reached end of section
161 if (currIndex == theCodeSection->elementCount()) {
162 break;
163 }
164
165 currElement = dynamic_cast<InstructionElement*>(
166 theCodeSection->element(currIndex));
167
168 } while (!currElement->begin());
169
170 // find out how many busses tpef have.
171 ResourceSection* resources = dynamic_cast<ResourceSection*>(
173
174 assert(resources != NULL);
175
176 std::vector<DisassemblyInstructionSlot*> organizedInstr;
177
178 for (Word i = 0; i < resources->elementCount(); i++) {
179 ResourceElement* resource =
180 dynamic_cast<ResourceElement*>(resources->element(i));
181
182 if (resource->type() == ResourceElement::MRT_BUS &&
183 resource->id() != ResourceElement::UNIVERSAL_BUS) {
184
185 organizedInstr.push_back(NULL);
186 }
187 }
188
189 for (unsigned int i = 0; i < moves.size(); i++) {
190 MoveElement *currMove = moves[i];
191
192 if (!currMove->isEmpty()) {
193 DisassemblyElement *source =
195 currMove->sourceUnit(),
196 currMove->sourceIndex(),
197 immediates);
198
199 DisassemblyElement *destination =
201 currMove->destinationUnit(),
202 currMove->destinationIndex(),
203 immediates);
204
205 DisassemblyGuard *guard = NULL;
206
207 if (currMove->isGuarded()) {
208 DisassemblyElement *guardElement =
210 currMove->guardUnit(),
211 currMove->guardIndex(),
212 immediates);
213
214 guard = new DisassemblyGuard(
215 guardElement, currMove->isGuardInverted());
216 }
217
218 DisassemblyMove *newMove =
219 new DisassemblyMove(source, destination, guard);
220
221 // add annotationes for the move
222 for (Word j = 0; j < currMove->annotationCount(); j++) {
223 InstructionAnnotation& ann = *(currMove->annotation(j));
224 newMove->addAnnotation(
225 new DisassemblyAnnotation(ann.id(), ann.payload()));
226 }
227
228 // add unassigned moves to end of instruction
229 if (currMove->bus() > 0) {
230 organizedInstr[currMove->bus() - 1] = newMove;
231 } else {
232 organizedInstr.push_back(newMove);
233 }
234 } else {
235 // empty move element. NOP?
236 // add annotationes for the move
237 for (Word j = 0; j < currMove->annotationCount(); j++) {
238 InstructionAnnotation& ann = *(currMove->annotation(j));
239 newInstruction->addAnnotation(
240 new DisassemblyAnnotation(ann.id(), ann.payload()));
241 }
242 }
243 }
244
245 // create all moves and add them to disassembler instruction
246 for (Word i = 0; i < organizedInstr.size(); i++) {
247
248 if (organizedInstr[i] != NULL) {
249 newInstruction->addMove(organizedInstr[i]);
250
251 } else {
252 DisassemblyNOP *newNOP = new DisassemblyNOP();
253 newInstruction->addMove(newNOP);
254 }
255 }
256
257 return newInstruction;
258}
void addAnnotation(DisassemblyAnnotation *annotation)
void addAnnotation(DisassemblyAnnotation *annotation)
void addLongImmediate(DisassemblyImmediateAssignment *longImm)
void addMove(DisassemblyInstructionSlot *move)
DisassemblyElement * createDisassemblyElement(TPEF::MoveElement::FieldType type, Word unit, Word index, ImmediateMap &immediateMap) const
std::map< ImmediateKey, TPEF::ImmediateElement * > ImmediateMap
virtual InstructionElement * element(Word index) const
LongWord longWord() const
Byte destinationIndex() const
Byte destinationUnit() const
const std::vector< Byte > & payload() const
Word annotationCount() const
InstructionAnnotation * annotation(Word index) const
bool isGuarded() const
FieldType destinationType() const
HalfWord destinationIndex() const
HalfWord destinationUnit() const
bool isEmpty() const
HalfWord bus() const
HalfWord guardUnit() const
HalfWord sourceUnit() const
FieldType guardType() const
HalfWord guardIndex() const
bool isGuardInverted() const
HalfWord sourceIndex() const
FieldType sourceType() const
ResourceType type() const
HalfWord id() const
@ MRT_BUS
Transport bus.
@ UNIVERSAL_BUS
Universal bus.
@ ST_CODE
Text section.
Definition Section.hh:79
SectionElement * element(Word index) const
Word elementCount() const

References DisassemblyInstruction::addAnnotation(), DisassemblyInstructionSlot::addAnnotation(), DisassemblyInstruction::addLongImmediate(), DisassemblyInstruction::addMove(), TPEF::InstructionElement::annotation(), TPEF::InstructionElement::annotationCount(), assert, TPEF::InstructionElement::begin(), TPEF::MoveElement::bus(), createDisassemblyElement(), TPEF::ImmediateElement::destinationIndex(), TPEF::MoveElement::destinationIndex(), TPEF::MoveElement::destinationType(), TPEF::ImmediateElement::destinationUnit(), TPEF::MoveElement::destinationUnit(), TPEF::CodeSection::element(), TPEF::Section::element(), TPEF::Section::elementCount(), TPEF::MoveElement::guardIndex(), TPEF::MoveElement::guardType(), TPEF::MoveElement::guardUnit(), TPEF::InstructionAnnotation::id(), TPEF::ResourceElement::id(), initCache(), instructionStartCache_, TPEF::MoveElement::isEmpty(), TPEF::MoveElement::isGuarded(), TPEF::MoveElement::isGuardInverted(), TPEF::InstructionElement::isImmediate(), TPEF::ImmediateElement::isInline(), TPEF::InstructionElement::isMove(), TPEF::ImmediateElement::longWord(), TPEF::MoveElement::MF_IMM, TPEF::ResourceElement::MRT_BUS, TPEF::InstructionAnnotation::payload(), TPEF::Binary::section(), TPEF::MoveElement::sourceIndex(), TPEF::MoveElement::sourceType(), TPEF::MoveElement::sourceUnit(), TPEF::Section::ST_CODE, TPEF::Section::ST_MR, tpef_, TPEF::ResourceElement::type(), and TPEF::ResourceElement::UNIVERSAL_BUS.

Referenced by TPEFDumper::section().

Here is the call graph for this function:

◆ initCache()

void TPEFDisassembler::initCache ( ) const
protected

Initilises instruction start indexes in code section to vector.

After cache init we have vector of all instruction start indexes of the section.

Definition at line 307 of file TPEFDisassembler.cc.

307 {
308 CodeSection *theCodeSection =
309 dynamic_cast<CodeSection*>(tpef_->section(Section::ST_CODE,0));
310
311 assert(theCodeSection != NULL);
312
313 for (Word i = 0; i < theCodeSection->elementCount(); i++) {
314 if (dynamic_cast<InstructionElement*>(
315 theCodeSection->element(i))->begin()) {
316 // if i is begin of instruction push it to instruction start vector
317 instructionStartCache_.push_back(i);
318 }
319 }
320}

References assert, TPEF::InstructionElement::begin(), TPEF::CodeSection::element(), TPEF::Section::elementCount(), instructionStartCache_, TPEF::Binary::section(), TPEF::Section::ST_CODE, and tpef_.

Referenced by createInstruction(), and instructionCount().

Here is the call graph for this function:

◆ instructionCount()

Word TPEFDisassembler::instructionCount ( ) const
virtual

Number of instructions available in first code section of TPEF.

Returns
Number of instruction available.

Definition at line 280 of file TPEFDisassembler.cc.

280 {
281 if (instructionStartCache_.empty()) {
282 initCache();
283 }
284 return instructionStartCache_.size();
285}

References initCache(), and instructionStartCache_.

Referenced by TPEFDumper::section().

Here is the call graph for this function:

◆ startAddress()

Word TPEFDisassembler::startAddress ( ) const
virtual

Address of first instruction.

Returns
Address of first instruction.

Definition at line 266 of file TPEFDisassembler.cc.

266 {
267 CodeSection *theCodeSection =
268 dynamic_cast<CodeSection*>(tpef_->section(Section::ST_CODE,0));
269
270 assert(theCodeSection != NULL);
271 return theCodeSection->startingAddress();
272}
AddressImage startingAddress() const

References assert, TPEF::Binary::section(), TPEF::Section::ST_CODE, TPEF::Section::startingAddress(), and tpef_.

Referenced by TPEFDumper::section().

Here is the call graph for this function:

Member Data Documentation

◆ instructionStartCache_

std::vector<Word> TPEFDisassembler::instructionStartCache_
mutableprivate

Cache of starting elements of instructions.

Definition at line 86 of file TPEFDisassembler.hh.

Referenced by clearCache(), createInstruction(), initCache(), and instructionCount().

◆ tpef_

const TPEF::Binary* TPEFDisassembler::tpef_
private

Binary where data for disassembler is retrieved.

Definition at line 83 of file TPEFDisassembler.hh.

Referenced by createDisassemblyElement(), createInstruction(), initCache(), and startAddress().


The documentation for this class was generated from the following files: