OpenASIP  2.0
TPEFProgramFactory.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2014 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 TPEFProgramFactory.cc
26  *
27  * Implementation of TPEFProgramFactory class.
28  *
29  * @author Mikael Lepistö 2005 (tmlepist-no.spam-cs.tut.fi)
30  * @author Pekka Jääskeläinen 2011,2014
31  * @note rating: yellow
32  */
33 
34 #include <list>
35 #include <map>
36 #include <vector>
37 #include <boost/format.hpp>
38 
39 #include "TPEFProgramFactory.hh"
40 #include "ContainerTools.hh"
41 #include "ASpaceElement.hh"
42 #include "Section.hh"
43 #include "SymbolSection.hh"
44 #include "CodeSymElement.hh"
45 #include "CodeSection.hh"
46 #include "DataSymElement.hh"
47 #include "ImmediateElement.hh"
48 #include "Instruction.hh"
49 #include "Procedure.hh"
50 #include "MoveGuard.hh"
51 #include "Move.hh"
52 #include "UnboundedRegisterFile.hh"
53 #include "UniversalFunctionUnit.hh"
54 #include "TerminalRegister.hh"
55 #include "TerminalFUPort.hh"
56 #include "TerminalImmediate.hh"
57 #include "OperationPool.hh"
58 #include "FUPort.hh"
59 #include "Guard.hh"
60 #include "HWOperation.hh"
61 #include "ControlUnit.hh"
62 #include "SpecialRegisterPort.hh"
63 #include "Application.hh"
64 #include "CodeLabel.hh"
65 #include "DataLabel.hh"
66 #include "RelocElement.hh"
67 #include "AddressSpace.hh"
70 #include "TerminalAddress.hh"
71 #include "InstructionReference.hh"
72 #include "RelocSection.hh"
73 #include "ProcedSymElement.hh"
74 #include "Immediate.hh"
76 #include "DataMemory.hh"
77 #include "DataDefinition.hh"
78 #include "DataAddressDef.hh"
80 #include "ProgramAnnotation.hh"
81 #include "BinaryStream.hh"
82 #include "BinaryReader.hh"
83 #include "MathTools.hh"
84 #include "GlobalScope.hh"
85 #include "UniversalMachine.hh"
86 #include "Program.hh"
87 
88 using namespace TTAMachine;
89 using namespace TPEF;
90 using std::string;
91 
92 namespace TTAProgram {
93 
94 /**
95  * Little helper class for storing information of function start points.
96  */
98 public:
99  FunctionStart(std::string aName) :
100  name_(aName) { }
101 
102  std::string name() const {return name_;}
103 
104 private:
105  std::string name_;
106 };
107 
108 /**
109  * Constructor.
110  *
111  * For mixed code which contains universal machine references and
112  * target machine references.
113  *
114  * @param aBinary Binary that contains a program's instructions and data.
115  * @param aMachine Actual machine to which parallel code refers.
116  * @param aUniversalMachine Universal machine for sequential code.
117  * @param relocs Managed collection of relocation points in the program.
118  */
119 TPEFProgramFactory::TPEFProgramFactory(
120  const Binary& aBinary,
121  const Machine& aMachine,
123  binary_(&aBinary), machine_(&aMachine),
124  universalMachine_(&UniversalMachine::instance()),
125  tpefTools_(aBinary),
126  adfInstrASpace_(NULL),
127  tpefInstrASpace_(NULL) {
128 }
129 
130 /**
131  * Constructor for fully scheduled code.
132  *
133  * @param aBinary Binary that contains a program's instructions and data.
134  * @param aMachine Machine to which code refers.
135  * @param relocs Managed collection of relocation points in the program.
136  */
138  const Binary& aBinary, const Machine& aMachine):
139  binary_(&aBinary), machine_(&aMachine),
140  universalMachine_(&UniversalMachine::instance()),
141  tpefTools_(aBinary),
142  adfInstrASpace_(NULL),
143  tpefInstrASpace_(NULL) {
144 }
145 
146 /**
147  * Constructor for fully unscheduled code.
148  *
149  * @param aBinary Binary that contains a program's instructions and data.
150  * @param uMachine Universal Machine to which code refers.
151  * @param relocs Managed collection of relocation points in the program.
152  */
154  const Binary &aBinary, UniversalMachine*):
155  binary_(&aBinary), machine_(NULL),
156  universalMachine_(&UniversalMachine::instance()),
157  tpefTools_(aBinary),
158  adfInstrASpace_(NULL),
159  tpefInstrASpace_(NULL) {
160 }
161 
162 
163 /**
164  * Destructor.
165  */
168 }
169 
170 /**
171  * Returns value of chunk as string.
172  *
173  * Helps getting names for various TPEF resources.
174  *
175  * @param chunk Chunk referring to section.
176  * @param chunkOwner StringSection that contains requested string.
177  * @return String referred by chunk.
178  */
179 std::string
181  const Chunk* chunk,
182  const Section* chunkOwner) const {
183 
184  const StringSection* strSect =
185  dynamic_cast<const StringSection*>(chunkOwner);
186  assert(strSect != NULL);
187  return strSect->chunk2String(chunk);
188 }
189 
190 /**
191  * Builds program model out of TPEF model.
192  *
193  * @return Created program.
194  * @exception NotAvailable if there the binary contains no sections; if the
195  * instruction address space is missing or conflicting with architecture
196  * definition.
197  * @exception Exception if the TPEF or program in it is somehow broken.
198  */
199 Program*
201  assert(machine_ != NULL || universalMachine_ != NULL);
202 
203  if (binary_->sectionCount(Section::ST_CODE) == 0) {
204  throw NotAvailable(
205  __FILE__, __LINE__, __func__,
206  "No code sections in TPEF.");
207  }
208 
209  tpefInstrASpace_ = binary_->section(Section::ST_CODE, 0)->aSpace();
210 
211  // get address space for program from machine depending on
212  // type of code (sequential, partially scheduled, fully scheduled)
213  adfInstrASpace_ = NULL;
214 
215  if (machine_ == NULL) {
217 
218  } else {
219 
220  if (binary_->type() == Binary::FT_OBJSEQ ||
221  binary_->type() == Binary::FT_PURESEQ ||
222  binary_->type() == Binary::FT_LIBSEQ) {
223  throw NotAvailable(
224  __FILE__, __LINE__, __func__,
225  "Tried to load a sequential program with ADF already "
226  "loaded.");
227  }
228 
229  // check if real machine has address space by defined name.
230  // if not found then use universal address space.
233 
234  std::string aSpaceName = stringOfChunk(
236  binary_->section(Section::ST_ADDRSP, 0)->link());
237 
238  if (aSpaceNav.hasItem(aSpaceName )) {
239  adfInstrASpace_ = aSpaceNav.item(aSpaceName);
240 
241  } else {
242  if (universalMachine_ == NULL) {
243  throw NotAvailable(
244  __FILE__, __LINE__, __func__,
245  "No instruction(gcu) address space in ADF.");
246  }
247 
249  }
250  }
251 
252  if (machine_ == NULL &&
253  binary_->type() == Binary::FT_PARALLEL) {
254  throw NotAvailable(
255  __FILE__, __LINE__, __func__,
256  "Tried to load a parallel TPEF without ADF.");
257  }
258 
259  assert(adfInstrASpace_ != NULL);
260 
261  // ignored for backwards compatibility
262  // if (tpefInstrASpace_->MAU() != 0) {
263  // throw NotAvailable(
264  // __FILE__, __LINE__, __func__,
265  // (boost::format(
266  // "TPEF instruction address space MAU size should be (%d).") %
267  // static_cast<int>(tpefInstrASpace_->MAU())).str());
268  // }
269 
270 
271  clearCache();
272 
274 
275  Program* newProgram = new Program(*adfInstrASpace_);
277 
278  // create all the code
279  addProcedures(*newProgram, *adfInstrASpace_);
280 
282  newProgram->instructionVector();
283  const InstructionAddress startAddress =
284  newProgram->startAddress().location();
285 
286  // fix TerminalAddresses pointing to instructions to be
287  // TerminalInstructionAddresses.
288  while (!instructionImmediates_.empty()) {
289  auto move = *instructionImmediates_.begin();
291 
292  Terminal &addressTerm = move->source();
293 
294  assert(&(addressTerm.address().space()) == adfInstrASpace_);
295 
296  Instruction& referencedInstruction =
297  *allInstructions.at(addressTerm.address().location() - startAddress);
298 
299  InstructionReference instructionReference =
301  referencedInstruction);
302 
303  TerminalInstructionReference* instrTerm =
304  new TerminalInstructionReference(instructionReference);
305 
306  move->setSource(instrTerm);
307  }
308 
309  // and same for long immediates which refers to instruction addresses
310  while (!longInstructionImmediates_.empty()) {
311  auto immediate = *longInstructionImmediates_.begin();
313 
314  TerminalImmediate &addressTerm = immediate->value();
315 
316  assert(&(addressTerm.address().space()) == adfInstrASpace_);
317 
318  Instruction& referencedInstruction =
319  *allInstructions.at(addressTerm.address().location() - startAddress);
320 
321  InstructionReference instructionReference =
323  referencedInstruction);
324 
325  TerminalInstructionReference* instrTerm =
326  new TerminalInstructionReference(instructionReference);
327 
328  immediate->setValue(instrTerm);
329  }
330 
331  createDataMemories(*newProgram);
332  createLabels(*newProgram);
333 
334  return newProgram;
335 }
336 
337 /**
338  * Parses procedures from all TPEF CodeSections and adds them to Program.
339  *
340  * @param program Program where to add new procedures.
341  * @param programASpace Address space of instruction memory.
342  */
343  void
345  Program& program,
346  const AddressSpace& programASpace) const {
347 
348  // find code sections to chop and organize them by start address
349  std::list<CodeSection*> sectionsToChop;
350 
351  for (Word i = 0; i < binary_->sectionCount(Section::ST_CODE); i++) {
352 
353  CodeSection* sectionToAdd =
354  dynamic_cast<CodeSection*>(
355  binary_->section(Section::ST_CODE, i));
356 
357  if (sectionsToChop.empty()) {
358  sectionsToChop.push_back(sectionToAdd);
359  continue;
360  }
361 
362  std::list<CodeSection*>::iterator iter = sectionsToChop.begin();
363 
364  while (iter != sectionsToChop.end()) {
365 
366  if ((*iter)->startingAddress() >
367  sectionToAdd->startingAddress()) {
368  sectionsToChop.insert(iter, sectionToAdd);
369  break;
370  }
371 
372  iter++;
373  }
374  }
375 
376  // NOTE: maybe it should be checked if found code sections are legal.
377  // (adressSpaces and addresses does not collide)
378 
379  // add instruction elements of every found section
380  std::list<CodeSection*>::iterator sectionIterator =
381  sectionsToChop.begin();
382 
383  while (sectionIterator != sectionsToChop.end()) {
384  CodeSection* section = *sectionIterator;
385 
386  ResourceSection* resources =
387  dynamic_cast<ResourceSection*>(section->link());
388  assert(resources != NULL);
389 
390  Word i = 0;
391  int currentInstructionNumber = 0;
392  while (i < section->elementCount()) {
393 
394  try {
395  // Create and add a new procedure to program with name if
396  // new procedure is started by current instruction or if
397  // there is no procedures in program.
398 
399  SectionElement* element = section->element(i);
400  InstructionElement* instructionElement =
401  dynamic_cast<InstructionElement*>(element);
402  assert(instructionElement != NULL);
403 
404  if (isFunctionStart(*instructionElement) ||
405  program.procedureCount() == 0) {
406 
407  assert(instructionElement->begin());
408 
409  // TODO: set the real start address.. ?
410 
411  Procedure* newProcedure = new Procedure(
412  functionName(*instructionElement),
413  programASpace, 0);
414 
415  program.addProcedure(newProcedure);
416  }
417 
418  // scan instruction elements of next instruction
419 
420  // moves of instruction
421  MoveVector moveElements;
422  // slots that encode immediate bits of instruction
423  ImmediateVector longImmediates;
424  // inline immediates of instruction
425  ImmediateMap immElements;
426 
427  InstructionElement* beginElement = NULL;
428 
429  do {
430  if (instructionElement->begin()) {
431  beginElement = instructionElement;
432  }
433 
434  if (instructionElement->isMove()) {
435  moveElements.push_back(
436  dynamic_cast<MoveElement*>(instructionElement));
437 
438  } else if (instructionElement->isImmediate()) {
439  ImmediateElement* imm =
440  dynamic_cast<ImmediateElement*>(
441  instructionElement);
442 
443  if (imm->isInline()) {
444  std::pair<Word,Word>
445  immKey(imm->destinationUnit(),
446  imm->destinationIndex());
447  immElements[immKey] = imm;
448  } else {
449  longImmediates.push_back(imm);
450  }
451  } else {
452  abortWithError("Unknown instruction element type.");
453  }
454 
455  i++;
456  if (i >= section->elementCount()) {
457  break;
458  }
459 
460  SectionElement* sectionElement = section->element(i);
461  assert(sectionElement != NULL);
462 
463  instructionElement =
464  dynamic_cast<InstructionElement*>(sectionElement);
465 
466  assert(i < section->elementCount());
467 
468  } while (instructionElement->begin() == false);
469 
470  Instruction* currentInstruction =
471  createInstruction(*resources, moveElements,
472  longImmediates, immElements);
473 
474  // add created instruction to map for finding program
475  // instruction by tpef instruction element
476  assert(beginElement != NULL);
477 
478  instructionMap_[beginElement] = currentInstruction;
479 
480  assert(currentInstruction != NULL);
481 
482  program.addInstruction(currentInstruction);
483  currentInstructionNumber++;
484 
485  } catch (const Exception& e) {
486  // add instruction number to start of exception message
487  NotAvailable error(
488  __FILE__, __LINE__, __func__,
489  (boost::format(
490  "Instruction %d: ") % currentInstructionNumber).
491  str() + e.errorMessage());
492  error.setCause(e);
493 
494  throw error;
495  }
496  }
497 
498  sectionIterator++;
499  }
500  }
501 
502 /**
503  * Creates an instruction out of given moves and immediate elements.
504  *
505  * @param resources TPEF resource section.
506  * @param moveElements Move elements of instruction.
507  * @param longImemdiates Long immediates of instruction.
508  * @param immElements Immediate elements of instruction.
509  * @return A new instruction.
510  */
513  const TPEF::ResourceSection& resources,
514  MoveVector& moveElements,
515  ImmediateVector& longImmediates,
516  ImmediateMap& immElements) const {
517 
518  std::vector<SocketAllocation> allocatedSockets;
519 
520  Instruction* newInstruction =
521  new Instruction(NullInstructionTemplate::instance());
522 
523  for (unsigned int i = 0; i < moveElements.size(); i++) {
524  MoveElement* move = moveElements[i];
525 
526  // NOTE: we just ignore empty moves
527  if (!move->isEmpty()) {
528  std::shared_ptr<TTAProgram::Move> newMove;
529  Terminal* source = NULL;
530  Terminal* destination = NULL;
531  Terminal* guardRegister = NULL;
532  MoveGuard* guard = NULL;
533 
534  // get bus
535  Bus& bus = findBus(resources, move->bus());
536 
537  try {
538  // create source terminal
539  source = createTerminal(
540  resources, &bus, Socket::OUTPUT, move->sourceType(),
541  move->sourceUnit(), move->sourceIndex(), &immElements);
542 
543  // and destination terminal
544  destination = createTerminal(
545  resources, &bus, Socket::INPUT, move->destinationType(),
546  move->destinationUnit(), move->destinationIndex());
547 
548  // create guard if move is guarded
549  if (move->isGuarded()) {
550 
551  Guard &adfGuard = findGuard(
552  resources,
553  bus,
554  move->guardType(),
555  move->guardUnit(),
556  move->guardIndex(),
557  move->isGuardInverted());
558 
559  guard = new MoveGuard(adfGuard);
560 
561  assert(guard != NULL);
562  }
563 
564  } catch (const NotAvailable& e) {
565 
566  if (guard != NULL) {
567  delete guard;
568  guard = NULL;
569 
570  } else {
571  if (guardRegister != NULL) {
572  delete guardRegister;
573  guardRegister = NULL;
574  }
575  }
576 
577  if (source != NULL) {
578  delete source;
579  source = NULL;
580  }
581 
582  if (destination != NULL) {
583  delete destination;
584  destination = NULL;
585  }
586 
587  delete newInstruction;
588  newInstruction = NULL;
589 
590  throw e;
591  } catch (Exception& e) {
592  throw e;
593  }
594 
595  if (guard != NULL) {
596  newMove = std::make_shared<TTAProgram::Move>(source, destination, bus, guard);
597  } else {
598  newMove = std::make_shared<TTAProgram::Move>(source, destination, bus);
599  }
600  assert(newMove != NULL);
601 
602  // Add possible sockets for register references.
603  Machine::SocketNavigator socketNav =
604  bus.machine()->socketNavigator();
605 
606  SocketAllocation newAlloc(newMove, allocatedSockets.size());
607 
608  // find possible sockets for move source and destination
609  for (int i = 0; i < socketNav.count(); i++) {
610  Socket* currSocket = socketNav.item(i);
611 
612  if (currSocket->isConnectedTo(bus)) {
613  for (int j = 0; j < currSocket->portCount(); j++) {
614 
615  if ((source->isGPR() ||
616  source->isImmediateRegister()) &&
617  currSocket->direction() == Socket::OUTPUT &&
618  currSocket->port(j)->parentUnit() ==
619  source->port().parentUnit()) {
620 
621  newAlloc.srcSocks.push_back(currSocket);
622  }
623 
624  if ((destination->isGPR() ||
625  destination->isImmediateRegister()) &&
626  currSocket->direction() == Socket::INPUT &&
627  currSocket->port(j)->parentUnit() ==
628  destination->port().parentUnit()) {
629 
630  newAlloc.dstSocks.push_back(currSocket);
631  }
632  }
633  }
634  }
635 
636  allocatedSockets.push_back(newAlloc);
637 
638  // add move annotations
639  if (move->annotationCount() > 0) {
640  for (Word annotationIndex = 0;
641  annotationIndex < move->annotationCount();
642  ++annotationIndex) {
643  newMove->addAnnotation(
645  static_cast<ProgramAnnotation::Id>(
646  move->annotation(annotationIndex)->id()),
647  move->annotation(annotationIndex)->payload()));
648  }
649  }
650 
651  newInstruction->addMove(newMove);
652 
653  if (newMove->source().isAddress() &&
654  &(newMove->source().address().space()) == adfInstrASpace_) {
655  instructionImmediates_.push_back(newMove);
656  }
657  } else {
658  // empty instruction
659 
660  // add move annotations
661  if (move->annotationCount() > 0) {
662  for (Word annotationIndex = 0;
663  annotationIndex < move->annotationCount();
664  ++annotationIndex) {
665  newInstruction->addAnnotation(
667  static_cast<ProgramAnnotation::Id>(
668  move->annotation(annotationIndex)->id()),
669  move->annotation(annotationIndex)->payload()));
670  }
671  }
672 
673  }
674  }
675 
676  // get template
677  InstructionTemplate& instrTemplate =
678  findInstrTemplate(resources, longImmediates, moveElements);
679 
680  newInstruction->setInstructionTemplate(instrTemplate);
681 
682  // and add long immediates
683  for (unsigned int i = 0; i < longImmediates.size(); i++) {
684  ImmediateElement* imm = longImmediates[i];
685  Byte iUnitID = imm->destinationUnit();
686 
687  Terminal* destination = createTerminal(
688  resources, NULL, Socket::INPUT,
689  MoveElement::MF_IMM, iUnitID, imm->destinationIndex());
690 
691  ImmediateUnit& immUnit(findImmediateUnit(resources, iUnitID));
692  SimValue simVal(instrTemplate.supportedWidth(immUnit));
693 
694  if (immUnit.signExtends()) {
695  simVal = imm->sLongWord();
696  } else {
697  simVal = imm->longWord();
698  }
699 
700  TerminalImmediate* immTerm = NULL;
701 
702  // TODO: refactor with createTerminal method's line 57
703  bool isInstructionReference = false;
704 
705  if (tpefTools_.hasRelocation(*imm)) {
706  const RelocElement &reloc = tpefTools_.relocation(*imm);
707 
708  // check if instruction address space
709  if (tpefInstrASpace_ == reloc.aSpace()) {
710  // create temporary TerminalAddress and add to vector
711  // for late replacement
712  immTerm = new TerminalAddress(simVal, *adfInstrASpace_);
713 
714  isInstructionReference = true;
715 
716  } else {
717  AddressSpace& adfDataSpace =
718  findAddressSpace(reloc.aSpace());
719  immTerm =
720  new TerminalAddress(simVal, adfDataSpace);
721  }
722 
723  } else {
724  immTerm = new TerminalImmediate(simVal);
725  }
726 
727  auto newImmediate = std::make_shared<Immediate>(immTerm, destination);
728 
729  newInstruction->addImmediate(newImmediate);
730 
731  if (isInstructionReference) {
732  longInstructionImmediates_.push_back(newImmediate);
733  }
734  }
735 
736  resolveSocketAllocations(allocatedSockets);
737  return newInstruction;
738 }
739 
740 /**
741  * Creates a move terminal of the appropriate type for given input data.
742  *
743  * This method *cannot* be used for creating terminal for immediate unit
744  * or register file registers.
745  *
746  *
747  * @param resources TPEF resource section.
748  * @param aBus Bus to which terminal is connected.
749  * @param direction Read or write terminal.
750  * @param type TPEF type of terminal.
751  * @param unitId TPEF identification code of the unit to which terminal
752  * belongs.
753  * @param index Register or operation terminal index, or immediate
754  * identifier.
755  * @param immediateMap All immediates of currently created instruction.
756  * @return A new move terminal.
757  */
758 Terminal*
760  const ResourceSection& resources, const Bus* aBus,
761  Socket::Direction direction, MoveElement::FieldType type, HalfWord unitId,
762  HalfWord index, const ImmediateMap* immediateMap) const {
763 
764  // omit caching because RF and IMM unit ports are resolved later
765  if (type == MoveElement::MF_RF) {
766  // port(0) just a dummy temporary assignment, it may even be illegal
767  RegisterFile& registerFile = findRegisterFile(resources, unitId);
768  return new TerminalRegister(*registerFile.port(0), index);
769 
770  } else if (type == MoveElement::MF_IMM &&
771  unitId != ResourceElement::INLINE_IMM) {
772 
773  // port(0) just a dummy temporary assignment, it may even be illegal
774  ImmediateUnit& immUnit = findImmediateUnit(resources, unitId);
775  return new TerminalRegister(*immUnit.port(0), index);
776  }
777 
778  CacheKey cacheKey(*aBus, direction, type, unitId, index);
779 
780  Terminal* returnValue = getFromCache(cacheKey);
781 
782  if (returnValue == NULL) {
783 
784  switch (type) {
785 
786  case MoveElement::MF_IMM: {
787  ImmediateKey immKey(unitId, index);
788  ImmediateElement* imm = NULL;
789 
790  if (MapTools::containsKey(*immediateMap, immKey)) {
791  imm = MapTools::valueForKey<ImmediateElement*>(
792  *immediateMap, immKey);
793  } else {
795  << "Cannot find immediate with unitId/index "
796  << static_cast<int>(unitId) << "/" << index << std::endl
797  << "immediateMap.size(): " << immediateMap->size()
798  << std::endl;
800  }
801 
802  if (imm->isInline()) {
803 
804  int immWidth = aBus->immediateWidth();
805  SimValue simValue(immWidth);
806  simValue = imm->longWord();
807 
808  // TODO: refactor with line createInstruction
809  // method's line 158
810  if (tpefTools_.hasRelocation(*imm)) {
811  const RelocElement &reloc = tpefTools_.relocation(*imm);
812 
813  // check if instruction address space
814  if (tpefInstrASpace_ == reloc.aSpace()) {
815  // create temporary TerminalAddress and add to vector
816  // for late replacement
817  returnValue =
818  new TerminalAddress(simValue, *adfInstrASpace_);
819 
820  } else {
821  try {
822  AddressSpace& adfDataSpace =
823  findAddressSpace(reloc.aSpace());
824  returnValue =
825  new TerminalAddress(simValue, adfDataSpace);
826  } catch (const NotAvailable& e) {
827  NotAvailable newException(
828  __FILE__, __LINE__, __func__,
829  (boost::format(
830  "Unable to find address space for "
831  "target of reloc element for immediate "
832  "'%d'.") % imm->word()).
833  str());
834  newException.setCause(e);
835  throw newException;
836  }
837  }
838 
839  } else {
840  returnValue = new TerminalImmediate(simValue);
841  }
843  dynamic_cast<TerminalImmediate*>(returnValue);
844  assert(returnValue != NULL);
845  // add immediate annotations
846  if (imm->annotationCount() > 0) {
847  for (Word annotationIndex = 0;
848  annotationIndex < imm->annotationCount();
849  ++annotationIndex) {
850  retVal->addAnnotation(
852  static_cast<ProgramAnnotation::Id>(
853  imm->annotation(annotationIndex)->id()),
854  imm->annotation(annotationIndex)->payload()));
855  }
856  }
857 
858  } else {
859  abortWithError("Error: immediate register references "
860  "should be already handled in same place "
861  "with normal register references.");
862  }
863  } break;
864 
865  case MoveElement::MF_UNIT: {
866  ResourceElement* tpefResource = NULL;
867 
868  // TODO refactor
869  if (resources.hasResource(
870  ResourceElement::MRT_OP, index)) {
871 
872  tpefResource =
873  &resources.findResource(ResourceElement::MRT_OP, index);
874 
875  } else if (resources.hasResource(
876  ResourceElement::MRT_PORT, index)) {
877 
878  tpefResource =
879  &resources.findResource(ResourceElement::MRT_PORT, index);
880 
881  } else if (resources.hasResource(
882  ResourceElement::MRT_SR, index)) {
883 
884  tpefResource =
885  &resources.findResource(ResourceElement::MRT_SR, index);
886 
887  } else {
888  abortWithError("Can't find resource port, operation or "
889  "special register with index:" +
890  Conversion::toString(index));
891 
892  }
893 
894  assert(tpefResource != NULL);
895 
896  std::string tpefOpStr =
897  stringOfChunk(tpefResource->name(), resources.link());
898 
899  // TODO:
900  // I need only unit.port and unit.operation.index parsing since
901  // unit.port.opcode references are converted to
902  // unit.operation.index form in tpef
903 
904  // NOTE:
905  // for now parser can chop just add.1 and sub.3 etc. kind of
906  // strings.
907 
908  // start of hack parser
909  bool opCodePort = false;
910  std::string::size_type opNameLength = tpefOpStr.rfind('.');
911  std::string tpefOpName = tpefOpStr;
912  int tpefOpIndex = 0;
913 
914  if (opNameLength != std::string::npos) {
915  tpefOpName = tpefOpStr.substr(0, opNameLength);
916  std::string::size_type opIndexStart = opNameLength + 1;
917  std::string tpefOpIndexStr =
918  tpefOpStr.substr(
919  opIndexStart, tpefOpStr.length() - opIndexStart);
920  tpefOpIndex = Conversion::toInt(tpefOpIndexStr);
921  opCodePort = true;
922  }
923  // end of hack parser
924 
925  // returns normal fu or universal fu or universal gcu..
926  FunctionUnit& functionUnit =
927  findFunctionUnit(resources, unitId, tpefOpName);
928 
929  if (opCodePort) {
930  // find HWOperation....
931  HWOperation& oper = *functionUnit.operation(tpefOpName);
932  returnValue = new TerminalFUPort(oper, tpefOpIndex);
933 
934  } else {
935  // special register or plain port reference
936  BaseFUPort& port = dynamic_cast<BaseFUPort&>(
937  findPort(*aBus, functionUnit, tpefOpName));
938 
939  returnValue = new TerminalFUPort(port);
940  }
941  } break;
942 
943  default: {
944  abortWithError("Unknown move field type!");
945  }
946 
947  }
948 
949  // immediates are not cached...
950  if (type != MoveElement::MF_IMM) {
951  addToCache(cacheKey, returnValue);
952  }
953 
954  } else {
955  return returnValue->copy();
956  }
957 
958  return returnValue;
959 }
960 
961 /**
962  * Returns the bus of real or universal machine with the given bus
963  * identification number, as found in TPEF.
964  *
965  * @param resources The resource section where the bus should be searched.
966  * @param busId Id of requested bus.
967  * @return Requested bus.
968  * @exception NotAvailable if requested bus does not belong to the
969  * target architecture.
970  */
971 Bus&
973  const ResourceSection &resources,
974  HalfWord busId) const {
975 
976  if (busId == ResourceElement::UNIVERSAL_BUS) {
977  if (universalMachine_ == NULL) {
978  throw NotAvailable(
979  __FILE__, __LINE__, __func__,
980  "TPEF needs universal machine for universal bus reference.");
981  }
982 
984 
985  } else {
986  if (machine_ == NULL) {
987  throw NotAvailable(
988  __FILE__, __LINE__, __func__,
989  "TPEF needs real machine for non-universal bus reference.");
990  }
991 
992  // internal error with TPEF...
993  assert(resources.hasResource(ResourceElement::MRT_BUS, busId));
994 
995  ResourceElement &tpefBus =
996  resources.findResource(ResourceElement::MRT_BUS, busId);
997 
998  std::string busName =
999  stringOfChunk(tpefBus.name(), resources.link());
1000 
1001  if (!machine_->busNavigator().hasItem(busName)) {
1002  throw NotAvailable(
1003  __FILE__, __LINE__, __func__,
1004  "ADF does not contain bus: " + busName);
1005  }
1006 
1007  return *(machine_->busNavigator().item(busName));
1008  }
1009 }
1010 
1011 /**
1012  * Returns RegisterFile by TPEF id number.
1013  *
1014  * @param resources The resource section where the bus should be searched.
1015  * @param rfId Id of requested register file.
1016  * @return Register file from real or universal machine.
1017  * @exception NotAvailable if requested register file does not belong to the
1018  * target architecture.
1019  */
1020 RegisterFile&
1022  const ResourceSection& resources,
1023  HalfWord rfId) const {
1024 
1025  switch (rfId) {
1026 
1027  case ResourceElement::ILLEGAL_RF:
1028  abortWithError("Illegal registerfile ID!");
1029 
1030  case ResourceElement::INT_RF:
1031  if (universalMachine_ == NULL) {
1032  throw NotAvailable(
1033  __FILE__, __LINE__, __func__,
1034  "TPEF needs universal machine for universal integer RF "
1035  "reference.");
1036  }
1037 
1039 
1040  case ResourceElement::BOOL_RF:
1041  if (universalMachine_ == NULL) {
1042  throw NotAvailable(
1043  __FILE__, __LINE__, __func__,
1044  "TPEF needs universal machine for universal boolean RF "
1045  "reference.");
1046  }
1047 
1049 
1050  case ResourceElement::FP_RF:
1051  if (universalMachine_ == NULL) {
1052  throw NotAvailable(
1053  __FILE__, __LINE__, __func__,
1054  "TPEF needs universal machine for universal floating point "
1055  "RF reference.");
1056  }
1057 
1059 
1060  default: {
1061 
1062  if (machine_ == NULL) {
1063  throw NotAvailable(
1064  __FILE__, __LINE__, __func__,
1065  "TPEF needs real machine for non-universal RF reference.");
1066  }
1067 
1068  ResourceElement &tpefRF =
1069  resources.findResource(ResourceElement::MRT_RF, rfId);
1070 
1071  std::string rfName =
1072  stringOfChunk(tpefRF.name(), resources.link());
1073 
1074  if (!machine_->registerFileNavigator().hasItem(rfName)) {
1075  throw NotAvailable(
1076  __FILE__, __LINE__, __func__,
1077  "Can't find RF \"" + rfName + "\" from ADF.");
1078  }
1079 
1080  return *(machine_->registerFileNavigator().item(rfName));
1081  }
1082 
1083  }
1084 
1085  abortWithError("This line should never be executed!");
1087 }
1088 
1089 /**
1090  * Returns ImmediateUnit by TPEF id number.
1091  *
1092  * @param resources The resource section where the bus should be searched.
1093  * @param immUnitId Id of requested immediate unit.
1094  * @return Immediate unit.
1095  * @exception NotAvailable if requested immediate unit does not belong to the
1096  * target architecture.
1097  */
1100  const ResourceSection& resources,
1101  Byte immUnitId) const {
1102 
1103  if (machine_ == NULL) {
1104  throw NotAvailable(
1105  __FILE__, __LINE__, __func__,
1106  "TPEF needs real machine for immediate unit reference.");
1107  }
1108 
1109  ResourceElement &tpefImmUnit =
1110  resources.findResource(ResourceElement::MRT_IMM, immUnitId);
1111 
1112  std::string immUnitName =
1113  stringOfChunk(tpefImmUnit.name(), resources.link());
1114 
1115  if (!machine_->immediateUnitNavigator().hasItem(immUnitName)) {
1116  throw NotAvailable(
1117  __FILE__, __LINE__, __func__,
1118  "Can't find immediate unit \"" + immUnitName + "\" from ADF.");
1119  }
1120 
1121  return *(machine_->immediateUnitNavigator().item(immUnitName));
1122 }
1123 
1124 /**
1125  * Returns FunctionUnit by TPEF identification number and operation name.
1126  *
1127  * If function unit ID corresponds to the universal function unit, then
1128  * operation name is checked to see if we should return universal gcu or
1129  * universal fu.
1130  *
1131  * If operation name is special register of function unit or if operation
1132  * name is operation of gcu then universal gcu is returned.
1133  *
1134  * @param resources The resource section where the bus should be searched.
1135  * @param unitId Id of requested unit.
1136  * @param tpefOpName Name of operation or special register for
1137  * universal machine resources.
1138  * @return Function unit from real or universal machine.
1139  * @exception NotAvailable if requested function unit does not belong to the
1140  * target architecture.
1141  */
1142 FunctionUnit&
1144  const ResourceSection& resources,
1145  HalfWord unitId,
1146  std::string tpefOpName) const {
1147 
1148  switch (unitId) {
1149 
1150  case ResourceElement::UNIVERSAL_FU: {
1151 
1152  if (universalMachine_ == NULL) {
1153  throw NotAvailable(
1154  __FILE__, __LINE__, __func__,
1155  "TPEF needs universal machine for getting universal FU.");
1156  }
1157 
1159 
1160  assert(gcu != NULL);
1161 
1162  if (tpefOpName == ResourceElement::RETURN_ADDRESS_NAME) {
1163  return *gcu;
1164  }
1165 
1167  assert(fu != NULL);
1168 
1169  if (gcu->hasOperation(tpefOpName)) {
1170  return *gcu;
1171 
1172  } else if (fu->hasOperation(tpefOpName)) {
1173  return *fu;
1174 
1175  } else {
1176  boost::format errMsg(
1177  "Unknown operation '%1%'. Operation definition not found.");
1178  throw NotAvailable(
1179  __FILE__, __LINE__, __func__, (errMsg % tpefOpName).str());
1180  }
1181  }
1182 
1183  default: {
1184 
1185  if (machine_ == NULL) {
1186  throw NotAvailable(__FILE__, __LINE__, __func__,
1187  "TPEF needs real target architecture for getting a "
1188  "non-universal FU.");
1189  }
1190 
1191  ResourceElement &tpefFU = resources.findResource(
1192  ResourceElement::MRT_UNIT, unitId);
1193 
1194  std::string fuName =
1195  stringOfChunk(tpefFU.name(), resources.link());
1196 
1197  if (machine_->functionUnitNavigator().hasItem(fuName)) {
1198  return *(machine_->functionUnitNavigator().item(fuName));
1199 
1200  } else {
1201 
1202  // maybe it's GCU ..
1203  if (machine_->controlUnit()->name() == fuName) {
1204  return *machine_->controlUnit();
1205 
1206  } else {
1207  throw NotAvailable(
1208  __FILE__, __LINE__, __func__,
1209  "Can't find RFU \"" + fuName + "\" from ADF.");
1210  }
1211  }
1212  }
1213 
1214  }
1215 
1216  abortWithError("This line should never be run!");
1218 }
1219 
1220 /**
1221  * Finds any function unit or special register port from target architecture
1222  * (possiby the universal machine).
1223  *
1224  * NOTE: this is currently used only for plain port references
1225  * (sr or port without opcode) if TPEFProgramFactory. However
1226  * method should be able finding also function unit ports.
1227  *
1228  * @param bus Bus where to socket is connected.
1229  * @param portParent Parent to which port in connected to.
1230  * @param tpefOpName Name of operation if opcode port to find.
1231  * @param tpefOpIndex Terminal index of operation if opcode port to find.
1232  * @return Found port.
1233  * @exception NotAvailable if requested port does not belong to the target
1234  * architecture.
1235  */
1236 Port&
1238  const Bus& bus,
1239  const Unit& portParent,
1240  std::string tpefOpName,
1241  int tpefOpIndex) const {
1242 
1243  const Machine* machineOfBus = NULL;
1244 
1245  if (universalMachine_ != NULL &&
1246  &bus == &universalMachine_->universalBus()) {
1247  machineOfBus = universalMachine_;
1248  } else {
1249  machineOfBus = machine_;
1250  }
1251 
1252  assert(machineOfBus != NULL);
1253 
1254  // check if it is function unit port to find
1255  const FunctionUnit* fu =
1256  dynamic_cast<const FunctionUnit*>(&portParent);
1257 
1258  if (fu != NULL) {
1259 
1260  // check if known special register (for sequential code)
1261  if (tpefOpName == ResourceElement::RETURN_ADDRESS_NAME) {
1262 
1263  const ControlUnit &controlUnit =
1264  dynamic_cast<const ControlUnit&>(portParent);
1265 
1266  if (controlUnit.hasReturnAddressPort()) {
1267  return *(controlUnit.returnAddressPort());
1268 
1269  } else {
1270  throw NotAvailable(
1271  __FILE__, __LINE__, __func__,
1272  "GCU needs return address port.");
1273  }
1274 
1275  } else {
1276  // function unit is either gcu or real fu
1277 
1278  // if operation index is valid and opname is found from FU
1279  // then we know that it's port with opcode given
1280  if (fu->hasOperation(tpefOpName) && tpefOpIndex != 0) {
1281  // must be operation port
1282  HWOperation* oper = fu->operation(tpefOpName);
1283  return *(oper->port(tpefOpIndex));
1284 
1285  } else if (fu->hasPort(tpefOpName)) {
1286  // must be special plain port reference
1288  dynamic_cast<TTAMachine::SpecialRegisterPort*>(
1289  fu->port(tpefOpName));
1290 
1291  if (srPort != NULL) {
1292  // NOTE: only known specialregister ports are allowed!
1293  // add asserts for special registers here :)
1294  assert(srPort ==
1295  machineOfBus->controlUnit()->returnAddressPort());
1296  return *srPort;
1297  } else {
1298  return *fu->port(tpefOpName);
1299  }
1300 
1301  } else {
1302  throw NotAvailable(
1303  __FILE__, __LINE__, __func__, "Can't find port for: " +
1304  fu->name() + "." + tpefOpName + "." +
1305  Conversion::toString(tpefOpIndex));
1306  }
1307  }
1308  }
1309 
1310  // didn't seem to be fu port... this is not used for normal
1311  // registers anymore...
1312 
1313  std::string throwError = "Can't find port for: " + portParent.name();
1314 
1315  if (tpefOpName != "") {
1316  throwError += "." + tpefOpName;
1317  }
1318 
1319  throwError += "." + Conversion::toString(tpefOpIndex);
1320 
1321  throw NotAvailable(__FILE__, __LINE__, __func__,throwError);
1322 }
1323 
1324 /**
1325  * Finds address space by name.
1326  *
1327  * @param Name of address space.
1328  * @return Address space.
1329  * @exception NotAvailable if requested address space does not belong to
1330  * the target architecture.
1331  */
1334 
1335  std::string aSpaceName = tpefTools_.addressSpaceName(*aSpace);
1336 
1337  if (machine_ != NULL) {
1338  Machine::AddressSpaceNavigator aSpaceNavi =
1340 
1341  if (aSpaceNavi.hasItem(aSpaceName)) {
1342  return *aSpaceNavi.item(aSpaceName);
1343  }
1344  }
1345 
1346  if (universalMachine_ != NULL) {
1347  if (aSpaceName == universalMachine_->dataAddressSpace().name()) {
1349  } else if (aSpaceName ==
1352 
1353  }
1354  }
1355 
1356  throw NotAvailable(
1357  __FILE__, __LINE__, __func__,
1358  "Can't find address space by name: " + aSpaceName +
1359  " MAU: " + Conversion::toString(static_cast<int>(aSpace->MAU())));
1360 }
1361 
1362 /**
1363  * Finds guard of bus.
1364  *
1365  * @param resources TPEF resource section.
1366  * @param bus Bus of guard.
1367  * @param type Is fu or register guard.
1368  * @param unitId Id of the unit that contains guard register or port.
1369  * @param index Register or operand index of guard.
1370  * @param isInverted Is inverted guard.
1371  */
1374  const TPEF::ResourceSection &resources,
1376  HalfWord unitId, HalfWord index, bool isInverted) const {
1377 
1378  RegisterFile* guardRF = NULL;
1379  Port* guardPort = NULL;
1380 
1381  // find corresponding function unit or register file.
1382  switch (type) {
1384  FunctionUnit &guardUnit = findFunctionUnit(resources, unitId);
1385 
1386  // find port
1387  ResourceElement* resource = NULL;
1388 
1389  // TODO refactor
1390  if (resources.hasResource(
1391  ResourceElement::MRT_OP, index)) {
1392 
1393  resource =
1394  &resources.findResource(ResourceElement::MRT_OP, index);
1395 
1396  } else if (resources.hasResource(
1397  ResourceElement::MRT_PORT, index)) {
1398 
1399  resource =
1400  &resources.findResource(ResourceElement::MRT_PORT, index);
1401 
1402  } else if (resources.hasResource(
1403  ResourceElement::MRT_SR, index)) {
1404 
1405  resource =
1406  &resources.findResource(ResourceElement::MRT_SR, index);
1407 
1408  } else {
1409  abortWithError("Can't find resource port, operation or "
1410  "special register with index:" +
1411  Conversion::toString(index));
1412 
1413  }
1414 
1415 
1416  std::string tpefOpStr =
1417  stringOfChunk(resource->name(), resources.link());
1418 
1419  // find operation port or special register port
1420  if (guardUnit.hasPort(tpefOpStr)) {
1421  guardPort = guardUnit.port(tpefOpStr);
1422 
1423  } else {
1424  std::string::size_type dotPos = tpefOpStr.find('.');
1425  assert (dotPos != std::string::npos);
1426  std::string operationName = tpefOpStr.substr(0, dotPos);
1427  HWOperation* oper = guardUnit.operation(operationName);
1428  Word operandIndex = Conversion::toInt(
1429  tpefOpStr.substr(dotPos+1, tpefOpStr.length() - dotPos - 1));
1430 
1431  guardPort = oper->port(operandIndex);
1432  }
1433  } break;
1434 
1436  guardRF = &findRegisterFile(resources, unitId);
1437  break;
1438 
1439  default:
1441  "Error: Unknown guard type. Guard must be either FU port "
1442  "or RF index.");
1443  }
1444 
1445  assert (reinterpret_cast<long int>(guardPort) !=
1446  reinterpret_cast<long int>(guardRF));
1447 
1448  for (int i = 0; i < bus.guardCount(); i++) {
1449  Guard* currGuard = bus.guard(i);
1450 
1451  if (currGuard->isInverted() == isInverted) {
1452  PortGuard* portGuard = dynamic_cast<PortGuard*>(currGuard);
1453  RegisterGuard* registerGuard =
1454  dynamic_cast<RegisterGuard*>(currGuard);
1455 
1456  if (portGuard != NULL && guardPort != NULL) {
1457  if (portGuard->port() == guardPort) {
1458  return *currGuard;
1459  }
1460 
1461  } else if (registerGuard != NULL && guardRF != NULL) {
1462  if (registerGuard->registerFile() == guardRF &&
1463  registerGuard->registerIndex() == index) {
1464  return *currGuard;
1465  }
1466  }
1467  }
1468  }
1469 
1470  std::string guardType;
1471  if (isInverted) {
1472  guardType = "! ";
1473  } else {
1474  guardType = "? ";
1475  }
1476 
1477  if (guardRF != NULL) {
1478  guardType += guardRF->name() + "." + Conversion::toString(index);
1479  }
1480 
1481  if (guardPort != NULL) {
1482  guardType += "Some FU operation or special register.";
1483  }
1484 
1485  throw NotAvailable(
1486  __FILE__, __LINE__, __func__,
1487  "Can't find suitable guard: " + guardType + "\tfrom bus: " +
1488  bus.name());
1489 
1490  return *bus.guard(0);
1491 }
1492 
1493 /**
1494  * Returns instruction template that can be used for current instruction.
1495  *
1496  * @param resources TPEF resource section.
1497  * @param longImmediates Long immediates of instruction.
1498  * @param moves Moves of instruction.
1499  * @return Instruction template that can be used for this instruction.
1500  */
1503  const TPEF::ResourceSection &resources,
1504  ImmediateVector& longImmediates,
1505  MoveVector& moves) const {
1506 
1507  if (machine_ == NULL) {
1508  assert(
1511  }
1512 
1513  // check how many bits must be written to each immediate unit....
1514  std::map<ImmediateUnit*, int> bitsToWrite;
1515 
1516  for (unsigned int i = 0; i < longImmediates.size(); i++) {
1517  ImmediateElement* imm = longImmediates[i];
1518 
1519  // destination unit
1520  ImmediateUnit* dstUnit =
1521  &findImmediateUnit(resources, imm->destinationUnit());
1522 
1523  if (MapTools::containsKey(bitsToWrite, dstUnit)) {
1524  throw NotAvailable(
1525  __FILE__, __LINE__, __func__,
1526  "Can't write two immediates to the same immediate unit "
1527  " in the same instruction.");
1528  } else {
1529  bitsToWrite[dstUnit] = dstUnit->zeroExtends() ?
1532  }
1533  }
1534 
1535  // find suitable template
1538 
1539  // try to find an instruction template with the most NOP slots
1540  // to enhance the possible variable length encoding benefits
1541  InstructionTemplate* bestiTempFound = NULL;
1542 
1543  for (int i = 0; i < tempNav.count(); i++) {
1544  InstructionTemplate* insTemp = tempNav.item(i);
1545 
1546  // check if numberOfDestinations is same that number of
1547  // immediates to write
1548  if (insTemp->numberOfDestinations() ==
1549  static_cast<int>(bitsToWrite.size())) {
1550 
1551  bool templateIsGood = true;
1552 
1553  // check that destinations and bitwidths match
1554  for (std::map<ImmediateUnit*, int>::iterator iter =
1555  bitsToWrite.begin();
1556  iter != bitsToWrite.end();
1557  iter++) {
1558 
1559  if (!insTemp->isOneOfDestinations(*(*iter).first) ||
1560  (*iter).second >
1561  insTemp->supportedWidth(*(*iter).first)) {
1562  templateIsGood = false;
1563  break;
1564  }
1565  }
1566 
1567  // check if move slots allows to use this template
1568  if (templateIsGood) {
1569  for (unsigned int j = 0; j < moves.size(); j++) {
1570  MoveElement* move = moves[j];
1571 
1572  if (move->isEmpty()) {
1573  continue;
1574  }
1575 
1576  Bus& usedBus = findBus(resources, move->bus());
1577 
1578  // can be NOP slot also in which case the template cannot
1579  // used for the move either
1580  if (insTemp->usesSlot(usedBus.name())) {
1581  templateIsGood = false;
1582  break;
1583  }
1584  }
1585  }
1586 
1587  // if template passed all the checks
1588  if (templateIsGood) {
1589  if (bestiTempFound == NULL)
1590  bestiTempFound = insTemp;
1591  }
1592  }
1593  }
1594 
1595  if (bestiTempFound == NULL) {
1596  std::string bitRequirementmsg;
1597  for (const auto& pair : bitsToWrite) {
1598  bitRequirementmsg += Conversion::toString(pair.second)
1599  + " bits to IU: " + pair.first->name() + "\n";
1600  }
1602  "Valid instruction template is not found for instruction layout:\n"
1603  + "An instruction template is needed that can write:\n"
1604  + bitRequirementmsg);
1605  } else {
1606  return *bestiTempFound;
1607  }
1608 }
1609 
1610 /**
1611  * Checks if the source of SocketAllocation can be assigned towards
1612  * given map of already allocated sockets.
1613  *
1614  * If tried socket is already used, it still can be used for another
1615  * reading if
1616  * 1) the source register index is same for both of the allocations, or
1617  * 2) the moves have opposite guards.
1618  *
1619  * @param alloc Socket allocation structure which is checked.
1620  * @param fixedSockets Map of already made socket allocations.
1621  * @return True if tried alloc is possible.
1622  */
1623 bool
1625  SocketAllocation& alloc,
1626  std::map<Socket*, std::vector<SocketAllocation*> >& fixedSockets) const {
1627 
1628  Socket* currentSocket = alloc.srcSocks[alloc.src];
1629 
1630  if (MapTools::containsKey(fixedSockets, currentSocket)) {
1631 
1632  std::vector<SocketAllocation*>& socketAllocs = fixedSockets[currentSocket];
1633 
1634  // test against all allocations.
1635  for (unsigned int i = 0; i < socketAllocs.size(); i++) {
1636  // TODO: check against all users.
1637  auto oldMove = socketAllocs[i]->move;
1638  Terminal* oldTerminal = &(oldMove->source());
1639 
1640  // allowed for same register of opposite guard.
1641  if (alloc.move->source().index() != oldTerminal->index() &&
1642  (alloc.move->isUnconditional() || oldMove->isUnconditional() ||
1643  !alloc.move->guard().guard().isOpposite(oldMove->guard().guard()))) {
1644  return false;
1645  }
1646  }
1647  //Application::errorStream() << insTemp->NOPSlotCount() << " " << templateIsGood << " ";
1648  //Application::errorStream() << std::endl;
1649  }
1650 
1651  return true;
1652 }
1653 
1654 
1655 /**
1656  * Checks if the destination of SocketAllocation can be assigned towards
1657  * given map of already allocated sockets.
1658  *
1659  * If tried socket is already used, it still can be used for another
1660  * writing if the moves have opposite guards.
1661  *
1662  * @param alloc Socket allocation structure which is checked.
1663  * @param fixedSockets Map of already made socket allocations.
1664  * @return True if tried alloc is possible.
1665  */
1666 bool
1668  SocketAllocation& alloc,
1669  std::map<Socket*, std::vector<SocketAllocation*> >& fixedSockets) const {
1670 
1671  Socket* currentSocket = alloc.dstSocks[alloc.dst];
1672 
1673  if (MapTools::containsKey(fixedSockets, currentSocket)) {
1674 
1675  std::vector<SocketAllocation*>& socketAllocs = fixedSockets[currentSocket];
1676 
1677  // test against all allocations.
1678  for (unsigned int i = 0; i < socketAllocs.size(); i++) {
1679  // TODO: check against all users.
1680  auto oldMove = socketAllocs[i]->move;
1681  if (alloc.move->isUnconditional() || oldMove->isUnconditional() ||
1682  !alloc.move->guard().guard().isOpposite(
1683  oldMove->guard().guard())) {
1684  return false;
1685  }
1686  }
1687  }
1688  return true;
1689 }
1690 
1691 
1692 
1693 
1694 /**
1695  * Resolves sockets that are used for GPR and Immediate Unit reading and
1696  * writing for instruction.
1697  *
1698  * NOTE: TPEF specification currently supports storing port information
1699  * of GPR references, so if this solution does not work or
1700  * if this is too slow, then register port information should
1701  * be implemented to TPEF object modell.
1702  *
1703  * @todo Yes, we should store the port allocations also
1704  * to TPEF, if they have been assigned by the scheduler. This kind of
1705  * resolving again and again does not make sense!
1706  *
1707  * @param allocs All GPR and IU reads and writes of instruction.
1708  * One item in this vector represents one move in the instruction.
1709  */
1710 void
1712  std::vector<SocketAllocation>& allocs) const {
1713 
1714  // map of socket to all moves which use it.
1715  std::map<Socket*, std::vector<SocketAllocation*> > fixedSockets;
1716 
1717  // try to resolve working combination starting from the first allocation
1718  unsigned currIndex = 0;
1719 
1720  while (currIndex < allocs.size()) {
1721  bool allocationWasSuccess = true;
1722 
1723  SocketAllocation& alloc = allocs[currIndex];
1724 
1725  if (alloc.srcSocks.empty()) {
1726  currIndex++;
1727  continue;
1728  }
1729 
1730  // try to get allocation for current element
1731  if (alloc.src < alloc.srcSocks.size()) {
1732  while (!canSourceBeAssigned(alloc, fixedSockets)) {
1733  alloc.src++;
1734 
1735  if (alloc.src == alloc.srcSocks.size()) {
1736  // working socket could not be found
1737  allocationWasSuccess = false;
1738  break;
1739  }
1740  }
1741  } else {
1742  allocationWasSuccess = false;
1743  }
1744 
1745  // if allocation was success add allocation to for the socket
1746  // otherwise remove the latest allocations and try to resolve them
1747  // again
1748 
1749  if (allocationWasSuccess) {
1750  // assign allocation for this socket
1751  Socket* currentSocket = alloc.srcSocks[alloc.src];
1752  fixedSockets[currentSocket].push_back(&alloc);
1753 
1754  } else {
1755  // reset allocation try sequence
1756  alloc.src = 0;
1757 
1758  // free previous allocation and try again
1759  unsigned int prevIndex = currIndex;
1760 
1761  do {
1762  if (prevIndex == 0) {
1763  throw NotAvailable(
1764  __FILE__, __LINE__, __func__,
1765  "Can't resolve src sockets for instruction.");
1766  }
1767 
1768  prevIndex--;
1769 
1770  } while (allocs[prevIndex].srcSocks.empty());
1771 
1772 
1773  Socket* socketToFree =
1774  allocs[prevIndex].srcSocks[allocs[prevIndex].src];
1775  std::vector<SocketAllocation*>& freedAllocs =
1776  fixedSockets[socketToFree];
1777 
1778  bool prevFound = false;
1779  // find first freed allocation where we continue search
1780  for (int k = prevIndex; k >= 0 && !prevFound; k--) {
1781  for (std::vector<SocketAllocation*>::iterator j =
1782  freedAllocs.begin(); j != freedAllocs.end(); j++) {
1783 
1784  if (static_cast<int>((*j)->index) == k) {
1785  (*j)->src++;
1786  currIndex = k;
1787  prevFound = true;
1788  freedAllocs.erase(j);
1789  break;
1790  }
1791  }
1792  }
1793  continue; // don't touch currIndex here
1794  }
1795 
1796  currIndex++;
1797  }
1798 
1799 
1800  // and same for the destinations
1801  fixedSockets.clear();
1802  currIndex = 0;
1803 
1804  while (currIndex < allocs.size()) {
1805  bool allocationWasSuccess = true;
1806 
1807  SocketAllocation& alloc = allocs[currIndex];
1808 
1809  if (alloc.dstSocks.empty()) {
1810  currIndex++;
1811  continue;
1812  }
1813 
1814  // try to get allocation for current element
1815  if (alloc.dst < alloc.dstSocks.size()) {
1816  while (!canDestinationBeAssigned(alloc, fixedSockets)) {
1817  alloc.dst++;
1818 
1819  if (alloc.dst == alloc.dstSocks.size()) {
1820  // working socket could not be found
1821  allocationWasSuccess = false;
1822  break;
1823  }
1824  }
1825  } else {
1826  allocationWasSuccess = false;
1827  }
1828 
1829  // if allocation was success add allocation to for the socket
1830  // otherwise remove the latest allocations and try to resolve them
1831  // again
1832 
1833  if (allocationWasSuccess) {
1834  // assign allocation for this socket
1835  Socket* currentSocket = alloc.dstSocks[alloc.dst];
1836  fixedSockets[currentSocket].push_back(&alloc);
1837 
1838  } else {
1839  // reset allocation try sequence
1840  alloc.dst = 0;
1841 
1842  // free previous allocation and try again
1843  unsigned int prevIndex = currIndex;
1844 
1845  do {
1846  if (prevIndex == 0) {
1847  throw NotAvailable(
1848  __FILE__, __LINE__, __func__,
1849  "Can't resolve dst sockets for instruction.");
1850  }
1851 
1852  prevIndex--;
1853 
1854  } while (allocs[prevIndex].dstSocks.empty());
1855 
1856 
1857  Socket* socketToFree =
1858  allocs[prevIndex].dstSocks[allocs[prevIndex].dst];
1859  std::vector<SocketAllocation*>& freedAllocs =
1860  fixedSockets[socketToFree];
1861 
1862  // find first freed allocation where we continue search
1863  for (unsigned int j = 0; j < freedAllocs.size(); j++) {
1864  if (freedAllocs[j]->index < currIndex) {
1865  currIndex = freedAllocs[j]->index;
1866  }
1867  }
1868 
1869  // clean allocation indexes and increment index that is used
1870  // as a next start point for the search loop
1871  for (unsigned int j = 0; j < freedAllocs.size(); j++) {
1872  if (freedAllocs[j]->index != currIndex) {
1873  freedAllocs[j]->dst = 0;
1874  } else {
1875  freedAllocs[j]->dst++;
1876  }
1877  }
1878 
1879  fixedSockets.erase(socketToFree);
1880  continue; // don't touch currIndex here
1881  }
1882 
1883  currIndex++;
1884  }
1885 
1886  // fix terminals
1887  for (unsigned i = 0; i < allocs.size(); i++) {
1888  SocketAllocation &alloc = allocs[i];
1889 
1890 #if 0
1891  std::cerr << "next allocation source: "
1892  << alloc.move->source().isGPR()
1893  << " destination: "
1894  << alloc.move->destination().isGPR() << std::endl;
1895 #endif
1896 
1897  if (!alloc.srcSocks.empty()) {
1898  Socket* srcSocket = alloc.srcSocks[alloc.src];
1899  Unit* parent = alloc.move->source().port().parentUnit();
1900 
1901  for (int j = 0; j < srcSocket->portCount(); j++) {
1902  if (srcSocket->port(j)->parentUnit() == parent) {
1903  alloc.move->setSource(
1904  new TerminalRegister(
1905  *srcSocket->port(j),
1906  alloc.move->source().index()));
1907 #if 0
1908  std::cerr << "source was replaced" << std::endl;
1909 #endif
1910  break;
1911  }
1912  }
1913  }
1914 
1915  if (!alloc.dstSocks.empty()) {
1916  Socket* dstSocket = alloc.dstSocks[alloc.dst];
1917  Unit* parent = alloc.move->destination().port().parentUnit();
1918 
1919  for (int j = 0; j < dstSocket->portCount(); j++) {
1920  if (dstSocket->port(j)->parentUnit() == parent) {
1921  alloc.move->setDestination(
1922  new TerminalRegister(
1923  *dstSocket->port(j),
1924  alloc.move->destination().index()));
1925 #if 0
1926  std::cerr << "dst was replaced" << std::endl;
1927 #endif
1928  break;
1929  }
1930  }
1931  }
1932 #if 0
1933  if (alloc.move->source().isGPR() &&
1934  alloc.move->destination().isGPR()) {
1935  std::cerr << "next allocation source: "
1936  << alloc.move->source().port().name()
1937  << " destination: "
1938  << alloc.move->destination().port().name() << std::endl;
1939  }
1940 #endif
1941  }
1942 }
1943 
1944 /**
1945  * Returns cached terminal.
1946  *
1947  * @param key Cache key of terminal.
1948  * @return Cached terminal if there is one, NULL otherwise.
1949  */
1950 Terminal*
1952  const TPEFProgramFactory::CacheKey &key) const {
1953 
1954  if (MapTools::containsKey(cache_,key)) {
1955  return MapTools::valueForKey<Terminal*>(cache_,key);
1956  }
1957  return NULL;
1958 }
1959 
1960 /**
1961  * Adds Terminal to cache.
1962  *
1963  * @param key Key of search variables for getting terminal from machine(s).
1964  * @param cachedTerm Terminal to be add to cache.
1965  * @return cached terminal if there is one.
1966  */
1967 void
1969  const CacheKey &key,
1970  Terminal* cachedTerm) const {
1971 
1972  cache_[key] = cachedTerm;
1973 }
1974 
1975 /**
1976  * Clears cache.
1977  */
1978 void
1980  cache_.clear();
1981 }
1982 
1983 /**
1984  * Analyses all CodeSection from TPEF and tries to find function start points.
1985  *
1986  * @todo This function should do code analysis, but for it actually scans
1987  * symbol sections for code symbol, which are intepret as function
1988  * start points.
1989  */
1990 void
1992 
1993  // clear table if already exists (from previous POM builds)
1995 
1996  // check every symbol section
1997  for (Word i = 0; i < binary_->sectionCount(Section::ST_SYMTAB); i++) {
1998 
1999  SymbolSection *currSect =
2000  dynamic_cast<SymbolSection*>(
2001  binary_->section(Section::ST_SYMTAB, i));
2002 
2003  for (Word j = 0; j < currSect->elementCount(); j++) {
2004  ProcedSymElement* procedSymbol =
2005  dynamic_cast<ProcedSymElement*>(currSect->element(j));
2006 
2007  // symbol was not procedure symbol
2008  if (procedSymbol == NULL) {
2009  continue;
2010  }
2011 
2012  InstructionElement* referencedInstruction =
2013  procedSymbol->reference();
2014 
2015  // maybe we just could ignore null elements... but
2016  // there really should not be NULL code symbols, unless
2017  // referenced instruction has been moved or something...
2018  assert(referencedInstruction != NULL);
2019 
2020  std::string functionName =
2021  stringOfChunk(procedSymbol->name(), currSect->link());
2022 
2023  // add instruction element of symbol to entrypoint table
2024  functionStartPositions_[referencedInstruction] =
2026  }
2027  }
2028 }
2029 
2030 /**
2031  * Adds global labels of TPEF to Program.
2032  *
2033  * @param prog Program where to add labels.
2034  */
2035 void
2037  /// prevent addition of local symbol with same name multiple times
2038  std::map<string, std::pair<DataLabel*, bool> > dataLabels;
2039 
2040  for (Word i = 0; i < binary_->sectionCount(Section::ST_SYMTAB); i++) {
2041 
2042  SymbolSection* currSect = dynamic_cast<SymbolSection*>(
2043  binary_->section(Section::ST_SYMTAB, i));
2044 
2045  assert(currSect != NULL);
2046 
2047  StringSection* strings =
2048  dynamic_cast<StringSection*>(currSect->link());
2049 
2050  assert(strings != NULL);
2051 
2052  for (Word j = 0; j < currSect->elementCount(); j++) {
2053  SymbolElement* sym =
2054  dynamic_cast<SymbolElement*>(currSect->element(j));
2055 
2056  // read all local and global data labels
2057  if (sym->type() == SymbolElement::STT_DATA) {
2058 
2059  DataSymElement* dataSym =
2060  dynamic_cast<DataSymElement*>(sym);
2061 
2062  const std::string labelString =
2063  strings->chunk2String(dataSym->name());
2064 
2065  UDataSection* dataSection = dynamic_cast<UDataSection*>(
2066  dataSym->section());
2067 
2068  assert(dataSection != NULL);
2069 
2070  TTAMachine::AddressSpace* targetASpace = NULL;
2071  try {
2072  targetASpace =
2073  &findAddressSpace(dataSection->aSpace());
2074  } catch (const NotAvailable& e) {
2075  NotAvailable newException(
2076  __FILE__, __LINE__, __func__,
2077  (boost::format(
2078  "Unable to find address space for target "
2079  "of data label '%s'") % labelString).str());
2080  newException.setCause(e);
2081  throw newException;
2082  }
2083 
2084  Address refAddress(
2085  dataSection->bytesToMAUs(
2086  dataSym->reference()->offset()) +
2087  dataSection->startingAddress(),
2088  *targetASpace);
2089 
2090  DataLabel* dataLabel = new DataLabel(
2091  labelString, refAddress, prog.globalScope());
2092 
2093 // nice debug info
2094 // std::cerr << "Added data label\t"
2095 // <<"\tname: " << dataLabel->name()
2096 // << "\taddress: "
2097 // << Conversion::toString(dataLabel->address().location())
2098 // << std::endl;
2099 
2100  // check if label name is already used
2101  if (MapTools::containsKey(dataLabels, labelString)) {
2102 
2103  // if latest is global remove old one
2104  if (sym->binding() == SymbolElement::STB_GLOBAL) {
2105 
2106  // if there is two global symbols with same name
2107  // throw exception
2108  if (dataLabels[labelString].second) {
2109 
2110  // free reserved labels
2111  for (std::map<string,
2112  std::pair<DataLabel*,
2113  bool> >::iterator iter =
2114  dataLabels.begin();
2115  iter != dataLabels.end(); iter++) {
2116  delete (*iter).second.first;
2117  }
2118  delete dataLabel;
2119 
2120  throw NotAvailable(
2121  __FILE__, __LINE__, __func__,
2122  "Found two global symbols with same name: " +
2123  labelString);
2124  }
2125 
2126  delete dataLabels[labelString].first;
2127  dataLabels[labelString].first = dataLabel;
2128  dataLabels[labelString].second = true;
2129  }
2130  } else {
2131  // add symbol first time
2132  dataLabels[labelString].first = dataLabel;
2133  dataLabels[labelString].second =
2134  (sym->binding() == SymbolElement::STB_GLOBAL);
2135  }
2136 
2137  // Global code labels
2138  } else if (sym->binding() == SymbolElement::STB_GLOBAL &&
2139  sym->type() == SymbolElement::STT_CODE) {
2140 
2141  CodeSymElement* codeSym =
2142  dynamic_cast<CodeSymElement*>(sym);
2143 
2145  instructionMap_, codeSym->reference()));
2146 
2147  InstructionReference refIns =
2149  *instructionMap_[codeSym->reference()]);
2150 
2151  CodeLabel* newLabel =
2152  new CodeLabel(refIns,
2153  strings->chunk2String(sym->name()));
2154 
2155  prog.globalScope().addCodeLabel(newLabel);
2156  }
2157  }
2158  }
2159 
2160  // Add symbols to program
2161  /// prevent addition of local symbol with same name multiple times
2162  for (std::map<string, std::pair<DataLabel*, bool> >::iterator iter =
2163  dataLabels.begin();
2164  iter != dataLabels.end(); iter++) {
2165 
2166  prog.globalScope().addDataLabel((*iter).second.first);
2167  }
2168 }
2169 
2170 /**
2171  * Creates data memories to program.
2172  *
2173  * @param prog Program containing converted TPEF instructions.
2174  */
2175 void
2177 
2178  // ------- search through data sections and group them by address spaces
2179  std::map<AddressSpace*, std::vector<UDataSection*> > memories;
2180 
2181  for (int i = 0; i < static_cast<int>(binary_->sectionCount()); i++) {
2182  Section* currSect = binary_->section(i);
2183 
2184  if (currSect->type() == Section::ST_DATA ||
2185  currSect->type() == Section::ST_UDATA ||
2186  currSect->type() == Section::ST_LEDATA) {
2187 
2188  UDataSection* uDataSect = dynamic_cast<UDataSection*>(currSect);
2189 
2190  AddressSpace& aSpace = findAddressSpace(uDataSect->aSpace());
2191  std::vector<UDataSection*>& secVec = memories[&aSpace];
2192 
2193  // sort sections of current vector by addess...
2194  UDataSection* temp = NULL;
2195  for (int j = 0; j < static_cast<int>(secVec.size()); j++) {
2196  if (secVec[j]->startingAddress() >
2197  uDataSect->startingAddress()) {
2198  temp = secVec[j];
2199  secVec[j] = uDataSect;
2200  uDataSect = temp;
2201  }
2202  }
2203 
2204  secVec.push_back(uDataSect);
2205  }
2206  }
2207 
2208  // ------------- create DataMemory for each address space
2209  for (std::map<AddressSpace*, std::vector<UDataSection*> >::iterator iter =
2210  memories.begin();
2211  iter != memories.end(); iter++) {
2212 
2213  AddressSpace& aSpace = *(*iter).first;
2214  std::vector<UDataSection*>& secVec = (*iter).second;
2215 
2216  DataMemory* newDataMem = new DataMemory(aSpace);
2217 
2218  for (int i = 0; i < static_cast<int>(secVec.size()); i++) {
2219  UDataSection* currSect = secVec[i];
2220 
2221  if (currSect->type() == Section::ST_UDATA) {
2222  // ------- create uninitializes data definition
2223  DataDefinition* newDef =
2224  new DataDefinition(
2225  Address(currSect->startingAddress(), aSpace),
2226  static_cast<int>(currSect->lengthInMAUs()),
2227  prog.targetProcessor().isLittleEndian());
2228 
2229  newDataMem->addDataDefinition(newDef);
2230 
2231  } else {
2232  // -------- create initialized data definition
2233  assert(currSect->type() == Section::ST_DATA ||
2234  currSect->type() == Section::ST_LEDATA);
2235 
2236  // find relocation section for this section
2237  RelocSection* relocs = NULL;
2238 
2239  for (int j = 0;
2240  j < static_cast<int>(
2241  binary_->sectionCount(Section::ST_RELOC)); j++) {
2242 
2243  RelocSection* temp =
2244  dynamic_cast<RelocSection*>(
2245  binary_->section(Section::ST_RELOC, j));
2246 
2247  if (temp->referencedSection() == currSect) {
2248  // found it!
2249  relocs = temp;
2250  break;
2251  }
2252  }
2253 
2254  // ------- create relocated definitions.
2255  if (relocs != NULL) {
2256 
2257  DataSection* refSect = dynamic_cast<DataSection*>(
2258  relocs->referencedSection());
2259 
2260  for (int j = 0;
2261  j < static_cast<int>(relocs->elementCount()); j++) {
2262 
2263  RelocElement* currElem =
2264  dynamic_cast<RelocElement*>(relocs->element(j));
2265 
2266  AddressSpace& dstSpace =
2267  findAddressSpace(currElem->aSpace());
2268 
2269  // resolve location address of relocation
2270  Chunk* srcChunk =
2271  dynamic_cast<Chunk*>(currElem->location());
2272 
2273  int sourceAddress =
2274  refSect->startingAddress() +
2275  refSect->chunkToMAUIndex(srcChunk);
2276 
2277  Address startAddr(sourceAddress, aSpace);
2278 
2279  // resolve mau size of address field
2280  int mauSize = currElem->size() / aSpace.width();
2281 
2282  // field size must be multiple of mau of address space
2283  assert(currElem->size() % aSpace.width() == 0);
2284 
2285  if (&dstSpace == adfInstrASpace_) {
2286  // ------- destination is instruction
2287 
2288  InstructionElement* tpefInstr =
2289  dynamic_cast<InstructionElement*>(
2290  currElem->destination());
2291 
2292  assert(tpefInstr != NULL);
2293 
2294  // get the instruction reference of destination
2295  InstructionReference instrRef =
2297  createReference(*instructionMap_[tpefInstr]);
2298 
2299  DataInstructionAddressDef* newDataDef =
2301  startAddr, mauSize, instrRef,
2302  prog.targetProcessor().isLittleEndian());
2303 
2304  newDataMem->addDataDefinition(newDataDef);
2305 
2306  } else {
2307  // ------- destination is chunk
2308 
2309  // find dst section of destination() chunk
2310  Chunk* dstChunk =
2311  dynamic_cast<Chunk*>(currElem->destination());
2312 
2313  assert(dstChunk != NULL);
2314 
2315  UDataSection* dstSect = NULL;
2316 
2317  std::vector<UDataSection*>& dstSecs =
2318  memories[&dstSpace];
2319 
2320  for (int k = 0;
2321  k < static_cast<int>(dstSecs.size()); k++) {
2322 
2323  UDataSection* temp = dstSecs[k];
2324 
2325  if (temp->belongsToSection(dstChunk)) {
2326  // dst section found!
2327  dstSect = temp;
2328  break;
2329  }
2330  }
2331 
2332  assert(dstSect != NULL);
2333 
2334  Address dstAddr(
2335  dstSect->startingAddress() +
2336  dstSect->chunkToMAUIndex(dstChunk),
2337  dstSpace);
2338 
2339  DataAddressDef* newDataDef =
2340  new DataAddressDef(
2341  startAddr, mauSize, dstAddr,
2342  prog.targetProcessor().isLittleEndian());
2343 
2344  newDataMem->addDataDefinition(newDataDef);
2345 
2346  }
2347  }
2348  }
2349 
2350  // ----- create all the rest of the init data
2351 
2352  // find start and end addresses of current section
2353  std::pair<int, int> wholeSection(currSect->startingAddress(),
2354  currSect->lengthInMAUs());
2355 
2356  std::vector<std::pair <int, int> > dataAreas;
2357  dataAreas.push_back(wholeSection);
2358 
2359  // split area if there is some data area definitions in the
2360  // same addresses with current section
2361  for (int k = 0; k < newDataMem->dataDefinitionCount(); k++) {
2362  DataDefinition& currDef = newDataMem->dataDefinition(k);
2363 
2364  int prevIndex = dataAreas.size()-1;
2365  std::pair<int, int>& lastArea = dataAreas[prevIndex];
2366 
2367  // if data definition is inside this section, it splits
2368  // the last data area definition
2369  if (static_cast<int>(currDef.startAddress().location()) >=
2370  lastArea.first &&
2371  static_cast<int>(currDef.startAddress().location()) <
2372  lastArea.first + lastArea.second) {
2373 
2374  int lastAreaStart = lastArea.first;
2375  int lastAreaEnd = currDef.startAddress().location();
2376 
2377  int newAreaStart =
2378  currDef.startAddress().location() +
2379  currDef.size();
2380 
2381  int newAreaEnd = lastArea.first + lastArea.second;
2382 
2383  // new area starts after this data definition
2384  std::pair<int, int> newArea(
2385  newAreaStart, newAreaEnd - newAreaStart);
2386 
2387  // if the last area is no area anymore
2388  lastArea.second = lastAreaEnd - lastAreaStart;
2389 
2390  if (lastArea.second == 0) {
2391  dataAreas.pop_back();
2392  }
2393 
2394  if (newArea.second != 0) {
2395  dataAreas.push_back(newArea);
2396  }
2397  }
2398  }
2399 
2400  DataSection* dataSect = dynamic_cast<DataSection*>(currSect);
2401  assert(dataSect != NULL);
2402 
2403  // write out collected initialized data areas
2404  for (unsigned int k = 0; k < dataAreas.size(); k++) {
2405 
2406  std::pair<int, int>& currArea = dataAreas[k];
2407  std::vector<MinimumAddressableUnit> initData;
2408 
2409  int mauIndex =
2410  currArea.first - currSect->startingAddress();
2411 
2412  assert(mauIndex >= 0);
2413 
2414  assert(mauIndex + currArea.second <=
2415  static_cast<int>(currSect->lengthInMAUs()));
2416 
2417  bool allZeros = true;
2418  for (int l = 0; l < currArea.second; l++) {
2419  if(dataSect->MAU(mauIndex + l) != 0) {
2420  allZeros = false;
2421  }
2422  }
2423 
2424  DataDefinition* newDataDef = NULL;
2425 
2426  if (allZeros) {
2427  newDataDef = new DataDefinition(
2428  Address(currArea.first, aSpace),
2429  currArea.second,
2431  NULL, true);
2432  } else {
2433  for (int l = 0; l < currArea.second; l++) {
2434  initData.push_back(dataSect->MAU(mauIndex++));
2435  }
2436 
2437  newDataDef = new DataDefinition(
2438  Address(currArea.first, aSpace),
2439  initData, prog.targetProcessor().isLittleEndian());
2440  }
2441 
2442  newDataMem->addDataDefinition(newDataDef);
2443  }
2444  }
2445  }
2446 
2447  prog.addDataMemory(newDataMem);
2448  }
2449 }
2450 
2451 /**
2452  * Checks if move is start point of function.
2453  *
2454  * @param instructionElement Intruction element which should be checked.
2455  * @return True if instruction in parameter is function start point.
2456  */
2457 bool
2459  const InstructionElement &instructionElement) const {
2460  return MapTools::containsKey(
2461  functionStartPositions_, &instructionElement);
2462 }
2463 
2464 /**
2465  * Returns name of function, that starts, from given instruction element.
2466  *
2467  * @param instructionElement Starting element, of procedure.
2468  * @return Function name string.
2469  */
2470 std::string
2472  const InstructionElement &instructionElement) const {
2473  if (MapTools::containsKey(functionStartPositions_, &instructionElement)) {
2474  return MapTools::valueForKey<FunctionStart*>(
2475  functionStartPositions_, &instructionElement)->name();
2476  } else {
2477  return "unknownFunctionName";
2478  }
2479 }
2480 }
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
TPEF::CodeSection::element
virtual InstructionElement * element(Word index) const
Definition: CodeSection.cc:88
TTAMachine::Guard
Definition: Guard.hh:55
TTAProgram::TPEFProgramFactory::findPort
TTAMachine::Port & findPort(const TTAMachine::Bus &bus, const TTAMachine::Unit &portParent, std::string tpefOpName="", int tpefOpIndex=0) const
Definition: TPEFProgramFactory.cc:1237
UniversalMachine::integerRegisterFile
UnboundedRegisterFile & integerRegisterFile() const
Definition: UniversalMachine.cc:234
ASpaceElement.hh
UniversalMachine::dataAddressSpace
TTAMachine::AddressSpace & dataAddressSpace() const
Definition: UniversalMachine.cc:293
TerminalInstructionReference.hh
TTAProgram
Definition: Estimator.hh:65
UniversalMachine::booleanRegisterFile
TTAMachine::RegisterFile & booleanRegisterFile() const
Definition: UniversalMachine.cc:221
TTAProgram::TPEFProgramFactory::ImmediateKey
std::pair< Word, Word > ImmediateKey
Definition: TPEFProgramFactory.hh:107
TTAProgram::Program
Definition: Program.hh:63
TTAProgram::Instruction::addMove
void addMove(std::shared_ptr< Move > move)
Definition: Instruction.cc:147
TPEF::ResourceSection::hasResource
bool hasResource(ResourceElement::ResourceType aType, HalfWord anId) const
Definition: ResourceSection.cc:120
BinaryReader.hh
InstructionAddress
UInt32 InstructionAddress
Definition: BaseType.hh:175
TPEF::InstructionElement::isMove
bool isMove() const
TPEF::RawSection::lengthInMAUs
virtual Word lengthInMAUs() const
Definition: Section.cc:285
TPEF::Section::aSpace
ASpaceElement * aSpace() const
TPEF::DataSection::MAU
virtual MinimumAddressableUnit MAU(Word index) const
Definition: DataSection.cc:125
TTAProgram::TPEFProgramFactory::canDestinationBeAssigned
bool canDestinationBeAssigned(SocketAllocation &alloc, std::map< TTAMachine::Socket *, std::vector< SocketAllocation * > > &fixedSockets) const
Definition: TPEFProgramFactory.cc:1667
TTAMachine::Socket::port
Port * port(int index) const
Definition: Socket.cc:266
TTAMachine::Socket::portCount
int portCount() const
TPEF::ResourceSection
Definition: ResourceSection.hh:47
TTAProgram::DataDefinition
Definition: DataDefinition.hh:52
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TPEF::MoveElement::isGuarded
bool isGuarded() const
TTAProgram::TPEFProgramFactory::CacheKey
Cache key for resources that are accessed from MOM(s)
Definition: TPEFProgramFactory.hh:191
TPEF::TPEFTools::addressSpaceName
std::string addressSpaceName(const ASpaceElement &aSpace) const
Definition: TPEFTools.cc:96
TTAMachine::PortGuard::port
FUPort * port() const
TTAProgram::Terminal::index
virtual int index() const
Definition: Terminal.cc:274
TTAProgram::TPEFProgramFactory::findInstrTemplate
TTAMachine::InstructionTemplate & findInstrTemplate(const TPEF::ResourceSection &resources, ImmediateVector &longImmediates, MoveVector &moves) const
Definition: TPEFProgramFactory.cc:1502
TTAProgram::TPEFProgramFactory::adfInstrASpace_
TTAMachine::AddressSpace * adfInstrASpace_
Instruction address space of machine.
Definition: TPEFProgramFactory.hh:281
TTAProgram::Address
Definition: Address.hh:51
TTAProgram::DataDefinition::startAddress
virtual Address startAddress() const
Definition: DataDefinition.cc:129
TTAProgram::FunctionStart::FunctionStart
FunctionStart(std::string aName)
Definition: TPEFProgramFactory.cc:99
TPEF::ImmediateElement::sLongWord
SignedLongWord sLongWord() const
TPEF::ImmediateElement::destinationIndex
Byte destinationIndex() const
CodeSymElement.hh
TTAProgram::DataDefinition::size
virtual int size() const
Definition: DataDefinition.cc:211
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
TTAProgram::Scope::addDataLabel
virtual void addDataLabel(const DataLabel *dataLabel)
Definition: Scope.cc:415
TTAProgram::Program::startAddress
Address startAddress() const
Definition: Program.cc:286
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
TTAProgram::Terminal::isAddress
virtual bool isAddress() const
Definition: Terminal.cc:75
TPEF::InstructionElement
Definition: InstructionElement.hh:77
TTAProgram::TPEFProgramFactory::instructionMap_
std::map< TPEF::InstructionElement *, Instruction * > instructionMap_
Program instruction by TPEF instruction element.
Definition: TPEFProgramFactory.hh:303
UniversalMachine::universalBus
TTAMachine::Bus & universalBus() const
Definition: UniversalMachine.cc:306
TPEF::Binary
Definition: Binary.hh:49
TTAProgram::Instruction
Definition: Instruction.hh:57
TPEF::MoveElement::MF_UNIT
@ MF_UNIT
Function unit.
Definition: MoveElement.hh:56
TTAProgram::TPEFProgramFactory::longInstructionImmediates_
std::list< std::shared_ptr< Immediate > > longInstructionImmediates_
Long immediates whose value terminals refers to instructions.
Definition: TPEFProgramFactory.hh:293
Procedure.hh
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
TPEF::Section::type
virtual SectionType type() const =0
Returns SectioType of actual section instance.
TTAProgram::TPEFProgramFactory::~TPEFProgramFactory
virtual ~TPEFProgramFactory()
Definition: TPEFProgramFactory.cc:166
TPEF::MoveElement::FieldType
FieldType
Definition: MoveElement.hh:52
TTAMachine::ImmediateUnit::signExtends
bool signExtends() const
Definition: ImmediateUnit.hh:62
AddressSpace.hh
TTAProgram::TPEFProgramFactory::createLabels
void createLabels(Program &prog)
Definition: TPEFProgramFactory.cc:2036
MapTools::deleteAllValues
static void deleteAllValues(MapType &aMap)
TTAMachine::InstructionTemplate::numberOfDestinations
virtual int numberOfDestinations() const
Definition: InstructionTemplate.cc:300
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
TPEF::ResourceElement
Definition: ResourceElement.hh:47
TTAProgram::TPEFProgramFactory::TPEFProgramFactory
TPEFProgramFactory(const TPEF::Binary &aBinary, const TTAMachine::Machine &aMachine)
Definition: TPEFProgramFactory.cc:137
Exception::setCause
void setCause(const Exception &cause)
Definition: Exception.cc:75
TTAProgram::Address::space
const TTAMachine::AddressSpace & space() const
TTAProgram::DataMemory::dataDefinitionCount
int dataDefinitionCount() const
Definition: DataMemory.cc:129
UniversalMachine::doubleRegisterFile
UnboundedRegisterFile & doubleRegisterFile() const
Definition: UniversalMachine.cc:251
DataSymElement.hh
TPEF::ImmediateElement::word
Word word() const
TPEF::InstructionElement::annotation
InstructionAnnotation * annotation(Word index) const
TTAProgram::TPEFProgramFactory::SocketAllocation
Definition: TPEFProgramFactory.hh:240
TPEF::TPEFTools::hasRelocation
bool hasRelocation(const SectionElement &element) const
Definition: TPEFTools.cc:107
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
TPEF::DataSection
Definition: DataSection.hh:52
TPEF::ImmediateElement
Definition: ImmediateElement.hh:49
TPEF::Binary::section
Section * section(Word index) const
TPEF::StringSection::chunk2String
std::string chunk2String(const Chunk *chunk) const
Definition: StringSection.cc:72
TPEF::InstructionElement::isImmediate
bool isImmediate() const
TPEF::RelocSection::referencedSection
Section * referencedSection() const
TPEF::ASpaceElement::MAU
Byte MAU() const
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
TPEF::MoveElement::sourceIndex
HalfWord sourceIndex() const
TPEF::Binary::sectionCount
Word sectionCount() const
TPEF::ResourceSection::findResource
ResourceElement & findResource(ResourceElement::ResourceType aType, HalfWord anId) const
Definition: ResourceSection.cc:91
TPEF::MoveElement::isGuardInverted
bool isGuardInverted() const
TTAMachine::Socket::Direction
Direction
Definition: Socket.hh:58
TTAProgram::TPEFProgramFactory::addToCache
void addToCache(const CacheKey &key, Terminal *cachedTerm) const
Definition: TPEFProgramFactory.cc:1968
Byte
unsigned char Byte
Definition: BaseType.hh:116
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Socket::direction
Direction direction() const
TTAProgram::TPEFProgramFactory::createDataMemories
void createDataMemories(Program &prog)
Definition: TPEFProgramFactory.cc:2176
TPEF::SymbolElement::binding
SymbolBinding binding() const
DataInstructionAddressDef.hh
TPEF::RelocElement::size
Byte size() const
DataAddressDef.hh
TTAProgram::Terminal::address
virtual Address address() const
Definition: Terminal.cc:210
ImmediateElement.hh
DataLabel.hh
TPEF::RelocSection
Definition: RelocSection.hh:47
Conversion::toString
static std::string toString(const T &source)
NotAvailable
Definition: Exception.hh:728
TTAProgram::Program::InstructionVector
std::vector< Instruction * > InstructionVector
Vector for instructions.
Definition: Program.hh:66
TPEF::MoveElement::bus
HalfWord bus() const
TPEF::Section
Definition: Section.hh:64
TPEF::MoveElement::MF_RF
@ MF_RF
Register file.
Definition: MoveElement.hh:54
TPEF::ImmediateElement::longWord
LongWord longWord() const
TPEF::StringSection
Definition: StringSection.hh:48
TTAProgram::TPEFProgramFactory::createInstruction
Instruction * createInstruction(const TPEF::ResourceSection &resources, MoveVector &moveElements, ImmediateVector &longImmediates, ImmediateMap &immElements) const
Definition: TPEFProgramFactory.cc:512
TPEF::SymbolElement::section
Section * section() const
TTAProgram::TPEFProgramFactory::getFromCache
Terminal * getFromCache(const CacheKey &key) const
Definition: TPEFProgramFactory.cc:1951
SimValue
Definition: SimValue.hh:96
TerminalRegister.hh
TPEF::RawSection::belongsToSection
bool belongsToSection(const Chunk *chunk) const
Definition: Section.cc:238
TPEF::SymbolElement::name
Chunk * name() const
TTAMachine::Machine::isLittleEndian
bool isLittleEndian() const
Definition: Machine.hh:258
TPEF::InstructionAnnotation::payload
const std::vector< Byte > & payload() const
TTAProgram::TPEFProgramFactory::createTerminal
Terminal * createTerminal(const TPEF::ResourceSection &resources, const TTAMachine::Bus *aBus, TTAMachine::Socket::Direction direction, TPEF::MoveElement::FieldType type, HalfWord unitId, HalfWord index, const ImmediateMap *immediateMap=NULL) const
Definition: TPEFProgramFactory.cc:759
GlobalScope.hh
TPEF::ResourceElement::name
Chunk * name() const
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
TPEF::Section::link
Section * link() const
TTAProgram::ProgramAnnotation::Id
Id
the ID in TPEF is 24 bits, here enum
Definition: ProgramAnnotation.hh:52
TPEF::Section::element
SectionElement * element(Word index) const
assert
#define assert(condition)
Definition: Application.hh:86
TTAProgram::TerminalImmediate::value
virtual SimValue value() const
Definition: TerminalImmediate.cc:75
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
UniversalMachine.hh
TTAProgram::Terminal::isImmediateRegister
virtual bool isImmediateRegister() const
Definition: Terminal.cc:97
TPEF::SymbolElement::type
virtual SymbolType type() const =0
Returns type of symbol.
TPEF::DataSymElement::reference
Chunk * reference() const
Definition: DataSymElement.cc:71
TTAProgram::TPEFProgramFactory::tpefTools_
TPEF::TPEFTools tpefTools_
TPEFTools object for helper functions.
Definition: TPEFProgramFactory.hh:279
TTAProgram::Scope::addCodeLabel
virtual void addCodeLabel(const CodeLabel *codeLabel)
Definition: Scope.cc:376
TTAProgram::Program::addDataMemory
void addDataMemory(DataMemory *dataMem)
Definition: Program.cc:954
RelocSection.hh
TTAMachine::ImmediateUnit::zeroExtends
bool zeroExtends() const
Definition: ImmediateUnit.hh:63
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
SymbolSection.hh
HWOperation.hh
TTAMachine::Unit
Definition: Unit.hh:51
TTAProgram::TPEFProgramFactory::findBus
TTAMachine::Bus & findBus(const TPEF::ResourceSection &resources, HalfWord busId) const
Definition: TPEFProgramFactory.cc:972
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
TPEF::RelocElement::aSpace
ASpaceElement * aSpace() const
TPEF::MoveElement::sourceUnit
HalfWord sourceUnit() const
Instruction.hh
TPEF::Binary::type
FileType type() const
TTAProgram::FunctionStart
Definition: TPEFProgramFactory.cc:97
TTAProgram::DataMemory::addDataDefinition
void addDataDefinition(DataDefinition *dataDef)
Definition: DataMemory.cc:66
DataMemory.hh
TTAProgram::TPEFProgramFactory::findFunctionUnit
TTAMachine::FunctionUnit & findFunctionUnit(const TPEF::ResourceSection &resources, HalfWord unitId, std::string tpefOpName="") const
Definition: TPEFProgramFactory.cc:1143
UniversalFunctionUnit.hh
TPEF::SymbolSection
Definition: SymbolSection.hh:44
TPEF::ASpaceElement
Definition: ASpaceElement.hh:48
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
UniversalMachine
Definition: UniversalMachine.hh:56
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
TTAProgram::DataAddressDef
Definition: DataAddressDef.hh:45
TPEF::MoveElement::guardIndex
HalfWord guardIndex() const
TTAProgram::DataLabel
Definition: DataLabel.hh:45
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAMachine::Port
Definition: Port.hh:54
TTAProgram::TPEFProgramFactory::findAddressSpace
TTAMachine::AddressSpace & findAddressSpace(const TPEF::ASpaceElement *aSpace) const
Definition: TPEFProgramFactory.cc:1333
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
TTAProgram::TPEFProgramFactory::tpefInstrASpace_
TPEF::ASpaceElement * tpefInstrASpace_
Instruction address space element of TPEF.
Definition: TPEFProgramFactory.hh:283
Application.hh
TPEF::UDataSection
Definition: UDataSection.hh:47
TTAProgram::FunctionStart::name
std::string name() const
Definition: TPEFProgramFactory.cc:102
TPEF::MoveElement
Definition: MoveElement.hh:47
TPEF::RelocElement::destination
SectionElement * destination() const
UnboundedRegisterFile.hh
TPEF::SectionElement
Definition: SectionElement.hh:44
__func__
#define __func__
Definition: Application.hh:67
TTAProgram::TPEFProgramFactory::build
Program * build()
Definition: TPEFProgramFactory.cc:200
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
TPEF::InstructionElement::annotationCount
Word annotationCount() const
TTAMachine::Socket
Definition: Socket.hh:53
TPEF::InstructionAnnotation::id
Word id() const
RelocElement.hh
TPEF::InstructionElement::begin
bool begin() const
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
TTAProgram::TPEFProgramFactory::ImmediateVector
std::vector< TPEF::ImmediateElement * > ImmediateVector
Definition: TPEFProgramFactory.hh:110
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
TTAProgram::CodeLabel
Definition: CodeLabel.hh:49
Guard.hh
NullInstructionTemplate.hh
TTAProgram::TPEFProgramFactory::ImmediateMap
std::map< ImmediateKey, TPEF::ImmediateElement * > ImmediateMap
Definition: TPEFProgramFactory.hh:108
TTAProgram::TPEFProgramFactory::SocketAllocation::src
unsigned int src
Definition: TPEFProgramFactory.hh:248
TPEF::RawSection::bytesToMAUs
virtual Word bytesToMAUs(Word byteCount) const
Definition: Section.cc:296
TPEF::MoveElement::destinationIndex
HalfWord destinationIndex() const
TTAMachine::Unit::hasPort
virtual bool hasPort(const std::string &name) const
Definition: Unit.cc:96
TPEF::SymbolElement
Definition: SymbolElement.hh:52
MathTools::requiredBits
static int requiredBits(unsigned long int number)
TerminalFUPort.hh
TPEF::ASpaceElement::name
Chunk * name() const
TTAMachine::InstructionTemplate::supportedWidth
virtual int supportedWidth() const
Definition: InstructionTemplate.cc:427
TTAProgram::Address::location
InstructionAddress location() const
TTAProgram::TPEFProgramFactory::canSourceBeAssigned
bool canSourceBeAssigned(SocketAllocation &alloc, std::map< TTAMachine::Socket *, std::vector< SocketAllocation * > > &fixedSockets) const
Definition: TPEFProgramFactory.cc:1624
TTAProgram::TerminalAddress
Definition: TerminalAddress.hh:48
TPEF::DataSymElement
Definition: DataSymElement.hh:41
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Exception
Definition: Exception.hh:54
TPEF::MoveElement::destinationType
FieldType destinationType() const
TTAMachine::Machine::addressSpaceNavigator
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition: Machine.cc:392
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
TTAMachine::InstructionTemplate::isOneOfDestinations
virtual bool isOneOfDestinations(const ImmediateUnit &dstUnit) const
Definition: InstructionTemplate.cc:323
TPEF::CodeSection
Definition: CodeSection.hh:44
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Socket::isConnectedTo
bool isConnectedTo(const Bus &bus) const
Definition: Socket.cc:331
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TPEF::RelocElement
Definition: RelocElement.hh:51
TTAProgram::TPEFProgramFactory::SocketAllocation::move
std::shared_ptr< Move > move
Definition: TPEFProgramFactory.hh:245
TPEF::CodeSymElement::reference
InstructionElement * reference() const
Definition: CodeSymElement.cc:71
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
TPEF::MoveElement::destinationUnit
HalfWord destinationUnit() const
TTAProgram::TPEFProgramFactory::isFunctionStart
bool isFunctionStart(const TPEF::InstructionElement &instructionElement) const
Definition: TPEFProgramFactory.cc:2458
UniversalMachine::instructionAddressSpace
TTAMachine::AddressSpace & instructionAddressSpace() const
Definition: UniversalMachine.cc:280
TTAProgram::TPEFProgramFactory::functionStartPositions_
std::map< const TPEF::InstructionElement *, class FunctionStart * > functionStartPositions_
Stores information of start points of procedures that were found.
Definition: TPEFProgramFactory.hh:287
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
UniversalMachine::universalFunctionUnit
UniversalFunctionUnit & universalFunctionUnit() const
Definition: UniversalMachine.cc:205
TTAMachine::AddressSpace::width
virtual int width() const
Definition: AddressSpace.cc:155
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
TTAProgram::TPEFProgramFactory::findGuard
TTAMachine::Guard & findGuard(const TPEF::ResourceSection &resources, TTAMachine::Bus &bus, TPEF::MoveElement::FieldType type, HalfWord unitId, HalfWord index, bool isInverted) const
Definition: TPEFProgramFactory.cc:1373
TTAProgram::AnnotatedInstructionElement::addAnnotation
void addAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:63
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
TTAProgram::TPEFProgramFactory::machine_
const TTAMachine::Machine * machine_
Target machine of program.
Definition: TPEFProgramFactory.hh:274
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
TPEF::ProcedSymElement
Definition: ProcedSymElement.hh:45
TTAProgram::TPEFProgramFactory::resolveSocketAllocations
void resolveSocketAllocations(std::vector< SocketAllocation > &allocs) const
Definition: TPEFProgramFactory.cc:1711
TPEFProgramFactory.hh
TPEF::Chunk::offset
SectionOffset offset() const
TTAProgram::TPEFProgramFactory::SocketAllocation::dstSocks
std::vector< TTAMachine::Socket * > dstSocks
Definition: TPEFProgramFactory.hh:247
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
TTAMachine::Guard::isInverted
virtual bool isInverted() const
TPEF::MoveElement::guardType
FieldType guardType() const
Program.hh
TerminalImmediate.hh
Immediate.hh
TerminalAddress.hh
TTAProgram::TPEFProgramFactory::universalMachine_
UniversalMachine * universalMachine_
Universal machine of program.
Definition: TPEFProgramFactory.hh:276
TTAProgram::TPEFProgramFactory::MoveVector
std::vector< TPEF::MoveElement * > MoveVector
Definition: TPEFProgramFactory.hh:109
TTAMachine::Component::machine
virtual Machine * machine() const
TTAProgram::TPEFProgramFactory::findImmediateUnit
TTAMachine::ImmediateUnit & findImmediateUnit(const TPEF::ResourceSection &resources, Byte immUnitId) const
Definition: TPEFProgramFactory.cc:1099
InstructionReference.hh
FUPort.hh
Section.hh
ControlUnit.hh
TPEF::MoveElement::isEmpty
bool isEmpty() const
TTAProgram::Instruction::setInstructionTemplate
void setInstructionTemplate(const TTAMachine::InstructionTemplate &insTemp)
Definition: Instruction.cc:488
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
SpecialRegisterPort.hh
TTAProgram::DataMemory::dataDefinition
DataDefinition & dataDefinition(Address address) const
Definition: DataMemory.cc:79
TTAProgram::TPEFProgramFactory::seekFunctionStartPoints
void seekFunctionStartPoints()
Definition: TPEFProgramFactory.cc:1991
TTAProgram::Terminal::copy
virtual Terminal * copy() const =0
InstructionReferenceManager.hh
TTAProgram::Program::targetProcessor
TTAMachine::Machine & targetProcessor() const
Definition: Program.cc:202
BinaryStream.hh
TTAProgram::Terminal
Definition: Terminal.hh:60
TPEF::CodeSymElement
Definition: CodeSymElement.hh:46
TTAProgram::FunctionStart::name_
std::string name_
Definition: TPEFProgramFactory.cc:105
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::TPEFProgramFactory::findRegisterFile
TTAMachine::RegisterFile & findRegisterFile(const TPEF::ResourceSection &resources, HalfWord rfId) const
Definition: TPEFProgramFactory.cc:1021
TPEF::ImmediateElement::destinationUnit
Byte destinationUnit() const
TTAProgram::TPEFProgramFactory::instructionImmediates_
std::list< std::shared_ptr< Move > > instructionImmediates_
Moves whose source terminals are addresses referring to instructions.
Definition: TPEFProgramFactory.hh:290
ProcedSymElement.hh
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
program
find Finds info of the inner loops in the program
Definition: InnerLoopFinder.cc:80
TPEF::MoveElement::sourceType
FieldType sourceType() const
TTAProgram::TPEFProgramFactory::functionName
std::string functionName(const TPEF::InstructionElement &instructionElement) const
Definition: TPEFProgramFactory.cc:2471
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
Conversion::toInt
static int toInt(const T &source)
TPEF::UDataSection::type
virtual SectionType type() const
Definition: UDataSection.cc:69
MathTools.hh
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
TTAProgram::Program::globalScope
GlobalScope & globalScope()
Definition: Program.cc:180
TPEF::RelocElement::location
SectionElement * location() const
TTAProgram::DataMemory
Definition: DataMemory.hh:56
Move.hh
TTAMachine
Definition: Assembler.hh:48
Application::abortProgram
static void abortProgram() __attribute__((noreturn))
Definition: Application.cc:266
TTAMachine::ControlUnit::returnAddressPort
SpecialRegisterPort * returnAddressPort() const
Definition: ControlUnit.cc:307
TTAProgram::DataInstructionAddressDef
Definition: DataInstructionAddressDef.hh:48
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
TTAProgram::TPEFProgramFactory::SocketAllocation::srcSocks
std::vector< TTAMachine::Socket * > srcSocks
Definition: TPEFProgramFactory.hh:246
TTAProgram::TPEFProgramFactory::binary_
const TPEF::Binary * binary_
Binary that is used for creating program.
Definition: TPEFProgramFactory.hh:272
TTAProgram::TPEFProgramFactory::SocketAllocation::dst
unsigned int dst
Definition: TPEFProgramFactory.hh:249
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
TTAProgram::Program::instructionVector
InstructionVector instructionVector() const
Definition: Program.cc:1196
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
ProgramAnnotation.hh
TTAProgram::Procedure
Definition: Procedure.hh:55
TTAProgram::TPEFProgramFactory::cache_
std::map< const CacheKey, Terminal * > cache_
Cache map of terminals that are returned by different search parameters.
Definition: TPEFProgramFactory.hh:297
OperationPool.hh
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAProgram::Program::setUniversalMachine
void setUniversalMachine(UniversalMachine *umach)
Definition: Program.hh:81
DataDefinition.hh
TPEF::ImmediateElement::isInline
bool isInline() const
MathTools::requiredBitsSigned
static int requiredBitsSigned(SLongWord number)
TPEF::Section::startingAddress
AddressImage startingAddress() const
TPEF::RawSection::chunkToMAUIndex
virtual Word chunkToMAUIndex(const Chunk *chunk) const
Definition: Section.cc:341
CodeLabel.hh
TTAProgram::TPEFProgramFactory::clearCache
void clearCache() const
Definition: TPEFProgramFactory.cc:1979
TPEF::Chunk
Definition: Chunk.hh:45
CodeSection.hh
TTAProgram::TPEFProgramFactory::stringOfChunk
std::string stringOfChunk(const TPEF::Chunk *chunk, const TPEF::Section *chunkOwner) const
Definition: TPEFProgramFactory.cc:180
TPEF::MoveElement::guardUnit
HalfWord guardUnit() const
TTAMachine::ControlUnit::hasReturnAddressPort
bool hasReturnAddressPort() const
Definition: ControlUnit.cc:295
TTAMachine::InstructionTemplate::usesSlot
virtual bool usesSlot(const std::string &slotName) const
Definition: InstructionTemplate.cc:265
TTAProgram::TerminalRegister
Definition: TerminalRegister.hh:53
TTAProgram::Instruction::addImmediate
void addImmediate(std::shared_ptr< Immediate > imm)
Definition: Instruction.cc:234
TTAProgram::TPEFProgramFactory::addProcedures
void addProcedures(Program &program, const TTAMachine::AddressSpace &programASpace) const
Definition: TPEFProgramFactory.cc:344
TPEF::Section::elementCount
Word elementCount() const
TPEF
Definition: Assembler.hh:43
TTAMachine::Machine
Definition: Machine.hh:73
ContainerTools.hh
TPEF::TPEFTools::relocation
const RelocElement & relocation(const SectionElement &element) const
Definition: TPEFTools.cc:119
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50