34#include <boost/format.hpp>
153 mach_(mach), resources_(resources),
154 lastBusId_(1), lastUnitPortId_(1),
155 lastFunctionUnitId_(1), lastRegisterFileId_(1),
156 lastImmediateUnitId_(1) {
180 switch(currRes->
type()) {
182 case ResourceElement::MRT_NULL: {
186 case ResourceElement::MRT_BUS: {
188 assert(navi.hasItem(resourceName));
189 Bus *
bus = navi.item(resourceName);
194 case ResourceElement::MRT_UNIT: {
195 Machine::FunctionUnitNavigator navi =
197 assert(navi.hasItem(resourceName));
199 if (lastFunctionUnitId_ < currRes->
id()) {
208 case ResourceElement::MRT_RF: {
209 Machine::RegisterFileNavigator navi =
211 assert(navi.hasItem(resourceName));
213 if (lastRegisterFileId_ < currRes->
id()) {
222 case ResourceElement::MRT_OP: {
223 std::string::size_type dotPos = resourceName.find(
'.');
224 assert(dotPos != std::string::npos);
226 std::string operName = resourceName.substr(0, dotPos);
230 dotPos+1, resourceName.length() - dotPos - 1));
232 Machine::FunctionUnitNavigator navi =
235 if (lastUnitPortId_ < currRes->
id()) {
240 for (
int i = 0; i < navi.count(); i++) {
250 case ResourceElement::MRT_IMM: {
251 Machine::ImmediateUnitNavigator navi =
253 assert(navi.hasItem(resourceName));
255 if (lastImmediateUnitId_ < currRes->
id()) {
265 case ResourceElement::MRT_PORT:
266 case ResourceElement::MRT_SR: {
267 Machine::FunctionUnitNavigator navi =
270 if (lastUnitPortId_ < currRes->
id()) {
275 for (
int i = 0; i < navi.count(); i++) {
278 if (fu->
hasPort(resourceName)) {
323 newRes->
setType(ResourceElement::MRT_BUS);
336 newRes->
setId(ResourceElement::UNIVERSAL_BUS);
339 boost::format unexpectedBusMsg(
340 "Unexpected bus '%1%' in universal machine in addition "
341 "to the unique universal bus '%2%'.");
352 std::cerr <<
"added MRT_BUS resource type: " << newRes->
type()
353 <<
"\tid:" << newRes->
id() <<
"\tname: "
380 newRes->
setType(ResourceElement::MRT_PORT);
385 newRes->
setType(ResourceElement::MRT_SR);
389 "Port must be either FUPort or SpecialRegisterPort!");
407 ResourceElement::RETURN_ADDRESS_NAME));
414 boost::format unexpectedPortMsg(
415 "Port '%1%' in universal global control unit. "
416 "Normal RF and FU ports are not allowed there.");
417 unexpectedPortMsg % port.
name();
424 boost::format unexpectedSRPortMsg(
425 "The special register port '%1%' is not one of "
426 "the ports currently supported by the global "
428 unexpectedSRPortMsg % port.
name();
437 std::cerr <<
"added MRT_SR resource type: " << newRes->
type()
438 <<
"\tid:" << newRes->
id() <<
"\tname: "
471 newRes->
setType(ResourceElement::MRT_OP);
481 std::cerr <<
"Added MRT_OP resource type: " << newRes->
type()
482 <<
"\tid:" << newRes->
id() <<
"\tname: "
491 operandIndex)] = newRes;
494 "Parent unit: " + parentUnit->
name() +
495 " didn't contain requested operation:" + oper.
name());
519 newRes->
setType(ResourceElement::MRT_UNIT);
549 newRes->
setId(ResourceElement::UNIVERSAL_FU);
555 "Unknown universal machine reference to function unit: " +
565 std::cerr <<
"added MRT_UNIT resource type: " << newRes->
type()
566 <<
"\tid:" << newRes->
id() <<
"\tname: "
592 newRes->
setType(ResourceElement::MRT_RF);
605 newRes->
setId(ResourceElement::BOOL_RF);
607 newRes->
setId(ResourceElement::INT_RF);
609 newRes->
setId(ResourceElement::FP_RF);
612 "Reference to unknown universal register file.");
622 std::cerr <<
"added MRT_RF resource type: " << newRes->
type()
623 <<
"\tid:" << newRes->
id() <<
"\tname: "
652 newRes->
setType(ResourceElement::MRT_IMM);
661 std::cerr <<
"added MRT_IMM resource type: " << newRes->
type()
662 <<
"\tid:" << newRes->
id() <<
"\tname: "
705 Section::createSection(Section::ST_NULL));
708 Section::createSection(Section::ST_STRTAB));
712 Section::createSection(Section::ST_ADDRSP));
726 adfInstrASpace->
end())) {
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: "
743 Section::createSection(Section::ST_MR));
746 dynamic_cast<CodeSection*
>(Section::createSection(Section::ST_CODE));
750 Section::createSection(Section::ST_SYMTAB));
766 nullSection->
setLink(nullSection);
807 procedSym->
setBinding(SymbolElement::STB_LOCAL);
830 codeSym->
setBinding(SymbolElement::STB_GLOBAL);
850 dataSym->
setBinding(SymbolElement::STB_GLOBAL);
860 newBin->
section(Section::ST_ADDRSP,0));
869 if (TPEFTools::addressSpaceName(*newBin, *currElem) ==
872 dstASpace = currElem;
877 if (dstASpace == NULL) {
880 std::string(
"Cannot find address space ") +
882 " for data label " + currLabel.
name());
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 &&
901 dstSection = currSect;
906 if (dstSection == NULL) {
929 newBin->
setArch(Binary::FA_TTA_TUT);
961 for (
int i = 0; i < navi.count(); i++) {
964 updater.
bus(*navi.item(i));
974 HalfWord immediateIndex = 0;
975 bool beginFlag =
true;
977 for (
int k = 0; k < currInstr.
moveCount(); k++) {
988 for (
int annotationIndex = 0;
1010 std::cerr <<
"src type: " << sourceId.
type
1011 <<
"\tunit: " << sourceId.
unit
1012 <<
"\tindex: " << sourceId.
index
1032 for (
int annotationIndex = 0;
1034 ++annotationIndex) {
1046 unsigned long wordToStore =
1049 unsigned long uvalue = wordToStore;
1050 int requiredBits = 0;
1056 long svalue =
static_cast<long>(uvalue);
1059 svalue, fieldWidth);
1068 if (requiredBits <= fieldWidth) {
1071 wordToStore, fieldWidth);
1077 message << currProcedure.
name() <<
" Move: " <<
1078 disasm <<
" Inline immediate value " <<
1080 " of required width " <<
1084 " doesn't fit to bus: " <<
1088 __FILE__, __LINE__,
__func__, message);
1097 ResourceElement::INLINE_IMM);
1137 std::cerr <<
"dst type: " << destinationId.
type
1138 <<
"\tunit: " << destinationId.
unit
1139 <<
"\tindex: " << destinationId.
index
1162 if (portGuard != NULL) {
1198 *oper, oper->
io(*fuPort));
1209 }
else if (registerGuard != NULL) {
1286 for (
int annotationIndex = 0;
1288 ++annotationIndex) {
1315 retVal.
type = MoveElement::MF_RF;
1323 "This function should never be called with ImmediateTerminal "
1326 }
else if (term.
isGPR()) {
1327 retVal.
type = MoveElement::MF_RF;
1332 retVal.
type = MoveElement::MF_IMM;
1338 retVal.
type = MoveElement::MF_UNIT;
1352 std::string operationName =
1360 int index = oper->
io(
1367 "Can't find operation " + operationName +
1368 " from FU: " + fu.
name());
1385 "Problems with finding terminal: " +
1405 std::map<AddressSpace*, ASpaceElement*> aSpaceMap;
1408 bin->
section(Section::ST_ADDRSP, 0));
1426 if (currSect == NULL ||
1439 if (!littleEndian) {
1441 Section::createSection(Section::ST_DATA));
1444 Section::createSection(Section::ST_LEDATA));
1448 Section::createSection(Section::ST_UDATA));
1452 assert (currSect != NULL);
1470 int byteOffset = dataSect->
length();
1472 for (
int k = 0; k < currDef.
size(); k++) {
1478 dataSect, dataSect->
chunk(byteOffset),
1493 if (currSect != NULL) {
1495 <<
"datadef: addr: "
1498 <<
"\t" <<
"size: " << currDef.
size()
1500 <<
"\t" <<
"isAddr: " << currDef.
isAddress();
1514 if (currSect != NULL) {
1517 <<
"data section " << currSect <<
" length: "
1519 <<
"\tstart address: "
1520 << TPEFTools::addressSpaceName(
1521 *bin, *currSect->
aSpace())
1523 <<
"\tinitialized: "
1525 << (dSectTmp?
true:
false)
1548 bin.
section(Section::ST_STRTAB,0));
1556 if (&addressSpace ==
1580 bin->
section(Section::ST_STRTAB,0));
1583 bin->
section(Section::ST_ADDRSP,0));
1586 bin->
section(Section::ST_SYMTAB, 0));
1590 for (
int i = 0; i < static_cast<int>(
relocInfos_.size()); i++) {
1596 if (currRelocs == NULL ||
1600 Section::createSection(Section::ST_RELOC));
1628 dstElem = dataSect.
chunk(byteOffset);
1634 newReloc->
setType(RelocElement::RT_SELF);
1662 for (
int i = 0; i < static_cast<int>(bin.
sectionCount()); i++) {
1695 "Can't find section containing address: " + address.
space().
name() +
1713 bool univRefs =
false;
1714 bool realRefs =
false;
1716 for (
unsigned int i = 0; i < resources.
elementCount(); i++) {
1720 switch(res->
type()) {
1722 case ResourceElement::MRT_BUS:
1723 if (res->
id() == ResourceElement::UNIVERSAL_BUS) {
1730 case ResourceElement::MRT_UNIT:
1731 if (res->
id() == ResourceElement::UNIVERSAL_FU) {
1738 case ResourceElement::MRT_RF:
1739 if (res->
id() == ResourceElement::INT_RF ||
1740 res->
id() == ResourceElement::BOOL_RF ||
1741 res->
id() == ResourceElement::FP_RF) {
1748 case ResourceElement::MRT_IMM:
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;
1765 return Binary::FT_NULL;
#define abortWithError(message)
#define assert(condition)
static std::ostream & logStream()
static std::string toString(const T &source)
static int toInt(const T &source)
std::string errorMessage() const
void setCause(const Exception &cause)
static NullOperation & instance()
virtual TCEString name() const
static std::string disassemble(const TTAProgram::Move &move)
ULongWord uLongWordValue() const
unsigned int unsignedValue() const
SLongWord sLongWordValue() const
void setName(const ReferenceManager::SafePointer *aName)
ASpaceElement * undefinedASpace() const
void setUndefinedASpace(ASpaceElement *aSpace)
void addSection(Section *section)
void setArch(FileArchitecture arch)
Word sectionCount() const
Section * section(Word index) const
void setType(FileType type)
void setStrings(StringSection *strTable)
InstructionElement & instruction(Word index) const
virtual void addElement(SectionElement *element)
Word instructionCount() const
void setReference(InstructionElement *aReference)
virtual void addMAU(MinimumAddressableUnit aMAU)
virtual Word length() const
virtual void addByte(Byte aByte)
void setReference(Chunk *aReference)
void setBegin(bool isBegin)
void addAnnotation(InstructionAnnotation *anAnnotation)
void setGuardIndex(HalfWord aGuardIndex)
void setSourceType(FieldType aType)
void setGuardInverted(bool flag)
void setSourceIndex(HalfWord aSourceIndex)
void setBus(HalfWord aBus)
void setDestinationUnit(HalfWord aDestinationUnit)
void setGuarded(bool flag)
void setSourceUnit(HalfWord aSourceUnit)
void setGuardUnit(HalfWord aGuardUnit)
void setDestinationIndex(HalfWord aDestinationIndex)
void setDestinationType(FieldType aType)
void setGuardType(FieldType gType)
virtual void setLengthInMAUs(Word length)
virtual Chunk * chunk(SectionOffset offset) const
virtual Word MAUsToBytes(Word mauCount) const
virtual Word lengthInMAUs() const
void setASpace(ASpaceElement *anASpace)
void setLocation(SectionElement *aLocation)
void setSymbol(SymbolElement *aSymbol)
void setType(RelocType aType)
void setDestination(SectionElement *aDestination)
void setReferencedSection(Section *section)
Section * referencedSection() const
ResourceType type() const
void setName(ReferenceManager::SafePointer *aName)
void setType(ResourceType aType)
AddressImage startingAddress() const
bool isProgramSection() const
virtual void addElement(SectionElement *element)
void setStartingAddress(AddressImage address)
SectionElement * element(Word index) const
virtual bool isCodeSection() 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
virtual bool isDataSection() const
std::string chunk2String(const Chunk *chunk) const
Chunk * string2Chunk(const std::string &str)
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 int width() const
virtual ULongWord start() const
FunctionUnit * parentUnit() const
int immediateWidth() const
virtual Machine * machine() const
virtual TCEString name() const
SpecialRegisterPort * returnAddressPort() const
bool hasReturnAddressPort() const
virtual AddressSpace * addressSpace() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual bool hasOperationPort(const std::string &name) const
virtual bool hasOperation(const std::string &name) const
virtual BaseFUPort * port(const std::string &name) const
virtual bool isInverted() const
int io(const FUPort &port) const
const std::string & name() const
bool isBound(const FUPort &port) const
FunctionUnit * parentUnit() const
virtual RegisterFileNavigator registerFileNavigator() const
virtual FunctionUnitNavigator functionUnitNavigator() const
bool isLittleEndian() const
virtual ImmediateUnitNavigator immediateUnitNavigator() const
virtual BusNavigator busNavigator() const
virtual ControlUnit * controlUnit() const
Unit * parentUnit() const
virtual std::string name() const
int registerIndex() const
const RegisterFile * registerFile() const
virtual bool hasPort(const std::string &name) const
const TTAMachine::AddressSpace & space() const
InstructionAddress location() 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 Address address() const
virtual int instructionCount() const
virtual Address startAddress() const
virtual Instruction & instructionAtIndex(int index) const
virtual Address startAddress() const
virtual bool isAddress() const
virtual bool isInitialized() const
virtual MinimumAddressableUnit MAU(int index) const
virtual Address destinationAddress() const
DataDefinition & dataDefinition(Address address) const
int dataDefinitionCount() const
const TTAMachine::AddressSpace & addressSpace() const
const DataLabel & globalDataLabel(Address address, int index) const
const CodeLabel & globalCodeLabel(Address address, int index) const
int globalDataLabelCount(Address address) const
int globalCodeLabelCount(Address address) const
int immediateCount() const
Immediate & immediate(int i) const
virtual Address address() const
const TTAMachine::Guard & guard() const
MoveGuard & guard() const
bool isUnconditional() const
Instruction & parent() const
Terminal & source() const
Terminal & destination() const
const TTAMachine::Bus & bus() const
const std::vector< Byte > & payload() const
ProgramAnnotation::Id id() 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
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...
const Program & prog_
Program that is written to TPEF.
TPEF::Binary * createBinary() const
TPEF::Binary::FileType resolveFileType(TPEF::ResourceSection &resources) const
ProgramWriter(const Program &prog)
TPEF::Section & findSection(TPEF::Binary &bin, Address address) const
std::map< const TTAMachine::AddressSpace *, TPEF::ASpaceElement * > aSpaceMap_
Created TPEF binary.
TPEF::ASpaceElement & createASpaceElement(const TTAMachine::AddressSpace &addressSpace, TPEF::Binary &bin) const
static const int MAX_SIMM_WIDTH
Maximum width for short immediates.
Procedure & procedure(int index) const
Address startAddress() const
const GlobalScope & globalScopeConst() const
TTAMachine::Machine & targetProcessor() const
DataMemory & dataMemory(int index) const
int procedureCount() const
int instructionCount() const
int dataMemoryCount() const
HalfWord lastUnitPortId_
Last TPEF unit port id that was generated.
TPEF::ResourceElement & registerFile(const TTAMachine::RegisterFile &rf)
TPEF::ResourceElement & bus(const TTAMachine::Bus &bus)
HalfWord lastBusId_
Last TPEF bus id that was generated.
HalfWord lastFunctionUnitId_
Last TPEF function unit id that was generated.
TPEF::ResourceElement & functionUnit(const TTAMachine::FunctionUnit &fu)
TPEFResourceUpdater(TTAMachine::Machine &mach, TPEF::ResourceSection &resources)
TPEF::ResourceElement & immediateUnit(const TTAMachine::ImmediateUnit &immUnit)
HalfWord lastRegisterFileId_
Last TPEF register file id that was generated.
TPEF::ResourceElement & operand(const TTAMachine::HWOperation &oper, int operandIndex)
TPEF::ResourceSection & resources_
The TPEF input section that contains all machine resource entries.
std::pair< const TTAMachine::MachinePart *, int > CacheKey
HalfWord lastImmediateUnitId_
Last TPEF immediate unit id that was generated.
TTAMachine::Machine & mach_
The model of the target processor architecture.
TPEF::ResourceElement & functionUnitPort(const TTAMachine::Port &port)
ResourceCache cache_
Aggregate of all mappings between machine resource entries and target processor parts (machine parts)...
virtual Operation & hintOperation() const
virtual Operation & operation() const
virtual bool isOpcodeSetting() const
virtual SimValue value() const
virtual bool isAddress() const
virtual int index() const
virtual Address address() const
virtual bool isGPR() const
virtual bool isInstructionAddress() const
virtual bool isImmediateRegister() const
virtual const TTAMachine::Port & port() const
virtual bool isImmediate() const
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
virtual const TTAMachine::RegisterFile & registerFile() const
virtual bool isFUPort() const
TTAMachine::RegisterFile & booleanRegisterFile() const
UniversalFunctionUnit & universalFunctionUnit() const
UnboundedRegisterFile & integerRegisterFile() const
TTAMachine::Bus & universalBus() const
UnboundedRegisterFile & doubleRegisterFile() const
TPEF::SectionElement * srcElem
Location element.
TPEF::Section * srcSect
Location section.
int bits
Relocation width.
Address destination
Destination address.
TPEF::MoveElement::FieldType type
RF, UNIT or IMM.
HalfWord index
Operand or register file index.