OpenASIP 2.2
Loading...
Searching...
No Matches
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.
 
MachineResourceManagerresources_
 TPEF Resources and strings.
 
AssemblyParserDiagnosticparent_
 Place to add warnings during compilation.
 
bool isNextBegin_
 Next element is starting element of instruction.
 
UValue slotNumber_
 Slot number of current move.
 
UValue immediateIndex_
 Immediate index.
 

Static Private Attributes

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

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 };
@ IMMEDIATE
Long immediate assignment.
@ MOVE
Data transport.

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}
AssemblyParserDiagnostic * parent_
Place to add warnings during compilation.
UValue immediateIndex_
Immediate index.
UValue slotNumber_
Slot number of current move.
bool isNextBegin_
Next element is starting element of instruction.
const TTAMachine::Machine & mach_
MachineResourceManager & resources_
TPEF Resources and strings.

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}
#define __func__
const Byte BYTE_BITWIDTH
Definition BaseType.hh:136
unsigned char Byte
Definition BaseType.hh:116
unsigned long UValue
std::string toString() const
LiteralOrExpression litOrExpr
Initialisation value.
UValue width
Number of MAUs that are initialized by the init field.
UValue resolveExpressionValue(UValue asmLineNumber, LiteralOrExpression &litOrExpr)
bool isExpression
Does object contain expression or literal.
UValue value
If literal, the literal. Otherwise not used.
bool isSigned
Sign of the value.
void addAnnotation(InstructionAnnotation *anAnnotation)

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
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}
#define assert(condition)
void addWarning(UValue lineNumber, const std::string &message)
bool isDestinationAlreadyWritten(const InternalElement &elem) const
InternalSection internalSection_
Internal representation of code section.
static std::string toString(const T &source)
std::string errorMessage() const
Definition Exception.cc:123
ResourceID & resourceID(UValue currentLine, const RegisterTerm &term, UValue slotNumber, RequestType type)
UValue findBusWidth(UValue slotNumber)
@ RQST_INVGUARD
Inverted register or port guard.
@ RQST_READ
Register of port for reading.
@ RQST_WRITE
Register or port for writing.
@ RQST_GUARD
Register or port guard.
RegisterTerm regTerm
Guard port or register.
bool isInverted
Is guard inverted.
bool isGuarded
Is guard used.
@ TRANSPORT
Data transport (move).
@ EMPTY
Empty move slot.
@ LONG_IMMEDIATE
Encoding of one long immediate slot.
std::vector< Annotation > annotationes
MoveType type
Type of move.
ParserSource source
Source field.
bool isBegin
Tells whether the slot is the first of the instruction.
UValue asmLineNumber
Line number of source code for errors.
ParserGuard guard
Guard field.
RegisterTerm destination
Destination field.
bool isRegister
Is source register or immediate reference.
LiteralOrExpression immTerm
If immediate value, the literal or expression. Otherwise not used.
RegisterTerm regTerm
If register, the register. Otherwise not used.
std::string toString() const
@ MF_IMM
Immediate.
@ INLINE_IMM
Inline immediate unit id.
std::vector< InternalElement > elements
Elements of the section.
UValue width
Width of accessed port or other resource.
TPEF::MoveElement::FieldType type
Resource type.
UValue index
TPEF Resource operand id or register file index.

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, TPEF::ResourceElement::INLINE_IMM, internalSection_, CodeSectionCreator::InternalElement::isBegin, ParserMove::isBegin, isDestinationAlreadyWritten(), CodeSectionCreator::InternalElement::isGuarded, ParserGuard::isGuarded, CodeSectionCreator::InternalElement::isInverted, ParserGuard::isInverted, ParserSource::isRegister, ParserMove::LONG_IMMEDIATE, TPEF::MoveElement::MF_IMM, 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(), RegisterTerm::toString(), Conversion::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*>(
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() !=
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}
static std::ostream & logStream()
void addAnnotationes(TPEF::InstructionElement &instrElem, InternalElement &elem, LabelManager &lables) const
static const UValue CODE_RELOC_SIZE
Bitwidth of immediate value containing address to relocate.
void clearLastRelocations()
std::string aSpaceName(std::string &labelName)
void commitLastRelocations()
TPEF::ASpaceElement & aSpaceElement(std::string &labelName)
void addRelocation(TPEF::Section &locationSect, TPEF::SectionElement &location, TPEF::ASpaceElement &dstASpace, UValue destination, UValue bitWidth)
TPEF::Chunk * stringToChunk(const std::string aStr)
TPEF::ASpaceElement * codeAddressSpace()
TPEF::ResourceSection * resourceSection()
static int requiredBits(unsigned long int number)
void addSection(Section *section)
virtual void addElement(SectionElement *element)
void setDestinationIndex(Byte aDestinationIndex)
void setDestinationUnit(Byte aDestinationUnit)
Byte destinationUnit() const
void setWord(Word aValue)
void setBegin(bool isBegin)
void setGuardIndex(HalfWord aGuardIndex)
void setSourceType(FieldType aType)
void setGuardInverted(bool flag)
void setSourceIndex(HalfWord aSourceIndex)
void setBus(HalfWord aBus)
void setDestinationUnit(HalfWord aDestinationUnit)
void setGuarded(bool flag)
void setSourceUnit(HalfWord aSourceUnit)
void setGuardUnit(HalfWord aGuardUnit)
void setDestinationIndex(HalfWord aDestinationIndex)
void setEmpty(bool flag)
void setDestinationType(FieldType aType)
void setGuardType(FieldType gType)
static Section * createSection(SectionType type)
Definition Section.cc:91
@ ST_CODE
Text section.
Definition Section.hh:79
void setLink(const ReferenceManager::SafePointer *aLink)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
void setName(const ReferenceManager::SafePointer *sectionName)
virtual ULongWord end() const
ComponentType * item(int index) const
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392

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::Section::createSection(), 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, TPEF::ResourceElement::INLINE_IMM, 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, TPEF::Section::ST_CODE, 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 {
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}
UValue startAddress
Start address of the section.

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: