OpenASIP  2.0
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
CodeSectionCreator Class Reference

#include <CodeSectionCreator.hh>

Collaboration diagram for CodeSectionCreator:
Collaboration graph

Classes

struct  InternalElement
 
struct  InternalSection
 

Public Member Functions

 CodeSectionCreator (MachineResourceManager &resourceManager, const TTAMachine::Machine &targetMachine, AssemblyParserDiagnostic *parent)
 
void newSection (UValue startAddress)
 
void addMove (const ParserMove &move)
 
void finalize (TPEF::Binary &tpef, LabelManager &labels)
 
void cleanup ()
 

Private Types

enum  ElementType { EMPTY, MOVE, IMMEDIATE }
 

Private Member Functions

void startNewInstruction ()
 
UValue slotNumber ()
 
UValue immediateIndex ()
 
bool isDestinationAlreadyWritten (const InternalElement &elem) const
 
void addAnnotationes (TPEF::InstructionElement &instrElem, InternalElement &elem, LabelManager &lables) const
 

Private Attributes

const TTAMachine::Machinemach_
 
InternalSection internalSection_
 Internal representation of code section. More...
 
MachineResourceManagerresources_
 TPEF Resources and strings. More...
 
AssemblyParserDiagnosticparent_
 Place to add warnings during compilation. More...
 
bool isNextBegin_
 Next element is starting element of instruction. More...
 
UValue slotNumber_
 Slot number of current move. More...
 
UValue immediateIndex_
 Immediate index. More...
 

Static Private Attributes

static const UValue CODE_RELOC_SIZE = 32
 Bitwidth of immediate value containing address to relocate. More...
 

Detailed Description

Read moves and creates TPEF code section out of them.

Definition at line 58 of file CodeSectionCreator.hh.

Member Enumeration Documentation

◆ ElementType

Type of move element.

Enumerator
EMPTY 

Empty move.

MOVE 

Data transport.

IMMEDIATE 

Long immediate assignment.

Definition at line 80 of file CodeSectionCreator.hh.

80  {
81  EMPTY, ///< Empty move.
82  MOVE, ///< Data transport.
83  IMMEDIATE ///< Long immediate assignment.
84  };

Constructor & Destructor Documentation

◆ CodeSectionCreator()

CodeSectionCreator::CodeSectionCreator ( MachineResourceManager resourceManager,
const TTAMachine::Machine targetMachine,
AssemblyParserDiagnostic parent 
)

Constructor.

Parameters
resourceManagerTPEF resources and strings.
parentAssembler root class.

Definition at line 65 of file CodeSectionCreator.cc.

68  :
69  mach_(targetMachine),
70  resources_(resourceManager), parent_(parent),
72 }

Member Function Documentation

◆ addAnnotationes()

void CodeSectionCreator::addAnnotationes ( TPEF::InstructionElement instrElem,
InternalElement elem,
LabelManager labels 
) const
private

Adds annotations of element of internal presentation to TPEF element.

Parameters
instrElemTPEF InstructionElement where to add annotation data.
elemElement of internal presentation that caontains annotationes from assembly code.
Exceptions
CompileErrorIf defined value needs more room that is defined in init data.

Definition at line 636 of file CodeSectionCreator.cc.

637  {
638 
639  for (unsigned int i = 0; i < elem.annotationes.size();i++) {
640  Word id = elem.annotationes[i].id;
641  std::vector<Byte> payload;
642 
643  for (unsigned int j = 0; j < elem.annotationes[i].payload.size(); j++) {
644  InitDataField& initData = elem.annotationes[i].payload[j];
645  std::deque<Byte> temp;
646 
647  UValue value = 0;
648  if (initData.litOrExpr.isExpression) {
649  value = labels.resolveExpressionValue(elem.asmLineNumber,
650  initData.litOrExpr);
651  } else {
652  value = initData.litOrExpr.value;
653  }
654 
655  // write value to field
656  for (int k = sizeof(value) - 1; k >= 0; k--) {
657  Byte nextVal = (value >> (k*BYTE_BITWIDTH));
658  temp.push_back(nextVal);
659  }
660 
661  // remove extra leading ones if signed
662  if (initData.litOrExpr.isSigned) {
663  while (temp.size() > 1 && temp[0] == 0xff &&
664  temp.size() > initData.width &&
665  (temp[1] & 0x80) != 0) {
666 
667  temp.pop_front();
668  }
669  }
670 
671  // remove extra leading zeroes
672  while (temp[0] == 0 && temp.size() > initData.width) {
673  temp.pop_front();
674  }
675 
676  // add needed leading zeroes or ones if signed
677  while (temp.size() < initData.width) {
678 
679  if (initData.litOrExpr.isSigned && (temp[0] & 0x80) != 0) {
680  temp.push_front(0xff);
681  } else {
682  temp.push_front(0);
683  }
684 
685  }
686 
687  if (initData.width != 0 && temp.size() > initData.width) {
688  std::string errorMessage =
689  "Annotation payload " + initData.toString() +
690  " is too big for defined field size.";
691 
692  throw CompileError(
693  __FILE__, __LINE__, __func__,
694  errorMessage);
695  }
696 
697  // add to payload
698  for (unsigned int j = 0; j < temp.size(); j++) {
699  payload.push_back(temp[j]);
700  }
701  }
702 
703  instrElem.addAnnotation(new InstructionAnnotation(id, payload));
704  }
705 }

References __func__, TPEF::InstructionElement::addAnnotation(), CodeSectionCreator::InternalElement::annotationes, CodeSectionCreator::InternalElement::asmLineNumber, BYTE_BITWIDTH, LiteralOrExpression::isExpression, LiteralOrExpression::isSigned, InitDataField::litOrExpr, LabelManager::resolveExpressionValue(), InitDataField::toString(), LiteralOrExpression::value, and InitDataField::width.

Referenced by finalize().

Here is the call graph for this function:

◆ addMove()

void CodeSectionCreator::addMove ( const ParserMove move)

Adds new move to section.

If exception is thrown, creator will remain as it was before function call.

Parameters
moveParsed move.
Exceptions
CompileErrorIf referenced resource is not found from machine.

Definition at line 102 of file CodeSectionCreator.cc.

102  {
103  try {
104  if (move.isBegin) {
106  }
107 
108  InternalElement* newMove = NULL;
109  InternalElement* newImmediate = NULL;
110 
111  UValue srcWidth = 0, dstWidth = 0;
112 
113  switch (move.type) {
114 
116 
117  // check that source is valid
118  if (move.source.isRegister) {
119  CompileError error(
120  __FILE__, __LINE__, __func__,
121  "Internal error: Immediate source must be literal or "
122  "expression.");
123 
124  error.setCodeFileLineNumber(move.asmLineNumber);
125  throw error;
126  }
127 
128  static InternalElement newElement;
129  newImmediate = &newElement;
130 
131  newElement.type = IMMEDIATE;
132  newElement.asmLineNumber = move.asmLineNumber;
133  newElement.isBegin = false;
134 
135  newElement.annotationes = move.annotationes;
136 
137  // check value bitwidth
138  newElement.immValue = move.source.immTerm;
139 
140  UValue tempValue = newElement.immValue.value;
141  while(tempValue > 0) {
142  tempValue = tempValue >> 1;
143  srcWidth++;
144  }
145 
146  // destination of the immediate
149  move.asmLineNumber, move.destination, newElement.slot,
151 
152  newElement.dstType = resID.type;
153 
154  if (newElement.dstType != MoveElement::MF_IMM) {
155  CompileError error(
156  __FILE__, __LINE__, __func__,
157  "Long immediate destination must be immediate unit.");
158 
159  error.setCodeFileLineNumber(move.asmLineNumber);
160  throw error;
161  }
162 
163  newElement.dstUnit = resID.unit;
164  newElement.dstIndex = resID.index;
165  dstWidth = resID.width;
166 
167  } break;
168 
169  case ParserMove::EMPTY: {
170  static InternalElement newElement;
171  newMove = &newElement;
172 
173  newElement.asmLineNumber = move.asmLineNumber;
174  newElement.type = EMPTY;
175  newElement.isBegin = move.isBegin;
176  newElement.slot = slotNumber();
177  } break;
178 
179  case ParserMove::TRANSPORT: {
180  static InternalElement newElement;
181  newElement.asmLineNumber = move.asmLineNumber;
182  newMove = &newElement;
183 
184  newElement.slot = slotNumber();
185  newElement.type = MOVE;
186 
187  newElement.annotationes = move.annotationes;
188 
189  // source
190  if (move.source.isRegister) {
191 
194  move.asmLineNumber,
195  move.source.regTerm, newElement.slot,
197 
198  newElement.srcType = resID.type;
199  newElement.srcUnit = resID.unit;
200  newElement.srcIndex = resID.index;
201 
202  srcWidth = resID.width;
203 
204  } else {
205  // inline immediate
206  static InternalElement immediate;
207  immediate.asmLineNumber = move.asmLineNumber;
208  newImmediate = &immediate;
209 
210  immediate.slot = newElement.slot;
211  immediate.type = IMMEDIATE;
212  immediate.dstUnit = ResourceElement::INLINE_IMM;
213  immediate.dstIndex = immediateIndex();
214  immediate.isBegin = false;
215  immediate.immValue = move.source.immTerm;
216 
217  newElement.srcType = MoveElement::MF_IMM;
218  newElement.srcUnit = immediate.dstUnit;
219  newElement.srcIndex = immediate.dstIndex;
220 
221  // check value bitwidth
222  UValue tempValue = immediate.immValue.value;
223  while(tempValue > 0) {
224  tempValue = tempValue >> 1;
225  srcWidth++;
226  }
227  }
228 
229  // destination
232  move.destination, newElement.slot,
234 
235  newElement.dstType = resID.type;
236  newElement.dstUnit = resID.unit;
237  newElement.dstIndex = resID.index;
238  newElement.isBegin = move.isBegin;
239  dstWidth = resID.width;
240 
241  // guard
242  newElement.isGuarded = move.guard.isGuarded;
243 
244  if (newElement.isGuarded) {
245  newElement.isInverted = move.guard.isInverted;
246 
248 
249  if (newElement.isInverted) {
250  resID = &resources_.resourceID(
251  move.asmLineNumber,
252  move.guard.regTerm, newElement.slot,
254 
255  } else {
256  resID = &resources_.resourceID(
257  move.asmLineNumber,
258  move.guard.regTerm, newElement.slot,
260  }
261 
262  newElement.guardType = resID->type;
263  newElement.guardUnit = resID->unit;
264  newElement.guardIndex = resID->index;
265  }
266 
267  if (isDestinationAlreadyWritten(newElement)) {
269  move.asmLineNumber,
270  "Move destination: " +
271  move.destination.toString() +
272  " is already written "
273  "in current instruction.");
274  }
275 
276  } break;
277 
278  default:
279  assert(false);
280  }
281 
282  if (newMove != NULL) {
283  // check that there are enough busses with sufficient width for
284  // all parsed moves
285  try {
286  // if source is wider than bus
287  UValue busWidth = resources_.findBusWidth(newMove->slot);
288  if ( busWidth < srcWidth) {
289 
291  move.asmLineNumber,
292  "Bus width: " +
293  Conversion::toString(busWidth) +
294  " is smaller than source: " +
295  Conversion::toString(srcWidth));
296  }
297 
298  // if source or destination is wider than bus
299  if (dstWidth < srcWidth) {
301  move.asmLineNumber,
302  "Source is wider than destination.");
303  }
304 
305  } catch (OutOfRange& e) {
306  CompileError error(
307  __FILE__, __LINE__, __func__,
308  "Too many bus slots used.");
309  error.setCodeFileLineNumber(move.asmLineNumber);
310  error.setCause(e);
311 
312  throw error;
313  }
314 
315  internalSection_.elements.push_back(*newMove);
316  }
317 
318  if (newImmediate != NULL) {
319  internalSection_.elements.push_back(*newImmediate);
320  }
321 
322  } catch (IllegalMachine& e) {
323  CompileError error(
324  __FILE__, __LINE__, __func__, e.errorMessage());
325 
326  error.setCodeFileLineNumber(move.asmLineNumber);
327  error.setCause(e);
328 
329  throw error;
330  }
331 }

References __func__, AssemblyParserDiagnostic::addWarning(), CodeSectionCreator::InternalElement::annotationes, ParserMove::annotationes, CodeSectionCreator::InternalElement::asmLineNumber, ParserMove::asmLineNumber, assert, ParserMove::destination, CodeSectionCreator::InternalElement::dstIndex, CodeSectionCreator::InternalElement::dstType, CodeSectionCreator::InternalElement::dstUnit, CodeSectionCreator::InternalSection::elements, EMPTY, ParserMove::EMPTY, Exception::errorMessage(), MachineResourceManager::findBusWidth(), ParserMove::guard, CodeSectionCreator::InternalElement::guardIndex, CodeSectionCreator::InternalElement::guardType, CodeSectionCreator::InternalElement::guardUnit, IMMEDIATE, immediateIndex(), ParserSource::immTerm, CodeSectionCreator::InternalElement::immValue, MachineResourceManager::ResourceID::index, internalSection_, CodeSectionCreator::InternalElement::isBegin, ParserMove::isBegin, isDestinationAlreadyWritten(), CodeSectionCreator::InternalElement::isGuarded, ParserGuard::isGuarded, CodeSectionCreator::InternalElement::isInverted, ParserGuard::isInverted, ParserSource::isRegister, ParserMove::LONG_IMMEDIATE, MOVE, parent_, ParserSource::regTerm, ParserGuard::regTerm, MachineResourceManager::resourceID(), resources_, MachineResourceManager::RQST_GUARD, MachineResourceManager::RQST_INVGUARD, MachineResourceManager::RQST_READ, MachineResourceManager::RQST_WRITE, Exception::setCause(), CompileError::setCodeFileLineNumber(), CodeSectionCreator::InternalElement::slot, slotNumber(), ParserMove::source, CodeSectionCreator::InternalElement::srcIndex, CodeSectionCreator::InternalElement::srcType, CodeSectionCreator::InternalElement::srcUnit, startNewInstruction(), Conversion::toString(), RegisterTerm::toString(), ParserMove::TRANSPORT, CodeSectionCreator::InternalElement::type, MachineResourceManager::ResourceID::type, ParserMove::type, MachineResourceManager::ResourceID::unit, LiteralOrExpression::value, and MachineResourceManager::ResourceID::width.

Referenced by AddMoveActor::operator()().

Here is the call graph for this function:

◆ cleanup()

void CodeSectionCreator::cleanup ( )

Frees all internally allocated data.

Definition at line 518 of file CodeSectionCreator.cc.

518  {
519  immediateIndex_ = 0;
520  isNextBegin_ = true;
521  slotNumber_ = 0;
522 }

References immediateIndex_, isNextBegin_, and slotNumber_.

Referenced by AssemblerParser::cleanup(), and finalize().

◆ finalize()

void CodeSectionCreator::finalize ( TPEF::Binary tpef,
LabelManager labels 
)

Writes created sections to given binary.

All data stored inside creator is freed after this call, unless exception is thrown.

In case of exception creator restores its state to be same that state was before running finalize() (finalize() can be runned again).

Parameters
tpefBinary where to created sections should be added.
labelsLabelManager where to add data labels and relocations.
Exceptions
CompileErrorIf there is any errors during compiling.

Definition at line 347 of file CodeSectionCreator.cc.

347  {
348  // we don't have to have emty CodeSection
349  if (internalSection_.elements.size() > 0) {
350 
351  CodeSection* codeSection = dynamic_cast<CodeSection*>(
352  Section::createSection(Section::ST_CODE));
353 
354  assert(codeSection != NULL);
355 
356  try {
357  codeSection->setLink(resources_.resourceSection());
358  codeSection->setName(resources_.stringToChunk(""));
359 
360  try {
361  codeSection->setASpace(resources_.codeAddressSpace());
362 
363  } catch (IllegalMachine& e) {
364  CompileError error(
365  __FILE__, __LINE__, __func__,
366  "Can't find code address space.");
367 
368  error.setCause(e);
369 
370  throw error;
371  }
372 
373  std::vector<ImmediateElement*> recentImmediates;
374 
375  // create the moves
376  for (unsigned int i = 0;
377  i < internalSection_.elements.size(); i++) {
378 
379  InternalElement &elem = internalSection_.elements[i];
380 
381  assert(elem.slot <= 0xff);
382 
383  if (elem.isBegin) {
384  // TODO: Check that the recent long immediates are well
385  // formed, as per following conditions.
386 
387  // A valid instruction template exists that encodes
388  // them.
389 
390  // The same unit is never written twice.
391 
392  // There exists a combination of all destination units
393  // needed.
394 
395  // The fields that encode each immediate are wide enough
396  // to encode the given constant.
397 
398  recentImmediates.clear();
399  }
400 
401  switch(elem.type) {
402  case EMPTY: {
403  MoveElement *emptyMove = new MoveElement();
404  emptyMove->setBegin(elem.isBegin);
405  emptyMove->setEmpty(true);
406  emptyMove->setBus(elem.slot + 1);
407  addAnnotationes(*emptyMove, elem, labels);
408  codeSection->addElement(emptyMove);
409  } break;
410 
411  case IMMEDIATE: {
412  ImmediateElement *immElem = new ImmediateElement();
413  immElem->setBegin(elem.isBegin);
414 
415  UValue immValue = 0;
416  if (elem.immValue.isExpression) {
417 
418  immValue = labels.resolveExpressionValue(
419  elem.asmLineNumber, elem.immValue);
420 
421  // MARK
422  ASpaceElement& aSpaceElement =
423  labels.aSpaceElement(
424  elem.immValue.expression.label);
425 
426  const std::string aSpaceName =
427  labels.aSpaceName(elem.immValue.expression.label);
428 
429  std::size_t relocSize = CODE_RELOC_SIZE;
430 
431  try {
432  // figure out what is the maximum address of
433  // the referred address space and set it as
434  // the relocation width for the immediate
435  const TTAMachine::AddressSpace* addressSpace =
436  mach_.addressSpaceNavigator().item(aSpaceName);
437  assert(addressSpace != NULL);
438  relocSize = MathTools::requiredBits(
439  static_cast<unsigned int>(
440  addressSpace->end()));
441  } catch (const Exception& e) {
443  << "Could not get access to MOM address space."
444  << std::endl;
445  }
446 
447 
448  labels.addRelocation(
449  *codeSection, *immElem, aSpaceElement, immValue,
450  relocSize);
451 
452  } else {
453  immValue = elem.immValue.value;
454  }
455 
456  immElem->setDestinationUnit(elem.dstUnit);
457  immElem->setDestinationIndex(elem.dstIndex);
458  immElem->setWord(immValue);
459 
460  if (immElem->destinationUnit() !=
461  ResourceElement::INLINE_IMM) {
462 
463  recentImmediates.push_back(immElem);
464  }
465 
466  addAnnotationes(*immElem, elem, labels);
467  codeSection->addElement(immElem);
468  } break;
469 
470  case MOVE: {
471  MoveElement *newMove = new MoveElement();
472  newMove->setEmpty(false);
473  newMove->setBegin(elem.isBegin);
474 
475  newMove->setBus(elem.slot + 1);
476 
477  newMove->setSourceType(elem.srcType);
478  newMove->setSourceUnit(elem.srcUnit);
479  newMove->setSourceIndex(elem.srcIndex);
480 
481  newMove->setDestinationType(elem.dstType);
482  newMove->setDestinationUnit(elem.dstUnit);
483  newMove->setDestinationIndex(elem.dstIndex);
484 
485  newMove->setGuardType(elem.guardType);
486  newMove->setGuardUnit(elem.guardUnit);
487  newMove->setGuardIndex(elem.guardIndex);
488 
489  newMove->setGuarded(elem.isGuarded);
490  newMove->setGuardInverted(elem.isInverted);
491 
492  addAnnotationes(*newMove, elem, labels);
493  codeSection->addElement(newMove);
494  } break;
495 
496  default:
497  assert(false);
498  }
499  }
500 
501  } catch (CompileError& e) {
502  labels.clearLastRelocations();
503  delete codeSection;
504  throw e;
505  }
506 
507  labels.commitLastRelocations();
508  tpef.addSection(codeSection);
509  }
510 
511  cleanup();
512 }

References __func__, addAnnotationes(), TPEF::CodeSection::addElement(), LabelManager::addRelocation(), TTAMachine::Machine::addressSpaceNavigator(), TPEF::Binary::addSection(), CodeSectionCreator::InternalElement::asmLineNumber, LabelManager::aSpaceElement(), LabelManager::aSpaceName(), assert, cleanup(), LabelManager::clearLastRelocations(), CODE_RELOC_SIZE, MachineResourceManager::codeAddressSpace(), LabelManager::commitLastRelocations(), TPEF::ImmediateElement::destinationUnit(), CodeSectionCreator::InternalElement::dstIndex, CodeSectionCreator::InternalElement::dstType, CodeSectionCreator::InternalElement::dstUnit, CodeSectionCreator::InternalSection::elements, EMPTY, TTAMachine::AddressSpace::end(), LiteralOrExpression::expression, CodeSectionCreator::InternalElement::guardIndex, CodeSectionCreator::InternalElement::guardType, CodeSectionCreator::InternalElement::guardUnit, IMMEDIATE, CodeSectionCreator::InternalElement::immValue, internalSection_, CodeSectionCreator::InternalElement::isBegin, LiteralOrExpression::isExpression, CodeSectionCreator::InternalElement::isGuarded, CodeSectionCreator::InternalElement::isInverted, TTAMachine::Machine::Navigator< ComponentType >::item(), Expression::label, Application::logStream(), mach_, MOVE, MathTools::requiredBits(), LabelManager::resolveExpressionValue(), resources_, MachineResourceManager::resourceSection(), TPEF::Section::setASpace(), TPEF::InstructionElement::setBegin(), TPEF::MoveElement::setBus(), Exception::setCause(), TPEF::ImmediateElement::setDestinationIndex(), TPEF::MoveElement::setDestinationIndex(), TPEF::MoveElement::setDestinationType(), TPEF::ImmediateElement::setDestinationUnit(), TPEF::MoveElement::setDestinationUnit(), TPEF::MoveElement::setEmpty(), TPEF::MoveElement::setGuarded(), TPEF::MoveElement::setGuardIndex(), TPEF::MoveElement::setGuardInverted(), TPEF::MoveElement::setGuardType(), TPEF::MoveElement::setGuardUnit(), TPEF::Section::setLink(), TPEF::Section::setName(), TPEF::MoveElement::setSourceIndex(), TPEF::MoveElement::setSourceType(), TPEF::MoveElement::setSourceUnit(), TPEF::ImmediateElement::setWord(), CodeSectionCreator::InternalElement::slot, CodeSectionCreator::InternalElement::srcIndex, CodeSectionCreator::InternalElement::srcType, CodeSectionCreator::InternalElement::srcUnit, MachineResourceManager::stringToChunk(), CodeSectionCreator::InternalElement::type, and LiteralOrExpression::value.

Referenced by AssemblerParser::finalize().

Here is the call graph for this function:

◆ immediateIndex()

UValue CodeSectionCreator::immediateIndex ( )
private

Returns next possible index for inline immediate.

Returns
Next possible index for inline immediate.

Definition at line 550 of file CodeSectionCreator.cc.

550  {
551  immediateIndex_++;
552  return immediateIndex_;
553 }

References immediateIndex_.

Referenced by addMove().

◆ isDestinationAlreadyWritten()

bool CodeSectionCreator::isDestinationAlreadyWritten ( const InternalElement elem) const
private

Returns true if RF index or FU port is written twice in a same instruction.

Parameters
elemMove to check.
Returns
True if RF index or FU port is written twice in a same instruction.

Definition at line 562 of file CodeSectionCreator.cc.

563  {
564 
565  if (elem.type == MOVE && !elem.isBegin) {
566 
567  std::vector<const InternalElement*> guardedMoves;
568 
569  for (int i = internalSection_.elements.size() - 1;
570  i >= 0 && !internalSection_.elements[i].isBegin; i--) {
571 
572  const InternalElement &compare = internalSection_.elements[i];
573 
574  if (compare.type == elem.type &&
575  compare.dstType == elem.dstType &&
576  compare.dstUnit == elem.dstUnit &&
577  compare.dstIndex == elem.dstIndex) {
578 
579  if (!compare.isGuarded || !elem.isGuarded) {
580  // destination is same and only one of the moves
581  // is guarded
582  return true;
583 
584  } else {
585 
586  if (compare.guardType == elem.guardType &&
587  compare.guardUnit == elem.guardUnit &&
588  compare.guardIndex == elem.guardIndex &&
589  compare.isInverted == elem.isInverted) {
590 
591  // same destination and same guards
592  return true;
593  }
594 
595  // gather possibly colliding moves
596  guardedMoves.push_back(&compare);
597  }
598  }
599 
600  }
601 
602  // check if possibly colliding moves has two opposites of same guard
603  for (unsigned int i = 0; i < guardedMoves.size(); i++) {
604  for (unsigned int j = i + 1; j < guardedMoves.size(); j++) {
605 
606  const InternalElement* iMove = guardedMoves[i];
607  const InternalElement* jMove = guardedMoves[j];
608 
609  if (iMove->guardType == jMove->guardType &&
610  iMove->guardUnit == jMove->guardUnit &&
611  iMove->guardIndex == jMove->guardIndex &&
612  iMove->isInverted != jMove->isInverted) {
613 
614  // destination that is currently written is
615  // definately already written in this instruction
616  return true;
617  }
618  }
619  }
620  }
621 
622  return false;
623 }

References CodeSectionCreator::InternalElement::dstIndex, CodeSectionCreator::InternalElement::dstType, CodeSectionCreator::InternalElement::dstUnit, CodeSectionCreator::InternalSection::elements, CodeSectionCreator::InternalElement::guardIndex, CodeSectionCreator::InternalElement::guardType, CodeSectionCreator::InternalElement::guardUnit, internalSection_, CodeSectionCreator::InternalElement::isBegin, CodeSectionCreator::InternalElement::isGuarded, CodeSectionCreator::InternalElement::isInverted, MOVE, and CodeSectionCreator::InternalElement::type.

Referenced by addMove().

◆ newSection()

void CodeSectionCreator::newSection ( UValue  startAddress)

Creator to start new section from given start address.

Parameters
startAddressStart address of next section.
Exceptions
OutOfRangeStart address is not in code address space.

Definition at line 81 of file CodeSectionCreator.cc.

81  {
82  // Checks are not needed yet, since we support currently only
83  // one code section.
84 
85  // @todo if multiple times then create new section each time..
86  // for now only one code section is supported
87 
88  // @todo sanity checks for addresses and moves (next is begin...)
89 
90  internalSection_.startAddress = startAddress;
91 }

References internalSection_, and CodeSectionCreator::InternalSection::startAddress.

Referenced by NewCodeSectionActor::operator()().

◆ slotNumber()

UValue CodeSectionCreator::slotNumber ( )
private

Returns slot number for currently added move.

Returns
Slot number for currently added move.

Definition at line 539 of file CodeSectionCreator.cc.

539  {
540  slotNumber_++;
541  return slotNumber_ - 1;
542 }

References slotNumber_.

Referenced by addMove().

◆ startNewInstruction()

void CodeSectionCreator::startNewInstruction ( )
private

Inits privat attributes for start of new instruction.

Definition at line 528 of file CodeSectionCreator.cc.

528  {
529  slotNumber_ = 0;
530  immediateIndex_ = 0;
531 }

References immediateIndex_, and slotNumber_.

Referenced by addMove().

Member Data Documentation

◆ CODE_RELOC_SIZE

const UValue CodeSectionCreator::CODE_RELOC_SIZE = 32
staticprivate

Bitwidth of immediate value containing address to relocate.

Definition at line 178 of file CodeSectionCreator.hh.

Referenced by finalize().

◆ immediateIndex_

UValue CodeSectionCreator::immediateIndex_
private

Immediate index.

Definition at line 175 of file CodeSectionCreator.hh.

Referenced by cleanup(), immediateIndex(), and startNewInstruction().

◆ internalSection_

InternalSection CodeSectionCreator::internalSection_
private

Internal representation of code section.

Definition at line 160 of file CodeSectionCreator.hh.

Referenced by addMove(), finalize(), isDestinationAlreadyWritten(), and newSection().

◆ isNextBegin_

bool CodeSectionCreator::isNextBegin_
private

Next element is starting element of instruction.

Definition at line 169 of file CodeSectionCreator.hh.

Referenced by cleanup().

◆ mach_

const TTAMachine::Machine& CodeSectionCreator::mach_
private

Definition at line 157 of file CodeSectionCreator.hh.

Referenced by finalize().

◆ parent_

AssemblyParserDiagnostic* CodeSectionCreator::parent_
private

Place to add warnings during compilation.

Definition at line 166 of file CodeSectionCreator.hh.

Referenced by addMove().

◆ resources_

MachineResourceManager& CodeSectionCreator::resources_
private

TPEF Resources and strings.

Definition at line 163 of file CodeSectionCreator.hh.

Referenced by addMove(), and finalize().

◆ slotNumber_

UValue CodeSectionCreator::slotNumber_
private

Slot number of current move.

Definition at line 172 of file CodeSectionCreator.hh.

Referenced by cleanup(), slotNumber(), and startNewInstruction().


The documentation for this class was generated from the following files:
CodeSectionCreator::slotNumber
UValue slotNumber()
Definition: CodeSectionCreator.cc:539
CodeSectionCreator::internalSection_
InternalSection internalSection_
Internal representation of code section.
Definition: CodeSectionCreator.hh:160
TPEF::MoveElement::setGuardInverted
void setGuardInverted(bool flag)
TPEF::CodeSection::addElement
virtual void addElement(SectionElement *element)
Definition: CodeSection.cc:267
CodeSectionCreator::CODE_RELOC_SIZE
static const UValue CODE_RELOC_SIZE
Bitwidth of immediate value containing address to relocate.
Definition: CodeSectionCreator.hh:178
MachineResourceManager::stringToChunk
TPEF::Chunk * stringToChunk(const std::string aStr)
Definition: MachineResourceManager.cc:249
TPEF::InstructionElement::addAnnotation
void addAnnotation(InstructionAnnotation *anAnnotation)
ParserMove::isBegin
bool isBegin
Tells whether the slot is the first of the instruction.
Definition: ParserStructs.hh:404
MachineResourceManager::ResourceID
Definition: MachineResourceManager.hh:91
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
MachineResourceManager::resourceSection
TPEF::ResourceSection * resourceSection()
Definition: MachineResourceManager.cc:373
TPEF::MoveElement::setDestinationUnit
void setDestinationUnit(HalfWord aDestinationUnit)
CodeSectionCreator::InternalSection::startAddress
UValue startAddress
Start address of the section.
Definition: CodeSectionCreator.hh:141
OutOfRange
Definition: Exception.hh:320
LabelManager::commitLastRelocations
void commitLastRelocations()
Definition: LabelManager.cc:276
ParserGuard::isGuarded
bool isGuarded
Is guard used.
Definition: ParserStructs.hh:308
MachineResourceManager::findBusWidth
UValue findBusWidth(UValue slotNumber)
Definition: MachineResourceManager.cc:129
TPEF::ImmediateElement::setDestinationIndex
void setDestinationIndex(Byte aDestinationIndex)
TPEF::ImmediateElement::setWord
void setWord(Word aValue)
TPEF::Binary::addSection
void addSection(Section *section)
TPEF::MoveElement::setGuarded
void setGuarded(bool flag)
ParserMove::type
MoveType type
Type of move.
Definition: ParserStructs.hh:401
CompileError
Definition: Exception.hh:1019
TPEF::ImmediateElement
Definition: ImmediateElement.hh:49
MachineResourceManager::ResourceID::index
UValue index
TPEF Resource operand id or register file index.
Definition: MachineResourceManager.hh:102
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
MachineResourceManager::RQST_READ
@ RQST_READ
Register of port for reading.
Definition: MachineResourceManager.hh:82
TPEF::MoveElement::setDestinationType
void setDestinationType(FieldType aType)
Byte
unsigned char Byte
Definition: BaseType.hh:116
CodeSectionCreator::IMMEDIATE
@ IMMEDIATE
Long immediate assignment.
Definition: CodeSectionCreator.hh:83
CodeSectionCreator::MOVE
@ MOVE
Data transport.
Definition: CodeSectionCreator.hh:82
Conversion::toString
static std::string toString(const T &source)
TPEF::MoveElement::setBus
void setBus(HalfWord aBus)
ParserGuard::regTerm
RegisterTerm regTerm
Guard port or register.
Definition: ParserStructs.hh:312
LabelManager::resolveExpressionValue
UValue resolveExpressionValue(UValue asmLineNumber, LiteralOrExpression &litOrExpr)
Definition: LabelManager.cc:678
TPEF::ImmediateElement::setDestinationUnit
void setDestinationUnit(Byte aDestinationUnit)
assert
#define assert(condition)
Definition: Application.hh:86
InitDataField::width
UValue width
Number of MAUs that are initialized by the init field.
Definition: ParserStructs.hh:342
LiteralOrExpression::isExpression
bool isExpression
Does object contain expression or literal.
Definition: ParserStructs.hh:251
LabelManager::addRelocation
void addRelocation(TPEF::Section &locationSect, TPEF::SectionElement &location, TPEF::ASpaceElement &dstASpace, UValue destination, UValue bitWidth)
Definition: LabelManager.cc:231
ParserMove::LONG_IMMEDIATE
@ LONG_IMMEDIATE
Encoding of one long immediate slot.
Definition: ParserStructs.hh:396
ParserGuard::isInverted
bool isInverted
Is guard inverted.
Definition: ParserStructs.hh:310
MachineResourceManager::ResourceID::type
TPEF::MoveElement::FieldType type
Resource type.
Definition: MachineResourceManager.hh:98
UValue
unsigned long UValue
Definition: ParserStructs.hh:44
RegisterTerm::toString
std::string toString() const
Definition: ParserStructs.hh:161
MachineResourceManager::ResourceID::width
UValue width
Width of accessed port or other resource.
Definition: MachineResourceManager.hh:104
TPEF::MoveElement::setGuardIndex
void setGuardIndex(HalfWord aGuardIndex)
TPEF::ASpaceElement
Definition: ASpaceElement.hh:48
MachineResourceManager::RQST_INVGUARD
@ RQST_INVGUARD
Inverted register or port guard.
Definition: MachineResourceManager.hh:85
InitDataField
Definition: ParserStructs.hh:339
InitDataField::toString
std::string toString() const
Definition: ParserStructs.hh:349
TPEF::MoveElement
Definition: MoveElement.hh:47
CodeSectionCreator::startNewInstruction
void startNewInstruction()
Definition: CodeSectionCreator.cc:528
ParserMove::EMPTY
@ EMPTY
Empty move slot.
Definition: ParserStructs.hh:395
__func__
#define __func__
Definition: Application.hh:67
LabelManager::aSpaceName
std::string aSpaceName(std::string &labelName)
Definition: LabelManager.cc:147
CodeSectionCreator::slotNumber_
UValue slotNumber_
Slot number of current move.
Definition: CodeSectionCreator.hh:172
TPEF::MoveElement::setEmpty
void setEmpty(bool flag)
MathTools::requiredBits
static int requiredBits(unsigned long int number)
TPEF::MoveElement::setDestinationIndex
void setDestinationIndex(HalfWord aDestinationIndex)
Exception
Definition: Exception.hh:54
InitDataField::litOrExpr
LiteralOrExpression litOrExpr
Initialisation value.
Definition: ParserStructs.hh:344
TTAMachine::Machine::addressSpaceNavigator
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition: Machine.cc:392
TPEF::CodeSection
Definition: CodeSection.hh:44
CodeSectionCreator::immediateIndex_
UValue immediateIndex_
Immediate index.
Definition: CodeSectionCreator.hh:175
TPEF::Section::setName
void setName(const ReferenceManager::SafePointer *sectionName)
CodeSectionCreator::addAnnotationes
void addAnnotationes(TPEF::InstructionElement &instrElem, InternalElement &elem, LabelManager &lables) const
Definition: CodeSectionCreator.cc:636
TPEF::MoveElement::setGuardType
void setGuardType(FieldType gType)
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
CodeSectionCreator::resources_
MachineResourceManager & resources_
TPEF Resources and strings.
Definition: CodeSectionCreator.hh:163
ParserSource::regTerm
RegisterTerm regTerm
If register, the register. Otherwise not used.
Definition: ParserStructs.hh:284
TPEF::InstructionElement::setBegin
void setBegin(bool isBegin)
LiteralOrExpression::value
UValue value
If literal, the literal. Otherwise not used.
Definition: ParserStructs.hh:256
ParserMove::annotationes
std::vector< Annotation > annotationes
Definition: ParserStructs.hh:415
ParserSource::immTerm
LiteralOrExpression immTerm
If immediate value, the literal or expression. Otherwise not used.
Definition: ParserStructs.hh:286
LabelManager::aSpaceElement
TPEF::ASpaceElement & aSpaceElement(std::string &labelName)
Definition: LabelManager.cc:129
LiteralOrExpression::isSigned
bool isSigned
Sign of the value.
Definition: ParserStructs.hh:258
MachineResourceManager::ResourceID::unit
UValue unit
TPEF Resource unit id.
Definition: MachineResourceManager.hh:100
ParserMove::TRANSPORT
@ TRANSPORT
Data transport (move).
Definition: ParserStructs.hh:397
IllegalMachine
Definition: Exception.hh:878
ParserMove::destination
RegisterTerm destination
Destination field.
Definition: ParserStructs.hh:411
CodeSectionCreator::cleanup
void cleanup()
Definition: CodeSectionCreator.cc:518
BYTE_BITWIDTH
const Byte BYTE_BITWIDTH
Definition: BaseType.hh:136
CodeSectionCreator::mach_
const TTAMachine::Machine & mach_
Definition: CodeSectionCreator.hh:157
TPEF::MoveElement::setSourceUnit
void setSourceUnit(HalfWord aSourceUnit)
TPEF::Section::setASpace
void setASpace(const ReferenceManager::SafePointer *addrSpace)
CodeSectionCreator::EMPTY
@ EMPTY
Empty move.
Definition: CodeSectionCreator.hh:81
TPEF::InstructionAnnotation
Definition: InstructionElement.hh:49
MachineResourceManager::RQST_GUARD
@ RQST_GUARD
Register or port guard.
Definition: MachineResourceManager.hh:84
TPEF::MoveElement::setSourceIndex
void setSourceIndex(HalfWord aSourceIndex)
TPEF::Section::setLink
void setLink(const ReferenceManager::SafePointer *aLink)
MachineResourceManager::resourceID
ResourceID & resourceID(UValue currentLine, const RegisterTerm &term, UValue slotNumber, RequestType type)
Definition: MachineResourceManager.cc:285
ParserMove::source
ParserSource source
Source field.
Definition: ParserStructs.hh:409
TPEF::ImmediateElement::destinationUnit
Byte destinationUnit() const
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
ParserMove::guard
ParserGuard guard
Guard field.
Definition: ParserStructs.hh:407
MachineResourceManager::codeAddressSpace
TPEF::ASpaceElement * codeAddressSpace()
Definition: MachineResourceManager.cc:213
CodeSectionCreator::isNextBegin_
bool isNextBegin_
Next element is starting element of instruction.
Definition: CodeSectionCreator.hh:169
AssemblyParserDiagnostic::addWarning
void addWarning(UValue lineNumber, const std::string &message)
Definition: AssemblyParserDiagnostic.cc:56
TTAMachine::AddressSpace::end
virtual ULongWord end() const
Definition: AddressSpace.cc:177
LabelManager::clearLastRelocations
void clearLastRelocations()
Definition: LabelManager.cc:255
CodeSectionCreator::parent_
AssemblyParserDiagnostic * parent_
Place to add warnings during compilation.
Definition: CodeSectionCreator.hh:166
CodeSectionCreator::immediateIndex
UValue immediateIndex()
Definition: CodeSectionCreator.cc:550
MachineResourceManager::RQST_WRITE
@ RQST_WRITE
Register or port for writing.
Definition: MachineResourceManager.hh:83
TPEF::MoveElement::setSourceType
void setSourceType(FieldType aType)
CodeSectionCreator::InternalSection::elements
std::vector< InternalElement > elements
Elements of the section.
Definition: CodeSectionCreator.hh:143
TPEF::MoveElement::setGuardUnit
void setGuardUnit(HalfWord aGuardUnit)
CodeSectionCreator::isDestinationAlreadyWritten
bool isDestinationAlreadyWritten(const InternalElement &elem) const
Definition: CodeSectionCreator.cc:562
ParserSource::isRegister
bool isRegister
Is source register or immediate reference.
Definition: ParserStructs.hh:282
ParserMove::asmLineNumber
UValue asmLineNumber
Line number of source code for errors.
Definition: ParserStructs.hh:413