OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
TTAProgram::ProgramWriter Class Reference

#include <ProgramWriter.hh>

Collaboration diagram for TTAProgram::ProgramWriter:
Collaboration graph

Classes

struct  RelocInfo
 
struct  ResourceID
 

Public Member Functions

 ProgramWriter (const Program &prog)
 
TPEF::BinarycreateBinary () const
 

Static Public Member Functions

static TPEF::BinarycreateBinary (const Program &prog)
 

Private Member Functions

void createCodeSection (TPEF::CodeSection *code, TPEFResourceUpdater &updater) const
 
void createDataSections (TPEF::Binary *bin, bool littleEndian) const
 
void createRelocSections (TPEF::Binary *bin) const
 
TPEF::SectionfindSection (TPEF::Binary &bin, Address address) const
 
ResourceID terminalResource (const Terminal &term, TPEFResourceUpdater &updater) const
 
TPEF::Binary::FileType resolveFileType (TPEF::ResourceSection &resources) const
 
TPEF::ASpaceElementcreateASpaceElement (const TTAMachine::AddressSpace &addressSpace, TPEF::Binary &bin) const
 

Private Attributes

const Programprog_
 Program that is written to TPEF.
 
std::map< const TTAMachine::AddressSpace *, TPEF::ASpaceElement * > aSpaceMap_
 Created TPEF binary.
 
std::vector< RelocInforelocInfos_
 

Static Private Attributes

static const HalfWord IMMEDIATE_ADDRESS_WIDTH = WORD_BITWIDTH
 Default widt that is used as address width of relocations of immediate elements. This should be fixed by checking width from bus or template.
 
static const int MAX_SIMM_WIDTH = 64
 Maximum width for short immediates.
 

Detailed Description

Writes new TPEF out of POM and original TPEF.

Writer creates creates whole new code section, code relocation section, resource section and symbol section for code symbols. Data sections, uninitialized data sections and data to data relocations are also copied from original TPEF.

Client of POM has to write data to code relocations and all sections that client wants to preserve from original TPEF.

Definition at line 141 of file ProgramWriter.hh.

Constructor & Destructor Documentation

◆ ProgramWriter()

TTAProgram::ProgramWriter::ProgramWriter ( const Program prog)

Constructor.

Parameters
progProgram that from TPEF is created.

Definition at line 688 of file ProgramWriter.cc.

689 :
690 prog_(prog) {
691}
const Program & prog_
Program that is written to TPEF.

Member Function Documentation

◆ createASpaceElement()

TPEF::ASpaceElement & TTAProgram::ProgramWriter::createASpaceElement ( const TTAMachine::AddressSpace addressSpace,
TPEF::Binary bin 
) const
private

Creates new address space element to binary or returns already created one.

This function should be used always with same TPEF bin.

Parameters
addressSpaceADF address space whose TPEF version is needed.
binBinary to which created address space is added.
Returns
Address space element of corresponding ADF address space.

Definition at line 1544 of file ProgramWriter.cc.

1545 {
1546
1547 StringSection* strings = dynamic_cast<StringSection*>(
1548 bin.section(Section::ST_STRTAB,0));
1549 Section* aSpaceSection = bin.section(Section::ST_ADDRSP,0);
1550
1551 // create new address space if necessary
1552 if (!MapTools::containsKey(aSpaceMap_, &addressSpace)) {
1553 ASpaceElement *newASpace = new ASpaceElement();
1554
1555 // set mau of instruction address space to be 0
1556 if (&addressSpace ==
1558 newASpace->setMAU(0);
1559 } else {
1560 newASpace->setMAU(addressSpace.width());
1561 }
1562 newASpace->setName(
1563 strings->string2Chunk(addressSpace.name()));
1564 aSpaceSection->addElement(newASpace);
1565 aSpaceMap_[&addressSpace] = newASpace;
1566 }
1567
1568 return *aSpaceMap_[&addressSpace];
1569}
static bool containsKey(const MapType &aMap, const KeyType &aKey)
void setName(const ReferenceManager::SafePointer *aName)
void setMAU(Byte aMAU)
Section * section(Word index) const
virtual void addElement(SectionElement *element)
Definition Section.cc:133
Chunk * string2Chunk(const std::string &str)
virtual int width() const
virtual TCEString name() const
virtual AddressSpace * addressSpace() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
std::map< const TTAMachine::AddressSpace *, TPEF::ASpaceElement * > aSpaceMap_
Created TPEF binary.
TTAMachine::Machine & targetProcessor() const
Definition Program.cc:202

References TPEF::Section::addElement(), TTAMachine::FunctionUnit::addressSpace(), aSpaceMap_, MapTools::containsKey(), TTAMachine::Machine::controlUnit(), TTAMachine::Component::name(), prog_, TPEF::Binary::section(), TPEF::ASpaceElement::setMAU(), TPEF::ASpaceElement::setName(), TPEF::StringSection::string2Chunk(), TTAProgram::Program::targetProcessor(), and TTAMachine::AddressSpace::width().

Referenced by createBinary(), createDataSections(), createRelocSections(), and findSection().

Here is the call graph for this function:

◆ createBinary() [1/2]

Binary * TTAProgram::ProgramWriter::createBinary ( ) const

Creates TPEF binary.

Returns
TPEF binary of a program.

Definition at line 700 of file ProgramWriter.cc.

700 {
701 Binary* newBin = new Binary();
702
703 // create and initialize sections
704 NullSection* nullSection = dynamic_cast<NullSection*>(
705 Section::createSection(Section::ST_NULL));
706
707 StringSection* strings = dynamic_cast<StringSection*>(
708 Section::createSection(Section::ST_STRTAB));
709 strings->addByte(0);
710
711 ASpaceSection* aSpaces = dynamic_cast<ASpaceSection*>(
712 Section::createSection(Section::ST_ADDRSP));
713
714 ASpaceElement* undefASpace = new ASpaceElement();
715 undefASpace->setName(strings->string2Chunk(""));
716 aSpaces->setUndefinedASpace(undefASpace);
717
718 // check instruction address space from adf and init instruction space
720 ControlUnit* unit = adf.controlUnit();
721 AddressSpace* adfInstrASpace = unit->addressSpace();
722
723 if (prog_.instructionCount() > 0 &&
724 (prog_.startAddress().location() < adfInstrASpace->start() ||
726 adfInstrASpace->end())) {
727 TCEString err =
728 "The program is out of bounds of the imem."
729 " Please increase the instruction address space size in adf or "
730 " make the program smaller. "
731 "Using a smaller unroll and/or inlining threshold may help.";
732 err << " Imem address space size: "
733 << (adfInstrASpace->end() - adfInstrASpace->start() +1)
734 << ", required program size: "
736
737 throw CompileError(__FILE__, __LINE__, __func__, err);
738 }
739
740 aSpaces->addElement(undefASpace);
741
742 ResourceSection* resources = dynamic_cast<ResourceSection*>(
743 Section::createSection(Section::ST_MR));
744
745 CodeSection* code =
746 dynamic_cast<CodeSection*>(Section::createSection(Section::ST_CODE));
747
748 SymbolSection* symbols =
749 dynamic_cast<SymbolSection*>(
750 Section::createSection(Section::ST_SYMTAB));
751
752 NoTypeSymElement *undefSymbol = new NoTypeSymElement();
753 undefSymbol->setName(strings->string2Chunk(""));
754 symbols->addElement(undefSymbol);
755
756 // add sections to binary
757 newBin->addSection(nullSection);
758 newBin->addSection(aSpaces);
759 newBin->addSection(strings);
760 newBin->addSection(resources);
761 newBin->addSection(code);
762 newBin->addSection(symbols);
763 newBin->setStrings(strings);
764
765 // set link fields
766 nullSection->setLink(nullSection);
767 strings->setLink(nullSection);
768 aSpaces->setLink(strings);
769 resources->setLink(strings);
770 code->setLink(resources);
771 symbols->setLink(strings);
772
773 // set name fields
774 nullSection->setName(strings->string2Chunk(""));
775 strings->setName(strings->string2Chunk(""));
776 aSpaces->setName(strings->string2Chunk(""));
777 resources->setName(strings->string2Chunk(""));
778 code->setName(strings->string2Chunk(""));
779 symbols->setName(strings->string2Chunk(""));
780
781 // set adress space fields
782 nullSection->setASpace(undefASpace);
783 strings->setASpace(undefASpace);
784 aSpaces->setASpace(undefASpace);
785 resources->setASpace(undefASpace);
786 code->setASpace(&createASpaceElement(*adfInstrASpace, *newBin));
787 symbols->setASpace(undefASpace);
788
789 TPEFResourceUpdater resourceUpdater(prog_.targetProcessor(), *resources);
790
791 createCodeSection(code, resourceUpdater);
792 createDataSections(newBin, adf.isLittleEndian());
793
794 // TODO: add labels here (all labels are inserted at once from skope
795 // information after writing porgram sections)
796
797 // TODO: refactor this...
798
799 // procedure symbols
800 for (int i = 0; i < prog_.procedureCount(); i++) {
801 Procedure &currProced = prog_.procedure(i);
802
803 // create CodeSymElement and add it to symbols
804 ProcedSymElement *procedSym = new ProcedSymElement();
805
806 procedSym->setAbsolute(false);
807 procedSym->setBinding(SymbolElement::STB_LOCAL);
808
809 procedSym->setName(
810 strings->string2Chunk(currProced.name()));
811
812 procedSym->setSection(code);
813
814 procedSym->setReference(
815 &code->instruction(currProced.startAddress().location()));
816
817 symbols->addElement(procedSym);
818 }
819
820 // we add only global scope labels for now
821 const GlobalScope &globalScope = prog_.globalScopeConst();
822
823 for (int i = 0; i < globalScope.globalCodeLabelCount(); i++) {
824 const CodeLabel &currLabel = globalScope.globalCodeLabel(i);
825
826 // create CodeSymElement and add it to symbols
827 CodeSymElement *codeSym = new CodeSymElement();
828
829 codeSym->setAbsolute(false);
830 codeSym->setBinding(SymbolElement::STB_GLOBAL);
831
832 codeSym->setName(
833 strings->string2Chunk(currLabel.name()));
834
835 codeSym->setSection(code);
836
837 codeSym->setReference(
838 &code->instruction(currLabel.address().location()));
839
840 symbols->addElement(codeSym);
841 }
842
843 for (int i = 0; i < globalScope.globalDataLabelCount(); i++) {
844 const DataLabel &currLabel = globalScope.globalDataLabel(i);
845
846 // create DataSymElement and add it to symbols
847 DataSymElement *dataSym = new DataSymElement();
848
849 dataSym->setAbsolute(false);
850 dataSym->setBinding(SymbolElement::STB_GLOBAL);
851
852 dataSym->setName(strings->string2Chunk(currLabel.name()));
853
854 // TODO: find section by address.
855 // refactor to own method (Method is already written)
856
857 // it seems that we need to have some kind of data
858 // section finding by address
859 ASpaceSection* aSpaces = dynamic_cast<ASpaceSection*>(
860 newBin->section(Section::ST_ADDRSP,0));
861
862 ASpaceElement* dstASpace = NULL;
863
864 // find out dst address space by comparing names
865 for (Word k = 0; k < aSpaces->elementCount(); k++) {
866 ASpaceElement *currElem = dynamic_cast<ASpaceElement*>(
867 aSpaces->element(k));
868
869 if (TPEFTools::addressSpaceName(*newBin, *currElem) ==
870 currLabel.address().space().name()) {
871
872 dstASpace = currElem;
873 break;
874 }
875 }
876
877 if (dstASpace == NULL) {
878 throw NotAvailable(
879 __FILE__, __LINE__, __func__,
880 std::string("Cannot find address space ") +
881 currLabel.address().space().name() +
882 " for data label " + currLabel.name());
883
884 }
885 UDataSection* dstSection = NULL;
886 LongWord dstAddress = currLabel.address().location();
887
888 for (Word k = 0; k < newBin->sectionCount(); k++) {
889 UDataSection *currSect = dynamic_cast<UDataSection*>(
890 newBin->section(k));
891
892 if (currSect != NULL &&
893 (currSect->type() == Section::ST_DATA ||
894 currSect->type() == Section::ST_UDATA||
895 currSect->type() == Section::ST_LEDATA) &&
896 currSect->aSpace() == dstASpace &&
897 currSect->startingAddress() <= dstAddress &&
898 dstAddress <
899 currSect->startingAddress() + currSect->lengthInMAUs()) {
900
901 dstSection = currSect;
902 break;
903 }
904 }
905
906 if (dstSection == NULL) {
907 abortWithError("Can't find section for data address: " +
908 Conversion::toString(dstAddress));
909 }
910
911 dataSym->setSection(dstSection);
912
913 dstAddress -= dstSection->startingAddress();
914
915 dataSym->setReference(
916 dstSection->chunk(
917 dstSection->MAUsToBytes(dstAddress)));
918
919 symbols->addElement(dataSym);
920 }
921
922 // all the data is written... do the relocations
923 createRelocSections(newBin);
924
925 // clean up internal tables
926 aSpaceMap_.clear();
927 relocInfos_.clear();
928
929 newBin->setArch(Binary::FA_TTA_TUT);
930 newBin->setType(resolveFileType(*resources));
931
932 return newBin;
933}
#define __func__
#define abortWithError(message)
unsigned long LongWord
Definition BaseType.hh:49
static std::string toString(const T &source)
void setUndefinedASpace(ASpaceElement *aSpace)
void addSection(Section *section)
void setArch(FileArchitecture arch)
Word sectionCount() const
void setType(FileType type)
void setStrings(StringSection *strTable)
InstructionElement & instruction(Word index) const
void setReference(InstructionElement *aReference)
virtual void addByte(Byte aByte)
void setReference(Chunk *aReference)
virtual Chunk * chunk(SectionOffset offset) const
Definition Section.cc:212
virtual Word MAUsToBytes(Word mauCount) const
Definition Section.cc:320
virtual Word lengthInMAUs() const
Definition Section.cc:285
AddressImage startingAddress() const
SectionElement * element(Word index) const
Word elementCount() const
void setLink(const ReferenceManager::SafePointer *aLink)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
void setName(const ReferenceManager::SafePointer *sectionName)
ASpaceElement * aSpace() const
void setAbsolute(bool anAbsoluteness)
void setName(Chunk *aName)
void setBinding(SymbolBinding aBinding)
void setSection(Section *aSect)
virtual SectionType type() const
virtual ULongWord end() const
virtual ULongWord start() const
bool isLittleEndian() const
Definition Machine.hh:258
InstructionAddress location() const
const CodeLabel & globalCodeLabel(Address address, int index) const
std::vector< RelocInfo > relocInfos_
void createDataSections(TPEF::Binary *bin, bool littleEndian) const
void createRelocSections(TPEF::Binary *bin) const
void createCodeSection(TPEF::CodeSection *code, TPEFResourceUpdater &updater) const
TPEF::Binary::FileType resolveFileType(TPEF::ResourceSection &resources) const
TPEF::ASpaceElement & createASpaceElement(const TTAMachine::AddressSpace &addressSpace, TPEF::Binary &bin) const
Procedure & procedure(int index) const
Definition Program.cc:622
Address startAddress() const
Definition Program.cc:286
const GlobalScope & globalScopeConst() const
Definition Program.cc:192
int procedureCount() const
Definition Program.cc:610
int instructionCount() const
Definition Program.cc:1209

References __func__, abortWithError, TPEF::DataSection::addByte(), TPEF::Section::addElement(), TTAProgram::CodeLabel::address(), TTAProgram::Label::address(), TTAMachine::FunctionUnit::addressSpace(), TPEF::Binary::addSection(), TPEF::Section::aSpace(), aSpaceMap_, TPEF::RawSection::chunk(), TTAMachine::Machine::controlUnit(), createASpaceElement(), createCodeSection(), createDataSections(), createRelocSections(), TPEF::Section::element(), TPEF::Section::elementCount(), TTAMachine::AddressSpace::end(), TTAProgram::GlobalScope::globalCodeLabel(), TTAProgram::GlobalScope::globalCodeLabelCount(), TTAProgram::GlobalScope::globalDataLabel(), TTAProgram::GlobalScope::globalDataLabelCount(), TTAProgram::Program::globalScopeConst(), TPEF::CodeSection::instruction(), TTAProgram::Program::instructionCount(), TTAMachine::Machine::isLittleEndian(), TPEF::RawSection::lengthInMAUs(), TTAProgram::Address::location(), TPEF::RawSection::MAUsToBytes(), TTAMachine::Component::name(), TTAProgram::Label::name(), TTAProgram::Procedure::name(), TTAProgram::Program::procedure(), TTAProgram::Program::procedureCount(), prog_, relocInfos_, resolveFileType(), TPEF::Binary::section(), TPEF::Binary::sectionCount(), TPEF::SymbolElement::setAbsolute(), TPEF::Binary::setArch(), TPEF::Section::setASpace(), TPEF::SymbolElement::setBinding(), TPEF::Section::setLink(), TPEF::SymbolElement::setName(), TPEF::ASpaceElement::setName(), TPEF::Section::setName(), TPEF::DataSymElement::setReference(), TPEF::CodeSymElement::setReference(), TPEF::SymbolElement::setSection(), TPEF::Binary::setStrings(), TPEF::Binary::setType(), TPEF::ASpaceSection::setUndefinedASpace(), TTAProgram::Address::space(), TTAMachine::AddressSpace::start(), TTAProgram::CodeSnippet::startAddress(), TTAProgram::Program::startAddress(), TPEF::Section::startingAddress(), TPEF::StringSection::string2Chunk(), TTAProgram::Program::targetProcessor(), Conversion::toString(), and TPEF::UDataSection::type().

Referenced by createBinary(), RemoteController::loadIMemImage(), ProgrammabilityValidator::profile(), and TTAProgram::Program::writeToTPEF().

◆ createBinary() [2/2]

TPEF::Binary * TTAProgram::ProgramWriter::createBinary ( const Program prog)
static

Creates TPEF binary of given Program.

Returns
TPEF binary of a program.

Definition at line 941 of file ProgramWriter.cc.

941 {
942 ProgramWriter writer(prog);
943 return writer.createBinary();
944}
ProgramWriter(const Program &prog)

References createBinary().

Here is the call graph for this function:

◆ createCodeSection()

void TTAProgram::ProgramWriter::createCodeSection ( TPEF::CodeSection code,
TPEFResourceUpdater updater 
) const
private

Creates code section.

Parameters
codeCode section where to instructions are added.
updaterResource updater for finding TPEF resources for machine parts.

Definition at line 954 of file ProgramWriter.cc.

956 {
957
958 // add all busses from machine to resource section
960 Machine::BusNavigator navi = adf.busNavigator();
961 for (int i = 0; i < navi.count(); i++) {
962 // just call once for each bus, to make sure that all busses
963 // are written to machine resource table.
964 updater.bus(*navi.item(i));
965 }
966
968
969 for (int i = 0; i < prog_.procedureCount(); i++) {
970 Procedure& currProcedure = prog_.procedure(i);
971
972 for (int j = 0; j < currProcedure.instructionCount(); j++) {
973 Instruction &currInstr = currProcedure.instructionAtIndex(j);
974 HalfWord immediateIndex = 0;
975 bool beginFlag = true;
976
977 for (int k = 0; k < currInstr.moveCount(); k++) {
978 Move& progMove = currInstr.move(k);
979 MoveElement* tpefMove = new MoveElement();
980
981 tpefMove->setBegin(beginFlag);
982 beginFlag = false;
983 tpefMove->setBus(updater.bus(progMove.bus()).id());
984 tpefMove->setEmpty(false);
985
986 // add the possible move annotations
987 if (progMove.hasAnnotations()) {
988 for (int annotationIndex = 0;
989 annotationIndex < progMove.annotationCount();
990 ++annotationIndex) {
991 const ProgramAnnotation& annot =
992 progMove.annotation(annotationIndex);
993 tpefMove->addAnnotation(
995 annot.id(), annot.payload()));
996 }
997 }
998
999 code->addElement(tpefMove);
1000
1001 if (!tpefMove->isEmpty()) {
1002
1003 // set source
1004 if (!progMove.source().isImmediate()) {
1005
1006 ResourceID sourceId =
1007 terminalResource(progMove.source(), updater);
1008
1009#if 0
1010 std::cerr << "src type: " << sourceId.type
1011 << "\tunit: " << sourceId.unit
1012 << "\tindex: " << sourceId.index
1013 << std::endl;
1014#endif
1015
1016 tpefMove->setSourceType(sourceId.type);
1017 tpefMove->setSourceUnit(sourceId.unit);
1018 tpefMove->setSourceIndex(sourceId.index);
1019
1020 } else {
1021
1022 ImmediateElement *newImmediate =
1023 new ImmediateElement();
1024 newImmediate->setBegin(false);
1025
1026 const TTAProgram::TerminalImmediate& termImm =
1027 dynamic_cast<TerminalImmediate&>(
1028 progMove.source());
1029
1030 // add the possible immediate annotations
1031 if (termImm.hasAnnotations()) {
1032 for (int annotationIndex = 0;
1033 annotationIndex < termImm.annotationCount();
1034 ++annotationIndex) {
1035 const ProgramAnnotation& annot =
1036 termImm.annotation(annotationIndex);
1037 newImmediate->addAnnotation(
1039 annot.id(), annot.payload()));
1040 }
1041 }
1042
1043
1044 // check that inline immediate fits to bus's
1045 // inline immediate field
1046 unsigned long wordToStore =
1047 progMove.source().value().uLongWordValue();
1048
1049 unsigned long uvalue = wordToStore;
1050 int requiredBits = 0;
1051 int fieldWidth = progMove.bus().immediateWidth();
1052
1053 // TODO: why here? immediateelement can handle this???
1054 if (progMove.bus().signExtends()) {
1055 // Interpret as signed and sign extend if needed
1056 long svalue = static_cast<long>(uvalue);
1057 if (fieldWidth < MAX_SIMM_WIDTH) {
1058 svalue = MathTools::signExtendTo(
1059 svalue, fieldWidth);
1060 }
1061 requiredBits =
1063 } else {
1064 requiredBits =
1066 }
1067
1068 if (requiredBits <= fieldWidth) {
1069 wordToStore =
1071 wordToStore, fieldWidth);
1072 } else {
1073 TCEString disasm = POMDisassembler::disassemble(progMove);
1074 long location =
1075 progMove.parent().address().location();
1076 TCEString message = "In procedure:";
1077 message << currProcedure.name() << " Move: " <<
1078 disasm << " Inline immediate value " <<
1079 progMove.source().value().unsignedValue() <<
1080 " of required width " <<
1081 Conversion::toString(requiredBits) <<
1082 " at location " <<
1083 Conversion::toString(location) <<
1084 " doesn't fit to bus: " <<
1085 progMove.bus().name();
1086
1087 throw NotAvailable(
1088 __FILE__, __LINE__, __func__, message);
1089 }
1090
1091 if (progMove.bus().signExtends()) {
1092 newImmediate->setSignedLong(wordToStore);
1093 } else {
1094 newImmediate->setULongWord(wordToStore);
1095 }
1096 newImmediate->setDestinationUnit(
1097 ResourceElement::INLINE_IMM);
1098 newImmediate->setDestinationIndex(immediateIndex);
1099 immediateIndex++;
1100
1101 code->addElement(newImmediate);
1102
1103 tpefMove->setSourceType(MoveElement::MF_IMM);
1104 tpefMove->setSourceUnit(
1105 newImmediate->destinationUnit());
1106 tpefMove->setSourceIndex(
1107 newImmediate->destinationIndex());
1108
1109 // add relocation antries if needed
1110 if (progMove.source().isInstructionAddress()) {
1111
1112 // TODO: check size of inline immediate field
1113 RelocInfo newReloc(
1114 code, newImmediate,
1115 progMove.source().address(),
1117
1118 relocInfos_.push_back(newReloc);
1119
1120 } else if (progMove.source().isAddress()) {
1121
1122 // TODO: check size of inline immediate field
1123 RelocInfo newReloc(
1124 code, newImmediate,
1125 progMove.source().address(),
1127
1128 relocInfos_.push_back(newReloc);
1129
1130 }
1131 }
1132
1133 // set destination
1134 ResourceID destinationId =
1135 terminalResource(progMove.destination(), updater);
1136#if 0
1137 std::cerr << "dst type: " << destinationId.type
1138 << "\tunit: " << destinationId.unit
1139 << "\tindex: " << destinationId.index
1140 << std::endl;
1141#endif
1142 tpefMove->setDestinationType(destinationId.type);
1143 tpefMove->setDestinationUnit(destinationId.unit);
1144 tpefMove->setDestinationIndex(destinationId.index);
1145
1146 // set guard stuff
1147 if (progMove.isUnconditional()) {
1148 tpefMove->setGuarded(false);
1149 } else {
1150
1151 const Guard *guard = &progMove.guard().guard();
1152
1153 tpefMove->setGuarded(true);
1154
1155 tpefMove->setGuardInverted(guard->isInverted());
1156
1157 const PortGuard *portGuard =
1158 dynamic_cast<const PortGuard*>(guard);
1159 const RegisterGuard *registerGuard =
1160 dynamic_cast<const RegisterGuard*>(guard);
1161
1162 if (portGuard != NULL) {
1163 tpefMove->setGuardType(MoveElement::MF_UNIT);
1164
1165 FunctionUnit &funcUnit =
1166 *portGuard->port()->parentUnit();
1167
1168 ResourceElement &fu =
1169 updater.functionUnit(funcUnit);
1170 tpefMove->setGuardUnit(fu.id());
1171
1172 // is operation or special register port
1173 FunctionUnit *parentFu =
1174 portGuard->port()->parentUnit();
1175
1176 const FUPort *fuPort = portGuard->port();
1177
1178 if (parentFu->hasOperationPort(fuPort->name())) {
1179 HWOperation *oper = NULL;
1180
1181 // find just any operation that is
1182 // bound to guarded port
1183 for (int i = 0;
1184 i < parentFu->operationCount(); i++) {
1185 oper = parentFu->operation(i);
1186
1187 if (oper->isBound(*fuPort)) {
1188 break;
1189 }
1190
1191 oper = NULL;
1192 }
1193
1194 assert(oper != NULL);
1195
1196 ResourceElement &opPort =
1197 updater.operand(
1198 *oper, oper->io(*fuPort));
1199
1200 tpefMove->setGuardIndex(opPort.id());
1201
1202 } else {
1203 ResourceElement &fuPortResource =
1204 updater.functionUnitPort(*fuPort);
1205
1206 tpefMove->setGuardIndex(fuPortResource.id());
1207 }
1208
1209 } else if (registerGuard != NULL) {
1210 tpefMove->setGuardType(MoveElement::MF_RF);
1211
1212 const RegisterFile &regFile =
1213 *registerGuard->registerFile();
1214
1215 ResourceElement &rf =
1216 updater.registerFile(regFile);
1217
1218 tpefMove->setGuardUnit(rf.id());
1219
1220 tpefMove->setGuardIndex(
1221 registerGuard->registerIndex());
1222
1223 } else {
1224 abortWithError("Unknown machine guard type.");
1225 }
1226 }
1227 }
1228 }
1229
1230 // write long immediates
1231 for (int k = 0; k < currInstr.immediateCount(); k++) {
1232 Immediate& imm = currInstr.immediate(k);
1233
1234 ImmediateElement* tpefImm = new ImmediateElement();
1235
1236 tpefImm->setBegin(beginFlag);
1237 beginFlag = false;
1238
1239 if (imm.destination().immediateUnit().signExtends()) {
1240 tpefImm->setSignedLong(imm.value().value().sLongWordValue());
1241 } else {
1242 tpefImm->setULongWord(imm.value().value().uLongWordValue());
1243 }
1244
1245 ResourceID dstRes =
1246 terminalResource(imm.destination(), updater);
1247
1248 tpefImm->setDestinationUnit(dstRes.unit);
1249 tpefImm->setDestinationIndex(dstRes.index);
1250
1251 code->addElement(tpefImm);
1252
1253 // add relocation antries if needed
1254 if (imm.value().isInstructionAddress()) {
1255
1256 // TODO: check size of long immediate field
1257 RelocInfo newReloc(
1258 code, tpefImm,
1259 imm.value().address(),
1261
1262 relocInfos_.push_back(newReloc);
1263
1264 } else if (imm.value().isAddress()) {
1265
1266 // TODO: check size of long immediate field
1267 RelocInfo newReloc(
1268 code, tpefImm,
1269 imm.value().address(),
1271
1272 relocInfos_.push_back(newReloc);
1273
1274 }
1275 }
1276
1277 // add empty instruction (instruction containing one empty move)
1278 if (currInstr.moveCount() == 0 &&
1279 currInstr.immediateCount() == 0) {
1280
1281 MoveElement *tpefNOP = new MoveElement();
1282 tpefNOP->setBegin(true);
1283 tpefNOP->setEmpty(true);
1284
1285 if (currInstr.hasAnnotations()) {
1286 for (int annotationIndex = 0;
1287 annotationIndex < currInstr.annotationCount();
1288 ++annotationIndex) {
1289 const ProgramAnnotation& annot =
1290 currInstr.annotation(annotationIndex);
1291 tpefNOP->addAnnotation(
1293 annot.id(), annot.payload()));
1294 }
1295 }
1296 code->addElement(tpefNOP);
1297 }
1298 }
1299 }
1300}
#define assert(condition)
static SLongWord signExtendTo(SLongWord value, int width)
static int requiredBits(unsigned long int number)
static int requiredBitsSigned(SLongWord number)
static ULongWord zeroExtendTo(ULongWord value, int width)
static std::string disassemble(const TTAProgram::Move &move)
virtual void addElement(SectionElement *element)
void setDestinationIndex(Byte aDestinationIndex)
void setULongWord(ULongWord aValue)
Byte destinationIndex() const
void setDestinationUnit(Byte aDestinationUnit)
Byte destinationUnit() const
void setSignedLong(SLongWord aValue)
void setBegin(bool isBegin)
void addAnnotation(InstructionAnnotation *anAnnotation)
void setGuardIndex(HalfWord aGuardIndex)
void setSourceType(FieldType aType)
void setGuardInverted(bool flag)
bool isEmpty() const
void setSourceIndex(HalfWord aSourceIndex)
void setBus(HalfWord aBus)
void setDestinationUnit(HalfWord aDestinationUnit)
void setGuarded(bool flag)
void setSourceUnit(HalfWord aSourceUnit)
void setGuardUnit(HalfWord aGuardUnit)
void setDestinationIndex(HalfWord aDestinationIndex)
void setEmpty(bool flag)
void setDestinationType(FieldType aType)
void setGuardType(FieldType gType)
HalfWord id() const
void setStartingAddress(AddressImage address)
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasOperationPort(const std::string &name) const
virtual bool isInverted() const
int io(const FUPort &port) const
bool isBound(const FUPort &port) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
FUPort * port() const
virtual std::string name() const
Definition Port.cc:141
const RegisterFile * registerFile() const
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual Instruction & instructionAtIndex(int index) const
Move & move(int i) const
ResourceID terminalResource(const Terminal &term, TPEFResourceUpdater &updater) const
static const HalfWord IMMEDIATE_ADDRESS_WIDTH
Default widt that is used as address width of relocations of immediate elements. This should be fixed...
static const int MAX_SIMM_WIDTH
Maximum width for short immediates.

References __func__, abortWithError, TPEF::InstructionElement::addAnnotation(), TPEF::CodeSection::addElement(), TTAProgram::Instruction::address(), TTAProgram::Terminal::address(), TTAProgram::AnnotatedInstructionElement::annotation(), TTAProgram::AnnotatedInstructionElement::annotationCount(), assert, TTAProgram::Move::bus(), TTAProgram::TPEFResourceUpdater::bus(), TTAMachine::Machine::busNavigator(), TTAProgram::Immediate::destination(), TTAProgram::Move::destination(), TPEF::ImmediateElement::destinationIndex(), TPEF::ImmediateElement::destinationUnit(), POMDisassembler::disassemble(), TTAProgram::TPEFResourceUpdater::functionUnit(), TTAProgram::TPEFResourceUpdater::functionUnitPort(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), TTAMachine::FunctionUnit::hasOperationPort(), TTAProgram::ProgramAnnotation::id(), TPEF::ResourceElement::id(), TTAProgram::Instruction::immediate(), IMMEDIATE_ADDRESS_WIDTH, TTAProgram::Instruction::immediateCount(), TTAProgram::Terminal::immediateUnit(), TTAMachine::Bus::immediateWidth(), TTAProgram::ProgramWriter::ResourceID::index, TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAMachine::HWOperation::io(), TTAProgram::Terminal::isAddress(), TTAMachine::HWOperation::isBound(), TPEF::MoveElement::isEmpty(), TTAProgram::Terminal::isImmediate(), TTAProgram::Terminal::isInstructionAddress(), TTAMachine::Guard::isInverted(), TTAProgram::Move::isUnconditional(), TTAProgram::Address::location(), MAX_SIMM_WIDTH, TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAMachine::Component::name(), TTAMachine::Port::name(), TTAProgram::Procedure::name(), TTAProgram::TPEFResourceUpdater::operand(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), TTAProgram::Move::parent(), TTAMachine::BaseFUPort::parentUnit(), TTAProgram::ProgramAnnotation::payload(), TTAMachine::PortGuard::port(), TTAProgram::Program::procedure(), TTAProgram::Program::procedureCount(), prog_, TTAMachine::RegisterGuard::registerFile(), TTAProgram::TPEFResourceUpdater::registerFile(), TTAMachine::RegisterGuard::registerIndex(), relocInfos_, MathTools::requiredBits(), MathTools::requiredBitsSigned(), TPEF::InstructionElement::setBegin(), TPEF::MoveElement::setBus(), TPEF::ImmediateElement::setDestinationIndex(), TPEF::MoveElement::setDestinationIndex(), TPEF::MoveElement::setDestinationType(), TPEF::ImmediateElement::setDestinationUnit(), TPEF::MoveElement::setDestinationUnit(), TPEF::MoveElement::setEmpty(), TPEF::MoveElement::setGuarded(), TPEF::MoveElement::setGuardIndex(), TPEF::MoveElement::setGuardInverted(), TPEF::MoveElement::setGuardType(), TPEF::MoveElement::setGuardUnit(), TPEF::ImmediateElement::setSignedLong(), TPEF::MoveElement::setSourceIndex(), TPEF::MoveElement::setSourceType(), TPEF::MoveElement::setSourceUnit(), TPEF::Section::setStartingAddress(), TPEF::ImmediateElement::setULongWord(), TTAMachine::Bus::signExtends(), TTAMachine::ImmediateUnit::signExtends(), MathTools::signExtendTo(), SimValue::sLongWordValue(), TTAProgram::Move::source(), TTAProgram::Program::startAddress(), TTAProgram::Program::targetProcessor(), terminalResource(), Conversion::toString(), TTAProgram::ProgramWriter::ResourceID::type, SimValue::uLongWordValue(), TTAProgram::ProgramWriter::ResourceID::unit, SimValue::unsignedValue(), TTAProgram::Immediate::value(), TTAProgram::Terminal::value(), TTAProgram::TerminalImmediate::value(), and MathTools::zeroExtendTo().

Referenced by createBinary().

◆ createDataSections()

void TTAProgram::ProgramWriter::createDataSections ( TPEF::Binary bin,
bool  littleEndian 
) const
private

Creates data section to TPEF.

Parameters
binBinary to write the sections to.

Definition at line 1403 of file ProgramWriter.cc.

1403 {
1404
1405 std::map<AddressSpace*, ASpaceElement*> aSpaceMap;
1406
1407 ASpaceSection* aSpaceSection = dynamic_cast<ASpaceSection*>(
1408 bin->section(Section::ST_ADDRSP, 0));
1409
1410 StringSection* strings =
1411 dynamic_cast<StringSection*>(aSpaceSection->link());
1412
1413 // go through all the DataMemories of POM
1414 for (int i = 0; i < prog_.dataMemoryCount(); i++) {
1415 DataMemory& currMem = prog_.dataMemory(i);
1416
1417 UDataSection* currSect = NULL;
1418
1419 for (int j = 0; j < currMem.dataDefinitionCount(); j++) {
1420 DataDefinition& currDef = currMem.dataDefinition(j);
1421
1422 assert(&currDef.startAddress().space() ==
1423 &currMem.addressSpace());
1424
1425 // create new data dection if needed
1426 if (currSect == NULL ||
1427
1428 (currDef.isInitialized() &&
1429 !currSect->isDataSection()) ||
1430
1431 (!currDef.isInitialized() &&
1432 currSect->isDataSection()) ||
1433
1434 (currDef.startAddress().location() !=
1435 currSect->startingAddress() +
1436 currSect->lengthInMAUs())) {
1437
1438 if (currDef.isInitialized()) {
1439 if (!littleEndian) {
1440 currSect = dynamic_cast<DataSection*>(
1441 Section::createSection(Section::ST_DATA));
1442 } else {
1443 currSect = dynamic_cast<DataSection*>(
1444 Section::createSection(Section::ST_LEDATA));
1445 }
1446 } else {
1447 currSect = dynamic_cast<UDataSection*>(
1448 Section::createSection(Section::ST_UDATA));
1449 }
1450
1451 // add section to binary
1452 assert (currSect != NULL);
1453 bin->addSection(currSect);
1454
1455 currSect->setStartingAddress(
1456 currDef.startAddress().location());
1457
1458 currSect->setName(strings->string2Chunk(""));
1459
1460 currSect->setLink(bin->section(Section::ST_NULL,0));
1461
1462 const AddressSpace& adfASpace = currMem.addressSpace();
1463 currSect->setASpace(&createASpaceElement(adfASpace, *bin));
1464 }
1465
1466 // add data to section
1467 if (currDef.isInitialized()) {
1468 DataSection* dataSect = dynamic_cast<DataSection*>(currSect);
1469
1470 int byteOffset = dataSect->length();
1471
1472 for (int k = 0; k < currDef.size(); k++) {
1473 dataSect->addMAU(currDef.MAU(k));
1474 }
1475
1476 if (currDef.isAddress()) {
1477 RelocInfo newReloc(
1478 dataSect, dataSect->chunk(byteOffset),
1479 currDef.destinationAddress(),
1480 currDef.size() * dataSect->aSpace()->MAU());
1481
1482 relocInfos_.push_back(newReloc);
1483 }
1484
1485 } else {
1486 currSect->setLengthInMAUs(
1487 currSect->lengthInMAUs() + currDef.size());
1488 }
1489
1490
1491#if 0
1492 // Prints debug data of all encountered data definitions.
1493 if (currSect != NULL) {
1495 << "datadef: addr: "
1496 << currDef.startAddress().space().name() << ":"
1497 << currDef.startAddress().location()
1498 << "\t" << "size: " << currDef.size()
1499 << "\t" << "init: " << currDef.isInitialized()
1500 << "\t" << "isAddr: " << currDef.isAddress();
1501 if (currDef.isAddress()) {
1503 << "\t" << "dest: "
1504 << currDef.destinationAddress().space().name() << ":"
1505 << currDef.destinationAddress().location();
1506 }
1508 << std::endl;
1509 }
1510#endif
1511
1512#if 0
1513 // prints out debug data of all created data sections
1514 if (currSect != NULL) {
1515 DataSection* dSectTmp = dynamic_cast<DataSection*>(currSect);
1517 << "data section " << currSect << " length: "
1518 << currSect->lengthInMAUs()
1519 << "\tstart address: "
1520 << TPEFTools::addressSpaceName(
1521 *bin, *currSect->aSpace())
1522 << ":" << currSect->startingAddress()
1523 << "\tinitialized: "
1524 // << static_cast<int>(currSect->isDataSection())
1525 << (dSectTmp?true:false)
1526 << std::endl;
1527 }
1528#endif
1529
1530 }
1531 }
1532}
static std::ostream & logStream()
Byte MAU() const
virtual void addMAU(MinimumAddressableUnit aMAU)
virtual Word length() const
virtual void setLengthInMAUs(Word length)
Definition Section.cc:265
Section * link() const
virtual bool isDataSection() const
Definition Section.hh:142
DataMemory & dataMemory(int index) const
Definition Program.cc:967
int dataMemoryCount() const
Definition Program.cc:942

References TPEF::DataSection::addMAU(), TTAProgram::DataMemory::addressSpace(), TPEF::Binary::addSection(), TPEF::Section::aSpace(), assert, TPEF::RawSection::chunk(), createASpaceElement(), TTAProgram::DataMemory::dataDefinition(), TTAProgram::DataMemory::dataDefinitionCount(), TTAProgram::Program::dataMemory(), TTAProgram::Program::dataMemoryCount(), TTAProgram::DataDefinition::destinationAddress(), TTAProgram::DataDefinition::isAddress(), TPEF::Section::isDataSection(), TTAProgram::DataDefinition::isInitialized(), TPEF::DataSection::length(), TPEF::RawSection::lengthInMAUs(), TPEF::Section::link(), TTAProgram::Address::location(), Application::logStream(), TPEF::ASpaceElement::MAU(), TTAProgram::DataDefinition::MAU(), TTAMachine::Component::name(), prog_, relocInfos_, TPEF::Binary::section(), TPEF::Section::setASpace(), TPEF::RawSection::setLengthInMAUs(), TPEF::Section::setLink(), TPEF::Section::setName(), TPEF::Section::setStartingAddress(), TTAProgram::DataDefinition::size(), TTAProgram::Address::space(), TTAProgram::DataDefinition::startAddress(), TPEF::Section::startingAddress(), and TPEF::StringSection::string2Chunk().

Referenced by createBinary().

Here is the call graph for this function:

◆ createRelocSections()

void TTAProgram::ProgramWriter::createRelocSections ( TPEF::Binary bin) const
private

Create relocation tables to binary and add relocation elements.

Parameters
binBinary where to add relocation sections.
Exceptions
NotAvailableCan't find needed resource.

Definition at line 1578 of file ProgramWriter.cc.

1578 {
1579 StringSection* strings = dynamic_cast<StringSection*>(
1580 bin->section(Section::ST_STRTAB,0));
1581
1582 ASpaceSection* aSpaces = dynamic_cast<ASpaceSection*>(
1583 bin->section(Section::ST_ADDRSP,0));
1584
1585 SymbolSection* symbols = dynamic_cast<SymbolSection*>(
1586 bin->section(Section::ST_SYMTAB, 0));
1587
1588 RelocSection* currRelocs = NULL;
1589
1590 for (int i = 0; i < static_cast<int>(relocInfos_.size()); i++) {
1591 RelocInfo& currReloc = relocInfos_[i];
1592
1593 Section& dstSect = findSection(*bin, currReloc.destination);
1594
1595 // create new reloc section if needed
1596 if (currRelocs == NULL ||
1597 currRelocs->referencedSection() != currReloc.srcSect) {
1598
1599 currRelocs = dynamic_cast<RelocSection*>(
1600 Section::createSection(Section::ST_RELOC));
1601 bin->addSection(currRelocs);
1602
1603 currRelocs->setName(strings->string2Chunk(""));
1604 currRelocs->setLink(symbols);
1605 currRelocs->setASpace(aSpaces->undefinedASpace());
1606 currRelocs->setReferencedSection(currReloc.srcSect);
1607 }
1608
1609 SectionElement* dstElem = NULL;
1610
1611 // get element by address (destination element)
1612 if (dstSect.isCodeSection()) {
1613 CodeSection& codeSect =
1614 dynamic_cast<CodeSection&>(dstSect);
1615
1616 dstElem = &codeSect.instruction(
1617 currReloc.destination.location() -
1618 codeSect.startingAddress());
1619
1620 } else {
1621 UDataSection& dataSect =
1622 dynamic_cast<UDataSection&>(dstSect);
1623
1624 int byteOffset = dataSect.MAUsToBytes(
1625 currReloc.destination.location() -
1626 dataSect.startingAddress());
1627
1628 dstElem = dataSect.chunk(byteOffset);
1629 }
1630
1631 RelocElement* newReloc = new RelocElement();
1632 currRelocs->addElement(newReloc);
1633
1634 newReloc->setType(RelocElement::RT_SELF);
1635
1636 newReloc->setLocation(currReloc.srcElem);
1637
1638 newReloc->setDestination(dstElem);
1639
1640 newReloc->setSymbol(
1641 dynamic_cast<SymbolElement*>(symbols->element(0)));
1642
1643 newReloc->setASpace(
1645 currReloc.destination.space(), *bin));
1646
1647 newReloc->setSize(currReloc.bits);
1648
1649 }
1650}
ASpaceElement * undefinedASpace() const
void setASpace(ASpaceElement *anASpace)
void setLocation(SectionElement *aLocation)
void setSize(Byte aSize)
void setSymbol(SymbolElement *aSymbol)
void setType(RelocType aType)
void setDestination(SectionElement *aDestination)
void setReferencedSection(Section *section)
Section * referencedSection() const
virtual bool isCodeSection() const
Definition Section.hh:143
TPEF::Section & findSection(TPEF::Binary &bin, Address address) const

References TPEF::Section::addElement(), TPEF::Binary::addSection(), TTAProgram::ProgramWriter::RelocInfo::bits, TPEF::RawSection::chunk(), createASpaceElement(), TTAProgram::ProgramWriter::RelocInfo::destination, TPEF::Section::element(), findSection(), TPEF::CodeSection::instruction(), TPEF::Section::isCodeSection(), TTAProgram::Address::location(), TPEF::RawSection::MAUsToBytes(), TPEF::RelocSection::referencedSection(), relocInfos_, TPEF::Binary::section(), TPEF::RelocElement::setASpace(), TPEF::Section::setASpace(), TPEF::RelocElement::setDestination(), TPEF::Section::setLink(), TPEF::RelocElement::setLocation(), TPEF::Section::setName(), TPEF::RelocSection::setReferencedSection(), TPEF::RelocElement::setSize(), TPEF::RelocElement::setSymbol(), TPEF::RelocElement::setType(), TTAProgram::Address::space(), TTAProgram::ProgramWriter::RelocInfo::srcElem, TTAProgram::ProgramWriter::RelocInfo::srcSect, TPEF::Section::startingAddress(), TPEF::StringSection::string2Chunk(), and TPEF::ASpaceSection::undefinedASpace().

Referenced by createBinary().

Here is the call graph for this function:

◆ findSection()

TPEF::Section & TTAProgram::ProgramWriter::findSection ( TPEF::Binary bin,
Address  address 
) const
private

Finds section which contain requested address.

Parameters
binTPEF where from sections are searched.
addressThe address that are looked for.
Returns
The section which contains requested address.

Definition at line 1660 of file ProgramWriter.cc.

1660 {
1661
1662 for (int i = 0; i < static_cast<int>(bin.sectionCount()); i++) {
1663 Section& currSect = *bin.section(i);
1664
1665 if (currSect.isProgramSection()) {
1666 if (currSect.startingAddress() <= address.location() &&
1667 &createASpaceElement(address.space(), bin) ==
1668 currSect.aSpace()) {
1669
1670 if (currSect.isCodeSection()) {
1671 CodeSection& codeSect =
1672 dynamic_cast<CodeSection&>(currSect);
1673
1674 if (codeSect.instructionCount() +
1675 codeSect.startingAddress() > address.location()) {
1676
1677 return codeSect;
1678 }
1679 } else {
1680 UDataSection& dataSect =
1681 dynamic_cast<UDataSection&>(currSect);
1682
1683 if (dataSect.startingAddress() +
1684 dataSect.lengthInMAUs() > address.location()) {
1685
1686 return dataSect;
1687 }
1688 }
1689 }
1690 }
1691 }
1692
1693 throw NotAvailable(
1694 __FILE__, __LINE__, __func__,
1695 "Can't find section containing address: " + address.space().name() +
1696 ":" + Conversion::toString(address.location()));
1697}
Word instructionCount() const
bool isProgramSection() const

References __func__, TPEF::Section::aSpace(), createASpaceElement(), TPEF::CodeSection::instructionCount(), TPEF::Section::isCodeSection(), TPEF::Section::isProgramSection(), TPEF::RawSection::lengthInMAUs(), TTAProgram::Address::location(), TTAMachine::Component::name(), TPEF::Binary::section(), TPEF::Binary::sectionCount(), TTAProgram::Address::space(), TPEF::Section::startingAddress(), and Conversion::toString().

Referenced by createRelocSections().

Here is the call graph for this function:

◆ resolveFileType()

TPEF::Binary::FileType TTAProgram::ProgramWriter::resolveFileType ( TPEF::ResourceSection resources) const
private

Find out the kind of TPEF file type.

This method scans the resource section and checks the type of processor resource elements it contains. Based on their types, it figures out what should be the file type.

Parameters
resourcesResource section.
Returns
File type of TPEF binary.

Definition at line 1711 of file ProgramWriter.cc.

1711 {
1712
1713 bool univRefs = false;
1714 bool realRefs = false;
1715
1716 for (unsigned int i = 0; i < resources.elementCount(); i++) {
1717 ResourceElement* res =
1718 dynamic_cast<ResourceElement*>(resources.element(i));
1719
1720 switch(res->type()) {
1721
1722 case ResourceElement::MRT_BUS:
1723 if (res->id() == ResourceElement::UNIVERSAL_BUS) {
1724 univRefs = true;
1725 } else {
1726 realRefs = true;
1727 }
1728 break;
1729
1730 case ResourceElement::MRT_UNIT:
1731 if (res->id() == ResourceElement::UNIVERSAL_FU) {
1732 univRefs = true;
1733 } else {
1734 realRefs = true;
1735 }
1736 break;
1737
1738 case ResourceElement::MRT_RF:
1739 if (res->id() == ResourceElement::INT_RF ||
1740 res->id() == ResourceElement::BOOL_RF ||
1741 res->id() == ResourceElement::FP_RF) {
1742 univRefs = true;
1743 } else {
1744 realRefs = true;
1745 }
1746 break;
1747
1748 case ResourceElement::MRT_IMM:
1749 realRefs = true;
1750 break;
1751
1752 default:
1753 ;// just omit MRT_PORT, MRT_SR and MRT_OP
1754 }
1755 }
1756
1757 if (univRefs && realRefs) {
1758 return Binary::FT_MIXED;
1759 } else if (univRefs) {
1760 return Binary::FT_PURESEQ;
1761 } else if (!univRefs && realRefs) {
1762 return Binary::FT_PARALLEL;
1763 }
1764
1765 return Binary::FT_NULL;
1766}
ResourceType type() const

References TPEF::Section::element(), TPEF::Section::elementCount(), TPEF::ResourceElement::id(), and TPEF::ResourceElement::type().

Referenced by createBinary().

Here is the call graph for this function:

◆ terminalResource()

ProgramWriter::ResourceID TTAProgram::ProgramWriter::terminalResource ( const Terminal term,
TPEFResourceUpdater updater 
) const
private

Finds out resource element and index by terminal.

Parameters
termTerminal whose TPEF resource information is needed.
updaterResource updater for finding TPEF resources.

Definition at line 1310 of file ProgramWriter.cc.

1312 {
1313
1314 ResourceID retVal;
1315 retVal.type = MoveElement::MF_RF;
1316 retVal.unit = 0;
1317 retVal.index = 0;
1318
1319 try {
1320
1321 if (term.isImmediate()) {
1323 "This function should never be called with ImmediateTerminal "
1324 " instance type.");
1325
1326 } else if (term.isGPR()) {
1327 retVal.type = MoveElement::MF_RF;
1328 retVal.unit = updater.registerFile(term.registerFile()).id();
1329 retVal.index = term.index();
1330
1331 } else if (term.isImmediateRegister()) {
1332 retVal.type = MoveElement::MF_IMM;
1333 retVal.unit = updater.immediateUnit(term.immediateUnit()).id();
1334 retVal.index = term.index();
1335
1336 } else if (term.isFUPort()) {
1337
1338 retVal.type = MoveElement::MF_UNIT;
1339
1340 FunctionUnit &fu =
1341 *dynamic_cast<FunctionUnit*>(term.port().parentUnit());
1342
1343 retVal.unit = updater.functionUnit(fu).id();
1344
1345 const TerminalFUPort& fuTerm =
1346 dynamic_cast<const TerminalFUPort&>(term);
1347
1348 // find if there is information of operation in terminal
1349 if (&fuTerm.hintOperation() != &NullOperation::instance() ||
1350 fuTerm.isOpcodeSetting()) {
1351
1352 std::string operationName =
1353 (fuTerm.isOpcodeSetting()) ?
1354 (fuTerm.operation().name()) :
1355 (fuTerm.hintOperation().name());
1356
1357 if (fu.hasOperation(operationName)) {
1358 HWOperation *oper = fu.operation(operationName);
1359
1360 int index = oper->io(
1361 dynamic_cast<const FUPort&>(term.port()));
1362
1363 retVal.index = updater.operand(*oper, index).id();
1364
1365 } else {
1367 "Can't find operation " + operationName +
1368 " from FU: " + fu.name());
1369 }
1370
1371 } else {
1372 // not opcode setting normal fu port without operation hint
1373 assert(!fuTerm.isOpcodeSetting());
1374 ResourceElement &fuPort =
1375 updater.functionUnitPort(term.port());
1376 retVal.index = fuPort.id();
1377 }
1378
1379 } else {
1380 abortWithError("Unknown terminal type.");
1381 }
1382
1383 } catch (const InvalidData& e) {
1384 NotAvailable error(__FILE__, __LINE__, __func__,
1385 "Problems with finding terminal: " +
1386 e.errorMessage());
1387
1388 error.setCause(e);
1389
1390 throw error;
1391 }
1392
1393 return retVal;
1394}
std::string errorMessage() const
Definition Exception.cc:123
static NullOperation & instance()
virtual bool hasOperation(const std::string &name) const

References __func__, abortWithError, assert, Exception::errorMessage(), TTAProgram::TPEFResourceUpdater::functionUnit(), TTAProgram::TPEFResourceUpdater::functionUnitPort(), TTAMachine::FunctionUnit::hasOperation(), TTAProgram::TerminalFUPort::hintOperation(), TPEF::ResourceElement::id(), TTAProgram::Terminal::immediateUnit(), TTAProgram::TPEFResourceUpdater::immediateUnit(), TTAProgram::ProgramWriter::ResourceID::index, TTAProgram::Terminal::index(), NullOperation::instance(), TTAMachine::HWOperation::io(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediate(), TTAProgram::Terminal::isImmediateRegister(), TTAProgram::TerminalFUPort::isOpcodeSetting(), TTAMachine::Component::name(), Operation::name(), TTAProgram::TPEFResourceUpdater::operand(), TTAProgram::TerminalFUPort::operation(), TTAMachine::FunctionUnit::operation(), TTAMachine::Port::parentUnit(), TTAProgram::Terminal::port(), TTAProgram::Terminal::registerFile(), TTAProgram::TPEFResourceUpdater::registerFile(), Exception::setCause(), TTAProgram::ProgramWriter::ResourceID::type, and TTAProgram::ProgramWriter::ResourceID::unit.

Referenced by createCodeSection().

Here is the call graph for this function:

Member Data Documentation

◆ aSpaceMap_

std::map<const TTAMachine::AddressSpace*, TPEF::ASpaceElement*> TTAProgram::ProgramWriter::aSpaceMap_
mutableprivate

Created TPEF binary.

Map that contains created address spaces

Definition at line 209 of file ProgramWriter.hh.

Referenced by createASpaceElement(), and createBinary().

◆ IMMEDIATE_ADDRESS_WIDTH

const HalfWord TTAProgram::ProgramWriter::IMMEDIATE_ADDRESS_WIDTH = WORD_BITWIDTH
staticprivate

Default widt that is used as address width of relocations of immediate elements. This should be fixed by checking width from bus or template.

Definition at line 215 of file ProgramWriter.hh.

Referenced by createCodeSection().

◆ MAX_SIMM_WIDTH

const int TTAProgram::ProgramWriter::MAX_SIMM_WIDTH = 64
staticprivate

Maximum width for short immediates.

Definition at line 218 of file ProgramWriter.hh.

Referenced by createCodeSection().

◆ prog_

const Program& TTAProgram::ProgramWriter::prog_
private

Program that is written to TPEF.

Definition at line 203 of file ProgramWriter.hh.

Referenced by createASpaceElement(), createBinary(), createCodeSection(), and createDataSections().

◆ relocInfos_

std::vector<RelocInfo> TTAProgram::ProgramWriter::relocInfos_
mutableprivate

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