OpenASIP 2.2
Loading...
Searching...
No Matches
ProgramImageGenerator.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2011 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file ProgramImageGenerator.cc
26 *
27 * Implementation of ProgramImageGenerator class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @author Otto Esko 2008-2009 (otto.esko-no.spam-tut.fi)
31 * @author Pekka Jääskeläinen 2009 (pekka.jaaskelainen-no.spam-tut.fi)
32 * @author Otto Esko 2010(otto.esko-no.spam-tut.fi)
33 * @author Pekka Jääskeläinen 2011
34 * @note rating: red
35 */
36
38
39#include <cmath>
40#include <string>
41#include <vector>
42
45#include "Bin2nImageWriter.hh"
47#include "Binary.hh"
48#include "BinaryEncoding.hh"
51#include "CodeSection.hh"
52#include "CoeImageWriter.hh"
53#include "ControlUnit.hh"
54#include "DefaultCompressor.hh"
55#include "Environment.hh"
56#include "FileSystem.hh"
57#include "HexImageWriter.hh"
58#include "Immediate.hh"
60#include "InstructionElement.hh"
61#include "Machine.hh"
62#include "MifImageWriter.hh"
63#include "Move.hh"
64#include "PIGTextGenerator.hh"
65#include "PluginTools.hh"
66#include "Program.hh"
67#include "RawImageWriter.hh"
68#include "RelocElement.hh"
69#include "RelocSection.hh"
70#include "StringSection.hh"
71#include "Terminal.hh"
72#include "TerminalImmediate.hh"
73#include "VhdlImageWriter.hh"
75
76using namespace TTAMachine;
77using namespace TPEF;
78using namespace TTAProgram;
79
80using std::vector;
81using std::string;
82using boost::format;
83
84/**
85 * The constructor.
86 *
87 * @param program The program.
88 * @param bem The binary encoding map.
89 * @param machine The machine.
90 */
92 compressor_(new DEFAULT_Compressor()), entityName_("") {
93}
94
95
96/**
97 * The destructor.
98 */
102
103
104/**
105 * Loads the code compressor plugin from the given object file.
106 *
107 * @param fileName The file name.
108 * @exception FileNotFound If the given file is not found from the search
109 * paths of code compressor plugins.
110 * @exception DynamicLibraryException If the dynamic library cannot be
111 * opened.
112 */
113void
115 CodeCompressorPlugin* newCompressor = createCompressor(
116 fileName, pluginTool_);
117 delete compressor_;
118 compressor_ = newCompressor;
119}
120
121/**
122 * Loads the given code compressor plugin parameters to the plugin.
123 *
124 * @param parameters The parameters.
125 */
126void
132
133
134/**
135 * Loads the programs to be generated to the compressor plugin.
136 *
137 * @param programs The programs.
138 */
139void
143
144
145/**
146 * Sets the machine which executes the programs.
147 *
148 * @param machine The machine.
149 */
150void
154
155
156/**
157 * Sets the binary encoding map used when generating the program image.
158 *
159 * @param bem The binary encoding map.
160 */
161void
165
166
167/**
168 * Generates the program image to the given output stream in the given
169 * format.
170 *
171 * If the output is in ASCII format, mausPerLine parameter defines the number
172 * of MAUs printed per line. If 0 is given, each instruction is printed on
173 * different line.
174 *
175 * @param stream The output stream.
176 * @param format The output format.
177 * @param mausPerLine If the output is ASCII format, defines the number of
178 MAUs printed per line.
179 * @exception InvalidData If machine or BEM is not loaded or if they are
180 * erroneous or if the given program is not in the
181 * program set.
182 * @exception OutOfRange If mausPerLine is negative.
183 */
184void
186 const std::string& programName,
187 std::ostream& stream,
188 OutputFormat format,
189 int mausPerLine) {
190
191 if (mausPerLine < 0) {
192 string errorMsg = "Negative number of MAUs printed per line.";
193 throw OutOfRange(__FILE__, __LINE__, __func__, errorMsg);
194 }
195 InstructionBitVector* programBits = compressor_->compress(programName);
196 int mau = compressor_->machine().controlUnit()->addressSpace()->width();
197 BitImageWriter* writer = NULL;
198
199 if (Application::verboseLevel() > 0) {
200 size_t instructionCount =
202 size_t uncompressedWidth = compressor_->binaryEncoding().width();
204 << (boost::format(
205 "%s: %d instructions\n"
206 "uncompressed total size %d bits (%d bytes),\n")
207 % programName % instructionCount
208 % (uncompressedWidth * instructionCount)
209 % int(std::ceil(uncompressedWidth * instructionCount / 8.0))).
210 str();
211
213 << (boost::format(
214 "compressed total size %d bits (%d bytes)\n")
215 % programBits->size()
216 % size_t(std::ceil(programBits->size() / 8.0))).str();
217
218 // count some stats from the program that affect instruction
219 // memory usage
222
224 prog.instructionVector();
225
226 std::size_t moveSlots = mach.busNavigator().count();
227 std::size_t maxMoves = moveSlots * prog.instructionCount();
228 std::size_t moves = prog.moveCount();
229 std::size_t NOPCount = maxMoves - moves;
230
232 << (boost::format(
233 "number of NOP moves: %d (%.1f%% of total move slots)\n")
234 % NOPCount % (float(NOPCount) * 100 / maxMoves)).str();
235
236
237 // immediate stats
238 int totalImmediates = 0;
239 int totalLongImmediates = 0;
240 std::set<int> allImmediates;
241 std::set<int> programAddresses;
242 std::set<int> dataAddresses;
243
244 for (int m = 0; m < prog.moveCount(); ++m) {
245 const TTAProgram::Move& move = prog.moveAt(m);
246 if (move.source().isImmediate()) {
247 const auto value = move.source().value().sIntWordValue();
248 ++totalImmediates;
249 allImmediates.insert(value);
250 if (move.source().isAddress()) {
251 dataAddresses.insert(value);
252 } else if (move.source().isInstructionAddress()) {
253 programAddresses.insert(value);
254 }
255 }
256 }
257 // find the long immediates also
258 for (TTAProgram::Program::InstructionVector::const_iterator i =
259 instructions.begin(); i != instructions.end(); ++i) {
260 const TTAProgram::Instruction& instruction = **i;
261 for (int imm = 0; imm < instruction.immediateCount(); ++imm) {
262 const Immediate& immediate = instruction.immediate(imm);
263 const auto value = immediate.value().value().sIntWordValue();
264 ++totalImmediates;
265 ++totalLongImmediates;
266 allImmediates.insert(value);
267 if (immediate.value().isAddress()) {
268 dataAddresses.insert(value);
269 } else if (immediate.value().isInstructionAddress()) {
270 programAddresses.insert(value);
271 }
272 }
273
274 }
275
276 // variables for NOP counting
277 int totalFullNOPs = 0;
278 int totalTwoConsNOPs = 0;
279 int totalThreeConsNOPs = 0;
280 int totalFourConsNOPs = 0;
281 bool oneConsecutiveNOP = false;
282 bool twoConsecutiveNOPs = false;
283 bool threeConsecutiveNOPs = false;
284 bool fourConsecutiveNOPs = false;
285
286 // Find information about NOP instructions from program's instr.vectors
287 for (TTAProgram::Program::InstructionVector::const_iterator i =
288 instructions.begin(); i != instructions.end(); ++i) {
289 const TTAProgram::Instruction& instruction = **i;
290 if (instruction.isNOP()) {
291
292 // Increase count for each single full instruction NOP
293 ++totalFullNOPs;
294
295 // Find full instruction NOP groups iteratively, ie. if there
296 // are 4 NOPs in a row, decrease count for 3 NOPs, etc.
297 if (fourConsecutiveNOPs) {
298 // We don't change count beyond 4 or more consecutive
299 // NOP instructions.
300 } else if (threeConsecutiveNOPs) {
301 fourConsecutiveNOPs = true;
302 ++totalFourConsNOPs;
303 --totalThreeConsNOPs; // Actually 4 NOPs in a row, not 3
304 } else if (twoConsecutiveNOPs) {
305 threeConsecutiveNOPs = true;
306 ++totalThreeConsNOPs;
307 --totalTwoConsNOPs; // Actually 3 NOPs in a row, not 2
308 } else if (oneConsecutiveNOP) {
309 twoConsecutiveNOPs = true;
310 ++totalTwoConsNOPs;
311 }
312 oneConsecutiveNOP = true;
313 } else {
314 oneConsecutiveNOP = false;
315 twoConsecutiveNOPs = false;
316 threeConsecutiveNOPs = false;
317 fourConsecutiveNOPs = false;
318 }
319 }
320
321 // Print information about immediates, addresses and NOPs
323 << (boost::format(
324 "total immediates: %d (long %.1f%%), "
325 "different immediate values: %d,\n"
326 "instr. addresses %d (%.1f%%), "
327 "data addresses %d (%.1f%%),\n"
328 "total full instruction NOPs: %d (%.1f%% of instructions),\n"
329 "two consecutive full instruction NOPs: %d,\n"
330 "three consecutive full instruction NOPs: %d,\n"
331 "four consecutive full instruction NOPs: %d\n")
332 % totalImmediates
333 % (totalLongImmediates * 100.0 / totalImmediates)
334 % allImmediates.size() % programAddresses.size()
335 % (programAddresses.size() * 100.0 / allImmediates.size())
336 % dataAddresses.size()
337 % (dataAddresses.size() * 100.0 / allImmediates.size())
338 % totalFullNOPs
339 % (totalFullNOPs * 100.0 / instructionCount)
340 % totalTwoConsNOPs
341 % totalThreeConsNOPs
342 % totalFourConsNOPs)
343 .str();
344 }
345
346
347 if (format == BINARY) {
348 writer = new RawImageWriter(*programBits);
349 } else if (format == ASCII) {
350 // change this to "mausPerLine > 0" when mau == instructionwidth
351 // does not apply anymore
352 if (mausPerLine > 1) {
353 writer = new AsciiImageWriter(*programBits, mau * mausPerLine);
354 } else {
355 writer = new AsciiProgramImageWriter(*programBits);
356 }
357 } else if (format == ARRAY) {
358 if (mausPerLine > 1) {
359 writer = new ArrayImageWriter(*programBits, mau * mausPerLine);
360 } else {
361 writer = new ArrayProgramImageWriter(*programBits);
362 }
363 } else if (format == MIF) {
364 writer = new MifImageWriter(*programBits, mau);
365 } else if (format == VHDL) {
366 writer = new VhdlProgramImageWriter(*programBits, entityName_);
367 } else if (format == COE) {
368 writer = new CoeImageWriter(*programBits, mau);
369 } else if (format == HEX) {
370 writer = new HexImageWriter(*programBits, mau);
371 } else if (format == BIN2N) {
372 writer = new Bin2nProgramImageWriter(*programBits);
373 } else {
374 assert(false);
375 }
376
377
378 writer->writeImage(stream);
379
380 delete writer;
381 delete programBits;
382}
383
384
385/**
386 * Generates the data image of the given address space to the given
387 * output stream in the given format.
388 *
389 * @param program The program of which data image is generated.
390 * @param addressSpace The address space.
391 * @param stream The output stream.
392 * @param format The output format.
393 * @param mausPerLine Tells how many MAUs of data is generated on one line.
394 * @param usePregeneratedImage Tells whether use the program image that was
395 * previously generated for relocation of data
396 * elements.
397 * @exception InvalidData If tried to use pregenerated program but it has not
398 * been generated or if the given program is not in
399 * the program set loaded or if machine is not loaded
400 * or if is does not have the given address space.
401 * @exception OutOfRange If the given MAUs per line is not positive.
402 */
403void
405 const std::string& programName, TPEF::Binary& program,
406 const std::string& addressSpace, std::ostream& stream, OutputFormat format,
407 int mausPerLine, bool usePregeneratedImage) {
408 if (mausPerLine < 1) {
409 string errorMsg = "Data memory width in MAUs must be positive.";
410 throw OutOfRange(__FILE__, __LINE__, __func__, errorMsg);
411 }
412
413 const Machine* mach = NULL;
414 try {
415 mach = &compressor_->machine();
416 } catch (const Exception& e) {
417 throw InvalidData(__FILE__, __LINE__, __func__, e.errorMessage());
418 }
419
421 mach->addressSpaceNavigator();
422 if (!navigator.hasItem(addressSpace)) {
423 const string procName = "ProgramImageGenerator::generateDataImage";
424 throw InstanceNotFound(__FILE__, __LINE__, procName);
425 }
426 AddressSpace* as = navigator.item(addressSpace);
427 int memWidth = mausPerLine * as->width();
428
429 if (!usePregeneratedImage) {
430 InstructionBitVector* programBits = compressor_->compress(programName);
431 delete programBits;
432 }
433
434 BitVector dataBits;
435
436 // TODO: LEDATA? if le adf?
437 for (unsigned int i = 0; i < program.sectionCount(Section::ST_DATA);
438 i++) {
439 writeDataSection(program, dataBits, addressSpace,
440 *program.section(Section::ST_DATA, i));
441 }
442 for (unsigned int i = 0; i < program.sectionCount(Section::ST_LEDATA);
443 i++) {
444
445 unsigned int lineOffset = dataBits.size(); // start afer previous
446 // this writes data into the databits struct, not from it!
447 writeDataSection(program, dataBits, addressSpace,
448 *program.section(Section::ST_LEDATA, i));
449
450 // The stupid binary images are in big-endian bitness
451 // format(bit 0 == highest bit).
452 // Have to convert LE data into nasty mixed endian for
453 // initialization with those tools.
454 while (lineOffset < dataBits.size()) {
455 // Pad to full line width.
456 // if need padding (size not divisible by mem width)
457 // and we are at last iter of the loop, add pad.
458 if ((dataBits.size() % memWidth &&
459 lineOffset > (dataBits.size() - memWidth))) {
460 unsigned int preferredSize =
461 ((dataBits.size() / (memWidth))+1) *
462 (memWidth);
463 while (dataBits.size() < preferredSize) {
464 dataBits.push_back(0);
465 }
466 }
467
468 for (int k = 0; k < mausPerLine/2; k++) {
469 int bitOffset0 = k * as->width();
470 int bitOffset1 = (mausPerLine-k-1) * as->width();
471 // swap bytes of one MAU.
472 for (int j = 0; j < as->width(); j++) {
473 bool bit0 = dataBits[lineOffset+bitOffset0 + j];
474 dataBits[lineOffset+bitOffset0+j] =
475 dataBits[lineOffset+bitOffset1+j];
476 dataBits[lineOffset+bitOffset1+j] = bit0;
477 }
478 }
479 lineOffset += memWidth;
480 }
481 }
482
483 BitImageWriter* writer = NULL;
484 if (format == BINARY) {
485 writer = new RawImageWriter(dataBits);
486 } else if (format == ASCII) {
487 writer = new AsciiImageWriter(dataBits, as->width() * mausPerLine);
488 } else if (format == ARRAY) {
489 writer = new ArrayImageWriter(dataBits, as->width() * mausPerLine);
490 } else if (format == MIF) {
491 writer = new MifImageWriter(dataBits, as->width() * mausPerLine);
492 } else if (format == VHDL) {
493 writer = new VhdlImageWriter(
494 dataBits, as->width() * mausPerLine, entityName_);
495 } else if (format == COE) {
496 writer = new CoeImageWriter(dataBits, as->width() * mausPerLine);
497 } else if (format == HEX) {
498 writer = new HexImageWriter(dataBits, as->width() * mausPerLine);
499 } else if (format == BIN2N) {
500 writer = new Bin2nImageWriter(dataBits, as->width() * mausPerLine);
501 } else {
502 assert(false);
503 }
504
505 writer->writeImage(stream);
506 delete writer;
507}
508
509void
511 TPEF::Binary& program, BitVector& dataBits,
512 const std::string& addressSpace,
513 Section& section) {
514
515 // get the data section
516 StringSection* stringSection = program.strings();
517
518 CodeSection* codeSection = dynamic_cast<CodeSection*>(
519 program.section(Section::ST_CODE, 0));
520
521 if (stringSection->chunk2String(section.aSpace()->name()) ==
522 addressSpace) {
523
524 // correct data section found
525 DataSection& dataSection = dynamic_cast<DataSection&>(section);
526
527 // fill the beginning of the data image with zeros
528 AddressImage startingAddress = dataSection.startingAddress();
529 // If we already have put something, fill the correct number,
530 // not from 0.
531 unsigned int zeroFillStart = 0;
532 if ((dataBits.size() == 0) && isDataStartSet(addressSpace)) {
533 // User can set custom starting address, which means that the
534 // beginning is not zero-filled up to that point
535 zeroFillStart = dataStartAddress(addressSpace);
536 } else {
537 zeroFillStart = dataBits.size() / 8; // 8 bits per byte
538 }
539
540 for (AddressImage i = zeroFillStart; i < startingAddress; i++) {
541 dataBits.pushBack(0, 8);
542 }
543 if (zeroFillStart > startingAddress) {
544 throw InvalidData(
545 __FILE__,__LINE__,__func__, "Illegal order of data sections.");
546 }
547
548 // fill the data
549 Word sectionLength = dataSection.length();
550 for (Word offset = 0; offset < sectionLength;) {
552 this->relocTarget(program, dataSection, offset);
553 if (relocTarget != NULL) {
554 Word indexOfInstruction =
555 codeSection->indexOfInstruction(*relocTarget);
556 Instruction& instruction =
558 indexOfInstruction);
559 try {
560 unsigned int memAddress = compressor_->memoryAddress(
561 instruction);
563 // Byteswap the pointer
564 unsigned int num = memAddress;
565 memAddress = ((num>>24)&0xff) |
566 ((num<<8)&0xff0000) |
567 ((num>>8)&0xff00) |
568 ((num<<24)&0xff000000);
569 }
570 dataBits.pushBack(memAddress, 32);
571 offset += 4;
572 } catch (const Exception& e) {
573 string errorMsg =
574 "Program image must be generated before "
575 "generating data image.";
576 throw InvalidData(
577 __FILE__, __LINE__, __func__, errorMsg);
578 }
579 } else {
580 Byte byte = dataSection.byte(offset);
581 dataBits.pushBack(byte, 8);
582 offset++;
583 }
584 }
585 }
586}
587
588
589/**
590 * Generates the decompressor to the given output stream.
591 *
592 * Note! The program image should have been generated at first. Otherwise
593 * this may not function properly.
594 *
595 * @param stream The output stream.
596 * @param entityStr The entity string used to make HDL entity/component
597 * names unique for multiprocessor designs.
598 */
599void
601 std::ostream& stream,
602 TCEString entityStr) {
603 if (compressor_ == NULL) {
604 return;
605 } else {
606 compressor_->generateDecompressor(stream, entityStr);
607 }
608}
609
610
611/**
612 * Returns a vector containing paths to the compressors available.
613 *
614 * @return The vector.
615 */
616std::vector<std::string>
618
619 std::vector<string> paths = Environment::codeCompressorPaths();
620 std::vector<string> files;
621 for (std::vector<string>::const_iterator iter = paths.begin();
622 iter != paths.end(); iter++) {
623 if (FileSystem::fileExists(*iter)) {
624 std::vector<string> filesInPath = FileSystem::directoryContents(
625 *iter);
626 for (std::vector<string>::const_iterator iter =
627 filesInPath.begin();
628 iter != filesInPath.end(); iter++) {
629 if (!FileSystem::fileIsDirectory(*iter) &&
630 FileSystem::fileExtension(*iter) == ".so") {
631 files.push_back(*iter);
632 }
633 }
634 }
635 }
636
637 return files;
638}
639
640
641/**
642 * Loads the code compressor plugin from the given file and prints its
643 * description to the given stream.
644 *
645 * @param fileName The code compressor plugin file.
646 * @param stream The output stream.
647 * @exception FileNotFound If the given file is not found from the search
648 * paths of code compressor plugins.
649 * @exception DynamicLibraryException If the dynamic library cannot be
650 * opened.
651 */
652void
654 const std::string& fileName, std::ostream& stream) {
655 PluginTools pluginTool;
657 fileName, pluginTool);
659 delete compressor;
660}
661
662/**
663 * Creates the code compressor from the given dynamic module.
664 *
665 * @param fileName Name of the file.
666 * @param pluginTool The plugin tool to use.
667 * @return The newly created code compressor plugin.
668 * @exception FileNotFound If the given file is not found from the search
669 * paths of code compressor plugins.
670 * @exception DynamicLibraryException If the dynamic library cannot be
671 * opened.
672 */
675 const std::string& fileName, PluginTools& pluginTool) {
676 vector<string> searchPaths = Environment::codeCompressorPaths();
677 for (vector<string>::const_iterator iter = searchPaths.begin();
678 iter != searchPaths.end(); iter++) {
679 if (FileSystem::fileExists(*iter)) {
680 pluginTool.addSearchPath(*iter);
681 }
682 }
683
684 pluginTool.registerModule(fileName);
685 CodeCompressorPlugin* (*pluginCreator)();
686 pluginTool.importSymbol(
687 "create_code_compressor", pluginCreator, fileName);
688
689 return pluginCreator();
690}
691
692/**
693 * Returns an InstructionElement that is relocation target of the data in
694 * data section at the given offset. Returns NULL if the data doesn't need
695 * to be altered.
696 *
697 * @param dataSection The data section,
698 * @param dataSectionOffset The offset.
699 * @return The InstructionElement or NULL.
700 */
703 const TPEF::Binary& program,
704 const TPEF::DataSection& dataSection,
705 Word dataSectionOffset) const {
706
707 // find the correct reloc section
708 for (unsigned int i = 0; i < program.sectionCount(Section::ST_RELOC);
709 i++) {
710 RelocSection* section = dynamic_cast<RelocSection*>(
711 program.section(Section::ST_RELOC, i));
712 assert(section != NULL);
713 if (section->referencedSection() == &dataSection) {
714 // correct reloc section found
715 Word elemCount = section->elementCount();
716 for (Word elemIndex = 0; elemIndex < elemCount; elemIndex++) {
717 RelocElement* relocElem = dynamic_cast<RelocElement*>(
718 section->element(elemIndex));
719 assert(relocElem != NULL);
720 Chunk* location = dynamic_cast<Chunk*>(
721 relocElem->location());
722 assert(location != NULL);
723 if (location->offset() == dataSectionOffset) {
724 InstructionElement* destination =
725 dynamic_cast<InstructionElement*>(
726 relocElem->destination());
727 if (destination != NULL) {
728 return destination;
729 } else {
730 return NULL;
731 }
732 }
733 }
734 }
735 }
736
737 return NULL;
738}
739
740/**
741 * Asks the instruction memory mau width from code compressor plugin and
742 * returns it
743 *
744 * @return instruction memory mau width
745 */
746int
751
752
753void
754ProgramImageGenerator::setEntityName(const std::string& entity) {
755
756 entityName_ = entity;
757}
758
759void
763
765 "Data-start option is used "
766 "to set the global data start address for the address spaces. "
767 "The default is the first address of the address space. "
768 "data-start option must either be just the start "
769 "of the default address space (a single unsigned integer), "
770 "or a list consisting of pairs: "
771 "<Address-Space Name>,<Address-Space Start>");
772
773bool
774ProgramImageGenerator::isDataStartSet(std::string aSpace) const {
776 assert(opts);
777 if (opts->isDefined()) {
778 int size = opts->listSize();
779 if (size == 1) {
780 return true;
781 }
782 if (size % 2 != 0) {
783 abortWithError("ERROR: " + DATA_START_DESC);
784 }
785 for (int i = 1; i <= size; i += 2) {
786 TCEString as_name = opts->String(i);
787 if (as_name == aSpace) {
788 return true;
789 }
790 }
791 }
792 return false;
793}
794
795uint64_t
798 assert(opts);
799 if (opts->isDefined()) {
800 int size = opts->listSize();
801 if (size == 1) {
802 return Conversion::toUnsignedLong(opts->String(1));
803 }
804 if (size % 2 != 0) {
805 abortWithError("ERROR: " + DATA_START_DESC);
806 }
807 for (int i = 1; i <= size; i += 2) {
808 TCEString as_name = opts->String(i);
809 if (as_name == aSpace) {
810 return Conversion::toUnsignedLong(opts->String(i + 1));
811 }
812 }
813 }
814 abortWithError("ERROR: " + DATA_START_DESC);
815}
#define __func__
#define abortWithError(message)
#define assert(condition)
UInt32 AddressImage
Type for storing addresses to memory image.
Definition BaseType.hh:179
unsigned char Byte
Definition BaseType.hh:116
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the program
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
static int verboseLevel()
static std::ostream & logStream()
virtual int width(const TCEString &templateName) const
virtual void writeImage(std::ostream &stream) const =0
void pushBack(long long unsigned int integer, int size)
Definition BitVector.cc:94
virtual int listSize() const
virtual std::string String(int index=0) const
void setBEM(const BinaryEncoding &bem)
void setParameters(ParameterTable parameters)
void setPrograms(std::map< std::string, TPEF::Binary * > &programs)
const TTAMachine::Machine & machine() const
TTAProgram::Program & currentProgram() const
virtual InstructionBitVector * compress(const std::string &program)=0
unsigned int memoryAddress(const TTAProgram::Instruction &instruction) const
const BinaryEncoding & binaryEncoding() const
void setMachine(const TTAMachine::Machine &machine)
virtual void printDescription(std::ostream &stream)=0
virtual void generateDecompressor(std::ostream &stream, TCEString entityStr)=0
std::vector< Parameter > ParameterTable
Table for passing plugin parameters.
static ULongWord toUnsignedLong(const T &source)
static std::vector< std::string > codeCompressorPaths(bool libraryPathsOnly=false)
std::string errorMessage() const
Definition Exception.cc:123
static std::vector< std::string > directoryContents(const std::string &directory, const bool absolutePaths=true)
static std::string fileExtension(const std::string &fileName)
static bool fileIsDirectory(const std::string fileName)
static bool fileExists(const std::string fileName)
void importSymbol(const std::string &symbolName, T *&target, const std::string &module)
void addSearchPath(const std::string &searchPath)
void registerModule(const std::string &module)
TPEF::InstructionElement * relocTarget(const TPEF::Binary &program, const TPEF::DataSection &dataSection, Word dataSectionOffset) const
static CodeCompressorPlugin * createCompressor(const std::string &fileName, PluginTools &pluginTool)
bool isDataStartSet(std::string aSpace) const
std::string entityName_
Toplevel entity name.
void loadPrograms(TPEFMap programs)
void setDataStartOptions(CmdLineOptionParser *options)
static std::vector< std::string > availableCompressors()
CodeCompressorPlugin * compressor_
The code compressor.
void writeDataSection(TPEF::Binary &program, BitVector &bitVector, const std::string &addressSpace, TPEF::Section &section)
CmdLineOptionParser * dataStartOptions_
uint64_t dataStartAddress(std::string aSpace) const
std::map< std::string, TPEF::Binary * > TPEFMap
void generateDataImage(const std::string &programName, TPEF::Binary &program, const std::string &addressSpace, std::ostream &stream, OutputFormat format, int mausPerLine, bool usePregeneratedImage)
void setEntityName(const std::string &entity)
void loadCompressorPlugin(const std::string &fileName)
void loadCompressorParameters(CodeCompressorPlugin::ParameterTable parameters)
static const std::string DATA_START_DESC
OutputFormat
Different output formats of images.
@ BINARY
Real binary format.
@ VHDL
Array as a Vhdl package.
@ BIN2N
Binary format padded to 2**n.
@ MIF
MIF Memory Initialization File.
@ ARRAY
ASCII 1's and 0's in array form.
@ COE
COE memory initialization format.
@ HEX
HEX memory initialization format.
static void printCompressorDescription(const std::string &fileName, std::ostream &stream)
void generateProgramImage(const std::string &programName, std::ostream &stream, OutputFormat format, int mausPerLine=0)
void generateDecompressor(std::ostream &stream, TCEString entityStr)
void loadMachine(const TTAMachine::Machine &machine)
PluginTools pluginTool_
The plugin tool.
CodeCompressorPlugin & compressor()
void loadBEM(const BinaryEncoding &bem)
SIntWord sIntWordValue() const
Definition SimValue.cc:944
Chunk * name() const
SectionOffset offset() const
Word indexOfInstruction(const InstructionElement &elem) const
virtual Word length() const
virtual Byte byte(const Chunk *chunk) const
SectionElement * destination() const
SectionElement * location() const
Section * referencedSection() const
AddressImage startingAddress() const
@ ST_DATA
Initialized data section.
Definition Section.hh:80
@ ST_LEDATA
Initialized little endian data section.
Definition Section.hh:82
@ ST_CODE
Text section.
Definition Section.hh:79
@ ST_RELOC
Relocation section.
Definition Section.hh:74
SectionElement * element(Word index) const
Word elementCount() const
ASpaceElement * aSpace() const
std::string chunk2String(const Chunk *chunk) const
virtual int width() const
virtual AddressSpace * addressSpace() const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
bool isLittleEndian() const
Definition Machine.hh:258
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
TerminalImmediate & value() const
Definition Immediate.cc:103
Immediate & immediate(int i) const
Terminal & source() const
Definition Move.cc:302
std::vector< Instruction * > InstructionVector
Vector for instructions.
Definition Program.hh:66
const Move & moveAt(int number) const
Definition Program.cc:480
TTAMachine::Machine & targetProcessor() const
Definition Program.cc:202
int moveCount() const
Definition Program.cc:494
Instruction & instructionAt(InstructionAddress address) const
Definition Program.cc:374
int instructionCount() const
Definition Program.cc:1209
InstructionVector instructionVector() const
Definition Program.cc:1196
virtual SimValue value() const
virtual SimValue value() const
Definition Terminal.cc:178
virtual bool isAddress() const
Definition Terminal.cc:75
virtual bool isInstructionAddress() const
Definition Terminal.cc:87
virtual bool isImmediate() const
Definition Terminal.cc:63