OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
BEMGenerator Class Reference

#include <BEMGenerator.hh>

Collaboration diagram for BEMGenerator:
Collaboration graph

Public Member Functions

 BEMGenerator (const TTAMachine::Machine &machine)
 
virtual ~BEMGenerator ()
 
BinaryEncodinggenerate ()
 

Private Types

typedef std::map< const TTAMachine::Socket *, SocketCodeTable * > SCTableMap
 Map type for storing Socket - SocketCodeTable pairs.
 
typedef std::pair< unsigned int, unsigned int > Encoding
 Typedef for encoding (first = encoding, second = extra bits).
 

Private Member Functions

void addLongImmDstRegisterFields (BinaryEncoding &bem) const
 
void addSocketCodeTables (BinaryEncoding &bem)
 
void addTopLevelFields (BinaryEncoding &bem) const
 
void addSubfields (MoveSlot &slot) const
 
void addEncodings (ImmediateControlField &field) const
 
void addEncodings (DestinationField &field) const
 
void addEncodings (SourceField &field) const
 
void addEncodings (GuardField &field) const
 
void addRiscvFormat (TTAMachine::OperationTriggeredFormat *format, BinaryEncoding &bem, unsigned &amountOfRCustomOps, unsigned &amountOfR3RCustomOps) const
 
void addPortCodes (SocketCodeTable &table, const TTAMachine::Socket &socket) const
 
SocketCodeTablesocketCodeTable (const TTAMachine::Socket &socket) const
 
SocketCodeTablesuitableSocketCodeTable (const TTAMachine::Socket &socket) const
 
void assignSocketCodeTable (const TTAMachine::Socket *socket, SocketCodeTable *table)
 
std::multiset< int > socketCodeWidthsForBus (const TTAMachine::Bus &bus, TTAMachine::Socket::Direction socketDir) const
 
unsigned int maxLongImmSlotWidth (const MoveSlot &slot) const
 

Static Private Member Functions

static int socketCount (const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
 
static TTAMachine::Socketsocket (int index, const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
 
static bool needsSocketCodeTable (const TTAMachine::Socket &socket)
 
static bool haveEqualConnections (const TTAMachine::Socket &socket1, const TTAMachine::Socket &socket2)
 
static int sourceBridgeCount (const TTAMachine::Bus &bus)
 
static TTAMachine::BridgesourceBridge (int index, const TTAMachine::Bus &bus)
 
static bool hasUnconditionalGuard (const TTAMachine::Bus &bus)
 
static int requiredIndexWidth (const TTAMachine::BaseRegisterFile &regFile)
 
static void calculateEncodings (const std::multiset< int > &oppositeFieldWidths, bool leftAlignment, std::multiset< Encoding > &encodings)
 
static void addExtraBits (std::multiset< Encoding > &encodings, int bitCount)
 

Private Attributes

const TTAMachine::Machinemachine_
 The machine for which the BEM is generated.
 
SCTableMap scTableMap_
 A map which tells which socket code table belongs to a socket.
 

Detailed Description

Generates a binary encoding map for the given machine.

Definition at line 61 of file BEMGenerator.hh.

Member Typedef Documentation

◆ Encoding

typedef std::pair<unsigned int, unsigned int> BEMGenerator::Encoding
private

Typedef for encoding (first = encoding, second = extra bits).

Definition at line 72 of file BEMGenerator.hh.

◆ SCTableMap

typedef std::map<const TTAMachine::Socket*, SocketCodeTable*> BEMGenerator::SCTableMap
private

Map type for storing Socket - SocketCodeTable pairs.

Definition at line 70 of file BEMGenerator.hh.

Constructor & Destructor Documentation

◆ BEMGenerator()

BEMGenerator::BEMGenerator ( const TTAMachine::Machine machine)

The constructor.

Parameters
machineThe machine for which the binary encoding map will be generated.

Definition at line 86 of file BEMGenerator.cc.

86 :
88}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
const TTAMachine::Machine * machine_
The machine for which the BEM is generated.

◆ ~BEMGenerator()

BEMGenerator::~BEMGenerator ( )
virtual

The destructor.

Definition at line 94 of file BEMGenerator.cc.

94 {
95}

Member Function Documentation

◆ addEncodings() [1/4]

void BEMGenerator::addEncodings ( DestinationField field) const
private

Adds encodings for the given destination field.

Parameters
fieldThe destination field.

Definition at line 603 of file BEMGenerator.cc.

603 {
604
605 string busName = field.parent()->name();
607 assert(busNav.hasItem(busName));
608 Bus* bus = busNav.item(busName);
609 bool createNopField = true;
610 for (int i = 0; i < bus->guardCount(); i++) {
611 Guard* g = bus->guard(i);
612 if (g->isInverted() && dynamic_cast<UnconditionalGuard*>(g) != NULL) {
613 createNopField = false;
614 }
615 }
616
617 int dstSockets = socketCount(*bus, Socket::INPUT);
618 if (dstSockets == 0) {
619 return;
620 }
621
622 multiset<int> socketCodeWidths = socketCodeWidthsForBus(
623 *bus, Socket::INPUT);
624 // add socket code width for NOP encoding
625 if (createNopField) {
626 socketCodeWidths.insert(0);
627 }
628 multiset<Encoding> encodings;
629 calculateEncodings(socketCodeWidths, true, encodings);
630
631 set<Socket*> handledSockets;
632 multiset<int>::reverse_iterator scIter = socketCodeWidths.rbegin();
633 bool nopEncodingSet = false;
634 for (multiset<Encoding>::const_iterator encIter = encodings.begin();
635 encIter != encodings.end(); encIter++) {
636 Encoding enc = *encIter;
637 int scWidth = *scIter;
638 if (scWidth == 0 && !nopEncodingSet && createNopField) {
639 // add NOP encoding
640 new NOPEncoding(enc.first, enc.second, field);
641 nopEncodingSet = true;
642 } else {
643 // find socket that has correct socket code width
644 for (int i = 0; i < dstSockets; i++) {
646 i, *bus, Socket::INPUT);
648 if (scTable == NULL && scWidth == 0 &&
649 !AssocTools::containsKey(handledSockets, &socket)) {
650 new SocketEncoding(
651 socket.name(), enc.first, enc.second, field);
652 handledSockets.insert(&socket);
653 break;
654 } else if (scTable != NULL && scWidth == scTable->width() &&
656 handledSockets, &socket)) {
657 SocketEncoding* socketEnc = new SocketEncoding(
658 socket.name(), enc.first, enc.second, field);
659 socketEnc->setSocketCodes(*scTable);
660 handledSockets.insert(&socket);
661 break;
662 }
663 }
664 }
665 scIter++;
666 }
667}
#define assert(condition)
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
static int socketCount(const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
std::multiset< int > socketCodeWidthsForBus(const TTAMachine::Bus &bus, TTAMachine::Socket::Direction socketDir) const
static TTAMachine::Socket & socket(int index, const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
static void calculateEncodings(const std::multiset< int > &oppositeFieldWidths, bool leftAlignment, std::multiset< Encoding > &encodings)
SocketCodeTable * socketCodeTable(const TTAMachine::Socket &socket) const
std::string name() const
Definition MoveSlot.cc:136
MoveSlot * parent() const
Definition SlotField.cc:98
void setSocketCodes(SocketCodeTable &codeTable)
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual TCEString name() const
virtual bool isInverted() const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
@ INPUT
Data goes from bus to port.
Definition Socket.hh:59

References assert, TTAMachine::Machine::busNavigator(), calculateEncodings(), AssocTools::containsKey(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAMachine::Socket::INPUT, TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::Component::name(), SlotField::parent(), SocketEncoding::setSocketCodes(), socket(), socketCodeTable(), socketCodeWidthsForBus(), socketCount(), and SocketCodeTable::width().

Here is the call graph for this function:

◆ addEncodings() [2/4]

void BEMGenerator::addEncodings ( GuardField field) const
private

Adds guard encodings to the given guard field.

Parameters
fieldThe guard field.

Definition at line 773 of file BEMGenerator.cc.

773 {
774
775 string busName = field.parent()->name();
777 assert(busNav.hasItem(busName));
778 Bus* bus = busNav.item(busName);
779
780 int guards = bus->guardCount();
781
782 for (int i = 0; i < guards; i++) {
783 Guard* guard = bus->guard(i);
784 PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
785 RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
786 UnconditionalGuard* ucGuard =
787 dynamic_cast<UnconditionalGuard*>(guard);
788 if (portGuard != NULL) {
789 FUPort* port = portGuard->port();
790 new FUGuardEncoding(
791 port->parentUnit()->name(), port->name(),
792 portGuard->isInverted(), i, field);
793 } else if (regGuard != NULL) {
795 regGuard->registerFile()->name(), regGuard->registerIndex(),
796 regGuard->isInverted(), i, field);
797 } else if (ucGuard != NULL) {
798 new UnconditionalGuardEncoding(ucGuard->isInverted(), i, field);
799 } else {
800 assert(false);
801 }
802 }
803}
MoveSlot * parent() const
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
FUPort * port() const
virtual std::string name() const
Definition Port.cc:141
const RegisterFile * registerFile() const

References assert, TTAMachine::Machine::busNavigator(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::Component::name(), TTAMachine::Port::name(), GuardField::parent(), TTAMachine::BaseFUPort::parentUnit(), TTAMachine::PortGuard::port(), TTAMachine::RegisterGuard::registerFile(), and TTAMachine::RegisterGuard::registerIndex().

Here is the call graph for this function:

◆ addEncodings() [3/4]

void BEMGenerator::addEncodings ( ImmediateControlField field) const
private

Adds the encoding for instruction templates to the given immediate control field.

Parameters
fieldThe immediate control field.

Definition at line 587 of file BEMGenerator.cc.

587 {
590 for (int i = 0; i < itNav.count(); i++) {
591 InstructionTemplate* iTemp = itNav.item(i);
592 field.addTemplateEncoding(iTemp->name(), i);
593 }
594}
void addTemplateEncoding(const std::string &name, unsigned int encoding)
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428

References ImmediateControlField::addTemplateEncoding(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, and TTAMachine::Component::name().

Referenced by addSubfields(), and addTopLevelFields().

Here is the call graph for this function:

◆ addEncodings() [4/4]

void BEMGenerator::addEncodings ( SourceField field) const
private

Adds encodings for the given source field.

Parameters
fieldThe source field.

Definition at line 676 of file BEMGenerator.cc.

676 {
677
678 string busName = field.parent()->name();
680 assert(busNav.hasItem(busName));
681 Bus* bus = busNav.item(busName);
682 bool createNopField = true;
683 for (int i = 0; i < bus->guardCount(); i++) {
684 Guard* g = bus->guard(i);
685 if (g->isInverted() && dynamic_cast<UnconditionalGuard*>(g) != NULL) {
686 createNopField = false;
687 }
688 }
689
690 int srcSockets = socketCount(*bus, Socket::OUTPUT);
691 int srcBridges = sourceBridgeCount(*bus);
692 bool shortImmSupport = (bus->immediateWidth() > 0);
693
694 multiset<int> socketCodeWidths = socketCodeWidthsForBus(
695 *bus, Socket::OUTPUT);
696 for (int i = 0; i < srcBridges; i++) {
697 socketCodeWidths.insert(0);
698 }
699 if (shortImmSupport) {
700 socketCodeWidths.insert(bus->immediateWidth());
701 }
702 // one encoding for NOP
703 if (createNopField) {
704 socketCodeWidths.insert(0);
705 }
706
707 multiset<Encoding> encodings;
708 calculateEncodings(socketCodeWidths, true, encodings);
709
710 // set the encodings
711 set<Socket*> handledSockets;
712 int nextBridge = 0;
713 bool nopEncodingSet = false;
714 bool immEncodingSet = !shortImmSupport;
715 multiset<int>::reverse_iterator scIter = socketCodeWidths.rbegin();
716 for (multiset<Encoding>::const_iterator encIter = encodings.begin();
717 encIter != encodings.end(); encIter++) {
718 Encoding enc = *encIter;
719 int scWidth = *scIter;
720 if (scWidth == 0 && !nopEncodingSet && createNopField) {
721 new NOPEncoding(enc.first, enc.second, field);
722 nopEncodingSet = true;
723 } else if (!immEncodingSet && scWidth == bus->immediateWidth()) {
725 enc.first, enc.second, bus->immediateWidth(), field);
726 immEncodingSet = true;
727 } else {
728 bool socketFound = false;
729 // find the socket that has correct socket code width
730 for (int i = 0; i < srcSockets; i++) {
732 i, *bus, Socket::OUTPUT);
734 if (scTable == NULL && scWidth == 0 &&
735 !AssocTools::containsKey(handledSockets, &socket)) {
736 new SocketEncoding(
737 socket.name(), enc.first, enc.second, field);
738 handledSockets.insert(&socket);
739 socketFound = true;
740 break;
741 } else if (scTable != NULL && scWidth == scTable->width() &&
743 handledSockets, &socket)) {
744 SocketEncoding* socketEnc = new SocketEncoding(
745 socket.name(), enc.first, enc.second, field);
746 socketEnc->setSocketCodes(*scTable);
747 handledSockets.insert(&socket);
748 socketFound = true;
749 break;
750 }
751 }
752 if (!socketFound) {
753 assert(scWidth == 0);
754 assert(nextBridge < srcBridges);
756 nextBridge, *bus);
757 new BridgeEncoding(
758 bridge.name(), enc.first, enc.second, field);
759 nextBridge++;
760 }
761 }
762 scIter++;
763 }
764}
static int sourceBridgeCount(const TTAMachine::Bus &bus)
static TTAMachine::Bridge & sourceBridge(int index, const TTAMachine::Bus &bus)
int immediateWidth() const
Definition Bus.cc:160
@ OUTPUT
Data goes from port to bus.
Definition Socket.hh:60

References assert, TTAMachine::Machine::busNavigator(), calculateEncodings(), AssocTools::containsKey(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAMachine::Bus::immediateWidth(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::Component::name(), TTAMachine::Socket::OUTPUT, SlotField::parent(), SocketEncoding::setSocketCodes(), socket(), socketCodeTable(), socketCodeWidthsForBus(), socketCount(), sourceBridge(), sourceBridgeCount(), and SocketCodeTable::width().

Here is the call graph for this function:

◆ addExtraBits()

void BEMGenerator::addExtraBits ( std::multiset< Encoding > &  encodings,
int  bitCount 
)
staticprivate

Adds the given number of extra bits to the encodings in the given set.

Parameters
encodingsThe encodings.
bitLengthThe number of bits.

Definition at line 1351 of file BEMGenerator.cc.

1353 {
1354
1355 multiset<Encoding> newSet;
1356 for (multiset<Encoding>::iterator iter = encodings.begin();
1357 iter != encodings.end(); iter++) {
1358 unsigned int encoding = iter->first;
1359 unsigned int extraBits = iter->second;
1360 extraBits += bitCount;
1361 newSet.insert(Encoding(encoding, extraBits));
1362 }
1363
1364 encodings.clear();
1365 encodings.insert(newSet.begin(), newSet.end());
1366}
std::pair< unsigned int, unsigned int > Encoding
Typedef for encoding (first = encoding, second = extra bits).

Referenced by calculateEncodings().

◆ addLongImmDstRegisterFields()

void BEMGenerator::addLongImmDstRegisterFields ( BinaryEncoding bem) const
private

Adds the long immediate destination register fields to the given binary encoding map.

Parameters
bemThe binary encoding map.

Definition at line 445 of file BEMGenerator.cc.

445 {
446
447 // check how many fields is needed
450 int fieldCount(0);
451 for (int i = 0; i < itNav.count(); i++) {
452 InstructionTemplate* iTemp = itNav.item(i);
453 int thisRequires = 0;
456 for (int i = 0; i < iuNav.count(); i++) {
457 ImmediateUnit* iu = iuNav.item(i);
458 if (iu->numberOfRegisters() > 1 &&
459 iTemp->isOneOfDestinations(*iu)) {
460 thisRequires++;
461 }
462 }
463
464 if (thisRequires > fieldCount) {
465 fieldCount = thisRequires;
466 }
467 }
468
469 // create a vector that contains the required widths of the fields
472 std::vector<int> fieldWidths(fieldCount, 0);
473
474 for (int i = 0; i < itNav.count(); i++) {
475 InstructionTemplate* iTemp = itNav.item(i);
476
477 // collect the destinations units to a set
478 std::set<ImmediateUnit*> dstUnits;
479 for (int i = 0; i < iuNav.count(); i++) {
480 ImmediateUnit* iu = iuNav.item(i);
481 if (iTemp->isOneOfDestinations(*iu)) {
482 dstUnits.insert(iu);
483 }
484 }
485
486 // create a set containing the sizes required by all the destinations
487 // of the instruction template
488 std::multiset<int> requiredSizes;
489 for (set<ImmediateUnit*>::const_iterator iter = dstUnits.begin();
490 iter != dstUnits.end(); iter++) {
491 ImmediateUnit* iu = *iter;
492 if (iu->numberOfRegisters() > 1) {
493 requiredSizes.insert(
495 }
496 }
497
498 // increase the values in fieldWidhts if required
499 int counter(0);
500 for (multiset<int>::const_reverse_iterator iter =
501 requiredSizes.rbegin();
502 iter != requiredSizes.rend(); iter++) {
503 if (fieldWidths[counter] < *iter) {
504 fieldWidths[counter] = *iter;
505 }
506 counter++;
507 }
508 }
509
510 // create the fields
511 typedef std::pair<InstructionTemplate*, ImmediateUnit*> ImmDstMapping;
512 std::set<ImmDstMapping> mappedDestinations;
513 for (int i = fieldCount-1; i >= 0; i--) {
514 unsigned int fieldWidth = fieldWidths[i];
516 fieldWidth, bem);
517 for (int i = 0; i < itNav.count(); i++) {
518 InstructionTemplate* iTemp = itNav.item(i);
519 for (int i = 0; i < iuNav.count(); i++) {
520 ImmediateUnit* iu = iuNav.item(i);
521 if (iTemp->isOneOfDestinations(*iu) &&
522 iu->numberOfRegisters() > 1 &&
523 static_cast<unsigned int>(
525 <= fieldWidth &&
527 mappedDestinations,
528 ImmDstMapping(iTemp, iu))) {
529 newField->addDestination(iTemp->name(), iu->name());
530 mappedDestinations.insert(ImmDstMapping(iTemp, iu));
531 }
532 }
533 }
534 }
535}
void addDestination(const std::string &instructionTemplate, const std::string &immediateUnit)
static unsigned int bitLength(long unsigned int number)
virtual int numberOfRegisters() const
virtual bool isOneOfDestinations(const ImmediateUnit &dstUnit) const
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416

References LImmDstRegisterField::addDestination(), MathTools::bitLength(), AssocTools::containsKey(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::InstructionTemplate::isOneOfDestinations(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::Component::name(), and TTAMachine::BaseRegisterFile::numberOfRegisters().

Referenced by addTopLevelFields().

Here is the call graph for this function:

◆ addPortCodes()

void BEMGenerator::addPortCodes ( SocketCodeTable table,
const TTAMachine::Socket socket 
) const
private

Adds the port codes to the given socket code table.

Parameters
tableThe socket code table.
socketThe socket that will refer to the table.

Definition at line 969 of file BEMGenerator.cc.

971 {
972
973 // create a set of register index widths for each port code
974 multiset<int> indexWidths;
975 for (int i = 0; i < socket.portCount(); i++) {
976 Port* port = socket.port(i);
977 Unit* parentUnit = port->parentUnit();
978 BaseRegisterFile* rfParent = dynamic_cast<BaseRegisterFile*>(
979 parentUnit);
980 FunctionUnit* fuParent = dynamic_cast<FunctionUnit*>(parentUnit);
981
982 if (fuParent != NULL) {
983 int encodingsNeeded(0);
984 if (dynamic_cast<BaseFUPort*>(port)->isOpcodeSetting() &&
986 encodingsNeeded = fuParent->operationCount();
987 } else {
988 encodingsNeeded = 1;
989 }
990 for (int i = 0; i < encodingsNeeded; i++) {
991 indexWidths.insert(0);
992 }
993 } else {
994 assert(rfParent != NULL);
995 unsigned int indexWidth = requiredIndexWidth(*rfParent);
996 indexWidths.insert(indexWidth);
997 }
998 }
999
1000 // calculate port IDs
1001 multiset<Encoding> encodings;
1002 calculateEncodings(indexWidths, true, encodings);
1003
1004 // set the encodings
1005 if (encodings.size() == 0) {
1006 assert(socket.portCount() == 1);
1007 Port* port = socket.port(0);
1008 ImmediateUnit* iu = dynamic_cast<ImmediateUnit*>(port->parentUnit());
1009 RegisterFile* rf = dynamic_cast<RegisterFile*>(port->parentUnit());
1010 assert(iu != NULL || rf != NULL);
1011 // iu must be first because iu is inherited from rf
1012 if (iu != NULL) {
1013 new IUPortCode(iu->name(), requiredIndexWidth(*iu), table);
1014 } else {
1015 new RFPortCode(rf->name(), requiredIndexWidth(*rf), table);
1016 }
1017 } else {
1018 set<Port*> handledPorts;
1019 multiset<int>::const_reverse_iterator indexWidthIter =
1020 indexWidths.rbegin();
1021 for (multiset<Encoding>::const_iterator encIter = encodings.begin();
1022 encIter != encodings.end();) {
1023 int indexWidth = *indexWidthIter;
1024 Encoding enc = *encIter;
1025 for (int portIndex = 0; portIndex < socket.portCount();
1026 portIndex++) {
1027 Port* port = socket.port(portIndex);
1028 if (AssocTools::containsKey(handledPorts, port)) {
1029 continue;
1030 }
1031 RegisterFile* rfParent = dynamic_cast<RegisterFile*>(
1032 port->parentUnit());
1033 ImmediateUnit* iuParent = dynamic_cast<ImmediateUnit*>(
1034 port->parentUnit());
1035 FunctionUnit* fuParent = dynamic_cast<FunctionUnit*>(
1036 port->parentUnit());
1037 // iu must be first because iu is inherited from rf
1038 if (iuParent != NULL) {
1039 int reqIndexWidth = requiredIndexWidth(*iuParent);
1040 if (reqIndexWidth == indexWidth) {
1041 new IUPortCode(
1042 iuParent->name(), enc.first, enc.second,
1043 reqIndexWidth, table);
1044 indexWidthIter++;
1045 encIter++;
1046 handledPorts.insert(port);
1047 break;
1048 }
1049 } else if (rfParent != NULL) {
1050 int reqIndexWidth = requiredIndexWidth(*rfParent);
1051 if (reqIndexWidth == indexWidth) {
1052 new RFPortCode(
1053 rfParent->name(), enc.first, enc.second,
1054 reqIndexWidth, table);
1055 indexWidthIter++;
1056 encIter++;
1057 handledPorts.insert(port);
1058 break;
1059 }
1060 } else {
1061 if (indexWidth != 0) {
1062 continue;
1063 }
1064 assert(fuParent != NULL);
1065 BaseFUPort* fuPort = dynamic_cast<BaseFUPort*>(port);
1066 assert(fuPort != NULL);
1067 if (fuPort->isOpcodeSetting()) {
1068 // map<operation name, operation index in FU>
1069 map<string,int> opcodeSet;
1070 assert(*indexWidthIter == 0);
1071 // operation indeces are numbered according to the
1072 // alphabetical order of opertations
1073 for (int opIndex = 0;
1074 opIndex < fuParent->operationCount();
1075 opIndex++) {
1076 opcodeSet.insert(
1077 make_pair(
1078 fuParent->operation(opIndex)->name(),
1079 opIndex));
1080 }
1081
1082 for (map<string,int>::iterator
1083 iter = opcodeSet.begin();
1084 iter != opcodeSet.end(); iter++) {
1085 Encoding enc = *encIter;
1086 HWOperation* operation =
1087 fuParent->operation(iter->second);
1088 assert(operation->name() == iter->first);
1089 new FUPortCode(
1090 fuParent->name(), fuPort->name(),
1091 operation->name(), enc.first, enc.second,
1092 table);
1093 indexWidthIter++;
1094 encIter++;
1095 }
1096 } else {
1097 new FUPortCode(
1098 fuParent->name(), fuPort->name(), enc.first,
1099 enc.second, table);
1100 indexWidthIter++;
1101 encIter++;
1102 }
1103 handledPorts.insert(port);
1104 break;
1105 }
1106 }
1107 }
1108 }
1109}
static int requiredIndexWidth(const TTAMachine::BaseRegisterFile &regFile)
virtual bool isOpcodeSetting() const =0
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
const std::string & name() const
Unit * parentUnit() const
Direction direction() const
Port * port(int index) const
Definition Socket.cc:266
int portCount() const

References assert, calculateEncodings(), AssocTools::containsKey(), TTAMachine::Socket::direction(), TTAMachine::Socket::INPUT, TTAMachine::BaseFUPort::isOpcodeSetting(), TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), TTAMachine::Port::parentUnit(), TTAMachine::Socket::port(), TTAMachine::Socket::portCount(), requiredIndexWidth(), and socket().

Referenced by addSocketCodeTables().

Here is the call graph for this function:

◆ addRiscvFormat()

void BEMGenerator::addRiscvFormat ( TTAMachine::OperationTriggeredFormat format,
BinaryEncoding bem,
unsigned &  amountOfRCustomOps,
unsigned &  amountOfR3RCustomOps 
) const
private

Adds a RISC-V format to the binary encoding map

Parameters
formatThe operation triggered format
bemThe binary encoding

Definition at line 203 of file BEMGenerator.cc.

205 {
206 std::string name = format->name();
207 InstructionFormat* instrFormat = new InstructionFormat(name, bem);
208 const unsigned OPC_CUSTOM_0 = 0b0001011;
209 const unsigned OPC_CUSTOM_1 = 0b0101011;
210
211 if (name == RISCVFields::RISCV_R_TYPE_NAME) {
213 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
215 new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
217 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
218 new OperationTriggeredField(*rs1, 0, 15, 5);
219 new OperationTriggeredField(*rs2, 0, 20, 5);
220 new OperationTriggeredField(*rd, 0, 7, 5);
222 std::string("opcode"), *instrFormat);
223 new OperationTriggeredField(*opcode, 0, 0, 7);
224 new OperationTriggeredField(*opcode, 1, 12, 3);
225 new OperationTriggeredField(*opcode, 2, 25, 7);
226
227 // Reserve first few encodings for fixed special case
228 for (int i = 0; i < format->operationCount(); i++) {
229 const std::string op = format->operationAtIndex(i);
231 instrFormat->addOperation(op, RISCVFields::RISCVRTypeOperations.at(op));
232 } else {
233 unsigned int customEncoding = OPC_CUSTOM_0;
234 customEncoding += (amountOfRCustomOps << 7);
235 amountOfRCustomOps++;
236 // 10 bit encoding for operation
237 assert(amountOfRCustomOps < 1024);
238 instrFormat->addOperation(op, customEncoding);
239 }
240 }
241 } else if (name == RISCVFields::RISCV_I_TYPE_NAME) {
242 // TODO: shift operations use immediate bits for funct code in this
243 // format
245 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
247 new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
249 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
250 new OperationTriggeredField(*rs1, 0, 15, 5);
251 new OperationTriggeredField(*imm, 0, 25, 12);
252 new OperationTriggeredField(*rd, 0, 7, 5);
254 std::string("opcode"), *instrFormat);
255 new OperationTriggeredField(*opcode, 0, 0, 7);
256 new OperationTriggeredField(*opcode, 1, 12, 3);
257 new OperationTriggeredField(*opcode, 2, 25, 7);
258 for (int i = 0; i < format->operationCount(); i++) {
259 const std::string op = format->operationAtIndex(i);
261 instrFormat->addOperation(op, RISCVFields::RISCVITypeOperations.at(op));
262 } else {
263 assert(false);
264 }
265 }
266 } else if (name == RISCVFields::RISCV_S_TYPE_NAME) {
268 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
270 new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
272 new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
273 new OperationTriggeredField(*rs1, 0, 15, 5);
274 new OperationTriggeredField(*rs2, 0, 20, 5);
275 new OperationTriggeredField(*imm, 0, 7, 5);
276 new OperationTriggeredField(*imm, 1, 25, 7);
278 std::string("opcode"), *instrFormat);
279 new OperationTriggeredField(*opcode, 0, 0, 7);
280 new OperationTriggeredField(*opcode, 1, 12, 3);
281 for (int i = 0; i < format->operationCount(); i++) {
282 const std::string op = format->operationAtIndex(i);
284 instrFormat->addOperation(op, RISCVFields::RISCVSTypeOperations.at(op));
285 } else {
286 assert(false);
287 }
288 }
289 } else if (name == RISCVFields::RISCV_B_TYPE_NAME) {
291 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
293 new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
295 new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
296 new OperationTriggeredField(*rs1, 0, 15, 5);
297 new OperationTriggeredField(*rs2, 0, 20, 5);
298 new OperationTriggeredField(*imm, 0, 8, 4);
299 new OperationTriggeredField(*imm, 1, 25, 6);
300 new OperationTriggeredField(*imm, 2, 11, 1);
301 new OperationTriggeredField(*imm, 3, 31, 1);
303 std::string("opcode"), *instrFormat);
304 new OperationTriggeredField(*opcode, 0, 0, 7);
305 new OperationTriggeredField(*opcode, 1, 12, 3);
306 for (int i = 0; i < format->operationCount(); i++) {
307 const std::string op = format->operationAtIndex(i);
309 instrFormat->addOperation(op, RISCVFields::RISCVBTypeOperations.at(op));
310 } else {
311 assert(false);
312 }
313 }
314 } else if (name == RISCVFields::RISCV_U_TYPE_NAME) {
316 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
317 new OperationTriggeredField(*rd, 0, 7, 5);
319 std::string("opcode"), *instrFormat);
321 new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
322 new OperationTriggeredField(*imm, 0, 12, 20);
323 new OperationTriggeredField(*opcode, 0, 0, 7);
324 for (int i = 0; i < format->operationCount(); i++) {
325 const std::string op = format->operationAtIndex(i);
327 instrFormat->addOperation(op, RISCVFields::RISCVUTypeOperations.at(op));
328 } else {
329 assert(false);
330 }
331 }
332 } else if (name == RISCVFields::RISCV_J_TYPE_NAME) {
334 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
335 new OperationTriggeredField(*rd, 0, 7, 5);
337 std::string("opcode"), *instrFormat);
339 new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
340 new OperationTriggeredField(*imm, 0, 20, 10);
341 new OperationTriggeredField(*imm, 1, 20, 1);
342 new OperationTriggeredField(*imm, 2, 15, 8);
343 new OperationTriggeredField(*imm, 3, 31, 1);
344 new OperationTriggeredField(*opcode, 0, 0, 7);
345 for (int i = 0; i < format->operationCount(); i++) {
346 const std::string op = format->operationAtIndex(i);
348 instrFormat->addOperation(op, RISCVFields::RISCVJTypeOperations.at(op));
349 } else {
350 assert(false);
351 }
352 }
353 // This is a custom format for unary operations
354 // but it still uses R-format with rs2 = x0
355 } else if (name == RISCVFields::RISCV_R1R_TYPE_NAME) {
357 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
359 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
360 new OperationTriggeredField(*rs1, 0, 15, 5);
361 new OperationTriggeredField(*rd, 0, 7, 5);
363 std::string("opcode"), *instrFormat);
364 new OperationTriggeredField(*opcode, 0, 0, 7);
365 new OperationTriggeredField(*opcode, 1, 12, 3);
366 new OperationTriggeredField(*opcode, 2, 25, 7);
367
368 for (int i = 0; i < format->operationCount(); i++) {
369 const std::string op = format->operationAtIndex(i);
370 unsigned int customEncoding = OPC_CUSTOM_0;
371 customEncoding += (amountOfRCustomOps << 7);
372 amountOfRCustomOps++;
373 // 10 bit encoding for operation
374 assert(amountOfRCustomOps < 1024);
375 instrFormat->addOperation(op, customEncoding);
376 }
377 // unary without output, stdout for example
378 } else if (name == RISCVFields::RISCV_R1_TYPE_NAME) {
380 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
381 new OperationTriggeredField(*rs1, 0, 15, 5);
383 std::string("opcode"), *instrFormat);
384 new OperationTriggeredField(*opcode, 0, 0, 7);
385 new OperationTriggeredField(*opcode, 1, 12, 3);
386 new OperationTriggeredField(*opcode, 2, 25, 7);
387
388 for (int i = 0; i < format->operationCount(); i++) {
389 const std::string op = format->operationAtIndex(i);
390 unsigned int customEncoding = OPC_CUSTOM_0;
391 // Reserve this for printing
392 if (TCEString(op).lower() != "stdout") {
393 customEncoding += (amountOfRCustomOps << 7);
394 amountOfRCustomOps++;
395 }
396 // 10 bit encoding for operation
397 assert(amountOfRCustomOps < 1024);
398 instrFormat->addOperation(op, customEncoding);
399 }
400 } else if (name == RISCVFields::RISCV_R3R_TYPE_NAME) {
402 new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
404 new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
406 new OperationTriggeredEncoding(std::string("rs3"), *instrFormat);
408 new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
409 new OperationTriggeredField(*rs1, 0, 15, 5);
410 new OperationTriggeredField(*rs2, 0, 20, 5);
411 new OperationTriggeredField(*rs3, 0, 27, 5);
412 new OperationTriggeredField(*rd, 0, 7, 5);
414 std::string("opcode"), *instrFormat);
415 new OperationTriggeredField(*opcode, 0, 0, 7);
416 new OperationTriggeredField(*opcode, 1, 12, 3);
417 new OperationTriggeredField(*opcode, 2, 25, 2);
418
419 // Reserve first few encodings for fixed special case
420 for (int i = 0; i < format->operationCount(); i++) {
421 const std::string op = format->operationAtIndex(i);
423 instrFormat->addOperation(op, RISCVFields::RISCVRTypeOperations.at(op));
424 } else {
425 unsigned int customEncoding = OPC_CUSTOM_1;
426 customEncoding += (amountOfR3RCustomOps << 7);
427 amountOfR3RCustomOps++;
428 assert(amountOfR3RCustomOps < 32);
429 instrFormat->addOperation(op, customEncoding);
430 }
431 }
432 } else {
433 // TODO: Throw some meaniningful exception here
434 assert(false);
435 }
436}
void addOperation(std::string op, int encoding)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
const std::string RISCV_S_TYPE_NAME
const std::string RISCV_R1R_TYPE_NAME
const std::string RISCV_R3R_TYPE_NAME
const std::map< std::string, int > RISCVSTypeOperations
const std::string RISCV_B_TYPE_NAME
const std::map< std::string, int > RISCVJTypeOperations
const std::map< std::string, int > RISCVITypeOperations
const std::string RISCV_J_TYPE_NAME
const std::map< std::string, int > RISCVUTypeOperations
const std::string RISCV_R_TYPE_NAME
const std::string RISCV_R1_TYPE_NAME
const std::string RISCV_I_TYPE_NAME
const std::string RISCV_U_TYPE_NAME
const std::map< std::string, int > RISCVRTypeOperations
Definition RISCVFields.hh:8
const std::map< std::string, int > RISCVBTypeOperations

References InstructionFormat::addOperation(), assert, MapTools::containsKey(), TTAMachine::Component::name(), TTAMachine::OperationTriggeredFormat::operationAtIndex(), TTAMachine::OperationTriggeredFormat::operationCount(), RISCVFields::RISCV_B_TYPE_NAME, RISCVFields::RISCV_I_TYPE_NAME, RISCVFields::RISCV_J_TYPE_NAME, RISCVFields::RISCV_R1_TYPE_NAME, RISCVFields::RISCV_R1R_TYPE_NAME, RISCVFields::RISCV_R3R_TYPE_NAME, RISCVFields::RISCV_R_TYPE_NAME, RISCVFields::RISCV_S_TYPE_NAME, RISCVFields::RISCV_U_TYPE_NAME, RISCVFields::RISCVBTypeOperations, RISCVFields::RISCVITypeOperations, RISCVFields::RISCVJTypeOperations, RISCVFields::RISCVRTypeOperations, RISCVFields::RISCVSTypeOperations, and RISCVFields::RISCVUTypeOperations.

Referenced by addTopLevelFields().

Here is the call graph for this function:

◆ addSocketCodeTables()

void BEMGenerator::addSocketCodeTables ( BinaryEncoding bem)
private

Adds the socket code tables to the given binary encoding map.

Parameters
bemThe binary encoding map.

Definition at line 125 of file BEMGenerator.cc.

125 {
127 for (int i = 0; i < socketNav.count(); i++) {
128 Socket* socket = socketNav.item(i);
131 if (suitable != NULL) {
132 assignSocketCodeTable(socket, suitable);
133 } else {
134 SocketCodeTable* table =
135 new SocketCodeTable(socket->name(), bem);
136 addPortCodes(*table, *socket);
138 }
139 }
140 }
141}
static bool needsSocketCodeTable(const TTAMachine::Socket &socket)
void addPortCodes(SocketCodeTable &table, const TTAMachine::Socket &socket) const
SocketCodeTable * suitableSocketCodeTable(const TTAMachine::Socket &socket) const
void assignSocketCodeTable(const TTAMachine::Socket *socket, SocketCodeTable *table)
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368

References addPortCodes(), assignSocketCodeTable(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::Component::name(), needsSocketCodeTable(), socket(), TTAMachine::Machine::socketNavigator(), and suitableSocketCodeTable().

Referenced by generate().

Here is the call graph for this function:

◆ addSubfields()

void BEMGenerator::addSubfields ( MoveSlot slot) const
private

Adds subfields to the given move slot.

Parameters
slotThe move slot.

Definition at line 544 of file BEMGenerator.cc.

544 {
545
546 string busName = slot.name();
548 assert(busNav.hasItem(busName));
549 Bus* bus = busNav.item(busName);
550
553 SourceField* sField = new SourceField(BinaryEncoding::LEFT, slot);
554 GuardField* gField = NULL;
555
556 addEncodings(*dField); // destination field
557 addEncodings(*sField); // source field
558
559 // we need guard field only if we have >1 guard.
560 if (bus->guardCount() > 1) {
561 gField = new GuardField(slot);
562 addEncodings(*gField); // guard field
563 }
564
565 // adds extra bits to guard field (any field is probably ok) if needed.
566 // extra bits added so that long immediate fits to the slot.
567 int longImmWidth = maxLongImmSlotWidth(slot);
568 if (longImmWidth > slot.width()) {
569 // if no guard field, create it so that it can be enlarged.
570 if (gField == NULL) {
571 gField = new GuardField(slot);
572 addEncodings(*gField); // guard field
573 }
574 gField->setExtraBits((longImmWidth - slot.width()) +
575 gField->extraBits());
576 }
577}
void addEncodings(ImmediateControlField &field) const
unsigned int maxLongImmSlotWidth(const MoveSlot &slot) const
void setExtraBits(int bits)
virtual int width() const
Definition MoveSlot.cc:406

References addEncodings(), assert, TTAMachine::Machine::busNavigator(), InstructionField::extraBits(), TTAMachine::Bus::guardCount(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAMachine::Machine::Navigator< ComponentType >::item(), BinaryEncoding::LEFT, machine_, maxLongImmSlotWidth(), MoveSlot::name(), InstructionField::setExtraBits(), and MoveSlot::width().

Referenced by generate().

Here is the call graph for this function:

◆ addTopLevelFields()

void BEMGenerator::addTopLevelFields ( BinaryEncoding bem) const
private

Adds the top-level fields to the given binary encoding map.

Parameters
bemThe binary encoding to be modified.

Definition at line 150 of file BEMGenerator.cc.

150 {
151
152 // add immediate slots
155 for (int i = 0; i < isNav.count(); i++) {
156 ImmediateSlot* slot = isNav.item(i);
157 int width = slot->width();
158 if (width > 0) {
159 new ImmediateSlotField(slot->name(), width, bem);
160 }
161 }
162
163 // add move slots
165 for (int i = 0; i < busNav.count(); i++) {
166 Bus* bus = busNav.item(i);
167 new MoveSlot(bus->name(), bem);
168 }
169
170 // add long immediate destination register fields
172
173 // add long immediate control field
176
177 if (itNav.count() > 1) {
179 addEncodings(*field);
180 }
181
182 unsigned amountOfRCustomOps = 0;
183 unsigned amountOfR3RCustomOps = 0;
184
187
188 // For CVX-IF, make sure these are iterated in the correct order.
189 for (int i = 0; i < fNav.count(); i++) {
190 OperationTriggeredFormat* fTemp = fNav.item(i);
191 addRiscvFormat(fTemp, bem, amountOfRCustomOps, amountOfR3RCustomOps);
192 }
193}
void addRiscvFormat(TTAMachine::OperationTriggeredFormat *format, BinaryEncoding &bem, unsigned &amountOfRCustomOps, unsigned &amountOfR3RCustomOps) const
void addLongImmDstRegisterFields(BinaryEncoding &bem) const
virtual ImmediateSlotNavigator immediateSlotNavigator() const
Definition Machine.cc:462
virtual OperationTriggeredFormatNavigator operationTriggeredFormatNavigator() const
Definition Machine.cc:439

References addEncodings(), addLongImmDstRegisterFields(), addRiscvFormat(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::immediateSlotNavigator(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::Component::name(), TTAMachine::Machine::operationTriggeredFormatNavigator(), and TTAMachine::ImmediateSlot::width().

Referenced by generate().

Here is the call graph for this function:

◆ assignSocketCodeTable()

void BEMGenerator::assignSocketCodeTable ( const TTAMachine::Socket socket,
SocketCodeTable table 
)
private

Assigns the given socket code table for the given socket.

Parameters
socketThe socket.
tableThe socket code table.

Definition at line 852 of file BEMGenerator.cc.

854 {
855
857 scTableMap_.insert(pair<const Socket*, SocketCodeTable*>(socket, table));
858}
SCTableMap scTableMap_
A map which tells which socket code table belongs to a socket.

References assert, MapTools::containsKey(), scTableMap_, and socket().

Referenced by addSocketCodeTables().

Here is the call graph for this function:

◆ calculateEncodings()

void BEMGenerator::calculateEncodings ( const std::multiset< int > &  oppositeFieldWidths,
bool  alignment,
std::multiset< Encoding > &  encodings 
)
staticprivate

Calculates unambiguous encodings when the encodings have opposite fields of the given widths.

Minimizes both the total width of the field and the width of the encodings. Currently supports only left aligment of encodings.

Parameters
oppositeFieldWidthsWidths of the opposite fields.
alignmentTells whether the encodings are aligned to left (true) or right (false).
encodingThe encodings are added here.

Definition at line 1279 of file BEMGenerator.cc.

1282 {
1283
1284 if (oppositeFieldWidths.size() < 1) {
1285 return;
1286 }
1287
1288 assert(alignment);
1289
1290 unsigned int remainder = 0;
1291 unsigned int encodingsLeft = oppositeFieldWidths.size();
1292 unsigned int prevEncoding = 0;
1293 unsigned int nextEncoding = 0;
1294 unsigned int prevOppositeFieldWidth = 0;
1295
1296 for (multiset<int>::reverse_iterator iter = oppositeFieldWidths.rbegin();
1297 iter != oppositeFieldWidths.rend(); iter++) {
1298 unsigned int oppositeFieldWidth = *iter;
1299 if (iter == oppositeFieldWidths.rbegin()) {
1300 nextEncoding = 0;
1301 encodings.insert(Encoding(nextEncoding, 0));
1302 remainder = 1;
1303 } else {
1304 nextEncoding = prevEncoding + 1;
1305 if (MathTools::bitLength(nextEncoding) >
1306 MathTools::bitLength(prevEncoding)) {
1307 addExtraBits(encodings, 1);
1308 unsigned int setEncodingCount =
1309 oppositeFieldWidths.size() - encodingsLeft;
1310 remainder = (remainder << 1) + setEncodingCount;
1311 }
1312
1313 if (oppositeFieldWidth == prevOppositeFieldWidth) {
1314 encodings.insert(Encoding(nextEncoding, 0));
1315 } else {
1316 assert(oppositeFieldWidth < prevOppositeFieldWidth);
1317 unsigned int freeBits =
1318 prevOppositeFieldWidth - oppositeFieldWidth;
1319 // calculate the number of bits the encoding has to be
1320 // expanded
1321 unsigned int expansion = 0;
1322 while (remainder << expansion < encodingsLeft) {
1323 if (expansion < freeBits) {
1324 expansion++;
1325 } else {
1326 break;
1327 }
1328 }
1329 nextEncoding = nextEncoding << expansion;
1330 encodings.insert(Encoding(nextEncoding, 0));
1331 remainder = remainder << expansion;
1332 }
1333 }
1334 prevOppositeFieldWidth = oppositeFieldWidth;
1335 encodingsLeft--;
1336 remainder--;
1337 prevEncoding = nextEncoding;
1338 }
1339
1340 assert(encodings.size() == oppositeFieldWidths.size());
1341}
static void addExtraBits(std::multiset< Encoding > &encodings, int bitCount)

References addExtraBits(), assert, and MathTools::bitLength().

Referenced by addEncodings(), addEncodings(), and addPortCodes().

Here is the call graph for this function:

◆ generate()

BinaryEncoding * BEMGenerator::generate ( )

Generates the binary encoding map.

Returns
The newly created binary encoding map.

Definition at line 104 of file BEMGenerator.cc.

104 {
105
106 BinaryEncoding* bem = new BinaryEncoding();
107
109 addTopLevelFields(*bem);
110 for (int i = 0; i < bem->moveSlotCount(); i++) {
111 MoveSlot& slot = bem->moveSlot(i);
112 addSubfields(slot);
113 }
114
115 return bem;
116}
void addSubfields(MoveSlot &slot) const
void addSocketCodeTables(BinaryEncoding &bem)
void addTopLevelFields(BinaryEncoding &bem) const
int moveSlotCount() const
MoveSlot & moveSlot(int index) const

References addSocketCodeTables(), addSubfields(), addTopLevelFields(), BinaryEncoding::moveSlot(), and BinaryEncoding::moveSlotCount().

Referenced by ProGe::ProGeUI::generateProcessor(), initializeMachine(), llvm::LLVMTCERISCVIntrinsicsLowering::LLVMTCERISCVIntrinsicsLowering(), ProcessorImplementationWindow::loadICDecoderPlugin(), RemoteController::loadIMemImage(), main(), GenerateProcessorDialog::onOK(), RISCVTDGen::RISCVTDGen(), and MachineCanvas::updateMachine().

Here is the call graph for this function:

◆ hasUnconditionalGuard()

bool BEMGenerator::hasUnconditionalGuard ( const TTAMachine::Bus bus)
staticprivate

Tells whether the given bus has an unconditional guard.

Parameters
busThe bus.
Returns
True if the bus has an unconditional guard, otherwise false.

Definition at line 1238 of file BEMGenerator.cc.

1238 {
1239 for (int i = 0; i < bus.guardCount(); i++) {
1240 Guard* guard = bus.guard(i);
1241 if (dynamic_cast<UnconditionalGuard*>(guard) != NULL) {
1242 return true;
1243 }
1244 }
1245 return false;
1246}

References TTAMachine::Bus::guard(), and TTAMachine::Bus::guardCount().

Here is the call graph for this function:

◆ haveEqualConnections()

bool BEMGenerator::haveEqualConnections ( const TTAMachine::Socket socket1,
const TTAMachine::Socket socket2 
)
staticprivate

Checks whether the given sockets have equal port connections.

Parameters
socket1The first socket.
socket2The second socket.
Returns
True if the sockets have equal port connections, otherwise false.

Definition at line 1149 of file BEMGenerator.cc.

1151 {
1152
1153 std::set<Port*> socket1Ports;
1154 std::set<Port*> socket2Ports;
1155
1156 for (int i = 0; i < socket1.portCount(); i++) {
1157 socket1Ports.insert(socket1.port(i));
1158 }
1159
1160 for (int i = 0; i < socket2.portCount(); i++) {
1161 socket2Ports.insert(socket2.port(i));
1162 }
1163
1164 if (socket1Ports == socket2Ports) {
1165 return true;
1166 } else {
1167 return false;
1168 }
1169}

References TTAMachine::Socket::port(), and TTAMachine::Socket::portCount().

Referenced by suitableSocketCodeTable().

Here is the call graph for this function:

◆ maxLongImmSlotWidth()

unsigned int BEMGenerator::maxLongImmSlotWidth ( const MoveSlot slot) const
private

Returns the width of the longest long immediate template being encoded in a slot given as parameter.

Parameters
slotMove slot where to check if it's used to store long immediates.
Returns
Width of the longest long immediate width stored in a move slot.

Definition at line 1377 of file BEMGenerator.cc.

1377 {
1380 int maxWidth = 0;
1381
1382 for (int i = 0; i < itNav.count(); i++) {
1383 InstructionTemplate* iTemp = itNav.item(i);
1384 for (int i = 0; i < iTemp->slotCount(); ++i) {
1385 if (slot.name() == iTemp->slot(i)->slot() &&
1386 maxWidth < iTemp->slot(i)->width()) {
1387
1388 maxWidth = iTemp->slot(i)->width();
1389 }
1390 }
1391 }
1392
1393 return maxWidth;
1394}
virtual TemplateSlot * slot(int index) const
std::string slot() const

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, MoveSlot::name(), TTAMachine::TemplateSlot::slot(), TTAMachine::InstructionTemplate::slot(), TTAMachine::InstructionTemplate::slotCount(), and TTAMachine::TemplateSlot::width().

Referenced by addSubfields().

Here is the call graph for this function:

◆ needsSocketCodeTable()

bool BEMGenerator::needsSocketCodeTable ( const TTAMachine::Socket socket)
staticprivate

Tells whether the given socket needs a socket code table.

Returns
True if the socket needs a socket code table, otherwise false.

Definition at line 933 of file BEMGenerator.cc.

933 {
934
935 if (socket.portCount() > 1) {
936 return true;
937
938 } else if (socket.portCount() == 1) {
939
940 // socket code table is needed if the port is opcode setting with
941 // more than one possible opcode or if the port is a data port of
942 // register file with more than one register
943 Port* port = socket.port(0);
944 FUPort* fuPort = dynamic_cast<FUPort*>(port);
945 RFPort* rfPort = dynamic_cast<RFPort*>(port);
946 if (fuPort != NULL && fuPort->isOpcodeSetting() &&
947 fuPort->parentUnit()->operationCount() > 1) {
948 return true;
949 } else if (rfPort != NULL &&
950 rfPort->parentUnit()->numberOfRegisters() > 1) {
951 return true;
952 } else {
953 return false;
954 }
955
956 } else {
957 return false;
958 }
959}
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
BaseRegisterFile * parentUnit() const
Definition RFPort.cc:93

References TTAMachine::FUPort::isOpcodeSetting(), TTAMachine::BaseRegisterFile::numberOfRegisters(), TTAMachine::FunctionUnit::operationCount(), TTAMachine::BaseFUPort::parentUnit(), TTAMachine::RFPort::parentUnit(), TTAMachine::Socket::port(), TTAMachine::Socket::portCount(), and socket().

Referenced by addSocketCodeTables().

Here is the call graph for this function:

◆ requiredIndexWidth()

int BEMGenerator::requiredIndexWidth ( const TTAMachine::BaseRegisterFile regFile)
staticprivate

Returns the number of bits needed to identify a register in the given register file.

Parameters
regFileThe register file.
Returns
The number of bits needed for register index.

Definition at line 1257 of file BEMGenerator.cc.

1257 {
1258 if (regFile.numberOfRegisters() <= 1) {
1259 return 0;
1260 } else {
1261 return MathTools::bitLength(regFile.numberOfRegisters() - 1);
1262 }
1263}

References MathTools::bitLength(), and TTAMachine::BaseRegisterFile::numberOfRegisters().

Referenced by addPortCodes().

Here is the call graph for this function:

◆ socket()

Socket & BEMGenerator::socket ( int  index,
const TTAMachine::Bus bus,
TTAMachine::Socket::Direction  direction 
)
staticprivate

By the given index, returns a socket that is attached to the given bus and has the given direction.

Parameters
indexThe index.
busThe bus.
directionDirection of the sockets being returned.
Returns
The socket.

Definition at line 899 of file BEMGenerator.cc.

902 {
903
904 typedef std::vector<Socket*> SocketTable;
905
906 assert(index >= 0);
907 SocketTable connectedSockets;
908
909 for (int i = 0; i < bus.segmentCount(); i++) {
910 Segment* segment = bus.segment(i);
911 for (int i = 0; i < segment->connectionCount(); i++) {
912 Socket* socket = segment->connection(i);
913 if (socket->direction() == direction) {
915 connectedSockets, socket)) {
916 connectedSockets.push_back(socket);
917 }
918 }
919 }
920 }
921
922 assert(connectedSockets.size() > static_cast<size_t>(index));
923 return *connectedSockets[index];
924}
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
virtual Segment * segment(int index) const
Definition Bus.cc:329
virtual int segmentCount() const
Definition Bus.cc:385
const Connection & connection(const Socket &socket) const
Definition Segment.cc:250
int connectionCount() const

References assert, TTAMachine::Segment::connection(), TTAMachine::Segment::connectionCount(), ContainerTools::containsValue(), TTAMachine::Socket::direction(), TTAMachine::Bus::segment(), TTAMachine::Bus::segmentCount(), and socket().

Referenced by addEncodings(), addEncodings(), addPortCodes(), addSocketCodeTables(), assignSocketCodeTable(), needsSocketCodeTable(), socket(), socketCodeTable(), socketCodeWidthsForBus(), socketCount(), and suitableSocketCodeTable().

Here is the call graph for this function:

◆ socketCodeTable()

SocketCodeTable * BEMGenerator::socketCodeTable ( const TTAMachine::Socket socket) const
private

Returns the socket code table that is assigned to the given socket.

Parameters
socketThe socket.
Returns
The socket code table or NULL if no socket code table is assigned to the given socket.

Definition at line 814 of file BEMGenerator.cc.

814 {
817 } else {
818 return NULL;
819 }
820}
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)

References MapTools::containsKey(), MapTools::keyForValue(), scTableMap_, and socket().

Referenced by addEncodings(), addEncodings(), and socketCodeWidthsForBus().

Here is the call graph for this function:

◆ socketCodeWidthsForBus()

std::multiset< int > BEMGenerator::socketCodeWidthsForBus ( const TTAMachine::Bus bus,
TTAMachine::Socket::Direction  socketDir 
) const
private

Returns a multiset containing the socket code widths for sockets of the given direction that are connected to the given bus.

Parameters
busThe bus.
socketThe direction.
Returns
The multiset.

Definition at line 1121 of file BEMGenerator.cc.

1123 {
1124
1125 std::multiset<int> socketCodeWidths;
1126 int socketCount = BEMGenerator::socketCount(bus, socketDir);
1127 for (int i = 0; i < socketCount; i++) {
1128 Socket& socket = BEMGenerator::socket(i, bus, socketDir);
1130 if (scTable == NULL) {
1131 socketCodeWidths.insert(0);
1132 } else {
1133 socketCodeWidths.insert(scTable->width());
1134 }
1135 }
1136
1137 return socketCodeWidths;
1138}

References socket(), socketCodeTable(), socketCount(), and SocketCodeTable::width().

Referenced by addEncodings(), and addEncodings().

Here is the call graph for this function:

◆ socketCount()

int BEMGenerator::socketCount ( const TTAMachine::Bus bus,
TTAMachine::Socket::Direction  direction 
)
staticprivate

Returns the number of sockets of the given direction connected to the given bus.

Parameters
busThe bus.
directionThe direction
Returns
The number of sockets.

Definition at line 870 of file BEMGenerator.cc.

870 {
871
872 typedef std::set<Socket*> SocketSet;
873 SocketSet sockets;
874
875 for (int i = 0; i < bus.segmentCount(); i++) {
876 Segment* segment = bus.segment(i);
877 for (int i = 0; i < segment->connectionCount(); i++) {
878 Socket* socket = segment->connection(i);
879 if (socket->direction() == direction) {
880 sockets.insert(socket);
881 }
882 }
883 }
884
885 return sockets.size();
886}

References TTAMachine::Segment::connection(), TTAMachine::Segment::connectionCount(), TTAMachine::Socket::direction(), TTAMachine::Bus::segment(), TTAMachine::Bus::segmentCount(), and socket().

Referenced by addEncodings(), addEncodings(), and socketCodeWidthsForBus().

Here is the call graph for this function:

◆ sourceBridge()

Bridge & BEMGenerator::sourceBridge ( int  index,
const TTAMachine::Bus bus 
)
staticprivate

By the given index returns a source bridge for the given bus.

Parameters
indexThe index (0 or 1).
busThe bus.

Definition at line 1206 of file BEMGenerator.cc.

1206 {
1207
1208 Machine* mach = bus.machine();
1209 assert(mach != NULL);
1210 Machine::BridgeNavigator bridgeNav = mach->bridgeNavigator();
1211
1212 int count(0);
1213
1214 for (int i = 0; i < bridgeNav.count(); i++) {
1215 Bridge* bridge = bridgeNav.item(i);
1216 if (bridge->destinationBus() == &bus) {
1217 if (count == index) {
1218 return *bridge;
1219 } else {
1220 count++;
1221 }
1222 }
1223 }
1224
1225 assert(false);
1226 // dummy return
1227 return *bridgeNav.item(0);
1228}
Bus * destinationBus() const
virtual Machine * machine() const
virtual BridgeNavigator bridgeNavigator() const
Definition Machine.cc:404

References assert, TTAMachine::Machine::bridgeNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Bridge::destinationBus(), TTAMachine::Machine::Navigator< ComponentType >::item(), and TTAMachine::Component::machine().

Referenced by addEncodings().

Here is the call graph for this function:

◆ sourceBridgeCount()

int BEMGenerator::sourceBridgeCount ( const TTAMachine::Bus bus)
staticprivate

Tells how many source bridges the given bus has.

Parameters
busThe bus.
Returns
The number of source bridges.

Definition at line 1179 of file BEMGenerator.cc.

1179 {
1180
1181 Machine* mach = bus.machine();
1182 assert(mach != NULL);
1183 Machine::BridgeNavigator bridgeNav = mach->bridgeNavigator();
1184
1185 int count(0);
1186
1187 for (int i = 0; i < bridgeNav.count(); i++) {
1188 Bridge* bridge = bridgeNav.item(i);
1189 if (bridge->destinationBus() == &bus) {
1190 count++;
1191 }
1192 }
1193
1194 assert(count <= 2);
1195 return count;
1196}

References assert, TTAMachine::Machine::bridgeNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Bridge::destinationBus(), TTAMachine::Machine::Navigator< ComponentType >::item(), and TTAMachine::Component::machine().

Referenced by addEncodings().

Here is the call graph for this function:

◆ suitableSocketCodeTable()

SocketCodeTable * BEMGenerator::suitableSocketCodeTable ( const TTAMachine::Socket socket) const
private

Finds a suitable socket code table from the socket code table map for the given socket.

Returns NULL if there is no suitable socket code table.

Parameters
socketThe socket.
Returns
The socket code table or NULL.

Definition at line 833 of file BEMGenerator.cc.

833 {
834 for (SCTableMap::const_iterator iter = scTableMap_.begin();
835 iter != scTableMap_.end(); iter++) {
836 const Socket* toCheck = (*iter).first;
837 if (haveEqualConnections(socket, *toCheck)) {
838 return (*iter).second;
839 }
840 }
841 return NULL;
842}
static bool haveEqualConnections(const TTAMachine::Socket &socket1, const TTAMachine::Socket &socket2)

References haveEqualConnections(), scTableMap_, and socket().

Referenced by addSocketCodeTables().

Here is the call graph for this function:

Member Data Documentation

◆ machine_

const TTAMachine::Machine* BEMGenerator::machine_
private

◆ scTableMap_

SCTableMap BEMGenerator::scTableMap_
private

A map which tells which socket code table belongs to a socket.

Definition at line 131 of file BEMGenerator.hh.

Referenced by assignSocketCodeTable(), socketCodeTable(), and suitableSocketCodeTable().


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