OpenASIP  2.0
MachineInfo.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 MachineInfo.cc
26  *
27  * Implementation of MachineInfo class.
28  *
29  * @author Mikael Lepistö 2008 (mikael.lepisto-no.spam-tut.fi)
30  * @note rating: red
31  */
32 
33 #include "MachineInfo.hh"
34 
35 #include "StringTools.hh"
36 #include "Machine.hh"
37 #include "HWOperation.hh"
38 #include "OperationPool.hh"
39 #include "ControlUnit.hh"
40 #include "RegisterFile.hh"
41 #include "Guard.hh"
42 #include "Operation.hh"
43 #include "Operand.hh"
44 #include "FUPort.hh"
45 #include "InstructionTemplate.hh"
46 #include "OperationDAGSelector.hh"
47 #include "MathTools.hh"
49 #include "UniversalMachine.hh"
50 
51 using namespace TTAMachine;
52 
53 const TCEString MachineInfo::LOCK_READ_ = "lock_read";
54 const TCEString MachineInfo::TRY_LOCK_ADDR_ = "try_lock_addr";
55 const TCEString MachineInfo::UNLOCK_ADDR_ = "unlock_addr";
56 
57 /**
58  * Checks that the operands used in the operations of the given FU are
59  * bound to some port.
60  *
61  * @param mach The machine whose opset is requested.
62  * @return Opset supported by machine hardware.
63  */
66 
68 
70  mach.functionUnitNavigator();
71 
72  OperationPool opPool;
73 
74  for (int i = 0; i < fuNav.count(); i++) {
75  const TTAMachine::FunctionUnit* fu = fuNav.item(i);
76  for (int o = 0; o < fu->operationCount(); o++) {
77  const std::string opName = fu->operation(o)->name();
78  opNames.insert(StringTools::stringToLower(opName));
79  }
80  }
81 
82  return opNames;
83 }
84 
85 
86 /**
87  * Returns opset used by Global Control Unit.
88  *
89  * @param gcu The Global Control Unit whose opset is requested.
90  * @return Opset used by the Global Control Unit.
91  */
95  for (int i = 0; i < gcu.operationCount(); i++) {
96  const std::string opName = gcu.operation(i)->name();
97  opNames.insert(StringTools::stringToLower(opName));
98  }
99  return opNames;
100 }
101 
102 
103 /**
104  * Return first occurrence of FUPorts that are bound to operation given by
105  * name.
106  *
107  * Returned list has FUPorts ordered in the order of operands. At index 1 is
108  * port bounded to operand 1, at index 2 port bounded to operand 2 and so on.
109  * List is empty if operation was not found from machine. Unbounded operands
110  * have NULL at the index of operand (0 is always NULL).
111  *
112  * @param mach The machine.
113  * @param operationStr The operation.
114  * @return The list of ordered bound ports.
115  */
118  const TTAMachine::Machine& mach,
119  const std::string& operationStr) {
120 
121  ConstPortList bindedPorts;
122 
123  const TTAMachine::FunctionUnit* found = NULL;
125  mach.functionUnitNavigator();
126  for (int i = 0; i < fuNav.count(); i++) {
127  const TTAMachine::FunctionUnit* fu = fuNav.item(i);
128  if (fu->hasOperation(operationStr)) {
129  found = fu;
130  break;
131  }
132  }
133 
134  if (found == NULL) {
135  if (mach.controlUnit()->hasOperation(operationStr)) {
136  found = mach.controlUnit();
137  }
138  }
139  if (found != NULL) {
140  bindedPorts.push_back(NULL); // Shift indexing.
141  HWOperation* operation = found->operation(operationStr);
142  for (int i = 1; i <= operation->operandCount(); i++) {
143  bindedPorts.push_back(operation->port(i));
144  }
145  }
146  return bindedPorts;
147 }
148 
149 /**
150  * Returns port that is bound to operand index of the operation in the FU.
151  *
152  * Returns the port, if the FU has the operation and operation has the operand
153  * bound to some port. Otherwise, returns nullptr.
154  */
155 const TTAMachine::FUPort*
157  const TTAMachine::FunctionUnit& fu,
158  const std::string& opName, int operandIndex) {
159 
160  if (fu.hasOperation(opName)) {
161  const HWOperation* hwOp = fu.operation(opName);
162  if (hwOp->isBound(operandIndex)) {
163  return hwOp->port(operandIndex);
164  }
165  }
166  return nullptr;
167 }
168 
169 /**
170  * Finds the default data address space for given machine.
171  *
172  * @param mach The machine whose default data address space is requested.
173  * @return Default data address space for given machine
174  */
177 
178  const AddressSpace& instrAS = *mach.controlUnit()->addressSpace();
179 
181  mach.addressSpaceNavigator();
182  int asCount = asNav.count();
183  for (int i = 0; i < asCount; i++) {
184  // if there are more than two address spaces, choose one which
185  // contains numerical id 0
186  // otherwise choose the one which is not the instruction address space
187  if (asCount > 2) {
188  if (asNav.item(i)->hasNumericalId(0)) return asNav.item(i);
189  } else {
190  if (asNav.item(i) != &instrAS) return asNav.item(i);
191  }
192  }
193 
194  // no data address space found
195  throw IllegalMachine(
196  __FILE__, __LINE__, __func__,
197  "Target machine has no data address space");
198  return NULL;
199 }
200 
201 int
203  const TTAMachine::Machine& mach) {
204  int ggLatency = mach.controlUnit()->globalGuardLatency();
205 
206  const TTAMachine::Machine::BusNavigator busNav =
207  mach.busNavigator();
208 
209  for (int i = 0; i < busNav.count(); i++) {
210  const TTAMachine::Bus* bus = busNav.item(i);
211  for (int j = 0; j < bus->guardCount(); j++) {
212  Guard* guard = bus->guard(j);
213  RegisterGuard* rg = dynamic_cast<RegisterGuard*>(guard);
214  if (rg != NULL) {
215  int rgLat = rg->registerFile()->guardLatency();
216  if (rgLat != 0) {
217  assert(rgLat == 1);
218  return ggLatency + 1;
219  }
220  } else {
221  if (dynamic_cast<PortGuard*>(guard) != NULL) {
222  return ggLatency + 1;
223  }
224  }
225  }
226  }
227  return ggLatency;
228 }
229 
230 /**
231  * Returns Operand object for the given hardware operation attached to the port.
232  *
233  * InstanceNotFound exception is thrown, if the hardware operation doesn't have
234  * an operand in the given port.
235  *
236  * @param hwOp Hardware operation.
237  * @param port The port containing the desired Operand.
238  * @return Reference to the Operand object.
239  */
240 Operand&
242  const TTAMachine::HWOperation& hwOp,
243  const TTAMachine::FUPort& port) {
244 
245  const TCEString& opName = hwOp.name();
246  OperationPool opPool;
247  const Operation& op = opPool.operation(opName.c_str());
248 
249  assert(&op != &NullOperation::instance() && "Invalid operation name.");
250 
251  int opndIndex = hwOp.io(port);
252  return op.operand(opndIndex);
253 }
254 
255 /**
256  * Returns byte width of the widest load/store operation.
257  *
258  * @return Maximum memory alignment according to the widest memory operation.
259  */
260 int
262  int byteAlignment = 4; // Stack alignment is four bytes at minimum.
263 
264  TTAMachine::FunctionUnit* fu = nullptr;
266  mach.functionUnitNavigator();
267  for (int i = 0; i < fuNav.count(); i++) {
268  fu = fuNav.item(i);
269  if (fu->hasAddressSpace()) {
270  if (fu->addressSpace()->hasNumericalId(0)) {
271  break;
272  }
273  }
274  }
275  assert(fu && "Didn't find the LSU with local AS");
276  for (int k = 0; k < fu->operationCount(); k++) {
277  TCEString operation = fu->operation(k)->name();
278 
279  const TCEString opName = StringTools::stringToLower(operation);
280  if (opName.length() > 2 && isdigit(opName[2])) {
281  // Assume operations named ldNNxMM and stNNxMM are operations
282  // with alignment of NN (or ldNN / stNN).
283  // @todo fix this horrible hack by adding the alignment info explicitly
284  // to OSAL.
285 
286  // At least check for the name string format to match the above
287  // before parsing the number.
288  size_t xpos = opName.find("x", 3);
289  if (xpos == std::string::npos) {
290  for (size_t pos = 2; pos < opName.size(); ++pos)
291  if (!isdigit(opName[pos])) continue;
292 
293  if (opName.startsWith("ld")) {
294  int loadByteWidth = Conversion::toInt(opName.substr(2)) / 8;
295  if (loadByteWidth > byteAlignment) {
296  byteAlignment = loadByteWidth;
297  }
298  } else if (opName.startsWith("st")) {
299  int storeByteWidth = Conversion::toInt(opName.substr(2)) / 8;
300  if (storeByteWidth > byteAlignment) {
301  byteAlignment = storeByteWidth;
302  }
303  }
304  } else {
305  for (size_t pos = xpos + 1; pos < opName.size(); ++pos)
306  if (!isdigit(opName[pos])) continue;
307 
308  if (opName.startsWith("ld")) {
309  int loadByteWidth = Conversion::toInt(opName.substr(2, xpos - 2)) / 8;
310  if (loadByteWidth > byteAlignment) {
311  byteAlignment = loadByteWidth;
312  }
313  } else if (opName.startsWith("st")) {
314  int storeByteWidth = Conversion::toInt(opName.substr(2, xpos - 2)) / 8;
315  if (storeByteWidth > byteAlignment) {
316  byteAlignment = storeByteWidth;
317  }
318  }
319  }
320  }
321  }
322 
323  if (!(byteAlignment > 1 && !(byteAlignment & (byteAlignment - 1)))) {
324  std::cerr << "Stack alignment: " << byteAlignment << std::endl;
325  assert(false && "Error: stack alignment must be a power of 2.");
326  }
327 
328  return byteAlignment;
329 }
330 
331 /**
332  * Checks if slot is used in any of the instruction templates defined in ADF.
333  *
334  * @param mach The Machine.
335  * @param slotName The name of the slot.
336  * @return True if any template includes given slot. False otherwise.
337  */
338 bool
340  const TTAMachine::Machine& mach,
341  const std::string& slotName) {
342 
343  std::set<InstructionTemplate*> affectingInstTemplates;
346  for (int i = 0; i < itNav.count(); i++) {
347  InstructionTemplate* iTemp = itNav.item(i);
348  if (iTemp->usesSlot(slotName)) {
349  return true;
350  }
351  }
352 
353  return false;
354 }
355 
356 
357 /**
358  * Returns set of pointers to instruction templates that uses the given slot.
359  *
360  * @param mach The Machine.
361  * @param slotName The name of the slot.
362  * @return List of found templates or empty none was found.
363  */
364 std::set<TTAMachine::InstructionTemplate*>
366  const TTAMachine::Machine& mach,
367  const std::string& slotName) {
368  std::set<InstructionTemplate*> affectingInstTemplates;
371  for (int i = 0; i < itNav.count(); i++) {
372  InstructionTemplate* iTemp = itNav.item(i);
373  if (iTemp->usesSlot(slotName)) {
374  affectingInstTemplates.insert(iTemp);
375  }
376  }
377  return affectingInstTemplates;
378 }
379 
380 
381 bool
383  const TTAMachine::Machine& mach, TCEString operation) {
385  MachineInfo::getOpset(mach);
386  return opNames.find(operation.upper()) != opNames.end();
387 }
388 
389 bool
391  const TTAMachine::Bus& bus, int64_t imm, unsigned destWidth) {
392 
393  size_t requiredBitsSigned =
394  std::min((unsigned)MathTools::requiredBitsSigned((long int)imm), destWidth);
395  size_t requiredBitsUnsigned =
396  std::min((unsigned)MathTools::requiredBits(imm), destWidth);
397 
398  size_t requiredBits = bus.signExtends() ?
399  requiredBitsSigned : requiredBitsUnsigned;
400  // In case the short immediate can write all bits in
401  // the bus, let's assume this is the word width to the
402  // target operation and the extension mode can be
403  // assumed to be 'signed' (the targeted operation can
404  // interpret the value in the bus either way), we
405  // just have to be sure there is no information loss
406  // in the upper bits. This breaks with
407  // multibitwidth scalar machines, e.g., ones with
408  // INT32 datapath combined with FLOAT64 because now
409  // it assumes the constant can be written in case
410  // there's a 32b immediate slot for the INT32 bus. (*)
411  if (bus.width() == bus.immediateWidth() &&
412  requiredBitsSigned < requiredBits)
413  requiredBits = requiredBitsSigned;
414  if (static_cast<size_t>(bus.immediateWidth()) >= requiredBits)
415  return true;
416  return false;
417 }
418 
419 /**
420  * Checks if the given immediate can be transferred at all
421  * in the given machine.
422  *
423  * Takes in account the move slots' or the immediate unit's
424  * extension mode when considering the encoding of the given
425  * constant's bits. In case this function returns true,
426  * the register copy adder or similar pass should be able to
427  * route the constant to the wanted destination(s), in case
428  * no direct bus with the immediate support is found. In
429  * case the destination (port) is known, its width should
430  * be set to destWidth to constraint the required immediate
431  * extension width (in case the move tries to write to a port narrower
432  * than the immediate actually requires bits, the bug is earlier
433  * in the compilation).
434  *
435  * A complex example: a move where a negative constant with minimal
436  * encoding of 7b is transported through a 32b bus to a 8b destination
437  * with a 8b move slot that uses zero extension mode. The zero extension
438  * mode does not fill up the upper bits with 1, but it does not
439  * lead to information loss as the destination uses only the lower
440  * 8 bits which can be encoded directly to the immediate field,
441  * thus the extension is not needed.
442  */
443 bool
445  const TTAMachine::Machine& mach, int64_t imm, unsigned destWidth) {
446 
447  const Machine::BusNavigator& busNav = mach.busNavigator();
448 
449  // first check the short immediate slots
450  for (int bi = 0; bi < busNav.count(); ++bi) {
451  const Bus& bus = *busNav.item(bi);
452  if (canEncodeImmediateInteger(bus, imm, destWidth))
453  return true;
454  }
455 
456  // then the long immediate templates
458  if (canEncodeImmediateInteger(*temp, imm, destWidth))
459  return true;
460 
461  return false;
462 }
463 
464 bool
466  const TTAMachine::InstructionTemplate& temp, int64_t imm,
467  unsigned destWidth) {
468  size_t requiredBitsSigned =
469  std::min((unsigned)MathTools::requiredBitsSigned(
470  static_cast<SLongWord>(imm)), destWidth);
471  size_t requiredBitsUnsigned =
472  std::min((unsigned)MathTools::requiredBits(
473  static_cast<ULongWord>(imm)), destWidth);
474 
475  const TTAMachine::Machine& mach = *temp.machine();
477  mach.immediateUnitNavigator();
478  for (const TTAMachine::ImmediateUnit* iu: mach.immediateUnitNavigator()) {
479  size_t requiredBits = iu->signExtends() ?
480  requiredBitsSigned : requiredBitsUnsigned;
481  size_t supportedW = temp.supportedWidth(*iu);
482  // see above (*). Same applies here: if the template encodes
483  // as many bits as the buses that the IU can write to are wide,
484  // the extension mode is meaningless -> can interpret it as one wishes
485  // here.
486  size_t maxBusW = 0;
487  std::set<const TTAMachine::Bus*> buses;
489  *iu, buses);
490  for (auto bus: buses) {
491  if (static_cast<size_t>(bus->width()) > maxBusW)
492  maxBusW = bus->width();
493  }
494 
495  if (supportedW == maxBusW &&
496  requiredBitsSigned < requiredBits)
497  requiredBits = requiredBitsSigned;
498  if (supportedW >= requiredBits)
499  return true;
500 
501  }
502 
503  return false;
504 }
505 
506 int
508  const TTAMachine::FunctionUnit& fu, const Operation& op) {
509  if (fu.hasOperation(op.name())) {
510  TTAMachine::HWOperation* hwop =
511  fu.operation(op.name());
512  for (int j = 0; j < fu.operationPortCount(); j++) {
513  TTAMachine::FUPort* port = fu.operationPort(j);
514  if (port->isTriggering()) {
515  return hwop->io(*port);
516  }
517  }
518  }
519  // operation not found in this FU
520  return 0;
521 }
522 
523 /**
524  * Finds the operand index of trigger of given operation in the machine.
525  *
526  * If the operation is not found from the machine, return 0.
527  * If the index is ambiguos return -1.
528  */
529 int
531  const TTAMachine::Machine& machine, const Operation& op) {
534  if (&machine == &UniversalMachine::instance()) {
535  return op.numberOfInputs(); // last input
536  }
537  int index = 0;
538  for (int i = 0; i < nav.count(); i++) {
539  TTAMachine::FunctionUnit* fu = nav.item(i);
540  int curIndex = triggerIndex(*fu, op);
541  if (curIndex > 0) {
542  if (index > 0 && curIndex != index) {
543  return -1;
544  } else {
545  index = curIndex;
546  }
547  }
548  }
549  int curIndex = triggerIndex(*machine.controlUnit(), op);
550  if (curIndex > 0) {
551  if (index > 0 && curIndex != index) {
552  return -1;
553  } else {
554  index = curIndex;
555  }
556  }
557  return index;
558 }
559 
560 /**
561  * Finds the widest operand available in the machine.
562  *
563  * Helps finding the widest usable register in the machine.
564  */
565 unsigned
568  bool) {
569  OperationPool pool;
570  unsigned widestOperand = 0;
571 
574 
577  for (TCETools::CIStringSet::iterator it = opNames.begin();
578  it != opNames.end(); ++it) {
579 
580  const Operation& op = pool.operation(it->c_str());
581 
582  for (int j = 1; j < op.operandCount() + 1; ++j) {
583  if ((unsigned)(op.operand(j).width()) > widestOperand)
584  widestOperand = (unsigned)(op.operand(j).width());
585  }
586  }
587  return widestOperand;
588 }
589 
590 /**
591  * Counts registers of given width.
592  */
593 unsigned
595  const TTAMachine::Machine& machine, unsigned width) {
596 
597  unsigned numRegisters = 0;
600 
601  // Search register files of desired width and count registers
602  for (int i = 0; i < RFNavigator.count(); i++) {
603  TTAMachine::RegisterFile *rf = RFNavigator.item(i);
604  if ((unsigned)(rf->width()) == width) {
605  numRegisters += rf->size();
606  }
607  }
608  return numRegisters;
609 }
610 
611 /**
612  * Returns true if the machine has predicatable jump.
613  *
614  */
615 bool
617  const TTAMachine::Machine& machine) {
618  const ControlUnit* cu = machine.controlUnit();
619  if (cu == nullptr) {
620  return false;
621  }
622 
623  if (!cu->hasOperation("jump")) {
624  return false;
625  }
626 
627  const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
628  if (jumpPort == nullptr) {
629  return false;
630  }
631 
632  std::vector<const Bus*> guardedBuses;
633  for (const Bus* bus : machine.busNavigator()) {
634  for (int i = 0; i < bus->guardCount(); i++) {
635 
636  const TTAMachine::RegisterGuard *regGuard =
637  dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
638  if (regGuard && regGuard->registerFile()->width() == 1) {
639  guardedBuses.push_back(bus);
640  break;
641  }
642  }
643  }
644 
645  for (const Bus* bus : guardedBuses) {
646  if (MachineConnectivityCheck::busConnectedToPort(*bus, *jumpPort)) {
647  return true;
648  }
649  // Todo: Check if bus has sufficient transport capability for jumping?
650  // That is, it is at least connected to a RF, IU or can transport
651  // short immediates.
652  }
653 
654  return false;
655 }
656 
657 
658 /**
659  * Returns true if the machine has predicatable jump.
660  *
661  */
662 bool
664  const ControlUnit* cu = machine.controlUnit();
665  if (cu == nullptr) {
666  return false;
667  }
668 
669  if (!cu->hasOperation("jump")) {
670  return false;
671  }
672 
673  const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
674  if (jumpPort == nullptr) {
675  return false;
676  }
677 
678  std::vector<const Bus*> guardedBuses;
679  for (const Bus* bus : machine.busNavigator()) {
680  for (int i = 0; i < bus->guardCount(); i++) {
681  const TTAMachine::PortGuard *portGuard =
682  dynamic_cast<TTAMachine::PortGuard*>(bus->guard(i));
683  if (portGuard) {
684  // TODO: should check what ops found from the source FU
685  guardedBuses.push_back(bus);
686  }
687  }
688  }
689 
690  for (const Bus* bus : guardedBuses) {
691  if (MachineConnectivityCheck::busConnectedToPort(*bus, *jumpPort)) {
692  return true;
693  }
694  // Todo: Check if bus has sufficient transport capability for jumping?
695  // That is, it is at least connected to a RF, IU or can transport
696  // short immediates.
697  }
698 
699  return false;
700 }
701 
702 
704  const TTAMachine::Machine& machine, bool inverted, const TCEString& opName) {
705 
706  const ControlUnit* cu = machine.controlUnit();
707  if (cu == nullptr) {
708  return false;
709  }
710 
711  if (!cu->hasOperation("jump")) {
712  return false;
713  }
714 
715  const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
716  if (jumpPort == nullptr) {
717  return false;
718  }
719 
720  std::vector<const Bus*> guardedBuses;
721  for (const Bus* bus : machine.busNavigator()) {
722  for (int i = 0; i < bus->guardCount(); i++) {
723  TTAMachine::Guard* guard = bus->guard(i);
724  if (guard->isInverted() != inverted) continue;
725  const TTAMachine::PortGuard *portGuard =
726  dynamic_cast<TTAMachine::PortGuard*>(guard);
727  if (portGuard) {
728  TTAMachine::FUPort* fup = portGuard->port();
729  auto fu = fup->parentUnit();
730  if (fu->hasOperation(opName)) {
731  // TODO: should check what ops found from the source FU
732  guardedBuses.push_back(bus);
733  }
734  }
735  }
736  }
737 
738  for (const Bus* bus : guardedBuses) {
739  if (MachineConnectivityCheck::busConnectedToPort(*bus, *jumpPort)) {
740  return true;
741  }
742  // Todo: Check if bus has sufficient transport capability for jumping?
743  // That is, it is at least connected to a RF, IU or can transport
744  // short immediates.
745  }
746 
747  return false;
748 }
749 
750 /**
751  * Searches for lock unit FUs and returns them.
752  *
753  * Lock unit FU must have the correct operations and an address space
754  *
755  * @param machine Architecture to be searched
756  * @return Vector of found lock unit FUs
757  */
758 std::vector<const TTAMachine::FunctionUnit*>
760  std::vector<TCEString> requiredOperations;
761  requiredOperations.push_back(LOCK_READ_);
762  requiredOperations.push_back(TRY_LOCK_ADDR_);
763  requiredOperations.push_back(UNLOCK_ADDR_);
764 
765  std::vector<const FunctionUnit*> lockUnits;
767  for (int i = 0; i < fuNav.count(); i++) {
768  const FunctionUnit* fu = fuNav.item(i);
769  bool hasCorrectOperations = true;
770  for (unsigned int i = 0; i < requiredOperations.size(); i++) {
771  if (!fu->hasOperation(requiredOperations.at(i))) {
772  hasCorrectOperations = false;
773  break;
774  }
775  }
776  if (hasCorrectOperations) {
777  if (!fu->hasAddressSpace()) {
778  TCEString msg;
779  msg << "Lock Unit " << fu->name() << " has no address space";
780  throw InvalidData(__FILE__, __LINE__, __func__, msg);
781  }
782  lockUnits.push_back(fu);
783  }
784  }
785  return lockUnits;
786 }
787 
788 /**
789  * Convenience function for getting OSAL operation from HWOperation description.
790  *
791  * Throws InstanceNotFound if OSAL operation is not found.
792  */
793 Operation&
795  OperationPool opPool;
796 
797  Operation& op = opPool.operation(hwOp.name().c_str());
798  if (op.isNull()) {
800  "Operation '" + hwOp.name() + "' was not found in OSAL.");
801  }
802  return op;
803 }
804 
805 
807  int maxl = -1;
808  for (auto fu: mach.functionUnitNavigator()) {
809  if (fu->hasOperation(opName)) {
810  const auto op = fu->operation(opName);
811  maxl = std::max(maxl, op->latency());
812  }
813  }
814  if (mach.controlUnit()->hasOperation(opName)) {
815  const auto op = mach.controlUnit()->operation(opName);
816  maxl = std::max(maxl, op->latency());
817  }
818  return maxl;
819 }
Operand
Definition: Operand.hh:52
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
TTAMachine::Guard
Definition: Guard.hh:55
MachineInfo::templatesUsingSlot
static std::set< TTAMachine::InstructionTemplate * > templatesUsingSlot(const TTAMachine::Machine &mach, const std::string &slotName)
Definition: MachineInfo.cc:365
MachineConnectivityCheck::busConnectedToPort
static bool busConnectedToPort(const TTAMachine::Bus &bus, const TTAMachine::Port &port)
Definition: MachineConnectivityCheck.cc:1290
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
MachineInfo::maxMemoryAlignment
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:261
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MachineConnectivityCheck.hh
TTAMachine::PortGuard::port
FUPort * port() const
TTAMachine::FunctionUnit::hasAddressSpace
virtual bool hasAddressSpace() const
Definition: FunctionUnit.cc:608
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TCEString::startsWith
bool startsWith(const std::string &str) const
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
MachineInfo::supportsOperation
static bool supportsOperation(const TTAMachine::Machine &mach, TCEString operation)
Definition: MachineInfo.cc:382
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
TTAMachine::Bus::width
int width() const
Definition: Bus.cc:149
TTAMachine::AddressSpace::hasNumericalId
virtual bool hasNumericalId(unsigned id) const
Definition: AddressSpace.cc:383
MachineInfo::TRY_LOCK_ADDR_
static const TCEString TRY_LOCK_ADDR_
Definition: MachineInfo.hh:124
TTAMachine::Bus
Definition: Bus.hh:53
Operand::width
virtual int width() const
Definition: Operand.cc:318
MachineInfo.hh
MachineInfo::osalOperation
static Operation & osalOperation(const TTAMachine::HWOperation &hwOp)
Definition: MachineInfo.cc:794
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
MachineInfo::findLockUnits
static std::vector< const TTAMachine::FunctionUnit * > findLockUnits(const TTAMachine::Machine &machine)
Definition: MachineInfo.cc:759
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
TTAMachine::Machine::Navigator::count
int count() const
MachineInfo::maxLatency
static int maxLatency(const TTAMachine::Machine &mach, TCEString &opName)
Definition: MachineInfo.cc:806
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
TCEString::upper
TCEString upper() const
Definition: TCEString.cc:86
NullOperation::instance
static NullOperation & instance()
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
MachineInfo::defaultDataAddressSpace
static TTAMachine::AddressSpace * defaultDataAddressSpace(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:176
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
StringTools.hh
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
UniversalMachine.hh
TTAMachine::FUPort
Definition: FUPort.hh:46
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAMachine::HWOperation::io
int io(const FUPort &port) const
Definition: HWOperation.cc:364
HWOperation.hh
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
InvalidData
Definition: Exception.hh:149
MachineInfo::supportsPortGuardedJump
static bool supportsPortGuardedJump(const TTAMachine::Machine &machine, bool inverted, const TCEString &opName)
Definition: MachineInfo.cc:703
MachineInfo::LOCK_READ_
static const TCEString LOCK_READ_
Definition: MachineInfo.hh:123
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
InstructionTemplate.hh
TTAMachine::RegisterGuard
Definition: Guard.hh:137
MachineInfo::getBoundPort
static const TTAMachine::FUPort * getBoundPort(const TTAMachine::FunctionUnit &fu, const std::string &opName, int operandIndex)
Definition: MachineInfo.cc:156
TTAMachine::HWOperation::isBound
bool isBound(const FUPort &port) const
Definition: HWOperation.cc:338
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
MachineInfo::getOpset
static OperationSet getOpset(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:65
Guard.hh
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
Operation.hh
MathTools::requiredBits
static int requiredBits(unsigned long int number)
OperationDAGSelector.hh
TTAMachine::InstructionTemplate::supportedWidth
virtual int supportedWidth() const
Definition: InstructionTemplate.cc:427
MachineInfo::findWidestOperand
static unsigned findWidestOperand(const TTAMachine::Machine &machine, bool vector)
Definition: MachineInfo.cc:566
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
OperationDAGSelector::OperationSet
TCETools::CIStringSet OperationSet
Definition: OperationDAGSelector.hh:88
MachineInfo::longestGuardLatency
static int longestGuardLatency(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:202
TTAMachine::Machine::addressSpaceNavigator
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition: Machine.cc:392
MachineConnectivityCheck::appendConnectedDestinationBuses
static void appendConnectedDestinationBuses(const TTAMachine::Port &port, std::set< const TTAMachine::Bus * > &buses)
Definition: MachineConnectivityCheck.cc:818
TTAMachine::FunctionUnit::operationPortCount
virtual int operationPortCount() const
Definition: FunctionUnit.cc:182
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
MachineInfo::numberOfRegisters
static unsigned numberOfRegisters(const TTAMachine::Machine &machine, unsigned width)
Definition: MachineInfo.cc:594
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
Operation
Definition: Operation.hh:59
MachineInfo::UNLOCK_ADDR_
static const TCEString UNLOCK_ADDR_
Definition: MachineInfo.hh:125
Operation::operandCount
virtual int operandCount() const
Definition: Operation.cc:212
Operand.hh
TTAMachine::HWOperation::operandCount
int operandCount() const
Definition: HWOperation.cc:306
MachineInfo::operandFromPort
static Operand & operandFromPort(const TTAMachine::HWOperation &hwOp, const TTAMachine::FUPort &port)
Definition: MachineInfo.cc:241
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
IllegalMachine
Definition: Exception.hh:878
TTAMachine::Guard::isInverted
virtual bool isInverted() const
Operation::isNull
bool isNull() const
TTAMachine::Component::machine
virtual Machine * machine() const
RegisterFile.hh
TCEString
Definition: TCEString.hh:53
FUPort.hh
ControlUnit.hh
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
MachineInfo::supportsPortGuardedJumps
static bool supportsPortGuardedJumps(const TTAMachine::Machine &machine)
Definition: MachineInfo.cc:663
ULongWord
unsigned long ULongWord
Definition: BaseType.hh:51
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
TTAMachine::RegisterFile::guardLatency
virtual int guardLatency() const
Definition: RegisterFile.cc:333
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
Conversion::toInt
static int toInt(const T &source)
MathTools.hh
MachineInfo::getPortBindingsOfOperation
static ConstPortList getPortBindingsOfOperation(const TTAMachine::Machine &mach, const std::string &operation)
Definition: MachineInfo.cc:117
TTAMachine::FunctionUnit::operationPort
virtual FUPort * operationPort(const std::string &name) const
Definition: FunctionUnit.cc:224
OperationPool
Definition: OperationPool.hh:52
TTAMachine
Definition: Assembler.hh:48
TTAMachine::ControlUnit::globalGuardLatency
int globalGuardLatency() const
TTAMachine::BaseRegisterFile::size
virtual int size() const
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
TTAMachine::BaseRegisterFile::width
virtual int width() const
MachineInfo::ConstPortList
std::vector< const TTAMachine::FUPort * > ConstPortList
Definition: MachineInfo.hh:61
MachineInfo::triggerIndex
static int triggerIndex(const TTAMachine::Machine &machine, const Operation &op)
Definition: MachineInfo.cc:530
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
OperationPool.hh
MachineInfo::supportsBoolRegisterGuardedJumps
static bool supportsBoolRegisterGuardedJumps(const TTAMachine::Machine &machine)
Definition: MachineInfo.cc:616
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
SLongWord
long SLongWord
Definition: BaseType.hh:52
MathTools::requiredBitsSigned
static int requiredBitsSigned(SLongWord number)
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
TTAMachine::InstructionTemplate::usesSlot
virtual bool usesSlot(const std::string &slotName) const
Definition: InstructionTemplate.cc:265
MachineInfo::canEncodeImmediateInteger
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
Definition: MachineInfo.cc:444
InstanceNotFound
Definition: Exception.hh:304
TTAMachine::Machine
Definition: Machine.hh:73
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50
MachineInfo::templatesUsesSlot
static bool templatesUsesSlot(const TTAMachine::Machine &mach, const std::string &slotName)
Definition: MachineInfo.cc:339