OpenASIP 2.2
Loading...
Searching...
No Matches
CodeCompressorPlugin.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file CodeCompressorPlugin.cc
26 *
27 * Implementation of CodeCompressorPlugin class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @author Otto Esko 2008 (otto.esko-no.spam-tut.fi)
31 * @note rating: red
32 */
33
34#include <string>
35#include <boost/format.hpp>
36
39#include "PIGTextGenerator.hh"
40
41#include "BinaryEncoding.hh"
43#include "MoveSlot.hh"
44#include "ImmediateSlotField.hh"
46#include "SourceField.hh"
47#include "DestinationField.hh"
48#include "GuardField.hh"
51#include "GPRGuardEncoding.hh"
52#include "SocketEncoding.hh"
53#include "SocketCodeTable.hh"
54#include "IUPortCode.hh"
55#include "RFPortCode.hh"
56#include "FUPortCode.hh"
58#include "NullNOPEncoding.hh"
60
61#include "Machine.hh"
62#include "ControlUnit.hh"
63#include "Guard.hh"
64#include "FUPort.hh"
65#include "HWOperation.hh"
66
67#include "CodeSection.hh"
68#include "RelocSection.hh"
69#include "Binary.hh"
70#include "ImmediateElement.hh"
71#include "MoveElement.hh"
72#include "RelocElement.hh"
73#include "ResourceSection.hh"
74#include "TPEFTools.hh"
75
76#include "TPEFProgramFactory.hh"
77#include "NullInstruction.hh"
78#include "Immediate.hh"
79#include "TerminalFUPort.hh"
80#include "TerminalImmediate.hh"
81#include "Move.hh"
82#include "MoveGuard.hh"
83#include "TCEString.hh"
84#include "Program.hh"
85#include "Procedure.hh"
86#include "Operation.hh"
87
88#include "tce_config.h"
89#include "MathTools.hh"
90
91using std::string;
92using std::vector;
93using std::pair;
94using std::map;
95using boost::format;
96
97using namespace TTAMachine;
98using namespace TPEF;
99using namespace TTAProgram;
100
101/**
102 * The constructor.
103 */
105 tpefPrograms_(), currentTPEF_(NULL), currentPOM_(NULL),
106 currentProgram_(), bem_(NULL), machine_(NULL),
107 parameters_(), programBits_(NULL), allStartsAtBeginningOfMAU_(false),
108 mau_(0), addressSpaceOffset_(0), instructionsAtBeginningOfMAU_(),
109 immediatesToRelocate_(), terminalsToRelocate_(), relocMap_(),
110 indexTable_(), instructionAddresses_() {
111}
112
113
114/**
115 * The destructor.
116 */
118 if (currentPOM_ != NULL) {
119 delete currentPOM_;
120 }
121 if (programBits_ != NULL) {
122 delete programBits_;
123 }
124}
125
126
127/**
128 * Sets the plugin parameters.
129 *
130 * @param parameters The parameters.
131 */
132void
136
137
138/**
139 * Sets the programs to be executed in the machine.
140 *
141 * @param program Map of programs.
142 */
143void
145 std::map<std::string, TPEF::Binary*>& programs) {
146 tpefPrograms_ = programs;
147}
148
149
150/**
151 * Sets the machine.
152 *
153 * Machine must be set before generating the program image.
154 * BEM must be set before calling this
155 *
156 * @param machine The machine.
157 * @exception InvalidData If the machine does not have control unit.
158 * @exception InvalidData If bem is not set
159 */
160void
163 if (gcu == NULL) {
164 string errorMsg = "The machine does not have GCU.";
165 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
166 }
167 machine_ = &machine;
168 AddressSpace* iMem = gcu->addressSpace();
169 if (bem_ == NULL) {
170 string errorMsg = "Bem not set!";
171 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
172 }
173 mau_ = bem_->width();
174 // For RISCV fix mau to 4
175 if (machine.isRISCVMachine()) {
176 mau_ = 8;
177 setImemWidth(8);
178 // fix machines imem width if adf has wrong value
179 } else if (mau_ != iMem->width()) {
181 }
182 addressSpaceOffset_ = iMem->start();
183}
184
185
186/**
187 * Sets the binary encoding map.
188 *
189 * @param bem The BEM.
190 */
191void
193 bem_ = &bem;
194}
195
196
197/**
198 * Returns the bit image of the program encoded as the BEM determines.
199 *
200 * @param program The program.
201 * @return The program image.
202 * @exception InvalidData If the BEM is erroneous.
203 */
206 relocMap_.clear();
207 indexTable_.clear();
208
210 for (int i = 0; i < program.procedureCount(); i++) {
211 Procedure& p = program.procedure(i);
212 for (int j = 0; j < p.instructionCount(); j++) {
213 Instruction& instruction = p.instructionAtIndex(j);
214 InstructionBitVector* bits = bemInstructionBits(instruction);
215 assert(bits->size() == static_cast<size_t>(bem_->width()));
216 imageBits->pushBack(*bits);
217 }
218 }
219 return imageBits;
220}
221
222/**
223 * Returns the number of move slots
224 *
225 */
229
230/**
231 * Returns the width of the move slot in the given index
232 *
233 * @param index Index of move slot
234 */
236 return bem_->moveSlot(index).width();
237}
238
239/**
240 * Returns the index of first move slot defined in bem
241 */
243 int moveSlotIndex = 0;
245 moveSlotIndex = bem_->immediateControlField().width();
246 for (int i = 0; i < bem_->longImmDstRegisterFieldCount(); i++) {
247 moveSlotIndex += bem_->longImmDstRegisterField(i).width();
248 }
249 }
250 return moveSlotIndex;
251}
252
253/**
254 * Tells the memory address of the given instruction.
255 *
256 * @param instruction The instruction.
257 * @return The memory address.
258 * @exception InstanceNotFound If the program does not contain the given
259 * instruction.
260 */
261unsigned int
263 const TTAProgram::Instruction& instruction) const {
264 if (!MapTools::containsKey(instructionAddresses_, &instruction)) {
265 const string procName = "CodeCompressorPlugin::memoryAddress";
266 throw InstanceNotFound(__FILE__, __LINE__, procName);
267 } else {
269 instructionAddresses_, &instruction);
270 }
271}
272
273/**
274 * Returns the binary encoding map.
275 *
276 * @return The binary encoding map.
277 * @exception NotAvailable If the BEM is not set.
278 */
279const BinaryEncoding&
281 if (bem_ == NULL) {
282 throw NotAvailable(__FILE__, __LINE__, __func__);
283 }
284
285 return *bem_;
286}
287
288/**
289 * Returns the program (POM) being processed currently.
290 *
291 * @return The program.
292 * @exception NotAvailable If there is no program being processed.
293 */
296 if (currentPOM_ == NULL) {
297 throw NotAvailable(__FILE__, __LINE__, __func__);
298 }
299
300 return *currentPOM_;
301}
302
303/**
304 * Returns the machine.
305 *
306 * @return The machine.
307 * @exception NotAvailable If the machine is not set.
308 */
309const Machine&
311 if (machine_ == NULL) {
312 throw NotAvailable(__FILE__, __LINE__, __func__);
313 }
314
315 return *machine_;
316}
317
318/**
319 * Starts generating new program image.
320 *
321 * This function must be called always before starting to add instructions
322 * to the program image.
323 *
324 * @param programName The program of which to generate the image.
325 * @exception InvalidData If the program object model cannot be created.
326 */
327void
328CodeCompressorPlugin::startNewProgram(const string& programName) {
329 if (programBits_ != NULL) {
330 delete programBits_;
331 programBits_ = NULL;
332 }
333
334 if (tpefPrograms_.find(programName) == tpefPrograms_.end()) {
335 string errorMsg = "Program " + programName + " not found from "
336 + "compressor plugin";
337 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
338 }
339
340 TPEF::Binary* program = tpefPrograms_.find(programName)->second;
341
342 if (program == NULL) {
343 string errorMsg = "Program bits for program " + programName
344 + " not found";
345 throw InvalidData(__FILE__, __LINE__, __func__, errorMsg);
346 }
347
350
351 if (currentPOM_ != NULL) {
352 delete currentPOM_;
353 currentPOM_ = NULL;
354 }
355
357 try {
358 currentPOM_ = factory.build();
359 } catch (const Exception& e) {
360 throw InvalidData(__FILE__, __LINE__, __func__, e.errorMessage());
361 }
362
363 // clear previous relocations
364 if (immediatesToRelocate_.size() != 0) {
365 immediatesToRelocate_.clear();
366 }
367 if (terminalsToRelocate_.size() != 0) {
368 terminalsToRelocate_.clear();
369 }
371}
372
373/**
374 * Adds the given instruction to the program.
375 *
376 * @param instruction The instruction.
377 * @param bits The bits that models the instruction.
378 * @exception InvalidData If new program is not started by startNewProgram.
379 * @exception OutOfRange If some immediate would become too large to fit
380 * in its space due to the address of the instruction
381 * being added.
382 */
383void
385 const Instruction& instruction, InstructionBitVector* bits) {
386 if (programBits_ == NULL) {
387 throw InvalidData(__FILE__, __LINE__, __func__);
388 }
389
390 unsigned int firstFree = programBits_->size();
391 unsigned int instructionPosition = firstFree;
392
393 if (startsAtBeginningOfMAU(instruction)) {
394 instructionPosition = nextAddressablePositionFrom(firstFree);
395 }
396
397 // fill the memory from last instruction to this instruction with 0's
398 for (unsigned int i = firstFree; i < instructionPosition; i++) {
399 programBits_->push_back(false);
400 }
401
402 // add the instruction bits
403 programBits_->pushBack(*bits);
404 delete bits;
405
406 // mark the instruction starting point
407 programBits_->markInstructionStartingPoint(instructionPosition);
408
409 unsigned int memoryAddress = addressSpaceOffset_ +
410 (instructionPosition / mau_);
413 std::pair<const Instruction*, unsigned int>(
414 &instruction, memoryAddress));
415}
416
417/**
418 * Sets the given instruction to start at the beginning of MAU.
419 *
420 * This method must be called before the instruction is added to the bit
421 * vector.
422 *
423 * @param instruction The instruction.
424 */
425void
431
432
433/**
434 * Sets all instructions to start at the beginning of MAU.
435 *
436 * This method must be called before any instructions are added to the bit
437 * vector.
438 */
439void
443
444
445/**
446 * Returns bit vector that represents the given instruction as the BEM
447 * determines.
448 *
449 * @param instruction The instruction.
450 * @return The newly created bit vector containing the instruction bits.
451 * @exception InvalidData If the BEM is erroneous.
452 */
455 const TTAProgram::Instruction& instruction) {
456 if (bem_ == NULL) {
457 throw InvalidData(__FILE__, __LINE__, __func__);
458 }
459
460 InstructionBitVector* instructionBits = new InstructionBitVector();
461
462 // insert the bits to the vector
463 for (int i = binaryEncoding().childFieldCount() - 1; i >= 0; i--) {
465 ImmediateControlField* icField =
466 dynamic_cast<ImmediateControlField*>(&field);
467 MoveSlot* moveSlot = dynamic_cast<MoveSlot*>(&field);
468 ImmediateSlotField* immField =
469 dynamic_cast<ImmediateSlotField*>(&field);
470 LImmDstRegisterField* dstRegField =
471 dynamic_cast<LImmDstRegisterField*>(&field);
472 unsigned int oldSize = instructionBits->size();
473 if (icField != NULL) {
475 *icField, instruction, *instructionBits);
476 assert(
477 instructionBits->size() - oldSize ==
478 static_cast<size_t>(icField->width()));
479 } else if (moveSlot != NULL) {
481 *moveSlot, instruction, *instructionBits);
482 assert(
483 instructionBits->size() - oldSize ==
484 static_cast<size_t>(moveSlot->width()));
485 } else if (immField != NULL) {
487 *immField, instruction, *instructionBits);
488 assert(instructionBits->size() - oldSize ==
489 static_cast<size_t>(immField->width()));
490 } else if (dstRegField != NULL) {
492 *dstRegField, instruction, *instructionBits);
493 assert(
494 instructionBits->size() - oldSize ==
495 static_cast<size_t>(dstRegField->width()));
496 } else {
497 assert(false);
498 }
499 }
500
501 // mark the instruction references to the bit vector
502 for (RelocMap::const_iterator iter = relocMap_.begin();
503 iter != relocMap_.end(); iter++) {
504 const Immediate* immediate = (*iter).first;
505 const Instruction* instruction = (*iter).second;
507 vector<IndexBound> indexes = MapTools::valueForKey<
508 vector<IndexBound> >(indexTable_, immediate);
509 instructionBits->startSettingInstructionReference(*instruction);
510 for (vector<IndexBound>::const_iterator iter = indexes.begin();
511 iter != indexes.end(); iter++) {
512 instructionBits->addIndexBoundsForReference(*iter);
513 }
514 }
515
516 relocMap_.clear();
517 indexTable_.clear();
518
519 return instructionBits;
520}
521
522/**
523 * Returns the bits of the program constructed by calling addInstruction
524 * method several times.
525 *
526 * This method creates a copy of the constructed bit vector and add
527 * extra bits to the end to make sure the length of the vector is
528 * divisible by MAU.
529 *
530 * @return The program bits.
531 */
534
536
537 // add extra bits to the end if the length of program image is not
538 // divisible by MAU
539 int bitCount = mau_ - (bits->size() % mau_);
540 if (bitCount == mau_) {
541 bitCount = 0;
542 }
543 for (int i = 0; i < bitCount; i++) {
544 bits->push_back(false);
545 }
546
547 return bits;
548}
549
550
551/**
552 * Tells whether the plugin has the given parameter defined.
553 *
554 * @param paramName Name of the parameter.
555 * @return True if the given parameter is defined, otherwise false.
556 */
557bool
558CodeCompressorPlugin::hasParameter(const std::string& paramName) const {
559 for (ParameterTable::const_iterator iter = parameters_.begin();
560 iter != parameters_.end(); iter++) {
561 Parameter param = *iter;
562 if (param.name == paramName) {
563 return true;
564 }
565 }
566 return false;
567}
568
569
570/**
571 * Returns the value of the given parameter.
572 *
573 * @param paramName Name of the parameter.
574 * @return The value.
575 * @exception NotAvailable If the given parameter is not defined.
576 */
577std::string
578CodeCompressorPlugin::parameterValue(const std::string& paramName) const {
579 for (ParameterTable::const_iterator iter = parameters_.begin();
580 iter != parameters_.end(); iter++) {
581 Parameter param = *iter;
582 if (param.name == paramName) {
583 return param.value;
584 }
585 }
586
587 throw NotAvailable(__FILE__, __LINE__, __func__);
588}
589
590/**
591 * Returns the mau of instruction memory.
592 *
593 * Before compression this is the
594 * original width and after compression it returns the compressed instruction
595 * width
596 *
597 * @return mau width
598 */
599int
601 return mau_;
602}
603
604
605/**
606 * Sets the imem width to the given mau * widthInMaus and mau to given mau
607 *
608 * @param mau Mau of instruction memory
609 * @param widthInMaus Memory width in maus (default = 1)
610 */
611void
612CodeCompressorPlugin::setImemWidth(int mau, int widthInMaus) {
613 machine_->controlUnit()->addressSpace()->setWidth(mau*widthInMaus);
614 mau_ = mau;
615}
616
617/**
618 * Returns the number of programs to be compressed
619 *
620 * @return number of programs
621 */
622int
626
627/**
628 * Returns a const iterator to program map element at the given index
629 *
630 * @return const iterator to program map element
631 * @exception OutOfRange If index is out of range
632 */
633CodeCompressorPlugin::TPEFMap::const_iterator
635 if (index >= static_cast<int>(tpefPrograms_.size())) {
636 string errorMsg("Tried to overindex program map");
637 throw OutOfRange(__FILE__, __LINE__, __func__, errorMsg);
638 }
639 TPEFMap::const_iterator iter = tpefPrograms_.begin();
640 for (int i = 0; i < index; i++) {
641 iter++;
642 }
643 return iter;
644}
645
646/**
647 * Returns the indentation string of the given level.
648 *
649 * @param level The indentation level.
650 */
651std::string
653 string ind;
654 for (int i = 0; i < level; i++) {
655 ind += " ";
656 }
657 return ind;
658}
659
660/**
661 * Adds bits for immediate control field to the given bit vector.
662 *
663 * @param icField The immediate control field that determines the encoding.
664 * @param instruction The instruction that is being encoded.
665 * @param bitVector The bit vector to which the bits are added.
666 * @exception InvalidData If the BEM or machine is erroneous.
667 */
668void
670 const ImmediateControlField& icField,
671 const TTAProgram::Instruction& instruction, BitVector& bitVector) const {
672 string instructionTemplate("");
673
674 // find the instruction template of the instruction
675 try {
677 this->instructionTemplate(instruction);
678 } catch (const InstanceNotFound& exception) {
679 throw InvalidData(
680 __FILE__, __LINE__, __func__, exception.errorMessage());
681 }
682
683 // get the encoding
684 int encoding(0);
685 try {
686 encoding = icField.templateEncoding(instructionTemplate);
687 } catch (const InstanceNotFound& exception) {
688 PIGTextGenerator textGenerator;
689 format text = textGenerator.text(
691 text % instructionTemplate;
692 const string procName = "CodeCompressorPlugin::addBitsForICField";
693 throw InvalidData(__FILE__, __LINE__, procName, text.str());
694 }
695
696 // add the encoding
697 bitVector.pushBack(encoding, icField.width());
698}
699
700/**
701 * Adds bits for a move slot to the given bit vector.
702 *
703 * @param slot The move slot that determines the encoding.
704 * @param instruction The instruction that is being encoded.
705 * @param bitVector The bit vector to which the bits are added.
706 * @exception InvalidData If the BEM is erroneous.
707 */
708void
710 const MoveSlot& slot, const TTAProgram::Instruction& instruction,
711 InstructionBitVector& bitVector) {
712 // find the correct bus from the machine
713 string busName = slot.name();
715 if (!busNav.hasItem(busName)) {
716 PIGTextGenerator textGenerator;
717 format text = textGenerator.text(
719 text % busName;
720 const string procName = "CodeCompressorPlugin::addBitsForMoveSlot";
721 throw InvalidData(__FILE__, __LINE__, procName, text.str());
722 }
723
724 Bus* bus = busNav.item(busName);
725
726 // get the correct instruction template
727 string instructionTemplate = "";
728 try {
730 instruction);
731 } catch (const InstanceNotFound& exception) {
732 if (machine().immediateUnitNavigator().count() == 0) {
733 // if no immediate units, no instruction templates either
734 unsigned int oldSize = bitVector.size();
735 encodeMove(slot, instruction, bitVector);
736 assert(
737 bitVector.size() - oldSize ==
738 static_cast<size_t>(slot.width()));
739 return;
740 } else {
741 assert(false);
742 }
743 }
744
747 if (!itNav.hasItem(instructionTemplate)) {
748 assert(false);
749 }
750
751 // check whether there should be a long immediate on the move slot
753 if (iTemp->usesSlot(bus->name())) {
755 bus->name(), slot.width(), instruction, bitVector);
756 } else {
757 encodeMove(slot, instruction, bitVector);
758 }
759}
760
761/**
762 * Adds bits for a source field to the given bit vector.
763 *
764 * @param srcField The source field that determines the encoding rules.
765 * @param move The move that is being encoded.
766 * @param bitVector The bit vector to which the bits are added.
767 * @exception InvalidData If the BEM is erroneous.
768 */
769void
771 const SourceField& srcField, const TTAProgram::Move& move,
772 InstructionBitVector& bitVector) const {
773 unsigned int oldSize = bitVector.size();
774 assert(move.bus().name() == srcField.parent()->name());
775 Terminal& source = move.source();
776
777 if (source.isImmediateRegister()) {
778 encodeIUTerminal(srcField, source, bitVector);
779 } else if (source.isGPR()) {
780 encodeRFTerminal(srcField, source, bitVector);
781 } else if (source.isFUPort()) {
782 encodeFUTerminal(srcField, source, bitVector);
783 } else if (source.isImmediate()) {
784 encodeImmediateTerminal(srcField, source, bitVector);
785 }
786
787 assert(
788 bitVector.size() - oldSize == static_cast<size_t>(srcField.width()));
789}
790
791/**
792 * Adds bits for a destination field to the given bit vector.
793 *
794 * @param dstField The destination field that determines the encoding rules.
795 * @param move The move that is being encoded.
796 * @param bitVector The bit vector to which the bits are added.
797 * @exception InvalidData If the BEM is erroneous.
798 */
799void
801 const DestinationField& dstField, const TTAProgram::Move& move,
802 BitVector& bitVector) {
803 assert(move.bus().name() == dstField.parent()->name());
804 Terminal& destination = move.destination();
805
806 if (destination.isGPR()) {
807 encodeRFTerminal(dstField, destination, bitVector);
808 } else if (destination.isFUPort()) {
809 encodeFUTerminal(dstField, destination, bitVector);
810 } else {
811 assert(false);
812 }
813}
814
815/**
816 * Adds bits for a guard field to the given bit vector.
817 *
818 * @param guardField The guard field that determines the encoding rules.
819 * @param move The move that is being encoded.
820 * @param bitVector The bit vector to which the bits are added.
821 * @exception InvalidData If the BEM is erroneous.
822 */
823void
825 const GuardField& guardField, const TTAProgram::Move& move,
826 BitVector& bitVector) {
827 unsigned int encodingValue(0);
828 const string procName = "CodeCompressorPlugin::addBitsForGuardField";
829 string busName = guardField.parent()->name();
830
831 // find the correct encoding value
832 if (move.isUnconditional()) {
833 UnconditionalGuardEncoding& encoding = guardField.
834 unconditionalGuardEncoding(false);
835 if (&encoding == &NullUnconditionalGuardEncoding::instance()) {
836 PIGTextGenerator textGenerator;
837 format text = textGenerator.text(
839 text % busName;
840 throw InvalidData(__FILE__, __LINE__, procName, text.str());
841 }
842 encodingValue = encoding.encoding();
843
844 } else {
845 const Guard& guard = move.guard().guard();
846 const PortGuard* portGuard = dynamic_cast<const PortGuard*>(&guard);
847 const RegisterGuard* registerGuard =
848 dynamic_cast<const RegisterGuard*>(&guard);
849
850 if (portGuard != NULL) {
851 const Port& port = *portGuard->port();
852 string portName = port.name();
853 string fuName = port.parentUnit()->name();
854 FUGuardEncoding& encoding = guardField.fuGuardEncoding(
855 fuName, portName, guard.isInverted());
856 if (&encoding == &NullFUGuardEncoding::instance()) {
857 PIGTextGenerator textGenerator;
858 format text = textGenerator.text(
860 if (guard.isInverted()) {
861 text % "inverted" % portName % fuName;
862 } else {
863 text % "non-inverted" % portName % fuName;
864 }
865 throw InvalidData(
866 __FILE__, __LINE__, procName, text.str());
867 }
868 encodingValue = encoding.encoding();
869
870 } else if (registerGuard != NULL) {
871 string rfName = registerGuard->registerFile()->name();
872 int regIndex = registerGuard->registerIndex();
873 GPRGuardEncoding& encoding = guardField.gprGuardEncoding(
874 rfName, regIndex, guard.isInverted());
875 if (&encoding == &NullGPRGuardEncoding::instance()) {
876 PIGTextGenerator textGenerator;
877 format text = textGenerator.text(
879 if (guard.isInverted()) {
880 text % "inverted" % regIndex % rfName;
881 } else {
882 text % "non-inverted" % regIndex % rfName;
883 }
884 throw InvalidData(
885 __FILE__, __LINE__, procName, text.str());
886 }
887 encodingValue = encoding.encoding();
888
889 } else {
890 assert(false);
891 }
892 }
893
894 // push back the encoding value to the bit vector
895 unsigned int oldSize = bitVector.size();
896 bitVector.pushBack(encodingValue, guardField.width());
897 assert(
898 bitVector.size() - oldSize ==
899 static_cast<size_t>(guardField.width()));
900}
901
902/**
903 * Adds the immediate bits of the given immediate slot to the bit vector.
904 *
905 * @param immSlot The immediate slot.
906 * @param instruction The instruction that contains the immediate.
907 * @param bitVector The bit vector to which the bits are added.
908 * @exception InvalidData If the BEM is erroneous.
909 */
910void
912 const ImmediateSlotField& immSlot,
913 const TTAProgram::Instruction& instruction, BitVector& bitVector) {
914 // get the correct instruction template
915 string instructionTemplate = "";
916 try {
918 instruction);
919 } catch (const InstanceNotFound& exception) {
920 if (machine().immediateUnitNavigator().count() == 0) {
921 // if no immediate units, no instruction templates either
922 PIGTextGenerator textGenerator;
923 format text = textGenerator.text(
925 TXT_BEM_DEFINES_IMM_SLOT_THAT_IS_NEVER_USED);
926 const string procName =
927 "CodeCompressorPlugin::addBitsForImmediateSlot";
928 throw InvalidData(__FILE__, __LINE__, procName, text.str());
929 } else {
930 assert(false);
931 }
932 }
933
936 if (!itNav.hasItem(instructionTemplate)) {
937 assert(false);
938 }
939
940 // check whether there should be a long immediate on the immediate slot
942 if (iTemp->usesSlot(immSlot.name())) {
944 immSlot.name(), immSlot.width(), instruction, bitVector);
945 } else {
946 // fill the slot with zeros
947 bitVector.pushBack(0, immSlot.width());
948 }
949}
950
951/**
952 * Adds the bits of the given destination register field to the bit vector.
953 *
954 * @param field The long immediate destination register field.
955 * @param instruction The instruction.
956 * @param bitVector The bit vector to which the bits are added.
957 * @exception InvalidData If the instruction or BEM is erroneous.
958 */
959void
961 const LImmDstRegisterField& field,
962 const TTAProgram::Instruction& instruction, BitVector& bitVector) {
963 for (int i = 0; i < instruction.immediateCount(); i++) {
964 TTAProgram::Immediate& immediate = instruction.immediate(i);
965 const TTAProgram::Terminal& dstTerminal = immediate.destination();
966 const ImmediateUnit& dstIU = dstTerminal.immediateUnit();
967 if (dstIU.numberOfRegisters() == 1) {
968 continue;
969 }
970 string instructionTemplate = "";
971 try {
972 instructionTemplate = this->instructionTemplate(instruction);
973 } catch (const Exception& e) {
974 throw InvalidData(
975 __FILE__, __LINE__, __func__, e.errorMessage());
976 }
977
978 string iuName = field.immediateUnit(instructionTemplate);
979 if (dstIU.name() == iuName) {
980 bitVector.pushBack(dstTerminal.index(), field.width());
981 return;
982 }
983 }
984
985 // the field is not used by this instruction template
986 bitVector.pushBack(0, field.width());
987}
988
989/**
990 * Returns the name of the instruction template of the given instruction.
991 *
992 * @param instruction The instruction.
993 * @exception InstanceNotFound If the machine does not have such an
994 * instruction template.
995 */
996std::string
998 const TTAProgram::Instruction& instruction) const {
999 if (instruction.immediateCount() == 0) {
1002 for (int i = 0; i < itNav.count(); i++) {
1003 InstructionTemplate* iTemp = itNav.item(i);
1004 if (iTemp->isEmpty()) {
1005 return iTemp->name();
1006 }
1007 }
1008 const string procName = "CodeCompressorPlugin::instructionTemplate";
1009 PIGTextGenerator textGen;
1010 format text = textGen.text(PIGTextGenerator::TXT_EMPTY_ITEMP_MISSING);
1011 throw InstanceNotFound(__FILE__, __LINE__, procName, text.str());
1012 } else {
1013 return instruction.instructionTemplate().name();
1014 }
1015}
1016
1017/**
1018 * Tells whether the given instruction starts at the beginning of MAU.
1019 *
1020 * @param instruction The instruction.
1021 * @return True if the instruction start at the beginning of MAU, otherwise
1022 * false.
1023 */
1024bool
1026 const TTAProgram::Instruction& instruction) const {
1027
1029 return true;
1030 } else {
1032 instructionsAtBeginningOfMAU_, &instruction);
1033 }
1034}
1035
1036
1037/**
1038 * Returns the next addressable position in the bit vector calculated from
1039 * the given position.
1040 *
1041 * @param position The position.
1042 * @return The next addressable position.
1043 */
1044unsigned int
1046 unsigned int position) const {
1047
1048 if (position % mau_ == 0) {
1049 return position;
1050 } else {
1051 return position + mau_ - (position % mau_);
1052 }
1053}
1054
1055
1056/**
1057 * Encodes the instruction's long immediate bits that belong to the
1058 * given (move or immediate) slot to the bit vector.
1059 *
1060 * @param slotName Name of the slot.
1061 * @param width Bit width of the slot.
1062 * @param instruction The instruction that is being encoded.
1063 * @param bitVector The bit vector to which the bits are added.
1064 */
1065void
1067 const std::string& slotName,
1068 int slotWidth,
1069 const TTAProgram::Instruction& instruction,
1070 BitVector& bitVector) {
1071
1072 // find the correct immediate from the instruction
1073 for (int i = 0; i < instruction.immediateCount(); i++) {
1074 Immediate& imm = instruction.immediate(i);
1075 const InstructionTemplate& iTemp = instruction.instructionTemplate();
1076
1077 if (iTemp.usesSlot(slotName)) {
1078 // correct immediate
1079 ImmediateUnit* dstUnit = iTemp.destinationOfSlot(slotName);
1080
1081 // find the correct boundary of the long immediate which is to
1082 // be encoded in the given (immediate or move) slot
1083 int rightmostBitToEncode = 0;
1084 for (int i = iTemp.numberOfSlots(*dstUnit) - 1; i >= 0; i--) {
1085 string slotOfImm = iTemp.slotOfDestination(*dstUnit, i);
1086 if (slotOfImm != slotName) {
1087 rightmostBitToEncode += iTemp.supportedWidth(slotOfImm);
1088 } else {
1089 break;
1090 }
1091 }
1092 unsigned int limmSlotWidth = iTemp.supportedWidth(slotName);
1093 int leftmostBitToEncode =
1094 rightmostBitToEncode + limmSlotWidth - 1;
1095 assert(leftmostBitToEncode >= rightmostBitToEncode);
1096 assert(
1097 leftmostBitToEncode - rightmostBitToEncode < slotWidth);
1098
1099 // need to add zero bits to the move slot if the immediate
1100 // width is smaller than the width of the move slot
1101 int zerosToAdd = slotWidth - (
1102 leftmostBitToEncode - rightmostBitToEncode) - 1;
1103 assert(zerosToAdd >= 0);
1104 for (int i = 0; i < zerosToAdd; i++) {
1105 bitVector.push_back(false);
1106 }
1107
1108 // push back the immediate value
1109 UIntWord immediateValue = imm.value().value().uIntWordValue();
1110 addBits(
1111 immediateValue, leftmostBitToEncode, rightmostBitToEncode,
1112 bitVector);
1113
1114 // if the long immediate is address of an instruction, mark it
1115 // to relocMap_ and indexTable_
1117 Instruction& referenced = currentPOM_->instructionAt(
1118 immediateValue);
1119 unsigned int startIndex = bitVector.size() - slotWidth;
1120 unsigned int endIndex = bitVector.size() - 1;
1121 relocMap_.insert(
1122 pair<const Immediate*, const Instruction*>(
1123 &imm, &referenced));
1124 vector<IndexBound> indices;
1127 indexTable_, &imm);
1128 }
1129 IndexBound bounds(startIndex, endIndex, limmSlotWidth,
1130 leftmostBitToEncode, rightmostBitToEncode);
1131 indices.push_back(bounds);
1132 indexTable_[&imm] = indices;
1133 }
1134
1135 return;
1136 }
1137 }
1138 assert(false);
1139}
1140
1141
1142/**
1143 * Encodes a move to the given bit vector.
1144 *
1145 * @param slot The move slot that determines the encoding rules.
1146 * @param instruction The instruction that is being encoded.
1147 * @param bitVector The bit vector to which the bits are added.
1148 * @exception InvalidData If the BEM is erroneous.
1149 */
1150void
1152 const MoveSlot& slot, const TTAProgram::Instruction& instruction,
1153 InstructionBitVector& bitVector) const {
1154 string busName = slot.name();
1156 Bus* bus = busNav.item(busName);
1157
1158 for (int i = 0; i < instruction.moveCount(); i++) {
1159 Move& move = instruction.move(i);
1160 if (&move.bus() == bus) {
1161 // correct move
1162 SourceField& srcField = slot.sourceField();
1163 DestinationField& dstField = slot.destinationField();
1164 GuardField& guardField = slot.guardField();
1165 for (int i = slot.childFieldCount() - 1; i >= 0; i--) {
1166 InstructionField& childField = slot.childField(i);
1167 unsigned int oldSize = bitVector.size();
1168 if (dynamic_cast<GuardField*>(&childField) != NULL) {
1169 addBitsForGuardField(guardField, move, bitVector);
1170 assert(bitVector.size() - oldSize ==
1171 static_cast<size_t>(guardField.width()));
1172 } else if (dynamic_cast<SourceField*>(&childField) != NULL) {
1173 addBitsForSourceField(srcField, move, bitVector);
1174 assert(bitVector.size() - oldSize ==
1175 static_cast<size_t>(srcField.width()));
1176
1177 } else if (dynamic_cast<DestinationField*>(&childField) !=
1178 NULL) {
1179 addBitsForDestinationField(dstField, move, bitVector);
1180 assert(bitVector.size() - oldSize ==
1181 static_cast<size_t>(dstField.width()));
1182 } else {
1183 assert(false);
1184 }
1185 }
1186 return;
1187 }
1188 }
1189
1190 // no move on the bus
1191 unsigned int oldSize = bitVector.size();
1192 encodeNOP(slot, bitVector);
1193 assert(bitVector.size() - oldSize == static_cast<size_t>(slot.width()));
1194}
1195
1196/**
1197 * Encodes a NOP to the given bitVector.
1198 *
1199 * @param slot The move slot that determines the encoding rules.
1200 * @param bitVector The bit vector to which the bits are added.
1201 * @exception InvalidData If the BEM does not define encoding for NOP.
1202 */
1203void
1205 for (int i = slot.childFieldCount() - 1; i >= 0; i--) {
1206 InstructionField& childField = slot.childField(i);
1207 GuardField& guardField = slot.guardField();
1208 SourceField& srcField = slot.sourceField();
1209 DestinationField& dstField = slot.destinationField();
1210
1211 if (&guardField == &childField) {
1212 if ((!srcField.hasNoOperationEncoding() ||
1213 !dstField.hasNoOperationEncoding()) &&
1214 guardField.hasUnconditionalGuardEncoding(true)) {
1215 bitVector.pushBack(
1216 guardField.unconditionalGuardEncoding(true).encoding(),
1217 guardField.width());
1218 } else {
1219 bitVector.pushBack(0, guardField.width());
1220 }
1221
1222 } else if (&srcField == &childField) {
1223 if (srcField.width() == 0) {
1224 continue;
1225 }
1226
1227 NOPEncoding& encoding = srcField.noOperationEncoding();
1228 if (&encoding == &NullNOPEncoding::instance() &&
1229 !guardField.hasUnconditionalGuardEncoding(true)) {
1230 PIGTextGenerator textGenerator;
1231 format text = textGenerator.text(
1233 text % slot.name();
1234 const string procName = "CodeCompressorPlugin::encodeNOP";
1235 throw InvalidData(
1236 __FILE__, __LINE__, procName, text.str());
1237 }
1238 if (&encoding == &NullNOPEncoding::instance()) {
1239 bitVector.pushBack(0, srcField.width());
1240 } else {
1241 if (srcField.componentIDPosition() == BinaryEncoding::LEFT) {
1242 bitVector.pushBack(
1243 encoding.encoding(), encoding.width());
1244 bitVector.pushBack(
1245 0, srcField.width() - encoding.width());
1246 } else {
1247 bitVector.pushBack(
1248 encoding.encoding(), srcField.width());
1249 }
1250 }
1251
1252 } else if (&dstField == &childField) {
1253 if (dstField.width() == 0) {
1254 continue;
1255 }
1256 NOPEncoding& encoding = dstField.noOperationEncoding();
1257 if (&encoding == &NullNOPEncoding::instance() &&
1258 !guardField.hasUnconditionalGuardEncoding(true)) {
1259 PIGTextGenerator textGenerator;
1260 format text = textGenerator.text(
1262 text % slot.name();
1263 throw InvalidData(__FILE__, __LINE__, __func__, text.str());
1264 }
1265 if (&encoding == &NullNOPEncoding::instance()) {
1266 bitVector.pushBack(0, dstField.width());
1267 } else {
1268 if (dstField.componentIDPosition() == BinaryEncoding::LEFT) {
1269 bitVector.pushBack(encoding.encoding(), encoding.width());
1270 bitVector.pushBack(0, dstField.width() - encoding.width());
1271 } else {
1272 bitVector.pushBack(encoding.encoding(), dstField.width());
1273 }
1274 }
1275 }
1276 }
1277}
1278
1279/**
1280 * Encodes the immediate unit register terminal to the given bit vector.
1281 *
1282 * @param field The slot field that determines the encoding rules.
1283 * @param terminal The terminal to be encoded.
1284 * @param bitVector The bit vector to which the bits are added.
1285 * @exception InvalidData If the BEM is erroneous.
1286 */
1287void
1289 const SlotField& field, const TTAProgram::Terminal& terminal,
1290 BitVector& bitVector) {
1291 const string procName = "CodeCompressorPlugin::encodeIUTerminal";
1292 assert(terminal.isImmediateRegister());
1293 string iuName = terminal.immediateUnit().name();
1294 const Port& port = terminal.port();
1295 string socketName("");
1296
1297 // find the correct socket
1298 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1299 socketName = port.outputSocket()->name();
1300 } else if (dynamic_cast<const DestinationField*>(&field) != NULL) {
1301 socketName = port.inputSocket()->name();
1302 } else {
1303 assert(false);
1304 }
1305
1306 if (!field.hasSocketEncoding(socketName)) {
1307 PIGTextGenerator textGenerator;
1308 format text = textGenerator.text(
1310 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1311 text % socketName % "source" % field.parent()->name();
1312 } else {
1313 text % socketName % "destination" % field.parent()->name();
1314 }
1315 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1316 }
1317
1318 // create socket ID encoding
1319 SocketEncoding& socketID = field.socketEncoding(socketName);
1320 BitVector socketIDBits;
1321 socketIDBits.pushBack(socketID.encoding(), socketID.socketIDWidth());
1322
1323 // create socket code encoding
1325 if (socketID.hasSocketCodes()) {
1326 SocketCodeTable& socketCodes = socketID.socketCodes();
1327 if (!socketCodes.hasIUPortCode(iuName)) {
1328 PIGTextGenerator textGenerator;
1329 format text = textGenerator.text(
1331 text % iuName % socketName % field.parent()->name();
1332 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1333 }
1334
1335 IUPortCode& portCode = socketCodes.iuPortCode(iuName);
1336 unsigned int registerIndex = terminal.index();
1339 socketCodes, portCode, registerIndex));
1340 }
1341
1342 encodeSlotField(field, socketIDBits, socketCodeBits, bitVector);
1343}
1344
1345/**
1346 * Encodes the given register file terminal to the given bit vector.
1347 *
1348 * @param field The slot field that determines the encoding rules.
1349 * @param terminal The terminal to be encoded.
1350 * @param bitVector The bit vector to which the bits are added.
1351 * @exception InvalidData If the BEM is erroneous.
1352 */
1353void
1355 const SlotField& field, const TTAProgram::Terminal& terminal,
1356 BitVector& bitVector) {
1357 const string procName = "CodeCompressorPlugin::encodeRFTerminal";
1358 assert(terminal.isGPR());
1359 string rfName = terminal.registerFile().name();
1360 const Port& port = terminal.port();
1361 string socketName("");
1362
1363 // find the correct socket
1364 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1365 socketName = port.outputSocket()->name();
1366 } else if (dynamic_cast<const DestinationField*>(&field) != NULL) {
1367 socketName = port.inputSocket()->name();
1368 } else {
1369 assert(false);
1370 }
1371
1372 if (!field.hasSocketEncoding(socketName)) {
1373 PIGTextGenerator textGenerator;
1374 format text = textGenerator.text(
1376 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1377 text % socketName % "source" % field.parent()->name();
1378 } else {
1379 text % socketName % "destination" % field.parent()->name();
1380 }
1381 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1382 }
1383
1384 // create encoding for socket ID
1385 SocketEncoding& socketID = field.socketEncoding(socketName);
1386 BitVector socketIDBits;
1387 socketIDBits.pushBack(socketID.encoding(), socketID.socketIDWidth());
1388
1389 // create encoding for socket code
1391 if (socketID.hasSocketCodes()) {
1392 SocketCodeTable& socketCodes = socketID.socketCodes();
1393 if (!socketCodes.hasRFPortCode(rfName)) {
1394 PIGTextGenerator textGenerator;
1395 format text = textGenerator.text(
1397 text % rfName % socketName % field.parent()->name();
1398 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1399 }
1400 RFPortCode& portCode = socketCodes.rfPortCode(rfName);
1401 unsigned int registerIndex = terminal.index();
1403 socketCodes, portCode, registerIndex);
1404 }
1405
1406 encodeSlotField(field, socketIDBits, socketCodeBits, bitVector);
1407}
1408
1409/**
1410 * Encodes the given function unit terminal to the given bit vector.
1411 *
1412 * @param field The slot field that determines the encoding rules.
1413 * @param terminal The terminal to be encoded.
1414 * @param bitVector The bit vector to which the bits are added.
1415 * @exception InvalidData If the BEM is erroneous.
1416 */
1417void
1419 const SlotField& field, const TTAProgram::Terminal& terminal,
1420 BitVector& bitVector) {
1421 const string procName = "CodeCompressorPlugin::encodeFUTerminal";
1422 assert(terminal.isFUPort());
1423 string fuName = terminal.functionUnit().name();
1424 const Port& port = terminal.port();
1425 string socketName("");
1426
1427 // find the correct socket
1428 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1429 socketName = port.outputSocket()->name();
1430 } else if (dynamic_cast<const DestinationField*>(&field) != NULL) {
1431 socketName = port.inputSocket()->name();
1432 } else {
1433 assert(false);
1434 }
1435
1436 if (!field.hasSocketEncoding(socketName)) {
1437 PIGTextGenerator textGenerator;
1438 format text = textGenerator.text(
1440 if (dynamic_cast<const SourceField*>(&field) != NULL) {
1441 text % socketName % "source" % field.parent()->name();
1442 } else {
1443 text % socketName % "destination" % field.parent()->name();
1444 }
1445 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1446 }
1447
1448 // create encoding for socket ID
1449 SocketEncoding& socketID = field.socketEncoding(socketName);
1450 BitVector socketIDBits;
1451 socketIDBits.pushBack(socketID.encoding(), socketID.socketIDWidth());
1452
1453 // create encoding for socket code
1455 if (socketID.hasSocketCodes()) {
1456 SocketCodeTable& socketCodes = socketID.socketCodes();
1457 FUPortCode* portCode = NULL;
1458 if (terminal.isOpcodeSetting()) {
1459 if (&terminal.operation() == &NullOperation::instance()) {
1460 const TTAProgram::TerminalFUPort* fuTerm =
1461 dynamic_cast<const TerminalFUPort*>(&terminal);
1462 PIGTextGenerator textGenerator;
1463 format text = textGenerator.text(
1465 text % (fuTerm != NULL ? fuTerm->hwOperation()->name() : "") % fuName;
1466 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1467 }
1468 string opName = terminal.operation().name();
1469 if (!socketCodes.hasFUPortCode(fuName, port.name(), opName)) {
1470 PIGTextGenerator textGenerator;
1471 format text = textGenerator.text(
1473 text % fuName % opName;
1474 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1475 }
1476 portCode = &socketCodes.fuPortCode(fuName, port.name(), opName);
1477
1478 } else {
1479 if (!socketCodes.hasFUPortCode(fuName, port.name())) {
1480 PIGTextGenerator textGenerator;
1481 format text = textGenerator.text(
1483 text % port.name() % fuName % socketName;
1484 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1485 }
1486 portCode = &socketCodes.fuPortCode(fuName, port.name());
1487 }
1488 socketCodeBits.pushBack(portCode->encoding(), socketCodes.width());
1489 }
1490
1491 encodeSlotField(field, socketIDBits, socketCodeBits, bitVector);
1492}
1493
1494/**
1495 * Encodes the given immediate terminal to the given bit vector.
1496 *
1497 * @param field The source field which determines the encoding rules.
1498 * @param terminal The immediate terminal to be encoded.
1499 * @param bitVector The bit vector to which the bits are added.
1500 * @exception InvalidData If the BEM is erroneous.
1501 */
1502void
1504 const SourceField& field, const TTAProgram::Terminal& terminal,
1505 InstructionBitVector& bitVector) const {
1506 assert(terminal.isImmediate());
1507 unsigned int immValue = terminal.value().uIntWordValue();
1508 ImmediateEncoding& encoding = field.immediateEncoding();
1509
1510 if (&encoding == &NullImmediateEncoding::instance()) {
1511 PIGTextGenerator textGenerator;
1512 format text = textGenerator.text(
1514 text % field.parent()->name();
1515 const string procName =
1516 "CodeCompressorPlugin::encodeImmediateTerminal";
1517 throw InvalidData(__FILE__, __LINE__, procName, text.str());
1518 }
1519
1520 // create bits for the immediate value
1521 InstructionBitVector immediateBits;
1522 static_cast<BitVector&>(immediateBits).pushBack(
1523 immValue, field.width() - encoding.encodingWidth());
1525 Instruction& referenced = currentPOM_->instructionAt(immValue);
1526 assert(&referenced != &NullInstruction::instance());
1527 immediateBits.startSettingInstructionReference(referenced);
1528 IndexBound simmBound(0, (immediateBits.size()-1));
1529 immediateBits.addIndexBoundsForReference(simmBound);
1530 }
1531
1532 // encode the source field
1533 unsigned int oldSize = bitVector.size();
1535 static_cast<BitVector&>(bitVector).pushBack(
1536 encoding.encoding(), encoding.encodingWidth());
1537 bitVector.pushBack(immediateBits);
1538 } else {
1539 bitVector.pushBack(immediateBits);
1540 static_cast<BitVector&>(bitVector).pushBack(
1541 encoding.encoding(), encoding.encodingWidth());
1542 }
1543 assert(bitVector.size() - oldSize == static_cast<size_t>(field.width()));
1544}
1545
1546/**
1547 * Encodes the given source or destination field with the given bit vectors.
1548 *
1549 * @param field The source or destination field which determines the encoding
1550 * order of component ID bits and socket code bits.
1551 * @param componentIDBits The encoding for component ID.
1552 * @param socketCodeBits The encoding for socket code.
1553 * @param bitVector The bit vector to which the bits are added.
1554 */
1555void
1557 const SlotField& field,
1558 const BitVector& componentIDBits,
1559 const BitVector& socketCodeBits,
1560 BitVector& bitVector) {
1561
1562 unsigned int oldSize = bitVector.size();
1563 unsigned int numberOfZeros = field.width() - componentIDBits.size() -
1564 socketCodeBits.size();
1565
1567 bitVector.pushBack(componentIDBits);
1568 bitVector.pushBack(0, numberOfZeros);
1569 bitVector.pushBack(socketCodeBits);
1570 } else {
1571 bitVector.pushBack(socketCodeBits);
1572 bitVector.pushBack(0, numberOfZeros);
1573 bitVector.pushBack(componentIDBits);
1574 }
1575 assert(bitVector.size() - oldSize == static_cast<size_t>(field.width()));
1576}
1577
1578
1579/**
1580 * Creates a bit vector that encodes the given register file terminal.
1581 *
1582 * @param socketCodes The socket code table that contains the port codes.
1583 * @param portCode The port code that defines the encoding.
1584 * @param registerIndex The register index to be encoded.
1585 * @return Bit vector that contains encoding for the register file terminal.
1586 */
1589 const SocketCodeTable& socketCodes,
1590 const PortCode& portCode,
1591 unsigned int registerIndex) {
1592
1593 BitVector bits;
1594 unsigned int encodingWidth = portCode.width() - portCode.indexWidth();
1595 if (portCode.hasEncoding()) {
1596 bits.pushBack(portCode.encoding(), encodingWidth);
1597 }
1598 bits.pushBack(registerIndex, socketCodes.width() - encodingWidth);
1599 assert(bits.size() == static_cast<size_t>(socketCodes.width()));
1600 return bits;
1601}
1602
1603
1604/**
1605 * Initializes the immediatesToRelocate_ and terminalsToRelocate_ members.
1606 */
1607void
1609
1610 typedef std::set<const TPEF::SectionElement*> SectionElemSet;
1611 SectionElemSet toRelocate;
1612 RelocSection* relocSection = NULL;
1613
1614 // find the correct reloc section from tpef
1615 for (unsigned int sectionIndex = 0;
1617 sectionIndex++) {
1618 relocSection = dynamic_cast<RelocSection*>(
1619 currentTPEF_->section(Section::ST_RELOC, sectionIndex));
1620 Section* codeSection = currentTPEF_->section(Section::ST_CODE, 0);
1621 if (relocSection->referencedSection() == codeSection) {
1622 break;
1623 }
1624 }
1625
1626 if (relocSection == NULL) {
1627 return;
1628 }
1629
1630 // collect the section elements that are to be relocated to a set
1631 for (unsigned int i = 0; i < relocSection->elementCount(); i++) {
1632 RelocElement* element = dynamic_cast<RelocElement*>(
1633 relocSection->element(i));
1634 assert(element != NULL);
1635 SectionElement* location = element->location();
1636 SectionElement* destination = element->destination();
1637 assert(dynamic_cast<InstructionElement*>(location) != NULL);
1638 if (dynamic_cast<InstructionElement*>(destination) != NULL){
1639 toRelocate.insert(location);
1640 }
1641 }
1642
1643 // find the corresponding Immediates and Terminals from POM and add
1644 // them to immediatesToRelocate_ and terminalsToRelocate_ members
1645 CodeSection* codeSection = dynamic_cast<CodeSection*>(
1647 Instruction* instruction = &currentPOM_->firstInstruction();
1648 unsigned int instStart = 0;
1649 for (unsigned int i = 0; i < codeSection->elementCount(); i++) {
1650 InstructionElement* instructionElem =
1651 dynamic_cast<InstructionElement*>(codeSection->element(i));
1652 if (instructionElem->begin() && i > 0) {
1653 instruction = &currentPOM_->nextInstruction(*instruction);
1654 instStart = i;
1655 }
1656 if (AssocTools::containsKey(toRelocate, instructionElem)) {
1657 assert(instructionElem->isImmediate());
1658 ImmediateElement* immElem = dynamic_cast<ImmediateElement*>(
1659 instructionElem);
1660 Terminal* terminal = immediateTerminal(
1661 *codeSection, instStart, *immElem, *instruction);
1662 Immediate* immediate = programImmediate(*immElem, *instruction);
1663 if (terminal != NULL) {
1664 terminalsToRelocate_.insert(terminal);
1665 } else if (immediate != NULL) {
1666 immediatesToRelocate_.insert(immediate);
1667 } else {
1668 assert(false);
1669 }
1670 }
1671 }
1672}
1673
1674
1675/**
1676 * Adds the bits of the given number to the given bit vector.
1677 *
1678 * The bits added are determined by leftmostBit and rightmostBit parameters.
1679 *
1680 * @param number The number.
1681 * @param leftmost The leftmost bit of the number which is added to the bit
1682 * vector.
1683 * @param rightmost The rightmost bit of the number which is added to the
1684 * bit vector.
1685 * @param bitVector The bit vector to which the bits are added.
1686 */
1687void
1689 unsigned int number,
1690 int leftmostBit,
1691 int rightmostBit,
1692 BitVector& bitVector) {
1693
1694 for (int i = leftmostBit; i >= rightmostBit; i--) {
1695 bitVector.push_back(MathTools::bit(number, i));
1696 }
1697}
1698
1699
1700/**
1701 * Returns the immediate terminal that matches with the given
1702 * ImmediateElement instance.
1703 *
1704 * @param codeSection The code section that contains the immediate element.
1705 * @param elementIndex The index at which the instruction containing the
1706 * immediate element starts.
1707 * @param immElem The immediate element.
1708 * @param instruction The instruction that contains the immediate terminal.
1709 * @return The immediate terminal or NULL if there is no such terminal.
1710 */
1713 const TPEF::CodeSection& codeSection,
1714 unsigned int elementIndex,
1715 const TPEF::ImmediateElement& immElem,
1716 const TTAProgram::Instruction& instruction) const {
1717
1718 if (!immElem.isInline()) {
1719 return NULL;
1720 }
1721
1722 Byte busIndex = immElem.destinationIndex();
1723 string busName = "";
1724 for (unsigned int i = elementIndex; i < codeSection.elementCount();
1725 i++) {
1726 InstructionElement* element = dynamic_cast<InstructionElement*>(
1727 codeSection.element(i));
1728 if (element->begin() && i > elementIndex) {
1729 assert(false);
1730 }
1731 MoveElement* moveElem = dynamic_cast<MoveElement*>(element);
1732 if (moveElem != NULL &&
1733 moveElem->sourceType() == MoveElement::MF_IMM &&
1734 moveElem->sourceIndex() == busIndex) {
1735 busName = TPEFTools::resourceName(
1737 break;
1738 }
1739 }
1740
1741 assert(busName != "");
1742
1743 for (int i = 0; i < instruction.moveCount(); i++) {
1744 Move& move = instruction.move(i);
1745 if (move.bus().name() == busName) {
1746 return &move.source();
1747 }
1748 }
1749
1750 assert(false);
1751 return NULL;
1752}
1753
1754
1755/**
1756 * Returns the immediate in the given instruction that matches with the
1757 * given immediate element.
1758 *
1759 * @param immElem The immediate element.
1760 * @param instruction The instruction.
1761 * @return The immediate or NULL if there is no such an immediate.
1762 */
1765 const TPEF::ImmediateElement& immElem,
1766 const TTAProgram::Instruction& instruction) const {
1767
1768 if (immElem.isInline()) {
1769 return NULL;
1770 }
1771
1772 string dstUnitName = TPEFTools::resourceName(
1774
1775 for (int i = 0; i < instruction.immediateCount(); i++) {
1776 Immediate& immediate = instruction.immediate(i);
1777 const Terminal& dstTerminal = immediate.destination();
1778 assert(dstTerminal.isImmediateRegister());
1779 const ImmediateUnit& dstUnit = dstTerminal.immediateUnit();
1780 if (dstUnit.name() == dstUnitName) {
1781 return &immediate;
1782 }
1783 }
1784
1785 assert(false);
1786 return NULL;
1787}
#define __func__
#define assert(condition)
Word UIntWord
Definition BaseType.hh:144
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
find Finds info of the inner loops in the false
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
ImmediateControlField & immediateControlField() const
LImmDstRegisterField & longImmDstRegisterField(int index) const
int moveSlotCount() const
MoveSlot & moveSlot(int index) const
int longImmDstRegisterFieldCount() const
virtual int width(const TCEString &templateName) const
bool hasImmediateControlField() const
virtual InstructionField & childField(int position) const
void pushBack(long long unsigned int integer, int size)
Definition BitVector.cc:94
void encodeMove(const MoveSlot &slot, const TTAProgram::Instruction &instruction, InstructionBitVector &bitVector) const
void setBEM(const BinaryEncoding &bem)
static void encodeFUTerminal(const SlotField &field, const TTAProgram::Terminal &terminal, BitVector &bitVector)
IndexTable indexTable_
A table of indexes used when encoding long immediates.
void setParameters(ParameterTable parameters)
InstructionBitVector * bemBits(const TTAProgram::Program &program)
void setPrograms(std::map< std::string, TPEF::Binary * > &programs)
int addressSpaceOffset_
The offset of the instruction memory (the address of the first instruction).
void addBitsForDstRegisterField(const LImmDstRegisterField &field, const TTAProgram::Instruction &instruction, BitVector &bitVector)
const TTAMachine::Machine * machine_
The machine.
void setImemWidth(int mau, int widthInMaus=1)
InstructionSet instructionsAtBeginningOfMAU_
Set of instructions that start at the beginning of MAU.
void addBitsForSourceField(const SourceField &srcField, const TTAProgram::Move &move, InstructionBitVector &bitVector) const
void setInstructionToStartAtBeginningOfMAU(const TTAProgram::Instruction &instruction)
TPEFMap::const_iterator programElement(int index) const
void startNewProgram(const std::string &programName)
std::string instructionTemplate(const TTAProgram::Instruction &instruction) const
ImmediateSet immediatesToRelocate_
Set of (long) immediates that refer to an instruction.
int moveSlotWidth(int index) const
static void addBits(unsigned int number, int leftmostBit, int rightmostBit, BitVector &bitVector)
void addBitsForMoveSlot(const MoveSlot &slot, const TTAProgram::Instruction &instruction, InstructionBitVector &bitVector)
const TTAMachine::Machine & machine() const
static void addBitsForDestinationField(const DestinationField &dstField, const TTAProgram::Move &move, BitVector &bitVector)
void encodeLongImmediate(const std::string &slotName, int slotWidth, const TTAProgram::Instruction &instruction, BitVector &bitVector)
std::string indentation(int level)
void addInstruction(const TTAProgram::Instruction &instruction, InstructionBitVector *bits)
static BitVector socketCodeBits(const SocketCodeTable &socketCodes, const PortCode &portCode, unsigned int registerIndex)
TTAProgram::Program & currentProgram() const
TPEF::Binary * currentTPEF_
The current TPEF.
InstructionBitVector * programBits_
The bits of the program.
unsigned int memoryAddress(const TTAProgram::Instruction &instruction) const
std::string parameterValue(const std::string &paramName) const
const BinaryEncoding & binaryEncoding() const
void setMachine(const TTAMachine::Machine &machine)
static void encodeRFTerminal(const SlotField &field, const TTAProgram::Terminal &terminal, BitVector &bitVector)
bool hasParameter(const std::string &paramName) const
bool startsAtBeginningOfMAU(const TTAProgram::Instruction &instruction) const
bool allStartsAtBeginningOfMAU_
Tells whether all the instructions starts at the beginning of MAU.
static void encodeNOP(const MoveSlot &slot, BitVector &bitVector)
RelocMap relocMap_
Contains information to which instructions the immediates are referring to.
const BinaryEncoding * bem_
The binary encoding map.
int mau_
The size of the minimum addressable unit.
TTAProgram::Immediate * programImmediate(const TPEF::ImmediateElement &immElem, const TTAProgram::Instruction &instruction) const
static void encodeIUTerminal(const SlotField &field, const TTAProgram::Terminal &terminal, BitVector &bitVector)
ParameterTable parameters_
Parameters for the plugin.
void addBitsForImmediateSlot(const ImmediateSlotField &immSlot, const TTAProgram::Instruction &instruction, BitVector &bitVector)
TTAProgram::Program * currentPOM_
The current program in POM.
InstructionAddressMap instructionAddresses_
Contains the addresses of instructions.
void encodeImmediateTerminal(const SourceField &field, const TTAProgram::Terminal &terminal, InstructionBitVector &bitVector) const
std::vector< Parameter > ParameterTable
Table for passing plugin parameters.
static void addBitsForGuardField(const GuardField &guardField, const TTAProgram::Move &move, BitVector &bitVector)
static void encodeSlotField(const SlotField &field, const BitVector &componentIDBits, const BitVector &socketCodeBits, BitVector &BitVector)
InstructionBitVector * bemInstructionBits(const TTAProgram::Instruction &)
TPEFMap tpefPrograms_
Programs run in the machine.
void addBitsForICField(const ImmediateControlField &icField, const TTAProgram::Instruction &instruction, BitVector &bitVector) const
unsigned int nextAddressablePositionFrom(unsigned int position) const
TerminalSet terminalsToRelocate_
Set of (short) immediate terminals that refer to an instruction.
InstructionBitVector * programBits() const
TTAProgram::Terminal * immediateTerminal(const TPEF::CodeSection &codeSection, unsigned int elementIndex, const TPEF::ImmediateElement &immElem, const TTAProgram::Instruction &instruction) const
virtual int width() const
Definition Encoding.cc:130
unsigned int encoding() const
Definition Encoding.cc:108
std::string errorMessage() const
Definition Exception.cc:123
unsigned int encoding() const
FUGuardEncoding & fuGuardEncoding(int index) const
bool hasUnconditionalGuardEncoding(bool inverted) const
UnconditionalGuardEncoding & unconditionalGuardEncoding(bool inverted) const
GPRGuardEncoding & gprGuardEncoding(int index) const
virtual int width() const
MoveSlot * parent() const
unsigned int templateEncoding(const std::string &name) const
virtual int width() const
std::string name() const
void markInstructionStartingPoint(unsigned int position)
void startSettingInstructionReference(const TTAProgram::Instruction &instruction)
void pushBack(const InstructionBitVector &bits)
void fixInstructionAddress(const TTAProgram::Instruction &instruction, unsigned int address)
void addIndexBoundsForReference(IndexBound bounds)
virtual int width() const
std::string immediateUnit(const std::string &instructionTemplate) const
static ValueType valueForKey(const MapType &aMap, const KeyType &aKey)
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
static bool bit(ULongWord integer, unsigned int index)
SourceField & sourceField() const
Definition MoveSlot.cc:277
virtual InstructionField & childField(int position) const
Definition MoveSlot.cc:380
DestinationField & destinationField() const
Definition MoveSlot.cc:341
virtual int width() const
Definition MoveSlot.cc:406
std::string name() const
Definition MoveSlot.cc:136
GuardField & guardField() const
Definition MoveSlot.cc:215
virtual int childFieldCount() const
Definition MoveSlot.cc:357
static NullFUGuardEncoding & instance()
static NullGPRGuardEncoding & instance()
static NullImmediateEncoding & instance()
static NullNOPEncoding & instance()
static NullOperation & instance()
static NullUnconditionalGuardEncoding & instance()
virtual TCEString name() const
Definition Operation.cc:93
bool hasEncoding() const
Definition PortCode.cc:151
int indexWidth() const
Definition PortCode.cc:215
int width() const
Definition PortCode.cc:188
unsigned int encoding() const
Definition PortCode.cc:164
UIntWord uIntWordValue() const
Definition SimValue.cc:972
MoveSlot * parent() const
Definition SlotField.cc:98
bool hasSocketEncoding(const std::string &socket) const
Definition SlotField.cc:188
virtual int width() const
Definition SlotField.cc:307
SocketEncoding & socketEncoding(int index) const
Definition SlotField.cc:170
bool hasNoOperationEncoding() const
Definition SlotField.cc:267
NOPEncoding & noOperationEncoding() const
Definition SlotField.cc:281
BinaryEncoding::Position componentIDPosition() const
Definition SlotField.cc:296
FUPortCode & fuPortCode(int index) const
RFPortCode & rfPortCode(int index) const
bool hasRFPortCode(const std::string &regFile) const
bool hasIUPortCode(const std::string &immediateUnit) const
IUPortCode & iuPortCode(int index) const
bool hasFUPortCode(const std::string &fu, const std::string &port) const
SocketCodeTable & socketCodes() const
bool hasSocketCodes() const
int socketIDWidth() const
virtual int width() const
ImmediateEncoding & immediateEncoding() const
Word sectionCount() const
Section * section(Word index) const
virtual InstructionElement * element(Word index) const
Byte destinationIndex() const
Byte destinationUnit() const
HalfWord bus() const
HalfWord sourceIndex() const
FieldType sourceType() const
@ MF_IMM
Immediate.
SectionElement * destination() const
SectionElement * location() const
Section * referencedSection() const
@ MRT_BUS
Transport bus.
@ MRT_IMM
Immediate unit.
@ ST_CODE
Text section.
Definition Section.hh:79
@ ST_RELOC
Relocation section.
Definition Section.hh:74
SectionElement * element(Word index) const
Word elementCount() const
std::string resourceName(ResourceElement::ResourceType type, HalfWord resourceId) const
Definition TPEFTools.cc:84
virtual int width() const
virtual ULongWord start() const
virtual void setWidth(int width)
virtual int numberOfRegisters() const
virtual TCEString name() const
virtual AddressSpace * addressSpace() const
virtual bool isInverted() const
const std::string & name() const
virtual bool usesSlot(const std::string &slotName) const
virtual ImmediateUnit * destinationOfSlot(const std::string &slotName) const
virtual int numberOfSlots(const ImmediateUnit &dstUnit) const
virtual std::string slotOfDestination(const ImmediateUnit &dstUnit, int index) const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
bool isRISCVMachine() const
Definition Machine.cc:1057
FUPort * port() const
virtual Socket * outputSocket() const
Definition Port.cc:281
Unit * parentUnit() const
virtual Socket * inputSocket() const
Definition Port.cc:261
virtual std::string name() const
Definition Port.cc:141
const RegisterFile * registerFile() const
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
TerminalImmediate & value() const
Definition Immediate.cc:103
const Terminal & destination() const
Definition Immediate.cc:92
Move & move(int i) const
Immediate & immediate(int i) const
const TTAMachine::InstructionTemplate & instructionTemplate() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
const TTAMachine::Bus & bus() const
Definition Move.cc:373
static NullInstruction & instance()
Instruction & nextInstruction(const Instruction &) const
Definition Program.cc:403
Instruction & firstInstruction() const
Definition Program.cc:353
Instruction & instructionAt(InstructionAddress address) const
Definition Program.cc:374
virtual const TTAMachine::HWOperation * hwOperation() const
virtual SimValue value() const
virtual SimValue value() const
Definition Terminal.cc:178
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition Terminal.cc:251
virtual int index() const
Definition Terminal.cc:274
virtual bool isOpcodeSetting() const
Definition Terminal.cc:285
virtual Operation & operation() const
Definition Terminal.cc:319
virtual bool isGPR() const
Definition Terminal.cc:107
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual bool isImmediate() const
Definition Terminal.cc:63
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
virtual bool isFUPort() const
Definition Terminal.cc:118
virtual boost::format text(int textId)
std::string name
Name of the parameter.
std::string value
Value of the parameter.