Go to the documentation of this file.
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;
int immediateWidth() const
std::map< const TTAMachine::AddressSpace *, TPEF::ASpaceElement * > aSpaceMap_
Created TPEF binary.
UnboundedRegisterFile & integerRegisterFile() const
virtual bool isFUPort() const
TTAMachine::RegisterFile & booleanRegisterFile() const
TTAMachine::Machine & mach_
The model of the target processor architecture.
void setGuardInverted(bool flag)
virtual void addElement(SectionElement *element)
virtual Word lengthInMAUs() const
ASpaceElement * aSpace() const
void setReference(Chunk *aReference)
virtual TCEString name() const
void addAnnotation(InstructionAnnotation *anAnnotation)
virtual int index() const
SLongWord sLongWordValue() const
virtual bool isInstructionAddress() const
int procedureCount() const
virtual Address startAddress() const
HalfWord lastRegisterFileId_
Last TPEF register file id that was generated.
TPEF::ResourceElement & functionUnit(const TTAMachine::FunctionUnit &fu)
virtual bool isDataSection() const
virtual void addMAU(MinimumAddressableUnit aMAU)
Address startAddress() const
int registerIndex() const
virtual bool isAddress() const
FunctionUnit * parentUnit() const
virtual const TTAMachine::RegisterFile & registerFile() const
void createDataSections(TPEF::Binary *bin, bool littleEndian) const
std::pair< const TTAMachine::MachinePart *, int > CacheKey
void createRelocSections(TPEF::Binary *bin) const
void setDestinationUnit(HalfWord aDestinationUnit)
TTAMachine::Bus & universalBus() const
TPEF::Binary::FileType resolveFileType(TPEF::ResourceSection &resources) const
TPEF::ResourceElement & immediateUnit(const TTAMachine::ImmediateUnit &immUnit)
TPEF::ResourceElement & operand(const TTAMachine::HWOperation &oper, int operandIndex)
bool isUnconditional() const
ResourceType type() const
void createCodeSection(TPEF::CodeSection *code, 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 TTAMachine::AddressSpace & addressSpace() const
Terminal & destination() const
ResourceID terminalResource(const Terminal &term, TPEFResourceUpdater &updater) const
virtual bool isAddress() const
HalfWord index
Operand or register file index.
void addSection(Section *section)
void setCause(const Exception &cause)
const TTAMachine::AddressSpace & space() const
void setGuarded(bool flag)
int dataDefinitionCount() const
UnboundedRegisterFile & doubleRegisterFile() const
const TTAMachine::Bus & bus() const
virtual Operation & operation() const
void setType(FileType type)
virtual BaseFUPort * port(const std::string &name) const
virtual AddressSpace * addressSpace() const
Section * section(Word index) const
virtual Address startAddress() const
std::string chunk2String(const Chunk *chunk) const
Section * referencedSection() const
TPEFResourceUpdater(TTAMachine::Machine &mach, TPEF::ResourceSection &resources)
static std::ostream & logStream()
Word sectionCount() const
void setDestinationType(FieldType aType)
ResourceCache cache_
Aggregate of all mappings between machine resource entries and target processor parts (machine parts)...
virtual Word MAUsToBytes(Word mauCount) const
virtual void addByte(Byte aByte)
static NullOperation & instance()
int globalCodeLabelCount(Address address) const
virtual TCEString name() const
void setBinding(SymbolBinding aBinding)
virtual Address address() const
const DataLabel & globalDataLabel(Address address, int index) const
virtual Address address() const
static std::string toString(const T &source)
void setBus(HalfWord aBus)
void setType(ResourceType aType)
TPEF::MoveElement::FieldType type
RF, UNIT or IMM.
void setReference(InstructionElement *aReference)
bool isLittleEndian() const
HalfWord lastFunctionUnitId_
Last TPEF function unit id that was generated.
const GlobalScope & globalScopeConst() const
#define assert(condition)
SectionElement * element(Word index) const
virtual Operation & hintOperation() const
virtual void addElement(SectionElement *element)
virtual bool isImmediateRegister() const
TPEF::ResourceSection & resources_
The TPEF input section that contains all machine resource entries.
ProgramAnnotation::Id id() const
virtual ControlUnit * controlUnit() const
int io(const FUPort &port) const
#define abortWithError(message)
const std::string & name() const
TPEF::Section & findSection(TPEF::Binary &bin, Address address) const
void setType(RelocType aType)
virtual int instructionCount() const
void setGuardIndex(HalfWord aGuardIndex)
virtual ImmediateUnitNavigator immediateUnitNavigator() const
HalfWord lastImmediateUnitId_
Last TPEF immediate unit id that was generated.
virtual Address destinationAddress() const
ASpaceElement * undefinedASpace() const
const Program & prog_
Program that is written to TPEF.
DataMemory & dataMemory(int index) const
virtual bool isInitialized() const
MoveGuard & guard() const
static const int MAX_SIMM_WIDTH
Maximum width for short immediates.
Chunk * string2Chunk(const std::string &str)
void setSection(Section *aSect)
bool isBound(const FUPort &port) const
TPEF::ResourceElement & bus(const TTAMachine::Bus &bus)
TPEF::ASpaceElement & createASpaceElement(const TTAMachine::AddressSpace &addressSpace, TPEF::Binary &bin) const
InstructionElement & instruction(Word index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
ULongWord uLongWordValue() const
virtual bool isGPR() const
virtual int operationCount() const
virtual SimValue value() const
void setSymbol(SymbolElement *aSymbol)
virtual bool hasPort(const std::string &name) const
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
int globalDataLabelCount(Address address) const
void setDestinationIndex(HalfWord aDestinationIndex)
InstructionAddress location() const
int bits
Relocation width.
void setName(Chunk *aName)
TPEF::SectionElement * srcElem
Location element.
void setLocation(SectionElement *aLocation)
TPEF::ResourceElement & registerFile(const TTAMachine::RegisterFile &rf)
virtual bool hasOperation(const std::string &name) const
virtual bool isOpcodeSetting() const
virtual Address address() const
TPEF::ResourceElement & functionUnitPort(const TTAMachine::Port &port)
void setName(const ReferenceManager::SafePointer *sectionName)
void setGuardType(FieldType gType)
Immediate & immediate(int i) const
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
std::string errorMessage() const
int dataMemoryCount() const
std::vector< RelocInfo > relocInfos_
void setStartingAddress(AddressImage address)
void setBegin(bool isBegin)
unsigned int unsignedValue() const
virtual bool hasOperationPort(const std::string &name) const
UniversalFunctionUnit & universalFunctionUnit() const
virtual int width() const
int instructionCount() const
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual RegisterFileNavigator registerFileNavigator() const
static std::string disassemble(const TTAProgram::Move &move)
Instruction & parent() const
virtual bool isInverted() const
Word instructionCount() const
Address destination
Destination address.
void setSourceUnit(HalfWord aSourceUnit)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
virtual Machine * machine() const
virtual std::string name() const
virtual void setLengthInMAUs(Word length)
FunctionUnit * parentUnit() const
TPEF::Section * srcSect
Location section.
int immediateCount() const
virtual BusNavigator busNavigator() const
void setSourceIndex(HalfWord aSourceIndex)
void setAbsolute(bool anAbsoluteness)
DataDefinition & dataDefinition(Address address) const
void setLink(const ReferenceManager::SafePointer *aLink)
void setName(const ReferenceManager::SafePointer *aName)
HalfWord lastBusId_
Last TPEF bus id that was generated.
TTAMachine::Machine & targetProcessor() const
void setUndefinedASpace(ASpaceElement *aSpace)
void setASpace(ASpaceElement *anASpace)
virtual Word length() const
virtual Instruction & instructionAtIndex(int index) const
Terminal & source() const
const CodeLabel & globalCodeLabel(Address address, int index) const
virtual const TTAMachine::Port & port() const
bool isProgramSection() const
virtual HWOperation * operation(const std::string &name) const
static int toInt(const T &source)
virtual SectionType type() const
const TTAMachine::Guard & guard() const
void setDestination(SectionElement *aDestination)
void setReferencedSection(Section *section)
SpecialRegisterPort * returnAddressPort() const
virtual bool isImmediate() const
HalfWord lastUnitPortId_
Last TPEF unit port id that was generated.
virtual bool isCodeSection() const
virtual Chunk * chunk(SectionOffset offset) const
void setStrings(StringSection *strTable)
TPEF::Binary * createBinary() const
const RegisterFile * registerFile() const
virtual ULongWord start() const
Procedure & procedure(int index) const
virtual ULongWord end() const
AddressImage startingAddress() const
void setName(ReferenceManager::SafePointer *aName)
bool hasReturnAddressPort() const
const std::vector< Byte > & payload() const
Word elementCount() const
void setSourceType(FieldType aType)
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
void setGuardUnit(HalfWord aGuardUnit)
ProgramWriter(const Program &prog)
void setArch(FileArchitecture arch)
virtual MinimumAddressableUnit MAU(int index) const
Unit * parentUnit() const