37 #include <boost/format.hpp>
102 std::string
name()
const {
return name_;}
119 TPEFProgramFactory::TPEFProgramFactory(
123 binary_(&aBinary), machine_(&aMachine),
126 adfInstrASpace_(NULL),
127 tpefInstrASpace_(NULL) {
139 binary_(&aBinary), machine_(&aMachine),
142 adfInstrASpace_(NULL),
143 tpefInstrASpace_(NULL) {
155 binary_(&aBinary), machine_(NULL),
158 adfInstrASpace_(NULL),
159 tpefInstrASpace_(NULL) {
182 const Section* chunkOwner)
const {
206 "No code sections in TPEF.");
225 "Tried to load a sequential program with ADF already "
238 if (aSpaceNav.
hasItem(aSpaceName )) {
245 "No instruction(gcu) address space in ADF.");
256 "Tried to load a parallel TPEF without ADF.");
292 Terminal &addressTerm = move->source();
301 referencedInstruction);
306 move->setSource(instrTerm);
323 referencedInstruction);
328 immediate->setValue(instrTerm);
349 std::list<CodeSection*> sectionsToChop;
357 if (sectionsToChop.empty()) {
358 sectionsToChop.push_back(sectionToAdd);
362 std::list<CodeSection*>::iterator iter = sectionsToChop.begin();
364 while (iter != sectionsToChop.end()) {
366 if ((*iter)->startingAddress() >
368 sectionsToChop.insert(iter, sectionToAdd);
380 std::list<CodeSection*>::iterator sectionIterator =
381 sectionsToChop.begin();
383 while (sectionIterator != sectionsToChop.end()) {
388 assert(resources != NULL);
391 int currentInstructionNumber = 0;
392 while (i < section->elementCount()) {
402 assert(instructionElement != NULL);
405 program.procedureCount() == 0) {
415 program.addProcedure(newProcedure);
430 if (instructionElement->
begin()) {
431 beginElement = instructionElement;
434 if (instructionElement->
isMove()) {
435 moveElements.push_back(
447 immElements[immKey] = imm;
449 longImmediates.push_back(imm);
461 assert(sectionElement != NULL);
466 assert(i < section->elementCount());
468 }
while (instructionElement->
begin() ==
false);
472 longImmediates, immElements);
476 assert(beginElement != NULL);
480 assert(currentInstruction != NULL);
482 program.addInstruction(currentInstruction);
483 currentInstructionNumber++;
490 "Instruction %d: ") % currentInstructionNumber).
518 std::vector<SocketAllocation> allocatedSockets;
521 new Instruction(NullInstructionTemplate::instance());
523 for (
unsigned int i = 0; i < moveElements.size(); i++) {
528 std::shared_ptr<TTAProgram::Move> newMove;
540 resources, &bus, Socket::OUTPUT, move->
sourceType(),
571 if (guardRegister != NULL) {
572 delete guardRegister;
573 guardRegister = NULL;
577 if (source != NULL) {
582 if (destination != NULL) {
587 delete newInstruction;
588 newInstruction = NULL;
596 newMove = std::make_shared<TTAProgram::Move>(source, destination, bus, guard);
598 newMove = std::make_shared<TTAProgram::Move>(source, destination, bus);
609 for (
int i = 0; i < socketNav.
count(); i++) {
613 for (
int j = 0; j < currSocket->
portCount(); j++) {
615 if ((source->
isGPR() ||
617 currSocket->
direction() == Socket::OUTPUT &&
621 newAlloc.
srcSocks.push_back(currSocket);
624 if ((destination->
isGPR() ||
626 currSocket->
direction() == Socket::INPUT &&
630 newAlloc.
dstSocks.push_back(currSocket);
636 allocatedSockets.push_back(newAlloc);
640 for (Word annotationIndex = 0;
651 newInstruction->
addMove(newMove);
662 for (Word annotationIndex = 0;
683 for (
unsigned int i = 0; i < longImmediates.size(); i++) {
688 resources, NULL, Socket::INPUT,
703 bool isInstructionReference =
false;
714 isInstructionReference =
true;
727 auto newImmediate = std::make_shared<Immediate>(immTerm, destination);
731 if (isInstructionReference) {
737 return newInstruction;
762 HalfWord index,
const ImmediateMap* immediateMap)
const {
765 if (type == MoveElement::MF_RF) {
770 }
else if (type == MoveElement::MF_IMM &&
771 unitId != ResourceElement::INLINE_IMM) {
778 CacheKey cacheKey(*aBus, direction, type, unitId, index);
782 if (returnValue == NULL) {
786 case MoveElement::MF_IMM: {
791 imm = MapTools::valueForKey<ImmediateElement*>(
792 *immediateMap, immKey);
795 <<
"Cannot find immediate with unitId/index "
796 <<
static_cast<int>(unitId) <<
"/" << index << std::endl
797 <<
"immediateMap.size(): " << immediateMap->size()
830 "Unable to find address space for "
831 "target of reloc element for immediate "
832 "'%d'.") % imm->
word()).
844 assert(returnValue != NULL);
847 for (Word annotationIndex = 0;
860 "should be already handled in same place "
861 "with normal register references.");
865 case MoveElement::MF_UNIT: {
870 ResourceElement::MRT_OP, index)) {
873 &resources.
findResource(ResourceElement::MRT_OP, index);
876 ResourceElement::MRT_PORT, index)) {
879 &resources.
findResource(ResourceElement::MRT_PORT, index);
882 ResourceElement::MRT_SR, index)) {
885 &resources.
findResource(ResourceElement::MRT_SR, index);
889 "special register with index:" +
894 assert(tpefResource != NULL);
896 std::string tpefOpStr =
909 bool opCodePort =
false;
910 std::string::size_type opNameLength = tpefOpStr.rfind(
'.');
911 std::string tpefOpName = tpefOpStr;
914 if (opNameLength != std::string::npos) {
915 tpefOpName = tpefOpStr.substr(0, opNameLength);
916 std::string::size_type opIndexStart = opNameLength + 1;
917 std::string tpefOpIndexStr =
919 opIndexStart, tpefOpStr.length() - opIndexStart);
937 findPort(*aBus, functionUnit, tpefOpName));
950 if (type != MoveElement::MF_IMM) {
955 return returnValue->
copy();
974 HalfWord busId)
const {
976 if (busId == ResourceElement::UNIVERSAL_BUS) {
980 "TPEF needs universal machine for universal bus reference.");
989 "TPEF needs real machine for non-universal bus reference.");
996 resources.
findResource(ResourceElement::MRT_BUS, busId);
998 std::string busName =
1004 "ADF does not contain bus: " + busName);
1023 HalfWord rfId)
const {
1027 case ResourceElement::ILLEGAL_RF:
1030 case ResourceElement::INT_RF:
1034 "TPEF needs universal machine for universal integer RF "
1040 case ResourceElement::BOOL_RF:
1044 "TPEF needs universal machine for universal boolean RF "
1050 case ResourceElement::FP_RF:
1054 "TPEF needs universal machine for universal floating point "
1065 "TPEF needs real machine for non-universal RF reference.");
1071 std::string rfName =
1077 "Can't find RF \"" + rfName +
"\" from ADF.");
1101 Byte immUnitId)
const {
1106 "TPEF needs real machine for immediate unit reference.");
1110 resources.
findResource(ResourceElement::MRT_IMM, immUnitId);
1112 std::string immUnitName =
1118 "Can't find immediate unit \"" + immUnitName +
"\" from ADF.");
1146 std::string tpefOpName)
const {
1150 case ResourceElement::UNIVERSAL_FU: {
1155 "TPEF needs universal machine for getting universal FU.");
1162 if (tpefOpName == ResourceElement::RETURN_ADDRESS_NAME) {
1176 boost::format errMsg(
1177 "Unknown operation '%1%'. Operation definition not found.");
1179 __FILE__, __LINE__,
__func__, (errMsg % tpefOpName).str());
1187 "TPEF needs real target architecture for getting a "
1188 "non-universal FU.");
1192 ResourceElement::MRT_UNIT, unitId);
1194 std::string fuName =
1209 "Can't find RFU \"" + fuName +
"\" from ADF.");
1239 const Unit& portParent,
1240 std::string tpefOpName,
1241 int tpefOpIndex)
const {
1243 const Machine* machineOfBus = NULL;
1252 assert(machineOfBus != NULL);
1261 if (tpefOpName == ResourceElement::RETURN_ADDRESS_NAME) {
1272 "GCU needs return address port.");
1280 if (fu->
hasOperation(tpefOpName) && tpefOpIndex != 0) {
1283 return *(oper->
port(tpefOpIndex));
1285 }
else if (fu->
hasPort(tpefOpName)) {
1289 fu->
port(tpefOpName));
1291 if (srPort != NULL) {
1298 return *fu->
port(tpefOpName);
1303 __FILE__, __LINE__,
__func__,
"Can't find port for: " +
1304 fu->
name() +
"." + tpefOpName +
"." +
1313 std::string throwError =
"Can't find port for: " + portParent.
name();
1315 if (tpefOpName !=
"") {
1316 throwError +=
"." + tpefOpName;
1341 if (aSpaceNavi.
hasItem(aSpaceName)) {
1342 return *aSpaceNavi.
item(aSpaceName);
1349 }
else if (aSpaceName ==
1358 "Can't find address space by name: " + aSpaceName +
1376 HalfWord unitId, HalfWord index,
bool isInverted)
const {
1379 Port* guardPort = NULL;
1391 ResourceElement::MRT_OP, index)) {
1394 &resources.
findResource(ResourceElement::MRT_OP, index);
1397 ResourceElement::MRT_PORT, index)) {
1400 &resources.
findResource(ResourceElement::MRT_PORT, index);
1403 ResourceElement::MRT_SR, index)) {
1406 &resources.
findResource(ResourceElement::MRT_SR, index);
1410 "special register with index:" +
1416 std::string tpefOpStr =
1420 if (guardUnit.
hasPort(tpefOpStr)) {
1421 guardPort = guardUnit.
port(tpefOpStr);
1424 std::string::size_type dotPos = tpefOpStr.find(
'.');
1425 assert (dotPos != std::string::npos);
1426 std::string operationName = tpefOpStr.substr(0, dotPos);
1429 tpefOpStr.substr(dotPos+1, tpefOpStr.length() - dotPos - 1));
1431 guardPort = oper->
port(operandIndex);
1441 "Error: Unknown guard type. Guard must be either FU port "
1445 assert (
reinterpret_cast<long int>(guardPort) !=
1446 reinterpret_cast<long int>(guardRF));
1456 if (portGuard != NULL && guardPort != NULL) {
1457 if (portGuard->
port() == guardPort) {
1461 }
else if (registerGuard != NULL && guardRF != NULL) {
1470 std::string guardType;
1477 if (guardRF != NULL) {
1481 if (guardPort != NULL) {
1482 guardType +=
"Some FU operation or special register.";
1487 "Can't find suitable guard: " + guardType +
"\tfrom bus: " +
1490 return *bus.
guard(0);
1514 std::map<ImmediateUnit*, int> bitsToWrite;
1516 for (
unsigned int i = 0; i < longImmediates.size(); i++) {
1526 "Can't write two immediates to the same immediate unit "
1527 " in the same instruction.");
1543 for (
int i = 0; i < tempNav.
count(); i++) {
1549 static_cast<int>(bitsToWrite.size())) {
1551 bool templateIsGood =
true;
1554 for (std::map<ImmediateUnit*, int>::iterator iter =
1555 bitsToWrite.begin();
1556 iter != bitsToWrite.end();
1562 templateIsGood =
false;
1568 if (templateIsGood) {
1569 for (
unsigned int j = 0; j < moves.size(); j++) {
1581 templateIsGood =
false;
1588 if (templateIsGood) {
1589 if (bestiTempFound == NULL)
1590 bestiTempFound = insTemp;
1595 if (bestiTempFound == NULL) {
1596 std::string bitRequirementmsg;
1597 for (
const auto& pair : bitsToWrite) {
1599 +
" bits to IU: " + pair.first->name() +
"\n";
1602 "Valid instruction template is not found for instruction layout:\n"
1603 +
"An instruction template is needed that can write:\n"
1604 + bitRequirementmsg);
1606 return *bestiTempFound;
1626 std::map<
Socket*, std::vector<SocketAllocation*> >& fixedSockets)
const {
1632 std::vector<SocketAllocation*>& socketAllocs = fixedSockets[currentSocket];
1635 for (
unsigned int i = 0; i < socketAllocs.size(); i++) {
1637 auto oldMove = socketAllocs[i]->move;
1638 Terminal* oldTerminal = &(oldMove->source());
1641 if (alloc.
move->source().index() != oldTerminal->
index() &&
1642 (alloc.
move->isUnconditional() || oldMove->isUnconditional() ||
1643 !alloc.
move->guard().guard().isOpposite(oldMove->guard().guard()))) {
1669 std::map<
Socket*, std::vector<SocketAllocation*> >& fixedSockets)
const {
1675 std::vector<SocketAllocation*>& socketAllocs = fixedSockets[currentSocket];
1678 for (
unsigned int i = 0; i < socketAllocs.size(); i++) {
1680 auto oldMove = socketAllocs[i]->move;
1681 if (alloc.
move->isUnconditional() || oldMove->isUnconditional() ||
1682 !alloc.
move->guard().guard().isOpposite(
1683 oldMove->guard().guard())) {
1712 std::vector<SocketAllocation>& allocs)
const {
1715 std::map<Socket*, std::vector<SocketAllocation*> > fixedSockets;
1718 unsigned currIndex = 0;
1720 while (currIndex < allocs.size()) {
1721 bool allocationWasSuccess =
true;
1737 allocationWasSuccess =
false;
1742 allocationWasSuccess =
false;
1749 if (allocationWasSuccess) {
1752 fixedSockets[currentSocket].push_back(&alloc);
1759 unsigned int prevIndex = currIndex;
1762 if (prevIndex == 0) {
1765 "Can't resolve src sockets for instruction.");
1770 }
while (allocs[prevIndex].srcSocks.empty());
1774 allocs[prevIndex].srcSocks[allocs[prevIndex].src];
1775 std::vector<SocketAllocation*>& freedAllocs =
1776 fixedSockets[socketToFree];
1778 bool prevFound =
false;
1780 for (
int k = prevIndex; k >= 0 && !prevFound; k--) {
1781 for (std::vector<SocketAllocation*>::iterator j =
1782 freedAllocs.begin(); j != freedAllocs.end(); j++) {
1784 if (
static_cast<int>((*j)->index) == k) {
1788 freedAllocs.erase(j);
1801 fixedSockets.clear();
1804 while (currIndex < allocs.size()) {
1805 bool allocationWasSuccess =
true;
1821 allocationWasSuccess =
false;
1826 allocationWasSuccess =
false;
1833 if (allocationWasSuccess) {
1836 fixedSockets[currentSocket].push_back(&alloc);
1843 unsigned int prevIndex = currIndex;
1846 if (prevIndex == 0) {
1849 "Can't resolve dst sockets for instruction.");
1854 }
while (allocs[prevIndex].dstSocks.empty());
1858 allocs[prevIndex].dstSocks[allocs[prevIndex].dst];
1859 std::vector<SocketAllocation*>& freedAllocs =
1860 fixedSockets[socketToFree];
1863 for (
unsigned int j = 0; j < freedAllocs.size(); j++) {
1864 if (freedAllocs[j]->index < currIndex) {
1865 currIndex = freedAllocs[j]->index;
1871 for (
unsigned int j = 0; j < freedAllocs.size(); j++) {
1872 if (freedAllocs[j]->index != currIndex) {
1873 freedAllocs[j]->dst = 0;
1875 freedAllocs[j]->dst++;
1879 fixedSockets.erase(socketToFree);
1887 for (
unsigned i = 0; i < allocs.size(); i++) {
1891 std::cerr <<
"next allocation source: "
1892 << alloc.
move->source().isGPR()
1894 << alloc.
move->destination().isGPR() << std::endl;
1899 Unit* parent = alloc.
move->source().port().parentUnit();
1901 for (
int j = 0; j < srcSocket->
portCount(); j++) {
1903 alloc.
move->setSource(
1905 *srcSocket->
port(j),
1906 alloc.
move->source().index()));
1908 std::cerr <<
"source was replaced" << std::endl;
1917 Unit* parent = alloc.
move->destination().port().parentUnit();
1919 for (
int j = 0; j < dstSocket->
portCount(); j++) {
1921 alloc.
move->setDestination(
1923 *dstSocket->
port(j),
1924 alloc.
move->destination().index()));
1926 std::cerr <<
"dst was replaced" << std::endl;
1933 if (alloc.
move->source().isGPR() &&
1934 alloc.
move->destination().isGPR()) {
1935 std::cerr <<
"next allocation source: "
1936 << alloc.
move->source().port().name()
1938 << alloc.
move->destination().port().name() << std::endl;
1955 return MapTools::valueForKey<Terminal*>(
cache_,key);
1972 cache_[key] = cachedTerm;
2008 if (procedSymbol == NULL) {
2018 assert(referencedInstruction != NULL);
2038 std::map<string, std::pair<DataLabel*, bool> > dataLabels;
2045 assert(currSect != NULL);
2057 if (sym->
type() == SymbolElement::STT_DATA) {
2062 const std::string labelString =
2068 assert(dataSection != NULL);
2078 "Unable to find address space for target "
2079 "of data label '%s'") % labelString).str());
2104 if (sym->
binding() == SymbolElement::STB_GLOBAL) {
2108 if (dataLabels[labelString].second) {
2111 for (std::map<
string,
2113 bool> >::iterator iter =
2115 iter != dataLabels.end(); iter++) {
2116 delete (*iter).second.first;
2122 "Found two global symbols with same name: " +
2126 delete dataLabels[labelString].first;
2127 dataLabels[labelString].first = dataLabel;
2128 dataLabels[labelString].second =
true;
2132 dataLabels[labelString].first = dataLabel;
2133 dataLabels[labelString].second =
2134 (sym->
binding() == SymbolElement::STB_GLOBAL);
2138 }
else if (sym->
binding() == SymbolElement::STB_GLOBAL &&
2139 sym->
type() == SymbolElement::STT_CODE) {
2162 for (std::map<
string, std::pair<DataLabel*, bool> >::iterator iter =
2164 iter != dataLabels.end(); iter++) {
2179 std::map<AddressSpace*, std::vector<UDataSection*> > memories;
2184 if (currSect->
type() == Section::ST_DATA ||
2185 currSect->
type() == Section::ST_UDATA ||
2186 currSect->
type() == Section::ST_LEDATA) {
2191 std::vector<UDataSection*>& secVec = memories[&aSpace];
2195 for (
int j = 0; j < static_cast<int>(secVec.size()); j++) {
2196 if (secVec[j]->startingAddress() >
2199 secVec[j] = uDataSect;
2204 secVec.push_back(uDataSect);
2209 for (std::map<
AddressSpace*, std::vector<UDataSection*> >::iterator iter =
2211 iter != memories.end(); iter++) {
2214 std::vector<UDataSection*>& secVec = (*iter).second;
2218 for (
int i = 0; i < static_cast<int>(secVec.size()); i++) {
2221 if (currSect->
type() == Section::ST_UDATA) {
2233 assert(currSect->
type() == Section::ST_DATA ||
2234 currSect->
type() == Section::ST_LEDATA);
2240 j < static_cast<int>(
2255 if (relocs != NULL) {
2277 Address startAddr(sourceAddress, aSpace);
2280 int mauSize = currElem->
size() / aSpace.
width();
2292 assert(tpefInstr != NULL);
2301 startAddr, mauSize, instrRef,
2313 assert(dstChunk != NULL);
2317 std::vector<UDataSection*>& dstSecs =
2318 memories[&dstSpace];
2321 k < static_cast<int>(dstSecs.size()); k++) {
2341 startAddr, mauSize, dstAddr,
2356 std::vector<std::pair <int, int> > dataAreas;
2357 dataAreas.push_back(wholeSection);
2364 int prevIndex = dataAreas.size()-1;
2365 std::pair<int, int>& lastArea = dataAreas[prevIndex];
2372 lastArea.first + lastArea.second) {
2374 int lastAreaStart = lastArea.first;
2381 int newAreaEnd = lastArea.first + lastArea.second;
2384 std::pair<int, int> newArea(
2385 newAreaStart, newAreaEnd - newAreaStart);
2388 lastArea.second = lastAreaEnd - lastAreaStart;
2390 if (lastArea.second == 0) {
2391 dataAreas.pop_back();
2394 if (newArea.second != 0) {
2395 dataAreas.push_back(newArea);
2401 assert(dataSect != NULL);
2404 for (
unsigned int k = 0; k < dataAreas.size(); k++) {
2406 std::pair<int, int>& currArea = dataAreas[k];
2407 std::vector<MinimumAddressableUnit> initData;
2414 assert(mauIndex + currArea.second <=
2417 bool allZeros =
true;
2418 for (
int l = 0; l < currArea.second; l++) {
2419 if(dataSect->
MAU(mauIndex + l) != 0) {
2428 Address(currArea.first, aSpace),
2433 for (
int l = 0; l < currArea.second; l++) {
2434 initData.push_back(dataSect->
MAU(mauIndex++));
2438 Address(currArea.first, aSpace),
2474 return MapTools::valueForKey<FunctionStart*>(
2477 return "unknownFunctionName";