OpenASIP 2.2
Loading...
Searching...
No Matches
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
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
46namespace TPEF {
47
48using ReferenceManager::SafePointer;
49using ReferenceManager::SectionOffsetKey;
50using ReferenceManager::SectionIndexKey;
51using std::string;
52
53TPEFCodeSectionReader TPEFCodeSectionReader::proto_;
54
55/**
56 * Constructor.
57 *
58 * Registers itself to SectionReader.
59 */
63
64/**
65 * Destructor.
66 */
69
70/**
71 * Returns the type of section it is meant to read.
72 *
73 * @return The type of section it can read.
74 */
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 */
92void
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) {
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) {
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;
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*/
265void
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 */
284void
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 */
325HalfWord
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}
#define assert(condition)
const Byte BYTE_BITWIDTH
Definition BaseType.hh:136
unsigned char Byte
Definition BaseType.hh:116
unsigned int readPosition()
TPEFHeaders::TPEFVersion TPEFVersion() const
HalfWord readHalfWord()
virtual void addElement(SectionElement *element)
void setDestinationIndex(Byte aDestinationIndex)
void setDestinationUnit(Byte aDestinationUnit)
void addByte(Byte aByte)
void addByte(Byte aByte)
void setBegin(bool isBegin)
void addAnnotation(InstructionAnnotation *anAnnotation)
void setGuardIndex(HalfWord aGuardIndex)
void setSourceType(FieldType aType)
void setGuardInverted(bool flag)
void setSourceIndex(HalfWord aSourceIndex)
void setBus(HalfWord aBus)
void setDestinationUnit(HalfWord aDestinationUnit)
void setGuarded(bool flag)
void setSourceUnit(HalfWord aSourceUnit)
void setGuardUnit(HalfWord aGuardUnit)
void setDestinationIndex(HalfWord aDestinationIndex)
void setEmpty(bool flag)
void setDestinationType(FieldType aType)
void setGuardType(FieldType gType)
@ MF_RF
Register file.
@ MF_IMM
Immediate.
@ MF_UNIT
Function unit.
static void addObjectReference(SectionIndexKey key, const SafePointable *obj)
static void registerSectionReader(const SectionReader *sReader)
@ ST_CODE
Text section.
Definition Section.hh:79
bool noBits() const
virtual void readData(BinaryStream &stream, Section *section) const
virtual void readInfo(BinaryStream &stream, Section *sect) const
void readAnnotations(BinaryStream &stream, InstructionElement *elem) const
virtual HalfWord readId(BinaryStream &stream) const
virtual Section::SectionType type() const
static TPEFCodeSectionReader proto_
Prototype instance of TPEFCodeSectionReader to be registered to SectionReader.
virtual BinaryReader * parent() const
virtual void readData(BinaryStream &stream, Section *section) const
static const Header & header()
@ IA_END
Is end of instruction.
@ IA_MGUARD
Is conditional move or unconditional move.
@ IA_TYPE
Instruction type: move (0), immediate (1).
@ IA_ANNOTE
Contains annotation.
@ IA_EMPTY
Empty instruction.
@ IE_GUARD_TYPE_MASK
If (1) guard points to GPR,(0) to FU.
@ IE_GUARD_INV_MASK
Guard inverted (1) means inverted.
@ MVG_RF
Guard is RF.
@ MVD_UNIT
Destination is FU.
@ MVS_IMM
Source is immediate.
@ MVD_RF
Destination is RF.
@ MVS_UNIT
Source is FU.
@ MVG_UNIT
Guard is FU.
@ IE_DST_TYPE_MASK
Instruction destination type mask.
@ MVS_RF
Source is RF.
@ IE_SRC_TYPE_MASK
Instruction source type mask.
@ TPEF_V1
Initial TPEF version.
@ IANNOTE_SIZE
Size of payload of annotation.
@ IANNOTE_CONTINUATION
If there is more annotations.