OpenASIP  2.0
TPEFCodeSectionReader.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 TPEFCodeSectionReader.cc
26  *
27  * Definition of TPEFCodeSectionReader class.
28  *
29  * @author Mikael Lepistö 2003 (tmlepist-no.spam-cs.tut.fi)
30  *
31  * @note rating: yellow
32  */
33 
34 #include "TPEFCodeSectionReader.hh"
35 #include "SectionReader.hh"
36 #include "TPEFBaseType.hh"
37 #include "SafePointer.hh"
38 
39 #include "CodeSection.hh"
40 #include "InstructionElement.hh"
41 #include "MoveElement.hh"
42 #include "ImmediateElement.hh"
43 #include "BinaryStream.hh"
44 #include "TPEFHeaders.hh"
45 
46 namespace TPEF {
47 
48 using ReferenceManager::SafePointer;
49 using ReferenceManager::SectionOffsetKey;
50 using ReferenceManager::SectionIndexKey;
51 using std::string;
52 
53 TPEFCodeSectionReader TPEFCodeSectionReader::proto_;
54 
55 /**
56  * Constructor.
57  *
58  * Registers itself to SectionReader.
59  */
62 }
63 
64 /**
65  * Destructor.
66  */
68 }
69 
70 /**
71  * Returns the type of section it is meant to read.
72  *
73  * @return The type of section it can read.
74  */
77  return Section::ST_CODE;
78 }
79 
80 /**
81  * Reads section data from TPEF binary file.
82  *
83  * @param stream Stream to be read from.
84  * @param section Section where the information is to be stored.
85  * @exception UnreachableStream If reading of section fails.
86  * @exception KeyAlreadyExists Key was in use when trying to register object.
87  * @exception EndOfFile If end of file were reached while it shouldn't.
88  * @exception OutOfRange Some of read values were out of range.
89  * @exception WrongSubclass Some class couldn't do what it was asked for.
90  * @exception UnexpectedValue If there was unexpected value when reading.
91  */
92 void
94  // base classes implementation must be called with these.
95  TPEFSectionReader::readData(stream, section);
96 
97  CodeSection* codeSection = dynamic_cast<CodeSection*>(section);
98  assert(codeSection != NULL);
99 
100  bool nextIsBeginning = true;
101  Word sectionIndex = 0;
102 
103  // check that link section is defined properly
104  // (should point to machine resource section)
105  assert(header().linkId != 0);
106 
107  if (!section->noBits()) {
108 
109  while (stream.readPosition() <
110  header().bodyLength + header().bodyOffset) {
111 
113  sOffsetKey(header().sectionId,
114  stream.readPosition() - header().bodyOffset);
115 
116  Byte iAttr = stream.readByte();
117 
118  InstructionElement* newInstrElement = NULL;
119 
120  //if instruction is immediate
121  if (iAttr & TPEFHeaders::IA_TYPE) {
122 
123  ImmediateElement* newElem = new ImmediateElement();
124  newInstrElement = dynamic_cast<InstructionElement*>(newElem);
125 
126  newElem->setDestinationUnit(stream.readByte());
127  newElem->setDestinationIndex(stream.readByte());
128 
129  //iAttr mask 0xF0 number of bytes of immediate
130  Byte size = (iAttr >> (BYTE_BITWIDTH / 2));
131 
132  for (Byte i = 0; i < size; i++) {
133  newElem->addByte(stream.readByte());
134  }
135 
136  } else {
137 
138  MoveElement* newElem = new MoveElement();
139  newInstrElement = dynamic_cast<InstructionElement*>(newElem);
140 
141  newElem->setBus(readId(stream));
142 
143  Byte fieldTypes = stream.readByte();
144 
145  if (iAttr & TPEFHeaders::IA_EMPTY) {
146  newElem->setEmpty(true);
147 
148  } else {
149  newElem->setEmpty(false);
150 
151  switch (fieldTypes & TPEFHeaders::IE_SRC_TYPE_MASK) {
152  case TPEFHeaders::MVS_RF:
154  break;
157  break;
160  break;
161  default:
162  std::cerr << "field types: "
163  << std::hex << (int)fieldTypes
164  << std::dec << std::endl;
165  assert(false);
166  }
167 
168  switch (fieldTypes & TPEFHeaders::IE_DST_TYPE_MASK) {
169  case TPEFHeaders::MVD_RF:
171  break;
174  break;
175  default:
176  std::cerr << "field types: "
177  << std::hex << (int)fieldTypes
178  << std::dec << std::endl;
179  assert(false);
180  }
181 
182 
183  if (iAttr & TPEFHeaders::IA_MGUARD) {
184  newElem->setGuarded(true);
185 
186  switch (fieldTypes &
188 
191  break;
192  case TPEFHeaders::MVG_RF:
194  break;
195  default:
196  std::cerr << "field types: " << std::hex
197  << (int)fieldTypes
198  << std::dec << std::endl;
199  assert(false);
200  }
201 
202  } else {
203  newElem->setGuarded(false);
204  }
205  }
206 
207  newElem->setSourceUnit(readId(stream));
208  newElem->setSourceIndex(stream.readHalfWord());
209 
210  newElem->setDestinationUnit(readId(stream));
211  newElem->setDestinationIndex(stream.readHalfWord());
212 
213  newElem->setGuardUnit(readId(stream));
214  newElem->setGuardIndex(stream.readHalfWord());
215 
216  // guard extra parameters
217  if (fieldTypes & TPEFHeaders::IE_GUARD_INV_MASK) {
218  newElem->setGuardInverted(true);
219  } else {
220  newElem->setGuardInverted(false);
221  }
222  }
223 
224  newInstrElement->setBegin(nextIsBeginning);
225  nextIsBeginning = (iAttr & TPEFHeaders::IA_END);
226 
227  // create annotations for instruction if there are any
228  if (iAttr & TPEFHeaders::IA_ANNOTE) {
229  readAnnotations(stream, newInstrElement);
230  }
231 
232  // store reference to number of instruction for
233  // relocation destination resolving
234  if (newInstrElement->begin()) {
236  sIndexKey(header().sectionId, sectionIndex);
237  SafePointer::addObjectReference(sIndexKey, newInstrElement);
238  sectionIndex++;
239  }
240 
241  SafePointer::addObjectReference(sOffsetKey, newInstrElement);
242  codeSection->addElement(newInstrElement);
243  }
244 
245  // add section size to parent
246  dynamic_cast<TPEFReader*>(
247  parent())->addSectionSize(section, sectionIndex);
248  }
249 }
250 
251 /**
252  * Reads the info field of code section header.
253  *
254  * The `info' field of code sections normally contains the size of
255  * instruction word in memory image (in MAUs) and the instruction encoding
256  * type identifier. This information is ignored by the TUT_TTA architecture.
257  * The read position of the stream is moved 4 bytes forward.
258  *
259  * @todo Convert assertion onnstruction encoder identifier into a test with
260  * warning or error message.
261  *
262  * @param stream Stream from which the field is read.
263  * @param sect Target section. Unused.
264 */
265 void
267  BinaryStream& stream,
268  Section*) const {
269 
270  stream.readHalfWord(); // ignored
271  assert(stream.readByte() == 0); // instruction encoding ID
272  stream.readByte(); // padding - should warn if nonzero
273 }
274 
275 
276 /**
277  * Reads annotation fields and adds them to instruction.
278  *
279  * TODO: move to inline file...
280  *
281  * @param stream Stream pointing to start of annotation.
282  * @param elem Instruction where read annotations are added.
283  */
284 void
286  InstructionElement *elem) const {
287  bool continuation = true;
288 
289  while (continuation) {
290  Byte sizeAndContinuation = stream.readByte();
291 
292  // if continuation bit is down
293  if ((sizeAndContinuation & TPEFHeaders::IANNOTE_CONTINUATION) == 0) {
294  continuation = false;
295  }
296 
297 
298  Byte payloadSize = sizeAndContinuation & TPEFHeaders::IANNOTE_SIZE;
299 
300  // read three byte wide value (from big endian format)
301  Word id = stream.readByte() |
302  (static_cast<Word>(stream.readByte()) << (BYTE_BITWIDTH))|
303  (static_cast<Word>(stream.readByte()) << (BYTE_BITWIDTH*2));
304 
305  InstructionAnnotation *newAnnotation =
306  new InstructionAnnotation(id);
307 
308  for (int i = 0; i < payloadSize; i++) {
309  newAnnotation->addByte(stream.readByte());
310  }
311 
312  elem->addAnnotation(newAnnotation);
313  }
314 }
315 
316 /**
317  * Reads Bus, FU or RF id according to TPEF version.
318  *
319  * Original TPEF version 1 supports only less than 256 buses, FUs and RFs.
320  * Version 2 fixes that issue and we need to check the stream version for proper
321  * amount of bytes to read.
322  *
323  * @param stream Stream to which the data is read.
324  */
325 HalfWord
327 
328  TPEFHeaders::TPEFVersion version = stream.TPEFVersion();
329 
330  if (version == TPEFHeaders::TPEF_V1) {
331  return stream.readByte();
332  } else {
333  return stream.readHalfWord();
334  }
335 }
336 
337 }
TPEF::TPEFHeaders::IA_ANNOTE
@ IA_ANNOTE
Contains annotation.
Definition: TPEFHeaders.hh:123
TPEF::MoveElement::setGuardInverted
void setGuardInverted(bool flag)
TPEF::TPEFHeaders::IA_MGUARD
@ IA_MGUARD
Is conditional move or unconditional move.
Definition: TPEFHeaders.hh:126
TPEF::CodeSection::addElement
virtual void addElement(SectionElement *element)
Definition: CodeSection.cc:267
TPEF::TPEFHeaders::IA_END
@ IA_END
Is end of instruction.
Definition: TPEFHeaders.hh:122
TPEF::TPEFHeaders::MVD_RF
@ MVD_RF
Destination is RF.
Definition: TPEFHeaders.hh:141
TPEF::TPEFCodeSectionReader::proto_
static TPEFCodeSectionReader proto_
Prototype instance of TPEFCodeSectionReader to be registered to SectionReader.
Definition: TPEFCodeSectionReader.hh:70
TPEF::BinaryStream::readPosition
unsigned int readPosition()
Definition: BinaryStream.cc:561
TPEF::InstructionElement::addAnnotation
void addAnnotation(InstructionAnnotation *anAnnotation)
TPEF::ImmediateElement::addByte
void addByte(Byte aByte)
TPEF::TPEFHeaders::MVS_RF
@ MVS_RF
Source is RF.
Definition: TPEFHeaders.hh:137
TPEF::InstructionElement
Definition: InstructionElement.hh:77
TPEF::MoveElement::setDestinationUnit
void setDestinationUnit(HalfWord aDestinationUnit)
TPEF::MoveElement::MF_UNIT
@ MF_UNIT
Function unit.
Definition: MoveElement.hh:56
TPEF::TPEFHeaders::IANNOTE_CONTINUATION
@ IANNOTE_CONTINUATION
If there is more annotations.
Definition: TPEFHeaders.hh:113
TPEF::BinaryStream
Definition: BinaryStream.hh:59
TPEF::TPEFCodeSectionReader::~TPEFCodeSectionReader
virtual ~TPEFCodeSectionReader()
Definition: TPEFCodeSectionReader.cc:67
TPEF::TPEFHeaders::IA_TYPE
@ IA_TYPE
Instruction type: move (0), immediate (1).
Definition: TPEFHeaders.hh:121
TPEF::ImmediateElement::setDestinationIndex
void setDestinationIndex(Byte aDestinationIndex)
TPEF::MoveElement::setGuarded
void setGuarded(bool flag)
TPEF::MoveElement::MF_IMM
@ MF_IMM
Immediate.
Definition: MoveElement.hh:55
SafePointer.hh
TPEFHeaders.hh
TPEF::ImmediateElement
Definition: ImmediateElement.hh:49
InstructionElement.hh
TPEF::MoveElement::setDestinationType
void setDestinationType(FieldType aType)
Byte
unsigned char Byte
Definition: BaseType.hh:116
TPEF::ReferenceManager::SectionIndexKey
Definition: ReferenceKey.hh:65
TPEF::ReferenceManager::SafePointer::addObjectReference
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
Definition: SafePointer.cc:306
TPEF::TPEFCodeSectionReader::TPEFCodeSectionReader
TPEFCodeSectionReader()
Definition: TPEFCodeSectionReader.cc:60
ImmediateElement.hh
TPEF::MoveElement::setBus
void setBus(HalfWord aBus)
TPEF::InstructionAnnotation::addByte
void addByte(Byte aByte)
TPEF::Section
Definition: Section.hh:64
TPEF::MoveElement::MF_RF
@ MF_RF
Register file.
Definition: MoveElement.hh:54
TPEF::TPEFHeaders::MVS_UNIT
@ MVS_UNIT
Source is FU.
Definition: TPEFHeaders.hh:139
TPEF::ImmediateElement::setDestinationUnit
void setDestinationUnit(Byte aDestinationUnit)
assert
#define assert(condition)
Definition: Application.hh:86
TPEF::TPEFHeaders::TPEFVersion
TPEFVersion
Definition: TPEFHeaders.hh:56
TPEF::TPEFHeaders::MVG_RF
@ MVG_RF
Guard is RF.
Definition: TPEFHeaders.hh:145
TPEF::TPEFHeaders::IANNOTE_SIZE
@ IANNOTE_SIZE
Size of payload of annotation.
Definition: TPEFHeaders.hh:114
TPEF::MoveElement::setGuardIndex
void setGuardIndex(HalfWord aGuardIndex)
TPEF::TPEFCodeSectionReader::readData
virtual void readData(BinaryStream &stream, Section *section) const
Definition: TPEFCodeSectionReader.cc:93
TPEF::MoveElement
Definition: MoveElement.hh:47
SectionReader.hh
TPEF::TPEFHeaders::IA_EMPTY
@ IA_EMPTY
Empty instruction.
Definition: TPEFHeaders.hh:124
TPEF::TPEFHeaders::MVS_IMM
@ MVS_IMM
Source is immediate.
Definition: TPEFHeaders.hh:138
TPEFCodeSectionReader.hh
TPEF::InstructionElement::begin
bool begin() const
TPEF::MoveElement::setEmpty
void setEmpty(bool flag)
TPEF::TPEFCodeSectionReader::readId
virtual HalfWord readId(BinaryStream &stream) const
Definition: TPEFCodeSectionReader.cc:326
TPEF::TPEFHeaders::TPEF_V1
@ TPEF_V1
Initial TPEF version.
Definition: TPEFHeaders.hh:57
TPEF::SectionReader::registerSectionReader
static void registerSectionReader(const SectionReader *sReader)
Definition: SectionReader.cc:145
TPEF::TPEFHeaders::IE_GUARD_INV_MASK
@ IE_GUARD_INV_MASK
Guard inverted (1) means inverted.
Definition: TPEFHeaders.hh:146
TPEF::MoveElement::setDestinationIndex
void setDestinationIndex(HalfWord aDestinationIndex)
TPEF::BinaryStream::readHalfWord
HalfWord readHalfWord()
Definition: BinaryStream.cc:150
TPEF::TPEFSectionReader
Definition: TPEFSectionReader.hh:48
TPEF::BinaryStream::readByte
Byte readByte()
Definition: BinaryStream.cc:120
TPEF::TPEFHeaders::IE_GUARD_TYPE_MASK
@ IE_GUARD_TYPE_MASK
If (1) guard points to GPR,(0) to FU.
Definition: TPEFHeaders.hh:135
TPEF::CodeSection
Definition: CodeSection.hh:44
TPEF::MoveElement::setGuardType
void setGuardType(FieldType gType)
TPEF::Section::noBits
bool noBits() const
TPEF::TPEFHeaders::MVG_UNIT
@ MVG_UNIT
Guard is FU.
Definition: TPEFHeaders.hh:144
TPEF::TPEFSectionReader::parent
virtual BinaryReader * parent() const
Definition: TPEFSectionReader.cc:65
TPEF::InstructionElement::setBegin
void setBegin(bool isBegin)
TPEF::TPEFCodeSectionReader::readInfo
virtual void readInfo(BinaryStream &stream, Section *sect) const
Definition: TPEFCodeSectionReader.cc:266
TPEF::TPEFSectionReader::readData
virtual void readData(BinaryStream &stream, Section *section) const
Definition: TPEFSectionReader.cc:86
TPEF::TPEFReader
Definition: TPEFReader.hh:52
BYTE_BITWIDTH
const Byte BYTE_BITWIDTH
Definition: BaseType.hh:136
TPEF::MoveElement::setSourceUnit
void setSourceUnit(HalfWord aSourceUnit)
TPEF::TPEFHeaders::IE_DST_TYPE_MASK
@ IE_DST_TYPE_MASK
Instruction destination type mask.
Definition: TPEFHeaders.hh:134
TPEF::TPEFHeaders::MVD_UNIT
@ MVD_UNIT
Destination is FU.
Definition: TPEFHeaders.hh:143
TPEF::TPEFCodeSectionReader::type
virtual Section::SectionType type() const
Definition: TPEFCodeSectionReader.cc:76
TPEF::InstructionAnnotation
Definition: InstructionElement.hh:49
TPEF::MoveElement::setSourceIndex
void setSourceIndex(HalfWord aSourceIndex)
TPEF::ReferenceManager::SectionOffsetKey
Definition: ReferenceKey.hh:93
BinaryStream.hh
TPEF::Section::SectionType
SectionType
Definition: Section.hh:69
TPEF::BinaryStream::TPEFVersion
TPEFHeaders::TPEFVersion TPEFVersion() const
Definition: BinaryStream.cc:95
TPEFBaseType.hh
TPEF::Section::ST_CODE
@ ST_CODE
Text section.
Definition: Section.hh:79
MoveElement.hh
TPEF::TPEFCodeSectionReader::readAnnotations
void readAnnotations(BinaryStream &stream, InstructionElement *elem) const
Definition: TPEFCodeSectionReader.cc:285
CodeSection.hh
TPEF::TPEFHeaders::IE_SRC_TYPE_MASK
@ IE_SRC_TYPE_MASK
Instruction source type mask.
Definition: TPEFHeaders.hh:133
TPEF::TPEFSectionReader::header
static const Header & header()
Definition: TPEFSectionReader.cc:174
TPEF::MoveElement::setSourceType
void setSourceType(FieldType aType)
TPEF
Definition: Assembler.hh:43
TPEF::MoveElement::setGuardUnit
void setGuardUnit(HalfWord aGuardUnit)