OpenASIP  2.0
Program.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2016 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 Program.cc
26  *
27  * Implementation of Program class.
28  *
29  * @author Ari Metsähalme 2005 (ari.metsahalme-no.spam-tut.fi)
30  * @author Pekka Jääskeläinen 2006,2011,2016 (pekka.jaaskelainen-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
34 #include <string>
35 
36 #include "Program.hh"
37 #include "NullInstruction.hh"
38 #include "Procedure.hh"
39 #include "NullProcedure.hh"
40 #include "CodeLabel.hh"
41 #include "Terminal.hh"
42 #include "TerminalAddress.hh"
43 #include "Move.hh"
44 #include "InstructionReference.hh"
46 #include "NullProgram.hh"
47 #include "AddressSpace.hh"
48 #include "DataMemory.hh"
49 #include "DataDefinition.hh"
51 #include "AssocTools.hh"
52 #include "ControlUnit.hh"
53 #include "UniversalMachine.hh"
54 #include "SequenceTools.hh"
55 #include "DataLabel.hh"
56 #include "BinaryStream.hh"
57 #include "BinaryReader.hh"
58 #include "TPEFProgramFactory.hh"
59 #include "UniversalMachine.hh"
60 #include "Application.hh"
61 #include "ProgramWriter.hh"
62 #include "BinaryWriter.hh"
63 #include "TPEFWriter.hh"
64 #include "Immediate.hh"
65 #include "MathTools.hh"
67 #include "POMDisassembler.hh"
68 #include "hash_set.hh"
69 #include "GlobalScope.hh"
70 
71 using std::string;
72 
73 using namespace TTAMachine;
74 
75 namespace TTAProgram {
76 
77 /////////////////////////////////////////////////////////////////////////////
78 // Program
79 /////////////////////////////////////////////////////////////////////////////
80 
81 /**
82  * Constructor.
83  *
84  * Creates an empty program in given address space. A default value
85  * zero is used for start and entry addresses. Automatically creates
86  * an empty global scope to store all program symbols with external
87  * linkage.
88  *
89  * @param space The address space of the program.
90  */
91 Program::Program(const AddressSpace& space):
92  start_(0, space), entry_(0, space), umach_(NULL), finalized_(false),
93  instructionPerAddress_(true) {
94  globalScope_ = new GlobalScope();
96 }
97 
98 /**
99  * Deprecated.
100  *
101  * Use UniversalMachine::instance() directly.
102  */
106 }
107 
108 /**
109  * Constructor.
110  *
111  * Alternative constructor that takes the start address as a parameter.
112  *
113  * @param space The address space of the program.
114  * @param start The start address of the program.
115  */
116 Program::Program(const AddressSpace& space, Address start):
117  start_(start), entry_(0, space), umach_(NULL), finalized_(false),
118  instructionPerAddress_(true) {
119  globalScope_ = new GlobalScope();
121 }
122 
123 /**
124  * Constructor.
125  *
126  * Alternative constructor that takes the start and entry addresses as
127  * parameters.
128  *
129  * @param space The address space of the program.
130  * @param start The start address of the program.
131  * @param entry The entry address of the program.
132  */
134  const AddressSpace&, Address start, Address entry):
135  start_(start), entry_(entry), umach_(NULL), finalized_(false),
136  instructionPerAddress_(true) {
137  globalScope_ = new GlobalScope();
139 }
140 
141 /**
142  * The destructor.
143  */
145  cleanup();
146  delete globalScope_;
147  globalScope_ = NULL;
148  delete refManager_;
149  refManager_ = NULL;
150  // NOTE: we cannot delete universal machine anymore because after linking
151  // the Program to another Program, the new Program refers to the,
152  // TODO: make UniversalMachine a singleton and start hiding it from APIs.
153  // delete umach_;
154  // umach_ = NULL;
155 }
156 
157 /**
158  * Cleans up the program to a state it was at the construction.
159  */
160 void
162 
165 
166  delete globalScope_;
167  globalScope_ = NULL;
168  delete refManager_;
169  refManager_ = NULL;
170  globalScope_ = new GlobalScope();
172 }
173 
174 /**
175  * Returns the global scope of the program.
176  *
177  * @return The global scope of the program.
178  */
181  return *globalScope_;
182 }
183 
184 /**
185  * Returns the global scope of the program.
186  *
187  * Const version.
188  *
189  * @return The global scope of the program.
190  */
191 const GlobalScope&
193  return *globalScope_;
194 }
195 
196 /**
197  * Returns the target TTA processor of the program.
198  *
199  * @return The target TTA processor of the program.
200  */
201 Machine&
203  return *start_.space().machine();
204 }
205 
206 /**
207  * Returns the first procedure of the program.
208  *
209  * @return The first procedure of the prgram.
210  * @exception InstanceNotFound if there are no procedures.
211  */
212 Procedure&
214  if (procedureCount() > 0) {
215  return *procedures_.at(0);
216  } else {
217  throw InstanceNotFound(
218  __FILE__, __LINE__, __func__,
219  "There are no procedures in the program.");
220  }
221 }
222 
223 /**
224  * Returns the last procedure of the program.
225  *
226  * @return The last procedure of the prgram.
227  * @exception InstanceNotFound if there are no procedures.
228  */
229 Procedure&
231  if (procedureCount() > 0) {
232  return *procedures_.at(procedureCount() - 1);
233  } else {
234  throw InstanceNotFound(
235  __FILE__, __LINE__, __func__,
236  "There are no procedures in the program.");
237  }
238 }
239 
240 /**
241  * Returns the procedure following the given procedure.
242  *
243  * @return The procedure following the given procedure or a null procedure,
244  * if the given procedure is the last procedure in the program.
245  * @param proc The following procedure of this parameter is returned.
246  * @exception IllegalRegistration if the given procedure does not belong
247  * to this program.
248  */
249 Procedure&
250 Program::nextProcedure(const Procedure& proc) const {
251  if (!proc.isInProgram() || &proc.parent() != this) {
252  throw IllegalRegistration(
253  __FILE__, __LINE__, __func__,
254  "The procedure given in parameter doesn't "
255  "belong to this program.");
256  }
257 
258  if (&proc != &lastProcedure()) {
259  int i = 0;
260  for (; i < procedureCount(); i++) {
261  if (procedures_.at(i) == &proc) {
262  break;
263  }
264  }
265  assert(i < procedureCount() - 1);
266  return *procedures_.at(i + 1);
267 
268  } else {
269  return NullProcedure::instance();
270  }
271 }
272 
273 /**
274  * Returns the start (lowest) address of the program.
275  *
276  * The start address of the program is not necessarily the lowest address of
277  * the instruction address space.
278  *
279  * @note Preserving this value is not implemented in TPEFProgramFactory
280  * and ProgramWriter, however implementation of property is already
281  * specified in TPEF specs.
282  *
283  * @return The start (lowest) address of the program.
284  */
285 Address
287  return start_;
288 }
289 
290 /**
291  * Sets the start (lowest) address of the program.
292  *
293  * The start address of the program is not necessarily the lowest address of
294  * the instruction address space. Relocates instructions to start from the
295  * address.
296  *
297  * @note Preserving this value is not implemented in TPEFProgramFactory
298  * and ProgramWriter, however implementation of property is already
299  * specified in TPEF specs.
300  *
301  * @param start The start (lowest) address of the program.
302  */
303 void
305 
306  start_ = start;
307 
308  // move procedures before the new starting address
309  if (procedureCount() > 0 &&
310  firstProcedure().startAddress().location() < start_.location()) {
312  firstProcedure(),
313  start_.location() - firstProcedure().startAddress().location());
314  }
315 }
316 
317 /**
318  * Returns the address of the program entry point.
319  *
320  * The entry point is not necessarily the instruction of the program with
321  * the lowest address.
322  *
323  * @note Preserving this value is not implemented in TPEFProgramFactory
324  * and ProgramWriter, however implementation of property is already
325  * specified in TPEF specs.
326  *
327  * @return The address of the program entry point.
328  */
329 Address
331  return entry_;
332 }
333 
334 /**
335  * Sets the entry address of the program.
336  *
337  * @note Preserving this value is not implemented in TPEFProgramFactory
338  * and ProgramWriter, however implementation of property is already
339  * specified in TPEF specs.
340  */
341 void
343  entry_ = address;
344 }
345 
346 /**
347  * Returns the first instruction of the program.
348  *
349  * @return The first instruction of the program.
350  * @exception InstanceNotFound There is no instructions in program.
351  */
354  if (!procedures_.empty()) {
355  return firstProcedure().firstInstruction();
356  } else {
357  throw InstanceNotFound(
358  __FILE__, __LINE__, __func__,
359  "There is no instructions in the program.");
360  }
361 }
362 
363 /**
364  * Returns the instruction at a given address.
365  *
366  * The address space of the address is implied, since there is only
367  * one address space for instructions.
368  *
369  * @param address The address of the instruction.
370  * @exception KeyNotFound if given address is illegal.
371  * @return The instruction at the given address.
372  */
375  for (ProcIter iter = procedures_.begin(); iter != procedures_.end();
376  iter++) {
377 
378  if ((*iter)->startAddress().location() <= address &&
379  (*iter)->endAddress().location() > address) {
380  return (*iter)->instructionAt(address);
381  }
382  }
383 
384  throw KeyNotFound(
385  __FILE__, __LINE__, __func__,
386  "No instruction at address: " +
387  Conversion::toString(address));
388 }
389 
390 /**
391  * Returns the next instruction in the instruction stream.
392  *
393  * @return The next instruction in the instruction stream or a special
394  * null instruction if the given instruction is the last instruction
395  * of the program.
396  *
397  * @exception IllegalRegistration If given instruction does not belong
398  * to the program.
399  * @note This method is very slow, do not use it for traversing the
400  * whole program!
401  */
404  if (!ins.isInProcedure() || !ins.parent().isInProgram() ||
405  &ins.parent().parent() != this) {
406 
407  throw IllegalRegistration(
408  __FILE__, __LINE__, __func__,
409  "Instruction in parameter doesn't belong to this program.");
410  }
411 
412  unsigned int insAddress = ins.address().location();
413 
414  // Check first the basic case of having the next instruction in the same
415  // procedure. Find the instruction and return its next iterator.
416  Instruction* nextInstr = &ins.parent().nextInstruction(ins);
417  if (nextInstr != &NullInstruction::instance())
418  return *nextInstr;
419 
420  ProcIter iter = procedures_.begin();
421  while (iter != procedures_.end()) {
422 
423  // if the current instruction address fits procedure's
424  // address space
425  if ((*iter)->startAddress().location() <= insAddress &&
426  (*iter)->endAddress().location() > insAddress) {
427 
428  // return next instruction, if it's in the same procedure
429  if ((*iter)->hasNextInstruction(ins)) {
430  return (*iter)->nextInstruction(ins);
431 
432  // otherwise find the next non-empty procedure and return
433  // its first instruction
434  } else {
435  iter++;
436  while (iter != procedures_.end()) {
437  if ((*iter)->instructionCount() != 0) {
438  return (*iter)->instructionAt(
439  (*iter)->startAddress().location());
440  }
441  iter++;
442  }
443 
444  // if no non-empty procedures found, return null instruction
445  return NullInstruction::instance();
446  }
447  }
448  iter++;
449  }
450 
451  // no procedure where current instruction fits was found
452  // (should throw exception?)
453  return NullInstruction::instance();
454 }
455 
456 /**
457  * Returns the last instruction of the program.
458  *
459  * @return The last instruction of the program.
460  * @exception InstanceNotFound There is no instructions in the program.
461  */
464  if (!procedures_.empty()) {
465  return lastProcedure().lastInstruction();
466  } else {
467  throw InstanceNotFound(
468  __FILE__, __LINE__, __func__,
469  "There is no instructions in the program.");
470  }
471 }
472 
473 /**
474  * Returns a move at given location, counting from beginning, zero
475  * @param number zero-beginning count of move's location
476  * @return a reference to the found move
477  * @exception KeyNotFound if the move wasn't found at the given location
478  */
479 const TTAProgram::Move&
480 Program::moveAt(int number) const {
481  if (number < 0 || number >= static_cast<int>(moves_.size())) {
482  throw KeyNotFound(__FILE__, __LINE__, __FUNCTION__,
483  "Move not found at location: " + Conversion::toString(number));
484  }
485  return *moves_.at(number);
486 }
487 
488 /**
489  * Returns the total count of moves used in the program
490  *
491  * @return the total count of moves used in the program
492  */
493 int
495  return static_cast<int>(moves_.size());
496 }
497 
498 /**
499  * Returns the procedure at a given index in the container of procedures.
500  *
501  * This method is for quickly traversing through all the procedures within
502  * time critical loops.
503  *
504  * @param index The procedure index in the list of procedures.
505  * @return The Procedure at the given index.
506  */
507 const Procedure&
508 Program::procedureAtIndex(int index) const {
509  return *procedures_.at(index);
510 }
511 
512 /**
513  * Insert the given procedure as the last procedure of the program.
514  *
515  * The ownership of the procedure will be passed to the program. Labels
516  * must be added explicitely by client because only it knows the scope
517  * where to add the labels.
518  *
519  * @param proc The procedure to be inserted.
520  * @exception IllegalRegistration if the procedure belongs to another
521  * program.
522  */
523 void
525  if (proc->isInProgram()) {
526  throw IllegalRegistration(
527  __FILE__, __LINE__, __func__,
528  "Procedure is already in program.");
529  } else {
530 
531  proc->setParent(*this);
532  if (!procedures_.empty()) {
533  proc->setStartAddress(procedures_.back()->endAddress());
534  } else {
535  proc->setStartAddress(start_);
536  }
537 
538  procedures_.push_back(proc);
539  }
540 }
541 
542 /**
543  * Insert the given instruction as the instruction of the last
544  * procedure of the program.
545  *
546  * The ownership of the instruction will be passed to the procedure in which
547  * the instruction is inserted.
548  *
549  * @param ins The instruction to be inserted.
550  * @exception IllegalRegistration if the instruction belongs to a
551  * procedure or there are no procedures in the program.
552  */
553 void
555  if (procedures_.empty()) {
556  throw IllegalRegistration(
557  __FILE__, __LINE__, __func__,
558  "No procedures in the program.");
559  }
560 
561  // add all moves of an instruction to the move list
562  for (int i = 0; i < ins->moveCount(); ++i) {
563  moves_.push_back(&ins->move(i));
564  }
565 
566  if (!ins->isInProcedure()) {
567  procedures_.back()->add(ins);
568  } else {
569  throw IllegalRegistration(
570  __FILE__, __LINE__, __func__,
571  "Instruction already belongs to a procedure.");
572  }
573 }
574 
575 /**
576  * Moves the given procedure and its succeeding procedures the given
577  * count of instructions.
578  *
579  * @note If the given count is negative, does not perform any checking for
580  * overlapping procedures, thus the relocated procedure might end up
581  * sharing instruction indices with the preceeding procedure,
582  * which means a corrupted program.
583  *
584  * @param proc The procedure to move.
585  * @param howMuch How many instructions the procedure should be moved.
586  */
587 void
588 Program::moveProcedure(Procedure& proc, int howMuch) {
589  unsigned int index;
590  // skip procedures before given procedure
591  for (index = 0; index < procedures_.size(); index++) {
592  if (procedures_[index] == &proc) {
593  break;
594  }
595  }
596  // only update procedures after.
597  for (;index < procedures_.size(); index++) {
598  Procedure* p2 = procedures_[index];
599  UIntWord oldAddr = p2->startAddress().location();
600  p2->setStartAddress(Address(oldAddr + howMuch, start_.space()));
601  }
602 }
603 
604 /**
605  * Returns the number of procedures in the program.
606  *
607  * @return The number of procedures in the program.
608  */
609 int
611  return procedures_.size();
612 }
613 
614 /**
615  * Returns the procedure at the given index.
616  *
617  * @param index The position index.
618  * @return The procedure at the given index.
619  * @exception OutOfRange if the index is out of range.
620  */
621 Procedure&
622 Program::procedure(int index) const {
623  if (index >= 0 &&
624  static_cast<unsigned int>(index) < procedures_.size()) {
625  return *procedures_.at(index);
626  } else {
627  throw OutOfRange(
628  __FILE__, __LINE__, __func__,
629  "There is no procedure by index: " +
630  Conversion::toString(index));
631  }
632 }
633 
634 /**
635  * Returns the procedure at the given index.
636  *
637  * @param index The position index.
638  * @return The procedure at the given index.
639  * @exception OutOfRange if the index is out of range.
640  */
641 Procedure&
642 Program::operator[](size_t index) {
643  return *procedures_[index];
644 }
645 
646 /**
647  * Returns the procedure with the given name.
648  *
649  * @param name The procedure name.
650  * @return The procedure with given name.
651  * @exception KeyNotFound if the procedure cannot be found.
652  */
653 Procedure&
654 Program::procedure(const std::string& name) const {
655  ProcList::const_iterator i = procedures_.begin();
656  while (i != procedures_.end()) {
657  if ((*i)->name() == name) {
658  return *(*i);
659  }
660  ++i;
661  }
662 
663  throw KeyNotFound(
664  __FILE__, __LINE__, __func__,
665  "No procedure found with name: " +
666  name);
667 }
668 
669 /**
670  * Returns true in case the program has a procedure with the given name.
671  */
672 bool
673 Program::hasProcedure(const std::string& name) const {
674  ProcList::const_iterator i = procedures_.begin();
675  while (i != procedures_.end()) {
676  if ((*i)->name() == name) {
677  return true;
678  }
679  ++i;
680  }
681  return false;
682 }
683 
684 /**
685  * Return the instruction reference manager.
686  */
689  return *refManager_;
690 }
691 
692 /**
693  * Assignment operator.
694  *
695  * Replaces the contents of this program with the given program.
696  *
697  * @param newProgram The Program instance to be assigned
698  * @return The assigned Program instance.
699  */
700 Program&
701 Program::operator=(const Program& newProgram) {
702  copyFrom(newProgram);
703  return *this;
704 }
705 
706 /**
707  * Creates an exact copy of the program.
708  *
709  * References to external object models will remain untouched.
710  *
711  * @return An exact copy of the program.
712  */
713 Program*
714 Program::copy() const {
715 
716  Program* newProgram = new Program(
717  startAddress().space(), startAddress(), entryAddress());
718 
719  newProgram->copyFrom(*this);
720  return newProgram;
721 }
722 
723 /**
724  * Copies data from another program to itself.
725  *
726  * References to external object models will remain untouched. The old data
727  * is cleaned first. this->copyFrom(another) is equivalent to *this = another.
728  *
729  * @return source The other program to copy from.
730  */
731 void
732 Program::copyFrom(const Program& source) {
733 
734  // cleanup the old data first
735  cleanup();
736 
737  for (int k = 0; k < source.procedureCount(); k++) {
738  Procedure& proc = source.procedure(k);
739  Procedure* newProc =
740  new Procedure(
741  proc.name(), proc.startAddress().space(),
742  proc.startAddress().location());
743  addProcedure(newProc);
744 
745  for (int j = 0; j < proc.instructionCount(); j++) {
746  Instruction &ins = proc.instructionAtIndex(j);
747 
748  Instruction* newIns = ins.copy();
749  newProc->add(newIns);
750  }
751  }
752 
754  copyDataMemoriesFrom(source);
755 
756  // set addresses
757  setStartAddress(source.startAddress());
758  setEntryAddress(source.entryAddress());
759 
760  delete globalScope_;
761  globalScope_ = dynamic_cast<GlobalScope*>(
762  source.globalScopeConst().copyAndRelocate(*this));
763 
764 }
765 
766 /**
767  * Fix instruction references to point to the corresponding instructions
768  * of this Program.
769  *
770  * This should be called after copying procedures from
771  * other programs to transform the instruction references to
772  * point to the current program instead of the old one.
773  */
774 void
776  for (int k = 0; k < procedureCount(); k++) {
777  Procedure& proc = procedure(k);
778  for (int j = 0; j < proc.instructionCount(); j++) {
779  Instruction& ins = proc.instructionAtIndex(j);
780 
781  // sources of all moves.
782  for (int i = 0; i < ins.moveCount(); i++) {
783  Terminal& source = ins.move(i).source();
784 
785  if (source.isInstructionAddress()) {
786  Instruction& oldRefIns =
788 
789  // Fix the reference via
790  // a procedure offset to not break references
791  // inside Procedures copied from another Program
792  InstructionAddress procStartAddr =
793  procedure(dynamic_cast<Procedure&>(oldRefIns.parent()).name()).
795 
796  Instruction& newRefIns =
798  procStartAddr +
799  oldRefIns.address().location() -
800  oldRefIns.parent().startAddress().location());
801 
802  InstructionReference newRef =
804  newRefIns);
805  source.setInstructionReference(newRef);
806  }
807  }
808  // values of all immediates
809  for (int i = 0; i < ins.immediateCount(); i++) {
810  Terminal& value = ins.immediate(i).value();
811  if (value.isInstructionAddress()) {
812 
813  Instruction& oldRefIns =
815 
816 
817  InstructionAddress procStartAddr =
818  procedure(dynamic_cast<Procedure&>(oldRefIns.parent()).name()).
820 
821  Instruction& newRefIns =
823  procStartAddr +
824  oldRefIns.address().location() -
825  oldRefIns.parent().startAddress().location());
826 
827  InstructionReference newRef =
829  newRefIns);
830  value.setInstructionReference(newRef);
831  }
832  }
833  }
834  }
835 }
836 
837 /**
838  * Copy data memories from source program to destination and fixes
839  * data->code references to use InstructionReferenceManager of the
840  * instance.
841  *
842  * @param srcProg Program from which data is copied.
843  */
844 void
846 
847  // copy data memories
848  for (int i = 0; i < srcProg.dataMemoryCount(); i++) {
849  DataMemory& currMem = srcProg.dataMemory(i);
850 
851  DataMemory* newDataMem = new DataMemory(currMem.addressSpace());
852 
853  for (int j = 0; j < currMem.dataDefinitionCount(); j++) {
854  DataDefinition& currDef = currMem.dataDefinition(j);
855 
856  DataDefinition* newDef = NULL;
857 
858  if (currDef.isInstructionAddress()) {
859  Instruction& dstInstr = instructionAt(
860  currDef.destinationAddress().location());
861 
862  InstructionReference dstRef =
864  dstInstr);
865 
866  newDef = new DataInstructionAddressDef(
867  currDef.startAddress(), currDef.size(), dstRef,
868  targetProcessor().isLittleEndian());
869 
870  } else {
871  newDef = currDef.copy();
872  }
873 
874  newDataMem->addDataDefinition(newDef);
875  }
876 
877  addDataMemory(newDataMem);
878  }
879 }
880 
881 /**
882  * Remove procedure from the program.
883  *
884  * The procedure becomes independent (it is not deleted). All
885  * instructions following the removed procedure are relocated
886  * appropriately. All code labels attached to the removed procedure
887  * are deleted from the Program.
888  *
889  * @note Possible references to instructions in this procedure elsewhere
890  * in the program are not automatically fixed! It's a responsibility of
891  * the caller to fix the Program back to a consistent state.
892  *
893  * @todo Copy the deleted CodeLabels to the removed procedure's own
894  * Scope objects.
895  *
896  * @param proc Procedure to remove.
897  * @exception IllegalRegistration If procedure does not belong to the
898  * program.
899  */
900 void
902  if (&proc.parent() != this) {
903  throw IllegalRegistration(
904  __FILE__, __LINE__, __func__,
905  "Procedure doesn't belong to this program.");
906  }
907 
908  const InstructionAddress firstAddress = proc.startAddress().location();
909  const InstructionAddress lastAddress = proc.endAddress().location() - 1;
910 
911  for (InstructionAddress addr = firstAddress;
912  addr <= lastAddress;
913  ++addr) {
914 
916  }
917 
918  if (&proc != &lastProcedure()) {
920  nextProcedure(proc),
921  proc.startAddress().location() - proc.endAddress().location());
922  }
923 
924  for (ProcList::iterator iter = procedures_.begin();
925  iter != procedures_.end(); iter++) {
926 
927  if ((*iter) == &proc) {
928  procedures_.erase(iter);
929  break;
930  }
931  }
932 
934 }
935 
936 /**
937  * Returns the number of data memories accessed by the program.
938  *
939  * @return The number of data memories accessed by the program.
940  */
941 int
943  return dataMems_.size();
944 }
945 
946 /**
947  * Insert the given data memory to the program.
948  *
949  * @param dataMem The data memory to be inserted.
950  * @exception IllegalRegistration Memory with the same address space is
951  * found from the program.
952  */
953 void
955  // TODO: check that there is no another data mem with same address space...
956  dataMems_.push_back(dataMem);
957 }
958 
959 /**
960  * Returns the data memory at the given index.
961  *
962  * @param index The position index.
963  * @return The data memory at the given index.
964  * @exception OutOfRange the index is out of range.
965  */
966 DataMemory&
967 Program::dataMemory(int index) const {
968  if (index >= 0 &&
969  static_cast<unsigned int>(index) < dataMems_.size()) {
970  return *dataMems_.at(index);
971  } else {
972  throw OutOfRange(
973  __FILE__, __LINE__, __func__,
974  "There is no data memory with index: " +
975  Conversion::toString(index));
976  }
977 }
978 
979 /**
980  * Returns the data memory with the given address space name.
981  *
982  * @param aSpaceName The address space name of the memory.
983  * @return The data memory with given address space name.
984  * @exception KeyNotFound if the data memory cannot be found.
985  */
986 DataMemory&
987 Program::dataMemory(const std::string& aSpaceName) const {
988  for (int i = 0; i < dataMemoryCount(); i++) {
989  if (dataMemory(i).addressSpace().name() == aSpaceName) {
990  return dataMemory(i);
991  }
992  }
993 
994  throw KeyNotFound(
995  __FILE__, __LINE__, __func__,
996  "No data memory found by address space name: " +
997  aSpaceName);
998 }
999 
1000 /**
1001  * Replace instruction and data address space of a sequential program
1002  * with real ones of the target machine.
1003  *
1004  * Only the data address space of the target machine that corresponds
1005  * to the universal data address space is required. Target machine and
1006  * instruction address space are replaced implicitly.
1007  *
1008  * @param space New data address space.
1009  * @note Use only to convert a sequential program to use a real machine!
1010  */
1011 void
1013 
1014  if (dynamic_cast<UniversalMachine*>(start_.space().machine()) == NULL) {
1015  abortWithError("Address space not connected to a machine.");
1016  }
1017 
1018  AddressSpace& instructionAS =
1019  *space.machine()->controlUnit()->addressSpace();
1020 
1021  start_ = Address(start_.location(), instructionAS);
1022  entry_ = Address(entry_.location(), instructionAS);
1023 
1024 
1025  for (int k = 0; k < procedureCount(); k++) {
1026  Procedure& proc = procedure(k);
1027  for (int j = 0; j < proc.instructionCount(); j++) {
1028  Instruction &ins = proc.instructionAtIndex(j);
1029  for (int i = 0; i < ins.moveCount(); i++) {
1030  Move& move = ins.move(i);
1031  Terminal& source = move.source();
1032  if (source.isAddress() && !source.isInstructionAddress()) {
1033  TerminalAddress* newSource = new TerminalAddress(
1034  source.value(), const_cast<AddressSpace&>(space));
1035  move.setSource(newSource);
1036  }
1037  }
1038  }
1039  }
1040 
1041  if (dataMemoryCount() > 1) {
1042  throw IllegalProgram(
1043  __FILE__, __LINE__, __func__,
1044  "There should be less than two data memories. Number of memories: " +
1046  }
1047 
1048  if (dataMemoryCount() == 0) {
1049  // TODO: what to do when there is no data used in program...
1050  } else if (dataMemoryCount() == 1) {
1051  DataMemory& dataMem = dataMemory(0);
1052  dataMem.setAddressSpace(const_cast<AddressSpace&>(space));
1053 
1054  // fix dest addresses in data defs to point to the new single data AS
1055  for (int i = 0; i < dataMem.dataDefinitionCount(); i++) {
1056  DataDefinition& def = dataMem.dataDefinition(i);
1057  if (def.isAddress() && !def.isInstructionAddress()) {
1059  Address(def.destinationAddress().location(), space));
1060  }
1061  }
1062 
1063  assert(dataMemoryCount() == 1);
1065 
1066  } else {
1067  throw IllegalProgram(
1068  __FILE__, __LINE__, __func__,
1069  "There should be less than two data memories. Number of memories: " +
1071  }
1072 }
1073 
1074 /**
1075  * A shortcut for loading a partially scheduled program from a TPEF file.
1076  *
1077  * @param tpefFileName The file name of the TPEF.
1078  * @param theMachine The target machine.
1079  * @return Created program.
1080  * @exception Exception if the TPEF or program in it is somehow broken.
1081  */
1082 Program*
1084  const std::string& tpefFileName, const TTAMachine::Machine& theMachine) {
1085  TPEF::BinaryStream binaryStream(tpefFileName);
1086 
1087  // read to TPEF Handler Module
1088  TPEF::Binary* tpef = TPEF::BinaryReader::readBinary(binaryStream);
1089 
1090  if (tpef == NULL) {
1091  throw IOException(
1092  __FILE__, __LINE__, __func__, "Loading TPEF failed.");
1093  }
1094 
1095  // convert the loaded TPEF to POM
1096  TTAProgram::TPEFProgramFactory factory(*tpef, theMachine);
1097  Program* prog = factory.build();
1098  delete tpef;
1099  tpef = NULL;
1100  return prog;
1101 }
1102 
1103 /**
1104  * A shortcut for loading a scheduled program from a TPEF file.
1105  *
1106  * @param tpefFileName The file name of the TPEF.
1107  * @param theMachine The target machine.
1108  * @return Created program.
1109  * @exception Exception if the TPEF or program in it is somehow broken.
1110  */
1111 Program*
1113  const std::string& tpefFileName, const TTAMachine::Machine& theMachine) {
1114  TPEF::BinaryStream binaryStream(tpefFileName);
1115 
1116  // read to TPEF Handler Module
1117  TPEF::Binary* tpef = TPEF::BinaryReader::readBinary(binaryStream);
1118 
1119  if (tpef == NULL) {
1120  throw IOException(
1121  __FILE__, __LINE__, __func__, "Loading TPEF failed.");
1122  }
1123 
1124  // convert the loaded TPEF to POM
1125  TTAProgram::TPEFProgramFactory factory(*tpef, theMachine);
1126  Program* prog = factory.build();
1127  delete tpef;
1128  tpef = NULL;
1129  return prog;
1130 }
1131 
1132 /**
1133  * A shortcut for loading a sequential program (from the old gcc 2.7.0
1134  * frontend) from a TPEF file.
1135  *
1136  * @param tpefFileName The file name of the TPEF.
1137  * @param umach The universal machine for the unscheduled parts.
1138  * @return Created program.
1139  * @exception Exception if the TPEF or program in it is somehow broken.
1140  */
1141 Program*
1142 Program::loadFromUnscheduledTPEF(const std::string& tpefFileName) {
1143  TPEF::BinaryStream binaryStream(tpefFileName);
1144 
1145  // read to TPEF Handler Module
1146  TPEF::Binary* tpef = TPEF::BinaryReader::readBinary(binaryStream);
1147 
1148  if (tpef == NULL) {
1149  throw IOException(
1150  __FILE__, __LINE__, __func__, "Loading TPEF failed.");
1151  }
1152 
1153  // convert the loaded TPEF to POM
1155  Program* prog = factory.build();
1156  delete tpef;
1157  tpef = NULL;
1158  return prog;
1159 }
1160 
1161 /**
1162  * A shortcut for writing a program to a TPEF file.
1163  *
1164  * @param program The program to write.
1165  * @param tpefFileName The file name of the TPEF.
1166  * @exception Exception if the TPEF or program in it is somehow broken.
1167  */
1168 void
1170  const TTAProgram::Program& program, const std::string& tpefFileName) {
1171  std::ofstream outputFile(
1172  tpefFileName.c_str(),
1173  std::ios_base::out|std::ios_base::trunc|std::ios_base::binary);
1174  TPEF::BinaryStream binaryStream(outputFile);
1175 
1177  TPEF::Binary* tpefBin = writer.createBinary();
1178 
1179  TPEF::TPEFWriter::instance().writeBinary(binaryStream, tpefBin);
1180 
1181  delete tpefBin;
1182  tpefBin = NULL;
1183 }
1184 
1185 /**
1186  * Returns all Instructions in the program as random accessible vector.
1187  *
1188  * The returned vector can be used for faster traversal of the program's
1189  * instruction. It should be used instead of nextInstruction() or similar
1190  * very slow methods when traversing through the whole program. Note
1191  * that the Instruction* inside the vector should not be destroyed by
1192  * the client as they are owned by the Program. The InstructionVector
1193  * is not updated automatically as the Program changes!
1194  */
1197  InstructionVector instructions;
1198  for (std::size_t p = 0; p < procedures_.size(); ++p) {
1199  Procedure& proc = *procedures_.at(p);
1200  for (int i = 0; i < proc.instructionCount(); ++i) {
1201  Instruction* instr = &proc.instructionAtIndex(i);
1202  instructions.push_back(instr);
1203  }
1204  }
1205  return instructions;
1206 }
1207 
1208 int
1210  if (procedureCount() == 0) {
1211  return 0;
1212  }
1213  return lastProcedure().startAddress().location() +
1215  start_.location();
1216 }
1217 
1218 /**
1219  * Converts single TerminalSymbolReference into
1220  * InstructionReference to the symbol or TerminalImmediate into the
1221  * data label.
1222  *
1223  * @TODO: Use CodeLabels instead of procedure?
1224  */
1227  TCEString procName = tsr.toString();
1228  if (!hasProcedure(procName)) {
1229  if (procName == "_end") {
1230  for (int i = 0; i < globalScope_->globalDataLabelCount(); i++) {
1231  const DataLabel& dl = globalScope_->globalDataLabel(i);
1232  if (dl.name() == "_end") {
1233  // we do not know if this is going to sing- or zero
1234  // extending immediate, lets be sure it fits and use
1235  // signed. zero extends broke sign-extending ADFs
1236  return new TTAProgram::TerminalImmediate(
1237  SimValue(
1238  dl.address().location(),
1240  }
1241  }
1242  throw InstanceNotFound(__FILE__,__LINE__,__func__,
1243  "_end not found in program!");
1244  }
1245  throw InstanceNotFound(__FILE__,__LINE__,__func__,
1246  TCEString("procedure '")
1247  + procName + TCEString("' not found!"));
1248  }
1249  const Procedure& target = procedure(procName);
1250  assert(target.instructionCount() > 0);
1253  target.firstInstruction()));
1254 }
1255 
1256 /**
1257  * Converts all TerminalSymbolReferences into InstructionReferences pointing to
1258  * instructions or TerminalImmediates into data label.
1259  *
1260  * @param ignoreUnfoundSymbols if set to true, just skips symbol references for which
1261  * the symbol is not found. Otherwise throws in that case.
1262  */
1263 void
1264 Program::convertSymbolRefsToInsRefs(bool ignoreUnfoundSymbols) {
1265  for (int i = 0; i < procedureCount();i++) {
1266  Procedure& proc = procedure(i);
1267  for (int j = 0; j < proc.instructionCount(); j++) {
1269  for (int k = 0; k < ins.moveCount(); k++) {
1270  TTAProgram::Move& move = ins.move(k);
1271  TTAProgram::Terminal& src = move.source();
1272 
1273  if (src.isCodeSymbolReference()) {
1274 
1275  TCEString procName = src.toString();
1276  if (!hasProcedure(procName) && ignoreUnfoundSymbols)
1277  continue;
1278 
1279  move.setSource(convertSymbolRef(src));
1280  }
1281  }
1282  for (int k = 0; k < ins.immediateCount(); k++) {
1283  TTAProgram::Immediate& imm = ins.immediate(k);
1284  TTAProgram::Terminal& immVal = imm.value();
1285 
1286  if (immVal.isCodeSymbolReference()) {
1287 
1288  TCEString procName = immVal.toString();
1289  if (!hasProcedure(procName) && ignoreUnfoundSymbols)
1290  continue;
1291 
1292  imm.setValue(convertSymbolRef(immVal));
1293  }
1294  }
1295  }
1296  }
1297 }
1298 
1299 /**
1300  * Links the given Program with this one.
1301  *
1302  * "Linking" here means copying all the procedures to this Program and
1303  * fixing all fixable (external) symbol references. That is, in case
1304  * either this or the other Program contained calls to external
1305  * functions that are now found, the references are fixed to point
1306  * to the actual Procedures.
1307  */
1308 void
1310 
1311  if (other.procedureCount() == 0) return;
1312 
1313  for (int i = 0; i < other.procedureCount(); ++i) {
1314  addProcedure(dynamic_cast<Procedure*>(other.procedure(i).copy()));
1315  }
1316  copyDataMemoriesFrom(other);
1319 
1320  // todo merge GlobalScope (to retain labels)
1321 }
1322 
1323 /**
1324  * Dump the Program as a disassembly string.
1325  */
1326 TCEString
1328  return POMDisassembler::disassemble(*this, true);
1329 }
1330 
1331 /**
1332  * This should be called if the program has been fully constructed and won't
1333  * get new instructions added anymore.
1334  *
1335  * Computes and updates the final Instruction addresses with the best available
1336  * accuracy. Before this method is called, instruction per address indexing is
1337  * used, which is fast but might not reflect the final instruction addresses.
1338  * After this method has been called, the user of the Program can also assume
1339  * all the Instructions are attached to a Procedure and Procedures to the
1340  * Program.
1341  */
1342 void
1344 
1345  InstructionVector instructions = instructionVector();
1346 
1347  if (instructions.size() == 0) return;
1348 
1349  InstructionAddress previousAddress = startAddress().location();
1350 
1351  POMDisassembler* disasm =
1353 
1354  InstructionAddress currentSize =
1355  disasm->instructionSize(*instructions[0]);
1356 
1357  instructions[0]->setFinalAddress(previousAddress);
1358  instructions[0]->setSize(currentSize);
1359 
1360  bool newInstructionPerAddress = instructionPerAddress_;
1361  // From now on assume there's not an instruction per address layout.
1362  instructionPerAddress_ = false;
1363 
1364  if (currentSize != 1)
1365  newInstructionPerAddress = false;
1366 
1367  for (size_t i = 1; i < instructions.size(); ++i) {
1368  TTAProgram::Instruction* instr = instructions[i];
1369  currentSize = disasm->instructionSize(*instr);
1370  instr->setSize(currentSize);
1371  InstructionAddress newAddress = previousAddress + currentSize;
1372  instr->setFinalAddress(newAddress);
1373  previousAddress = newAddress;
1374  if (currentSize != 1)
1375  newInstructionPerAddress = false;
1376  }
1377 
1378  instructionPerAddress_ = newInstructionPerAddress;
1379 
1380  // Fix the procedure start and end addresses.
1381  ProcIter iter = procedures_.begin();
1382  while (iter != procedures_.end()) {
1383  Procedure& proc = **iter;
1384  proc.setStartAddress(proc.firstInstruction().address());
1385  // End address is the first address that doesn't store
1386  // instructions of the procedure.
1387  proc.setEndAddress(
1389  proc.lastInstruction().size(),
1390  proc.lastInstruction().address().space()));
1391  ++iter;
1392  }
1393 
1394  finalized_ = true;
1395  delete disasm;
1396 }
1397 
1398 } // namespace TTAProgram
1399 
TTAProgram::DataMemory::setAddressSpace
void setAddressSpace(const TTAMachine::AddressSpace &space)
Definition: DataMemory.cc:192
TerminalInstructionReference.hh
TTAProgram
Definition: Estimator.hh:65
TTAProgram::Immediate::value
TerminalImmediate & value() const
Definition: Immediate.cc:103
UIntWord
Word UIntWord
Definition: BaseType.hh:144
TTAProgram::InstructionReference::instruction
Instruction & instruction() const
Definition: InstructionReference.cc:138
TTAProgram::Program
Definition: Program.hh:63
TTAProgram::Program::addProcedure
void addProcedure(Procedure *proc)
Definition: Program.cc:524
TTAProgram::Program::firstInstruction
Instruction & firstInstruction() const
Definition: Program.cc:353
BinaryReader.hh
InstructionAddress
UInt32 InstructionAddress
Definition: BaseType.hh:175
TTAProgram::Program::operator[]
Procedure & operator[](size_t index)
Definition: Program.cc:642
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
TTAProgram::Program::addInstruction
void addInstruction(Instruction *ins)
Definition: Program.cc:554
TTAProgram::CodeSnippet::setParent
virtual void setParent(Program &prog)
Definition: CodeSnippet.cc:136
NullProcedure.hh
TTAProgram::DataDefinition
Definition: DataDefinition.hh:52
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTAProgram::Terminal::isInstructionAddress
virtual bool isInstructionAddress() const
Definition: Terminal.cc:87
TTAProgram::Address
Definition: Address.hh:51
TTAProgram::Program::procedureCount
int procedureCount() const
Definition: Program.cc:610
TTAProgram::DataDefinition::startAddress
virtual Address startAddress() const
Definition: DataDefinition.cc:129
TTAProgram::Program::firstProcedure
Procedure & firstProcedure() const
Definition: Program.cc:213
TTAProgram::DataDefinition::size
virtual int size() const
Definition: DataDefinition.cc:211
TTAProgram::Program::entryAddress
Address entryAddress() const
Definition: Program.cc:330
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
TTAProgram::Program::startAddress
Address startAddress() const
Definition: Program.cc:286
TTAProgram::Terminal::isAddress
virtual bool isAddress() const
Definition: Terminal.cc:75
TPEF::BinaryWriter::writeBinary
void writeBinary(BinaryStream &stream, const Binary *bin) const
Definition: BinaryWriter.cc:64
TTAProgram::CodeSnippet::setEndAddress
virtual void setEndAddress(Address end)
Definition: CodeSnippet.cc:195
TTAProgram::Program::nextInstruction
Instruction & nextInstruction(const Instruction &) const
Definition: Program.cc:403
TPEF::Binary
Definition: Binary.hh:49
TTAProgram::Instruction
Definition: Instruction.hh:57
OutOfRange
Definition: Exception.hh:320
Procedure.hh
SequenceTools.hh
TPEF::BinaryStream
Definition: BinaryStream.hh:59
TTAProgram::ProgramWriter
Definition: ProgramWriter.hh:141
TTAProgram::NullProcedure::instance
static NullProcedure & instance()
Definition: NullProcedure.cc:68
TTAProgram::DataMemory::addressSpace
const TTAMachine::AddressSpace & addressSpace() const
Definition: DataMemory.cc:182
TTAProgram::Program::finalized_
bool finalized_
True in case the program is not (and must not be) updated anymore and it has its final instruction ad...
Definition: Program.hh:200
AddressSpace.hh
TTAProgram::DataDefinition::isAddress
virtual bool isAddress() const
Definition: DataDefinition.cc:221
TTAProgram::GlobalScope::copyAndRelocate
virtual Scope * copyAndRelocate(const TTAProgram::Program &program) const
Definition: GlobalScope.cc:334
TTAProgram::Program::instructionPerAddress_
bool instructionPerAddress_
True in case the program is instruction indexed, that is, each instruction is assumed to be in a sing...
Definition: Program.hh:204
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
ProgramWriter.hh
TTAProgram::Address::space
const TTAMachine::AddressSpace & space() const
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
TTAProgram::DataMemory::dataDefinitionCount
int dataDefinitionCount() const
Definition: DataMemory.cc:129
POMDisassembler::disassembler
static POMDisassembler * disassembler(const TTAMachine::Machine &mach, const TTAProgram::Program &program)
Definition: POMDisassembler.cc:1022
TTAProgram::Program::moveAt
const Move & moveAt(int number) const
Definition: Program.cc:480
TTAProgram::CodeSnippet::nextInstruction
virtual Instruction & nextInstruction(const Instruction &ins) const
Definition: CodeSnippet.cc:318
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
TTAProgram::CodeSnippet::startAddress
virtual Address startAddress() const
Definition: CodeSnippet.cc:780
TTAProgram::Program::dataMems_
DataMemList dataMems_
The data memories in the program.
Definition: Program.hh:180
TTAProgram::CodeSnippet::setStartAddress
virtual void setStartAddress(Address start)
Definition: CodeSnippet.cc:190
Terminal.hh
TTAProgram::Terminal::instructionReference
virtual const InstructionReference & instructionReference() const
Definition: Terminal.cc:188
DataInstructionAddressDef.hh
TTAProgram::Procedure::copy
CodeSnippet * copy() const
Definition: Procedure.cc:137
TTAProgram::GlobalScope::globalDataLabel
const DataLabel & globalDataLabel(Address address, int index) const
Definition: GlobalScope.cc:220
DataLabel.hh
Conversion::toString
static std::string toString(const T &source)
TTAProgram::Program::InstructionVector
std::vector< Instruction * > InstructionVector
Vector for instructions.
Definition: Program.hh:66
TTAProgram::Program::refManager_
InstructionReferenceManager * refManager_
Keeps book of all instruction to instruction (jumps and calls) references in the program.
Definition: Program.hh:192
hash_set.hh
SimValue
Definition: SimValue.hh:96
POMDisassembler.hh
GlobalScope.hh
TTAProgram::Program::procedureAtIndex
const Procedure & procedureAtIndex(int index) const
Definition: Program.cc:508
TTAProgram::Program::hasProcedure
bool hasProcedure(const std::string &name) const
Definition: Program.cc:673
TTAProgram::TPEFProgramFactory
Definition: TPEFProgramFactory.hh:87
TTAProgram::Program::globalScopeConst
const GlobalScope & globalScopeConst() const
Definition: Program.cc:192
TTAProgram::NullProgram::instance
static NullProgram & instance()
Definition: NullProgram.cc:72
assert
#define assert(condition)
Definition: Application.hh:86
TTAProgram::Program::instructionAt
Instruction & instructionAt(InstructionAddress address) const
Definition: Program.cc:374
UniversalMachine.hh
SequenceTools::deleteAllItems
static void deleteAllItems(SequenceType &aSequence)
TTAProgram::Label::name
std::string name() const
Definition: Label.cc:74
TTAProgram::Program::addDataMemory
void addDataMemory(DataMemory *dataMem)
Definition: Program.cc:954
TTAProgram::Program::nextProcedure
Procedure & nextProcedure(const Procedure &proc) const
Definition: Program.cc:250
TTAProgram::Immediate
Definition: Immediate.hh:54
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
TTAProgram::Program::setEntryAddress
void setEntryAddress(Address address)
Definition: Program.cc:342
TTAProgram::Program::moveProcedure
void moveProcedure(Procedure &proc, int howMuch)
Definition: Program.cc:588
TTAProgram::DataMemory::addDataDefinition
void addDataDefinition(DataDefinition *dataDef)
Definition: DataMemory.cc:66
DataMemory.hh
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTAProgram::GlobalScope::setDataLabelAddressSpace
virtual void setDataLabelAddressSpace(const TTAMachine::AddressSpace &space)
Definition: GlobalScope.cc:305
UniversalMachine
Definition: UniversalMachine.hh:56
TTAProgram::DataDefinition::destinationAddress
virtual Address destinationAddress() const
Definition: DataDefinition.cc:241
TTAProgram::DataLabel
Definition: DataLabel.hh:45
TTAProgram::Program::link
void link(const TTAProgram::Program &other)
Definition: Program.cc:1309
TTAProgram::Instruction::copy
Instruction * copy() const
Definition: Instruction.cc:379
TTAProgram::Program::dataMemory
DataMemory & dataMemory(int index) const
Definition: Program.cc:967
Application.hh
POMDisassembler
Definition: POMDisassembler.hh:70
NullInstruction.hh
IllegalProgram
Definition: Exception.hh:895
__func__
#define __func__
Definition: Application.hh:67
TTAProgram::TPEFProgramFactory::build
Program * build()
Definition: TPEFProgramFactory.cc:200
TTAProgram::Instruction::parent
CodeSnippet & parent() const
Definition: Instruction.cc:109
TTAProgram::TerminalInstructionReference
Definition: TerminalInstructionReference.hh:48
TTAProgram::DataDefinition::setDestinationAddress
virtual void setDestinationAddress(Address dest)
Definition: DataDefinition.cc:251
TTAProgram::CodeSnippet::lastInstruction
virtual Instruction & lastInstruction() const
Definition: CodeSnippet.cc:387
TPEF::TPEFWriter::instance
static const BinaryWriter & instance()
Definition: TPEFWriter.cc:70
TTAProgram::Program::cleanup
void cleanup()
Definition: Program.cc:161
TTAProgram::Terminal::value
virtual SimValue value() const
Definition: Terminal.cc:178
BinaryWriter.hh
TTAProgram::GlobalScope::globalDataLabelCount
int globalDataLabelCount(Address address) const
Definition: GlobalScope.cc:195
TTAProgram::GlobalScope
Definition: GlobalScope.hh:47
TTAProgram::Address::location
InstructionAddress location() const
TTAProgram::Instruction::setSize
void setSize(short size)
Definition: Instruction.hh:104
TTAProgram::TerminalAddress
Definition: TerminalAddress.hh:48
TTAProgram::Move
Definition: Move.hh:55
TTAProgram::Program::copyDataMemoriesFrom
void copyDataMemoriesFrom(const Program &srcProg)
Definition: Program.cc:845
TTAProgram::NullInstruction::instance
static NullInstruction & instance()
Definition: NullInstruction.cc:66
TTAProgram::Label::address
virtual Address address() const
Definition: Label.cc:84
TTAProgram::Program::Program
Program(const TTAMachine::AddressSpace &space)
Definition: Program.cc:91
TTAProgram::Program::universalMachine
UniversalMachine & universalMachine() const
Definition: Program.cc:104
TTAProgram::Instruction::immediate
Immediate & immediate(int i) const
Definition: Instruction.cc:285
TTAProgram::Immediate::setValue
void setValue(TerminalImmediate *value)
Definition: Immediate.cc:114
TTAProgram::Program::operator=
Program & operator=(const Program &old)
Definition: Program.cc:701
TTAProgram::GlobalScope::removeCodeLabels
virtual void removeCodeLabels(InstructionAddress address)
Definition: GlobalScope.cc:363
TTAProgram::Program::dataMemoryCount
int dataMemoryCount() const
Definition: Program.cc:942
IllegalRegistration
Definition: Exception.hh:532
TTAProgram::Program::toString
TCEString toString() const
Definition: Program.cc:1327
TTAProgram::Program::moves_
MoveList moves_
List of all the moves of the program.
Definition: Program.hh:183
TTAProgram::Program::copy
Program * copy() const
Definition: Program.cc:714
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
TTAProgram::Program::instructionCount
int instructionCount() const
Definition: Program.cc:1209
TTAProgram::Program::setStartAddress
void setStartAddress(Address start)
Definition: Program.cc:304
TTAProgram::Instruction::isInProcedure
bool isInProcedure() const
Definition: Instruction.cc:135
POMDisassembler::disassemble
static std::string disassemble(const TTAProgram::Move &move)
Definition: POMDisassembler.cc:629
TTAProgram::Procedure::add
void add(Instruction *ins)
Definition: Procedure.cc:160
TPEFProgramFactory.hh
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
TTAProgram::Program::procedures_
ProcList procedures_
The procedures in the program.
Definition: Program.hh:177
Program.hh
TTAProgram::Terminal::toString
virtual TCEString toString() const =0
Immediate.hh
TerminalAddress.hh
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
TTAMachine::Component::machine
virtual Machine * machine() const
TTAProgram::Program::replaceUniversalAddressSpaces
void replaceUniversalAddressSpaces(const TTAMachine::AddressSpace &space)
Definition: Program.cc:1012
AssocTools.hh
TTAProgram::Program::moveCount
int moveCount() const
Definition: Program.cc:494
InstructionReference.hh
TTAProgram::CodeSnippet::parent
virtual Program & parent() const
Definition: CodeSnippet.cc:118
TCEString
Definition: TCEString.hh:53
TTAProgram::Instruction::size
short size() const
Definition: Instruction.cc:365
TTAProgram::Instruction::immediateCount
int immediateCount() const
Definition: Instruction.cc:267
ControlUnit.hh
TTAProgram::Program::writeToTPEF
static void writeToTPEF(const TTAProgram::Program &program, const std::string &tpefFileName)
Definition: Program.cc:1169
TTAProgram::DataMemory::dataDefinition
DataDefinition & dataDefinition(Address address) const
Definition: DataMemory.cc:79
TTAProgram::Program::entry_
Address entry_
The entry address of the program.
Definition: Program.hh:188
InstructionReferenceManager.hh
TTAProgram::Program::targetProcessor
TTAMachine::Machine & targetProcessor() const
Definition: Program.cc:202
TTAProgram::Procedure::name
TCEString name() const
Definition: Procedure.hh:66
TTAProgram::Program::loadFromTPEF
static Program * loadFromTPEF(const std::string &tpefFileName, const TTAMachine::Machine &theMachine)
Definition: Program.cc:1112
BinaryStream.hh
TTAProgram::Program::convertSymbolRef
TerminalImmediate * convertSymbolRef(Terminal &tsr)
Definition: Program.cc:1226
TTAProgram::Terminal
Definition: Terminal.hh:60
TPEFWriter.hh
TTAProgram::CodeSnippet::endAddress
virtual Address endAddress() const
Definition: CodeSnippet.cc:788
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Program::~Program
virtual ~Program()
Definition: Program.cc:144
TTAProgram::Program::globalScope_
GlobalScope * globalScope_
Global scope of the program.
Definition: Program.hh:174
KeyNotFound
Definition: Exception.hh:285
program
find Finds info of the inner loops in the program
Definition: InnerLoopFinder.cc:80
TTAProgram::Terminal::isCodeSymbolReference
virtual bool isCodeSymbolReference() const
Definition: Terminal.cc:154
IOException
Definition: Exception.hh:130
TTAProgram::Program::lastInstruction
Instruction & lastInstruction() const
Definition: Program.cc:463
MathTools.hh
TTAProgram::Terminal::setInstructionReference
virtual void setInstructionReference(InstructionReference ref)
Definition: Terminal.cc:404
TTAProgram::Program::lastProcedure
Procedure & lastProcedure() const
Definition: Program.cc:230
TTAProgram::Program::globalScope
GlobalScope & globalScope()
Definition: Program.cc:180
POMDisassembler::instructionSize
virtual size_t instructionSize(const TTAProgram::Instruction &)
Returns the size of the instruction in memory addresses, if known. Falls back to address per instruct...
Definition: POMDisassembler.hh:119
TTAProgram::DataMemory
Definition: DataMemory.hh:56
Move.hh
TTAMachine
Definition: Assembler.hh:48
TTAProgram::DataInstructionAddressDef
Definition: DataInstructionAddressDef.hh:48
TTAProgram::Program::fixInstructionReferences
void fixInstructionReferences()
Definition: Program.cc:775
TTAProgram::Program::removeProcedure
void removeProcedure(Procedure &proc)
Definition: Program.cc:901
NullProgram.hh
TTAProgram::Program::ProcIter
ProcList::const_iterator ProcIter
Iterator for the procedure list.
Definition: Program.hh:156
TTAProgram::Instruction::setFinalAddress
void setFinalAddress(InstructionAddress addr)
Definition: Instruction.hh:121
TTAProgram::ProgramWriter::createBinary
TPEF::Binary * createBinary() const
Definition: ProgramWriter.cc:700
TTAProgram::Program::copyFrom
void copyFrom(const Program &source)
Definition: Program.cc:732
TTAProgram::Program::start_
Address start_
The start address of the program.
Definition: Program.hh:186
TTAProgram::DataDefinition::copy
virtual DataDefinition * copy() const
Definition: DataDefinition.cc:262
TTAProgram::Program::instructionVector
InstructionVector instructionVector() const
Definition: Program.cc:1196
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
TTAProgram::Program::procedure
Procedure & procedure(int index) const
Definition: Program.cc:622
TTAProgram::Procedure
Definition: Procedure.hh:55
TTAProgram::DataDefinition::isInstructionAddress
virtual bool isInstructionAddress() const
Definition: DataDefinition.cc:231
DataDefinition.hh
MathTools::requiredBitsSigned
static int requiredBitsSigned(SLongWord number)
CodeLabel.hh
TTAProgram::Program::loadFromUnscheduledTPEF
static Program * loadFromUnscheduledTPEF(const std::string &tpefFileName, const TTAMachine::Machine &theMachine)
Definition: Program.cc:1083
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
TTAProgram::Program::convertSymbolRefsToInsRefs
void convertSymbolRefsToInsRefs(bool ignoreUnfoundSymbols=false)
Definition: Program.cc:1264
TTAProgram::Instruction::address
Address address() const
Definition: Instruction.cc:327
TPEF::BinaryReader::readBinary
static Binary * readBinary(BinaryStream &stream)
Definition: BinaryReader.cc:88
InstanceNotFound
Definition: Exception.hh:304
TTAProgram::Move::setSource
void setSource(Terminal *src)
Definition: Move.cc:312
TTAProgram::CodeSnippet::isInProgram
virtual bool isInProgram() const
Definition: CodeSnippet.cc:151
TTAMachine::Machine
Definition: Machine.hh:73
TTAProgram::Program::finalize
void finalize()
Definition: Program.cc:1343