OpenASIP  2.0
BEMGenerator.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file BEMGenerator.cc
26  *
27  * Implementation of BEMGenerator class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @note rating: red
31  */
32 
33 #include <string>
34 #include <set>
35 #include <map>
36 #include "BEMGenerator.hh"
37 #include "BinaryEncoding.hh"
38 #include "MoveSlot.hh"
39 #include "ImmediateSlotField.hh"
40 #include "ImmediateControlField.hh"
41 #include "LImmDstRegisterField.hh"
42 #include "DestinationField.hh"
43 #include "SourceField.hh"
44 #include "GuardField.hh"
45 #include "SocketEncoding.hh"
46 #include "BridgeEncoding.hh"
47 #include "ImmediateEncoding.hh"
48 #include "FUGuardEncoding.hh"
49 #include "GPRGuardEncoding.hh"
51 #include "NOPEncoding.hh"
52 #include "SocketCodeTable.hh"
53 #include "FUPortCode.hh"
54 #include "RFPortCode.hh"
55 #include "IUPortCode.hh"
56 #include "MathTools.hh"
57 #include "Machine.hh"
58 #include "Segment.hh"
59 #include "HWOperation.hh"
60 #include "FUPort.hh"
61 #include "Guard.hh"
62 #include "MapTools.hh"
63 #include "AssocTools.hh"
64 #include "TemplateSlot.hh"
65 #include "RISCVFields.hh"
66 #include "InstructionFormat.hh"
70 #include "TCEString.hh"
71 
72 using std::string;
73 using std::pair;
74 using std::set;
75 using std::vector;
76 using std::multiset;
77 using std::map;
78 using namespace TTAMachine;
79 
80 /**
81  * The constructor.
82  *
83  * @param machine The machine for which the binary encoding map will be
84  * generated.
85  */
87  machine_(&machine) {
88 }
89 
90 
91 /**
92  * The destructor.
93  */
95 }
96 
97 
98 /**
99  * Generates the binary encoding map.
100  *
101  * @return The newly created binary encoding map.
102  */
105 
106  BinaryEncoding* bem = new BinaryEncoding();
107 
108  addSocketCodeTables(*bem);
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 }
117 
118 
119 /**
120  * Adds the socket code tables to the given binary encoding map.
121  *
122  * @param bem The binary encoding map.
123  */
124 void
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 }
142 
143 
144 /**
145  * Adds the top-level fields to the given binary encoding map.
146  *
147  * @param bem The binary encoding to be modified.
148  */
149 void
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 
184  for (int i = 0; i < fNav.count(); i++) {
185  OperationTriggeredFormat* fTemp = fNav.item(i);
186  addRiscvFormat(fTemp, bem);
187  }
188 }
189 
190 /**
191  * Adds a RISC-V format to the binary encoding map
192  *
193  * @param format The operation triggered format
194  * @param bem The binary encoding
195  */
196 
197 void
199  OperationTriggeredFormat* format, BinaryEncoding& bem) const {
200  std::string name = format->name();
201  InstructionFormat* instrFormat = new InstructionFormat(name, bem);
202 
203  if (name == "riscv_r_type") {
205  new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
207  new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
209  new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
210  new OperationTriggeredField(*rs1, 0, 15, 5);
211  new OperationTriggeredField(*rs2, 0, 20, 5);
212  new OperationTriggeredField(*rd, 0, 7, 5);
214  std::string("opcode"), *instrFormat);
215  new OperationTriggeredField(*opcode, 0, 0, 7);
216  new OperationTriggeredField(*opcode, 1, 12, 3);
217  new OperationTriggeredField(*opcode, 2, 25, 7);
218 
219  std::vector<std::string> operations = format->operations();
220  // Preserve first few encodings for fixed special case
221  unsigned int amountOfCustomOps = 10;
222  for (const std::string& op : operations) {
224  instrFormat->addOperation(op, riscvRTypeOperations.at(op));
225  } else {
226  unsigned int customEncoding = 0b0001011;
227  //Preserve this for printing
228  if (TCEString(op).lower() == "stdout_riscv") {
229  customEncoding = 0b0001011;
230  } else {
231  customEncoding += (amountOfCustomOps << 7);
232  amountOfCustomOps++;
233  }
234  assert(amountOfCustomOps < 127);
235  instrFormat->addOperation(op, customEncoding);
236  }
237  }
238  } else if (name == "riscv_i_type") {
239  // TODO: shift operations use immediate bits for funct code in this
240  // format
242  new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
244  new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
246  new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
247  new OperationTriggeredField(*rs1, 0, 15, 5);
248  new OperationTriggeredField(*imm, 0, 25, 12);
249  new OperationTriggeredField(*rd, 0, 7, 5);
251  std::string("opcode"), *instrFormat);
252  new OperationTriggeredField(*opcode, 0, 0, 7);
253  new OperationTriggeredField(*opcode, 1, 12, 3);
254  new OperationTriggeredField(*opcode, 2, 25, 7);
255  std::vector<std::string> operations = format->operations();
256  for (const std::string& op : operations) {
258  instrFormat->addOperation(op, riscvITypeOperations.at(op));
259  } else {
260  assert(false);
261  }
262  }
263  } else if (name == "riscv_s_type") {
265  new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
267  new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
269  new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
270  new OperationTriggeredField(*rs1, 0, 15, 5);
271  new OperationTriggeredField(*rs2, 0, 20, 5);
272  new OperationTriggeredField(*imm, 0, 7, 5);
273  new OperationTriggeredField(*imm, 1, 25, 7);
275  std::string("opcode"), *instrFormat);
276  new OperationTriggeredField(*opcode, 0, 0, 7);
277  new OperationTriggeredField(*opcode, 1, 12, 3);
278  std::vector<std::string> operations = format->operations();
279  for (const std::string& op : operations) {
281  instrFormat->addOperation(op, riscvSTypeOperations.at(op));
282  } else {
283  assert(false);
284  }
285  }
286  } else if (name == "riscv_b_type") {
288  new OperationTriggeredEncoding(std::string("rs1"), *instrFormat);
290  new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
292  new OperationTriggeredEncoding(std::string("rs2"), *instrFormat);
293  new OperationTriggeredField(*rs1, 0, 15, 5);
294  new OperationTriggeredField(*rs2, 0, 20, 5);
295  new OperationTriggeredField(*imm, 0, 8, 4);
296  new OperationTriggeredField(*imm, 1, 25, 6);
297  new OperationTriggeredField(*imm, 2, 11, 1);
298  new OperationTriggeredField(*imm, 3, 31, 1);
300  std::string("opcode"), *instrFormat);
301  new OperationTriggeredField(*opcode, 0, 0, 7);
302  new OperationTriggeredField(*opcode, 1, 12, 3);
303  std::vector<std::string> operations = format->operations();
304  for (const std::string& op : operations) {
306  instrFormat->addOperation(op, riscvBTypeOperations.at(op));
307  } else {
308  assert(false);
309  }
310  }
311  } else if (name == "riscv_u_type") {
313  new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
314  new OperationTriggeredField(*rd, 0, 7, 5);
316  std::string("opcode"), *instrFormat);
318  new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
319  new OperationTriggeredField(*imm, 0, 12, 20);
320  new OperationTriggeredField(*opcode, 0, 0, 7);
321  std::vector<std::string> operations = format->operations();
322  for (const std::string& op : operations) {
324  instrFormat->addOperation(op, riscvUTypeOperations.at(op));
325  } else {
326  assert(false);
327  }
328  }
329  } else if (name == "riscv_j_type") {
331  new OperationTriggeredEncoding(std::string("rd"), *instrFormat);
332  new OperationTriggeredField(*rd, 0, 7, 5);
334  std::string("opcode"), *instrFormat);
336  new OperationTriggeredEncoding(std::string("imm"), *instrFormat);
337  new OperationTriggeredField(*imm, 0, 20, 10);
338  new OperationTriggeredField(*imm, 1, 20, 1);
339  new OperationTriggeredField(*imm, 2, 15, 8);
340  new OperationTriggeredField(*imm, 3, 31, 1);
341  new OperationTriggeredField(*opcode, 0, 0, 7);
342  std::vector<std::string> operations = format->operations();
343  for (const std::string& op : operations) {
345  instrFormat->addOperation(op, riscvJTypeOperations.at(op));
346  } else {
347  assert(false);
348  }
349  }
350  } else {
351  // TODO: Throw some meaniningful exception here
352  assert(false);
353  }
354 }
355 
356 /**
357  * Adds the long immediate destination register fields to the given
358  * binary encoding map.
359  *
360  * @param bem The binary encoding map.
361  */
362 void
364 
365  // check how many fields is needed
368  int fieldCount(0);
369  for (int i = 0; i < itNav.count(); i++) {
370  InstructionTemplate* iTemp = itNav.item(i);
371  int thisRequires = 0;
374  for (int i = 0; i < iuNav.count(); i++) {
375  ImmediateUnit* iu = iuNav.item(i);
376  if (iu->numberOfRegisters() > 1 &&
377  iTemp->isOneOfDestinations(*iu)) {
378  thisRequires++;
379  }
380  }
381 
382  if (thisRequires > fieldCount) {
383  fieldCount = thisRequires;
384  }
385  }
386 
387  // create a vector that contains the required widths of the fields
390  std::vector<int> fieldWidths(fieldCount, 0);
391 
392  for (int i = 0; i < itNav.count(); i++) {
393  InstructionTemplate* iTemp = itNav.item(i);
394 
395  // collect the destinations units to a set
396  std::set<ImmediateUnit*> dstUnits;
397  for (int i = 0; i < iuNav.count(); i++) {
398  ImmediateUnit* iu = iuNav.item(i);
399  if (iTemp->isOneOfDestinations(*iu)) {
400  dstUnits.insert(iu);
401  }
402  }
403 
404  // create a set containing the sizes required by all the destinations
405  // of the instruction template
406  std::multiset<int> requiredSizes;
407  for (set<ImmediateUnit*>::const_iterator iter = dstUnits.begin();
408  iter != dstUnits.end(); iter++) {
409  ImmediateUnit* iu = *iter;
410  if (iu->numberOfRegisters() > 1) {
411  requiredSizes.insert(
413  }
414  }
415 
416  // increase the values in fieldWidhts if required
417  int counter(0);
418  for (multiset<int>::const_reverse_iterator iter =
419  requiredSizes.rbegin();
420  iter != requiredSizes.rend(); iter++) {
421  if (fieldWidths[counter] < *iter) {
422  fieldWidths[counter] = *iter;
423  }
424  counter++;
425  }
426  }
427 
428  // create the fields
429  typedef std::pair<InstructionTemplate*, ImmediateUnit*> ImmDstMapping;
430  std::set<ImmDstMapping> mappedDestinations;
431  for (int i = fieldCount-1; i >= 0; i--) {
432  unsigned int fieldWidth = fieldWidths[i];
434  fieldWidth, bem);
435  for (int i = 0; i < itNav.count(); i++) {
436  InstructionTemplate* iTemp = itNav.item(i);
437  for (int i = 0; i < iuNav.count(); i++) {
438  ImmediateUnit* iu = iuNav.item(i);
439  if (iTemp->isOneOfDestinations(*iu) &&
440  iu->numberOfRegisters() > 1 &&
441  static_cast<unsigned int>(
443  <= fieldWidth &&
445  mappedDestinations,
446  ImmDstMapping(iTemp, iu))) {
447  newField->addDestination(iTemp->name(), iu->name());
448  mappedDestinations.insert(ImmDstMapping(iTemp, iu));
449  }
450  }
451  }
452  }
453 }
454 
455 
456 /**
457  * Adds subfields to the given move slot.
458  *
459  * @param slot The move slot.
460  */
461 void
463 
464  string busName = slot.name();
466  assert(busNav.hasItem(busName));
467  Bus* bus = busNav.item(busName);
468 
469  DestinationField* dField = new DestinationField(
470  BinaryEncoding::LEFT, slot);
471  SourceField* sField = new SourceField(BinaryEncoding::LEFT, slot);
472  GuardField* gField = NULL;
473 
474  addEncodings(*dField); // destination field
475  addEncodings(*sField); // source field
476 
477  // we need guard field only if we have >1 guard.
478  if (bus->guardCount() > 1) {
479  gField = new GuardField(slot);
480  addEncodings(*gField); // guard field
481  }
482 
483  // adds extra bits to guard field (any field is probably ok) if needed.
484  // extra bits added so that long immediate fits to the slot.
485  int longImmWidth = maxLongImmSlotWidth(slot);
486  if (longImmWidth > slot.width()) {
487  // if no guard field, create it so that it can be enlarged.
488  if (gField == NULL) {
489  gField = new GuardField(slot);
490  addEncodings(*gField); // guard field
491  }
492  gField->setExtraBits((longImmWidth - slot.width()) +
493  gField->extraBits());
494  }
495 }
496 
497 
498 /**
499  * Adds the encoding for instruction templates to the given immediate
500  * control field.
501  *
502  * @param field The immediate control field.
503  */
504 void
508  for (int i = 0; i < itNav.count(); i++) {
509  InstructionTemplate* iTemp = itNav.item(i);
510  field.addTemplateEncoding(iTemp->name(), i);
511  }
512 }
513 
514 
515 /**
516  * Adds encodings for the given destination field.
517  *
518  * @param field The destination field.
519  */
520 void
522 
523  string busName = field.parent()->name();
525  assert(busNav.hasItem(busName));
526  Bus* bus = busNav.item(busName);
527  bool createNopField = true;
528  for (int i = 0; i < bus->guardCount(); i++) {
529  Guard* g = bus->guard(i);
530  if (g->isInverted() && dynamic_cast<UnconditionalGuard*>(g) != NULL) {
531  createNopField = false;
532  }
533  }
534 
535  int dstSockets = socketCount(*bus, Socket::INPUT);
536  if (dstSockets == 0) {
537  return;
538  }
539 
540  multiset<int> socketCodeWidths = socketCodeWidthsForBus(
541  *bus, Socket::INPUT);
542  // add socket code width for NOP encoding
543  if (createNopField) {
544  socketCodeWidths.insert(0);
545  }
546  multiset<Encoding> encodings;
547  calculateEncodings(socketCodeWidths, true, encodings);
548 
549  set<Socket*> handledSockets;
550  multiset<int>::reverse_iterator scIter = socketCodeWidths.rbegin();
551  bool nopEncodingSet = false;
552  for (multiset<Encoding>::const_iterator encIter = encodings.begin();
553  encIter != encodings.end(); encIter++) {
554  Encoding enc = *encIter;
555  int scWidth = *scIter;
556  if (scWidth == 0 && !nopEncodingSet && createNopField) {
557  // add NOP encoding
558  new NOPEncoding(enc.first, enc.second, field);
559  nopEncodingSet = true;
560  } else {
561  // find socket that has correct socket code width
562  for (int i = 0; i < dstSockets; i++) {
564  i, *bus, Socket::INPUT);
566  if (scTable == NULL && scWidth == 0 &&
567  !AssocTools::containsKey(handledSockets, &socket)) {
568  new SocketEncoding(
569  socket.name(), enc.first, enc.second, field);
570  handledSockets.insert(&socket);
571  break;
572  } else if (scTable != NULL && scWidth == scTable->width() &&
574  handledSockets, &socket)) {
575  SocketEncoding* socketEnc = new SocketEncoding(
576  socket.name(), enc.first, enc.second, field);
577  socketEnc->setSocketCodes(*scTable);
578  handledSockets.insert(&socket);
579  break;
580  }
581  }
582  }
583  scIter++;
584  }
585 }
586 
587 
588 /**
589  * Adds encodings for the given source field.
590  *
591  * @param field The source field.
592  */
593 void
595 
596  string busName = field.parent()->name();
598  assert(busNav.hasItem(busName));
599  Bus* bus = busNav.item(busName);
600  bool createNopField = true;
601  for (int i = 0; i < bus->guardCount(); i++) {
602  Guard* g = bus->guard(i);
603  if (g->isInverted() && dynamic_cast<UnconditionalGuard*>(g) != NULL) {
604  createNopField = false;
605  }
606  }
607 
608  int srcSockets = socketCount(*bus, Socket::OUTPUT);
609  int srcBridges = sourceBridgeCount(*bus);
610  bool shortImmSupport = (bus->immediateWidth() > 0);
611 
612  multiset<int> socketCodeWidths = socketCodeWidthsForBus(
613  *bus, Socket::OUTPUT);
614  for (int i = 0; i < srcBridges; i++) {
615  socketCodeWidths.insert(0);
616  }
617  if (shortImmSupport) {
618  socketCodeWidths.insert(bus->immediateWidth());
619  }
620  // one encoding for NOP
621  if (createNopField) {
622  socketCodeWidths.insert(0);
623  }
624 
625  multiset<Encoding> encodings;
626  calculateEncodings(socketCodeWidths, true, encodings);
627 
628  // set the encodings
629  set<Socket*> handledSockets;
630  int nextBridge = 0;
631  bool nopEncodingSet = false;
632  bool immEncodingSet = !shortImmSupport;
633  multiset<int>::reverse_iterator scIter = socketCodeWidths.rbegin();
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  new NOPEncoding(enc.first, enc.second, field);
640  nopEncodingSet = true;
641  } else if (!immEncodingSet && scWidth == bus->immediateWidth()) {
642  new ImmediateEncoding(
643  enc.first, enc.second, bus->immediateWidth(), field);
644  immEncodingSet = true;
645  } else {
646  bool socketFound = false;
647  // find the socket that has correct socket code width
648  for (int i = 0; i < srcSockets; i++) {
650  i, *bus, Socket::OUTPUT);
652  if (scTable == NULL && scWidth == 0 &&
653  !AssocTools::containsKey(handledSockets, &socket)) {
654  new SocketEncoding(
655  socket.name(), enc.first, enc.second, field);
656  handledSockets.insert(&socket);
657  socketFound = true;
658  break;
659  } else if (scTable != NULL && scWidth == scTable->width() &&
661  handledSockets, &socket)) {
662  SocketEncoding* socketEnc = new SocketEncoding(
663  socket.name(), enc.first, enc.second, field);
664  socketEnc->setSocketCodes(*scTable);
665  handledSockets.insert(&socket);
666  socketFound = true;
667  break;
668  }
669  }
670  if (!socketFound) {
671  assert(scWidth == 0);
672  assert(nextBridge < srcBridges);
674  nextBridge, *bus);
675  new BridgeEncoding(
676  bridge.name(), enc.first, enc.second, field);
677  nextBridge++;
678  }
679  }
680  scIter++;
681  }
682 }
683 
684 
685 /**
686  * Adds guard encodings to the given guard field.
687  *
688  * @param field The guard field.
689  */
690 void
692 
693  string busName = field.parent()->name();
695  assert(busNav.hasItem(busName));
696  Bus* bus = busNav.item(busName);
697 
698  int guards = bus->guardCount();
699 
700  for (int i = 0; i < guards; i++) {
701  Guard* guard = bus->guard(i);
702  PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
703  RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(guard);
704  UnconditionalGuard* ucGuard =
705  dynamic_cast<UnconditionalGuard*>(guard);
706  if (portGuard != NULL) {
707  FUPort* port = portGuard->port();
708  new FUGuardEncoding(
709  port->parentUnit()->name(), port->name(),
710  portGuard->isInverted(), i, field);
711  } else if (regGuard != NULL) {
712  new GPRGuardEncoding(
713  regGuard->registerFile()->name(), regGuard->registerIndex(),
714  regGuard->isInverted(), i, field);
715  } else if (ucGuard != NULL) {
716  new UnconditionalGuardEncoding(ucGuard->isInverted(), i, field);
717  } else {
718  assert(false);
719  }
720  }
721 }
722 
723 
724 /**
725  * Returns the socket code table that is assigned to the given socket.
726  *
727  * @param socket The socket.
728  * @return The socket code table or NULL if no socket code table is assigned
729  * to the given socket.
730  */
732 BEMGenerator::socketCodeTable(const Socket& socket) const {
734  return MapTools::valueForKey<SocketCodeTable*>(scTableMap_, &socket);
735  } else {
736  return NULL;
737  }
738 }
739 
740 
741 /**
742  * Finds a suitable socket code table from the socket code table map for
743  * the given socket.
744  *
745  * Returns NULL if there is no suitable socket code table.
746  *
747  * @param socket The socket.
748  * @return The socket code table or NULL.
749  */
752  for (SCTableMap::const_iterator iter = scTableMap_.begin();
753  iter != scTableMap_.end(); iter++) {
754  const Socket* toCheck = (*iter).first;
755  if (haveEqualConnections(socket, *toCheck)) {
756  return (*iter).second;
757  }
758  }
759  return NULL;
760 }
761 
762 
763 /**
764  * Assigns the given socket code table for the given socket.
765  *
766  * @param socket The socket.
767  * @param table The socket code table.
768  */
769 void
771  const Socket* socket,
772  SocketCodeTable* table) {
773 
775  scTableMap_.insert(pair<const Socket*, SocketCodeTable*>(socket, table));
776 }
777 
778 
779 /**
780  * Returns the number of sockets of the given direction connected to the
781  * given bus.
782  *
783  * @param bus The bus.
784  * @param direction The direction
785  * @return The number of sockets.
786  */
787 int
789 
790  typedef std::set<Socket*> SocketSet;
791  SocketSet sockets;
792 
793  for (int i = 0; i < bus.segmentCount(); i++) {
794  Segment* segment = bus.segment(i);
795  for (int i = 0; i < segment->connectionCount(); i++) {
796  Socket* socket = segment->connection(i);
797  if (socket->direction() == direction) {
798  sockets.insert(socket);
799  }
800  }
801  }
802 
803  return sockets.size();
804 }
805 
806 
807 /**
808  * By the given index, returns a socket that is attached to the
809  * given bus and has the given direction.
810  *
811  * @param index The index.
812  * @param bus The bus.
813  * @param direction Direction of the sockets being returned.
814  * @return The socket.
815  */
816 Socket&
818  int index,
819  const Bus& bus,
820  Socket::Direction direction) {
821 
822  typedef std::vector<Socket*> SocketTable;
823 
824  assert(index >= 0);
825  SocketTable connectedSockets;
826 
827  for (int i = 0; i < bus.segmentCount(); i++) {
828  Segment* segment = bus.segment(i);
829  for (int i = 0; i < segment->connectionCount(); i++) {
830  Socket* socket = segment->connection(i);
831  if (socket->direction() == direction) {
833  connectedSockets, socket)) {
834  connectedSockets.push_back(socket);
835  }
836  }
837  }
838  }
839 
840  assert(connectedSockets.size() > static_cast<size_t>(index));
841  return *connectedSockets[index];
842 }
843 
844 
845 /**
846  * Tells whether the given socket needs a socket code table.
847  *
848  * @return True if the socket needs a socket code table, otherwise false.
849  */
850 bool
852 
853  if (socket.portCount() > 1) {
854  return true;
855 
856  } else if (socket.portCount() == 1) {
857 
858  // socket code table is needed if the port is opcode setting with
859  // more than one possible opcode or if the port is a data port of
860  // register file with more than one register
861  Port* port = socket.port(0);
862  FUPort* fuPort = dynamic_cast<FUPort*>(port);
863  RFPort* rfPort = dynamic_cast<RFPort*>(port);
864  if (fuPort != NULL && fuPort->isOpcodeSetting() &&
865  fuPort->parentUnit()->operationCount() > 1) {
866  return true;
867  } else if (rfPort != NULL &&
868  rfPort->parentUnit()->numberOfRegisters() > 1) {
869  return true;
870  } else {
871  return false;
872  }
873 
874  } else {
875  return false;
876  }
877 }
878 
879 
880 /**
881  * Adds the port codes to the given socket code table.
882  *
883  * @param table The socket code table.
884  * @param socket The socket that will refer to the table.
885  */
886 void
888  SocketCodeTable& table,
889  const Socket& socket) const {
890 
891  // create a set of register index widths for each port code
892  multiset<int> indexWidths;
893  for (int i = 0; i < socket.portCount(); i++) {
894  Port* port = socket.port(i);
895  Unit* parentUnit = port->parentUnit();
896  BaseRegisterFile* rfParent = dynamic_cast<BaseRegisterFile*>(
897  parentUnit);
898  FunctionUnit* fuParent = dynamic_cast<FunctionUnit*>(parentUnit);
899 
900  if (fuParent != NULL) {
901  int encodingsNeeded(0);
902  if (dynamic_cast<BaseFUPort*>(port)->isOpcodeSetting() &&
903  socket.direction() == Socket::INPUT) {
904  encodingsNeeded = fuParent->operationCount();
905  } else {
906  encodingsNeeded = 1;
907  }
908  for (int i = 0; i < encodingsNeeded; i++) {
909  indexWidths.insert(0);
910  }
911  } else {
912  assert(rfParent != NULL);
913  unsigned int indexWidth = requiredIndexWidth(*rfParent);
914  indexWidths.insert(indexWidth);
915  }
916  }
917 
918  // calculate port IDs
919  multiset<Encoding> encodings;
920  calculateEncodings(indexWidths, true, encodings);
921 
922  // set the encodings
923  if (encodings.size() == 0) {
924  assert(socket.portCount() == 1);
925  Port* port = socket.port(0);
926  ImmediateUnit* iu = dynamic_cast<ImmediateUnit*>(port->parentUnit());
927  RegisterFile* rf = dynamic_cast<RegisterFile*>(port->parentUnit());
928  assert(iu != NULL || rf != NULL);
929  // iu must be first because iu is inherited from rf
930  if (iu != NULL) {
931  new IUPortCode(iu->name(), requiredIndexWidth(*iu), table);
932  } else {
933  new RFPortCode(rf->name(), requiredIndexWidth(*rf), table);
934  }
935  } else {
936  set<Port*> handledPorts;
937  multiset<int>::const_reverse_iterator indexWidthIter =
938  indexWidths.rbegin();
939  for (multiset<Encoding>::const_iterator encIter = encodings.begin();
940  encIter != encodings.end();) {
941  int indexWidth = *indexWidthIter;
942  Encoding enc = *encIter;
943  for (int portIndex = 0; portIndex < socket.portCount();
944  portIndex++) {
945  Port* port = socket.port(portIndex);
946  if (AssocTools::containsKey(handledPorts, port)) {
947  continue;
948  }
949  RegisterFile* rfParent = dynamic_cast<RegisterFile*>(
950  port->parentUnit());
951  ImmediateUnit* iuParent = dynamic_cast<ImmediateUnit*>(
952  port->parentUnit());
953  FunctionUnit* fuParent = dynamic_cast<FunctionUnit*>(
954  port->parentUnit());
955  // iu must be first because iu is inherited from rf
956  if (iuParent != NULL) {
957  int reqIndexWidth = requiredIndexWidth(*iuParent);
958  if (reqIndexWidth == indexWidth) {
959  new IUPortCode(
960  iuParent->name(), enc.first, enc.second,
961  reqIndexWidth, table);
962  indexWidthIter++;
963  encIter++;
964  handledPorts.insert(port);
965  break;
966  }
967  } else if (rfParent != NULL) {
968  int reqIndexWidth = requiredIndexWidth(*rfParent);
969  if (reqIndexWidth == indexWidth) {
970  new RFPortCode(
971  rfParent->name(), enc.first, enc.second,
972  reqIndexWidth, table);
973  indexWidthIter++;
974  encIter++;
975  handledPorts.insert(port);
976  break;
977  }
978  } else {
979  if (indexWidth != 0) {
980  continue;
981  }
982  assert(fuParent != NULL);
983  BaseFUPort* fuPort = dynamic_cast<BaseFUPort*>(port);
984  assert(fuPort != NULL);
985  if (fuPort->isOpcodeSetting()) {
986  // map<operation name, operation index in FU>
987  map<string,int> opcodeSet;
988  assert(*indexWidthIter == 0);
989  // operation indeces are numbered according to the
990  // alphabetical order of opertations
991  for (int opIndex = 0;
992  opIndex < fuParent->operationCount();
993  opIndex++) {
994  opcodeSet.insert(
995  make_pair(
996  fuParent->operation(opIndex)->name(),
997  opIndex));
998  }
999 
1000  for (map<string,int>::iterator
1001  iter = opcodeSet.begin();
1002  iter != opcodeSet.end(); iter++) {
1003  Encoding enc = *encIter;
1004  HWOperation* operation =
1005  fuParent->operation(iter->second);
1006  assert(operation->name() == iter->first);
1007  new FUPortCode(
1008  fuParent->name(), fuPort->name(),
1009  operation->name(), enc.first, enc.second,
1010  table);
1011  indexWidthIter++;
1012  encIter++;
1013  }
1014  } else {
1015  new FUPortCode(
1016  fuParent->name(), fuPort->name(), enc.first,
1017  enc.second, table);
1018  indexWidthIter++;
1019  encIter++;
1020  }
1021  handledPorts.insert(port);
1022  break;
1023  }
1024  }
1025  }
1026  }
1027 }
1028 
1029 
1030 /**
1031  * Returns a multiset containing the socket code widths for sockets of
1032  * the given direction that are connected to the given bus.
1033  *
1034  * @param bus The bus.
1035  * @param socket The direction.
1036  * @return The multiset.
1037  */
1038 std::multiset<int>
1040  const TTAMachine::Bus& bus,
1041  Socket::Direction socketDir) const {
1042 
1043  std::multiset<int> socketCodeWidths;
1044  int socketCount = BEMGenerator::socketCount(bus, socketDir);
1045  for (int i = 0; i < socketCount; i++) {
1046  Socket& socket = BEMGenerator::socket(i, bus, socketDir);
1048  if (scTable == NULL) {
1049  socketCodeWidths.insert(0);
1050  } else {
1051  socketCodeWidths.insert(scTable->width());
1052  }
1053  }
1054 
1055  return socketCodeWidths;
1056 }
1057 
1058 
1059 /**
1060  * Checks whether the given sockets have equal port connections.
1061  *
1062  * @param socket1 The first socket.
1063  * @param socket2 The second socket.
1064  * @return True if the sockets have equal port connections, otherwise false.
1065  */
1066 bool
1068  const Socket& socket1,
1069  const Socket& socket2) {
1070 
1071  std::set<Port*> socket1Ports;
1072  std::set<Port*> socket2Ports;
1073 
1074  for (int i = 0; i < socket1.portCount(); i++) {
1075  socket1Ports.insert(socket1.port(i));
1076  }
1077 
1078  for (int i = 0; i < socket2.portCount(); i++) {
1079  socket2Ports.insert(socket2.port(i));
1080  }
1081 
1082  if (socket1Ports == socket2Ports) {
1083  return true;
1084  } else {
1085  return false;
1086  }
1087 }
1088 
1089 
1090 /**
1091  * Tells how many source bridges the given bus has.
1092  *
1093  * @param bus The bus.
1094  * @return The number of source bridges.
1095  */
1096 int
1098 
1099  Machine* mach = bus.machine();
1100  assert(mach != NULL);
1101  Machine::BridgeNavigator bridgeNav = mach->bridgeNavigator();
1102 
1103  int count(0);
1104 
1105  for (int i = 0; i < bridgeNav.count(); i++) {
1106  Bridge* bridge = bridgeNav.item(i);
1107  if (bridge->destinationBus() == &bus) {
1108  count++;
1109  }
1110  }
1111 
1112  assert(count <= 2);
1113  return count;
1114 }
1115 
1116 
1117 /**
1118  * By the given index returns a source bridge for the given bus.
1119  *
1120  * @param index The index (0 or 1).
1121  * @param bus The bus.
1122  */
1123 Bridge&
1124 BEMGenerator::sourceBridge(int index, const Bus& bus) {
1125 
1126  Machine* mach = bus.machine();
1127  assert(mach != NULL);
1128  Machine::BridgeNavigator bridgeNav = mach->bridgeNavigator();
1129 
1130  int count(0);
1131 
1132  for (int i = 0; i < bridgeNav.count(); i++) {
1133  Bridge* bridge = bridgeNav.item(i);
1134  if (bridge->destinationBus() == &bus) {
1135  if (count == index) {
1136  return *bridge;
1137  } else {
1138  count++;
1139  }
1140  }
1141  }
1142 
1143  assert(false);
1144  // dummy return
1145  return *bridgeNav.item(0);
1146 }
1147 
1148 
1149 /**
1150  * Tells whether the given bus has an unconditional guard.
1151  *
1152  * @param bus The bus.
1153  * @return True if the bus has an unconditional guard, otherwise false.
1154  */
1155 bool
1157  for (int i = 0; i < bus.guardCount(); i++) {
1158  Guard* guard = bus.guard(i);
1159  if (dynamic_cast<UnconditionalGuard*>(guard) != NULL) {
1160  return true;
1161  }
1162  }
1163  return false;
1164 }
1165 
1166 
1167 /**
1168  * Returns the number of bits needed to identify a register in the given
1169  * register file.
1170  *
1171  * @param regFile The register file.
1172  * @return The number of bits needed for register index.
1173  */
1174 int
1176  if (regFile.numberOfRegisters() <= 1) {
1177  return 0;
1178  } else {
1179  return MathTools::bitLength(regFile.numberOfRegisters() - 1);
1180  }
1181 }
1182 
1183 
1184 /**
1185  * Calculates unambiguous encodings when the encodings have opposite
1186  * fields of the given widths.
1187  *
1188  * Minimizes both the total width of the field and the width of the
1189  * encodings. Currently supports only left aligment of encodings.
1190  *
1191  * @param oppositeFieldWidths Widths of the opposite fields.
1192  * @param alignment Tells whether the encodings are aligned to left (true)
1193  * or right (false).
1194  * @param encoding The encodings are added here.
1195  */
1196 void
1198  const std::multiset<int>& oppositeFieldWidths,
1199  bool alignment,
1200  std::multiset<Encoding>& encodings) {
1201 
1202  if (oppositeFieldWidths.size() < 1) {
1203  return;
1204  }
1205 
1206  assert(alignment);
1207 
1208  unsigned int remainder = 0;
1209  unsigned int encodingsLeft = oppositeFieldWidths.size();
1210  unsigned int prevEncoding = 0;
1211  unsigned int nextEncoding = 0;
1212  unsigned int prevOppositeFieldWidth = 0;
1213 
1214  for (multiset<int>::reverse_iterator iter = oppositeFieldWidths.rbegin();
1215  iter != oppositeFieldWidths.rend(); iter++) {
1216  unsigned int oppositeFieldWidth = *iter;
1217  if (iter == oppositeFieldWidths.rbegin()) {
1218  nextEncoding = 0;
1219  encodings.insert(Encoding(nextEncoding, 0));
1220  remainder = 1;
1221  } else {
1222  nextEncoding = prevEncoding + 1;
1223  if (MathTools::bitLength(nextEncoding) >
1224  MathTools::bitLength(prevEncoding)) {
1225  addExtraBits(encodings, 1);
1226  unsigned int setEncodingCount =
1227  oppositeFieldWidths.size() - encodingsLeft;
1228  remainder = (remainder << 1) + setEncodingCount;
1229  }
1230 
1231  if (oppositeFieldWidth == prevOppositeFieldWidth) {
1232  encodings.insert(Encoding(nextEncoding, 0));
1233  } else {
1234  assert(oppositeFieldWidth < prevOppositeFieldWidth);
1235  unsigned int freeBits =
1236  prevOppositeFieldWidth - oppositeFieldWidth;
1237  // calculate the number of bits the encoding has to be
1238  // expanded
1239  unsigned int expansion = 0;
1240  while (remainder << expansion < encodingsLeft) {
1241  if (expansion < freeBits) {
1242  expansion++;
1243  } else {
1244  break;
1245  }
1246  }
1247  nextEncoding = nextEncoding << expansion;
1248  encodings.insert(Encoding(nextEncoding, 0));
1249  remainder = remainder << expansion;
1250  }
1251  }
1252  prevOppositeFieldWidth = oppositeFieldWidth;
1253  encodingsLeft--;
1254  remainder--;
1255  prevEncoding = nextEncoding;
1256  }
1257 
1258  assert(encodings.size() == oppositeFieldWidths.size());
1259 }
1260 
1261 
1262 /**
1263  * Adds the given number of extra bits to the encodings in the given set.
1264  *
1265  * @param encodings The encodings.
1266  * @param bitLength The number of bits.
1267  */
1268 void
1270  std::multiset<Encoding>& encodings,
1271  int bitCount) {
1272 
1273  multiset<Encoding> newSet;
1274  for (multiset<Encoding>::iterator iter = encodings.begin();
1275  iter != encodings.end(); iter++) {
1276  unsigned int encoding = iter->first;
1277  unsigned int extraBits = iter->second;
1278  extraBits += bitCount;
1279  newSet.insert(Encoding(encoding, extraBits));
1280  }
1281 
1282  encodings.clear();
1283  encodings.insert(newSet.begin(), newSet.end());
1284 }
1285 
1286 
1287 /**
1288  * Returns the width of the longest long immediate template being encoded in a
1289  * slot given as parameter.
1290  *
1291  * @param slot Move slot where to check if it's used to store long immediates.
1292  * @return Width of the longest long immediate width stored in a move slot.
1293  */
1294 unsigned int
1298  int maxWidth = 0;
1299 
1300  for (int i = 0; i < itNav.count(); i++) {
1301  InstructionTemplate* iTemp = itNav.item(i);
1302  for (int i = 0; i < iTemp->slotCount(); ++i) {
1303  if (slot.name() == iTemp->slot(i)->slot() &&
1304  maxWidth < iTemp->slot(i)->width()) {
1305 
1306  maxWidth = iTemp->slot(i)->width();
1307  }
1308  }
1309  }
1310 
1311  return maxWidth;
1312 }
1313 
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
OperationTriggeredEncoding.hh
TTAMachine::Guard
Definition: Guard.hh:55
UnconditionalGuardEncoding.hh
riscvRTypeOperations
const std::map< std::string, int > riscvRTypeOperations
Definition: RISCVFields.hh:6
BinaryEncoding
Definition: BinaryEncoding.hh:61
BEMGenerator.hh
TTAMachine::OperationTriggeredFormat::operations
std::vector< std::string > operations() const
Definition: OperationTriggeredFormat.cc:108
MoveSlot::name
std::string name() const
Definition: MoveSlot.cc:136
IUPortCode.hh
BEMGenerator::socket
static TTAMachine::Socket & socket(int index, const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
Definition: BEMGenerator.cc:817
TTAMachine::Socket::port
Port * port(int index) const
Definition: Socket.cc:266
TTAMachine::Socket::portCount
int portCount() const
TTAMachine::Bridge::destinationBus
Bus * destinationBus() const
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
InstructionFormat::addOperation
void addOperation(std::string op, int encoding)
Definition: InstructionFormat.cc:158
riscvSTypeOperations
const std::map< std::string, int > riscvSTypeOperations
Definition: RISCVFields.hh:27
TTAMachine::PortGuard::port
FUPort * port() const
DestinationField
Definition: DestinationField.hh:44
MoveSlot
Definition: MoveSlot.hh:60
OperationTriggeredField.hh
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAMachine::FUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: FUPort.cc:195
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
SocketEncoding::setSocketCodes
void setSocketCodes(SocketCodeTable &codeTable)
Definition: SocketEncoding.cc:156
BEMGenerator::assignSocketCodeTable
void assignSocketCodeTable(const TTAMachine::Socket *socket, SocketCodeTable *table)
Definition: BEMGenerator.cc:770
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
BEMGenerator::socketCount
static int socketCount(const TTAMachine::Bus &bus, TTAMachine::Socket::Direction direction)
Definition: BEMGenerator.cc:788
TTAMachine::Bridge
Definition: Bridge.hh:51
TTAMachine::Segment
Definition: Segment.hh:54
BEMGenerator::socketCodeWidthsForBus
std::multiset< int > socketCodeWidthsForBus(const TTAMachine::Bus &bus, TTAMachine::Socket::Direction socketDir) const
Definition: BEMGenerator.cc:1039
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
GuardField.hh
MapTools.hh
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
IUPortCode
Definition: IUPortCode.hh:41
BridgeEncoding
Definition: BridgeEncoding.hh:47
SocketCodeTable.hh
ImmediateSlotField.hh
RFPortCode.hh
RFPortCode
Definition: RFPortCode.hh:44
FUPortCode
Definition: FUPortCode.hh:47
GuardField
Definition: GuardField.hh:55
ImmediateEncoding.hh
BEMGenerator::maxLongImmSlotWidth
unsigned int maxLongImmSlotWidth(const MoveSlot &slot) const
Definition: BEMGenerator.cc:1295
BEMGenerator::addExtraBits
static void addExtraBits(std::multiset< Encoding > &encodings, int bitCount)
Definition: BEMGenerator.cc:1269
riscvJTypeOperations
const std::map< std::string, int > riscvJTypeOperations
Definition: RISCVFields.hh:37
TTAMachine::Socket::Direction
Direction
Definition: Socket.hh:58
SourceField.hh
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Socket::direction
Direction direction() const
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
FUGuardEncoding
Definition: FUGuardEncoding.hh:47
TTAMachine::InstructionTemplate::slotCount
virtual int slotCount() const
Definition: InstructionTemplate.cc:236
MoveSlot.hh
BridgeEncoding.hh
BEMGenerator::socketCodeTable
SocketCodeTable * socketCodeTable(const TTAMachine::Socket &socket) const
Definition: BEMGenerator.cc:732
ImmediateSlotField
Definition: ImmediateSlotField.hh:44
TTAMachine::RFPort
Definition: RFPort.hh:45
TTAMachine::BaseFUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const =0
SocketCodeTable
Definition: SocketCodeTable.hh:68
TTAMachine::BaseRegisterFile::numberOfRegisters
virtual int numberOfRegisters() const
Encoding
Definition: Encoding.hh:46
BEMGenerator::sourceBridge
static TTAMachine::Bridge & sourceBridge(int index, const TTAMachine::Bus &bus)
Definition: BEMGenerator.cc:1124
TCEString.hh
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
BEMGenerator::needsSocketCodeTable
static bool needsSocketCodeTable(const TTAMachine::Socket &socket)
Definition: BEMGenerator.cc:851
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TemplateSlot.hh
TTAMachine::Segment::connectionCount
int connectionCount() const
TTAMachine::UnconditionalGuard
Definition: Guard.hh:180
riscvUTypeOperations
const std::map< std::string, int > riscvUTypeOperations
Definition: RISCVFields.hh:34
TTAMachine::FUPort
Definition: FUPort.hh:46
BEMGenerator::requiredIndexWidth
static int requiredIndexWidth(const TTAMachine::BaseRegisterFile &regFile)
Definition: BEMGenerator.cc:1175
TTAMachine::Machine::operationTriggeredFormatNavigator
virtual OperationTriggeredFormatNavigator operationTriggeredFormatNavigator() const
Definition: Machine.cc:439
Segment.hh
TTAMachine::BaseRegisterFile
Definition: BaseRegisterFile.hh:48
FUGuardEncoding.hh
BEMGenerator::addEncodings
void addEncodings(ImmediateControlField &field) const
Definition: BEMGenerator.cc:505
HWOperation.hh
ImmediateControlField
Definition: ImmediateControlField.hh:57
TTAMachine::Unit
Definition: Unit.hh:51
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
TTAMachine::Machine::bridgeNavigator
virtual BridgeNavigator bridgeNavigator() const
Definition: Machine.cc:404
BEMGenerator::addLongImmDstRegisterFields
void addLongImmDstRegisterFields(BinaryEncoding &bem) const
Definition: BEMGenerator.cc:363
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::RegisterGuard
Definition: Guard.hh:137
BinaryEncoding.hh
TTAMachine::Port
Definition: Port.hh:54
GuardField::parent
MoveSlot * parent() const
Definition: GuardField.cc:117
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
BinaryEncoding::LEFT
@ LEFT
Definition: BinaryEncoding.hh:64
TTAMachine::TemplateSlot::slot
std::string slot() const
BEMGenerator::suitableSocketCodeTable
SocketCodeTable * suitableSocketCodeTable(const TTAMachine::Socket &socket) const
Definition: BEMGenerator.cc:751
TTAMachine::Socket
Definition: Socket.hh:53
Guard.hh
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
NOPEncoding.hh
OperationTriggeredEncoding
Definition: OperationTriggeredEncoding.hh:44
Machine.hh
BEMGenerator::addSocketCodeTables
void addSocketCodeTables(BinaryEncoding &bem)
Definition: BEMGenerator.cc:125
BEMGenerator::calculateEncodings
static void calculateEncodings(const std::multiset< int > &oppositeFieldWidths, bool leftAlignment, std::multiset< Encoding > &encodings)
Definition: BEMGenerator.cc:1197
BEMGenerator::addPortCodes
void addPortCodes(SocketCodeTable &table, const TTAMachine::Socket &socket) const
Definition: BEMGenerator.cc:887
OperationTriggeredField
Definition: OperationTriggeredField.hh:43
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
MoveSlot::width
virtual int width() const
Definition: MoveSlot.cc:406
BEMGenerator::sourceBridgeCount
static int sourceBridgeCount(const TTAMachine::Bus &bus)
Definition: BEMGenerator.cc:1097
TTAMachine::InstructionTemplate::isOneOfDestinations
virtual bool isOneOfDestinations(const ImmediateUnit &dstUnit) const
Definition: InstructionTemplate.cc:323
NOPEncoding
Definition: NOPEncoding.hh:44
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Segment::connection
const Connection & connection(const Socket &socket) const
Definition: Segment.cc:250
InstructionFormat
Definition: InstructionFormat.hh:46
TTAMachine::ImmediateSlot::width
int width() const
Definition: ImmediateSlot.cc:117
TTAMachine::Machine::immediateSlotNavigator
virtual ImmediateSlotNavigator immediateSlotNavigator() const
Definition: Machine.cc:462
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
InstructionField::setExtraBits
void setExtraBits(int bits)
Definition: InstructionField.cc:214
TTAMachine::OperationTriggeredFormat
Definition: OperationTriggeredFormat.hh:44
SocketEncoding.hh
GPRGuardEncoding.hh
BEMGenerator::Encoding
std::pair< unsigned int, unsigned int > Encoding
Typedef for encoding (first = encoding, second = extra bits).
Definition: BEMGenerator.hh:72
ImmediateControlField.hh
BEMGenerator::BEMGenerator
BEMGenerator(const TTAMachine::Machine &machine)
Definition: BEMGenerator.cc:86
BEMGenerator::addRiscvFormat
void addRiscvFormat(TTAMachine::OperationTriggeredFormat *format, BinaryEncoding &bem) const
Definition: BEMGenerator.cc:198
TTAMachine::RFPort::parentUnit
BaseRegisterFile * parentUnit() const
Definition: RFPort.cc:93
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
BEMGenerator::addSubfields
void addSubfields(MoveSlot &slot) const
Definition: BEMGenerator.cc:462
InstructionField::extraBits
int extraBits() const
Definition: InstructionField.cc:229
BEMGenerator::scTableMap_
SCTableMap scTableMap_
A map which tells which socket code table belongs to a socket.
Definition: BEMGenerator.hh:130
TTAMachine::Guard::isInverted
virtual bool isInverted() const
LImmDstRegisterField::addDestination
void addDestination(const std::string &instructionTemplate, const std::string &immediateUnit)
Definition: LImmDstRegisterField.cc:129
TTAMachine::Component::machine
virtual Machine * machine() const
AssocTools.hh
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
riscvBTypeOperations
const std::map< std::string, int > riscvBTypeOperations
Definition: RISCVFields.hh:30
TCEString
Definition: TCEString.hh:53
FUPort.hh
MathTools::bitLength
static unsigned int bitLength(long unsigned int number)
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
LImmDstRegisterField
Definition: LImmDstRegisterField.hh:47
riscvITypeOperations
const std::map< std::string, int > riscvITypeOperations
Definition: RISCVFields.hh:17
InstructionFormat.hh
BinaryEncoding::moveSlot
MoveSlot & moveSlot(int index) const
Definition: BinaryEncoding.cc:121
BEMGenerator::~BEMGenerator
virtual ~BEMGenerator()
Definition: BEMGenerator.cc:94
ContainerTools::containsValue
static bool containsValue(const ContainerType &aContainer, const ElementType &aKey)
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
OperationTriggeredFormat.hh
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
DestinationField.hh
MathTools.hh
ImmediateEncoding
Definition: ImmediateEncoding.hh:44
BEMGenerator::hasUnconditionalGuard
static bool hasUnconditionalGuard(const TTAMachine::Bus &bus)
Definition: BEMGenerator.cc:1156
TTAMachine
Definition: Assembler.hh:48
BinaryEncoding::moveSlotCount
int moveSlotCount() const
Definition: BinaryEncoding.cc:104
TTAMachine::TemplateSlot::width
int width() const
SocketEncoding
Definition: SocketEncoding.hh:51
GPRGuardEncoding
Definition: GPRGuardEncoding.hh:47
FUPortCode.hh
BEMGenerator::addTopLevelFields
void addTopLevelFields(BinaryEncoding &bem) const
Definition: BEMGenerator.cc:150
SlotField::parent
MoveSlot * parent() const
Definition: SlotField.cc:98
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
UnconditionalGuardEncoding
Definition: UnconditionalGuardEncoding.hh:47
RISCVFields.hh
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
SocketCodeTable::width
int width() const
Definition: SocketCodeTable.cc:200
TTAMachine::Bus::segmentCount
virtual int segmentCount() const
Definition: Bus.cc:385
ImmediateControlField::addTemplateEncoding
void addTemplateEncoding(const std::string &name, unsigned int encoding)
Definition: ImmediateControlField.cc:206
BEMGenerator::generate
BinaryEncoding * generate()
Definition: BEMGenerator.cc:104
LImmDstRegisterField.hh
TTAMachine::ImmediateSlot
Definition: ImmediateSlot.hh:44
TTAMachine::InstructionTemplate::slot
virtual TemplateSlot * slot(int index) const
Definition: InstructionTemplate.cc:249
BEMGenerator::haveEqualConnections
static bool haveEqualConnections(const TTAMachine::Socket &socket1, const TTAMachine::Socket &socket2)
Definition: BEMGenerator.cc:1067
BEMGenerator::machine_
const TTAMachine::Machine * machine_
The machine for which the BEM is generated.
Definition: BEMGenerator.hh:128
TTAMachine::Machine
Definition: Machine.hh:73
TTAMachine::Port::parentUnit
Unit * parentUnit() const
SourceField
Definition: SourceField.hh:48
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50