OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
DataSectionCreator Class Reference

#include <DataSectionCreator.hh>

Collaboration diagram for DataSectionCreator:
Collaboration graph

Classes

struct  InternalSection
 

Public Member Functions

 DataSectionCreator (MachineResourceManager &resourceManager, AssemblyParserDiagnostic *parent)
 
 ~DataSectionCreator ()
 
void setAreaStartAddress (UValue address)
 
void addDataLine (const DataLine &origLine)
 
void finalize (TPEF::Binary &tpef, LabelManager &labels, bool littleEndian)
 
void cleanup ()
 

Private Member Functions

void resolveDataAreaSizesAndLabelAddresses (std::map< std::string, UValue > &addressSpaceUsedMAUs, std::vector< std::string > &addedLabels, LabelManager &labels)
 
UValue writeDataLineToTPEF (DataLine *line, TPEF::DataSection *dataSection, LabelManager &labels, UValue currentMAUIndex)
 
int sizeInWords (UValue value, int MAUWidth, bool isSigned) const
 

Private Attributes

MachineResourceManagerresources_
 TPEF Resources and strings.
 
UValue currentStartAddress_
 Start address of next line (if fixed address).
 
bool isStartAddressDefined_
 Is next data line address fixed.
 
std::vector< InternalSectionsections_
 Internal data sections.
 

Detailed Description

Collects data area information and parses data to tpef data sections.

Definition at line 52 of file DataSectionCreator.hh.

Constructor & Destructor Documentation

◆ DataSectionCreator()

DataSectionCreator::DataSectionCreator ( MachineResourceManager resourceManager,
AssemblyParserDiagnostic parent 
)

Constructor.

Parameters
resourceManagerResource manager for TPEF to create.

Definition at line 55 of file DataSectionCreator.cc.

56 :
57 resources_(resourceManager), currentStartAddress_(0),
59}
UValue currentStartAddress_
Start address of next line (if fixed address).
MachineResourceManager & resources_
TPEF Resources and strings.
bool isStartAddressDefined_
Is next data line address fixed.

◆ ~DataSectionCreator()

DataSectionCreator::~DataSectionCreator ( )

Destructor.

Definition at line 64 of file DataSectionCreator.cc.

64 {
65 cleanup();
66}

References cleanup().

Here is the call graph for this function:

Member Function Documentation

◆ addDataLine()

void DataSectionCreator::addDataLine ( const DataLine origLine)

Adds data line.

Parameters
origLineParsed data line to copy to creator.

Definition at line 84 of file DataSectionCreator.cc.

84 {
85
86 // make copy of original
87 DataLine* line = new DataLine;
88
89 line->dataSpace = origLine.dataSpace;
90 line->width = origLine.width;
91 line->initData = origLine.initData;
92 line->labels = origLine.labels;
93 line->asmLineNumber = origLine.asmLineNumber;
94
95 // find out section where to we add line by
96 // address and address space
97 assert(line != NULL);
98
99 InternalSection* foundSection = NULL;
100 for (int foundIndex = sections_.size() - 1;
101 foundIndex >= 0; foundIndex--) {
102
103 InternalSection& section = sections_[foundIndex];
104
105 // try to find last suitable section for the data line
106 if (section.addressSpace == line->dataSpace) {
107
108 // we always create new section for datalines with fixed address,
109 // otherwise we just check, if last created section is fine for
110 // currently added line
111
112 if (section.isInitialized != line->initData.empty() &&
114
115 // section with same type of data lines was found
116 foundSection = &section;
117 break;
118
119 } else {
120 // section with same type of data lines
121 // was not found -> create new section
122 break;
123 }
124 }
125 }
126
127 // create new section if suitable is not found
128 if (foundSection == NULL) {
129 InternalSection newSection;
130
131 newSection.isInitialized = !line->initData.empty();
132 newSection.fixedStartAddress = isStartAddressDefined_;
133 newSection.startAddress = currentStartAddress_;
134 newSection.addressSpace = line->dataSpace;
135 newSection.length = 0;
136
137 sections_.push_back(newSection);
138
139 // set found section
140 foundSection = &sections_.back();
141
144 }
145
146 assert(foundSection != NULL);
147
148 // add line to section
149 foundSection->lines.push_back(line);
150}
#define assert(condition)
UValue width
Number of MAUs initialized by this data line.
std::vector< InitDataField > initData
Init data fields of data line. Uninitilized data line, if empty.
std::vector< std::string > labels
Labels of this data line.
std::string dataSpace
Address space whose MAUs are initialized.
UValue asmLineNumber
Line number where in source code this DA line is found.
std::vector< InternalSection > sections_
Internal data sections.

References DataSectionCreator::InternalSection::addressSpace, DataLine::asmLineNumber, assert, currentStartAddress_, DataLine::dataSpace, DataSectionCreator::InternalSection::fixedStartAddress, DataLine::initData, DataSectionCreator::InternalSection::isInitialized, isStartAddressDefined_, DataLine::labels, DataSectionCreator::InternalSection::length, DataSectionCreator::InternalSection::lines, sections_, DataSectionCreator::InternalSection::startAddress, and DataLine::width.

Referenced by AddDataLineActor::operator()().

◆ cleanup()

void DataSectionCreator::cleanup ( )

Frees all internally allocated data.

Definition at line 156 of file DataSectionCreator.cc.

156 {
157
158 for (unsigned int i = 0; i < sections_.size(); i++) {
159 InternalSection &section = sections_[i];
160
161 for (unsigned int j = 0; j < section.lines.size(); j++) {
162 section.lines[j]->initData.clear();
163 section.lines[j]->labels.clear();
164 delete section.lines[j];
165 }
166
167 section.lines.clear();
168 }
169
170 sections_.clear();
171
174}

References currentStartAddress_, isStartAddressDefined_, DataSectionCreator::InternalSection::lines, and sections_.

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

◆ finalize()

void DataSectionCreator::finalize ( TPEF::Binary tpef,
LabelManager labels,
bool  littleEndian 
)

Writes created sections to given binary.

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

In case of exception the creator restores its state to what it was before calling this method, and this method can be run again.

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

Definition at line 190 of file DataSectionCreator.cc.

191 {
192 // completed tpef data sections.
193 std::vector<TPEF::Section*> completed;
194
195 // find out start addresses of each section and resolve label values
196 std::map<std::string, UValue> addressSpaceUsedMAUs;
197 std::vector<std::string> addedLabels;
198
199 try {
200
202 addressSpaceUsedMAUs, addedLabels, labels);
203
204 // create TPEF sections and add initialization data + relocation
205 // elements
206 for (unsigned int i = 0; i < sections_.size(); i++) {
207 InternalSection &section = sections_[i];
208
209 Section* newSection = NULL;
210
211 // if initialized, generate initialization data
212 if (section.isInitialized) {
213 if (littleEndian) {
215 } else {
217 }
218 } else {
220 }
221
222 // add section to completed sections
223 completed.push_back(newSection);
224
225 newSection->setName(resources_.stringToChunk(""));
226
227 assert(section.fixedStartAddress);
228 newSection->setStartingAddress(section.startAddress);
229
230 ASpaceElement* aSpace = NULL;
231
232 // wrap IllegalMachine to
233 // CompileError exception with linenumber
234 try {
235 aSpace =
236 resources_.findDataAddressSpace(section.addressSpace);
237
238 } catch (IllegalMachine& e) {
239 CompileError error(
240 __FILE__, __LINE__, __func__, e.errorMessage());
241
242 error.setCodeFileLineNumber(section.lines[0]->asmLineNumber);
243 error.setCause(e);
244
245 throw error;
246
247 } catch (InvalidData& e) {
248 CompileError error(
249 __FILE__, __LINE__, __func__,
250 "Can't write data to instruction memory.");
251
252 error.setCodeFileLineNumber(section.lines[0]->asmLineNumber);
253 error.setCause(e);
254
255 throw error;
256 }
257
258 assert(aSpace != NULL);
259 newSection->setASpace(aSpace);
260
261 // sets data section length in MAUs
262 RawSection *rawSection = dynamic_cast<RawSection*>(newSection);
263 assert(rawSection != NULL);
264 rawSection->setLengthInMAUs(section.length);
265
266 // aSpace had to be set before writing initialization data of
267 // section
268 if (section.isInitialized) {
269 DataSection *dataSection =
270 dynamic_cast<DataSection*>(newSection);
271
272 UValue currentMAUIndex = 0;
273
274 for (unsigned int j = 0; j < section.lines.size(); j++) {
275 DataLine *line = section.lines[j];
276 currentMAUIndex += writeDataLineToTPEF(
277 line, dataSection, labels, currentMAUIndex);
278 }
279 }
280 }
281
282 } catch (CompileError& e) {
283
284 labels.clearLastRelocations();
285
286 // clean added labels
287 for (unsigned int i = 0; i < addedLabels.size(); i++) {
288 labels.removeLabel(addedLabels[i]);
289 }
290
291 // clean already created stuff and throw error forward
292 for (UValue j = 0; j < completed.size(); j++) {
293 delete completed[j];
294 }
295
296 completed.clear();
297
298 throw e;
299
300 }
301
302 // really add relocations to manager
303 labels.commitLastRelocations();
304
305 // add completed sections to binary
306 for (UValue i = 0; i < completed.size(); i++) {
307 tpef.addSection(completed[i]);
308 }
309
310 cleanup();
311}
#define __func__
unsigned long UValue
void resolveDataAreaSizesAndLabelAddresses(std::map< std::string, UValue > &addressSpaceUsedMAUs, std::vector< std::string > &addedLabels, LabelManager &labels)
UValue writeDataLineToTPEF(DataLine *line, TPEF::DataSection *dataSection, LabelManager &labels, UValue currentMAUIndex)
std::string errorMessage() const
Definition Exception.cc:123
void removeLabel(std::string &name)
void clearLastRelocations()
void commitLastRelocations()
TPEF::ASpaceElement * findDataAddressSpace(std::string name)
TPEF::Chunk * stringToChunk(const std::string aStr)
void addSection(Section *section)
virtual void setLengthInMAUs(Word length)
Definition Section.cc:265
static Section * createSection(SectionType type)
Definition Section.cc:91
@ ST_DATA
Initialized data section.
Definition Section.hh:80
@ ST_UDATA
Uninitialized data section.
Definition Section.hh:81
@ ST_LEDATA
Initialized little endian data section.
Definition Section.hh:82
void setStartingAddress(AddressImage address)
void setASpace(const ReferenceManager::SafePointer *addrSpace)
void setName(const ReferenceManager::SafePointer *sectionName)

References __func__, DataSectionCreator::InternalSection::addressSpace, TPEF::Binary::addSection(), assert, cleanup(), LabelManager::clearLastRelocations(), LabelManager::commitLastRelocations(), TPEF::Section::createSection(), Exception::errorMessage(), MachineResourceManager::findDataAddressSpace(), DataSectionCreator::InternalSection::fixedStartAddress, DataSectionCreator::InternalSection::isInitialized, DataSectionCreator::InternalSection::length, DataSectionCreator::InternalSection::lines, LabelManager::removeLabel(), resolveDataAreaSizesAndLabelAddresses(), resources_, sections_, TPEF::Section::setASpace(), Exception::setCause(), CompileError::setCodeFileLineNumber(), TPEF::RawSection::setLengthInMAUs(), TPEF::Section::setName(), TPEF::Section::setStartingAddress(), TPEF::Section::ST_DATA, TPEF::Section::ST_LEDATA, TPEF::Section::ST_UDATA, DataSectionCreator::InternalSection::startAddress, MachineResourceManager::stringToChunk(), and writeDataLineToTPEF().

Referenced by AssemblerParser::finalize().

Here is the call graph for this function:

◆ resolveDataAreaSizesAndLabelAddresses()

void DataSectionCreator::resolveDataAreaSizesAndLabelAddresses ( std::map< std::string, UValue > &  addressSpaceUsedMAUs,
std::vector< std::string > &  addedLabels,
LabelManager labels 
)
private

Resolves data area definition sizes, addresses and writes resolved data labels to label manager.

Parameters
addressSpaceUsedMAUsTable for updating number of MAUs that are used for each section.
addedLabelsList of all labels added to label manager for error cleanup.
labelsLabel bookkeeper.

Definition at line 324 of file DataSectionCreator.cc.

326 {
327 // calculate sizes and addresses for each data section and
328 // add values for labels
329
330 for (unsigned int i = 0; i < sections_.size(); i++) {
331 InternalSection &section = sections_[i];
332 UValue spaceLastAddress;
333
335 addressSpaceUsedMAUs, section.addressSpace)) {
336
337 addressSpaceUsedMAUs[section.addressSpace] = 0;
338 }
339
340 // last used address of address space of current section
341 spaceLastAddress = addressSpaceUsedMAUs[section.addressSpace];
342
343 // check if we have to look, if current address is ok or
344 // we set the address
345 if (section.fixedStartAddress) {
346 if (spaceLastAddress > section.startAddress) {
347
348 CompileError error(
349 __FILE__, __LINE__, __func__,
350 "Can't start data section from address: " +
351 Conversion::toString(section.startAddress) +
352 " first unused address in address space: " +
353 section.addressSpace +
354 " is: " + Conversion::toString(spaceLastAddress));
355
356 error.setCodeFileLineNumber(section.lines[0]->asmLineNumber);
357
358 throw error;
359 }
360 } else {
361 section.startAddress = spaceLastAddress;
362 }
363
364 section.fixedStartAddress = true;
365
366 // add also labels to label map
367 UValue dataLineAddress = section.startAddress;
368
369 for (unsigned int j = 0; j < section.lines.size(); j++) {
370 DataLine *currentLine = section.lines[j];
371
372 // wrap IllegalMachine and ObjectAlreadyExists exceptions
373 // to CompileError exception with linenumber
374 try {
375
376 for (unsigned int k = 0;
377 k < currentLine->labels.size(); k++) {
378
379 labels.addLabel(
381 section.addressSpace),
382 currentLine->labels[k], dataLineAddress);
383
384 // for cleanup
385 addedLabels.push_back(currentLine->labels[k]);
386 }
387
388 dataLineAddress += currentLine->width;
389
390 } catch (InvalidData& e) {
391 CompileError error(
392 __FILE__, __LINE__, __func__,
393 "Can't write data to instruction memory.");
394
395 error.setCodeFileLineNumber(currentLine->asmLineNumber);
396 error.setCause(e);
397
398 throw error;
399
400 } catch (Exception& e) {
401
402 CompileError error(
403 __FILE__, __LINE__, __func__, e.errorMessage());
404
405 error.setCodeFileLineNumber(currentLine->asmLineNumber);
406 error.setCause(e);
407
408 throw error;
409 }
410 }
411
412 section.length = dataLineAddress - section.startAddress;
413 addressSpaceUsedMAUs[section.addressSpace] = dataLineAddress;
414#if 0
415 // some useful dedug info about created data sections and mapping
416 std::cerr << "Section length: " << section.length
417 << "\tSection start: " << section.startAddress
418 << std::endl;
419#endif
420 // NOTE: here we can check if we can merge two sections together.
421 // If both are initialized or uninitialized and second
422 // section's start address is same that first section
423 // start address + first section size then merging can
424 // be done.
425 }
426}
static std::string toString(const T &source)
void addLabel(TPEF::ASpaceElement &aSpace, std::string &name, UValue value)
static bool containsKey(const MapType &aMap, const KeyType &aKey)

References __func__, LabelManager::addLabel(), DataSectionCreator::InternalSection::addressSpace, DataLine::asmLineNumber, MapTools::containsKey(), Exception::errorMessage(), MachineResourceManager::findDataAddressSpace(), DataSectionCreator::InternalSection::fixedStartAddress, DataLine::labels, DataSectionCreator::InternalSection::length, DataSectionCreator::InternalSection::lines, resources_, sections_, Exception::setCause(), CompileError::setCodeFileLineNumber(), DataSectionCreator::InternalSection::startAddress, Conversion::toString(), and DataLine::width.

Referenced by finalize().

Here is the call graph for this function:

◆ setAreaStartAddress()

void DataSectionCreator::setAreaStartAddress ( UValue  address)

Sets fixed address for the next data area definition.

Parameters
addressStart address of next data area definition.

Definition at line 73 of file DataSectionCreator.cc.

73 {
74 currentStartAddress_ = address;
76}

References currentStartAddress_, and isStartAddressDefined_.

Referenced by SetStartAddressActor::operator()().

◆ sizeInWords()

int DataSectionCreator::sizeInWords ( UValue  value,
int  width,
bool  isSigned 
) const
private

Compute the minimum number of words of given bit width that are necessary to encode an integer value.

Parameters
valueInteger value to encode.
widthBit width of the words.
isSignedTells whether the value had a sign ('+'/'-') in front of it.

Definition at line 544 of file DataSectionCreator.cc.

545 {
546
547 // maximum word width allowed: 32 bits
548 assert(static_cast<unsigned int>(width) <= sizeof(value) * BYTE_BITWIDTH);
549
550 int neededBits = 0;
551
552 if (isSigned) {
553 neededBits = MathTools::requiredBitsSigned(SLongWord(value));
554 } else {
555 neededBits = MathTools::requiredBits(value);
556 }
557
558 int wordCount = static_cast<int>(
559 ceil(static_cast<double>(neededBits) /
560 static_cast<double>(width)));
561
562 return wordCount;
563}
long SLongWord
Definition BaseType.hh:52
const Byte BYTE_BITWIDTH
Definition BaseType.hh:136
static int requiredBits(unsigned long int number)
static int requiredBitsSigned(SLongWord number)

References assert, BYTE_BITWIDTH, MathTools::requiredBits(), and MathTools::requiredBitsSigned().

Referenced by writeDataLineToTPEF().

Here is the call graph for this function:

◆ writeDataLineToTPEF()

UValue DataSectionCreator::writeDataLineToTPEF ( DataLine line,
TPEF::DataSection dataSection,
LabelManager labels,
UValue  currentMAUIndex 
)
private

Write one data line definition to TPEF data section.

Parameters
lineData line to write.
dataSectionSection where to write data.
labelLabel manager to resolve label values.
currentMAUIndexMAU index to start of data line in TPEF.
Returns
MAU count that were written to TPEF.
Exceptions
CompileErrorthe data line contains errors.

Definition at line 439 of file DataSectionCreator.cc.

441 {
442 UValue writtenMAUs = 0;
443
444 // read maus from init data until inited data of line ends
445 for (unsigned int k = 0; k < line->initData.size(); k++) {
446 InitDataField &data = line->initData[k];
447
448 UValue value = 0;
449 bool isSigned = false;
450
451 // if expression resolve value
452 if(data.litOrExpr.isExpression) {
453 value = labels.resolveExpressionValue(
454 line->asmLineNumber, data.litOrExpr);
455 } else {
456 value = data.litOrExpr.value;
457 isSigned = data.litOrExpr.isSigned;
458 }
459
460 UValue usedMAUs =
461 sizeInWords(value, dataSection->aSpace()->MAU(), isSigned);
462
463 // if data width is explicitely set use that width
464 if (data.width != 0) {
465 if (usedMAUs > data.width) {
466
467 CompileError error(
468 __FILE__, __LINE__, __func__,
469 "Init field contains too long value. Reserved MAUs: " +
471 " Needed MAUs: " +
472 Conversion::toString(usedMAUs));
473
474 error.setCodeFileLineNumber(line->asmLineNumber);
475
476 throw error;
477 }
478
479 usedMAUs = data.width;
480 }
481
482 // check if data line width is enough for writing next value
483 if (writtenMAUs + usedMAUs > line->width) {
484
485 CompileError error(
486 __FILE__, __LINE__, __func__,
487 "Data line contains too much init data. Reserved MAUs: " +
489 " Already inited MAUs: " +
490 Conversion::toString(writtenMAUs));
491
492 error.setCodeFileLineNumber(line->asmLineNumber);
493
494 throw error;
495 }
496
497 // select extending for writing data to data section
498 if (isSigned) {
499 dataSection->writeValue(
500 currentMAUIndex + writtenMAUs,
501 usedMAUs, static_cast<SValue>(value));
502
503 } else {
504 dataSection->writeValue(
505 currentMAUIndex + writtenMAUs, usedMAUs, value);
506 }
507
508 // if expression then add relocation.
509 if(data.litOrExpr.isExpression) {
510 Chunk *srcChunk =
511 dataSection->chunk(
512 dataSection->MAUsToBytes(
513 currentMAUIndex + writtenMAUs));
514
515 labels.addRelocation(
516 *dataSection, *srcChunk,
518 value, usedMAUs * dataSection->aSpace()->MAU());
519 }
520
521 writtenMAUs += usedMAUs;
522 }
523
524 if (writtenMAUs < line->width) {
525 dataSection->writeValue(currentMAUIndex+writtenMAUs, 1,
526 static_cast<unsigned long>(0));
527 writtenMAUs++;
528 }
529
530 // increase index to data section
531 return line->width;
532}
long SValue
int sizeInWords(UValue value, int MAUWidth, bool isSigned) const
std::string label
Name of the label.
LiteralOrExpression litOrExpr
Initialisation value.
UValue width
Number of MAUs that are initialized by the init field.
UValue resolveExpressionValue(UValue asmLineNumber, LiteralOrExpression &litOrExpr)
TPEF::ASpaceElement & aSpaceElement(std::string &labelName)
void addRelocation(TPEF::Section &locationSect, TPEF::SectionElement &location, TPEF::ASpaceElement &dstASpace, UValue destination, UValue bitWidth)
bool isExpression
Does object contain expression or literal.
UValue value
If literal, the literal. Otherwise not used.
bool isSigned
Sign of the value.
Expression expression
If expression the expression, Otherwise not used.
Byte MAU() const
virtual void writeValue(Word index, Word numOfMAUs, unsigned long value)
virtual Chunk * chunk(SectionOffset offset) const
Definition Section.cc:212
virtual Word MAUsToBytes(Word mauCount) const
Definition Section.cc:320
ASpaceElement * aSpace() const

References __func__, LabelManager::addRelocation(), DataLine::asmLineNumber, TPEF::Section::aSpace(), LabelManager::aSpaceElement(), TPEF::RawSection::chunk(), LiteralOrExpression::expression, DataLine::initData, LiteralOrExpression::isExpression, LiteralOrExpression::isSigned, Expression::label, InitDataField::litOrExpr, TPEF::ASpaceElement::MAU(), TPEF::RawSection::MAUsToBytes(), LabelManager::resolveExpressionValue(), CompileError::setCodeFileLineNumber(), sizeInWords(), Conversion::toString(), LiteralOrExpression::value, InitDataField::width, DataLine::width, and TPEF::DataSection::writeValue().

Referenced by finalize().

Here is the call graph for this function:

Member Data Documentation

◆ currentStartAddress_

UValue DataSectionCreator::currentStartAddress_
private

Start address of next line (if fixed address).

Definition at line 104 of file DataSectionCreator.hh.

Referenced by addDataLine(), cleanup(), and setAreaStartAddress().

◆ isStartAddressDefined_

bool DataSectionCreator::isStartAddressDefined_
private

Is next data line address fixed.

Definition at line 106 of file DataSectionCreator.hh.

Referenced by addDataLine(), cleanup(), and setAreaStartAddress().

◆ resources_

MachineResourceManager& DataSectionCreator::resources_
private

TPEF Resources and strings.

Definition at line 101 of file DataSectionCreator.hh.

Referenced by finalize(), and resolveDataAreaSizesAndLabelAddresses().

◆ sections_

std::vector<InternalSection> DataSectionCreator::sections_
private

Internal data sections.

Definition at line 109 of file DataSectionCreator.hh.

Referenced by addDataLine(), cleanup(), finalize(), and resolveDataAreaSizesAndLabelAddresses().


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